Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Daniel Kahn Gillmor
Knot DNS Resolver
Commits
c27905a9
Commit
c27905a9
authored
Jun 13, 2016
by
Marek Vavrusa
Browse files
modules/http: added safe stream handler, doc
parent
52e76f36
Changes
2
Hide whitespace changes
Inline
Side-by-side
modules/http/README.rst
View file @
c27905a9
...
...
@@ -157,6 +157,64 @@ exported restful APIs and subscribe to WebSockets.
http.snippets['/health'] = {'Health service', '<p>UP!</p>'}
How to expose RESTful services
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A RESTful service is likely to respond differently to different type of methods and requests,
there are three things that you can do in a service handler to send back results.
First is to just send whatever you want to send back, it has to respect MIME type that the service
declared in the endpoint definition. The response code would then be ``200 OK``, any non-string
responses will be packed to JSON. Alternatively, you can respond with a number corresponding to
the HTTP response code or send headers and body yourself.
.. code-block:: lua
-- Our upvalue
local value = 42
-- Expose the service
http.endpoints['/service'] = {'application/json',
function (h, stream)
-- Get request method and deal with it properly
local m = h:get(':method')
local path = h:get(':path')
log('[service] method %s path %s', m, path)
-- Return table, response code will be '200 OK'
if m == 'GET' then
return {key = path, value = value}
-- Save body, perform check and either respond with 505 or 200 OK
elseif m == 'POST' then
local data = stream:get_body_as_string()
if not tonumber(data) then
return 505
end
value = tonumber(data)
-- Unsupported method, return 405 Method not allowed
else
return 405
end
end}
In some cases you might need to send back your own headers instead of default provided by HTTP handler,
you can do this, but then you have to return ``false`` to notify handler that it shouldn't try to generate
a response.
.. code-block:: lua
local headers = require('http.headers')
function (h, stream)
-- Send back headers
local hsend = headers.new()
hsend:append(':status', '200')
hsend:append('content-type', 'binary/octet-stream')
assert(stream:write_headers(hsend, false))
-- Send back data
local data = 'binary-data'
assert(stream:write_chunk(data, true))
-- Disable default handler action
return false
end
How to expose more interfaces
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
...
modules/http/http.lua
View file @
c27905a9
...
...
@@ -86,28 +86,30 @@ end
-- Export HTTP service page snippets
M
.
snippets
=
{}
-- Serve GET requests, we only support a fixed
-- number of endpoints that are actually preloaded
-- in memory or constructed on request
local
function
serve_get
(
h
,
stream
)
-- Serve known requests, for methods other than GET
-- the endpoint must be a closure and not a preloaded string
local
function
serve
(
h
,
stream
)
local
hsend
=
headers
.
new
()
local
path
=
h
:
get
(
':path'
)
local
entry
=
M
.
endpoints
[
path
]
-- Unpack MIME and data
local
mime
,
data
local
mime
,
data
,
err
if
entry
then
mime
,
data
=
unpack
(
entry
)
end
-- Get string data out of service endpoint
if
type
(
data
)
==
'function'
then
data
=
data
(
h
,
stream
)
data
,
err
=
data
(
h
,
stream
)
-- Handler doesn't provide any data
if
data
==
false
then
return
end
if
type
(
data
)
==
'number'
then
return
tostring
(
data
)
end
-- Methods other than GET require handler to be closure
elseif
h
:
get
(
':method'
)
~=
'GET'
then
return
'501'
end
if
type
(
data
)
==
'table'
then
data
=
tojson
(
data
)
end
if
not
mime
or
type
(
data
)
~=
'string'
then
hsend
:
append
(
':status'
,
'404'
)
assert
(
stream
:
write_headers
(
hsend
,
true
))
return
'404'
else
-- Serve content type appropriately
hsend
:
append
(
':status'
,
'200'
)
...
...
@@ -147,14 +149,15 @@ local function route(endpoints)
end
ws
:
close
()
return
-- Handle HTTP method appropriately
elseif
m
==
'GET'
then
serve_get
(
h
,
stream
)
else
-- Method is not supported
local
hsend
=
headers
.
new
()
hsend
:
append
(
':status'
,
'500'
)
assert
(
stream
:
write_headers
(
hsend
,
true
))
local
ok
,
err
=
pcall
(
serve
,
h
,
stream
)
if
not
ok
or
err
then
log
(
'[http] %s %s: %s'
,
m
,
path
,
err
or
'500'
)
-- Method is not supported
local
hsend
=
headers
.
new
()
hsend
:
append
(
':status'
,
err
or
'500'
)
assert
(
stream
:
write_headers
(
hsend
,
true
))
end
end
stream
:
shutdown
()
end
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment