Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
567 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
load("../julia_webserver_base.jl") | ||
load("sub.jl") | ||
|
||
mainHandler = Handler( | ||
function (f) | ||
f.render("index") | ||
end | ||
, | ||
function (f) | ||
c = f.get_argument("request", "2") | ||
f.set_cookie("user", c) | ||
f.write("thanks for post data $c") | ||
end | ||
) | ||
|
||
SourceLoopHandler = Handler( | ||
function (f) | ||
f.render("source/loop") | ||
end, | ||
nothing | ||
) | ||
|
||
__handlers = [ | ||
(r"/", mainHandler), | ||
(r"/source/loop", SourceLoopHandler), | ||
(r"/[^/]+", subHandler), | ||
] | ||
_setting = { | ||
debug = true | ||
} | ||
|
||
loop() |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
subHandler = Handler( | ||
function (f) | ||
f.write("welcome to sub") | ||
f.write("!haha") | ||
f.senderror(502) | ||
end | ||
, nothing) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
|
||
const DEFAULT_PROTOCOL = "HTTP/1.1" | ||
const DEFAULT_METHOD = "GET" | ||
const DEFAULT_PATH = "/" | ||
const LIB_PATH = "/home/cheney/juliawebserver/" | ||
const LIB_FILE_PREFIX = strcat(LIB_PATH, "julia_webserver_") | ||
const DEBUG = true | ||
|
||
function loads(mods::Array{ASCIIString}) | ||
for mod = mods | ||
load(strcat(LIB_FILE_PREFIX, mod, ".jl")) | ||
end | ||
end | ||
|
||
loads(["string", "type", "iostream", "template"]) | ||
load("./ui/webserver/message_types.h") | ||
|
||
|
||
|
||
|
||
|
||
function __htmlfunc_senderror(code) | ||
lib = { | ||
200 => "OK", | ||
301 => "Moved Permanently", | ||
302 => "Found", | ||
304 => "Forbidden", | ||
304 => "Not Modified", | ||
404 => "Not Found", | ||
405 => "Method Not Allowed", | ||
408 => "Request Timeout", | ||
500 => "Internal Server Error", | ||
502 => "Bad Gateway", | ||
504 => "Gateway Timeout" | ||
} | ||
"$code $(lib[code])" | ||
end | ||
|
||
function get_func(header) | ||
data = {"html" => "", "status" => "200 OK", "cookie" => []} | ||
func_base = Func( | ||
data,header, | ||
|
||
#write | ||
function (str) | ||
if str == nothing | ||
return | ||
end | ||
func_base.data["html"] = strcat(func_base.data["html"], ASCIIString(str.data)) | ||
end, | ||
|
||
#senderror | ||
function (code) | ||
func_base.data["status"] = __htmlfunc_senderror(code) | ||
func_base.data["html"] = func_base.data["status"] | ||
end, | ||
|
||
#get_argument | ||
function (field, default) | ||
if has(func_base.header.data, "args") && has(func_base.header.data["args"], field) | ||
return func_base.header.data["args"][field] | ||
end | ||
default | ||
end, | ||
|
||
#set cookie | ||
function (field, value) | ||
func_base.data["cookie"] = append(func_base.data["cookie"], [strcat(field, "=", value)]) | ||
end, | ||
|
||
#get cookie | ||
function (field, default) | ||
if has(func_base.header.data, "Cookie") && has(func_base.header.data["Cookie"], field) | ||
return func_base.header.data["Cookie"][field] | ||
end | ||
default | ||
end, | ||
|
||
#render | ||
function (filename) | ||
content = render_string(filename) | ||
func_base.write(content) | ||
end, | ||
) | ||
end | ||
|
||
function __socket_callback(fd) | ||
__msg = __read_header() | ||
put(__eval_channel, (fd, __msg)) | ||
end | ||
|
||
# event handler for socket input | ||
|
||
function __eval_exprs(__parsed_exprs) | ||
(fd, __msg) = __parsed_exprs | ||
f = nothing | ||
match_route = false | ||
for i = __handlers | ||
m = match(i[1], __msg.path) | ||
if m != nothing && m.match == __msg.path | ||
match_route = true | ||
f = get_func(__msg) | ||
if __msg.method == "GET" && i[2].get != nothing | ||
i[2].get(f) | ||
elseif __msg.method == "POST" && i[2].post != nothing | ||
i[2].post(f) | ||
else | ||
# method not allow | ||
f.senderror(405) | ||
end | ||
break | ||
end | ||
end | ||
|
||
if f != nothing && match_route | ||
html = f.data["html"] | ||
status = f.data["status"] | ||
cookie = f.data["cookie"] | ||
else | ||
status = __htmlfunc_senderror(404) | ||
html = status | ||
cookie = nothing | ||
end | ||
|
||
__write_back(html, status, cookie) | ||
__connect() | ||
end | ||
|
||
__ports = nothing | ||
__sockfd = nothing | ||
__connectfd = nothing | ||
__io = nothing | ||
__eval_channel = RemoteRef() | ||
function loop() | ||
global __connectfd, __io, __port, __sockfd | ||
__ports = [int16(4444)] | ||
__sockfd = ccall(:open_any_tcp_port, Int32, (Ptr{Int16},), __ports) | ||
if __sockfd == -1 | ||
# couldn't open the socket | ||
println("could not open server socket on port 4444.") | ||
exit() | ||
end | ||
println(__ports) | ||
__connect() | ||
add_fd_handler(__connectfd, __socket_callback) | ||
while true | ||
__eval_exprs(take(__eval_channel)) | ||
end | ||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
function __readline() | ||
global __io | ||
line = "" | ||
while true | ||
char = read(__io, Char) | ||
if char == '\n' | ||
break | ||
end | ||
line = strcat(line, char) | ||
end | ||
line | ||
end | ||
|
||
function __write_back(html, status, cookie) | ||
global __io, __connectfd | ||
write(__io, "$DEFAULT_PROTOCOL $status\n") | ||
write(__io, "Server: Microsoft-IIS/5.0\n") | ||
write(__io, "Content-Length: $(length(html))\n") | ||
if cookie != nothing && length(cookie) > 0 | ||
for i = cookie | ||
write(__io, "Set-Cookie: $i\n") | ||
end | ||
end | ||
write(__io, "Content-Type: text/html; charset=UTF-8\n\n") | ||
|
||
write(__io, "$html\n") | ||
flush(__io) | ||
close(__io) | ||
end | ||
|
||
function __connect() | ||
global __connectfd, __io | ||
__connectfd = ccall(:accept, Int32, (Int32, Ptr{Void}, Ptr{Void}), __sockfd, C_NULL, C_NULL) | ||
__io = fdio(__connectfd, true) | ||
end | ||
|
||
function __read_cookie(data) | ||
cookies = HashTable() | ||
|
||
cookies | ||
end | ||
|
||
function __read_header() | ||
line_index = 0 | ||
__method = DEFAULT_METHOD | ||
__path = DEFAULT_PATH | ||
__protocol = DEFAULT_PROTOCOL | ||
__data = HashTable() | ||
post_read_more_line = false | ||
|
||
while true | ||
line = __readline() | ||
if length(line) <= 1 | ||
if post_read_more_line | ||
post_read_more_line = false | ||
__data["args"] = __read_arguments_from_header(__data) | ||
end | ||
break | ||
end | ||
if line_index == 0 | ||
m = match(r"^(\w+)\s([^\s]+)\s([^\n\r]+)", line) | ||
(__method, __path, __protocol) = m.captures | ||
if __method == "POST" | ||
post_read_more_line = true | ||
end | ||
else | ||
m = match(r"^([\w\-]+)\:\s([^\n\r]+)", line) | ||
(key, value) = m.captures | ||
if key == "Cookie" | ||
local tmp = split(value, ';') | ||
local cookies = HashTable() | ||
for cookie_item = tmp | ||
(cookie_filed, cookie_value) = match(r"^\s*(\w+)=(.*)$", cookie_item).captures | ||
cookies[cookie_filed] = cookie_value | ||
end | ||
__data[key] = cookies | ||
else | ||
__data[key] = value | ||
end | ||
end | ||
line_index += 1 | ||
end | ||
__Header(__method, __path, __protocol, __data) | ||
end | ||
|
||
function __read_arguments_from_header(__data) | ||
if has(__data, "Content-Length") == false || int(__data["Content-Length"]) <= 0 | ||
return __data | ||
end | ||
argstring = read(__io, Uint8, int(__data["Content-Length"])) | ||
argstring = UTF8String(argstring) | ||
__args = split(argstring, '&') | ||
args_hash = HashTable() | ||
for arg_string = __args | ||
(key, value) = match(r"^([^=]+)=(.*)$", arg_string).captures | ||
args_hash[key] = URLDecode(value) | ||
end | ||
|
||
args_hash | ||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
function +(str1::ASCIIString, str2::ASCIIString) | ||
strcat(str1, str2) | ||
end | ||
function replace(str::ASCIIString, ch::Char, replacement::ASCIIString) | ||
replace(str, Regex(UTF8String([uint8(ch)])), replacement) | ||
end | ||
|
||
function URLDecode(str) | ||
str = replace(str, "+", "%20") | ||
chars = split(str, '%') | ||
if length(chars) <= 1 | ||
return str | ||
end | ||
strs = "" | ||
for i=chars | ||
global strs | ||
if length(i) < 2 | ||
continue | ||
end | ||
strs = strcat(strs, UTF8String([hextoten(i[1:2])]), i[3:]) | ||
end | ||
strs | ||
end | ||
|
||
function hextoten(num) | ||
len = length(num) | ||
num = uppercase(num) | ||
index = 0 | ||
total = 0x0 | ||
for i=num | ||
index += 1 | ||
count = 0 | ||
if int(i) <= 57 | ||
count = int(i) - 48 | ||
else | ||
count = int(i) - 55 | ||
end | ||
count = count * 16^(len-index) | ||
total += count | ||
end | ||
convert(Uint8, total) | ||
end |
Oops, something went wrong.