Source release 16.4.0

This commit is contained in:
John W. Bruce
2020-10-09 16:08:56 -07:00
parent 160df9f57a
commit 9d17a531ee
562 changed files with 52913 additions and 37426 deletions

View File

@@ -21,6 +21,10 @@ const int kConnectTimeoutMs = 15000;
const int kWriteTimeoutMs = 12000;
const int kReadTimeoutMs = 12000;
const std::string kGoogleHeaderUpper("X-Google");
const std::string kGoogleHeaderLower("x-google");
const std::string kCrLf("\r\n");
// Concatenate all chunks into one blob and returns the response with
// header information.
void ConcatenateChunkedResponse(const std::string http_response,
@@ -37,7 +41,7 @@ void ConcatenateChunkedResponse(const std::string http_response,
sscanf(&http_response[chunk_size_pos], "%zx", &chunk_size);
if (chunk_size > http_response.size()) {
// precaution, in case we misread chunk size
LOGE("invalid chunk size %u", chunk_size);
LOGE("Invalid chunk size %zu", chunk_size);
return;
}
@@ -48,7 +52,6 @@ void ConcatenateChunkedResponse(const std::string http_response,
// chunk size\r\n
// chunk data\r\n
// 0\r\n
const std::string kCrLf = "\r\n";
size_t chunk_pos = http_response.find(kCrLf, chunk_size_pos);
modified_response->assign(http_response, 0, chunk_size_pos);
@@ -61,7 +64,7 @@ void ConcatenateChunkedResponse(const std::string http_response,
sscanf(&http_response[chunk_size_pos], "%zx", &chunk_size);
if (chunk_size > http_response.size()) {
// precaution, in case we misread chunk size
LOGE("invalid chunk size %u", chunk_size);
LOGE("Invalid chunk size %zu", chunk_size);
break;
}
chunk_pos = http_response.find(kCrLf, chunk_size_pos);
@@ -101,11 +104,12 @@ bool UrlRequest::GetResponse(std::string* message) {
// non-blocking mode.
while (true) {
char read_buffer[kReadBufferSize];
int bytes = socket_.Read(read_buffer, sizeof(read_buffer), kReadTimeoutMs);
const int bytes =
socket_.Read(read_buffer, sizeof(read_buffer), kReadTimeoutMs);
if (bytes > 0) {
response.append(read_buffer, bytes);
} else if (bytes < 0) {
LOGE("read error, errno = %d", errno);
LOGE("Read error, errno = %d", errno);
return false;
} else {
// end of stream.
@@ -114,7 +118,9 @@ bool UrlRequest::GetResponse(std::string* message) {
}
ConcatenateChunkedResponse(response, message);
LOGV("HTTP response: (%d): %s", message->size(), message->c_str());
LOGV("HTTP response from %s://%s:%d%s: (%zu): %s", socket_.scheme().c_str(),
socket_.domain_name().c_str(), socket_.port(),
socket_.resource_path().c_str(), message->size(), message->c_str());
return true;
}
@@ -131,6 +137,45 @@ int UrlRequest::GetStatusCode(const std::string& response) {
return status_code;
}
// static
bool UrlRequest::GetDebugHeaderFields(
const std::string& response, std::map<std::string, std::string>* fields) {
if (fields == nullptr) return false;
fields->clear();
const auto find_next = [&](size_t pos) -> size_t {
// Some of Google's HTTPS return header fields in lower case,
// this lambda will check for both and return the position that
// that is next or npos if none are found.
const size_t lower_pos = response.find(kGoogleHeaderLower, pos + 1);
const size_t upper_pos = response.find(kGoogleHeaderUpper, pos + 1);
if (lower_pos == std::string::npos) return upper_pos;
if (upper_pos == std::string::npos || lower_pos < upper_pos)
return lower_pos;
return upper_pos;
};
// Search is relatively simple, and may pick up additional matches within
// the body of the request. This is not anticiapted for the limited use
// cases of parsing provisioning/license/renewal responses.
for (size_t key_pos = find_next(0); key_pos != std::string::npos;
key_pos = find_next(key_pos)) {
const size_t end_key_pos = response.find(":", key_pos);
const size_t end_value_pos = response.find(kCrLf, key_pos);
// Skip if the colon cannot be found. Technically possible to find
// "X-Google" inside the value of a nother header field.
if (end_key_pos == std::string::npos || end_value_pos == std::string::npos)
continue;
const size_t value_pos = end_key_pos + 2;
if (end_value_pos < value_pos) continue;
const std::string key = response.substr(key_pos, end_key_pos - key_pos);
const std::string value =
response.substr(value_pos, end_value_pos - value_pos);
fields->insert({key, value});
}
return !fields->empty();
}
bool UrlRequest::PostRequestWithPath(const std::string& path,
const std::string& data) {
std::string request;
@@ -160,7 +205,7 @@ bool UrlRequest::PostRequestWithPath(const std::string& path,
const int ret =
socket_.Write(request.c_str(), request.size(), kWriteTimeoutMs);
LOGV("HTTP request: (%d): %s", request.size(), b2a_hex(request).c_str());
LOGV("HTTP request: (%zu): %s", request.size(), b2a_hex(request).c_str());
return ret != -1;
}