Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cdn: re-add get_cdn_auth_token in CDNClient #475

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions protobufs/steammessages_contentsystem.proto
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,23 @@ message CContentServerDirectory_GetManifestRequestCode_Response {
optional uint64 manifest_request_code = 1;
}

message CContentServerDirectory_GetCDNAuthToken_Request {
optional uint32 depot_id = 1;
optional string host_name = 2;
optional uint32 app_id = 3;
}

message CContentServerDirectory_GetCDNAuthToken_Response {
optional string token = 1;
optional uint32 expiration_time = 2;
}

service ContentServerDirectory {
option (service_description) = "Content Server and CDN directory";

rpc GetServersForSteamPipe (.CContentServerDirectory_GetServersForSteamPipe_Request) returns (.CContentServerDirectory_GetServersForSteamPipe_Response);
rpc GetDepotPatchInfo (.CContentServerDirectory_GetDepotPatchInfo_Request) returns (.CContentServerDirectory_GetDepotPatchInfo_Response);
rpc GetClientUpdateHosts (.CContentServerDirectory_GetClientUpdateHosts_Request) returns (.CContentServerDirectory_GetClientUpdateHosts_Response);
rpc GetManifestRequestCode (.CContentServerDirectory_GetManifestRequestCode_Request) returns (.CContentServerDirectory_GetManifestRequestCode_Response);
rpc GetCDNAuthToken (.CContentServerDirectory_GetCDNAuthToken_Request) returns (.CContentServerDirectory_GetCDNAuthToken_Response);
}
61 changes: 56 additions & 5 deletions steam/client/cdn.py
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ def __init__(self, client):
self.cell_id = self.steam.cell_id

self.web = make_requests_session()
self.cdn_auth_tokens = {} #: CDN authentication token
self.depot_keys = {} #: depot decryption keys
self.manifests = {} #: CDNDepotManifest instances
self.app_depots = {} #: app depot info
Expand Down Expand Up @@ -530,6 +531,51 @@ def get_content_server(self, rotate=False):
self.servers.rotate(-1)
return self.servers[0]

def get_cdn_auth_token(self, app_id, depot_id, hostname):
"""Get CDN authentication token

:param app_id: app id
:type app_id: :class:`int`
:param depot_id: depot id
:type depot_id: :class:`int`
:param hostname: cdn hostname
:type hostname: :class:`str`
:return: CDN authentication token
:rtype: str
"""
def update_cdn_auth_tokens():
resp = self.steam.send_um_and_wait('ContentServerDirectory.GetCDNAuthToken#1', {
'app_id': app_id,
'depot_id': depot_id,
'host_name': hostname
}, timeout=10)

if resp is None or resp.header.eresult != EResult.OK:
if resp.header.eresult == EResult.Fail:
# no need authtoken?
pass
else:
raise SteamError("Failed to get CDNAuthToken for %s, %s, %s" % (app_id, depot_id, hostname),
EResult.Timeout if resp is None else EResult(resp.header.eresult))

self.cdn_auth_tokens.update({app_id:{depot_id:{hostname: {
'eresult': resp.header.eresult,
'token': resp.body.token or '',
'expiration_time': resp.body.expiration_time or 0
}}}})

if app_id not in self.cdn_auth_tokens or \
depot_id not in self.cdn_auth_tokens[app_id] or \
hostname not in self.cdn_auth_tokens[app_id][depot_id]:
update_cdn_auth_tokens()
else:
if self.cdn_auth_tokens[app_id][depot_id][hostname]['eresult'] != EResult.OK:
pass
elif datetime.fromtimestamp(self.cdn_auth_tokens[app_id][depot_id][hostname]['expiration_time'] - 60) < datetime.now():
update_cdn_auth_tokens()

return self.cdn_auth_tokens[app_id][depot_id][hostname]['token']

def get_depot_key(self, app_id, depot_id):
"""Get depot key, which is needed to decrypt files

Expand All @@ -552,26 +598,31 @@ def get_depot_key(self, app_id, depot_id):

return self.depot_keys[depot_id]

def cdn_cmd(self, command, args):
def cdn_cmd(self, command, args, app_id=None, depot_id=None):
"""Run CDN command request

:param command: command name
:type command: str
:param args: args
:type args: str
:param args: app_id: (optional) required for CDN authentication token
:type args: int
:param args: depot_id: (optional) required for CDN authentication token
:type args: int
:returns: requests response
:rtype: :class:`requests.Response`
:raises SteamError: on error
"""
server = self.get_content_server()

while True:
url = "%s://%s:%s/%s/%s" % (
url = "%s://%s:%s/%s/%s%s" % (
'https' if server.https else 'http',
server.host,
server.port,
command,
args,
self.get_cdn_auth_token(app_id, depot_id, str(server.host))
)

try:
Expand Down Expand Up @@ -602,7 +653,7 @@ def get_chunk(self, app_id, depot_id, chunk_id):
:raises SteamError: error message
"""
if (depot_id, chunk_id) not in self._chunk_cache:
resp = self.cdn_cmd('depot', '%s/chunk/%s' % (depot_id, chunk_id))
resp = self.cdn_cmd('depot', '%s/chunk/%s' % (depot_id, chunk_id), app_id, depot_id)

data = symmetric_decrypt(resp.content, self.get_depot_key(app_id, depot_id))

Expand Down Expand Up @@ -688,9 +739,9 @@ def get_manifest(self, app_id, depot_id, manifest_gid, decrypt=True, manifest_re
"""
if (app_id, depot_id, manifest_gid) not in self.manifests:
if manifest_request_code:
resp = self.cdn_cmd('depot', '%s/manifest/%s/5/%s' % (depot_id, manifest_gid, manifest_request_code))
resp = self.cdn_cmd('depot', '%s/manifest/%s/5/%s' % (depot_id, manifest_gid, manifest_request_code), app_id, depot_id)
else:
resp = self.cdn_cmd('depot', '%s/manifest/%s/5' % (depot_id, manifest_gid))
resp = self.cdn_cmd('depot', '%s/manifest/%s/5' % (depot_id, manifest_gid), app_id, depot_id)

if resp.ok:
manifest = self.DepotManifestClass(self, app_id, resp.content)
Expand Down
117 changes: 114 additions & 3 deletions steam/protobufs/steammessages_contentsystem_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.