Server side minimalistic HTTP protocol implementation for the Arduino platform.

ArduinoHttpServer

Codacy Badge Build Status Code Climate Test Coverage

Server side minimalistic Object Oriented HTTP protocol implementation for the Arduino platform.

ArduinoHttpServer is a simple HTTP request and reply implementation targeted for the embedded Arduino framework. The implementation parses an HTTP request/reply reading/printing from/to any Stream (either Serial or Wifi/Ethernet).

What you do with the request or what you reply is entirely up to your imagination. Very little implicit behaviour.

Quick start

Reading an HTTP request from some Stream instance

// This example uses the Stream instance Serial, might also be a WifiClient object.
// Reserve 512 bytes for body content storage.
ArduinoHttpServer::StreamHttpRequest<512> httpRequest(Serial);
bool success(httpRequest.readRequest())
if (success) // If no HTTP parsing error or read timeout occurred.
{
   // See interface api for other methods.
   const char *body( httpRequest.getBody() );
   // Retrieve 4th part (index is zero based) of the resource URL.
   // E.g. state from: "/api/sensors/1/state"
   const String& restFunction( httpRequest.getResource()[3] );
}

Writing an HTTP reply to some Stream

ArduinoHttpServer::StreamHttpReply httpReply(Serial, "application/json");
httpReply.send("{\"All your base are belong to us!\"}");

Documentation

Documentation available in the ArduinoHttpServer Github wiki

Characteristics

  • HTTP parser with protocol validation.
  • Puts you in control on how to react on a HTTP request; no implicit behaviour.
  • Customizable memory footprint for caching returned body data.
  • No external dependencies outside of the standard Arduino framework.
  • Object oriented implementation.
  • Basic authorization support (initial version by Tomer-W)
