Skip to content

Commit eb23acb

Browse files
committed
elimination of global variables and headeralways
1 parent 4a5a304 commit eb23acb

7 files changed

Lines changed: 143 additions & 117 deletions

File tree

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,11 @@ server.notfound("notfound.html")
245245
```julia
246246
server.useCORS(true)
247247
```
248+
###Headers always
249+
You can add headers that will always be returned in each request
250+
```julia
251+
server.headersalways("Strict-Transport-Security","max-age=10886400; includeSubDomains; preload")
252+
```
248253

249254
### Bonus
250255
If you forgot the MIME type of a file you can use the next instruction

src/Merly.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ include("base.jl")
1010
include("mimetypes.jl")
1111
include("routes.jl")
1212
include("allformats.jl")
13-
include("webserver.jl")
1413

1514
export app, @page, @route, GET,POST,PUT,DELETE,HEAD,OPTIONS,PATCH,Get,Post,Put,Delete
1615

src/base.jl

Lines changed: 96 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,7 @@ mutable struct myrequest
1818
end
1919
end
2020

21-
struct App
22-
notfound::Function
23-
start::Function
24-
useCORS::Function
25-
webserverfiles::Function
26-
webserverpath::Function
27-
end
28-
2921
my_headers= HTTP.mkheaders(["Content-Type" => "text/plain"])
30-
root=pwd()
31-
if root[end]=='/'
32-
root=root[1:end-1]
33-
elseif Sys.iswindows() && root[end]=='\\'
34-
root=root[1:end-1]
35-
end
36-
exten="\"\""::AbstractString
37-
notfound_message = "NotFound"::String
38-
39-
40-
function File(file::String)
41-
path = normpath(root, file)
42-
return String(read(path))
43-
end
4422

4523
function searchroute_regex(ruta::String)
4624
for i in 1:length(routes_patterns_array)
@@ -96,50 +74,108 @@ function handler(request::HTTP.Messages.Request)
9674
end
9775

9876

99-
function app()
100-
global exten
77+
struct app
78+
notfound::Function
79+
start::Function
80+
useCORS::Function
81+
webserverfiles::Function
82+
webserverpath::Function
83+
headersalways::Function
10184

102-
function useCORS(activate::Bool)
103-
HTTP.setheader(my_headers,"Access-Control-Allow-Origin" => "*")
104-
HTTP.setheader(my_headers,"Access-Control-Allow-Methods" => "POST,GET,OPTIONS")
105-
return true
106-
end
85+
function app()
86+
root=pwd()
10787

108-
function notfound(text::String)
109-
if occursin(".html", text)
110-
notfound_message= File(text)
111-
else
112-
notfound_message= text
88+
function File(file::String)
89+
path = normpath(root, file)
90+
return String(read(path))
11391
end
114-
end
11592

116-
function webserverfiles(load::AbstractString)
117-
if load=="*"
118-
WebServer(root)
119-
else
120-
exten=load::AbstractString
121-
WebServer(root)
93+
function files(arch::Array{Any,1})
94+
roop=""
95+
for i=1:length(arch)
96+
roop=replace(replace(arch[i],root => ""),"\\" => "/")
97+
extension="text/plain"
98+
ext= split(roop,".")
99+
if(length(ext)>1)
100+
my_extension = ext[2]
101+
if (haskey(mimetypes,my_extension))
102+
extension=mimetypes[my_extension]
103+
end
104+
end
105+
data = File(roop[2:end])
106+
createurl("GET"*roop,(req,res)->(begin
107+
res.headers["Content-Type"]= extension
108+
res.status = 200
109+
res.body= data
110+
end))
111+
end
122112
end
123-
end
124113

125-
function webserverpath(path::AbstractString)
126-
root= path
127-
end
114+
function WebServer(rootte::String,exten::String)
115+
cd(rootte)
116+
ls= readdir()
117+
arrfile=[]
118+
arrdir=[]
119+
for i=1:length(ls)
120+
if isfile(ls[i])
121+
if ( (occursin(Regex("((.)*\\.(?!($exten)))"),ls[i])) && (!occursin(r"^(\.)",ls[i])))
122+
push!(arrfile,normpath(rootte,ls[i]))
123+
end
124+
end
125+
if isdir(ls[i])
126+
push!(arrdir,normpath(rootte,ls[i]))
127+
end
128+
end
129+
files(arrfile)
130+
for i=1:length(arrdir)
131+
WebServer(arrdir[i],exten)
132+
end
133+
end
128134

129-
function start(config=Dict("host" => "127.0.0.1","port" => 8000)::Dict)
130-
host= Sockets.IPv4("127.0.0.1")
131-
port=get(config, "port", 8000)::Int
132-
my_host = get(config, "host", "127.0.0.1")::String
133-
if ('.' in my_host) host=Sockets.IPv4(my_host) end
134-
if (':' in my_host) host=Sockets.IPv6(my_host) end
135-
http = (req)-> handler(req)
136-
myserver= HTTP.Servers.Server(http, stdout)
137-
@info("Listening on: $(host) : $(port)")
138-
return HTTP.Servers.serve(myserver, host, port)
139-
end
135+
function useCORS(activate::Bool)
136+
HTTP.setheader(my_headers,"Access-Control-Allow-Origin" => "*")
137+
HTTP.setheader(my_headers,"Access-Control-Allow-Methods" => "POST,GET,OPTIONS")
138+
return true
139+
end
140140

