Adjust WidevineEncryptionKeySource to handle timeout
Change-Id: Iac4a86acae2e522c6cfc84ce02ae7ec1dd30c47e
This commit is contained in:
parent
419d463eaa
commit
1927109818
|
@ -40,6 +40,7 @@ const int kFirstRetryDelayMilliseconds = 1000;
|
|||
// key rotation enabled request.
|
||||
const int kDefaultCryptoPeriodCount = 10;
|
||||
const int kGetKeyTimeoutInSeconds = 5 * 60; // 5 minutes.
|
||||
const int kHttpTimeoutInSeconds = 60; // 1 minute.
|
||||
|
||||
bool Base64StringToBytes(const std::string& base64_string,
|
||||
std::vector<uint8>* bytes) {
|
||||
|
@ -129,7 +130,7 @@ WidevineEncryptionKeySource::WidevineEncryptionKeySource(
|
|||
const std::string& policy,
|
||||
scoped_ptr<RequestSigner> signer,
|
||||
int first_crypto_period_index)
|
||||
: http_fetcher_(new SimpleHttpFetcher()),
|
||||
: http_fetcher_(new SimpleHttpFetcher(kHttpTimeoutInSeconds)),
|
||||
server_url_(server_url),
|
||||
content_id_(content_id),
|
||||
policy_(policy),
|
||||
|
@ -243,24 +244,26 @@ Status WidevineEncryptionKeySource::FetchKeys(
|
|||
// server limitation.
|
||||
for (int i = 0; i < kNumTransientErrorRetries; ++i) {
|
||||
status = http_fetcher_->Post(server_url_, message, &raw_response);
|
||||
if (!status.ok())
|
||||
if (status.ok()) {
|
||||
VLOG(1) << "Retry [" << i << "] Response:" << raw_response;
|
||||
|
||||
std::string response;
|
||||
if (!DecodeResponse(raw_response, &response)) {
|
||||
return Status(error::SERVER_ERROR,
|
||||
"Failed to decode response '" + raw_response + "'.");
|
||||
}
|
||||
|
||||
bool transient_error = false;
|
||||
if (ExtractEncryptionKey(response, &transient_error))
|
||||
return Status::OK;
|
||||
|
||||
if (!transient_error) {
|
||||
return Status(
|
||||
error::SERVER_ERROR,
|
||||
"Failed to extract encryption key from '" + response + "'.");
|
||||
}
|
||||
} else if (status.error_code() != error::TIME_OUT) {
|
||||
return status;
|
||||
VLOG(1) << "Retry [" << i << "] Response:" << raw_response;
|
||||
|
||||
std::string response;
|
||||
if (!DecodeResponse(raw_response, &response)) {
|
||||
return Status(error::SERVER_ERROR,
|
||||
"Failed to decode response '" + raw_response + "'.");
|
||||
}
|
||||
|
||||
bool transient_error = false;
|
||||
if (ExtractEncryptionKey(response, &transient_error))
|
||||
return Status::OK;
|
||||
|
||||
if (!transient_error) {
|
||||
return Status(
|
||||
error::SERVER_ERROR,
|
||||
"Failed to extract encryption key from '" + response + "'.");
|
||||
}
|
||||
|
||||
// Exponential backoff.
|
||||
|
|
|
@ -143,6 +143,20 @@ class WidevineEncryptionKeySourceTest : public ::testing::Test {
|
|||
mock_http_fetcher_.PassAs<HttpFetcher>());
|
||||
}
|
||||
|
||||
void VerifyKeys() {
|
||||
EncryptionKey encryption_key;
|
||||
const std::string kTrackTypes[] = {"SD", "HD", "AUDIO"};
|
||||
for (size_t i = 0; i < arraysize(kTrackTypes); ++i) {
|
||||
ASSERT_OK(widevine_encryption_key_source_->GetKey(
|
||||
EncryptionKeySource::GetTrackTypeFromString(kTrackTypes[i]),
|
||||
&encryption_key));
|
||||
EXPECT_EQ(GetMockKeyId(kTrackTypes[i]), ToString(encryption_key.key_id));
|
||||
EXPECT_EQ(GetMockKey(kTrackTypes[i]), ToString(encryption_key.key));
|
||||
EXPECT_EQ(GetMockPsshData(kTrackTypes[i]),
|
||||
GetPsshDataFromPsshBox(ToString(encryption_key.pssh)));
|
||||
}
|
||||
}
|
||||
|
||||
scoped_ptr<MockRequestSigner> mock_request_signer_;
|
||||
scoped_ptr<MockHttpFetcher> mock_http_fetcher_;
|
||||
scoped_ptr<WidevineEncryptionKeySource> widevine_encryption_key_source_;
|
||||
|
@ -217,18 +231,24 @@ TEST_F(WidevineEncryptionKeySourceTest, LicenseStatusOK) {
|
|||
|
||||
CreateWidevineEncryptionKeySource(kDisableKeyRotation);
|
||||
ASSERT_OK(widevine_encryption_key_source_->Initialize());
|
||||
VerifyKeys();
|
||||
}
|
||||
|
||||
EncryptionKey encryption_key;
|
||||
const std::string kTrackTypes[] = {"SD", "HD", "AUDIO"};
|
||||
for (size_t i = 0; i < 3; ++i) {
|
||||
ASSERT_OK(widevine_encryption_key_source_->GetKey(
|
||||
EncryptionKeySource::GetTrackTypeFromString(kTrackTypes[i]),
|
||||
&encryption_key));
|
||||
EXPECT_EQ(GetMockKeyId(kTrackTypes[i]), ToString(encryption_key.key_id));
|
||||
EXPECT_EQ(GetMockKey(kTrackTypes[i]), ToString(encryption_key.key));
|
||||
EXPECT_EQ(GetMockPsshData(kTrackTypes[i]),
|
||||
GetPsshDataFromPsshBox(ToString(encryption_key.pssh)));
|
||||
}
|
||||
TEST_F(WidevineEncryptionKeySourceTest, RetryOnHttpTimeout) {
|
||||
EXPECT_CALL(*mock_request_signer_, GenerateSignature(_, _))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
std::string mock_response = base::StringPrintf(
|
||||
kHttpResponseFormat, Base64Encode(GenerateMockLicenseResponse()).c_str());
|
||||
|
||||
// Retry is expected on HTTP timeout.
|
||||
EXPECT_CALL(*mock_http_fetcher_, Post(_, _, _))
|
||||
.WillOnce(Return(Status(error::TIME_OUT, "")))
|
||||
.WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK)));
|
||||
|
||||
CreateWidevineEncryptionKeySource(kDisableKeyRotation);
|
||||
ASSERT_OK(widevine_encryption_key_source_->Initialize());
|
||||
VerifyKeys();
|
||||
}
|
||||
|
||||
TEST_F(WidevineEncryptionKeySourceTest, RetryOnTransientError) {
|
||||
|
@ -251,14 +271,7 @@ TEST_F(WidevineEncryptionKeySourceTest, RetryOnTransientError) {
|
|||
|
||||
CreateWidevineEncryptionKeySource(kDisableKeyRotation);
|
||||
ASSERT_OK(widevine_encryption_key_source_->Initialize());
|
||||
|
||||
EncryptionKey encryption_key;
|
||||
ASSERT_OK(widevine_encryption_key_source_->GetKey(
|
||||
EncryptionKeySource::TRACK_TYPE_SD, &encryption_key));
|
||||
EXPECT_EQ(GetMockKeyId("SD"), ToString(encryption_key.key_id));
|
||||
EXPECT_EQ(GetMockKey("SD"), ToString(encryption_key.key));
|
||||
EXPECT_EQ(GetMockPsshData("SD"),
|
||||
GetPsshDataFromPsshBox(ToString(encryption_key.pssh)));
|
||||
VerifyKeys();
|
||||
}
|
||||
|
||||
TEST_F(WidevineEncryptionKeySourceTest, NoRetryOnUnknownError) {
|
||||
|
|
Loading…
Reference in New Issue