处理 HTTP POST 请求/响应

Dot*_*ota 1 c++ unix sockets http

我一直在尝试向 facebook 发送 HTTP POST 请求,但没有成功,我从服务器收到此响应:

HTTP/1.1 400 错误请求内容类型:text/html;charset=utf-8 日期:2016 年 12 月 10 日,星期六 21:28:17 GMT 连接:关闭 内容长度:2959

脸书 | 错误

抱歉,出了点问题,我们正在处理,会尽快修复

我的代码

#include <iostream>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <fstream>
using namespace std;

int main()
{
    int s, error;
    struct sockaddr_in addr;


        s = socket(AF_INET, SOCK_STREAM, 0);
    if(s <0)
    {
        cout<<"Error 01: creating socket failed!\n";
        close(s);
        return 1;
    }

    addr.sin_family = AF_INET;
    addr.sin_port = htons(80);
    inet_aton("31.13.90.36",&addr.sin_addr);

    error = connect(s,(sockaddr*)&addr,sizeof(addr));
    if(error!=0)
    {
        cout<<"Error 02: conecting to server failed!\n";
        close(s);
        return 1;
    }

     const int msgSize = 1042;
     char msg[] = "POST /login.php?login_attempt=1 \r\n"
                     "HTTP/1.1\r\n"
                     "HOST: facebook.com\r\n\r\n"
                     "Content-type: application/x-www-form-urlencoded\r\n"
                     "Content-Length: 41\r\n"
                     "email=lel@gmail.com&pass=test123&submit=1\r\n" ;







     char answ[1042];

    //cin.getline(&msg[0],256);

    send(s,msg,strlen(msg),0);


    ssize_t len;
    while((len = recv(s, msg, strlen(msg), 0)) > 0)
    {
        cout.write(msg, len);

        std::cout << std::flush;
    }
    if(len < 0)
    {
        cout << "error";
    }
    close(s);  

}
Run Code Online (Sandbox Code Playgroud)

我做错了什么?

Ste*_*ich 5

您的消息中有几个错误。这是您根据代码发送的内容:

1  POST /login.php?login_attempt=1 \r\n
2  HTTP/1.1\r\n 
3  HOST: facebook.com\r\n\r\n
4  Content-type: application/x-www-form-urlencoded\r\n
5  Content-Length: 41\r\n
6  email=lel@gmail.com&pass=test123&submit=1\r\n
Run Code Online (Sandbox Code Playgroud)

相反,它应该是这样的:

1  POST /login.php?login_attempt=1 HTTP/1.1\r\n
2  HOST: facebook.com\r\n
3  Content-type: application/x-www-form-urlencoded\r\n
4  Content-Length: 41\r\n
5  \r\n
6  email=lel@gmail.com&pass=test123&submit=1
Run Code Online (Sandbox Code Playgroud)

详细地:

  • 第 1 行和第 2 行应该是一行,即“方法路径 HTTP 版本”
  • 第 3 行不应包含多个\r\n
  • 相反,空行\r\n应该位于所有 HTTP 标头之后(新行 5)
  • 第 6 行的正文应仅包含内容长度所涵盖的数据。您在那里设置的 41 字节不包括\r\n您发送的

除此之外,您没有正确解析响应,而是期望服务器在响应完成后关闭连接。由于您正在使用HTTP/1.1隐式使用持久连接(HTTP 保持活动),因此服务器实际上可能会在同一 TCP 连接中等待更多请求,并且不会立即关闭连接。

我强烈建议您研究HTTP 标准,而不是猜测该协议如何工作。