diff --git a/httpserver.lua b/httpserver.lua index eb592d4..d6eae2f 100644 --- a/httpserver.lua +++ b/httpserver.lua @@ -1,42 +1,15 @@ -- httpserver -- Author: Marcos Kirsch --- This is a very simple HTTP server designed to work on nodemcu (http://nodemcu.com) --- It can handle GET and POST. -require "printTable" +module("httpserver", package.seeall) -httpserver = {} +require("TablePrinter") - --- Starts web server in the specified port. ---function httpserver.start(port, clientTimeoutInSeconds, debug) --- -- Server constants --- server = net.createServer(net.TCP, clientTimeoutInSeconds) server:listen(port, private.handleRequest) ---end - - -httpserver.private = {} -- not part of the public API - -function httpserver.private.onReceive(connection, payload) - print(payload) -- for debugging - - -- parse payload and decide what to serve. - parsedRequest = private.parseRequest(payload) - httpserver.private.printTable(parsedRequest, 3) - - --generates HTML web site - httpHeader200 = "HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nCache-Control: private, no-store\r\n\r\n" - html = "

Hola mundo

" - connection:send(httpHeader200 .. html) -end - -function httpserver.private.handleRequest(connection) - connection:on("receive", onReceive) - connection:on("sent",function(connection) connection:close() end) -end +-- Functions below aren't part of the public API +-- Clients don't need to worry about them. -- given an HTTP request, returns the method (i.e. GET) -function httpserver.private.getRequestMethod(request) +local function getRequestMethod(request) -- HTTP Request Methods. -- HTTP servers are required to implement at least the GET and HEAD methods -- http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods @@ -51,29 +24,82 @@ function httpserver.private.getRequestMethod(request) return (httpMethods[found]) end --- given an HTTP request, returns a table with all the information. -function httpserver.private.parseRequest(request) - parsedRequest = {} - -- First get the method +---- given an HTTP request, returns a table with all the information. +--local function parseRequest(request) +-- parsedRequest = {} +-- +-- -- First get the method +-- parsedRequest["method"] = getRequestMethod(request) +-- if parsedRequest["method"] == nil then +-- return nil +-- end +-- -- Now get each value out of the header, skip the first line +-- lineNumber = 0 +-- for line in request:gmatch("[^\r\n]+") do +-- if lineNumber ~=0 then +-- -- tag / value are of the style "Host: 10.0.7.15". Break them up. +-- found, valueIndex = string.find(line, ": ") +-- if found == nil then +-- break +-- end +-- tag = string.sub(line, 1, found - 1) +-- value = string.sub(line, found + 2, #line) +-- parsedRequest[tag] = value +-- end +-- lineNumber = lineNumber + 1 +-- end +-- return parsedRequest +--end - parsedRequest["method"] = httpserver.private.getRequestMethod(request) - if parsedRequest["method"] == nil then - return nil - end - -- Now get each value out of the header, skip the first line - lineNumber = 0 - for line in request:gmatch("[^\r\n]+") do - if lineNumber ~=0 then - -- tag / value are of the style "Host: 10.0.7.15". Break them up. - found, valueIndex = string.find(line, ": ") - if found == nil then - break - end - tag = string.sub(line, 1, found - 1) - value = string.sub(line, found + 2, #line) - parsedRequest[tag] = value - end - lineNumber = lineNumber + 1 - end - return parsedRequest +function parseRequest(request) + local result = {} + local matchEnd = 0 + + local matchBegin = matchEnd + 1 + matchEnd = string.find (request, " ", matchBegin) + result.method = string.sub(request, matchBegin, matchEnd-1) + + matchBegin = matchEnd + 1 + matchEnd = string.find(request, " ", matchBegin) + result.url = string.sub(request, matchBegin, matchEnd-1) + + matchBegin = matchEnd + 1 + matchEnd = string.find(request, "\r\n", matchBegin) + result.version = string.sub(request, matchBegin, matchEnd-1) + + return result end + +local function onReceive(connection, payload) + print(payload) -- for debugging + + -- parse payload and decide what to serve. + parsedRequest = parseRequest(payload) + --TablePrinter.print(parsedRequest, 3) + + --generates HTML web site + httpHeader200 = "HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nCache-Control: private, no-store\r\n\r\n" + html = "

Hola mundo

" + connection:send(httpHeader200 .. html) +end + +local function handleRequest(connection) + connection:on("receive", onReceive) + connection:on("sent", function(connection) connection:close() end) +end + +-- Starts web server in the specified port. +function httpserver.start(port, clientTimeoutInSeconds) + server = net.createServer(net.TCP, clientTimeoutInSeconds) + server:listen(port, handleRequest) + return server +end + +-- Stops the server. +function httpserver.stop(server) + server:close() +end + +return mymodule + +