218 lines
5.9 KiB
C++
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));
|
|
}
|