lasselukkari / aWOT

Arduino web server library.
MIT License
294 stars 42 forks source link
arduino esp32 esp8266 http iot rest rest-api web-server

aWOT Build Status

Arduino web server library.

Documentation

1. Getting started

Compatibility

The aWOT web server library has been designed to work with all Arduino compatible development boards and networking options. This also means that switching the board or changing from WiFi to Ethernet will require minimal changes. The examples directory shows you how to use the library with the most popular Ethernet and WiFi libraries

However there are few subtle differences that need to be taken into account. Also unfortunately some of the WiFi and Ethernet libraries have bugs that prevent the library from working properly.

Previously the library has been tested with:

ESP32 and ESP8266 WiFi

In both of the ESP Arduino cores the WiFiClient closes the connection automatically in the class destructor. This means that the client.stop(), does not need to be explicitly called but you will need to take extra steps if you want to keep the connection alive.

ESP32 + Wiznet W5500

The current version of the ESP32 Arduino core uses a non standard version of the Server class. Until the ESP32 core is fixed you need to manually modify the begin function in the Server.h if you want to use the Ethernet library that is shipped with the core.

Bug report: https://github.com/espressif/arduino-esp32/issues/2704

Teensy 4.1 + Ethernet

The Teensy 4.1 Ethernet library currently has a bug that causes the connection to stall and reset when connections to the server are opened in fast phase. The bug has been verified but not fixed yet.

Bug report: https://github.com/vjmuzik/NativeEthernet/issues/7

Arduino UNO

Because of the limited RAM and ROM Arduino UNO is on the edge of being usable for anything more complicated. If you want to use this library together with the SD card or any JSON parsing library, pay attention that you do not run out of memory.

Examples

Hello World

#include <WiFi.h>
#include <aWOT.h>

WiFiServer server(80);
Application app;

void index(Request &req, Response &res) {
  res.print("Hello World!");
}

void setup() {
  Serial.begin(115200);

  WiFi.begin("ssid", "password");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(WiFi.localIP());

  app.get("/", &index);
  server.begin();
}

void loop() {  
  WiFiClient client = server.available();

  if (client.connected()) {
    app.process(&client);
    client.stop();
  }
}

Query parameters

// HTTP GET /cats?type=lolcat
void queryParams(Request &req, Response &res) {
  char type[64];
  req.query("type", type, 64);

  res.print(type); // "lolcat"
}

void setup() {
  // other setup ...
  app.get("/cats", &queryParams);
}

Route paramaters

// HTTP GET /cats/lolcat
void routeParams(Request &req, Response &res) {
  char catId[64];
  req.route("catId", catId, 64);

  res.print(catId);
}

void setup() {
  // other setup
  app.get("/cats/:catId", &routeParams);
}

Post parameters

void postParams(Request &req, Response &res) {
  char name[10];
  char value[64];

  while (req.left()) {
    req.form(name, 10, value, 64);
    res.print(name);
    res.print(": ");
    res.println(value);
  }
}

void setup() {
  // other setup

  app.post("/form", &postParams);
}

Reading and writing headers

char userAgentBuffer[200];

// HTTP GET /headers
void headers(Request &req, Response &res) {
  char * userAgent = req.get("User-Agent"); // "Mozilla/5.0 (Macintosh; Inte ...."

  res.set("Cookie", "lolcat"); // will set Cookie header value to "lolcat"
  res.print(userAgent);
}

void setup() {
  // other setup

  // header names are handled case insensitive
  app.header("User-Agent", userAgentBuffer, 200); 
  app.get("/useragent", &headers);
}

Routers

Application app;
Router cats;

void looooong(Request &req, Response &res) {
  res.print("looooong cat is long!");
}

void ceiling(Request &req, Response &res) {
  res.print("ceiling cat is watching you debug!");
}

void nyannyan(Request &req, Response &res) {
  for (int i = 0; i < 100; i++) {
      res.print("nyan ");
  }
}

void setup() {
  // other setup

  cats.get("/long", &looooong);
  cats.get("/ceiling", &ceiling);
  cats.get("/nyan", &nyannyan);

  app.use("/cats", &cats);
}

Reducing memory usage

If you need to reduce the memory consumption add #define LOW_MEMORY_MCU before you import the library. This will reduce the size of a few internal buffers. Normally this is only used for the smallest AVR boards but it can be enabled for others if needed.

Also use the P macro to place any strings in to the program memory instead of wasting the precious RAM.

P(longString) = "Lots of text here...";
res.printP(longString);

Acknowledgements

Based on Webduino, Copyright 2009-2014 Ben Combee, Ran Talbott, Christopher Lee, Martin Lormes, Francisco M Cuenca-Acuna

Licence

MIT