uploadserver 5.2.2__tar.gz → 6.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: uploadserver
3
- Version: 5.2.2
3
+ Version: 6.0.1
4
4
  Summary: Python's http.server extended to include a file upload page
5
5
  Home-page: https://github.com/Densaugeo/uploadserver
6
6
  Author: Densaugeo
@@ -8,9 +8,18 @@ Author-email: author@example.com
8
8
  Classifier: Programming Language :: Python :: 3
9
9
  Classifier: License :: OSI Approved :: MIT License
10
10
  Classifier: Operating System :: OS Independent
11
- Requires-Python: >=3.8
11
+ Requires-Python: >=3.9
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
+ Dynamic: author
15
+ Dynamic: author-email
16
+ Dynamic: classifier
17
+ Dynamic: description
18
+ Dynamic: description-content-type
19
+ Dynamic: home-page
20
+ Dynamic: license-file
21
+ Dynamic: requires-python
22
+ Dynamic: summary
14
23
 
15
24
  # uploadserver
16
25
 
@@ -23,8 +32,8 @@ Python's http.server extended to include a file upload page
23
32
 
24
33
  | Platform | Supported? | Notes |
25
34
  |-|-|-|
26
- | Python 3.8+ | Yes | Tested on 3.8 through 3.12 every release. |
27
- | Python 3.6-3.7 | No | Was supported by previous versions. |
35
+ | Python 3.9+ | Yes | Tested on 3.9 through 3.14 every release. |
36
+ | Python 3.6-3.8 | No | Was supported by previous versions. |
28
37
  | Python 3.5- | No | |
29
38
  | Linux | Yes | Tested on Fedora and Ubuntu every release. |
30
39
  | Windows | Yes | Occasional manual testing. Haven't noticed any obvious problems. |
@@ -32,13 +41,13 @@ Python's http.server extended to include a file upload page
32
41
 
33
42
  ## Installation
34
43
 
35
- ~~~
44
+ ~~~bash
36
45
  python3 -m pip install --user uploadserver
37
46
  ~~~
38
47
 
39
48
  ## Usage
40
49
 
41
- ~~~
50
+ ~~~bash
42
51
  python3 -m uploadserver
43
52
  ~~~
44
53
 
@@ -49,18 +58,18 @@ After the server starts, the upload page is at /upload. For example, if the serv
49
58
  Warning: This is an upload server, and running it will allow uploads.
50
59
 
51
60
  Now supports uploading multiple files at once! Select multiple files in the web page's file selector, or upload with cURL:
52
- ~~~
61
+ ~~~bash
53
62
  curl -X POST http://127.0.0.1:8000/upload -F 'files=@multiple-example-1.txt' -F 'files=@multiple-example-2.txt'
54
63
  ~~~
55
64
 
56
65
  ## Basic Authentication (downloads and uploads)
57
66
 
58
- ~~~
67
+ ~~~bash
59
68
  python3 -m uploadserver --basic-auth hello:world
60
69
  ~~~
61
70
 
62
71
  Now you can upload with basic authentication. For example:
63
- ~~~
72
+ ~~~bash
64
73
  curl -X POST http://127.0.0.1:8000/upload -F 'files=@basicauth-example.txt' -u hello:world
65
74
  ~~~
66
75
 
@@ -68,7 +77,7 @@ All requests without authentication will be rejected. Note that basic authentica
68
77
 
69
78
  ## Basic Authentication (uploads only)
70
79
 
71
- ~~~
80
+ ~~~bash
72
81
  python3 -m uploadserver --basic-auth-upload hello:world
73
82
  ~~~
74
83
 
@@ -79,18 +88,18 @@ If both `--basic-auth` and `--basic-auth-upload` are specified, all requests wil
79
88
  ## Theme Option
80
89
 
81
90
  The upload page supports a dark mode for showing white text on black background. If no option is specified, the color scheme is chosen from the client’s browser’s preference (which typically matches their operating system’s setting, if light or dark mode is supported by the OS). To enforce the light or dark theme, the CLI parameter `--theme` can be used:
82
- ~~~
91
+ ~~~bash
83
92
  python3 -m uploadserver --theme light
84
93
  ~~~
85
94
  or
86
- ~~~
95
+ ~~~bash
87
96
  python3 -m uploadserver --theme dark
88
97
  ~~~
