|
@@ -13,9 +13,7 @@ void HTTPClient::HTTPResponse::close() {
|
|
bufPtr = nullptr;
|
|
bufPtr = nullptr;
|
|
}
|
|
}
|
|
HTTPClient::HTTPResponse::~HTTPResponse() {
|
|
HTTPClient::HTTPResponse::~HTTPResponse() {
|
|
- socket = nullptr;
|
|
|
|
- if (buf)
|
|
|
|
- free(buf);
|
|
|
|
|
|
+ this->close();
|
|
}
|
|
}
|
|
|
|
|
|
HTTPResponse_t HTTPClient::execute(const struct HTTPRequest &request) {
|
|
HTTPResponse_t HTTPClient::execute(const struct HTTPRequest &request) {
|
|
@@ -70,10 +68,12 @@ HTTPResponse_t HTTPClient::executeImpl(const struct HTTPRequest &request, HTTPRe
|
|
stream << header.first << ": " << header.second << endl;
|
|
stream << header.first << ": " << header.second << endl;
|
|
}
|
|
}
|
|
stream << endl;
|
|
stream << endl;
|
|
- stream << request.body;
|
|
|
|
|
|
+ if (request.body != nullptr) {
|
|
|
|
+ stream << request.body;
|
|
|
|
+ }
|
|
std::string data = stream.str();
|
|
std::string data = stream.str();
|
|
|
|
|
|
- size_t len = response->socket->write((uint8_t *)data.c_str(), data.size());
|
|
|
|
|
|
+ uint32_t len = response->socket->write((uint8_t *)data.c_str(), data.size());
|
|
if (len != data.size()) {
|
|
if (len != data.size()) {
|
|
response->close();
|
|
response->close();
|
|
BELL_LOG(error, "http", "Writing failed: wrote %d of %d bytes", len, data.size());
|
|
BELL_LOG(error, "http", "Writing failed: wrote %d of %d bytes", len, data.size());
|
|
@@ -91,7 +91,7 @@ HTTPResponse_t HTTPClient::executeImpl(const struct HTTPRequest &request, HTTPRe
|
|
}
|
|
}
|
|
|
|
|
|
bool HTTPClient::readHeader(const char *&header, const char *name) {
|
|
bool HTTPClient::readHeader(const char *&header, const char *name) {
|
|
- size_t len = strlen(name);
|
|
|
|
|
|
+ uint32_t len = strlen(name);
|
|
if (strncasecmp(header, name, len) == 0) {
|
|
if (strncasecmp(header, name, len) == 0) {
|
|
header += len;
|
|
header += len;
|
|
while (*header == ' ')
|
|
while (*header == ' ')
|
|
@@ -101,8 +101,13 @@ bool HTTPClient::readHeader(const char *&header, const char *name) {
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
-size_t HTTPClient::HTTPResponse::readRaw(char *dst) {
|
|
|
|
- size_t len = this->socket->read((uint8_t *)dst, BUF_SIZE);
|
|
|
|
|
|
+uint32_t HTTPClient::HTTPResponse::readRaw(char *dst) {
|
|
|
|
+ if (!this->socket)
|
|
|
|
+ return 0; // socket is already closed, I guess
|
|
|
|
+ uint32_t len = this->socket->read((uint8_t *)dst, BUF_SIZE);
|
|
|
|
+ if (len == 0 || len == -1) {
|
|
|
|
+ isComplete = true;
|
|
|
|
+ }
|
|
if (dumpRawFs)
|
|
if (dumpRawFs)
|
|
dumpRawFs->write(dst, (long)len);
|
|
dumpRawFs->write(dst, (long)len);
|
|
// BELL_LOG(debug, "http", "Read %d bytes", len);
|
|
// BELL_LOG(debug, "http", "Read %d bytes", len);
|
|
@@ -111,7 +116,7 @@ size_t HTTPClient::HTTPResponse::readRaw(char *dst) {
|
|
}
|
|
}
|
|
|
|
|
|
void HTTPClient::HTTPResponse::readHeaders() {
|
|
void HTTPClient::HTTPResponse::readHeaders() {
|
|
- size_t len;
|
|
|
|
|
|
+ uint32_t len;
|
|
char *line, *lineEnd;
|
|
char *line, *lineEnd;
|
|
bool complete = false;
|
|
bool complete = false;
|
|
std::string lineBuf;
|
|
std::string lineBuf;
|
|
@@ -185,8 +190,8 @@ void HTTPClient::HTTPResponse::readHeaders() {
|
|
} while (!complete && len); // if len == 0, the connection is closed
|
|
} while (!complete && len); // if len == 0, the connection is closed
|
|
}
|
|
}
|
|
|
|
|
|
-bool HTTPClient::HTTPResponse::skipRaw(size_t len, bool dontRead) {
|
|
|
|
- size_t skip = 0;
|
|
|
|
|
|
+bool HTTPClient::HTTPResponse::skipRaw(uint32_t len, bool dontRead) {
|
|
|
|
+ uint32_t skip = 0;
|
|
if (len > bufRemaining) {
|
|
if (len > bufRemaining) {
|
|
skip = len - bufRemaining;
|
|
skip = len - bufRemaining;
|
|
len = bufRemaining;
|
|
len = bufRemaining;
|
|
@@ -211,16 +216,17 @@ bool HTTPClient::HTTPResponse::skipRaw(size_t len, bool dontRead) {
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
-size_t HTTPClient::HTTPResponse::read(char *dst, size_t toRead, bool wait) {
|
|
|
|
|
|
+uint32_t HTTPClient::HTTPResponse::read(char *dst, uint32_t toRead, bool wait) {
|
|
if (isComplete) {
|
|
if (isComplete) {
|
|
// end of chunked stream was found OR complete body was read
|
|
// end of chunked stream was found OR complete body was read
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
auto *dstStart = dst ? dst : nullptr;
|
|
auto *dstStart = dst ? dst : nullptr;
|
|
- size_t read = 0;
|
|
|
|
|
|
+ uint32_t read = 0;
|
|
while (toRead) { // this loop ends after original toRead
|
|
while (toRead) { // this loop ends after original toRead
|
|
skipRaw(0); // ensure the buffer contains data, wait if necessary
|
|
skipRaw(0); // ensure the buffer contains data, wait if necessary
|
|
if (isChunked && !chunkRemaining) {
|
|
if (isChunked && !chunkRemaining) {
|
|
|
|
+ // chunked responses (either streaming or not)
|
|
if (*bufPtr == '0') { // all chunks were read *and emitted*
|
|
if (*bufPtr == '0') { // all chunks were read *and emitted*
|
|
isComplete = true;
|
|
isComplete = true;
|
|
break;
|
|
break;
|
|
@@ -241,11 +247,15 @@ size_t HTTPClient::HTTPResponse::read(char *dst, size_t toRead, bool wait) {
|
|
if (!skipRaw(endPtr - bufPtr + 2)) // skip the size and \r\n
|
|
if (!skipRaw(endPtr - bufPtr + 2)) // skip the size and \r\n
|
|
break; // -> no more data, break out of main loop
|
|
break; // -> no more data, break out of main loop
|
|
} else if (contentLength && !chunkRemaining) {
|
|
} else if (contentLength && !chunkRemaining) {
|
|
|
|
+ // normal responses (having content-length)
|
|
chunkRemaining = contentLength;
|
|
chunkRemaining = contentLength;
|
|
|
|
+ } else if (!chunkRemaining) {
|
|
|
|
+ // fallback for non-chunked streams (without content-length)
|
|
|
|
+ chunkRemaining = toRead;
|
|
}
|
|
}
|
|
|
|
|
|
while (chunkRemaining && toRead) {
|
|
while (chunkRemaining && toRead) {
|
|
- size_t count = std::min(toRead, std::min(bufRemaining, chunkRemaining));
|
|
|
|
|
|
+ uint32_t count = std::min(toRead, std::min(bufRemaining, chunkRemaining));
|
|
if (dst) {
|
|
if (dst) {
|
|
memcpy(dst, bufPtr, count);
|
|
memcpy(dst, bufPtr, count);
|
|
dst += count; // move the dst pointer
|
|
dst += count; // move the dst pointer
|
|
@@ -287,8 +297,8 @@ std::string HTTPClient::HTTPResponse::readToString() {
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
std::string result;
|
|
std::string result;
|
|
- char buffer[BUF_SIZE+1]; // make space for null-terminator
|
|
|
|
- size_t len;
|
|
|
|
|
|
+ char buffer[BUF_SIZE + 1]; // make space for null-terminator
|
|
|
|
+ uint32_t len;
|
|
do {
|
|
do {
|
|
len = this->read(buffer, BUF_SIZE);
|
|
len = this->read(buffer, BUF_SIZE);
|
|
buffer[len] = '\0';
|
|
buffer[len] = '\0';
|