-
-
Save fabiand/5628006 to your computer and use it in GitHub Desktop.
# python3 -m SimpleHTTPPutServer 8080 | |
from http.server import HTTPServer, SimpleHTTPRequestHandler | |
class PutHTTPRequestHandler(SimpleHTTPRequestHandler): | |
def do_PUT(self): | |
print(self.headers) | |
length = int(self.headers["Content-Length"]) | |
path = self.translate_path(self.path) | |
with open(path, "wb") as dst: | |
dst.write(self.rfile.read(length)) | |
self.send_response(200) | |
self.end_headers() | |
def run(server_class=HTTPServer, handler_class=PutHTTPRequestHandler): | |
server_address = ('', 8000) | |
httpd = server_class(server_address, handler_class) | |
httpd.serve_forever() | |
if __name__ == '__main__': | |
run() |
Hey Maruf you gotta execute the script in python not python3
Python 2 is end of life. Why not align to Python 3? If there is something built into Python 3 that could be used instead, would be worth mentioning this here.
Yes this would be great!
Here, based on https://gist.github.com/mdonkers/63e115cc0c79b4f6b8b3a6b797e485c7
DISCLAIMER: I added protection for access outside the running directory, but I don't guarantee it cannot be bypassed.
#!/usr/bin/env python3
"""
Very simple HTTP file server in python
Usage::
./server.py [<port>]
"""
from http.server import BaseHTTPRequestHandler, HTTPServer
import mimetypes
import os
import pathlib
cwd = os.path.normcase(os.getcwd())
class S(BaseHTTPRequestHandler):
def __init__(self, *args, directory=None, **kwargs):
self.protocol_version = 'HTTP/1.1'
super().__init__(*args, **kwargs)
def _send_response(self, code = 200, msg='Done', content_type='text/plain'):
body = msg.encode('utf-8')
self.send_response(code)
self.send_header('Content-type', content_type)
self.send_header('Content-Length', len(body))
self.end_headers()
self.wfile.write(body)
def req_path(self):
fname = self.path[1:] # Strip leading slash
path = os.path.normcase(os.path.dirname(os.path.realpath(fname)))
if os.path.commonpath((path, cwd)) == cwd:
return fname
raise Exception("Access denied")
def do_GET(self):
try:
with open(self.req_path(), "rb") as src:
self._send_response(200, src.read(), mimetypes.guess_type(self.req_path()))
except:
self._send_response(404, '404 Not Found\r\n')
def do_PUT(self):
try:
path = self.req_path()
pathlib.Path(path).parent.mkdir(parents=True, exist_ok=True)
with open(path, "wb") as dst:
content_length = int(self.headers['Content-Length'])
dst.write(self.rfile.read(content_length))
self._send_response(200, 'Done\r\n')
except Exception as ex:
print(ex)
self._send_response(500, '500 Access Denied\r\n')
def do_POST(self):
return self.do_PUT()
def run(port=8000):
server_address = ('', port)
httpd = HTTPServer(server_address, S)
print(f'Listening on port {port}')
try:
httpd.serve_forever()
except KeyboardInterrupt:
pass
httpd.server_close()
if __name__ == '__main__':
from sys import argv
if len(argv) == 2:
run(port=int(argv[1]))
else:
run()
Thanks @orgads. That is what I was looking for. It works fine for me.
hello i have a question how can i make simpleHTTPServer work it give error when i use it give it print self.headers
^^^^^^^^^^^^^^^^^^^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(...)?
i use prython 3
Hello @stefanstruik. Check the code that @orgads shared here. If you want to run the first code (of @fabiand ) you need to install python 2.7
I can do you ok in a zip existence for me I still have it for my education
het works thanks jou wel
Crazy how old this snippet is by now.
help i have a question how can i make simpleHTTPServer work it give error when i use it give python: can't open file SimpleHTTPPutServer': [Errno 2] No such file or directory i use Python 3.10.8
gr stefan
I made a few changes to @orgads' implementation --- thank you! --- that suit my needs. The GET method didn't work, because the file content was already binary while _send_response
expected the message to be still a string. If you want to read it binary for optimal efficiency, just edit _send_response
instead.
Also, I used it in a web-browser, where multiple files where being retrieved. It made me wait for 2 minutes before axios fetched it and I never saw it in the log. This is because the non-threaded version of the previous authors will simply not see the request coming in and ignore it, until axios tries another time (apparently, that is after 2 minutes). I solved it by using a threaded server from the same http.server
library.
The disclaimer still holds:
DISCLAIMER: I added protection for access outside the running directory, but I don't guarantee it cannot be bypassed.
I recommend looking at the script --- it's not hard. But for those who don't have the time, the directory being served is expected to be the current working directory of the script (cwd = os.path.normcase(os.getcwd())
), so either move to the directory and execute the script from there, or configure it so you can pass a parameter and share your updated version here ;-) I did the former with one of my scripts ("serve": "cd data; python3 ./server.py 8756"
)
#!/usr/bin/env python3
"""
Very simple HTTP file server in python
Usage::
./server.py [<port>]
Authors::
fabiand, orgads, TijlE-1951707 (https://gist.github.com/fabiand/5628006)
"""
from http.server import BaseHTTPRequestHandler, HTTPServer, ThreadingHTTPServer
import mimetypes
import os
import pathlib
# # https://stackoverflow.com/questions/62599036/python-requests-is-slow-and-takes-very-long-to-complete-http-or-https-request
# import logging
# import http.server
# BaseHTTPRequestHandler=http.server.BaseHTTPRequestHandler
# HTTPServer=http.server.HTTPServer
# http.server.BaseHTTPRequestHandler.debuglevel = 1
# http.server.HTTPServer.debuglevel = 1
# logging.basicConfig()
# logging.getLogger().setLevel(logging.DEBUG)
cwd = os.path.normcase(os.getcwd())
print(cwd)
class S(BaseHTTPRequestHandler):
def __init__(self, *args, directory=None, **kwargs):
self.protocol_version = 'HTTP/1.1'
super().__init__(*args, **kwargs)
def _send_response(self, code = 200, msg='Done', content_type='text/plain'):
body = msg.encode('utf-8')
self.send_response(code)
self.send_header('Content-type', content_type)
self.send_header('Content-Length', len(body))
# self.send_header('Keep-Alive', "timeout=5")
# self.send_header('Connection', "keep-alive")
self.send_header('Cache-Control', "no-store") # seemed to be necessary to GET through axios, and added in GET through Insomnia
# self.send_header('Cache-Control', "no-cache, no-store, must-revalidate") # is all that Insomnia added to custom requests
self.end_headers()
self.wfile.write(body)
def req_path(self):
fname = self.path[1:] # Strip leading slash
path = os.path.normcase(os.path.dirname(os.path.realpath(fname)))
if os.path.commonpath((path, cwd)) == cwd:
return fname.replace("%20", " ")
raise Exception("Access denied")
def do_GET(self):
try:
path = self.req_path()
mime_type = mimetypes.guess_type(self.req_path())
content_type = ('text/plain' if (t:= mime_type[0]) == None else t) + ('' if (e := mime_type[1]) == None else f"; charset={e}")
with open(path, "r") as src:
self._send_response(200, src.read(), content_type)
except FileNotFoundError as ex:
self._send_response(404, '404 Not Found\r\n')
except BrokenPipeError as ex:
print("client disconnected")
print(ex)
except Exception as ex:
print(ex, type(ex))
self._send_response(500, 'Internal server error\r\n')
def do_PUT(self):
try:
path = self.req_path()
pathlib.Path(path).parent.mkdir(parents=True, exist_ok=True)
with open(path, "wb") as dst:
content_length = int(self.headers['Content-Length'])
dst.write(self.rfile.read(content_length))
self._send_response(200, 'Done\r\n')
except Exception as ex:
print(ex)
self._send_response(403, '403 Access Denied\r\n')
# def do_POST(self):
# print("infinite loop?")
# return self.do_PUT()
def run(port=8000):
server_address = ('', port)
# httpd = HTTPServer(server_address, S) # WARNING: if the server is busy, it will completely miss incoming requests!
httpd = ThreadingHTTPServer(server_address, S)
print(f'Listening on port {port}')
try:
httpd.serve_forever()
except KeyboardInterrupt:
pass
httpd.server_close()
if __name__ == '__main__':
from sys import argv
if len(argv) == 2:
run(port=int(argv[1]))
else:
run()
I've updated the gist to stay minimal, but be python3 based.
For Python3 You Can Use Code From My WPG Project:
https://github.com/heyxmirko/Simple-Wifi-Password-Grabber