89
98
 
90
99
  ## HTTPS Option
91
100
 
92
101
  Run with HTTPS and without client authentication:
93
- ~~~
102
+ ~~~bash
94
103
  # Generate self-signed server certificate
95
104
  openssl req -x509 -out server.pem -keyout server.pem -newkey rsa:2048 -nodes -sha256 -subj '/CN=server'
96
105
 
@@ -103,7 +112,7 @@ curl -X POST https://localhost:8000/upload --insecure -F files=@simple-example.t
103
112
  ~~~
104
113
 
105
114
  Run with HTTPS and with client authentication:
106
- ~~~
115
+ ~~~bash
107
116
  # Generate self-signed server certificate
108
117
  openssl req -x509 -out server.pem -keyout server.pem -newkey rsa:2048 -nodes -sha256 -subj '/CN=server'
109
118
 
@@ -123,6 +132,51 @@ curl -X POST https://localhost:8000/upload --insecure --cert client.pem -F files
123
132
 
124
133
  Note: This uses a self-signed server certificate which clients such as web browser and cURL will warn about. Most browsers will allow you to proceed after adding an exception, and cURL will work if given the -k/--insecure option. Using your own certificate from a certificate authority will avoid these warnings.
125
134
 
135
+ ## Available Options
136
+
137
+ ```
138
+ usage: __main__.py [-h] [--cgi] [--allow-replace] [--bind ADDRESS]
139
+ [--directory DIRECTORY] [--theme {light,auto,dark}]
140
+ [--server-certificate SERVER_CERTIFICATE]
141
+ [--client-certificate CLIENT_CERTIFICATE]
142
+ [--basic-auth BASIC_AUTH]
143
+ [--basic-auth-upload BASIC_AUTH_UPLOAD]
144
+ [port]
145
+
146
+ positional arguments:
147
+ port Specify alternate port [default: 8000]
148
+
149
+ options:
150
+ -h, --help show this help message and exit
151
+ --cgi Run as CGI Server
152
+ --allow-replace Replace existing file if uploaded file has the same
153
+ name. Auto rename by default.
154
+ --bind, -b ADDRESS Specify alternate bind address [default: all
155
+ interfaces]
156
+ --directory, -d DIRECTORY
157
+ Specify alternative directory [default:current
158
+ directory]
159
+ --theme {light,auto,dark}
160
+ Specify a light or dark theme for the upload page
161
+ [default: auto]
162
+ --server-certificate, --certificate, -c SERVER_CERTIFICATE
163
+ Specify HTTPS server certificate to use [default:
164
+ none]
165
+ --client-certificate CLIENT_CERTIFICATE
166
+ Specify HTTPS client certificate to accept for mutual
167
+ TLS [default: none]
168
+ --basic-auth BASIC_AUTH
169
+ Specify user:pass for basic authentication (downloads
170
+ and uploads)
171
+ --basic-auth-upload BASIC_AUTH_UPLOAD
172
+ Specify user:pass for basic authentication (uploads
173
+ only)
174
+ ```
175
+
176
+ ## Breaking Changes in 6.0.0
177
+
178
+ - Support for Python 3.8 dropped.
179
+
126
180
  ## Breaking Changes in 5.0.0
127
181
 
128
182
  - Support for Python 3.6-7 dropped.
@@ -1,17 +1,3 @@
1
- Metadata-Version: 2.1
2
- Name: uploadserver
3
- Version: 5.2.2
4
- Summary: Python's http.server extended to include a file upload page
5
- Home-page: https://github.com/Densaugeo/uploadserver
6
- Author: Densaugeo
7
- Author-email: author@example.com
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: License :: OSI Approved :: MIT License
10
- Classifier: Operating System :: OS Independent
11
- Requires-Python: >=3.8
12
- Description-Content-Type: text/markdown
13
- License-File: LICENSE
14
-
15
1
  # uploadserver
16
2
 
17
3
  Python's http.server extended to include a file upload page
@@ -23,8 +9,8 @@ Python's http.server extended to include a file upload page
23
9
 
24
10
  | Platform | Supported? | Notes |
25
11
  |-|-|-|
