Skip to content

Commit 0634f2d

Browse files
committed
update to v0.7
1 parent 545137c commit 0634f2d

File tree

8 files changed

+1098
-106
lines changed

8 files changed

+1098
-106
lines changed

README.md

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
<img src="https://codecov.io/gh/codeneomatrix/Merly.jl/branch/master/graph/badge.svg" />
99
</a>
1010
&nbsp;&nbsp
11-
<a href="https://pkg.julialang.org/detail/Merly"><img src="http://pkg.julialang.org/badges/Merly_0.6.svg"></a>
1211
<a href="https://pkg.julialang.org/detail/Merly"><img src="http://pkg.julialang.org/badges/Merly_0.7.svg"></a>
1312
&nbsp;&nbsp;
1413
<a href="https://raw.githubusercontent.com/codeneomatrix/Merly.jl/master/LICENSE.md"><img src="https://img.shields.io/badge/license-MIT-blue.svg"></a>
@@ -24,12 +23,12 @@ Roadmap
2423
- [x] optimizing routes
2524
- [x] refactor notfount, cors, body
2625

27-
Below are some of the features that are planned to be added in future versions of Merly.jl once version 1.0 of the language is released.
26+
Below are some of the features that are planned to be added in future versions of Merly.jl once version 0.7 of the language is released.
2827

2928
### All contributions and suggestions are welcome !!!!
3029

3130
#### Version 0.1.0
32-
- [ ] Julia version 1.0 syntax update
31+
- [ ] Julia version 0.7 syntax update
3332

3433
#### Version 0.1.2
3534
- [ ] Implementation of a websocket module
@@ -62,21 +61,21 @@ server = Merly.app()
6261
end
6362

6463
@route POST "/post" begin
65-
res.data = "I did something!"
64+
res.body = "I did something!"
6665
end
6766

6867
@route POST|PUT|DELETE "/" begin
6968
println("params: ",q.params)
7069
println("query: ",q.query)
7170
println("body: ",q.body)
7271

73-
res.headers["Content-Type"]="text/plain"
72+
q.headers["Content-Type"]= "text/plain"
7473

7574
"I did something!"
7675
end
7776

7877
Get("/data", (q,req,res)->(begin
79-
res.headers["Content-Type"]="text/plain"
78+
q.headers["Content-Type"]= "text/plain"
8079
u*"data"
8180
end))
8281

@@ -85,13 +84,13 @@ Post("/data", (q,req,res)->(begin
8584
println("params: ",q.params)
8685
println("query: ",q.query)
8786
println("body: ",q.body)
88-
res.headers["Content-Type"]="text/plain"
87+
q.headers["Content-Type"]= "text/plain"
8988
global u="bye"
9089
"I did something!"
9190
end))
9291

9392

94-
server.start("localhost", 8080)
93+
server.start(Dict("host" => "127.0.0.1","port" => 8000))
9594

9695
```
9796

@@ -109,7 +108,7 @@ end
109108

110109
```julia
111110
@route POST|PUT|DELETE "/" begin
112-
res.headers["Content-Type"]="text/plain"
111+
q.headers["Content-Type"]= "text/plain"
113112
# matches "POST /?title=foo&author=bar"
114113
title = q.query["title"]
115114
author = q.query["author"]
@@ -123,8 +122,8 @@ Payload
123122
```
124123
```julia
125124
@route POST|PUT|DELETE "/" begin
126-
res.headers["Content-Type"]="text/plain"
127-
res.data = "Payload data "*q.body["data1"]
125+
q.headers["Content-Type"]= "text/plain"
126+
res.body = "Payload data "*q.body["data1"]
128127
end
129128
```
130129

@@ -136,7 +135,7 @@ Payload
136135
```
137136
```julia
138137
@route POST|PUT|DELETE "/" begin
139-
res.headers["Content-Type"]="text/plain"
138+
q.headers["Content-Type"]= "text/plain"
140139
"Payload data "*q.body["Data"]["Data1"]
141140
end
142141
```
@@ -145,7 +144,7 @@ end
145144

146145
```julia
147146
@route POST|PUT|DELETE "/" begin
148-
res.headers["Content-Type"]="application/json"
147+
q.headers["Content-Type"]="application/json"
149148
res.status = 200 #optional
150149
"{\"data1\":2,\"data2\":\"t\"}"
151150
end
@@ -154,12 +153,12 @@ end
154153
or
155154
```julia
156155
@route POST|PUT|DELETE "/" begin
157-
res.headers["Content-Type"]="application/json"
156+
q.headers["Content-Type"]="application/json"
158157
info=Dict()
159158
info["data1"]=2
160159
info["data2"]="t"
161160
res.status = 200 #optional
162-
res.data = JSON.json(info)
161+
res.body = JSON.json(info)
163162
end
164163

165164
```
@@ -168,7 +167,7 @@ end
168167

169168
```julia
170169
@route POST|PUT|DELETE "/" begin
171-
res.headers["Content-Type"]="application/xml"
170+
q.headers["Content-Type"]="application/xml"
172171

173172
"<ListAllMyBucketsResult>
174173
<Buckets>
@@ -195,12 +194,11 @@ end
195194
# with the following instruction.
196195
server.webserverpath("C:\\path") # example in windows
197196

198-
199-
server.webserverfiles("*") #
200197
```
201198
```clojure
202199
Possible values of webserverfiles
203200

201+
server.webserverfiles("*") #
204202
"*" Load all the files located in the path, except what started with "."
205203
"jl","clj|jl|py" Extension in files that will not be exposed
206204
```
@@ -224,5 +222,6 @@ server.useCORS(true)
224222
### Bonus
225223
If you forgot the MIME type of a file you can use the next instruction
226224
```julia
227-
res.headers["Content-Type"]=mimetypes["file extension"]
228-
```
225+
q.headers["Content-Type"]= mimetypes["file extension"]
226+
```
227+
the file mimetypes.jl was taken from https://github.com/JuliaWeb/HttpServer.jl guys are great

REQUIRE

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
julia 0.6
2-
HttpServer
1+
julia 0.7-
32
HttpCommon
43
JSON
5-
XMLDict

src/Merly.jl

Lines changed: 53 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,55 @@
11
__precompile__()
22
module Merly
3-
import HttpServer.mimetypes
43
import Base.|
54

6-
using HttpServer,
5+
using Sockets,
76
HttpCommon,
87
JSON,
8+
HTTP,
99
XMLDict
1010

11+
include("mimetypes.jl")
1112
include("routes.jl")
1213
include("allformats.jl")
1314
include("webserver.jl")
1415

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

1718
cors=false::Bool
18-
debug=true::Bool
1919
root=pwd()
2020
if root[end]=='/'
2121
root=root[1:end-1]
22-
elseif is_windows() && root[end]=='\\'
22+
elseif Sys.iswindows() && root[end]=='\\'
2323
root=root[1:end-1]
2424
end
2525

2626
exten="\"\""::AbstractString
2727

28-
type Q
28+
mutable struct Data
2929
query::Dict
3030
params::Any
31-
body::AbstractString
32-
notfound_message::AbstractString
31+
body::Any
32+
headers::Dict
3333
end
34+
global notfound_message = "NotFound"::AbstractString
35+
global q=Data(Dict(),"","",Dict())
3436

35-
global q=Q(Dict(),Dict(),"","NotFound")
36-
37-
type Fram
37+
mutable struct Fram
3838
notfound::Function
3939
start::Function
4040
useCORS::Function
4141
webserverfiles::Function
4242
webserverpath::Function
4343
end
4444

45-
function _body(data::Array{UInt8,1},format::String)
46-
content=""
47-
for i=1:length(data)
48-
content*="$(Char(data[i]))"
49-
end
50-
return getindex(formats, format)(content)
45+
function _body(data::Array{UInt8,1},format::SubString{String})
46+
return getindex(formats, format)(String(data))
5147
end
5248

5349
function File(file::String)
5450
try
5551
path = normpath(root, file)
56-
return readstring(path)
52+
return String(read(path))
5753
catch
5854
return file
5955
end
@@ -68,51 +64,56 @@ function resolveroute(ruta::String)
6864
end
6965
end
7066

71-
function processroute_pattern(searchroute::String,request::HttpCommon.Request,response::HttpCommon.Response)
67+
function processroute_pattern(searchroute::String,request,response)
7268
q.params, _function = resolveroute(searchroute)
7369
respond = _function(q,request,response)
74-
sal = matchall(Regex("{{([a-z])+}}"),respond)
70+
sal = collect((m.match for m = eachmatch(Regex("{{([a-z])+}}"), respond)))
7571
for i in sal
76-
respond = replace(respond,Regex(i),q.params["$(i[3:end-2])"])
72+
respond = replace(respond,Regex(i) => q.params["$(i[3:end-2])"])
7773
end
74+
response.status = 200
7875
return respond
7976
end
8077

