A more complicated Arduino-based Http-serving application starting point
 
 
Go to file
Kenneth Barbour 42b1566785 added assignment operator and const correctness 2018-11-29 14:16:44 -05:00
examples some basic examples that toggle the builtin ESP8266 LED 2018-04-16 21:01:19 -04:00
src added assignment operator and const correctness 2018-11-29 14:16:44 -05:00
test added assignment operator and const correctness 2018-11-29 14:16:44 -05:00
.gitignore gitignore, simpler directory structure and Makefile 2018-02-20 19:13:20 -05:00
LICENSE.txt added license 2018-04-28 10:15:34 -04:00
Makefile Removed unused constructors for HttpResponse 2018-04-05 12:48:08 -04:00
README.markdown Usage documentation 2018-04-25 12:37:37 -04:00
library.properties Added a properties file for arduino ide 2018-03-02 18:26:04 -05:00

README.markdown

HttpServer

A Complicated Arduino Web Server Implementation

Features

  • Designed around the popular ESP8266 playform
  • Pattern-based request routing allows a callback to handle URL requests matching simple patterns
  • Basic Buffer class provided for Response content, as well as support for File and other Stream-based content
  • Simple request lifecycle control allows processing before and after requests are made
  • Error handling callback functions

Usage

Included here, a guide for implementing a Web Application as part of your Arduino project. For simplicity, this guide stores variables and implements function globally.

Define

Include WebKernel.h and define a Routes array, WebKernel object, and a Response Buffer to store response data. The WebKernel contructor needs the port number, routes array, and the number of routes in the array.

/*
 *  File: example.ino
 */
#include <WebKernel.h>

// Define maximum size of content buffer
#define CONTENT_SIZE 512

// TODO: put function prototypes here

Routes routes = {
		{ GET, "/", handle_index },
		{ GET|POST, "/foo", handle_foo },
		{ POST, "/bar", handle_post_bar },
		{ GET, "/bar", handle_get_bar }
	};

WebKernel webKernel(80, routes, sizeof(routes)/sizeof(routes[0]));

uint8_t content_data[CONTENT_SIZE];			// Global block of memory to store content
Buffer content(content_data, CONTENT_SIZE);   // Buffer to write data to previously allocated content_data

Implement

Each route defined in the routes array will need a function implemented to handle requests for that route. You can put them in the main sketch .ino file anywhere as long as you include a function prototype before the Routes definition. Alternatively, you could write prototypes in a file like routes.h, and implement them in a file like routes.cpp.

// Function prototypes
void handle_index    (HttpRequest&, HttpResponse&); // handle GET request for '/'
void handle_foo      (HttpRequest&, HttpResponse&); // handle GET or POST request for '/foo'
void handle_post_bar (HttpRequest&, HttpResponse&); // handle POST request for '/bar'
void handle_get_bar  (HttpRequest&, HttpResponse&); // handle GET request for '/bar'

Function prototypes should be put before any other reference to one of the functions is made. In this example, they should be defined before defining the Route array.

Next, implement each of the functions we just defined:

void handle_index(HttpRequest& request, HttpResponse& response)
{
	response.setContent(content);
	content.println("<!doctype html><html><head><title>Site Index</title></head><body><h1>Site Index</h1></body></html>");
}

Initialize

Initialize the webKernel in your sketch's setup function.

void setup()
{
	// initialize Serial, WiFi, Ethernet, etc

	webKernel.begin();
}

Drive

The WebKernel has everything it needs to handle requests now. The only thing left is to make a call to webKernel.handleClients() as part of your sketch's loop function.

void loop()
{

	webKernel.handleClients();

	// ... include other sketch routines
}

Additional Callbacks

For more complicated projects, such as projects also serving static files or other Stream objects, its helpful to have more control over the WebKernel throughout the request handling process. It is also helpful to have control over Method Not Allowed and File Not Found errors.

Each of the callbacks listed below are of the form void handler (HttpRequest&, HttpResponse&) with the exception of the Terminate Handler, which is void terminate_handler (const HttpRequest&, const HttpResponse&).

void setup()
{
	// ... other setup routines

	webKernel.begin();
	webKernel.setInitHandler(init_webkernel); // called before dispatching to the routes handler
	webKernel.setTerminateHandler(term_webkernel); // called after sending response to client
	webKernel.setNotFoundHandler(handle_not_found); // called if a route is not found for the request
	webKernel.setMethodNotAllowedHandler(handle_method_not_allowed); // called if a route is found, but the request method is not allowed

}

Examples

Basic Web Application

Open the basic example in your Arduino IDE and upload it to your ESP8266. These examples use the ESP8266 as a Standalone Access Point, so refer to the sketch for the SSID and password, or connect it to a Serial monitor before it starts.

To test, connect to its wireless access point and go to (http://192.168.1.4/), the default IP address for the ESP.

Filesystem Web Application

Similar to the basic example, except this example also includes static content in the data directory that needs to be uploaded separately.

To upload the static content to an ESP8266, you will need to use the ESP8266FS tool described here: (https://esp8266.github.io/Arduino/versions/2.0.0/doc/filesystem.html#uploading-files-to-file-system)