0

我有一个 AWS EC2 实例(Windows Server 2022 数据中心),我在其中托管了一个网站用于我的音乐混音:

http://www.shahspace.com/music mixes/

它由 node.js 托管。一切正常,除了偶尔,它似乎想要浏览目录而不是呈现页面。

在此处输入图像描述

我做了一些实验,发现每当我尝试访问www.shahspace.com下的 ASP.NET 应用程序时都会发生这种情况(我不会发布确切的 url,因为它包含敏感信息,但我们称之为http:/ /www.shahspace.com/asp.net/。我可以通过重启node.js服务来修复它。换句话说,www.shahspace.com有两个不同的(可能是冲突的)托管平台:IIS和Node.js。

IIS在我的 ASP.NET 应用程序所在的路径 C:\inetpub\wwwroot\shahspace.com\asp.net\托管http://www.shahspace.com/asp.net/ 。Node.js 在路径 C:\inetpub\wwwroot\ 上运行,并提供来自 C:\inetpub\wwwroot\music mixes\views\index.hbs 的音乐混音登录页面。我之所以这样设置,是因为我希望 node.js 成为路由端口 80 上的所有入站流量的主要集线器。由于 ASP.NET 应用程序是一个 ASP.NET 应用程序,因此我还需要 IIS 作为该站点的托管平台,node.js 将请求适当地委托给该站点。

我在防火墙中为端口 80 设置了一个有效的入站规则,在 AWS 中,我也有相同的设置:

在此处输入图像描述

IIS 只有指向 C:\inetpub\wwwroot\shahspace.com\asp.net\ 的默认网站并监听端口 8000:

在此处输入图像描述

这是 node.js 服务的样子:

const bouncy = require('bouncy');
const express = require('express');
const path = require('path');
const { create, engine } = require('express-handlebars');

bouncy(function(req, bounce) {
    const host = req.headers.host;
    if (host === 'shahspace.com' || host === 'www.shahspace.com') {
        if (req.url.includes('/music%20mixes/')) bounce(8002);
        else bounce(8000);
    }
    
    // other domains get bounced to their own respective ports

}).listen(80);
    
const musicMixApp = express();
musicMixApp.engine('.hbs', engine({
    extname: 'hbs',
    defaultLayout: false
}));
musicMixApp.set('view engine', 'hbs');
musicMixApp.set('views', path.join(__dirname, 'shahspace.com/music mixes/views'));

musicMixApp.get('/music%20mixes', (req, res) => {
    const folders = getMixFolders();
    res.render('index', { folders });
});
musicMixApp.get('/music%20mixes/:mix', (req, res) => {
    const mixName = req.params.mix;
    const playlist = getPlaylist(mixName);
    res.render('mix', {
        mixName: mixName.substring(3, mixName.length),
        playlist
    });
});
musicMixApp.get('/music%20mixes/:mix/:mp3', (req, res) => {
    const mix = req.params.mix;
    const mp3 = req.params.mp3;
    res.sendFile(`${__dirname}/shahspace.com/music mixes/${mix}/${mp3}`);
});

musicMixApp.listen(8002);

function getMixFolders() {
    const { readdirSync, statSync } = require('fs');
    
    const mixPath = './shahspace.com/music mixes/';
    const folderInfo = readdirSync(mixPath, { withFileTypes: true })
        .filter(item => item.isDirectory() && item.name !== 'views')
        .map(folder => folder.name)
        .sort((f1, f2) => f1 < f2 ? 1 : -1);
    
    return folderInfo.map(folder => ({
        number: folder.substring(0, 2),
        name: folder.substring(3, folder.length)
    }));
}

function getPlaylist(mixName) {
    if (!mixName) return [];

    const { readdirSync } = require('fs');

    let songs = [];
    try {
        songs = readdirSync(`./shahspace.com/music mixes/${mixName}`, { withFileTypes: true })
            .filter(item => item.name.endsWith('.mp3'));
    } catch (err) {
        return [];
    }

    return songs.map(song => song.name.substring(0, song.name.length - 4));
}

要查看的主要内容是对 bouncy() 的调用。它说的是,如果端口 80 上的请求是“shahspace.com”,特别是“shahspace.com/music mixes”,那么重定向到端口 8002,musicMixApp 正在侦听该端口。否则,如果它是“shahspace.com”而不是“shahspace.com/music mixes/”,则重定向到端口 8000(我的 ASP.NET 站点正在侦听,由默认网站站点的 IIS 设置确定)。

本质上,这意味着 node.js 服务器是唯一一个侦听端口 80 的服务器,并根据指定的主机(由 确定req.headers.host)重定向到适当的端口。我为我的音乐混音应用程序路由到端口 8002,为www.shahspace.com下不是我的音乐混音应用程序的任何东西路由到端口 8000。所有其他域(即 www.not_shahspace.com)都被路由到其他端口。我用 bouncy 做这一切,而 bouncy 本身在端口 80 上侦听。

我不知道以上所有内容是否与我遇到的问题有关。我所知道的是,当我访问我的 ASP.NET 站点,然后返回我的音乐混音应用程序(或者如果它已经打开,则只刷新它),它会尝试浏览目录而不是在视图持有者下加载 index.hbs。我知道这一点:如果您查看上面 403.13 错误的屏幕截图,它表明它正在尝试连接端口 8000。当我将控制台日志添加到 node.js 服务(bouncy 在其中工作)时,它不打印任何东西。奇怪的是,在我去我的 ASP.NET 站点之前它似乎去端口 80 并且 bouncy 发挥了它的魔力,但是在我去我的 ASP.NET 站点并刷新我的音乐混合站点上的页面之后(或者去它在新的浏览器选项卡中),它似乎想直接转到端口 8000(绕过弹性)。爱荷华州,

当然,启用目录浏览不是答案,因为我想提供页面而不是允许用户浏览目录。

如果有人可以建议为什么会发生这种情况和/或如何解决问题,将不胜感激。谢谢你。

更新

我按照 samwu 的建议,让请求失败跟踪工作。我复制了错误并获得了它所跟踪内容的完整报告。现在我需要有人帮我解释一下。或者可能不是。据我所知,错误是请求从一开始就从端口 8000 进入,这是不应该的。它应该进入端口 80。

在此处输入图像描述

实际的 403.14 错误发生在第 176 行:

在此处输入图像描述

但这在这一点上并不神秘。无法浏览目录,因为我禁用了目录浏览。我想要那个。问题是,为什么它进入端口 8000 而不是 80?为什么运行我的 ASP.NET 应用程序(在端口 8000 上)会导致对www.shahspace.com/music mixes / 的所有后续请求也在端口 8000 上?

4

0 回答 0