From 1c06e9fce42fc9060e9628013b8297ce5c3d2ac0 Mon Sep 17 00:00:00 2001 From: Adrien Guinet Date: Sat, 26 Sep 2020 18:03:41 +0200 Subject: Resume download & show expected MD5 digest (#7) * Ability to resume downloads * Fetch version using TLS * Show expected MD5 if returned by the server Co-authored-by: Adrien Guinet Co-authored-by: Nayil Mukhametshin <66028747+nlscc@users.noreply.github.com> --- samloader/fusclient.py | 7 +++++-- samloader/main.py | 27 +++++++++++++++++++-------- samloader/versionfetch.py | 2 +- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/samloader/fusclient.py b/samloader/fusclient.py index 6836923..2acb165 100644 --- a/samloader/fusclient.py +++ b/samloader/fusclient.py @@ -24,9 +24,12 @@ class FUSClient(object): self.sessid = r.cookies["JSESSIONID"] r.raise_for_status() return r.text - def downloadfile(self, filename): + def downloadfile(self, filename, start=0): authv = 'FUS nonce="' + self.encnonce + '", signature="' + self.auth + '", nc="", type="", realm="", newauth="1"' + headers = {"Authorization": authv} + if start > 0: + headers["Range"] = "bytes={}-".format(start) r = requests.get("https://cloud-neofussvr.sslcs.cdngc.net/NF_DownloadBinaryForMass.do", - params={"file": filename}, headers={"Authorization": authv}, stream=True) + params={"file": filename}, headers=headers, stream=True) r.raise_for_status() return r diff --git a/samloader/main.py b/samloader/main.py index a4896bb..4d20bc9 100644 --- a/samloader/main.py +++ b/samloader/main.py @@ -3,6 +3,7 @@ import click import os +import base64 import xml.etree.ElementTree as ET from clint.textui import progress @@ -42,17 +43,27 @@ def checkupdate(model, region): def download(version, model, region, out): client = fusclient.FUSClient() path, filename = getbinaryfile(client, version, region, model) - print("Downloading file {} ...".format(path+filename)) initdownload(client, filename) - r = client.downloadfile(path+filename) - length = int(r.headers["Content-Length"]) if os.path.isdir(out): out = os.path.join(out, filename) - with open(out, "wb") as f: - for chunk in progress.bar(r.iter_content(chunk_size=0x10000), expected_size=(length/0x10000)+1): - if chunk: - f.write(chunk) - f.flush() + if os.path.exists(out): + f = open(out, "ab") + start = os.stat(out).st_size + print("Resuming {} at {}".format(path+filename, start)) + else: + f = open(out, "wb") + start = 0 + print("Downloading {}".format(path+filename)) + r = client.downloadfile(path+filename, start) + length = int(r.headers["Content-Length"]) + if "Content-MD5" in r.headers: + md5 = base64.b64decode(r.headers["Content-MD5"]).hex() + print("MD5: {}".format(md5)) + for chunk in progress.bar(r.iter_content(chunk_size=0x10000), expected_size=(length/0x10000)+1): + if chunk: + f.write(chunk) + f.flush() + f.close() print("Done!") @cli.command(help="Decrypt enc4 files.") diff --git a/samloader/versionfetch.py b/samloader/versionfetch.py index 800a297..9ef1595 100644 --- a/samloader/versionfetch.py +++ b/samloader/versionfetch.py @@ -7,7 +7,7 @@ import xml.etree.ElementTree as ET import requests def getlatestver(region, model): - r = requests.get("http://fota-cloud-dn.ospserver.net/firmware/" + region + "/" + model + "/version.xml") + r = requests.get("https://fota-cloud-dn.ospserver.net/firmware/" + region + "/" + model + "/version.xml") r.raise_for_status() root = ET.fromstring(r.text) vercode = root.find("./firmware/version/latest").text -- cgit v1.2.3