can specify extra headers

This commit is contained in:
Benjamin Sergeant 2019-02-25 17:17:05 -08:00
parent 3bcd6f97a6
commit b563541b14
4 changed files with 54 additions and 55 deletions

View File

@ -36,6 +36,7 @@ namespace ix
HttpResponse HttpClient::request(
const std::string& url,
const std::string& verb,
const WebSocketHttpHeaders& extraHeaders,
const HttpParameters& httpParameters,
bool verbose)
{
@ -98,6 +99,12 @@ namespace ix
ss << "Host: " << host << "\r\n";
ss << "User-Agent: ixwebsocket/1.0.0" << "\r\n";
ss << "Accept: */*" << "\r\n";
for (auto&& it : extraHeaders)
{
ss << it.first << ": " << urlEncode(it.second) << "\r\n";
}
if (verb == "POST")
{
ss << "Content-Length: " << body.size() << "\r\n";
@ -196,7 +203,7 @@ namespace ix
payload.reserve(contentLength);
// very inefficient way to read bytes, but it works...
// FIXME: very inefficient way to read bytes, but it works...
for (int i = 0; i < contentLength; ++i)
{
char c;
@ -215,17 +222,19 @@ namespace ix
HttpResponse HttpClient::get(
const std::string& url,
const WebSocketHttpHeaders& extraHeaders,
bool verbose)
{
return request(url, "GET", HttpParameters(), verbose);
return request(url, "GET", extraHeaders, HttpParameters(), verbose);
}
HttpResponse HttpClient::post(
const std::string& url,
const WebSocketHttpHeaders& extraHeaders,
const HttpParameters& httpParameters,
bool verbose)
{
return request(url, "POST", httpParameters, verbose);
return request(url, "POST", extraHeaders, httpParameters, verbose);
}
std::string HttpClient::urlEncode(const std::string& value)
@ -255,48 +264,3 @@ namespace ix
return escaped.str();
}
}
#if 0
std::vector<uint8_t> rxbuf;
while (true)
{
int N = (int) _rxbuf.size();
_rxbuf.resize(N + 1500);
ssize_t ret = _socket->recv((char*)&_rxbuf[0] + N, 1500);
if (ret < 0 && (_socket->getErrno() == EWOULDBLOCK ||
_socket->getErrno() == EAGAIN)) {
_rxbuf.resize(N);
break;
}
else if (ret <= 0)
{
_rxbuf.resize(N);
_socket->close();
setReadyState(CLOSED);
break;
}
else
{
_rxbuf.resize(N + ret);
}
}
ssize_t ret = _socket->recv((char*)&rxbuf[0], contentLength);
payload = std::string(rxbuf.begin(), rxbuf.end());
std::cerr << "socket->recv: " << ret << std::endl;
if (ret != contentLength)
{
ss.str("");
ss << "Cannot retrieve all bytes"
<< " want: " << contentLength
<< ", got: " << ret;
std::cerr << "adscasdcadcasdc" << std::endl;
std::cerr << ss.str() << std::endl;
return std::make_tuple(-1, headers, payload, ss.str());
}
#endif

View File

@ -28,14 +28,18 @@ namespace ix
~HttpClient();
// Static methods ?
HttpResponse get(const std::string& url, bool verbose);
HttpResponse get(const std::string& url,
const WebSocketHttpHeaders& extraHeaders,
bool verbose);
HttpResponse post(const std::string& url,
const WebSocketHttpHeaders& extraHeaders,
const HttpParameters& httpParameters,
bool verbose);
private:
HttpResponse request(const std::string& url,
const std::string& verb,
const WebSocketHttpHeaders& extraHeaders,
const HttpParameters& httpParameters,
bool verbose);

View File

@ -18,6 +18,7 @@
namespace ix
{
int ws_http_client_main(const std::string& url,
const std::string& headers,
const std::string& data);
int ws_ping_pong_main(const std::string& url);
@ -49,6 +50,7 @@ int main(int argc, char** argv)
std::string path;
std::string user;
std::string data;
std::string headers;
int port = 8080;
CLI::App* sendApp = app.add_subcommand("send", "Send a file");
@ -82,6 +84,7 @@ int main(int argc, char** argv)
httpClientApp->add_option("url", url, "Connection url")->required();
httpClientApp->add_option("-d", data, "Form data")->join();
httpClientApp->add_option("-F", data, "Form data")->join();
httpClientApp->add_option("-H", headers, "Header")->join();
CLI11_PARSE(app, argc, argv);
@ -123,7 +126,7 @@ int main(int argc, char** argv)
else if (app.got_subcommand("http_client"))
{
std::cout << "data: " << data << std::endl;
return ix::ws_http_client_main(url, data);
return ix::ws_http_client_main(url, headers, data);
}
return 1;

View File

@ -7,9 +7,35 @@
#include <iostream>
#include <sstream>
#include <ixwebsocket/IXHttpClient.h>
#include <ixwebsocket/IXWebSocketHttpHeaders.h>
namespace ix
{
WebSocketHttpHeaders parseHeaders(const std::string& data)
{
WebSocketHttpHeaders headers;
// Split by \n
std::string token;
std::stringstream tokenStream(data);
while (std::getline(tokenStream, token))
{
std::size_t pos = token.rfind(':');
// Bail out if last '.' is found
if (pos == std::string::npos) continue;
auto key = token.substr(0, pos);
auto val = token.substr(pos+2);
std::cout << key << ": " << val << std::endl;
headers[key] = val;
}
return headers;
}
//
// Useful endpoint to test HTTP post
// https://postman-echo.com/post
@ -18,7 +44,7 @@ namespace ix
{
HttpParameters httpParameters;
// Split by ;
// Split by \n
std::string token;
std::stringstream tokenStream(data);
@ -40,27 +66,29 @@ namespace ix
}
int ws_http_client_main(const std::string& url,
const std::string& headersData,
const std::string& data)
{
HttpParameters httpParameters = parsePostParameters(data);
WebSocketHttpHeaders headers = parseHeaders(headersData);
HttpClient httpClient;
bool verbose = true;
HttpResponse out;
if (data.empty())
{
out = httpClient.get(url, verbose);
out = httpClient.get(url, headers, verbose);
}
else
{
out = httpClient.post(url, httpParameters, verbose);
out = httpClient.post(url, headers, httpParameters, verbose);
}
auto errorCode = std::get<0>(out);
auto headers = std::get<1>(out);
auto responseHeaders = std::get<1>(out);
auto payload = std::get<2>(out);
auto errorMsg = std::get<3>(out);
for (auto it : headers)
for (auto it : responseHeaders)
{
std::cout << it.first << ": " << it.second << std::endl;
}