1

我正在创建一个简单的服务器,它只在端口 2222 处提供现有文件 /home/john/www。我的 www 文件夹包含三个文件:index.html、server.c、client.c。

运行服务器,我的 firefox 现在可以通过以下方式请求页面:

localhost:2222/server.c

问题是,不是在我的 Firefox 上显示 server.c 的内容,而是下载文件。(firefox 提示查看或保存文件。)与 index.html 和 client.c 相同。

几天前,我能够在我的浏览器上显示 server.c 的内容。但我不再记得我为使浏览器表现得那样所做的更改。

这是我正在修改的代码片段:

#define LINE_LEN 128
#define MAX_LEN 1024
...
int process_request(int fd, char *www_path) {
    char cmessage[MAX_LEN];
    char *r;
    int n, read_size;
    FILE *file;
    char line[LINE_LEN];
    struct stat sb;
    if((n = read(fd, cmessage, MAX_LEN)) <= 0) {
        return 6;
    }
    cmessage[n] = '\0';
    // assume GET method
    r = cmessage + 4;
    n = 0;
    while(r[n] != ' ') {
        n++;
    }
    int len = strlen(www_path);
    char req_file[len+n+1];
    char temp[n+1];
    strncpy(temp, r, n);
    temp[n] = '\0';
    sprintf(req_file, "%s%s", www_path, temp);
    if(stat(req_file, &sb) == -1) {
        perror("stat");
        return 7;
    }
    char size[10];
    sprintf(size, "%d", sb.st_size);
    file = fopen(req_file, "rb");
    write(fd, "HTTP/1.1 200 OK\r\nContent-length: ", 33);
    write(fd, size, strlen(size));
    write(fd, "\r\n\r\n", 4);
    while((read_size = fread(line, sizeof(char), LINE_LEN, file)) != 0) {
        write(fd, line, read_size);
    }
    fclose(file);
    return 0;
}

或者这只是可以在我的网络浏览器设置中设置的配置?

更多细节:

套接字是使用创建的

socket(AF_INET, SOCK_STREAM, 0);

listen()、bind() 和 accept() 成功。select() 语句用于等待准备好读取的文件描述符。在对某个文件描述符的 read() 返回 -1 之前,连接的客户端的文件描述符不会关闭。

感谢您抽出时间来阅读。:-) 希望对为什么会发生这种情况有一个有用的答案。

4

2 回答 2

4

作为服务器响应的一部分,您需要为浏览器提供适当的内容类型。这可能是您硬编码的内容,也可能是从文件名派生的内容。例如:

Content-Type: text/plain
于 2012-07-06T08:40:10.790 回答
1

您应该设置 Content Type 标头,以指定要发送的内容的 MIME 类型。浏览器按内容的类型处理内容。

如果浏览器无法识别内容类型,它会要求用户保存文件。

write(fd, "\r\nContent-Type: text/html");

MIME 类型取决于您发送的内容,对于 index.html,它应该是 text/html,对于 .c 文件,它可以是 text/plain

除此之外,我觉得代码逻辑中缺少以下内容:

  • Content-Length 是如何派生的
  • 根据 HTTP 协议,内容在标头之后开始。要标记标题的结尾和内容的开始,您应该有 2 个新行条目 - 即内容和标题之间的空白行
于 2012-07-06T08:41:09.073 回答