No Description

Marcos Kirsch dfb2dbecdf Smaller GIF, but animated 9 years ago
http dfb2dbecdf Smaller GIF, but animated 9 years ago
LICENSE 49d8dc8d43 Initial commit 9 years ago
README.md 9c35443ea4 Updated to match code 9 years ago
b64.lua b0cbe2a77f Fix for Lua builds without floating point. 9 years ago
b64.py f52e8f47e6 Add all files to source control even though they are messy and don't do much yet 9 years ago
httpserver-error.lua 77920f4a94 Big refactoring: server now uses a separate thread that yields and then resumes on 'sent'. This allows us to serve large files. Moved serving of error pages and serving of static files into separate scripts httpserver-error.lua and httpserver-static.lua 9 years ago
httpserver-static.lua 4f6cd02b1f Fixes serving multiple connections simultaneously by reopening and scanning the file 9 years ago
httpserver.lua 84f7a06aa1 No longer crashes when request is HTTP 1.0 9 years ago
init.lua 1284b6363e Add compilation of server files. 9 years ago
makefile e31c35a3f3 Change to use nodemcu-uploader.py rather than luatool.py. It's faster with multiple files, but more importantly, it allows uploading binary files like images. Note that you will need a farly recent version of nodemcu-uploader. 9 years ago

README.md

nodemcu-httpserver

A (very) simple web server written in Lua for the ESP8266 firmware NodeMCU.

Features

  • GET
  • Multiple MIME types
  • Error pages (404 and others)
  • Server-side execution of Lua scripts
  • Query string argument parsing

How to use

  1. Upload server files using luatool.py or equivalent. Or, even better, use GNU Make with the bundled makefile. Type the following to upload server code, init.lua (which you may want to modify), and some example files.

     make upload
    

Compile the server files so that it uses less memory. This needs free memory so I suggest you do it after a fresh node.restart().

     node.compile("httpserver.lua")
     node.compile("httpserver-static.lua")
     node.compile("httpserver-error.lua")

If this is not in init.lua, then start the server by typing:

     dofile("httpserver.lc")(80)

In this example, 80 is the port your server is listening at but you can change it.

  1. Upload files you want to serve. Again, use luatool.py or similar and upload the HTML and other files.

All the files you upload must be prefixed with «http/». Wait, what?

Yes: NodeMCU’s filesystem does not support folders, but filenames can contain slashes. Only files that begin with «http/» will be accessible through the server.

  1. Visit your server from a web browser.

Example: Say the IP for your ESP8266 is 2.2.2.2 and the server is running in the default port 80. Go to http://2.2.2.2/index.html using your web browser. The ESP8266 will serve you with the contents of the file «http/myPage.html» (if it exists). If you visit the root (/) then index.html is served. By the way, unlike some http servers, the URLs are case-sensitive.

How to create dynamic Lua scripts

Similar to static files, upload a Lua script called «http/[name].lua where you replace [name] with the script’s name. The script should return a function that takes two parameters:

  return function (connection, args)
     -- code goes here
  end

Use the connection parameter to send the response back to the client. Note that you are in charge of sending the HTTP header. The args parameter is a Lua table that contains any arguments sent by the client in the GET request.

For example, if the client requests http://2.2.2.2/foo.lua?color=red then the server will execute the function in your Lua script foo.lua and pass in connection and args, where args.color == «red».

If you are going to be sending lots (as in over a KB) of data, you should yield the thread/coroutine every now and then in order to avoid overflowing the buffer in the microcontroller. Use:

  coroutine.yield()

Look at the included example scripts for more ideas.

Example: Garage door opener

Purpose

This is a bundled example that shows how to use nodemcu-httpserver together with server-side scripting to control something with the ESP8266. In this example, we will pretend to open a garage door. This is a very simple example that doesn’t even use arguments passed in the request (see example args.lua for that).

Your typical garage door opener has a wired remote with a single button. The button simply connects to two terminals on the electric motor and when pushed, the terminals are shorted. This causes the motor to open or close.

Hardware description

This example assumes that GPIO2 on the ESP8266 is connected to a relay that can be controlled. How to wire such thing is outside of the scope of this document but information is easily found online. The relay is controlled by the microcontroller and acts as the button, and can actually be connected in parallel with the existing mechanical button.

Software description

This example consists of the following files:

  • garage_door_opener.html: Static HTML displays a button with a link to the garage_door_opener.lua script. That’s it!
  • garage_door_opener.css: Provides styling for garage_door_opener.html just so it looks pretty.
  • garage_door_opener.lua: Does the actual work. The script first sends a little javascript snippet to redirect the client back to garage_door_opener.html and then toggles the GPIO2 line for a short amount of time (roughly equivalent to the typical button press for opening a garage door) and then toggles it back.
  • apple-touch-icon.png: This is optional. Provides an icon that will be used if you «Add to Home Screen» the demo. Now it looks like an app!`

Security implications

Be careful permanently installing something like this in your home. The scripts use no authentication and no encryption. Your only layer of security is your wifi network and anyone with access to it could open or close your garage, enter your home, and steal your flatscreen TV.

This script is provided simply as an educational example and you should treat accordingly.

Not supported

  • Other methods: HEAD, POST, PUT, DELETE, TRACE, OPTIONS, CONNECT, PATCH
  • HTTP authentication
  • Encryption

Open issues

  • File system doesn’t like long names, need to protect:

    PANIC: unprotected error in call to Lua API (httpserver.lua:78: filename too long)
    
  • nodemcu firmware with floating point doesn’t have enough memory to compile nor run the server. See below.

  • luatool.py which is used by the makefile, doesn’t support uploading binary files (yet?). But I’ve successfully used nodemcu-uploader. The only thing to know is that after uploading a file, you need to file.rename() it to add the http/ prefix.

Notes on memory usage.

The chip is very, very memory constrained. You must use a recent build of nodemcu-firmware that supports node.compile() since the server expects the helper scripts to be compiled.

  • If you can’t compile the server code without error even after a fresh restart, then you may need a build of the firmware without floating point. In file nodemcu-firmware/app/lua/luaconf.h right around line 572 (line number may change in the future) add

     #define LUA_NUMBER_INTEGRAL
    

    Then rebuild and re-flash the firmware.

  • Any help reducing the memory needs of the server without crippling its features are appreciated!