diff --git a/ixwebsocket/IXHttpClient.cpp b/ixwebsocket/IXHttpClient.cpp index c0e27681..04ee57a8 100644 --- a/ixwebsocket/IXHttpClient.cpp +++ b/ixwebsocket/IXHttpClient.cpp @@ -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 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 diff --git a/ixwebsocket/IXHttpClient.h b/ixwebsocket/IXHttpClient.h index 48cf640c..1e10a92d 100644 --- a/ixwebsocket/IXHttpClient.h +++ b/ixwebsocket/IXHttpClient.h @@ -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); diff --git a/ws/ws.cpp b/ws/ws.cpp index 2dbb9e9d..f334fd76 100644 --- a/ws/ws.cpp +++ b/ws/ws.cpp @@ -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; diff --git a/ws/ws_http_client.cpp b/ws/ws_http_client.cpp index 37a3a388..88cf3d5c 100644 --- a/ws/ws_http_client.cpp +++ b/ws/ws_http_client.cpp @@ -7,9 +7,35 @@ #include #include #include +#include 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; }