Owner
Sander
Slow pace developing of HomeKit related automation devices and plugins in my spare time.
Sander
Comments
  • Add basic authorization support.

    Add basic authorization support.

    Hi QuickSander,

    I really like this HTTP server, noticeably light. I was missing the basic authorization support so decided to add it. There is only one caveat with this change, it does require dependency on another library to get base64 encoding which is needed for this task. I'm not sure I know how to mark that dependency so the Arduino IDE will be aware of that. That library is tiny so I hope it will be ok with you.

    I also did some minor fix in your sample as it seems you are missing closing the connection.

    If you are fine with that direction, I can add new sample to show the usage.

    Thanks, Tomer.

  • StreamHttpRequest.hpp Syntax Error

    StreamHttpRequest.hpp Syntax Error

    In file included from lib/ArduinoHttpServer-0.1.1/src/ArduinoHttpServer.h:11,
                     from .build/uno/src/blinky.cpp:2:
    lib/ArduinoHttpServer-0.1.1/src/internals/StreamHttpRequest.hpp: In constructor 'ArduinoHttpServer::StreamHttpRequest<MAX_BODY_LENGTH>::StreamHttpRequest(Stream&)':
    lib/ArduinoHttpServer-0.1.1/src/internals/StreamHttpRequest.hpp:110: error: expected `(' before '{' token
    lib/ArduinoHttpServer-0.1.1/src/internals/StreamHttpRequest.hpp:110: error: expected `;' before '}' token
    lib/ArduinoHttpServer-0.1.1/src/internals/StreamHttpRequest.hpp: At global scope:
    lib/ArduinoHttpServer-0.1.1/src/internals/StreamHttpRequest.hpp:110: error: expected unqualified-id before ',' token
    lib/ArduinoHttpServer-0.1.1/src/internals/StreamHttpRequest.hpp:111: error: expected constructor, destructor, or type conversion before '(' token
    
  • Not working from either the Web editor nor the IDE

    Not working from either the Web editor nor the IDE

    Hello,

    I am building a fan controller script using an Arduino Uno WiFi Rev2 but I always an error regarding a missing Base64 library not being included in ArduinoHttpServer:

    StreamHttpRequest.hpp:403:30: error: 'Base64' was not declared in this scope

    This happens on both the Web editor and the regular Arduino IDE. I've already tried manually including Base64 in the top of my script.

    This is my script:

    // ArduinoHttpServer - Version: Latest
    #include <ArduinoHttpServer.h>
    
    // #include <Arduino.h>
    
    
    #include <SPI.h>
    #include <WiFi.h>
    
    const char* ssid = "MYWIFI";
    const char* password = "PASSWORD";
    
    // UTIL FUNCTIONS
    
    String wrapInQoutes(String input) {
      return "\"" + input + "\"";
    }
    
    String boolToString(boolean b) {
      if (b) {
        return "true";
      } else {
        return "false";
      }
    }
    
    
    struct fan {
      int pin;
      String name = "";
      int speed = 0;
      boolean clockwiseRotation = true;
    };
    
    struct fan fans[4];
    
    void makeFans() {
      fans[0].pin = 3;
      fans[0].name = "ROOM 1";
    
      fans[1].pin = 5;
      fans[1].name = "ROOM 2";
    
      fans[2].pin = 6;
      fans[2].name = "ROOM 3";
    
      fans[3].pin = 9;
      fans[3].name = "ROOM 4";
    }
    
    
    void setupPins() {
      pinMode(3, OUTPUT);
      pinMode(5, OUTPUT);
      pinMode(6, OUTPUT);
      pinMode(9, OUTPUT);
      
      analogWrite(3, 127);
      analogWrite(5, 127);
      analogWrite(6, 127);
      analogWrite(9, 127);
    }
    
    String makeJSONForFan(struct fan *f) {
      Serial.println("makeJSONForFan");
      Serial.println("Making JSON for fan " + f->name);
      String output = "";
      output += "{ ";
      output += wrapInQoutes("pin");
      output += ": ";
      output += f->pin;
      output += ", ";
      output += wrapInQoutes("name");
      output += ": ";
      output += wrapInQoutes(f->name);
      output += ", ";
      output += wrapInQoutes("speed");
      output += ": ";
      output += f->speed;
      output += ", ";
      output += wrapInQoutes("clockwiseRotation");
      output += ": ";
      output += boolToString(f->clockwiseRotation);
      output += " }";
      return output;
    }
    
    
    
    WiFiServer wifiServer(80);
    
    void setup()
    {
      setupPins();
      delay(1000);
      Serial.begin(9600);
    
      makeFans();
      Serial.println("Starting Wifi Connection…");
    
      WiFi.begin(const_cast<char*>(ssid), password);
      while (WiFi.status() != WL_CONNECTED)
      {
        delay(1000);
        Serial.println("Connecting...");
      }
      printWifiStatus();
      wifiServer.begin();
    }
    
    void(* reset) (void) = 0; 
    
    void printWifiStatus() {
      // print the SSID of the network you're attached to:
      Serial.print("SSID: ");
      Serial.println(WiFi.SSID());
    
      // print your WiFi shield's IP address:
      IPAddress ip = WiFi.localIP();
      Serial.print("IP Address: ");
      Serial.println(ip);
    
      // print the received signal strength:
      long rssi = WiFi.RSSI();
      Serial.print("signal strength (RSSI):");
      Serial.print(rssi);
      Serial.println(" dBm");
    }
    
    
    
    void updateFan(struct fan f) {
      // PWM from 0-255, 0-126 clockwise, 128-255 counter-clockwise
      // speed should be 0-100
      double calc = f.speed * 127 / 100 * (f.clockwiseRotation * 2 - 1) + 127;
      int c = calc;
      Serial.println("Setting PWM of fan " + f.name + " on PIN " + f.pin + " to " + c);
      analogWrite(f.pin, c);
    }
    
    
    
    void loop()
    {
      if (WiFi.status() != WL_CONNECTED) {
        reset();
      }
      WiFiClient client( wifiServer.available() );
      if (client.connected())
      {
        // Connected to client. Allocate and initialize StreamHttpRequest object.
        ArduinoHttpServer::StreamHttpRequest<1023> httpRequest(client);
    
        // Parse the request.
        if (httpRequest.readRequest())
        {
          // Use the information you like they way you like.
    
          // Retrieve HTTP resource / URL requested
          Serial.println( httpRequest.getResource().toString());
    
          
    
          // Retrieve HTTP method.
          // E.g.: GET / PUT / HEAD / DELETE / POST
          ArduinoHttpServer::Method method( ArduinoHttpServer::Method::Invalid );
          method = httpRequest.getMethod();
    
          if ( method == ArduinoHttpServer::Method::Get )
          {
            if (httpRequest.getResource()[0] == "fans") {
              // /fans
              // check if root
              if (httpRequest.getResource().toString() == "/fans") {
                Serial.println("List all fans");
                // List all fans
                ArduinoHttpServer::StreamHttpReply httpReply(client, "application/json");
                String allFansJSON = "[";
    
                allFansJSON += makeJSONForFan(&fans[0]);
                allFansJSON += ", ";
    
                allFansJSON += makeJSONForFan(&fans[1]);
                allFansJSON += ", ";
    
                allFansJSON += makeJSONForFan(&fans[2]);
                allFansJSON += ", ";
    
                allFansJSON += makeJSONForFan(&fans[3]);
                allFansJSON += "]";
    
    
                httpReply.send(allFansJSON);
    
              } else {
                // /fans/[0-3]
                String fanIDString = httpRequest.getResource()[1];
                int fanID = fanIDString.toInt();
                if (fanID > -1 && fanID < 4) {
                  // /fans/[0-3]/speed/[0-100]
                  if (httpRequest.getResource()[2] == "speed") {
                    // set fan speed
                    String speedString = httpRequest.getResource()[3];
                    int newSpeed = speedString.toInt();
                    fans[fanID].speed = newSpeed;
                    updateFan(fans[fanID]);
    
                  } else if (httpRequest.getResource()[2] == "direction") {
                    // /fans/[0-3]/direction
                    // set fan direction
                    if (httpRequest.getResource()[3] == "clockwise") {
                      // set fan direction clockwise
                      fans[fanID].clockwiseRotation = true;
                      updateFan(fans[fanID]);
                    } else if (httpRequest.getResource()[3] == "counter-clockwise") {
                      // set fan direction counter-clockwise
                      fans[fanID].clockwiseRotation = false;
                      updateFan(fans[fanID]);
    
                    }
                  }
                  ArduinoHttpServer::StreamHttpReply httpReply(client, "application/json");
                  httpReply.send(makeJSONForFan(&fans[fanID]));
                }
              }
    
    
    
    
    
    
            }
    
        }
    
    
        }
        else
        {
          // HTTP parsing failed. Client did not provide correct HTTP data or
          // client requested an unsupported feature.
          ArduinoHttpServer::StreamHttpErrorReply httpReply(client, httpRequest.getContentType());
          httpReply.send("");
        }
      }
    
    }
    

    I assume this is an issue in the ArduinoHttpServer since the error mentions Base64 not being included inside it.

  • Save some RAM by putting strings only to program memory.

    Save some RAM by putting strings only to program memory.

    Store strings only in the program memory, instead of keeping them additional in the RAM. This helps much using the library on small Arduino devices, especially for the Atmel controllers.

  • Use a single tab field separator in keywords.txt

    Use a single tab field separator in keywords.txt

    Each field of keywords.txt is separated by a single true tab. When you use multiple tabs it causes the field to be interpreted as empty. On Arduino IDE 1.6.5 and newer an empty KEYWORD_TOKENTYPE causes the default editor.function.style coloration to be used (as with KEYWORD2, KEYWORD3, LITERAL2). On Arduino IDE 1.6.4 and older it causes the keyword to not be recognized for any special coloration.

    Reference: https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification#keywords

  • Feature/add headers

    Feature/add headers

    This adds the possibility to add maximum 3 extra header fields to the response. This is useful when using the ArduinoHttpServer to serve REST calls and you want the caller to reside somewhere else (like a local HTML file).

    Usage:

    httpReply.addHeader("Access-Control-Allow-Origin", "*");

    Tested and works on the Arduino MKR Wifi

  • Compile issue using Arduino IDE 1.8.13

    Compile issue using Arduino IDE 1.8.13

    When I include the library in my code, I'm unable to compile...

    In file included from C:\Users\stidsen\Documents\Arduino\libraries\ArduinoHttpServer\src\internals\HttpResource.cpp:10:0: C:\Users\stidsen\Documents\Arduino\libraries\ArduinoHttpServer\src\internals\HttpResource.hpp:23:24: error: 'String' does not name a type HttpResource(const String& resource); ^~~~~~

    I worked my way around the problem by:

    1. Changing the order of #include "FixString.hpp" and #include "Arduino.h" in HttpField.hpp
    2. Replaced #include <WString.h> by #include <Arduino.h> in HttpResource.hpp
