Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions scripts/shttpd.r
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
REBOL [title: "A tiny static HTTP server" author: 'abolka date: 2009-11-04]

crlf2bin: to binary! join-of crlf crlf
code-map: make map! [200 "OK" 400 "Forbidden" 404 "Not Found"]
mime-map: make map! [
"html" "text/html" "css" "text/css" "js" "application/javascript"
"gif" "image/gif" "jpg" "image/jpeg" "png" "image/png"
"r" "text/plain" "r3" "text/plain" "reb" "text/plain"

]
error-template: trim/auto {
error-template: trim/auto copy {
<html><head><title>$code $text</title></head><body><h1>$text</h1>
<p>Requested URI: <code>$uri</code></p><hr><i>shttpd.r</i> on
<a href="http://www.rebol.com/rebol3/">REBOL 3</a> $r3</body></html>
Expand Down Expand Up @@ -37,28 +39,35 @@ send-chunk: func [port] [
unless empty? port/locals [write port take/part port/locals 32'000]
]

handle-request: func [config req /local uri type file data] [
handle-request: func [config req /local uri type file data ext] [
parse to-string req ["get " ["/ " | copy uri to " "]]
default 'uri "index.html"
parse uri [some [thru "."] copy ext to end (type: mime-map/:ext)]
default 'type "application/octet-stream"
uri: default ["index.html"]
parse uri [some [thru "."] copy ext: to end (type: select mime-map ext)]
type: default ["application/octet-stream"]
if not exists? file: config/root/:uri [return error-response 404 uri]
if error? try [data: read file] [return error-response 400 uri]
reduce [200 type data]
]

awake-client: func [event /local port res] [
port: event/port
print ["Event type: " event/type]
switch event/type [
read [
either find port/data to-binary join crlf crlf [
either find port/data crlf2bin [
res: handle-request port/locals/config port/data
start-response port res
] [
read port
]
]
wrote [unless send-chunk port [close port]]
wrote [
either empty? port/locals [
close port
][
send-chunk port
]
]
close [close port]
]
]
Expand All @@ -72,9 +81,10 @@ awake-server: func [event /local client] [
]

serve: func [web-port web-root /local listen-port] [
listen-port: open join tcp://: web-port
listen-port/locals: construct compose/deep [config: [root: (web-root)]]
listen-port: open rejoin [tcp://: web-port]
listen-port/locals: make object! compose/deep [config: [root: (web-root)]]
listen-port/awake: :awake-server
print ajoin ["serving on port " web-port "..."]
wait listen-port
]

Expand Down