141-
@info("App created")
142-
return App(notfound,start,useCORS,webserverfiles,webserverpath)
143-
end
141+
function headersalways(head::AbstractString,value::AbstractString)
142+
HTTP.setheader(my_headers,head => value)
143+
end
144+
145+
function notfound(text::String)
146+
if occursin(".html", text)
147+
notfound_message= File(text)
148+
addnotfound(notfound_message)
149+
else
150+
addnotfound(text)
151+
end
152+
end
153+
154+
function webserverfiles(load::AbstractString)
155+
if load=="*"
156+
WebServer(root," ")
157+
else
158+
WebServer(root,load)
159+
end
160+
end
144161

145-
#HSTS HTTP.setheader(response,"Strict-Transport-Security" => "max-age=10886400; includeSubDomains; preload"
162+
function webserverpath(path::AbstractString)
163+
root = path
164+
end
165+
166+
function start(config=Dict("host" => "127.0.0.1","port" => 8000)::Dict)
167+
host= Sockets.IPv4("127.0.0.1")
168+
port=get(config, "port", 8000)::Int
169+
my_host = get(config, "host", "127.0.0.1")::String
170+
if ('.' in my_host) host=Sockets.IPv4(my_host) end
171+
if (':' in my_host) host=Sockets.IPv6(my_host) end
172+
http = (req)-> handler(req)
173+
myserver= HTTP.Servers.Server(http, stdout)
174+
@info("Listening on: $(host) : $(port)")
175+
return HTTP.Servers.serve(myserver, host, port)
176+
end
177+
178+
@info("App created")
179+
return new(notfound,start,useCORS,webserverfiles,webserverpath,headersalways)
180+
end
181+
end

src/routes.jl

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,21 @@ HEAD = "HEAD"
99
OPTIONS = "OPTIONS"
1010
PATCH = "PATCH"
1111

12-
function NotFound(req,res)
13-
res.status = 404
14-
return notfound_message
15-
end
12+
1613

1714
routes=Dict()
1815
routes_array=[]
1916
routes_patterns=Dict()
2017
routes_patterns_array=[]
21-
routes["notfound"] = NotFound
18+
19+
function addnotfound(message::String)
20+
routes["notfound"] = (req,res) -> begin
21+
res.status = 404
22+
return message
23+
end
24+
end
25+
26+
addnotfound("NotFound")
2227

2328
function createurl(url::String,funtion::Function)
2429
if occursin(":",url)||occursin("(",url)

src/webserver.jl

Lines changed: 0 additions & 37 deletions
This file was deleted.

test/notfound.html

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Document</title>
6+
</head>
7+
<body>
8+
Not found!!!
9+
</body>
10+
</html>

test/runtests.jl

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,27 @@ using JSON
66
#Pkg.add("BenchmarkTools")
77
#using BenchmarkTools
88

9-
ip = "127.0.0.1" #127.0.0.1
9+
ip = "127.0.0.1"
1010
port = 8086
1111
# write your own tests here
1212
server = Merly.app()
1313