26
- | Python 3.8+ | Yes | Tested on 3.8 through 3.12 every release. |
27
- | Python 3.6-3.7 | No | Was supported by previous versions. |
12
+ | Python 3.9+ | Yes | Tested on 3.9 through 3.14 every release. |
13
+ | Python 3.6-3.8 | No | Was supported by previous versions. |
28
14
  | Python 3.5- | No | |
29
15
  | Linux | Yes | Tested on Fedora and Ubuntu every release. |
30
16
  | Windows | Yes | Occasional manual testing. Haven't noticed any obvious problems. |
@@ -32,13 +18,13 @@ Python's http.server extended to include a file upload page
32
18
 
33
19
  ## Installation
34
20
 
35
- ~~~
21
+ ~~~bash
36
22
  python3 -m pip install --user uploadserver
37
23
  ~~~
38
24
 
39
25
  ## Usage
40
26
 
41
- ~~~
27
+ ~~~bash
42
28
  python3 -m uploadserver
43
29
  ~~~
44
30
 
@@ -49,18 +35,18 @@ After the server starts, the upload page is at /upload. For example, if the serv
49
35
  Warning: This is an upload server, and running it will allow uploads.
50
36
 
51
37
  Now supports uploading multiple files at once! Select multiple files in the web page's file selector, or upload with cURL:
52
- ~~~
38
+ ~~~bash
53
39
  curl -X POST http://127.0.0.1:8000/upload -F 'files=@multiple-example-1.txt' -F 'files=@multiple-example-2.txt'
54
40
  ~~~
55
41
 
56
42
  ## Basic Authentication (downloads and uploads)
57
43
 
58
- ~~~
44
+ ~~~bash
59
45
  python3 -m uploadserver --basic-auth hello:world
60
46
  ~~~
61
47
 
62
48
  Now you can upload with basic authentication. For example:
63
- ~~~
49
+ ~~~bash
64
50
  curl -X POST http://127.0.0.1:8000/upload -F 'files=@basicauth-example.txt' -u hello:world
65
51
  ~~~
66
52
 
@@ -68,7 +54,7 @@ All requests without authentication will be rejected. Note that basic authentica
68
54
 
69
55
  ## Basic Authentication (uploads only)
70
56
 
71
- ~~~
57
+ ~~~bash
72
58
  python3 -m uploadserver --basic-auth-upload hello:world
73
59
  ~~~
74
60
 
@@ -79,18 +65,18 @@ If both `--basic-auth` and `--basic-auth-upload` are specified, all requests wil
79
65
  ## Theme Option
80
66
 
81
67
  The upload page supports a dark mode for showing white text on black background. If no option is specified, the color scheme is chosen from the client’s browser’s preference (which typically matches their operating system’s setting, if light or dark mode is supported by the OS). To enforce the light or dark theme, the CLI parameter `--theme` can be used:
82
- ~~~
68
+ ~~~bash
83
69
  python3 -m uploadserver --theme light
84
70
  ~~~
85
71
  or
86
- ~~~
72
+ ~~~bash
87
73
  python3 -m uploadserver --theme dark
88
74
  ~~~
89
75
 
90
76
  ## HTTPS Option
91
77
 
92
78
  Run with HTTPS and without client authentication:
93
- ~~~
79
+ ~~~bash
94
80
  # Generate self-signed server certificate
95
81
  openssl req -x509 -out server.pem -keyout server.pem -newkey rsa:2048 -nodes -sha256 -subj '/CN=server'
96
82
 
@@ -103,7 +89,7 @@ curl -X POST https://localhost:8000/upload --insecure -F files=@simple-example.t
103
89
  ~~~
104
90
 
105
91
  Run with HTTPS and with client authentication:
106
- ~~~
92
+ ~~~bash
107
93
  # Generate self-signed server certificate
108
94
  openssl req -x509 -out server.pem -keyout server.pem -newkey rsa:2048 -nodes -sha256 -subj '/CN=server'
109
95
 
@@ -123,6 +109,51 @@ curl -X POST https://localhost:8000/upload --insecure --cert client.pem -F files
123
109
 
124
110
  Note: This uses a self-signed server certificate which clients such as web browser and cURL will warn about. Most browsers will allow you to proceed after adding an exception, and cURL will work if given the -k/--insecure option. Using your own certificate from a certificate authority will avoid these warnings.
125
111
 