81-
function handler(request::HttpCommon.Request,response::HttpCommon.Response)
82-
83-
data = split(request.resource,"?")
78+
function handler(request::HTTP.Messages.Request)
79+
data = split(request.target,"?")
8480
url=data[1]
85-
8681
searchroute = request.method*url
87-
8882
try
89-
q.query= parsequerystring(data[2]);
83+
q.query= HTTP.queryparams(data[2]);
84+
catch
9085
end
86+
response = HTTP.Response()
9187

9288
try
93-
q.body = _body(request.data,request.headers["Content-Type"])
89+
q.body= _body(request.body,HTTP.header(request, "Content-Type"))
9490
catch
95-
q.body = _body(request.data,"*/*")
91+
q.body = _body(request.body,SubString("*/*"))
9692
end
9793

9894
if cors
99-
response.headers["Access-Control-Allow-Origin"]="*"
100-
response.headers["Access-Control-Allow-Methods"]="POST,GET,OPTIONS"
95+
HTTP.setheader(response,"Access-Control-Allow-Origin" => "*")
96+
HTTP.setheader(response,"Access-Control-Allow-Methods" => "POST,GET,OPTIONS")
10197
end
10298

103-
if debug
104-
info("METODO : ",request.method," URL : ",url)
105-
end
106-
try
107-
response.data = getindex(routes, searchroute)(q,request,response)
108-
catch
99+
HTTP.setheader(response,"Content-Type" => "text/plain" )
100+
101+
#try
102+
response.status= 200
103+
response.body = getindex(routes, searchroute)(q,request,response)
104+
#=catch
109105
try
110-
response.data = processroute_pattern(searchroute,request,response)
106+
response.body = processroute_pattern(searchroute,request,response)
111107
catch
112-
response.data = getindex(routes, "notfound")(q,request,response)
108+
response.body = getindex(routes, "notfound")(q,request,response)
113109
end
110+
end=#
111+
112+
for (key, value) in q.headers
113+
HTTP.setheader(response,key => value )
114114
end
115115

116+
116117
return response
117118
end
118119

@@ -121,14 +122,13 @@ function app()
121122
global root
122123
global exten
123124
global cors
124-
global debug
125125

126126
function useCORS(activate::Bool)
127127
cors=activate
128128
end
129129

130130
function notfound(text::AbstractString)
131-
q.notfound_message= File(text)
131+
notfound_message= File(text)
132132
end
133133

134134
function webserverfiles(load::AbstractString)
@@ -144,48 +144,40 @@ global debug
144144
root= path
145145
end
146146

147-
function start(config=Dict("host" => "127.0.0.1","port" => 8000,"debug" => true)::Dict)
148-
host= "127.0.0.1"
147+
function start(config=Dict("host" => "127.0.0.1","port" => 8000)::Dict)
148+
host= Sockets.IPv4("127.0.0.1")
149149
port= 8000
150150

151151
try
152-
host=get(config, "host", "127.0.0.1")::AbstractString
152+
host=Sockets.IPv4(get(config, "host", "127.0.0.1")::AbstractString)
153153
catch
154-
error("Verify the format of the ip address \n AbstractString \"127.0.0.1\"")
154+
try
155+
host=Sockets.IPv6(get(config, "host", "127.0.0.1")::AbstractString)
156+
catch
157+
end
155158
end
156159

157160
try
158161
port=get(config, "port", 8000)::Int
159162
catch
160-
error("Verify the port format \n Int 8000 ")
163+
@info("Port 8000 ")
161164
end
162165

163-
try
164-
debug=get(config, "debug", true)::Bool
165-
catch
166-
error("Verify the debug format \n Bool true ")
167-
end
166+
http = (req)-> handler(req)
168167

169-
http = HttpHandler((req, res)-> handler(req,res))
170-
http.events["error"] = (client, error) -> println(error)
171-
http.events["listen"] = (port) -> println("Listening on $port...")
172-
server = Server(http)
168+
myserver= HTTP.Servers.Server(http, stdout)
173169

174-
if host=="localhost"
175-
host="127.0.0.1"
176-
end
177170
try
178171
#@async run(server, host=IPv4(host), port=port)
179-
run(server, host=IPv4(host), port=port)
172+
HTTP.Servers.serve(myserver, host, port)
180173
catch
181174
try
182-
run(server, host=IPv6(host), port=port)
175+
HTTP.Servers.serve(myserver, host, port)
183176
catch
184-
warn("Address not valid, check it")
177+
@warn("Address not valid, check it")
185178
end
186179
end
187180
end
188-
189181
return Fram(notfound,start,useCORS,webserverfiles,webserverpath)
190182
end
191183
end # module

0 commit comments

Comments
 (0)