Created
July 9, 2012 14:16
-
-
Save vgel/3076825 to your computer and use it in GitHub Desktop.
A very basic HTTP file server in 13 lines of python. Assumes all requests are GETs, and it vulnerable to directory traversal (Run it in ~ and localhost:8080/../../ will ls root), so don't use it online. Will correctly list files in directories.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys, os, socket | |
s = socket.socket() | |
s.bind((sys.argv[1], int(sys.argv[2]))) | |
s.listen(5) | |
try: | |
while True: | |
conn, addr = s.accept() | |
path = os.path.join(os.getcwd(), "./"+conn.recv(4096).split("\n")[0].split(" ")[1]) | |
conn.send((open(path).read() if os.path.isfile(path) else reduce(lambda x,s:x+"\n"+s+("/" if os.path.isdir(s) else ""),sorted(os.listdir(path)),"Directory "+path+" ls")) if os.path.exists(path) else '404: '+path) | |
conn.close() | |
finally: | |
s.close() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/env python | |
#pretty version | |
import sys, os, socket | |
s = socket.socket() #set up out socket | |
s.bind((sys.argv[1], int(sys.argv[2]))) #bind (I usually pass in localhost 8080, you will need root for a port < 1000) | |
s.listen(5) #start listening, drop all connection if we have > 5 waiting connections | |
try: | |
while True: #listen loop | |
conn, addr = s.accept() #block for a connection | |
request = conn.recv(4096) #read up to 4 kb, I figure no get request should be more than this | |
first_line = request.split("\n")[0] #get the GET <path> HTTP/1.1 line, this should be "\r\n" but it doesn't make a difference for this | |
requested_file = first_line.split(" ")[1] #the the <path> part | |
path = os.path.join(os.getcwd(), "./" + requested_file) #join to current directory. THIS DOES NOT PROTECT AGAINST DIRECTORY TRAVERSAL!! | |
if os.path.exists(path): #checks to see is we have a file, obviously | |
if os.path.isfile(path): | |
conn.send(open(path).read()) #read that file. Seems to fail on very large files. | |
else: | |
conn.send("Directory " + path + " ls\n") #send the header | |
for p in sorted(os.listdir(path)): #sort, does not put directories first like most file servers | |
if os.path.isdir(p): | |
conn.send(p + "/\n") #append a forward slash | |
else: | |
conn.send(p + "\n") | |
else: | |
conn.send("404: " + path) #meh | |
conn.close() #we're done here | |
finally: | |
s.close() #close the socket, freeing the port so we can relaunch on it |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment