bug: 8620943 This is a merge of changes made to the Widevine CDM repository during certificate provisioning verification. The following changes are included: Fixes for certificate based licensing https://widevine-internal-review.googlesource.com/#/c/5162/ Base64 encode and decode now handles non-multiple of 24-bits input https://widevine-internal-review.googlesource.com/#/c/4981/ Fixed issues with device provisioning response handling https://widevine-internal-review.googlesource.com/#/c/5153/ Persistent storage to support device certificates https://widevine-internal-review.googlesource.com/#/c/5161/ Enable loading of certificates https://widevine-internal-review.googlesource.com/#/c/5172/ Provide license server url https://widevine-internal-review.googlesource.com/#/c/5173/ Change-Id: I0c032c1ae0055dcc1a7a77ad4b0ea0898030dc7d
132 lines
3.7 KiB
C++
132 lines
3.7 KiB
C++
// Copyright 2013 Google Inc. All Rights Reserved.
|
|
|
|
#include "url_request.h"
|
|
|
|
#include "http_socket.h"
|
|
#include "log.h"
|
|
#include "string_conversions.h"
|
|
|
|
namespace wvcdm {
|
|
|
|
UrlRequest::UrlRequest(const std::string& url, const std::string& port)
|
|
: is_connected_(false),
|
|
port_("80"),
|
|
request_(""),
|
|
server_url_(url)
|
|
{
|
|
if (!port.empty()) {
|
|
port_.assign(port);
|
|
}
|
|
if (socket_.Connect((server_url_).c_str(), port_, true)) {
|
|
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());
|
|
}
|
|
}
|
|
|
|
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, "%x\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
|
|
}
|
|
|
|
int UrlRequest::GetResponse(std::string& response) {
|
|
response.clear();
|
|
|
|
const int kTimeoutInMs = 1500 * 2;
|
|
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;
|
|
}
|
|
|
|
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::PostRequest(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
|
|
|
|
// calls AppendChunkToUpload repeatedly for multiple chunks
|
|
AppendChunkToUpload(data);
|
|
|
|
// terminates last chunk with 0\r\n, then ends header with an empty line
|
|
request_.append("0\r\n\r\n");
|
|
|
|
socket_.Write(request_.c_str(), request_.size());
|
|
return true;
|
|
}
|
|
|
|
void UrlRequest::AppendData(const std::string& data) {
|
|
request_.append(data);
|
|
request_.append("\r\n"); // marks end of data
|
|
}
|
|
|
|
bool UrlRequest::PostCertRequest(const std::string& data) {
|
|
request_.assign("POST /");
|
|
request_.append(socket_.resource_path());
|
|
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: ");
|
|
request_.append(UintToString(data.size()));
|
|
request_.append("\r\n"); // empty line to terminate header
|
|
request_.append("\r\n"); // terminates the request
|
|
|
|
AppendData(data);
|
|
|
|
socket_.Write(request_.c_str(), request_.size());
|
|
return true;
|
|
}
|
|
|
|
} // namespace wvcdm
|