/
put_file.py
147 lines (123 loc) · 4.63 KB
/
put_file.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
"""Upload file via WebDAV PUT method."""
from wsgiref.simple_server import make_server, WSGIServer
from socketserver import ThreadingMixIn
from hashlib import sha256
from tempfile import TemporaryFile
import os
import sys
import logging as log
EXAMPLES_PATH = os.path.dirname(__file__)
sys.path.insert(0, os.path.abspath(
os.path.join(EXAMPLES_PATH, os.path.pardir)))
# pylint: disable=import-error, disable=wrong-import-position
from poorwsgi import Application, state # noqa
from poorwsgi.response import JSONResponse
logger = log.getLogger()
logger.setLevel("DEBUG")
app = application = Application("large_file")
app.debug = True
@app.route('/blackhole/<filename>', method=state.METHOD_PUT)
def blackhole_put(req, filename:str):
"""Upload file via PUT method like in webdav"""
checksum = sha256()
uploaded = 0
if req.content_length > 0:
block = min(app.cached_size, req.content_length)
data = req.read(block)
while data:
uploaded += len(data)
checksum.update(data)
block = min(app.cached_size, req.content_length-uploaded)
if block > 1:
data = req.read(block)
else:
data = b''
return JSONResponse(status_code=200, uploaded=uploaded,
checksum=checksum.hexdigest(), filename=filename)
@app.route('/temporary/<filename>', method=state.METHOD_PUT)
def temporary_put(req, filename:str):
"""Upload file via PUT method like in webdav"""
checksum = sha256()
uploaded = 0
if req.content_length > 0:
with TemporaryFile('wb+') as temp:
block = min(app.cached_size, req.content_length)
data = req.read(block)
while data:
uploaded += temp.write(data)
checksum.update(data)
block = min(app.cached_size, req.content_length-uploaded)
if block > 1:
data = req.read(block)
else:
data = b''
return JSONResponse(status_code=200, uploaded=uploaded,
checksum=checksum.hexdigest(), filename=filename)
@app.route('/')
def root(req):
"""Return Root (Index) page."""
assert req
return """<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Large File Upload Example</title>
<style>
body {width:90%%; max-width:900px; margin:auto; padding-top:30px;}
h1 {text-align: center; color: #707070;}
</style>
</head>
<body>
<h1>Large File Upload Example</h1>
<input type="file" name="file"/>
<ul>
<li><a href="#blackhole" id="blackhole"/>Blackhole</a>
<li><a href="#temporary" id="temporary"/>Temporary</a>
</ul>
<hr>
<small>Copyright (c) 2021 Ondřej Tůma. See
<a href="http://poorhttp.zeropage.cz">poorhttp.zeropage.cz</a>
</small>
<script>
function upload(path){
let file = document.querySelector('input[type=file]').files[0];
if (file === undefined) {
alert("No file selected.");
return;
}
let ajax = new XMLHttpRequest();
ajax.open("PUT", path+file.name, true);
ajax.onload = function (ev) {
alert(ajax.response);
};
const reader = new FileReader();
reader.onload = function(e) {
const blob = new Blob([new Uint8Array(e.target.result)],
{type: file.type });
ajax.send(blob);
};
reader.readAsArrayBuffer(file);
}
let blackhole = document.getElementById('blackhole');
blackhole.addEventListener('click', function(event){
upload('/blackhole/');
});
let temporary = document.getElementById('temporary');
temporary.addEventListener('click', function(event){
upload('/temporary/');
});
</script>
</body>
</html>
"""
class ThreadingWSGIServer(ThreadingMixIn, WSGIServer):
"""This class is identical to WSGIServer but uses threads to handle
requests by using the ThreadingMixIn. This is useful to handle weg
browsers pre-opening sockets, on which Server would wait indefinitely.
"""
multithread = True
daemon_threads = True
if __name__ == '__main__':
ADDRESS = sys.argv[1] if len(sys.argv) > 1 else '127.0.0.1'
httpd = make_server(ADDRESS, 8080, app, ThreadingWSGIServer)
print("Starting to serve on http://%s:8080" % ADDRESS)
httpd.serve_forever()