Browse Source

Minimalistic server can be started and returns hardcoded message, prior to cleanup

Marcos Kirsch 9 years ago
parent
commit
1c709b838b
1 changed files with 79 additions and 53 deletions
  1. 79 53
      httpserver.lua

+ 79 - 53
httpserver.lua

@@ -1,28 +1,81 @@
 -- 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")
 
+-- Functions below aren't part of the public API
+-- Clients don't need to worry about them.
 
--- 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)
+-- given an HTTP request, returns the method (i.e. GET)
+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
+   httpMethods = {"GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "OPTIONS", "CONNECT", "PATCH"}
+   method = nil
+   for i=1,#httpMethods do
+      found = string.find(request, httpMethods[i])
+      if found == 1 then
+         break
+      end
+   end
+   return (httpMethods[found])
+end
+
+---- 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
 
+function parseRequest(request)
+   local result = {}
+   local matchEnd = 0
 
-httpserver.private = {} -- not part of the public API
+   local matchBegin = matchEnd + 1
+   matchEnd = string.find (request, " ", matchBegin)
+   result.method = string.sub(request, matchBegin, matchEnd-1)
 
-function httpserver.private.onReceive(connection, payload)
+   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 = private.parseRequest(payload)
-   httpserver.private.printTable(parsedRequest, 3)
+   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"
@@ -30,50 +83,23 @@ function httpserver.private.onReceive(connection, payload)
    connection:send(httpHeader200 .. html)
 end
 
-function httpserver.private.handleRequest(connection)
+local function handleRequest(connection)
    connection:on("receive", onReceive)
-   connection:on("sent",function(connection) connection:close() end)
+   connection:on("sent", function(connection) connection:close() end)
 end
 
--- given an HTTP request, returns the method (i.e. GET)
-function httpserver.private.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
-   httpMethods = {"GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "OPTIONS", "CONNECT", "PATCH"}
-   method = nil
-   for i=1,#httpMethods do
-      found = string.find(request, httpMethods[i])
-      if found == 1 then
-         break
-      end
-   end
-   return (httpMethods[found])
+-- 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
 
--- given an HTTP request, returns a table with all the information.
-function httpserver.private.parseRequest(request)
-   parsedRequest = {}
-   -- First get the method
-
-   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
+-- Stops the server.
+function httpserver.stop(server)
+   server:close()
 end
+
+return mymodule
+
+