# coding: utf-8
require 'socket'
# Damit Ruby auch bei Fehlern im Thread abbricht mit Fehlermeldung
Thread.abort_on_exception=true
# 2 Methoden für Fehlermeldungen
def notfound(client, pfad, debug="")
msg = "
404 Not found
Sorry, ich bin halt nur ein Webserver... #{pfad} habe ich nicht gefunden...
Debug Info
#{debug}"
client.puts "HTTP/1.1 404 Not Found\r
Content-Type: text/html\r
Content-Length: #{msg.size}\r\n\r\n"
client.puts msg
puts "Got a 404"
end
def badRequest(client, req, debug="")
msg = "400 Bad request
Sorry, die Anfrage #{req} verstehe ich nicht.
Debug Info
#{debug}"
client.puts "HTTP/1.1 400 Bad request\r
Content-Type: text/html\r
Content-Length: #{msg.size}\r\n\r\n"
client.puts msg
puts "Got a 400"
end
# Methode für Dirlisting
def dirlist(client,basepfad, abspfad, relpfad)
relpfad = "/" if (relpfad=="")
puts "Dirlist für #{abspfad}, #{relpfad}"
files = Dir.glob(abspfad+"/*") # Alle Dateien im Verzeichnis
relpfad.gsub(/\/+$/,"") # Remove trailing slash
msg = "Directory #{relpfad}
"
relpfad.gsub!(/\/+$/,"") # Remove trailing slashes
files.each{|f|
f = File.basename(f)
puts relpfad
puts f
msg+="- #{f}
\n"
}
client.puts "HTTP/1.1 200 OK\r
Content-Type: text/html\r
Content-Length: #{msg.size}\r\n\r\n"
client.puts msg
puts "Listed #{abspfad}"
end
# Server auf port 420XX laufen lassen
server = TCPServer.open(42001)
# Endlos-Schleife
loop {
# Auf Verbindung warten.
# Wenn verbunden, einen Thread damit beschäftigen
# und gleich auf nächste Verbindung warten
Thread.start(server.accept) { |client|
# Request einlesen, zeilenweise im Array all speichern
all = []
while ((req=client.gets.chomp)!="")
puts req
all.push(req)
end
p all
# Erste Zeile analysieren
pfad = all[0].scan(/^GET ([^ ]+)/)
# Wenn kein Match, also bad request (nicht http-protokoll)
p pfad
if (pfad.size==0)
puts "400!"
badRequest(client, all[0], all.join("\n"))
else
puts
# Dem Request den ordner 'html' vorne anfügen
pfad = "html"+pfad[0][0]
# Daraus den absoluten Pfad erstellen
pfad = File.absolute_path(pfad)
# Überprüfen, ob auch im richtigen verzeichnis
# Aktueller Pfad plus html
richtig = File.absolute_path(Dir.pwd+"/html")
p pfad
p richtig
if pfad.start_with?(richtig) && File.exists?(pfad)
if (File.directory?(pfad))
dirlist(client,richtig, pfad, pfad.gsub(richtig,""))
else
puts "Got a 200"
# Typ bestimmen: Paare aus RegEx und MIME-Type (/i macht die regex case-insensitive)
types = [[/html?$/i,"text/html"],
[/jpe?g$/i,'image/jpg'],
[/png$/i,'image/png'],
[/gif/i, 'image/gif'],
[/txt/i, 'text/plain']]
type = "text/html" # Default, wenn nichts anderes gefunden
types.each{|t|
if pfad =~ t[0]
type=t[1]
end
}
daten = File.read(pfad)
client.puts "HTTP/1.1 200 OK\r
Content-Type: #{type}\r
Content-Length: #{daten.size}\r\n\r\n"
client.print daten
end
else
puts "Not found"
notfound(client, pfad, all.join("\n"))
end
end
client.close
}
}