Simple HTTP framework

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
User avatar
fdushin
Posts: 32
Joined: Thu Jul 21, 2016 5:38 pm

Simple HTTP framework

Post by fdushin » Sun Nov 27, 2016 3:29 pm

I'm sure a million of these have been written already, but in the spirit of the recent FTP and Telnet servers, I have written a simple HTTP server and framework for micro python and the ESP8266. I feel like it's 1992 all over again!

https://github.com/fadushin/esp8266/tre ... hon/uhttpd

I am not a professional python coder by any stretch of the imagination, so any comments, criticisms, PRs, etc are appreciated. I wrote this as a framework for writing a web interface to control a simple ESP8266 application I am blogging about, but I thought it might be of more use, generally to people. The accepting socket is meant to run in the background, but to keep things simple, I have left the sockets representing the client connections in blocking mode.

Also, in case it is not glaringly obvious already, this software provides NO SECURITY and may expose sensitive security information, such as webrepl or other passwords, to malicious agents on your network. This software is NOT intended for production use!

Enjoy!
Last edited by fdushin on Mon Jan 02, 2017 12:51 am, edited 1 time in total.

User avatar
fdushin
Posts: 32
Joined: Thu Jul 21, 2016 5:38 pm

Re: Simple HTTP framework

Post by fdushin » Mon Dec 05, 2016 4:34 am

I've posted some improvements. While the server does not (yet) support SSL, some of the caveats are now mitigated by using a root path ('/www', but default) to service files. The server now supports a REST-based JSON API. Eventually I'd like to write a thick web client using backbone.js or equivalent for managing the device (networking, time, memory usage, etc) through a web console.

bitninja
Posts: 115
Joined: Thu Sep 15, 2016 4:09 pm
Location: Spring, Texas

Re: Simple HTTP framework

Post by bitninja » Tue Dec 06, 2016 2:41 am

Thanks for posting your work!

I've given it a spin and noticed that I could only get it to work from a hard reset. When I try to start it from a soft reboot, I get this...
error.png
error.png (8.38 KiB) Viewed 7388 times
Here is my simple test (test_http.py)...

Code: Select all

import uhttpd
import http_file_handler

def main():
    server = uhttpd.Server([('/', http_file_handler.Handler())])
    server.start()
and (main.py)...

Code: Select all

import test_http
test_http.main()
Is this a memory issue?

User avatar
Roberthh
Posts: 1569
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Simple HTTP framework

Post by Roberthh » Tue Dec 06, 2016 6:08 am

I get that all the time during testing. That happens when you leave your code with open connections. If you close all sockets, then soft reboot works fine.

User avatar
fdushin
Posts: 32
Joined: Thu Jul 21, 2016 5:38 pm

Re: Simple HTTP framework

Post by fdushin » Tue Dec 06, 2016 2:22 pm

Roberthh wrote:I get that all the time during testing. That happens when you leave your code with open connections. If you close all sockets, then soft reboot works fine.
Thanks @Roberthh. I almost never use soft reboots, so I had never seen this.

@bitninja You can stop the server by using the stop() method, and that seems to do the trick.

bitninja
Posts: 115
Joined: Thu Sep 15, 2016 4:09 pm
Location: Spring, Texas

Re: Simple HTTP framework

Post by bitninja » Tue Dec 06, 2016 11:06 pm

Roberthh wrote:I get that all the time during testing. That happens when you leave your code with open connections. If you close all sockets, then soft reboot works fine.
Thanks for the info. How do I close open sockets ? (When they are embedded in a class). Are there some generic commands for closing any open sockets?

I've changed my test script...

Code: Select all

import uhttpd
import http_file_handler

def main():
    server = uhttpd.Server([('/', http_file_handler.Handler())])
    server.start()
    server.stop()
But I am still unclear as to how I am getting into a state with an open socket. Hows does one do that?

User avatar
Roberthh
Posts: 1569
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Simple HTTP framework

Post by Roberthh » Wed Dec 07, 2016 6:21 am

How do I close open sockets ?
That's hard to tell and depends on you set-up. I assume that the server.stop() method closes all sockets opened by the server class. Butthere may be more open, like when you connect through webrepl.

For myself, I do not care so much, since during testing a) pushing the reset button is more convenient than typing stop() + Ctrl-D, and b) reset bring the device into a well defined initial state. And when a system with a server is done and operational, it's not supposed to stop.

User avatar
fdushin
Posts: 32
Joined: Thu Jul 21, 2016 5:38 pm

Re: Simple HTTP framework

Post by fdushin » Wed Dec 07, 2016 11:59 am

Thanks for the info. How do I close open sockets ? (When they are embedded in a class). Are there some generic commands for closing any open sockets?
When you start the uhttpd server, that will open a server-side socket which is listening on port 80 (by default) for connections from clients. That socket is needed for the server to service HTTP requests, and will stay open until the server is stopped.
I've changed my test script...

Code: Select all

import uhttpd
import http_file_handler

def main():
    server = uhttpd.Server([('/', http_file_handler.Handler())])
    server.start()
    server.stop()
This will just start the server and then stop it. That's probably not what you want, if you want to use the server.
But I am still unclear as to how I am getting into a state with an open socket. Hows does one do that?
I think what you want is a command that will do a soft reset, but stop the server first. I am not sure why a soft reset is necessary for you -- I usually just use machine.reset(). So you could try:

Code: Select all

import uhttpd
import http_file_handler

def main():
    server = uhttpd.Server([('/', http_file_handler.Handler())])
    server.start()

def reboot():
    server.stop()
    import machine
    machine.reset()
But that's a hard reset. I don't know how to do a soft reset programatically. Google suggests sys.exit, but that's doesn't seem to do the trick. Is there a reason you need to do a soft reset?

bitninja
Posts: 115
Joined: Thu Sep 15, 2016 4:09 pm
Location: Spring, Texas

Re: Simple HTTP framework

Post by bitninja » Wed Dec 07, 2016 3:00 pm

OK, I think I've got it. Thanks everybody for the information and the help.

User avatar
fdushin
Posts: 32
Joined: Thu Jul 21, 2016 5:38 pm

Re: Simple HTTP framework

Post by fdushin » Sun Dec 11, 2016 12:38 am

I moved the uhttpd module to https://github.com/fadushin/esp8266/tre ... hon/uhttpd and added support for HTTP Basic authentication.

In manipulating HTML and Javascript files on the ESP8266, I found myself wanting a shell, so I wrote a very basic one called ush, which you can find at

https://github.com/fadushin/esp8266/tre ... thon/tools

It, too, takes memory to run, so I'd recommend burning it into flash, but it's really more a of a development tool, rather than a runtime production tool.

Enjoy!

Post Reply