我很难在C中实现代理服务器。它适用于几个第一个网页,但在等待新请求时我被阻止。
设计
Firefox -> Proxy -> Webserver --.
Firefox <- Proxy <- Webserver <-'
因此,每个请求都是从浏览器到代理和服务器的往返,然后返回。在请求的响应回来之前,什么都不应该发生。我使用无流水线,线程或类似的东西,而是以线性串行方式仅使用recv()
和send()
(为了简单和直观)。我也没有关闭任何套接字,因为我想拥有持久连接。
我希望能够获取整个网页,包括css,img,js等子请求资源。
在我的实现中,我设法获取一些网页的第一个请求。然后挂起第1步。
实现:
puts("Waiting for user to connect..");
int sock_user = accept(sock, (struct sockaddr*)NULL, NULL);
int sock_host = -1;
printf("User connected.\n");
// Accept requests
while(1){
http_request req;
http_response resp;
// 1. Client ==> Proxy Server
http_parse_request(sock_user, &req); // uses recv()
// 2. Client Proxy ==> Server
if (sock_host < 0)
sock_host = proxy_connect_host(req.header->host);
write(sock_host, req.header->raw_data, req.header->raw_size);
// 3. Client Proxy <== Server
http_parse_response(sock_host, &resp); // uses recv()
// 4. Client <== Proxy Server
write(sock_user, resp.header->raw_data, resp.header->raw_size);
write(sock_user, resp.body ->first_block->data, resp.body ->first_block->size);
}
日志:
---- ......................................... ----
---- after succesfully responded to 4 requests ----
Client ==> Proxy Server
Received 389
Client Proxy ==> Server
Sending.. 389
Sent 389
Client Proxy <== Server
Got header 312
Got body 1437
Response total 1749
Client <== Proxy Server
Sending header.. 312
Sent 312
Sending body.. 1437
Sent 1437
Client ==> Proxy Server
---- Hangs/blocks here ----
萤火虫:
Wireshark的:
我对这个障碍的原因没有直觉,而且我花了整整一周的时间试图解决这个问题而没有取得突破。
试图解决问题的事情:
CRLF
recv()
和send()
的返回值。 (在上面的日志中,
打印的值是recv
和send
的返回值
{{1}} )我希望有人可以至少给出一些方向来解决这个问题,否则我的大脑会很快爆炸:)
答案 0 :(得分:0)
您必须非常小心,不要阅读太多数据。例如。确保:
标头只读到双CRLF;存储额外数据并与身体一起发送
在服务器发送完整标题之前不开始发送正文(不适用于此GET情况但对POST或CONNECT很重要)
收到并仅发送来自正文的Content-Length字节
这适用于客户 - &gt;代理请求和服务器 - &gt;代理响应。
您的示例代码保持无限循环(while (1) ...
)。你怎么中止这个?您是否尊重“代理连接”标题?