Files
android/libwvdrmengine/cdm/core/test/url_request.cpp
Fred Gylys-Colwell b5e8b87fed Merge Changes from CDM repository
This CL merges the following changes from the Widevine repository:

Avoid CdmSession reinitialization
https://widevine-internal-review.googlesource.com/#/c/10530/

Fix timer-related unit tests.
https://widevine-internal-review.googlesource.com/#/c/10510/

Correct return statement
bug: 15590802
https://widevine-internal-review.googlesource.com/#/c/10553/

Usage reporting fixes
bug/15388863
https://widevine-internal-review.googlesource.com/#/c/10460/

Make public methods virtual
https://widevine-internal-review.googlesource.com/#/c/10500/

Fix the SetTimer contract in the CDM.
https://widevine-internal-review.googlesource.com/#/c/10493/

Move inline CDM methods, add OVERRIDE.
https://widevine-internal-review.googlesource.com/#/c/10475/

Simplify storage APIs related cleanup.
https://widevine-internal-review.googlesource.com/#/c/10473/

Duration values are not correctly reported when queried
b/15592374
https://widevine-internal-review.googlesource.com/#/c/10437/

Propagate IsKeyValid() through ContentDecryptionModule.
https://widevine-internal-review.googlesource.com/#/c/10483/

Minor clean up in config_test_env.
https://widevine-internal-review.googlesource.com/#/c/10440/

General clean up.
https://widevine-internal-review.googlesource.com/#/c/10441/

Refactor HttpSocket and simplify UrlRequest interface.
https://widevine-internal-review.googlesource.com/#/c/10410/

Install good keybox at end of unit tests
b/15385981
https://widevine-internal-review.googlesource.com/#/c/10374/

Privacy crypto fixes
b/15475012
https://widevine-internal-review.googlesource.com/#/c/10383/

Incorporate header files to resolve build issued based on customers feedback.
https://widevine-internal-review.googlesource.com/#/c/10420/

Support unprovisioning
b/12247651
https://widevine-internal-review.googlesource.com/#/c/10356/

Correct usage of Host::Allocate and Cdm::Decrypt.
https://widevine-internal-review.googlesource.com/#/c/10378/

Fix logging bug, arguments in wrong order.
https://widevine-internal-review.googlesource.com/#/c/10380/

Rename types that look like constants.
https://widevine-internal-review.googlesource.com/#/c/10379/

Fix offline test failures
b/13909635
https://widevine-internal-review.googlesource.com/#/c/10348/

Add -DUNIT_TEST to the unit test makefile for Android
https://widevine-internal-review.googlesource.com/#/c/10375/

Refactor privacy-crypto and add dummy version.
https://widevine-internal-review.googlesource.com/#/c/10353/

Remove References to Apiary
https://widevine-internal-review.googlesource.com/#/c/9924/

Delete oldest entry in usage table when full
bug: 15184824
https://widevine-internal-review.googlesource.com/#/c/10295/

Port DeviceFiles to iOS.
https://widevine-internal-review.googlesource.com/#/c/10355/

Make testing functions in DeviceFiles private.
https://widevine-internal-review.googlesource.com/#/c/10354/

Add RSA encryption to haystack
https://widevine-internal-review.googlesource.com/#/c/10280/

Add string and vector includes to CDM header.
https://widevine-internal-review.googlesource.com/#/c/10352/

First version of oemcrypto logging
https://widevine-internal-review.googlesource.com/#/c/10252/

Update Names of Secure Stop Methods
bug: 11987015
https://widevine-internal-review.googlesource.com/#/c/10152/

Adjust timing on the Usage Table unit test
https://widevine-internal-review.googlesource.com/#/c/10307/

Fix all compiler warnings in CDM source release.
https://widevine-internal-review.googlesource.com/#/c/10293/

Fix memset bug: args in wrong order
https://widevine-internal-review.googlesource.com/#/c/10292/

Partial revert of 'Remove refs to test prov server, Level3 support...'
https://widevine-internal-review.googlesource.com/#/c/10281/

Pack structure OEMCrypto_PST_Report
https://widevine-internal-review.googlesource.com/#/c/10243/

Remove refs to test prov server, Level3 support; remove dead code
https://widevine-internal-review.googlesource.com/#/c/10220/

Partial revert of 'Document data strings; clean up license server parameters.'
https://widevine-internal-review.googlesource.com/#/c/10188/

Document data strings; clean up license server parameters.
https://widevine-internal-review.googlesource.com/#/c/10120/

Fix broken build after partner branch merge.
https://widevine-internal-review.googlesource.com/#/c/10181/

TODO Cleanup - core/src, core/include
https://widevine-internal-review.googlesource.com/#/c/9965/

TODO Cleanup - cdm, chromium, core/test.
https://widevine-internal-review.googlesource.com/#/c/9419/

Remove unneeded properties.
https://widevine-internal-review.googlesource.com/#/c/10162/

Change-Id: If2bb9d743a562a3875bebb91933c0aaadea286b2
2014-06-27 18:59:56 +00:00

171 lines
4.9 KiB
C++

// Copyright 2013 Google Inc. All Rights Reserved.
#include "url_request.h"
#include <errno.h>
#include <sstream>
#include "http_socket.h"
#include "log.h"
#include "string_conversions.h"
namespace {
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 ConcatenateChunkedResponse(const std::string http_response,
std::string* modified_response) {
if (http_response.empty()) return;
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], "%zx", &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], "%zx", &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);
}
}
} // 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;
// 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(read_buffer, bytes);
} else if (bytes < 0) {
LOGE("read error, errno = %d", errno);
return false;
} else {
// end of stream.
break;
}
}
ConcatenateChunkedResponse(response, message);
LOGD("HTTP response: (%d): %s", message->size(), b2a_hex(*message).c_str());
return true;
}
// static
int UrlRequest::GetStatusCode(const std::string& response) {
const std::string kHttpVersion("HTTP/1.1 ");
int status_code = -1;
size_t pos = response.find(kHttpVersion);
if (pos != std::string::npos) {
pos += kHttpVersion.size();
sscanf(response.substr(pos).c_str(), "%d", &status_code);
}
return status_code;
}
bool UrlRequest::PostRequestWithPath(const std::string& path,
const std::string& data) {
std::string request;
request.append("POST ");
request.append(path);
request.append(" HTTP/1.1\r\n");
request.append("Host: ");
request.append(socket_.domain_name());
request.append("\r\n");
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) {
return PostRequestWithPath(socket_.resource_path(), data);
}
bool UrlRequest::PostCertRequestInQueryString(const std::string& data) {
std::string path = socket_.resource_path();
path.append("&signedRequest=");
path.append(data);
return PostRequestWithPath(path, "");
}
} // namespace wvcdm