Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Makes a https server easier... #346

Merged
merged 1 commit into from

2 participants

@kans

by making the onClient handler public and by adding a :shutdown to cleartext so
that the http.Response can call self.socket:shutdown (ie, on Cleartext).

@kans kans Makes a https server easier...
by making the onClient handler public and by adding a :shutdown to cleartext so
that the http.Response can call self.socket:shutdown (ie, on Cleartext).
e6e63f5
@rphillips rphillips merged commit 6acab3a into luvit:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 21, 2012
  1. @kans @rphillips

    Makes a https server easier...

    kans authored rphillips committed
    by making the onClient handler public and by adding a :shutdown to cleartext so
    that the http.Response can call self.socket:shutdown (ie, on Cleartext).
This page is out of date. Refresh to see the latest.
Showing with 145 additions and 140 deletions.
  1. +140 −139 lib/luvit/http.lua
  2. +4 −0 lib/luvit/tls.lua
  3. +1 −1  tests/runner.lua
View
279 lib/luvit/http.lua
@@ -1054,164 +1054,165 @@ function http.get(options, callback)
return req
end
-function http.createServer(onConnection)
- local server
- server = net.createServer(function (client)
-
- -- Convert tcp stream to HTTP stream
- local request
- local current_field
- local parser
- local url
- local headers
- parser = HttpParser.new("request", {
- onMessageBegin = function ()
- headers = {}
- end,
- onUrl = function (value)
- url = value
- end,
- onHeaderField = function (field)
- current_field = field:lower()
- end,
- onHeaderValue = function (value)
- headers[current_field] = value
- end,
- onHeadersComplete = function (info)
-
- -- Accept the client and build request and response objects
- request = Request:new(client)
- local response = Response:new(client)
-
- request.method = info.method
- request.headers = headers
- request.url = url
- request.upgrade = info.upgrade
-
- request.version_major = info.version_major
- request.version_minor = info.version_minor
-
- -- Give upgrade requests access to the raw client if they want it
- if info.upgrade then
- request.client = client
- end
+function http.onClient(server, client, onConnection)
+ -- Convert tcp stream to HTTP stream
+ local request
+ local current_field
+ local parser
+ local url
+ local headers
+ parser = HttpParser.new("request", {
+ onMessageBegin = function ()
+ headers = {}
+ end,
+ onUrl = function (value)
+ url = value
+ end,
+ onHeaderField = function (field)
+ current_field = field:lower()
+ end,
+ onHeaderValue = function (value)
+ headers[current_field] = value
+ end,
+ onHeadersComplete = function (info)
- -- HTTP keep-alive logic
- request.should_keep_alive = info.should_keep_alive
- response.should_keep_alive = info.should_keep_alive
- -- N.B. keep-alive requires explicit message length
- if info.should_keep_alive then
- --[[
- In order to remain persistent, all messages on the connection MUST
- have a self-defined message length (i.e., one not defined by closure
- of the connection)
- ]]
- response.auto_content_length = false
- -- HTTP/1.0 should insert Connection: keep-alive
- if info.version_minor < 1 then
- response:setHeader("Connection", "keep-alive")
- end
- else
- -- HTTP/1.1 should insert Connection: close for last message
- if info.version_minor >= 1 then
- response:setHeader("Connection", "close")
- end
- end
+ -- Accept the client and build request and response objects
+ request = Request:new(client)
+ local response = Response:new(client)
- -- Handle 100-continue requests
- if request.headers.expect
- and info.version_major == 1
- and info.version_minor == 1
- and request.headers.expect:lower() == "100-continue"
- then
- if server.handlers and server.handlers.check_continue then
- server:emit("check_continue", request, response)
- else
- response:writeContinue()
- onConnection(request, response)
- end
- else
- onConnection(request, response)
- end
+ request.method = info.method
+ request.headers = headers
+ request.url = url
+ request.upgrade = info.upgrade
- end,
- onBody = function (chunk)
- request:emit("data", chunk)
- end,
- onMessageComplete = function ()
- request:emit("end")
- request:removeListener("end")
- if request.should_keep_alive then
- parser:finish()
- end
- end
- })
+ request.version_major = info.version_major
+ request.version_minor = info.version_minor
- client:on("data", function (chunk)
+ -- Give upgrade requests access to the raw client if they want it
+ if info.upgrade then
+ request.client = client
+ end
- -- Once we're in "upgrade" mode, the protocol is no longer HTTP and we
- -- shouldn't send data to the HTTP parser
- if request and request.upgrade then
- request:emit("data", chunk)
- return
+ -- HTTP keep-alive logic
+ request.should_keep_alive = info.should_keep_alive
+ response.should_keep_alive = info.should_keep_alive
+ -- N.B. keep-alive requires explicit message length
+ if info.should_keep_alive then
+ --[[
+ In order to remain persistent, all messages on the connection MUST
+ have a self-defined message length (i.e., one not defined by closure
+ of the connection)
+ ]]
+ response.auto_content_length = false
+ -- HTTP/1.0 should insert Connection: keep-alive
+ if info.version_minor < 1 then
+ response:setHeader("Connection", "keep-alive")
+ end
+ else
+ -- HTTP/1.1 should insert Connection: close for last message
+ if info.version_minor >= 1 then
+ response:setHeader("Connection", "close")
+ end
end
- --[[ from http_parser documentation:
- To tell http_parser about EOF, give 0 as the forth parameter to
- http_parser_execute()
- ]]--
- -- don't route empty chunks to the parser
- if #chunk == 0 then return end
-
- -- Parse the chunk of HTTP, this will syncronously emit several of the
- -- above events and return how many bytes were parsed
- local nparsed = parser:execute(chunk, 0, #chunk)
-
- -- If it wasn't all parsed then there was an error parsing
- if nparsed < #chunk and request then
- if request.upgrade then
- request:emit("data", chunk:sub(nparsed + 1))
+ -- Handle 100-continue requests
+ if request.headers.expect
+ and info.version_major == 1
+ and info.version_minor == 1
+ and request.headers.expect:lower() == "100-continue"
+ then
+ if server.handlers and server.handlers.check_continue then
+ server:emit("check_continue", request, response)
else
- request:emit("error", "parse error: " .. chunk)
+ response:writeContinue()
+ onConnection(request, response)
end
+ else
+ onConnection(request, response)
end
- end)
-
- client:once("end", function ()
- if request then
- request:emit("end")
- request:removeListener("end")
+ end,
+ onBody = function (chunk)
+ request:emit("data", chunk)
+ end,
+ onMessageComplete = function ()
+ request:emit("end")
+ request:removeListener("end")
+ if request.should_keep_alive then
+ parser:finish()
end
- parser:finish()
- end)
+ end
+ })
- client:once("closed", function ()
- if request then
- request:emit("end")
- request:removeListener("end")
- end
- parser:finish()
- end)
+ client:on("data", function(chunk)
+ -- Once we're in "upgrade" mode, the protocol is no longer HTTP and we
+ -- shouldn't send data to the HTTP parser
+ if request and request.upgrade then
+ request:emit("data", chunk)
+ return
+ end
+
+ --[[ from http_parser documentation:
+ To tell http_parser about EOF, give 0 as the forth parameter to
+ http_parser_execute()
+ ]]--
+ -- don't route empty chunks to the parser
+ if #chunk == 0 then return end
+
+ -- Parse the chunk of HTTP, this will syncronously emit several of the
+ -- above events and return how many bytes were parsed
+ local nparsed = parser:execute(chunk, 0, #chunk)
- client:once("error", function (err)
- parser:finish()
- -- read from closed client
- if err.code == "ECONNRESET" then
- -- ???
- -- written to closed client
- elseif err.code == "EPIPE" then
- -- ???
- -- other errors
+ -- If it wasn't all parsed then there was an error parsing
+ if nparsed < #chunk and request then
+ if request.upgrade then
+ request:emit("data", chunk:sub(nparsed + 1))
else
- if request then
- request:emit("error", err)
- end
+ request:emit("error", "parse error: " .. chunk)
end
- end)
+ end
+ end)
+ client:once("end", function ()
+ if request then
+ request:emit("end")
+ request:removeListener("end")
+ end
+ parser:finish()
+ end)
+
+ client:once("closed", function ()
+ if request then
+ request:emit("end")
+ request:removeListener("end")
+ end
+ parser:finish()
end)
+ client:once("error", function (err)
+ parser:finish()
+ -- read from closed client
+ if err.code == "ECONNRESET" then
+ -- ???
+ -- written to closed client
+ elseif err.code == "EPIPE" then
+ -- ???
+ -- other errors
+ else
+ if request then
+ request:emit("error", err)
+ end
+ end
+ end)
+
+ return server
+end
+
+function http.createServer(onConnection)
+ local server
+ server = net.createServer(function(client)
+ return http.onClient(server, client, onConnection)
+ end)
return server
end
View
4 lib/luvit/tls.lua
@@ -427,6 +427,10 @@ function CleartextStream:_pusher()
return self.pair.ssl:clearOut()
end
+function CleartextStream:shutdown(cb)
+ self:destroy()
+ if cb then cb() end
+end
function CleartextStream:destroy()
if self.socket and self._closing ~= true then
self.socket:destroy()
View
2  tests/runner.lua
@@ -92,7 +92,7 @@ local function run(callback)
end
process.stdout:write('Done\n')
if nerr ~= 0 then
- callback()
+ if callback then callback() end
process.exit(1)
end
end)
Something went wrong with that request. Please try again.