in src/discovery/Discovery.cpp [80:215]
ResponseCode DiscoverAction::ReadResponseFromNetwork(std::shared_ptr<NetworkConnection> p_network_connection,
util::String &sent_packet,
util::String &read_payload,
std::chrono::milliseconds max_response_wait_time) {
ResponseCode rc;
util::Vector<unsigned char> temp_buf;
util::Vector<unsigned char> read_buf;
bool received_crlf = false;
size_t read_bytes = 0;
auto max_wait = std::chrono::steady_clock::now() + max_response_wait_time;
do {
rc = ReadFromNetworkBuffer(p_network_connection, temp_buf, 1);
if (ResponseCode::SUCCESS == rc) {
read_bytes++;
read_buf.push_back(temp_buf[0]);
if ((read_bytes > 1) && read_buf[read_bytes - 1] == '\n' && read_buf[read_bytes - 2] == '\r') {
received_crlf = true;
}
}
if (std::chrono::steady_clock::now() > max_wait) {
rc = ResponseCode::DISCOVER_ACTION_REQUEST_TIMED_OUT_ERROR;
break;
}
} while (!received_crlf);
if (ResponseCode::SUCCESS != rc) {
return rc;
}
received_crlf = false;
read_bytes = 0;
// Parse header
util::String response_header(read_buf.begin(), read_buf.end());
if (util::String::npos == response_header.find(DISCOVER_ACTION_EXPECTED_SUCCESS_RESPONSE)) {
if (util::String::npos != response_header.find(DISCOVER_ACTION_FAIL_INFO_NOT_PRESENT)) {
return ResponseCode::DISCOVER_ACTION_NO_INFORMATION_PRESENT;
} else if (util::String::npos != response_header.find(DISCOVER_ACTION_FAIL_TOO_MANY_REQUESTS)) {
return ResponseCode::DISCOVER_ACTION_REQUEST_OVERLOAD;
} else if (util::String::npos != response_header.find(DISCOVER_ACTION_FAIL_UNAUTHORIZED)) {
return ResponseCode::DISCOVER_ACTION_UNAUTHORIZED;
} else {
AWS_LOG_ERROR(DISCOVER_LOG_TAG, "Discover Action HTTP request failed with a Response Header : \n%s",
response_header.c_str());
return ResponseCode::DISCOVER_ACTION_SERVER_ERROR;
}
}
util::String content_length_string(HTTP_CONTENT_LENGTH_STRING);
size_t content_length_index = std::string::npos;
read_buf.clear();
do {
rc = ReadFromNetworkBuffer(p_network_connection, temp_buf, 1);
if (ResponseCode::SUCCESS != rc) {
break;
}
read_bytes++;
read_buf.push_back(temp_buf[0]);
if ((read_bytes > 1) && read_buf[read_bytes - 1] == '\n' && read_buf[read_bytes - 2] == '\r') {
util::String header_line(read_buf.begin(), read_buf.end());
content_length_index = header_line.find(content_length_string);
if (util::String::npos == content_length_index) {
read_buf.clear();
read_bytes = 0;
continue;
}
received_crlf = true;
}
if (std::chrono::steady_clock::now() > max_wait) {
rc = ResponseCode::DISCOVER_ACTION_REQUEST_TIMED_OUT_ERROR;
break;
}
} while (!received_crlf);
if (content_length_index == std::string::npos) {
if (ResponseCode::SUCCESS != rc) {
return rc;
}
return ResponseCode::DISCOVER_ACTION_NO_INFORMATION_PRESENT;
}
size_t content_length_begin_offset = content_length_index + content_length_string.length();
size_t content_length_end_offset = content_length_begin_offset;
while ('\r' != (char) read_buf[content_length_end_offset]) {
content_length_end_offset++;
}
util::String content_length_str
(read_buf.begin() + content_length_begin_offset, read_buf.begin() + content_length_end_offset);
size_t content_length = std::stoul(content_length_str);
// Skip the rest of the header
received_crlf = false;
do {
rc = ReadFromNetworkBuffer(p_network_connection, temp_buf, 1);
if (ResponseCode::SUCCESS != rc) {
break;
}
read_bytes++;
read_buf.push_back(temp_buf[0]);
if ((read_bytes > 1) && read_buf[read_bytes - 1] == '\n' && read_buf[read_bytes - 2] == '\r'
&& read_buf[read_bytes - 3] == '\n' && read_buf[read_bytes - 4] == '\r') {
received_crlf = true;
}
if (std::chrono::steady_clock::now() > max_wait) {
rc = ResponseCode::DISCOVER_ACTION_REQUEST_TIMED_OUT_ERROR;
break;
}
} while (!received_crlf);
read_buf.clear();
if (0 < content_length) {
rc = ReadFromNetworkBuffer(p_network_connection, read_buf, content_length);
if (ResponseCode::SUCCESS == rc) {
read_payload.append(read_buf.begin(), read_buf.end());
size_t received_len = read_payload.length();
IOT_UNUSED(received_len);
read_buf.clear();
}
} else {
rc = ResponseCode::DISCOVER_ACTION_REQUEST_FAILED_ERROR;
}
return rc;
}