A web server in 30 lines of code

Just found myself writing that, and it was amusing.

import System.Net
import System.IO

if argv.Length != 2:
	print "You must pass [prefix] [path] as parameters"
	return

prefix = argv[0]
path = argv[1]

if not Directory.Exists(path):
	print "Could not find ${path}"
	return

listener = HttpListener()
listener.Prefixes.Add(prefix)
listener.Start()

while true:
	context = listener.GetContext()
	file = Path.GetFileName(context.Request.RawUrl)
	fullPath = Path.Combine(path, file)
	if File.Exists(fullPath):
		context.Response.AddHeader("Content-Disposition","attachment; filename=${file}")
		bytes = File.ReadAllBytes(fullPath)
		context.Response.OutputStream.Write(bytes, 0, bytes.Length)
		context.Response.OutputStream.Flush()
		context.Response.Close()
	else:
		context.Response.StatusCode = 404
		context.Response.Close()

Print | posted on Sunday, March 30, 2008 10:35 PM

Feedback


Gravatar

# re: A web server in 30 lines of code 3/30/2008 11:17 PM Pieter Joost van de Sande

Wow, let's benchmark! Instead of switching to IIS7 we should use this :)


Gravatar

 re: A web server in 30 lines of code 3/30/2008 11:31 PM Tuna Toksoz

the altdotnet style :)


 re: A web server in 30 lines of code 3/31/2008 7:31 PM Thomas Krause

But, what happens if you pass something like:
http://localhost/prefix/../../../Windows/System32/Secret.File

Sorry, couldn't resist ;-)


Gravatar

# re: A web server in 30 lines of code 3/31/2008 7:35 PM Ayende Rahien

Well, did you note

Path.GetFileName(context.Request.RawUrl)

??

That will stop those attacks


 re: A web server in 30 lines of code 3/31/2008 11:20 PM Thomas Krause

Oh, you're right. I missed that somehow. I read something like:

fullPath = Path.Combine(path, context.Request.RawUrl)

Nevermind...

Comments have been closed on this topic.