C/C++ Posix BSD 套接字 - HTTP 请求始终返回状态 400

标签 c sockets http

我正在学习在 OS X 机器上使用 C 和 C++ 中的 native 套接字。在之前的项目中,我在 http://castifyreceiver.com/index.html 设置了一个非常简单的网页。 。该网页几乎不再执行任何操作,因此我不介意分享真实的 URL。

基本上我的问题是我的所有 HTTP 请求都返回 400 Bad Request。我知道我用于此练习的网页已启动并正在运行,并且我可以通过浏览器访问它。这让我相信我错误地实现了 HTTP 协议(protocol),但我不知道哪里出了问题。

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

#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我仍然找不到我做错了什么。如有任何帮助,我们将不胜感激。

最佳答案

有两件事:

  • 您必须发送 Host header ,参见。 RFC 2616 页。 129:

    A client MUST include a Host header field in all HTTP/1.1 request messages . If the requested URI does not include an Internet host name for the service being requested, then the Host header field MUST be given with an empty value.

  • 使用 \r\n 终止 HTTP 中的行,而不仅仅是 \n,参见RFC 2616 页。 16:

    HTTP/1.1 defines the sequence CR LF as the end-of-line marker for all protocol elements except the entity-body (see appendix 19.3 for tolerant applications). The end-of-line marker within an entity-body is defined by its associated media type, as described in section 3.7.

如果你改变它应该会起作用。

关于C/C++ Posix BSD 套接字 - HTTP 请求始终返回状态 400,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33552232/

相关文章:

c - C中函数指针的递归声明

c - ncurses 窗口中的 Shell?

c - "warning: control reaches end of non-void function"但实际上该函数被声明为 int 并返回一个 int

linux - 在哪个本地接口(interface)上接收到连接或数据包?

php - Laravel 5.2 和 Valet - 无法发送电子邮件 - 无法找到套接字传输 "plain"

c - ZeroMQ 请求/回复不向一个方向回复

java - 如何在不离开页面的情况下从 servlet 返回一个字符串?

c++ - 如何使用 CGI 流式传输 motion jpeg?

java - 在 Java Servlet 中限制 HTTP 请求

c++ - 套接字编程学习