RadioLibSmol/src/protocols/HTTP/HTTP.cpp
2019-11-20 17:19:15 +01:00

218 lines
5.9 KiB
C++

#include "HTTP.h"
HTTPClient::HTTPClient(TransportLayer* tl, uint16_t port) {
_tl = tl;
_port = port;
}
int16_t HTTPClient::get(String& url, String& response) {
return(HTTPClient::get(url.c_str(), response));
}
int16_t HTTPClient::get(const char* url, String& response) {
// get the host address and endpoint
char* httpPrefix = strstr(url, "http://");
char* endpoint;
char* host;
if(httpPrefix != NULL) {
// find the host string
char* hostStart = strchr(url, '/');
hostStart = strchr(hostStart + 1, '/');
char* hostEnd = strchr(hostStart + 1, '/');
host = new char[hostEnd - hostStart];
strncpy(host, hostStart + 1, hostEnd - hostStart - 1);
host[hostEnd - hostStart - 1] = '\0';
// find the endpoint string
endpoint = new char[url + strlen(url) - hostEnd + 1];
strcpy(endpoint, hostEnd);
} else {
// find the host string
char* hostEnd = strchr(url, '/');
host = new char[hostEnd - url + 1];
strncpy(host, url, hostEnd - url);
host[hostEnd - url] = '\0';
// find the endpoint string
endpoint = new char[url + strlen(url) - hostEnd + 1];
strcpy(endpoint, hostEnd);
}
// build the GET request
char* request = new char[strlen(endpoint) + strlen(host) + 25 + 1];
strcpy(request, "GET ");
strcat(request, endpoint);
strcat(request, " HTTP/1.1\r\nHost: ");
strcat(request, host);
strcat(request, "\r\n\r\n");
delete[] endpoint;
// create TCP connection
int16_t state = _tl->openTransportConnection(host, "TCP", _port);
delete[] host;
if(state != ERR_NONE) {
delete[] request;
return(state);
}
// send the GET request
state = _tl->send(request);
delete[] request;
if(state != ERR_NONE) {
return(state);
}
//delay(1000);
// get the response length
size_t numBytes = _tl->getNumBytes();
if(numBytes == 0) {
return(ERR_RESPONSE_MALFORMED_AT);
}
// read the response
char* raw = new char[numBytes + 1];
size_t rawLength = _tl->receive((uint8_t*)raw, numBytes);
if(rawLength == 0) {
delete[] raw;
return(ERR_RESPONSE_MALFORMED);
}
// close the tl connection
state = _tl->closeTransportConnection();
if(state != ERR_NONE) {
delete[] raw;
return(state);
}
// get the response body
char* responseStart = strstr(raw, "\r\n");
if(responseStart == NULL) {
delete[] raw;
return(ERR_RESPONSE_MALFORMED);
}
char* responseStr = new char[raw + rawLength - responseStart - 1 + 1];
strncpy(responseStr, responseStart + 2, raw + rawLength - responseStart - 1);
responseStr[raw + rawLength - responseStart - 2] = '\0';
response = String(responseStr);
delete[] responseStr;
// return the HTTP status code
char* statusStart = strchr(raw, ' ');
delete[] raw;
if(statusStart == NULL) {
return(ERR_RESPONSE_MALFORMED);
}
char statusStr[4];
strncpy(statusStr, statusStart + 1, 3);
statusStr[3] = 0x00;
return(atoi(statusStr));
}
int16_t HTTPClient::post(const char* url, const char* content, String& response, const char* contentType) {
// get the host address and endpoint
char* httpPrefix = strstr(url, "http://");
char* endpoint;
char* host;
if(httpPrefix != NULL) {
// find the host string
char* hostStart = strchr(url, '/');
hostStart = strchr(hostStart + 1, '/');
char* hostEnd = strchr(hostStart + 1, '/');
host = new char[hostEnd - hostStart];
strncpy(host, hostStart + 1, hostEnd - hostStart - 1);
host[hostEnd - hostStart - 1] = '\0';
// find the endpoint string
endpoint = new char[url + strlen(url) - hostEnd + 1];
strcpy(endpoint, hostEnd);
} else {
// find the host string
char* hostEnd = strchr(url, '/');
host = new char[hostEnd - url + 1];
strncpy(host, url, hostEnd - url);
host[hostEnd - url] = '\0';
// find the endpoint string
endpoint = new char[url + strlen(url) - hostEnd + 1];
strcpy(endpoint, hostEnd);
}
// build the POST request
char contentLengthStr[8];
itoa(strlen(content), contentLengthStr, 10);
char* request = new char[strlen(endpoint) + strlen(host) + strlen(contentType) + strlen(contentLengthStr) + strlen(content) + 64 + 1];
strcpy(request, "POST ");
strcat(request, endpoint);
strcat(request, " HTTP/1.1\r\nHost: ");
strcat(request, host);
strcat(request, "\r\nContent-Type: ");
strcat(request, contentType);
strcat(request, "\r\nContent-length: ");
strcat(request, contentLengthStr);
strcat(request, "\r\n\r\n");
strcat(request, content);
strcat(request, "\r\n\r\n");
delete[] endpoint;
// create TCP connection
int16_t state = _tl->openTransportConnection(host, "TCP", _port);
delete[] host;
if(state != ERR_NONE) {
delete[] request;
return(state);
}
// send the POST request
state = _tl->send(request);
delete[] request;
if(state != ERR_NONE) {
return(state);
}
// get the response length
size_t numBytes = _tl->getNumBytes();
if(numBytes == 0) {
return(ERR_RESPONSE_MALFORMED_AT);
}
// read the response
char* raw = new char[numBytes];
size_t rawLength = _tl->receive((uint8_t*)raw, numBytes);
if(rawLength == 0) {
delete[] raw;
return(ERR_RESPONSE_MALFORMED);
}
// close the tl connection
state = _tl->closeTransportConnection();
if(state != ERR_NONE) {
delete[] raw;
return(state);
}
// get the response body
char* responseStart = strstr(raw, "\r\n");
if(responseStart == NULL) {
delete[] raw;
return(ERR_RESPONSE_MALFORMED);
}
char* responseStr = new char[raw + rawLength - responseStart - 1];
strncpy(responseStr, responseStart + 2, raw + rawLength - responseStart - 1);
responseStr[raw + rawLength - responseStart - 2] = 0x00;
response = String(responseStr);
delete[] responseStr;
// return the HTTP status code
char* statusStart = strchr(raw, ' ');
delete[] raw;
if(statusStart == NULL) {
return(ERR_RESPONSE_MALFORMED);
}
char statusStr[4];
strncpy(statusStr, statusStart + 1, 3);
statusStr[3] = 0x00;
return(atoi(statusStr));
}