Source release v2.1.2-0-773 + third_party libs
Change-Id: Ia07608577b65b301c22a8ff4bf7f743c2d3f9274
This commit is contained in:
@@ -10,52 +10,16 @@
|
||||
#include "string_conversions.h"
|
||||
|
||||
namespace {
|
||||
const int kMaxReadAttempts = 4;
|
||||
const int kSingleReadAttempt = 1;
|
||||
} // namespace
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
UrlRequest::UrlRequest(const std::string& url, const std::string& port,
|
||||
bool secure_connection, bool chunk_transfer_mode)
|
||||
: chunk_transfer_mode_(chunk_transfer_mode),
|
||||
is_connected_(false),
|
||||
port_("80"),
|
||||
request_(""),
|
||||
server_url_(url) {
|
||||
if (!port.empty()) {
|
||||
port_.assign(port);
|
||||
}
|
||||
if (socket_.Connect((server_url_).c_str(), port_, true, secure_connection)) {
|
||||
is_connected_ = true;
|
||||
} else {
|
||||
LOGE("failed to connect to %s, port=%s", socket_.domain_name().c_str(),
|
||||
port.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
UrlRequest::~UrlRequest() { socket_.CloseSocket(); }
|
||||
|
||||
void UrlRequest::AppendChunkToUpload(const std::string& data) {
|
||||
// format of chunk:
|
||||
// size of chunk in hex\r\n
|
||||
// data\r\n
|
||||
// . . .
|
||||
// 0\r\n
|
||||
|
||||
// buffer to store length of chunk
|
||||
memset(buffer_, 0, kHttpBufferSize);
|
||||
snprintf(buffer_, kHttpBufferSize, "%zx\r\n", data.size());
|
||||
request_.append(buffer_); // appends size of chunk
|
||||
LOGD("...\r\n%s", request_.c_str());
|
||||
request_.append(data);
|
||||
request_.append("\r\n"); // marks end of data
|
||||
}
|
||||
const int kReadBufferSize = 1024;
|
||||
const int kConnectTimeoutMs = 5000;
|
||||
const int kWriteTimeoutMs = 3000;
|
||||
const int kReadTimeoutMs = 3000;
|
||||
|
||||
// Concatenate all chunks into one blob and returns the response with
|
||||
// header information.
|
||||
void UrlRequest::ConcatenateChunkedResponse(const std::string http_response,
|
||||
std::string* modified_response) {
|
||||
void ConcatenateChunkedResponse(const std::string http_response,
|
||||
std::string* modified_response) {
|
||||
if (http_response.empty()) return;
|
||||
|
||||
modified_response->clear();
|
||||
@@ -103,33 +67,52 @@ void UrlRequest::ConcatenateChunkedResponse(const std::string http_response,
|
||||
}
|
||||
}
|
||||
|
||||
int UrlRequest::GetResponse(std::string* message) {
|
||||
message->clear();
|
||||
} // namespace
|
||||
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
UrlRequest::UrlRequest(const std::string& url)
|
||||
: is_connected_(false),
|
||||
socket_(url) {
|
||||
if (socket_.Connect(kConnectTimeoutMs)) {
|
||||
is_connected_ = true;
|
||||
} else {
|
||||
LOGE("failed to connect to %s, port=%d", socket_.domain_name().c_str(),
|
||||
socket_.port());
|
||||
}
|
||||
}
|
||||
|
||||
UrlRequest::~UrlRequest() {}
|
||||
|
||||
bool UrlRequest::GetResponse(std::string* message) {
|
||||
std::string response;
|
||||
const int kTimeoutInMs = 3000;
|
||||
int bytes = 0;
|
||||
for (int attempts = kMaxReadAttempts; attempts > 0; --attempts) {
|
||||
memset(buffer_, 0, kHttpBufferSize);
|
||||
bytes = socket_.Read(buffer_, kHttpBufferSize, kTimeoutInMs);
|
||||
|
||||
// Keep reading until end of stream (0 bytes read) or timeout. Partial
|
||||
// buffers worth of data can and do happen, especially with OpenSSL in
|
||||
// non-blocking mode.
|
||||
while (true) {
|
||||
char read_buffer[kReadBufferSize];
|
||||
int bytes = socket_.Read(read_buffer, sizeof(read_buffer), kReadTimeoutMs);
|
||||
if (bytes > 0) {
|
||||
response.append(buffer_, bytes);
|
||||
if (bytes < static_cast<int>(kHttpBufferSize)) {
|
||||
attempts = kSingleReadAttempt;
|
||||
}
|
||||
response.append(read_buffer, bytes);
|
||||
} else if (bytes < 0) {
|
||||
LOGE("read error, errno = %d", errno);
|
||||
return false;
|
||||
} else {
|
||||
if (bytes < 0) LOGE("read error = ", errno);
|
||||
// bytes == 0 indicates nothing to read
|
||||
// end of stream.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ConcatenateChunkedResponse(response, message);
|
||||
LOGD("HTTP response: (%d): %s", message->size(), b2a_hex(*message).c_str());
|
||||
return message->size();
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
int UrlRequest::GetStatusCode(const std::string& response) {
|
||||
const std::string kHttpVersion("HTTP/1.1");
|
||||
const std::string kHttpVersion("HTTP/1.1 ");
|
||||
|
||||
int status_code = -1;
|
||||
size_t pos = response.find(kHttpVersion);
|
||||
@@ -140,79 +123,48 @@ int UrlRequest::GetStatusCode(const std::string& response) {
|
||||
return status_code;
|
||||
}
|
||||
|
||||
bool UrlRequest::PostRequestChunk(const std::string& data) {
|
||||
request_.assign("POST /");
|
||||
request_.append(socket_.resource_path());
|
||||
request_.append(" HTTP/1.1\r\n");
|
||||
request_.append("Host: ");
|
||||
request_.append(socket_.domain_name());
|
||||
request_.append("\r\nConnection: Keep-Alive\r\n");
|
||||
request_.append("Transfer-Encoding: chunked\r\n");
|
||||
request_.append("User-Agent: Widevine CDM v1.0\r\n");
|
||||
request_.append("Accept-Encoding: gzip,deflate\r\n");
|
||||
request_.append("Accept-Language: en-us,fr\r\n");
|
||||
request_.append("Accept-Charset: iso-8859-1,*,utf-8\r\n");
|
||||
request_.append("\r\n"); // empty line to terminate header
|
||||
bool UrlRequest::PostRequestWithPath(const std::string& path,
|
||||
const std::string& data) {
|
||||
std::string request;
|
||||
|
||||
// calls AppendChunkToUpload repeatedly for multiple chunks
|
||||
AppendChunkToUpload(data);
|
||||
request.append("POST ");
|
||||
request.append(path);
|
||||
request.append(" HTTP/1.1\r\n");
|
||||
|
||||
// terminates last chunk with 0\r\n, then ends header with an empty line
|
||||
request_.append("0\r\n\r\n");
|
||||
request.append("Host: ");
|
||||
request.append(socket_.domain_name());
|
||||
request.append("\r\n");
|
||||
|
||||
socket_.Write(request_.c_str(), request_.size());
|
||||
return true;
|
||||
request.append("Connection: close\r\n");
|
||||
request.append("User-Agent: Widevine CDM v1.0\r\n");
|
||||
|
||||
// buffer to store length of data as a string
|
||||
char data_size_buffer[32] = {0};
|
||||
snprintf(data_size_buffer, sizeof(data_size_buffer), "%zd", data.size());
|
||||
|
||||
request.append("Content-Length: ");
|
||||
request.append(data_size_buffer); // appends size of data
|
||||
request.append("\r\n");
|
||||
|
||||
request.append("\r\n"); // empty line to terminate headers
|
||||
|
||||
request.append(data);
|
||||
|
||||
int ret = socket_.Write(request.c_str(), request.size(), kWriteTimeoutMs);
|
||||
LOGD("HTTP request: (%d): %s", request.size(), b2a_hex(request).c_str());
|
||||
return ret != -1;
|
||||
}
|
||||
|
||||
bool UrlRequest::PostRequest(const std::string& data) {
|
||||
if (chunk_transfer_mode_) {
|
||||
return PostRequestChunk(data);
|
||||
}
|
||||
request_.assign("POST /");
|
||||
request_.append(socket_.resource_path());
|
||||
request_.append(" HTTP/1.1\r\n");
|
||||
request_.append("Host: ");
|
||||
request_.append(socket_.domain_name());
|
||||
request_.append("\r\nConnection: Keep-Alive\r\n");
|
||||
request_.append("User-Agent: Widevine CDM v1.0\r\n");
|
||||
request_.append("Accept-Encoding: gzip,deflate\r\n");
|
||||
request_.append("Accept-Language: en-us,fr\r\n");
|
||||
request_.append("Accept-Charset: iso-8859-1,*,utf-8\r\n");
|
||||
std::ostringstream ss;
|
||||
ss << data.size();
|
||||
request_.append("Content-Length: ");
|
||||
request_.append(ss.str());
|
||||
request_.append("\r\n\r\n");
|
||||
request_.append(data);
|
||||
|
||||
// terminates with \r\n, then ends with an empty line
|
||||
request_.append("\r\n\r\n");
|
||||
|
||||
socket_.Write(request_.c_str(), request_.size());
|
||||
LOGD("HTTP request: (%d): %s", request_.size(), request_.c_str());
|
||||
LOGD("HTTP request: (%d): %s", request_.size(), b2a_hex(request_).c_str());
|
||||
return true;
|
||||
return PostRequestWithPath(socket_.resource_path(), data);
|
||||
}
|
||||
|
||||
bool UrlRequest::PostCertRequestInQueryString(const std::string& data) {
|
||||
request_.assign("POST /");
|
||||
request_.append(socket_.resource_path());
|
||||
request_.append("&signedRequest=");
|
||||
request_.append(data);
|
||||
request_.append(" HTTP/1.1\r\n");
|
||||
request_.append("User-Agent: Widevine CDM v1.0\r\n");
|
||||
request_.append("Host: ");
|
||||
request_.append(socket_.domain_name());
|
||||
request_.append("\r\nAccept: */*");
|
||||
request_.append("\r\nContent-Type: application/json");
|
||||
request_.append("\r\nContent-Length: 0");
|
||||
request_.append("\r\n"); // empty line to terminate header
|
||||
request_.append("\r\n"); // terminates the request
|
||||
std::string path = socket_.resource_path();
|
||||
path.append("&signedRequest=");
|
||||
path.append(data);
|
||||
|
||||
socket_.Write(request_.c_str(), request_.size());
|
||||
LOGD("HTTP request: (%d): %s", request_.size(), request_.c_str());
|
||||
LOGD("HTTP request: (%d): %s", request_.size(), b2a_hex(request_).c_str());
|
||||
return true;
|
||||
return PostRequestWithPath(path, "");
|
||||
}
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
Reference in New Issue
Block a user