Skip to content

Commit

Permalink
HttpClient: memory usage fixes. (SmingHub#1161)
Browse files Browse the repository at this point in the history
Related to SmingHub#1138.
  • Loading branch information
slaff authored Jun 19, 2017
1 parent 68c0df1 commit f6c1199
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 35 deletions.
63 changes: 29 additions & 34 deletions Sming/SmingCore/Network/Http/HttpConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,26 @@

HttpConnection::HttpConnection(RequestQueue* queue): TcpClient(false), mode(eHCM_String) {
this->waitingQueue = queue;

http_parser_init(&parser, HTTP_RESPONSE);
parser.data = (void*)this;

memset(&parserSettings, 0, sizeof(parserSettings));

// Notification callbacks: on_message_begin, on_headers_complete, on_message_complete.
parserSettings.on_message_begin = staticOnMessageBegin;
parserSettings.on_headers_complete = staticOnHeadersComplete;
parserSettings.on_message_complete = staticOnMessageComplete;

parserSettings.on_chunk_header = staticOnChunkHeader;
parserSettings.on_chunk_complete = staticOnChunkComplete;


// Data callbacks: on_url, (common) on_header_field, on_header_value, on_body;
parserSettings.on_status = staticOnStatus;
parserSettings.on_header_field = staticOnHeaderField;
parserSettings.on_header_value = staticOnHeaderValue;
parserSettings.on_body = staticOnBody;
}

bool HttpConnection::connect(const String& host, int port, bool useSsl /* = false */, uint32_t sslOptions /* = 0 */) {
Expand Down Expand Up @@ -112,7 +132,9 @@ void HttpConnection::reset()
}

code = 0;
responseStringData = "";
if(responseStringData.length()) {
responseStringData = "";
}
responseHeaders.clear();

lastWasValue = true;
Expand Down Expand Up @@ -324,34 +346,12 @@ int HttpConnection::staticOnChunkComplete(http_parser* parser) {

err_t HttpConnection::onConnected(err_t err) {
if (err == ERR_OK) {
// create parser ...
if(parser == NULL) {
parser = new http_parser;
http_parser_init(parser, HTTP_RESPONSE);
parser->data = (void*)this;

memset(&parserSettings, 0, sizeof(parserSettings));
// Notification callbacks: on_message_begin, on_headers_complete, on_message_complete.
parserSettings.on_message_begin = staticOnMessageBegin;
parserSettings.on_headers_complete = staticOnHeadersComplete;
parserSettings.on_message_complete = staticOnMessageComplete;

parserSettings.on_chunk_header = staticOnChunkHeader;
parserSettings.on_chunk_complete = staticOnChunkComplete;


// Data callbacks: on_url, (common) on_header_field, on_header_value, on_body;
parserSettings.on_status = staticOnStatus;
parserSettings.on_header_field = staticOnHeaderField;
parserSettings.on_header_value = staticOnHeaderValue;
parserSettings.on_body = staticOnBody;
}

debugf("HttpConnection::onConnected: waitingQueue.count: %d", waitingQueue->count());

do {
HttpRequest* request = waitingQueue->peek();
if(request == NULL) {
debugf("Nothing in the waiting queue");
break;
}

Expand Down Expand Up @@ -511,10 +511,10 @@ err_t HttpConnection::onReceive(pbuf *buf) {
pbuf *cur = buf;
int parsedBytes = 0;
while (cur != NULL && cur->len > 0) {
parsedBytes += http_parser_execute(parser, &parserSettings, (char*) cur->payload, cur->len);
if(HTTP_PARSER_ERRNO(parser) != HPE_OK) {
parsedBytes += http_parser_execute(&parser, &parserSettings, (char*) cur->payload, cur->len);
if(HTTP_PARSER_ERRNO(&parser) != HPE_OK) {
// we ran into trouble - abort the connection
debugf("HTTP parser error: %s", http_errno_name(HTTP_PARSER_ERRNO(parser)));
debugf("HTTP parser error: %s", http_errno_name(HTTP_PARSER_ERRNO(&parser)));
cleanup();
TcpConnection::onReceive(NULL);
return ERR_ABRT;
Expand All @@ -523,8 +523,8 @@ err_t HttpConnection::onReceive(pbuf *buf) {
cur = cur->next;
}

if (parser->upgrade) {
return onProtocolUpgrade(parser);
if (parser.upgrade) {
return onProtocolUpgrade(&parser);
} else if (parsedBytes != buf->tot_len) {
TcpClient::onReceive(NULL);

Expand Down Expand Up @@ -552,11 +552,6 @@ void HttpConnection::cleanup() {
for(int i=0; i < executionQueue.count(); i++) {
waitingQueue->enqueue(executionQueue.dequeue());
}

if(parser != NULL) {
delete parser;
parser = NULL;
}
}

HttpConnection::~HttpConnection() {
Expand Down
2 changes: 1 addition & 1 deletion Sming/SmingCore/Network/Http/HttpConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class HttpConnection : protected TcpClient {

RequestQueue* waitingQueue;
RequestQueue executionQueue;
http_parser *parser = NULL;
http_parser parser;
http_parser_settings parserSettings;
HttpHeaders responseHeaders;

Expand Down
3 changes: 3 additions & 0 deletions Sming/SmingCore/Network/HttpClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ bool HttpClient::send(HttpRequest* request) {
if(!queue[cacheKey]->enqueue(request)) {
// the queue is full and we cannot add more requests at the time.
debugf("The request queue is full at the moment");
delete request;
return false;
}

Expand All @@ -34,6 +35,8 @@ bool HttpClient::send(HttpRequest* request) {

debugf("Removing stale connection: State: %d, Active: %d", (int)httpConnectionPool[cacheKey]->getConnectionState(),
(httpConnectionPool[cacheKey]->isActive() ? 1: 0));
delete httpConnectionPool[cacheKey];
httpConnectionPool[cacheKey] = NULL;
httpConnectionPool.remove(cacheKey);
}

Expand Down
10 changes: 10 additions & 0 deletions Sming/SmingCore/Network/HttpClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,17 @@ class HttpClient
bool downloadFile(const String& url, const String& saveFileName, RequestCompletedDelegate requestComplete = NULL);

/* Low Level Methods */

/*
* @brief This method queues a request and sends it, once it is connected to the remote server.
* @param HttpRequest* request The request object will be freed inside of the method.
* Do not try to reuse it outside of the send method as it will lead to unpredicted results
*
* @retval bool true if the request was queued, false otherwise.
*
*/
bool send(HttpRequest* request);

HttpRequest* request(const String& url);

#ifdef ENABLE_SSL
Expand Down

0 comments on commit f6c1199

Please sign in to comment.