6 from .common
import InfoExtractor
9 class AWSIE(InfoExtractor
): # XXX: Conventionally, base classes should end with BaseIE/InfoExtractor
10 _AWS_ALGORITHM
= 'AWS4-HMAC-SHA256'
11 _AWS_REGION
= 'us-east-1'
13 def _aws_execute_api(self
, aws_dict
, video_id
, query
=None):
15 amz_date
= dt
.datetime
.now(dt
.timezone
.utc
).strftime('%Y%m%dT%H%M%SZ')
18 'Accept': 'application/json',
19 'Host': self
._AWS
_PROXY
_HOST
,
20 'X-Amz-Date': amz_date
,
21 'X-Api-Key': self
._AWS
_API
_KEY
,
23 session_token
= aws_dict
.get('session_token')
25 headers
['X-Amz-Security-Token'] = session_token
28 return hashlib
.sha256(s
.encode()).hexdigest()
30 # Task 1: http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
31 canonical_querystring
= urllib
.parse
.urlencode(query
)
32 canonical_headers
= ''
33 for header_name
, header_value
in sorted(headers
.items()):
34 canonical_headers
+= f
'{header_name.lower()}:{header_value}\n'
35 signed_headers
= ';'.join([header
.lower() for header
in sorted(headers
.keys())])
36 canonical_request
= '\n'.join([
39 canonical_querystring
,
45 # Task 2: http://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html
46 credential_scope_list
= [date
, self
._AWS
_REGION
, 'execute-api', 'aws4_request']
47 credential_scope
= '/'.join(credential_scope_list
)
48 string_to_sign
= '\n'.join([self
._AWS
_ALGORITHM
, amz_date
, credential_scope
, aws_hash(canonical_request
)])
50 # Task 3: http://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html
51 def aws_hmac(key
, msg
):
52 return hmac
.new(key
, msg
.encode(), hashlib
.sha256
)
54 def aws_hmac_digest(key
, msg
):
55 return aws_hmac(key
, msg
).digest()
57 def aws_hmac_hexdigest(key
, msg
):
58 return aws_hmac(key
, msg
).hexdigest()
60 k_signing
= ('AWS4' + aws_dict
['secret_key']).encode()
61 for value
in credential_scope_list
:
62 k_signing
= aws_hmac_digest(k_signing
, value
)
64 signature
= aws_hmac_hexdigest(k_signing
, string_to_sign
)
66 # Task 4: http://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html
67 headers
['Authorization'] = ', '.join([
68 '{} Credential={}/{}'.format(self
._AWS
_ALGORITHM
, aws_dict
['access_key'], credential_scope
),
69 f
'SignedHeaders={signed_headers}',
70 f
'Signature={signature}',
73 return self
._download
_json
(
74 'https://{}{}{}'.format(self
._AWS
_PROXY
_HOST
, aws_dict
['uri'], '?' + canonical_querystring
if canonical_querystring
else ''),
75 video_id
, headers
=headers
)