add http 206 partial content
This commit is contained in:
parent
c4e190f8bb
commit
de29747dd1
@ -129,7 +129,7 @@ class HttpCli(object):
|
||||
response.extend(headers)
|
||||
response_str = "\r\n".join(response).encode("utf-8")
|
||||
try:
|
||||
self.s.send(response_str + b"\r\n\r\n" + body)
|
||||
self.s.sendall(response_str + b"\r\n\r\n" + body)
|
||||
except:
|
||||
raise Pebkac("client disconnected before http response")
|
||||
|
||||
@ -140,7 +140,17 @@ class HttpCli(object):
|
||||
self.reply(b"<pre>" + body.encode("utf-8"), *list(args), **kwargs)
|
||||
|
||||
def handle_get(self):
|
||||
self.log("{:4} {}".format(self.mode, self.req))
|
||||
logmsg = "{:4} {}".format(self.mode, self.req)
|
||||
|
||||
if "range" in self.headers:
|
||||
try:
|
||||
rval = self.headers["range"].split("=", 1)[1]
|
||||
except:
|
||||
rval += self.headers["range"]
|
||||
|
||||
logmsg += " [\033[36m" + rval + "\033[0m]"
|
||||
|
||||
self.log(logmsg)
|
||||
|
||||
# "embedded" resources
|
||||
if self.vpath.startswith(".cpr"):
|
||||
@ -183,7 +193,7 @@ class HttpCli(object):
|
||||
|
||||
try:
|
||||
if self.headers["expect"].lower() == "100-continue":
|
||||
self.s.send(b"HTTP/1.1 100 Continue\r\n\r\n")
|
||||
self.s.sendall(b"HTTP/1.1 100 Continue\r\n\r\n")
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
@ -317,6 +327,13 @@ class HttpCli(object):
|
||||
file_lastmod = file_dt.strftime("%a, %b %d %Y %H:%M:%S GMT")
|
||||
|
||||
do_send = True
|
||||
status = "200 OK"
|
||||
extra_headers = []
|
||||
logmsg = "{:4} {} {}".format("", self.req, status)
|
||||
|
||||
#
|
||||
# if-modified
|
||||
|
||||
if "if-modified-since" in self.headers:
|
||||
cli_lastmod = self.headers["if-modified-since"]
|
||||
try:
|
||||
@ -327,38 +344,85 @@ class HttpCli(object):
|
||||
self.log("bad lastmod format: {}".format(cli_lastmod))
|
||||
do_send = file_lastmod != cli_lastmod
|
||||
|
||||
status = "200 OK"
|
||||
if not do_send:
|
||||
status = "304 Not Modified"
|
||||
|
||||
#
|
||||
# partial
|
||||
|
||||
file_sz = os.path.getsize(fsenc(path))
|
||||
lower = 0
|
||||
upper = file_sz
|
||||
|
||||
if do_send and "range" in self.headers:
|
||||
try:
|
||||
hrange = self.headers["range"]
|
||||
a, b = hrange.split("=", 1)[1].split("-")
|
||||
|
||||
if a.strip():
|
||||
lower = int(a.strip())
|
||||
else:
|
||||
lower = 0
|
||||
|
||||
if b.strip():
|
||||
upper = int(b.strip()) + 1
|
||||
else:
|
||||
upper = file_sz
|
||||
|
||||
if lower < 0 or lower >= file_sz or upper < 0 or upper > file_sz:
|
||||
raise Pebkac("na")
|
||||
|
||||
except:
|
||||
self.loud_reply("invalid range requested: " + hrange)
|
||||
|
||||
status = "206 Partial Content"
|
||||
extra_headers.append(
|
||||
"Content-Range: bytes {}-{}/{}".format(lower, upper - 1, file_sz)
|
||||
)
|
||||
|
||||
logmsg += " [\033[36m" + str(lower) + "-" + str(upper) + "\033[0m]"
|
||||
|
||||
#
|
||||
# send reply
|
||||
|
||||
mime = mimetypes.guess_type(path)[0] or "application/octet-stream"
|
||||
|
||||
headers = [
|
||||
"HTTP/1.1 " + status,
|
||||
"Connection: Keep-Alive",
|
||||
"Content-Type: " + mime,
|
||||
"Content-Length: " + str(os.path.getsize(fsenc(path))),
|
||||
"Content-Length: " + str(upper - lower),
|
||||
"Accept-Ranges: bytes",
|
||||
"Last-Modified: " + file_lastmod,
|
||||
]
|
||||
|
||||
headers.extend(extra_headers)
|
||||
headers = "\r\n".join(headers).encode("utf-8") + b"\r\n\r\n"
|
||||
self.s.send(headers)
|
||||
|
||||
logmsg = "{:4} {} {}".format("", self.req, status)
|
||||
self.s.sendall(headers)
|
||||
|
||||
if self.mode == "HEAD" or not do_send:
|
||||
self.log(logmsg)
|
||||
return True
|
||||
|
||||
with open(fsenc(path), "rb") as f:
|
||||
while True:
|
||||
# 512 kB is optimal for huge files, use 64k
|
||||
with open(fsenc(path), "rb", 64 * 1024) as f:
|
||||
remains = upper - lower
|
||||
f.seek(lower)
|
||||
while remains > 0:
|
||||
# time.sleep(0.01)
|
||||
buf = f.read(4096)
|
||||
if not buf:
|
||||
break
|
||||
|
||||
if remains < len(buf):
|
||||
buf = buf[:remains]
|
||||
|
||||
remains -= len(buf)
|
||||
|
||||
try:
|
||||
self.s.send(buf)
|
||||
self.s.sendall(buf)
|
||||
except:
|
||||
logmsg += " \033[31m" + str(upper - remains) + "\033[0m"
|
||||
self.log(logmsg)
|
||||
return False
|
||||
|
||||
self.log(logmsg)
|
||||
|
Loading…
Reference in New Issue
Block a user