Arduino Arduino library for the CloudStorage server project. The library provides easy access to server-stored values and operations.

Arduino-CloudStorage Arduino/ESP8266 library that allows you to easly store and retreive data from a remote (cloud) storage in a key/value fashion. Cl

Jan 30, 2022
Arduino HTTP Client library

ArduinoHttpClient ArduinoHttpClient is a library to make it easier to interact with web servers from Arduino. Derived from Adrian McEwen's HttpClient

Jan 6, 2023
A library to simplify the process of getting and storing data to Antares IoT Platform through HTTP on ESP8266.
A library to simplify the process of getting and storing data to Antares IoT Platform through HTTP on ESP8266.

Antares ESP8266 HTTP This is the documentation for Antares ESP8266 library. This library is meant to simplify the process of retrieving and deploying

Jul 2, 2021
Arduino web server library.

aWOT Arduino web server library. Documentation 1. Getting started Hello World Basic routing Application generator Serving static files 2. Guide Routin

Jan 4, 2023
Arduino library for making an IHC in or output module using an Arduino

Introduction This is an Arduino library for making an IHC in or output module using an Arduino. (IHC controller is a home automation controller made b

Mar 26, 2020
ArduinoIoTCloud library is the central element of the firmware enabling certain Arduino boards to connect to the Arduino IoT Cloud

ArduinoIoTCloud What? The ArduinoIoTCloud library is the central element of the firmware enabling certain Arduino boards to connect to the Arduino IoT

Dec 16, 2022
Arduino TopLevel Client for aliyun IoT Platform

运行于 arduino 的 阿里云 IoT 接入 SDK,在底层连接的基础上增加数据回调绑定、发送数据和事件等 api 的封装,免去自己解析数据的痛苦

Dec 13, 2022
The World's Most Useless Arduino Platform.
The World's Most Useless Arduino Platform.

boot2duino boot2duino serves no other purpose than to generate a bootable x86 floppy image using the Arduino IDE, which seemingly serves no purpose. W

Nov 6, 2022
An implementation of a ANT driver for Arduino, Mbed and ESP-IDF

ant-arduino Arduino library for communicating with ANT radios, with support for nRF51 devices. This library Includes support for the majority of packe

Dec 4, 2022
An Implementation of the ANT+ Network on top of ant-arduino

antplus-arduino An Implementation of the Ant+ Network on top of ant-arduino Status News 6/28/2020 v2.0.0 of ant-arduino released with support for mbed

Dec 2, 2022
High level HTTP Request Library that gives a javascript fetch like API.

Fetch for Arduino fetch is a high level HTTP Request Library that gives you a javascript fetch like API. ResponseOptions options; options.method = "PO

Dec 28, 2022
Arduino library for controlling the MCP2515 in order to receive/transmit CAN frames.
Arduino library for controlling the MCP2515 in order to receive/transmit CAN frames.

107-Arduino-MCP2515 Arduino library for controlling the MCP2515 in order to receive/transmit CAN frames. This library is prepared to interface easily

Nov 16, 2022
Arduino library for interfacing with any GPS, GLONASS, Galileo or GNSS module and interpreting its NMEA messages.
Arduino library for interfacing with any GPS, GLONASS, Galileo or GNSS module and interpreting its NMEA messages.

107-Arduino-NMEA-Parser Arduino library for interfacing with any GPS, GLONASS, Galileo or GNSS module and interpreting its NMEA messages. This library

Jan 1, 2023
Arduino library for providing a convenient C++ interface for accessing UAVCAN.
Arduino library for providing a convenient C++ interface for accessing UAVCAN.

107-Arduino-UAVCAN Arduino library for providing a convenient C++ interface for accessing UAVCAN (v1.0-beta) utilizing libcanard. This library works f

Jan 2, 2023
A RESTful environment for Arduino

aREST Overview A simple library that implements a REST API for Arduino & the ESP8266 WiFi chip. It is designed to be universal and currently supports

Dec 29, 2022
Arduino, esp32 and esp8266 library for ABB (ex PowerOne) Aurora Inverter, implement a full methods to retrieve data from the Inverter via RS-485
Arduino, esp32 and esp8266 library for ABB (ex PowerOne) Aurora Inverter, implement a full methods to retrieve data from the Inverter via RS-485

ABB Aurora protocol You can refer the complete documentation on my site ABB Aurora PV inverter library for Arduino, esp8266 and esp32 I create this li

Nov 22, 2022
MCP2515 CAN Controller Driver for Arduino

MCP2515 CAN Controller Library for Arduino Compatibility with the ACAN library This library is fully compatible with the Teensy 3.x ACAN library https

Dec 13, 2022
Arduino library for the MCP2515 CAN Controller

MCP2515 CAN Controller Library for Arduino Compatibility with the ACAN library This library is fully compatible with the Teensy 3.x ACAN library https

Dec 18, 2022
Arduino CAN driver for MCP2517FD CAN Controller (in CAN 2.0B mode)

MCP2517FD CAN Controller Library for Arduino (in CAN 2.0B mode) Compatibility with the other ACAN libraries This library is fully compatible with the

Dec 22, 2022