Browse Source

make version public, optional postBody field (POST Support)

master
Odilitime 5 years ago
parent
commit
4933c42dee
  1. 21
      src/networking/HTTPRequest.cpp
  2. 6
      src/networking/HTTPRequest.h
  3. 23
      src/networking/HTTPSRequest.cpp
  4. 8
      src/networking/HTTPSRequest.h

21
src/networking/HTTPRequest.cpp

@ -37,11 +37,14 @@ HTTPRequest::HTTPRequest(const std::shared_ptr<URL> u) { @@ -37,11 +37,14 @@ HTTPRequest::HTTPRequest(const std::shared_ptr<URL> u) {
userAgent = "NetRunner";
}
bool HTTPRequest::sendRequest(std::function<void(const HTTPResponse&)> responseCallback) const {
bool HTTPRequest::sendRequest(std::function<void(const HTTPResponse&)> responseCallback, std::unique_ptr<std::string> ptrPostBody) const {
struct addrinfo hints;
struct addrinfo *serverInfo = nullptr;
std::string host = uri->host;
std::string document = uri->path;
if (uri->query != "") {
document += "?" + uri->query;
}
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
@ -65,8 +68,20 @@ bool HTTPRequest::sendRequest(std::function<void(const HTTPResponse&)> responseC @@ -65,8 +68,20 @@ bool HTTPRequest::sendRequest(std::function<void(const HTTPResponse&)> responseC
freeaddrinfo(serverInfo);
return false;
}
std::string postBody = "";
if (ptrPostBody) {
// The moral of the story is, if you have binary (non-alphanumeric) data (or a significantly sized payload) to transmit, use multipart/form-data
std::string fixedPostBody(*ptrPostBody);
auto search = fixedPostBody.find(" ");
if (search != std::string::npos) {
fixedPostBody.replace(search, 1, "+");
}
// close userAgent
postBody = "\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: " + std::to_string(fixedPostBody.size())+ "\r\n\r\n" + fixedPostBody;
}
const std::string request = methodToString(method) + std::string(" ") + document + std::string(" ") + versionToString(version) + std::string("\r\nHost: ") + host + std::string("\r\nUser-Agent: ") + userAgent + std::string("\r\n\r\n");
const std::string request = methodToString(method) + std::string(" ") + document + std::string(" ") + versionToString(version) + std::string("\r\nHost: ") + host + std::string("\r\nUser-Agent: ") + userAgent + postBody + std::string("\r\n\r\n");
std::cout << "HTTP Request: " << request << std::endl;
const ssize_t sent = send(sock, request.c_str(), request.length(), 0);
if (sent == -1) {
std::cout << "Could not send \"" << request << "\": " << errno << std::endl;
@ -91,6 +106,8 @@ const std::string HTTPRequest::versionToString(const Version ver) const { @@ -91,6 +106,8 @@ const std::string HTTPRequest::versionToString(const Version ver) const {
switch (ver) {
case Version::HTTP10:
return "HTTP/1.0";
case Version::HTTP11:
return "HTTP/1.1";
default:
return "ERROR";
}

6
src/networking/HTTPRequest.h

@ -10,12 +10,12 @@ @@ -10,12 +10,12 @@
class HTTPRequest {
public:
HTTPRequest(const std::shared_ptr<URL> u);
bool sendRequest(std::function<void(const HTTPResponse&)> responseCallback) const;
bool sendRequest(std::function<void(const HTTPResponse&)> responseCallback, std::unique_ptr<std::string> ptrPostBody) const;
const std::string versionToString(const Version version) const;
const std::string methodToString(const Method method) const;
private:
Version version;
Method method;
Version version;
private:
std::string userAgent;
std::shared_ptr<URL> uri;
};

23
src/networking/HTTPSRequest.cpp

@ -22,9 +22,12 @@ HTTPSRequest::HTTPSRequest(const std::shared_ptr<URL> u) { @@ -22,9 +22,12 @@ HTTPSRequest::HTTPSRequest(const std::shared_ptr<URL> u) {
userAgent = "NetRunner/0.1 PolarSSL/2.5.1";
}
bool HTTPSRequest::sendRequest(std::function<void(const HTTPResponse&)> responseCallback) const {
bool HTTPSRequest::sendRequest(std::function<void(const HTTPResponse&)> responseCallback, std::unique_ptr<std::string> ptrPostBody) const {
std::string response;
std::string document = uri->path;
if (uri->query != "") {
document += "?" + uri->query;
}
std::string host = uri->host;
std::string port = std::to_string(uri->port);
@ -66,9 +69,21 @@ bool HTTPSRequest::sendRequest(std::function<void(const HTTPResponse&)> response @@ -66,9 +69,21 @@ bool HTTPSRequest::sendRequest(std::function<void(const HTTPResponse&)> response
printf("Invalid server cert!");
return false;
}
std::string postBody = "";
if (ptrPostBody) {
// The moral of the story is, if you have binary (non-alphanumeric) data (or a significantly sized payload) to transmit, use multipart/form-data
std::string fixedPostBody(*ptrPostBody);
auto search = fixedPostBody.find(" ");
if (search != std::string::npos) {
fixedPostBody.replace(search, 1, "+");
}
// close userAgent
postBody = "\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: " + std::to_string(fixedPostBody.size())+ "\r\n\r\n" + fixedPostBody;
}
const std::string request = methodToString(method) + std::string(" ") + document + std::string(" ") + versionToString(version) + std::string("\r\nHost: ") + host + std::string("\r\nUser-Agent: ") + userAgent + std::string("\r\n\r\n");
const std::string request = methodToString(method) + std::string(" ") + document + std::string(" ") + versionToString(version) + std::string("\r\nHost: ") + host + std::string("\r\nUser-Agent: ") + userAgent + postBody + std::string("\r\n\r\n");
std::cout << "HTTPS Request: " << request << std::endl;
while( ( state = mbedtls_ssl_write( &ssl, reinterpret_cast<const unsigned char*>(request.c_str()), request.length() ) ) <= 0 ){
if( state != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ){
printf( " failed\n ! mbedtls_ssl_write returned %d\n\n", state );
@ -103,6 +118,8 @@ const std::string HTTPSRequest::versionToString(const Version ver) const { @@ -103,6 +118,8 @@ const std::string HTTPSRequest::versionToString(const Version ver) const {
switch (ver) {
case Version::HTTP10:
return "HTTP/1.0";
case Version::HTTP11:
return "HTTP/1.1";
default:
return "ERROR";
}

8
src/networking/HTTPSRequest.h

@ -19,16 +19,18 @@ @@ -19,16 +19,18 @@
#include <mbedtls/error.h>
#include <mbedtls/certs.h>
// FIXME: needs to extend HTTPRequest
class HTTPSRequest {
public:
HTTPSRequest(const std::shared_ptr<URL> u);
bool sendRequest(std::function<void(const HTTPResponse&)> responseCallback) const;
bool sendRequest(std::function<void(const HTTPResponse&)> responseCallback, std::unique_ptr<std::string> ptrPostBody) const;
const std::string versionToString(const Version version) const;
const std::string methodToString(const Method method) const;
bool initTLS();
private:
Version version;
// has to be public, otherwise how are we going to change it
Method method;
Version version;
private:
std::string userAgent;
std::shared_ptr<URL> uri;
};

Loading…
Cancel
Save