112
+ ## Available Options
113
+
114
+ ```
115
+ usage: __main__.py [-h] [--cgi] [--allow-replace] [--bind ADDRESS]
116
+ [--directory DIRECTORY] [--theme {light,auto,dark}]
117
+ [--server-certificate SERVER_CERTIFICATE]
118
+ [--client-certificate CLIENT_CERTIFICATE]
119
+ [--basic-auth BASIC_AUTH]
120
+ [--basic-auth-upload BASIC_AUTH_UPLOAD]
121
+ [port]
122
+
123
+ positional arguments:
124
+ port Specify alternate port [default: 8000]
125
+
126
+ options:
127
+ -h, --help show this help message and exit
128
+ --cgi Run as CGI Server
129
+ --allow-replace Replace existing file if uploaded file has the same
130
+ name. Auto rename by default.
131
+ --bind, -b ADDRESS Specify alternate bind address [default: all
132
+ interfaces]
133
+ --directory, -d DIRECTORY
134
+ Specify alternative directory [default:current
135
+ directory]
136
+ --theme {light,auto,dark}
137
+ Specify a light or dark theme for the upload page
138
+ [default: auto]
139
+ --server-certificate, --certificate, -c SERVER_CERTIFICATE
140
+ Specify HTTPS server certificate to use [default:
141
+ none]
142
+ --client-certificate CLIENT_CERTIFICATE
143
+ Specify HTTPS client certificate to accept for mutual
144
+ TLS [default: none]
145
+ --basic-auth BASIC_AUTH
146
+ Specify user:pass for basic authentication (downloads
147
+ and uploads)
148
+ --basic-auth-upload BASIC_AUTH_UPLOAD
149
+ Specify user:pass for basic authentication (uploads
150
+ only)
151
+ ```
152
+
153
+ ## Breaking Changes in 6.0.0
154
+
155
+ - Support for Python 3.8 dropped.
156
+
126
157
  ## Breaking Changes in 5.0.0
127
158
 
128
159
  - Support for Python 3.6-7 dropped.
@@ -5,7 +5,7 @@ with open('README.md', 'r') as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name='uploadserver',
8
- version='5.2.2',
8
+ version='6.0.1',
9
9
  author='Densaugeo',
10
10
  author_email='author@example.com',
11
11
  description='Python\'s http.server extended to include a file upload page',
@@ -18,7 +18,7 @@ setuptools.setup(
18
18
  'License :: OSI Approved :: MIT License',
19
19
  'Operating System :: OS Independent',
20
20
  ],
21
- python_requires='>=3.8',
21
+ python_requires='>=3.9',
22
22
  entry_points = {
23
23
  'console_scripts': ['uploadserver=uploadserver:main'],
24
24
  }
@@ -1,4 +1,5 @@
1
1
  import http.server, http, pathlib, sys, argparse, ssl, os, builtins, tempfile
2
+ import ipaddress
2
3
  import base64, binascii, functools, contextlib
3
4
 
4
5
  # Does not seem to do be used, but leaving this import out causes uploadserver
@@ -18,7 +19,7 @@ COLOR_SCHEME = {
18
19
  'dark': 'dark',
19
20
  }
20
21
 
21
- def get_upload_page(theme):
22
+ def get_upload_page(theme: str) -> bytes:
22
23
  return bytes('''<!DOCTYPE html>
23
24
  <html>
24
25
  <head>
@@ -74,7 +75,7 @@ document.getElementsByTagName('form')[0].addEventListener('submit', async e => {
74
75
  </script>
75
76
  </html>''', 'utf-8')
76
77
 