1414
@test server.useCORS(true) == true
15-
15+
server.headersalways("Strict-Transport-Security","max-age=10886400; includeSubDomains; preload")
1616
@test server.notfound("<!DOCTYPE html>
1717
<html>
1818
<head><title>Not found</title></head>
1919
<body><h1>404, Not found</h1></body>
20-
</html>") == "<!DOCTYPE html>
21-
<html>
22-
<head><title>Not found</title></head>
23-
<body><h1>404, Not found</h1></body>
24-
</html>"
20+
</html>") == server.notfound("<!DOCTYPE html>\n <html>\n <head><title>Not found</title></head>\n <body><h1>404, Not found</h1></body>\n </html>")
21+
server.notfound("notfound.html")
2522

2623
u="hello"
2724

2825
@page "/" "Hello World!"
2926
@page "/hola/:usr>" "<b>Hello {{usr}}!</b>"
3027

28+
@page "/mifile" File("Index.html")
29+
3130
@route GET "/get/:data>" begin
3231
"get this back: {{data}}"
3332
end
@@ -71,6 +70,8 @@ Post("/data", (req,res)->(begin
7170
end))
7271

7372
server.webserverfiles("jl")
73+
#server.webserverpath("C:\\Users\\ito\\.julia\\dev\\Merly\\prueba")
74+
#server.webserverfiles("*")
7475

7576
@async server.start(Dict("host" => "$(ip)","port" => port))
7677

@@ -103,7 +104,7 @@ r = HTTP.get("http://$(ip):$(port)/data")
103104
@test String(r.body) == "byedata"
104105

105106

106-
107+
my_headers = HTTP.mkheaders(["Accept" => "application/json"])
107108
r = HTTP.post("http://$(ip):$(port)/post",my_headers,JSON.json(myjson))
108109
@test r.status == 200
109110
@test String(r.body) == "I did something!"
@@ -119,33 +120,40 @@ r = HTTP.put("http://$(ip):$(port)/",my_headers,JSON.json(myjson))
119120
r = HTTP.delete("http://$(ip):$(port)/")
120121
@test r.status == 200
121122
@test String(r.body) == "I did something!"
122-
@test r.headers == Pair{SubString{String},SubString{String}}["Content-Type"=>"text/plain", "Access-Control-Allow-Origin"=>"*", "Access-Control-Allow-Methods"=>"POST,GET,OPTIONS", "Transfer-Encoding"=>"chunked"]
123+
@test r.headers == Pair{SubString{String},SubString{String}}["Content-Type"=>"text/plain", "Access-Control-Allow-Origin"=>"*", "Access-Control-Allow-Methods"=>"POST,GET,OPTIONS", "Strict-Transport-Security"=>"max-age=10886400; includeSubDomains; preload", "Transfer-Encoding"=>"chunked"]
123124

124125
try
125126
r = HTTP.get("http://$(ip):$(port)/nada")
126127
catch e
127128
@test e.status == 404
128-
@test String(e.response.body) == "NotFound"
129+
if Sys.iswindows()
130+
@test String(e.response.body) == "<!DOCTYPE html>\r\n<html lang=\"en\">\r\n<head>\r\n\t<meta charset=\"UTF-8\">\r\n\t<title>Document</title>\r\n</head>\r\n<body>\r\nNot found!!!\r\n</body>\r\n</html>"
131+
else
132+
@test String(e.response.body) == "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n\t<meta charset=\"UTF-8\">\n\t<title>Document</title>\n</head>\n<body>\nNot found!!!\n</body>\n</html>"
133+
end
129134
end
130135

131136
r = HTTP.get("http://$(ip):$(port)/prueba.txt")
132137
@test r.status == 200
133138
@test String(r.body) == "probando webserver"
134-
@test r.headers == Pair{SubString{String},SubString{String}}["Content-Type"=>"text/plain", "Access-Control-Allow-Origin"=>"*", "Access-Control-Allow-Methods"=>"POST,GET,OPTIONS", "Transfer-Encoding"=>"chunked"]
139+
@test r.headers == Pair{SubString{String},SubString{String}}["Content-Type"=>"text/plain", "Access-Control-Allow-Origin"=>"*", "Access-Control-Allow-Methods"=>"POST,GET,OPTIONS", "Strict-Transport-Security"=>"max-age=10886400; includeSubDomains; preload", "Transfer-Encoding"=>"chunked"]
135140

136-
r = HTTP.get("http://$(ip):$(port)/index.html")
141+
r = HTTP.get("http://$(ip):$(port)/Index.html")
137142
@test r.status == 200
138143
if Sys.iswindows()
139144
@test String(r.body) == "<!DOCTYPE html>\r\n<html lang=\"en\">\r\n<head>\r\n\t<meta charset=\"UTF-8\">\r\n\t<title>Document</title>\r\n</head>\r\n<body>\r\n<h1>hola</h1>\r\n</body>\r\n</html>"
140145
else
141146
@test String(r.body) == "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n\t<meta charset=\"UTF-8\">\n\t<title>Document</title>\n</head>\n<body>\n<h1>hola</h1>\n</body>\n</html>"
142147
end
143-
144-
@test r.headers == Pair{SubString{String},SubString{String}}["Content-Type"=>"text/html", "Access-Control-Allow-Origin"=>"*", "Access-Control-Allow-Methods"=>"POST,GET,OPTIONS", "Transfer-Encoding"=>"chunked"]
148+
@test r.headers == Pair{SubString{String},SubString{String}}["Content-Type"=>"text/html", "Access-Control-Allow-Origin"=>"*", "Access-Control-Allow-Methods"=>"POST,GET,OPTIONS", "Strict-Transport-Security"=>"max-age=10886400; includeSubDomains; preload", "Transfer-Encoding"=>"chunked"]
145149

146150

147151
r= HTTP.get("http://$(ip):$(port)/regex/test1")
148152
@test String(r.body) == "datos test1"
153+
154+
#r= HTTP.get("http://$(ip):$(port)/prueba/file.txt")
155+
#@test String(r.body) == "texto de prueba"
156+
149157
#@btime HTTP.get("http://$(ip):$(port)/?hola=5") # 3.864 ms (8304 allocations: 381.20 KiB)
150158
#@btime HTTP.get("http://$(ip):$(port)/hola/usuario") # 4.211 ms (7685 allocations: 353.44 KiB)
151159
#@btime r= HTTP.get("http://$(ip):$(port)/get/testdata") # 3.906 ms (7693 allocations: 353.78 KiB)

0 commit comments

Comments
 (0)