2015-11-05 57 views
2

我正在学习在OS X机器上使用C和C++中的本地套接字。从以前的项目中,我已经在http://castifyreceiver.com/index.html上建立了一个非常简单的网页。这个网页几乎没有任何东西了,所以我不介意分享真实的网址。C++ C++ Posix BSD套接字 - HTTP请求总是返回状态400

基本上我的问题是,我的所有HTTP请求都返回400错误请求。我知道我正在使用这个练习的网页正在运行,我可以通过浏览器访问它。这导致我相信我错误地实现了HTTP协议,但我不知道我错在哪里。

以下是我用于通过套接字请求此页的所有代码。

#include <stdio.h> 
#include <unistd.h> 
#include <sys/socket.h> 
#include <netdb.h> 
#include <string.h> 

int main(int argc, const char * argv[]) { 

// create the request 
const char * request = "GET /index.html HTTP/1.1\nAccept: */*\n\n"; 
size_t length = strlen(request); 
printf("request:\n\n%s", request); 

// get the destination address 
struct addrinfo hints; 
memset(&hints, 0, sizeof(hints)); 
hints.ai_family = AF_UNSPEC; 
hints.ai_socktype = SOCK_STREAM; 
hints.ai_flags = AI_PASSIVE; 
struct addrinfo * address; 
getaddrinfo("castifyreceiver.com", "http", &hints, &address); 

// create a socket 
int sfd = socket(address->ai_family, address->ai_socktype, address->ai_protocol); 
int result = connect(sfd, address->ai_addr, address->ai_addrlen); 
if (result != 0) { 
    printf("connection failed: %i\n", result); 
    freeaddrinfo(address); 
    close(sfd); 
    return 0; 
} else { 
    printf("connected\n"); 
} 

// write to socket 
ssize_t written = write(sfd, request, length); 
printf("wrote %lu of %lu expected\n", written, length); 

// read from socket and cleanup 
char response[4096]; 
ssize_t readed = read(sfd, response, 4096); 
printf("read %lu of 4096 possible\n", readed); 
close(sfd); 
freeaddrinfo(address); 

// display response message 
response[readed] = '\0'; 
printf("response:\n\n%s\n", response); 

return 0; 
} 

这个节目一贯输出类似于下面的内容:

request: 

GET /index.html HTTP/1.1 
Accept: */* 

connected 
wrote 38 of 38 expected 
read 590 of 4096 possible 
response: 

HTTP/1.1 400 Bad Request 
Date: Thu, 05 Nov 2015 18:24:08 GMT 
Server: Apache/2.2.31 (Unix) mod_ssl/2.2.31 OpenSSL/1.0.1e-fips mod_bwlimited/1.4 
Content-Length: 357 
Connection: close 
Content-Type: text/html; charset=iso-8859-1 

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> 
<html><head> 
<title>400 Bad Request</title> 
</head><body> 
<h1>Bad Request</h1> 
<p>Your browser sent a request that this server could not understand. <br /> 
</p> 
<hr> 
<address>Apache/2.2.31 (Unix) mod_ssl/2.2.31 OpenSSL/1.0.1e-fips mod_bwlimited/1.4 Server at 108.167.131.50 Port 80</address> 
</body></html> 

我花了很多时间找过RFC 2616,我仍然无法找到我在做什么错。任何帮助表示赞赏。

回答

3

两件事情:

  • 必须发送一个Host头,比照。 RFC 2616 p。 129:

    客户端必须在所有HTTP/1.1请求 消息中包含主机头字段。如果所请求的URI不包括所请求的服务的互联网主机名称,则主机头域必须为空值赋予 。

  • 使用\r\n终止您行HTTP,而不是仅仅\n,比照。 RFC 2616 p。 16:

    HTTP/1.1定义了序列CR LF作为结束线标记为除了实体主体所有 协议元素(见附录19.3 宽容应用)。实体主体 内的行尾标记由其关联的媒体类型定义,如3.7节所述。

,如果你改变它应该工作。

+0

它工作!非常感谢! –

+0

@WilliamRosenbloom我很高兴!不要忘记将答案标记为已接受。 – fuz