77
- def get_directory_head_injection(theme):
78
+ def get_directory_head_injection(theme: str) -> bytes:
78
79
  return bytes('''<!-- Injected by uploadserver -->
79
80
  <meta name="viewport" content="width=device-width" />
80
81
  <meta name="color-scheme" content="''' + COLOR_SCHEME.get(theme) + '''">
@@ -88,7 +89,7 @@ DIRECTORY_BODY_INJECTION = b'''<!-- Injected by uploadserver -->
88
89
  <!-- End injection by uploadserver -->
89
90
  '''
90
91
 
91
- def send_upload_page(handler):
92
+ def send_upload_page(handler: http.server.BaseHTTPRequestHandler):
92
93
  handler.send_response(http.HTTPStatus.OK)
93
94
  handler.send_header('Content-Type', 'text/html; charset=utf-8')
94
95
  handler.send_header('Content-Length', len(get_upload_page(args.theme)))
@@ -99,7 +100,7 @@ class PersistentFieldStorage(cgi.FieldStorage):
99
100
  # Override cgi.FieldStorage.make_file() method. Valid for Python 3.1 ~ 3.10.
100
101
  # Modified version of the original .make_file() method (base copied from
101
102
  # Python 3.10)
102
- def make_file(self):
103
+ def make_file(self) -> object:
103
104
  if self._binary_file:
104
105
  return tempfile.NamedTemporaryFile(mode = 'wb+',
105
106
  dir = args.directory, delete = False)
@@ -107,7 +108,9 @@ class PersistentFieldStorage(cgi.FieldStorage):
107
108
  return tempfile.NamedTemporaryFile("w+", dir = args.directory,
108
109
  delete = False, encoding = self.encoding, newline = '\n')
109
110
 
110
- def auto_rename(path):
111
+ # True argument/return type is str | pathlib.Path, but Python 3.9 doesn't
112
+ # support |
113
+ def auto_rename(path: pathlib.Path) -> pathlib.Path:
111
114
  if not os.path.exists(path):
112
115
  return path
113
116
  (base, ext) = os.path.splitext(path)
@@ -117,7 +120,8 @@ def auto_rename(path):
117
120
  return renamed_path
118
121
  raise FileExistsError(f'File {path} already exists.')
119
122
 
120
- def receive_upload(handler):
123
+ def receive_upload(handler: http.server.BaseHTTPRequestHandler,
124
+ ) -> tuple[http.HTTPStatus, str]:
121
125
  result = (http.HTTPStatus.INTERNAL_SERVER_ERROR, 'Server error')
122
126
  name_conflict = False
123
127
 
@@ -153,16 +157,19 @@ def receive_upload(handler):
153
157
  os.rename(source, destination)
154
158
  # class '_io.BytesIO', small file (< 1000B, in cgi.py), in-memory
155
159
  # buffer
156
- else:
160
+ else:
157
161
  with open(destination, 'wb') as f:
158
162
  f.write(field.file.read())
159
- handler.log_message(f'[Uploaded] "{filename}" --> {destination}')
163
+ handler.log_message('[Uploaded] "%s" --> %s', filename, destination)
160
164
  result = (http.HTTPStatus.NO_CONTENT, 'Some filename(s) changed '
161
165
  'due to name conflict' if name_conflict else 'Files accepted')
162
166
 
163
167
  return result
164
168
 
165
- def check_http_authentication_header(handler, auth):
169
+ # True return type is tuple[bool, str | None], but Python 3.9 doesn't support |
170
+ def check_http_authentication_header(
171
+ handler: http.server.BaseHTTPRequestHandler, auth: str,
172
+ ) -> tuple[bool, str]:
166
173
  auth_header = handler.headers.get('Authorization')
167
174
  if auth_header is None:
168
175
  return (False, 'No credentials given')
@@ -186,7 +193,8 @@ def check_http_authentication_header(handler, auth):
186
193
 
187
194
  return (True, None)
188
195
 
189
- def check_http_authentication(handler):
196
+ def check_http_authentication(handler: http.server.BaseHTTPRequestHandler
197
+ ) -> bool:
190
198
  """
191
199
  This function should be called in at the beginning of HTTP method handler.
192
200
  It validates Authorization header and sends back 401 response on failure.
@@ -219,7 +227,7 @@ def check_http_authentication(handler):
219
227
  valid, message = check_http_authentication_header(handler, args.basic_auth_upload)
220
228
 
221
229
  if not valid:
222
- handler.log_message(f'Request rejected ({message})')
230
+ handler.log_message('Request rejected (%s)', message)
223
231
  handler.send_response(http.HTTPStatus.UNAUTHORIZED, message)
224
232
  handler.send_header('WWW-Authenticate', 'Basic realm="uploadserver"')
225
233
  handler.end_headers()
@@ -251,7 +259,8 @@ class ListDirectoryInterception:
251
259
  content = content.replace(b'<ul>', DIRECTORY_BODY_INJECTION + b'<ul>')
252
260
  outputfile.write(content)
253
261
 
254
- def list_directory(self, path):
262
+ # True argument type is str | pathlib.Path, but Python 3.9 doesn't support |
263
+ def list_directory(self, path: pathlib.Path) -> object:
255
264
  setattr(self, 'flush_headers', self.flush_headers_interceptor)
256
265
  setattr(self, 'copyfile', self.copyfile_interceptor)
257
266
 
@@ -323,7 +332,7 @@ def intercept_first_print():
323
332
  builtins.print = old_print
324
333
  builtins.print = new_print
325
334
 
326
- def ssl_wrap(socket):
335
+ def ssl_wrap(socket: socket.socket) -> ssl.SSLSocket:
327
336
  context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
328
337
  server_root = pathlib.Path(args.directory).resolve()
329
338
 
@@ -444,5 +453,14 @@ def main():
444
453
 
445
454
  args = parser.parse_args()
446
455
  if not hasattr(args, 'directory'): args.directory = os.getcwd()
456
+ if args.bind:
457
+ try:
458
+ ipaddress.ip_address(args.bind)
459
+ except ValueError:
460
+ parser.error(
461
+ 'Invalid -b/--bind address. Expected an IP address (no port). '
462
+ 'Example: -b 192.168.1.10 and pass the port as a separate '
463
+ 'argument.'
464
+ )
447
465
 
448
466
  serve_forever()
@@ -1,3 +1,26 @@
1
+ Metadata-Version: 2.4
2
+ Name: uploadserver
3
+ Version: 6.0.1
4
+ Summary: Python's http.server extended to include a file upload page
5
+ Home-page: https://github.com/Densaugeo/uploadserver
6
+ Author: Densaugeo
7
+ Author-email: author@example.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.9
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Dynamic: author
15
+ Dynamic: author-email
16
+ Dynamic: classifier
17
+ Dynamic: description
18
+ Dynamic: description-content-type
19
+ Dynamic: home-page
20
+ Dynamic: license-file
21
+ Dynamic: requires-python
22
+ Dynamic: summary
23
+
1
24
  # uploadserver
2
25
 
3
26
  Python's http.server extended to include a file upload page
@@ -9,8 +32,8 @@ Python's http.server extended to include a file upload page
9
32
 
10
33
  | Platform | Supported? | Notes |
11
34
  |-|-|-|
12
- | Python 3.8+ | Yes | Tested on 3.8 through 3.12 every release. |
13
- | Python 3.6-3.7 | No | Was supported by previous versions. |
35
+ | Python 3.9+ | Yes | Tested on 3.9 through 3.14 every release. |
36
+ | Python 3.6-3.8 | No | Was supported by previous versions. |
14
37
  | Python 3.5- | No | |
15
38
  | Linux | Yes | Tested on Fedora and Ubuntu every release. |
16
39
  | Windows | Yes | Occasional manual testing. Haven't noticed any obvious problems. |
@@ -18,13 +41,13 @@ Python's http.server extended to include a file upload page
18
41
 
19
42
  ## Installation
20
43
 
21
- ~~~
44
+ ~~~bash
22
45
  python3 -m pip install --user uploadserver
23
46
  ~~~
24
47
 
25
48
  ## Usage
26
49
 
27
- ~~~
50
+ ~~~bash
28
51
  python3 -m uploadserver
29
52
  ~~~
30
53
 
@@ -35,18 +58,18 @@ After the server starts, the upload page is at /upload. For example, if the serv
35
58
  Warning: This is an upload server, and running it will allow uploads.
36
59
 
37
60
  Now supports uploading multiple files at once! Select multiple files in the web page's file selector, or upload with cURL:
38
- ~~~
61
+ ~~~bash
39
62
  curl -X POST http://127.0.0.1:8000/upload -F 'files=@multiple-example-1.txt' -F 'files=@multiple-example-2.txt'
40
63
  ~~~
41
64
 
42
65
  ## Basic Authentication (downloads and uploads)
43
66
 
44
- ~~~
67
+ ~~~bash
45
68
  python3 -m uploadserver --basic-auth hello:world
46
69
  ~~~
47
70
 
48
71
  Now you can upload with basic authentication. For example:
49
- ~~~
72
+ ~~~bash
50
73
  curl -X POST http://127.0.0.1:8000/upload -F 'files=@basicauth-example.txt' -u hello:world
51
74
  ~~~
52
75
 
@@ -54,7 +77,7 @@ All requests without authentication will be rejected. Note that basic authentica
54
77
 
55
78
  ## Basic Authentication (uploads only)
56
79
 
57
- ~~~
80
+ ~~~bash
58
81
  python3 -m uploadserver --basic-auth-upload hello:world
59
82
  ~~~
60
83
 
@@ -65,18 +88,18 @@ If both `--basic-auth` and `--basic-auth-upload` are specified, all requests wil
65
88
  ## Theme Option
66
89
 
67
90
  The upload page supports a dark mode for showing white text on black background. If no option is specified, the color scheme is chosen from the client’s browser’s preference (which typically matches their operating system’s setting, if light or dark mode is supported by the OS). To enforce the light or dark theme, the CLI parameter `--theme` can be used:
68
- ~~~
91
+ ~~~bash
69
92
  python3 -m uploadserver --theme light
70
93
  ~~~
71
94
  or
72
- ~~~
95
+ ~~~bash
73
96
  python3 -m uploadserver --theme dark
74
97
  ~~~
75
98
 
76
99
  ## HTTPS Option
77
100
 
78
101
  Run with HTTPS and without client authentication:
79
- ~~~
102
+ ~~~bash
80
103
  # Generate self-signed server certificate
81
104
  openssl req -x509 -out server.pem -keyout server.pem -newkey rsa:2048 -nodes -sha256 -subj '/CN=server'
82
105
 
@@ -89,7 +112,7 @@ curl -X POST https://localhost:8000/upload --insecure -F files=@simple-example.t
89
112
  ~~~
90
113
 
91
114
  Run with HTTPS and with client authentication:
92
- ~~~
115
+ ~~~bash
93
116
  # Generate self-signed server certificate
94
117
  openssl req -x509 -out server.pem -keyout server.pem -newkey rsa:2048 -nodes -sha256 -subj '/CN=server'
95
118
 
@@ -109,6 +132,51 @@ curl -X POST https://localhost:8000/upload --insecure --cert client.pem -F files
109
132
 
110
133
  Note: This uses a self-signed server certificate which clients such as web browser and cURL will warn about. Most browsers will allow you to proceed after adding an exception, and cURL will work if given the -k/--insecure option. Using your own certificate from a certificate authority will avoid these warnings.
111
134
 
135
+ ## Available Options
136
+
137
+ ```
138
+ usage: __main__.py [-h] [--cgi] [--allow-replace] [--bind ADDRESS]
139
+ [--directory DIRECTORY] [--theme {light,auto,dark}]
140
+ [--server-certificate SERVER_CERTIFICATE]
141
+ [--client-certificate CLIENT_CERTIFICATE]
142
+ [--basic-auth BASIC_AUTH]
143
+ [--basic-auth-upload BASIC_AUTH_UPLOAD]
144
+ [port]
145
+
146
+ positional arguments:
147
+ port Specify alternate port [default: 8000]
148
+
149
+ options:
150
+ -h, --help show this help message and exit
151
+ --cgi Run as CGI Server
152
+ --allow-replace Replace existing file if uploaded file has the same
153
+ name. Auto rename by default.
154
+ --bind, -b ADDRESS Specify alternate bind address [default: all
155
+ interfaces]
156
+ --directory, -d DIRECTORY
157
+ Specify alternative directory [default:current
158
+ directory]
159
+ --theme {light,auto,dark}
160
+ Specify a light or dark theme for the upload page
161
+ [default: auto]
162
+ --server-certificate, --certificate, -c SERVER_CERTIFICATE
163
+ Specify HTTPS server certificate to use [default:
164
+ none]
165
+ --client-certificate CLIENT_CERTIFICATE
166
+ Specify HTTPS client certificate to accept for mutual
167
+ TLS [default: none]
168
+ --basic-auth BASIC_AUTH
169
+ Specify user:pass for basic authentication (downloads
170
+ and uploads)
171
+ --basic-auth-upload BASIC_AUTH_UPLOAD
172
+ Specify user:pass for basic authentication (uploads
173
+ only)
174
+ ```
175
+
176
+ ## Breaking Changes in 6.0.0
177
+
178
+ - Support for Python 3.8 dropped.
179
+
112
180
  ## Breaking Changes in 5.0.0
113
181
 
114
182
  - Support for Python 3.6-7 dropped.
File without changes
File without changes