2012-04-15 3 views
0

Мне нужно отправить пост-запрос, используя чистые сокеты в C++. Я не могу понять, куда отправить тело запроса:Запрос POST с гнездами

int *binary = new int[bufferLength]; 
... 

std::stringstream out(data); 
out << "POST /push1_pub?id=game HTTP/1.1\n"; 
out << "Host: http://0.0.0.0:80\n"; 
out << "Content-Length: "; 
out << bufferLength*sizeof(int); 
out << "\r\n\r\n"; 
out << binary; 

if (socket.send(data.c_str(), data.size()) == -1) 
{ 
    std::cout << "Failed to send headers\n"; 
} 
else 
{ 
    // Send request body 
    socket.send(reinterpret_cast<char*>(binary), bufferLength*sizeof(int)); 
    // Get the answer of server 
    char buf[1024]; 
    std::cout << socket.recv(buf, 1024) << std::endl; 
    std::cout << buf << std::endl; 
} 

Но в buf после отправки тела у меня есть:

<html> 
<head><title>400 Bad Request</title></head> 
<body bgcolor="white"> 
<center><h1>400 Bad Request</h1></center> 
<hr><center>nginx</center> 
</body> 
</html> 

Что может быть не так?


обн:

Новые заголовки, которые я написал в связи с вашими комментариями:

std::string data; 
std::stringstream out(data); 
out << "POST /push1_pub?id=game\r\n"; 
out << "Host: http://localhost\r\n"; 
out << "Content-Length: "; 
out << bufferLength << "\r\n"; 
out << "\r\n\r\n"; 
out << binary; 

Еще есть такая же проблема.


UPD2

С помощью этой команды: curl -s -v -X POST 'http://0.0.0.0/push1_pub?id=game' -d 'Test' Все работает отлично и запрос на запись формируется и отправляется прямо.

+0

Что вы видите в Fiddler? – SLaks

+0

@SLaks Я не могу запустить его под Linux? – Ockonal

+0

Хотя это не настоящая проблема, вы должны прервать каждый заголовок с помощью [CRLF] (http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.1), а не только CR. Кроме того, вы не должны указывать 'HTTP/1.1', если вы не поддерживаете [закодированное кодирование] (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1). (Обратите внимание на строку * MUST * в конце этого раздела.) –

ответ

2

Неправильная строка вашего хоста. Это должно быть простое имя хоста, например. «localhost» или «example.com», а не URL-адрес http://0.0.0.0:80, который у вас есть.

Линия хоста используется веб-сервером для определения того, какая из потенциально ТЫСЯЧ сайтов, размещенных на одном IP-адресе, запрашивается. Номер порта также бесполезен, поскольку к тому времени, когда вы отправляете заголовки HTTP, TCP-соединение уже установлено. И поскольку вы уже выполняете HTTP-запрос, нет необходимости избыточно указывать используемый протокол.

+0

Хорошо, спасибо. Но где именно отправить массив 'binary' - тело запроса? Я добавляю его в заголовки, а также пытаюсь отправить после отправки заголовков. постскриптум есть еще 400 ошибок. – Ockonal

+0

У вас есть ряд проблем в вашем коде, некоторые крупные и некоторые второстепенные. Вы действительно должны начать с изучения [HTTP-спецификации] (http://www.w3.org/Protocols/rfc2616/rfc2616.html), если вы настаиваете на написании своей собственной реализации HTTP-клиента. Но гораздо разумнее использовать тот, который уже сделан. HTTP действительно не простой протокол –

Смежные вопросы