Migration from jb-mr2 to master for Widevine CDM

Android development of the widevine CDM has been done
on the jb-mr2 branch of the cdm code base.  This CL
contains a merge of that jb-mr2 work to CDM master, and
also reflects the evolution of the common Modular DRM
code base since jb-mr2 branched.

Change-Id: I1d7e1a12d092c00044a4298261146cb97808d4ef
This commit is contained in:
Jeff Tinker
2013-07-29 17:29:07 -07:00
parent edb987db07
commit 0190f99fb3
68 changed files with 4754 additions and 3601 deletions

View File

@@ -2,6 +2,7 @@
#include "url_request.h"
#include <errno.h>
#include <sstream>
#include "http_socket.h"
@@ -10,28 +11,26 @@
namespace wvcdm {
UrlRequest::UrlRequest(const std::string& url, const std::string& port)
: is_connected_(false),
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)
{
server_url_(url) {
if (!port.empty()) {
port_.assign(port);
}
if (socket_.Connect((server_url_).c_str(), port_, true)) {
if (socket_.Connect((server_url_).c_str(), port_, true, secure_connection)) {
LOGD("connected to %s", socket_.domain_name().c_str());
is_connected_ = true;
} else {
LOGE("failed to connect to %s, port=%s",
socket_.domain_name().c_str(), port.c_str());
LOGE("failed to connect to %s, port=%s", socket_.domain_name().c_str(),
port.c_str());
}
}
UrlRequest::~UrlRequest()
{
socket_.CloseSocket();
}
UrlRequest::~UrlRequest() { socket_.CloseSocket(); }
void UrlRequest::AppendChunkToUpload(const std::string& data) {
// format of chunk:
@@ -49,24 +48,97 @@ void UrlRequest::AppendChunkToUpload(const std::string& data) {
request_.append("\r\n"); // marks end of data
}
int UrlRequest::GetResponse(std::string& response) {
response.clear();
// 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) {
if (http_response.empty()) return;
const int kTimeoutInMs = 1500 * 2;
modified_response->clear();
const std::string kChunkedTag = "Transfer-Encoding: chunked\r\n\r\n";
size_t chunked_tag_pos = http_response.find(kChunkedTag);
if (std::string::npos != chunked_tag_pos) {
// processes chunked encoding
size_t chunk_size = 0;
size_t chunk_size_pos = chunked_tag_pos + kChunkedTag.size();
sscanf(&http_response[chunk_size_pos], "%x", &chunk_size);
if (chunk_size > http_response.size()) {
// precaution, in case we misread chunk size
LOGE("invalid chunk size %u", chunk_size);
return;
}
// Search for chunks in the following format:
// header
// chunk size\r\n <-- chunk_size_pos @ beginning of chunk size
// chunk data\r\n <-- chunk_pos @ beginning of chunk data
// 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);
while ((chunk_size > 0) && (std::string::npos != chunk_pos)) {
chunk_pos += kCrLf.size();
modified_response->append(http_response, chunk_pos, chunk_size);
// Search for next chunk
chunk_size_pos = chunk_pos + chunk_size + kCrLf.size();
sscanf(&http_response[chunk_size_pos], "%x", &chunk_size);
if (chunk_size > http_response.size()) {
// precaution, in case we misread chunk size
LOGE("invalid chunk size %u", chunk_size);
break;
}
chunk_pos = http_response.find(kCrLf, chunk_size_pos);
}
} else {
// Response is not chunked encoded
modified_response->assign(http_response);
}
}
void UrlRequest::DumpMessage(const std::string& description,
const std::string& message) {
if (description.empty()) return;
LOGD("%s (%d bytes):", description.c_str(), message.size());
size_t remaining = message.size();
size_t portion = 0;
size_t start = 0;
while (remaining > 0) {
// LOGX may not get to empty its buffer if it is too large,
// pick an arbitrary small size to be safe
portion = (remaining < 512) ? remaining : 512;
LOGD("%s", message.substr(start, portion).c_str());
start += portion;
remaining -= portion;
}
LOGD("total bytes dumped(%d)", start);
}
int UrlRequest::GetResponse(std::string* message) {
message->clear();
std::string response;
const int kTimeoutInMs = 3000;
int bytes = 0;
int total_bytes = 0;
do {
memset(buffer_, 0, kHttpBufferSize);
bytes = socket_.Read(buffer_, kHttpBufferSize, kTimeoutInMs);
if (bytes > 0) {
response.append(buffer_, bytes);
total_bytes += bytes;
} else {
if (bytes < 0) LOGE("read error = ", errno);
// bytes == 0 indicates nothing to read
}
} while (bytes > 0);
return total_bytes;
ConcatenateChunkedResponse(response, message);
LOGD("%d bytes returned", message->size());
return message->size();
}
int UrlRequest::GetStatusCode(const std::string& response) {
@@ -106,6 +178,9 @@ bool UrlRequest::PostRequestChunk(const std::string& data) {
}
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");
@@ -149,4 +224,4 @@ bool UrlRequest::PostCertRequestInQueryString(const std::string& data) {
return true;
}
} // namespace wvcdm
} // namespace wvcdm