【问题标题】:C Programming - Sending HTTP RequestC 编程 - 发送 HTTP 请求
【发布时间】:2012-12-29 03:03:48
【问题描述】:

我最近的任务是使用套接字编程在 C 中创建一个代理。代理只需要使用 HTTP/1.0 构建。经过几个小时的工作,我制作了一个可以与 Chromium 一起使用的代理。可以加载各种网站,例如google和几个.edu网站;但是,许多网站给我一个找不到页面的 404 错误(这些链接在不通过我的代理时工作正常)。这些 404 错误甚至发生在站点的根地址“/”上……这没有意义。

这可能是我的 HTTP 请求有问题吗?将从浏览器发送的 HTTP 请求解析为 HTTP 请求方法、主机名和端口。例如,如果从浏览器解析 GET 请求,则与提供的主机名和端口建立 TCP 连接,并以以下格式发送 HTTP GET 请求:

GET /path/name/item.html HTTP/1.0\r\n\r\n

此格式适用于少量网站,但会为其余网站创建 404 错误消息。这可能是问题吗?如果没有,还有什么可能给我这个问题?

任何帮助将不胜感激。

【问题讨论】:

    标签: sockets httprequest rfc


    【解决方案1】:

    一个可能的解释是您设计了一个 HTTP/1.0 代理,而现在共享托管站点上的任何网站都只能使用 HTTP/1.1(嗯,不完全是,但我会谈到等一下)。

    这并不是唯一可能出现的问题,但您必须举一个网站的例子,该网站像这样失败,以获得更多想法。

    您似乎了解 HTTP 的基础知识,客户端与服务器建立 TCP 连接并通过它发送 HTTP 请求,该请求由请求行(例如GET /path/name/item.html HTTP/1.0)和一组可选标头组成行,全部由 CRLF 分隔(即\r\n)。整个批次以两个连续的 CRLF 序列结束,此时另一端的服务器将请求与资源匹配并发回适当的响应。资源全部由路径标识(例如/path/name/item.html),该路径可以是真实文件,也可以是动态页面。

    自从 HTTP 首次发明以来,大部分内容几乎没有变化。但是,请考虑客户端如何找到要连接的服务器。你给它的是一个 URL,像这样:

    http://www.example.com/path/name/item.html
    

    由此它查看http方案,因此它知道它正在建立一个HTTP 连接。下一部分是主机名。在原始 HTTP 下,假设每个主机名都解析为自己的 IP 地址,然后客户端连接到该 IP 地址并发出请求。由于当时每台服务器只有一个网站,因此效果很好。

    然而,随着网站数量的增加,为每个网站分配不同的 IP 地址变得越来越困难,特别是因为许多网站非常简单,可以很容易地在同一台物理机器上共享。将多个域指向同一个 IP 地址很容易(DNS 系统使这非常简单),但是当服务器收到 TCP 请求时,它只会知道它有一个对其 IP 地址的请求——它不知道是哪个网站寄回。因此,添加了一个新的Host 标头,以便客户端可以在请求本身中指示它正在请求哪个主机名。这意味着一台服务器可以托管许多网站,并且网络服务器可以使用 Host 标头来告诉在响应中服务哪一个。

    现在这很常见 - 如果您不使用 Host 标头,那么许多网站将不知道您要使用哪个服务器。通常发生的情况是,他们假设他们拥有的列表中有一些默认网站,并且很可能没有您要的文件。即使您要求/,如果您不提供Host 标头,那么网络服务器可能会给您一个404,如果它是这样配置的 - 如果没有合理的配置,这并不是不合理的默认网站给你。

    如果您想了解更多技术细节,可以在the HTTP RFC 中找到Host 标头的说明。

    此外,网站可能只是简单地拒绝 HTTP/1.0 - 如果这种情况发生在这么多网站上,我会略微感到惊讶,但你永远不会知道。不过,请先尝试 Host 标头。

    与某些人认为的相反,没有什么可以阻止您在 HTTP/1.0 中使用 Host 标头,尽管您可能仍然会发现一些不喜欢这样的服务器。它比支持完整的 HTTP/1.1 要容易一些,这需要您了解分块编码和其他复杂性,尽管对于简单的示例代码,您可能只需添加 Host 标头并将其称为 HTTP/1.1(我不会不建议这对于生产代码是足够的,但是)。

    无论如何,您可以尝试添加Host 标头以使您的请求如下:

    GET /path/name/item.html HTTP/1.0\r\n
    Host: www.example.com\r\n
    \r\n
    

    为了便于阅读,我将它分成几行 - 你可以看到末尾仍然有空白行。

    即使这不会导致您看到的问题,Host 标头如今也是一个非常好的主意,因为肯定有一些网站没有它就无法工作。如果您仍然遇到问题,请给我一个不适合您的网站示例,我们可以尝试找出原因。

    如果我所说的任何内容不清楚或需要更多详细信息,请询问。

    【讨论】:

    • 非常感谢您的详细回复。我不知道我需要包含 Host 标头。我将此添加到我的 HTTP 请求中,一切都开始正常工作!感谢您的帮助!
    • 不客气。严格来说,您不需要 Host 标头 - 但正如您所发现的,没有它,很多网站都无法运行! (^_^)
    • 很好的解释!
    • 执行我的 C 客户端时卡住了。请参阅this question我发布的更多详细信息
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-30
    • 1970-01-01
    • 2015-03-15
    • 1970-01-01
    相关资源
    最近更新 更多