Skip to content

This is simple yet complete WebServer library for AVR, Portenta_H7, Teensy, SAM DUE, SAMD21/SAMD51, nRF52, STM32, RP2040-based, etc. boards running Ethernet shields. The functions are similar and compatible to ESP8266/ESP32 WebServer libraries to make life much easier to port sketches from ESP8266/ESP32.

License

Notifications You must be signed in to change notification settings

latchdevel/EthernetWebServer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EthernetWebServer

arduino-library-badge GitHub release GitHub contributions welcome GitHub issues

New in v1.0.6

  1. Add support to ESP32 and ESP8266 boards.

New in v1.0.5

  1. Add support to nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense, Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc.
  2. Support any future custom Ethernet library that meets the no-compiling-error requirements. Currently Ethernet2, EThernet3, EthernetLarge libraries are supported. Ethernet_Shield_W5200, EtherCard, EtherSia libraries are not supported now.

New in v1.0.4

  1. Add support to SAM51 (Itsy-Bitsy M4, Metro M4, Grand Central M4, Feather M4 Express, etc.).

From v1.0.3+, the library supports more Arduino boards ( SAM DUE, SAMD21: ZERO, MKR, NANO_33_IOT, M0, M0 Pro, AdaFruit CIRCUITPLAYGROUND_EXPRESS, etc.)

From v1.0.2+, the library supports many more Arduino boards (Atmel AVR-s, Atmel SAM3X8E ARM Cortex-M3, STM32F series, ESP8266, Intel ARC32(Genuino101), Nordic nRF51(RFduino), Teensy boards, Realtek Ameba(RTL8195A,RTL8710)) using Wiznet W5x00 or ENC28J60 EThernet shields by using UIPEthernet library besides standard Ethernet library.

This is simple yet complete WebServer library for AVR, Teensy,SAM, STM32F, Intel, etc. boards running Ethernet shields. The functions are similar and compatible to ESP8266/ESP32 WebServer libraries to make life much easier to port sketches from ESP8266/ESP32.

The library supports

  1. HTTP Server and Client
  2. HTTP GET and POST requests, provides argument parsing, handles one client at a time.

Library is based on and modified from:

  1. Ivan Grokhotkov's ESP8266WebServer

The EthernetWebServer class found in EthernetWebServer.h header, is a simple web server that knows how to handle HTTP requests such as GET and POST and can only support one simultaneous client.

Prerequisite

  1. Arduino IDE 1.8.11 or later for Arduino
  2. Arduino AVR core 1.8.2 or later for Arduino (Use Arduino Board Manager)
  3. Depending on which Ethernet card you're using:
  4. Functional-VLPP library to use lambda function

Installation

Use Arduino Library Manager

Another way is to use Arduino Library Manager or arduino-library-badge. Search for EthernetWebServer, then select / install the latest version.

Manual Install

  1. Navigate to EthernetWebServer page.
  2. Download the latest release EthernetWebServer-master.zip.
  3. Extract the zip file to EthernetWebServer-master directory
  4. Copy whole
  • EthernetWebServer-master folder to Arduino libraries' directory such as ~/Arduino/libraries/.

Important notes

  1. If your application requires 2K+ HTML page, the current Ethernet library must be modified if you are using W5200/W5500 Ethernet shields. W5100 is not supported for 2K+ buffer.
  2. To fix Ethernet library, just copy these following files into the Ethernet library directory to overwrite the old files:
  1. How to select which built-in Ethernet or shield to use
  • Standard Ethernet library is used by default, just check in the sketch these line are commented out
//#define USE_UIP_ETHERNET        true
//#define USE_CUSTOM_ETHERNET     true
//#include <Ethernet2.h>
//#include <Ethernet3.h>
//#include <EthernetLarge.h>
  • To use built-in UIPEthernet built-in or shield:
#define USE_UIP_ETHERNET        true
//#define USE_CUSTOM_ETHERNET     true
//#include <Ethernet2.h>
//#include <Ethernet3.h>
//#include <EthernetLarge.h>
  • To use any of the custom Ethernet library, such as Ethernet2, Ethernet3, EthernetLarge:
//#define USE_UIP_ETHERNET        true
#define USE_CUSTOM_ETHERNET     true
#include <Ethernet2.h>
//#include <Ethernet3.h>
//#include <EthernetLarge.h>
  • To use another Ethernet library For example, Ethernet_XYZ library uses Ethernet_XYZ.h
//#define USE_UIP_ETHERNET        true
#define USE_CUSTOM_ETHERNET     true
//#include <Ethernet2.h>
//#include <Ethernet3.h>
//#include <EthernetLarge.h>
#include <Ethernet_XYZ.h>
...
//Must be placed before #include <EthernetWebServer.h>
#include <WiFi_XYZ.h>
#include <WiFiWebServer.h>

Important:

  • The Ethernet_Shield_W5200, EtherCard, EtherSia libraries are not supported. Don't use unless you know how to modify those libraries.
  • Requests to support for any future custom Ethernet library will be ignored. Use at your own risk.

Usage

Class Constructor

  EthernetWebServer server(80);

Creates the EthernetWebServer class object.

Parameters:

host port number: int port (default is the standard HTTP port 80)

Basic Operations

Starting the server

  void begin();

Handling incoming client requests

  void handleClient();

Disabling the server

  void close();
  void stop();

Both methods function the same

Client request handlers

  void on();
  void addHandler();
  void onNotFound();
  void onFileUpload();	

Example:*

  server.on("/", handlerFunction);
  server.onNotFound(handlerFunction);   // called when handler is not assigned
  server.onFileUpload(handlerFunction); // handle file uploads

Sending responses to the client

  void send();
  void send_P();

Parameters:

code - HTTP response code, can be 200 or 404, etc.

content_type - HTTP content type, like "text/plain" or "image/png", etc.

content - actual content body

Advanced Options

Getting information about request arguments

  const String & arg();
  const String & argName();
  int args();
  bool hasArg();

Function usage:

arg - get request argument value, use arg("plain") to get POST body

argName - get request argument name

args - get arguments count

hasArg - check if argument exist

Getting information about request headers

  const String & header();
  const String & headerName();
  const String & hostHeader();
  int headers();
  bool hasHeader();

Function usage:

header - get request header value

headerName - get request header name

hostHeader - get request host header if available, else empty string

headers - get header count

hasHeader - check if header exist

Authentication

  bool authenticate();
  void requestAuthentication();

Function usage:

authenticate - server authentication, returns true if client is authenticated else false

requestAuthentication - sends authentication failure response to the client

Example Usage:

  if(!server.authenticate(username, password)){
    server.requestAuthentication();
  }

Other Function Calls

  const String & uri(); // get the current uri
  HTTPMethod  method(); // get the current method 
  WiFiClient client(); // get the current client
  HTTPUpload & upload(); // get the current upload
  void setContentLength(); // set content length
  void sendHeader(); // send HTTP header
  void sendContent(); // send content
  void sendContent_P(); 
  void collectHeaders(); // set the request headers to collect
  void serveStatic();
  size_t streamFile();

Also see examples:

  1. HelloServer
  2. HelloServer2
  3. AdvancedWebServer
  4. HttpBasicAuth
  5. PostServer
  6. SimpleAuthentication

Example HelloServer

Please take a look at other examples as well.

#if    ( defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010) \
      || defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_SAMD_MKRFox1200) || defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) \
      || defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRNB1500) || defined(ARDUINO_SAMD_MKRVIDOR4000) || defined(__SAMD21G18A__) \
      || defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(__SAMD21E18A__) || defined(__SAMD51__) || defined(__SAMD51J20A__) || defined(__SAMD51J19A__) \
      || defined(__SAMD51G19A__) || defined(__SAMD21G18A__) )
#if defined(ETHERNET_USE_SAMD)
#undef ETHERNET_USE_SAMD
#endif
#define ETHERNET_USE_SAMD      true
#endif

#if ( defined(NRF52840_FEATHER) || defined(NRF52832_FEATHER) || defined(NRF52_SERIES) || defined(ARDUINO_NRF52_ADAFRUIT) || \
        defined(NRF52840_FEATHER_SENSE) || defined(NRF52840_ITSYBITSY) || defined(NRF52840_CIRCUITPLAY) || defined(NRF52840_CLUE) || \
        defined(NRF52840_METRO) || defined(NRF52840_PCA10056) || defined(PARTICLE_XENON) || defined(NINA_B302_ublox) )
#if defined(ETHERNET_USE_NRF528XX)
#undef ETHERNET_USE_NRF528XX
#endif
#define ETHERNET_USE_NRF528XX      true

//This is workaround for NINA_B302_ublox
// Change the pin
#define ENC28J60_CONTROL_CS         10
#define ENC28J60_USE_SPILIB         true
#warning Use nRF52 with SPI pins defined

#endif

#if ( defined(ARDUINO_SAM_DUE) || defined(__SAM3X8E__) )
#if defined(ETHERNET_USE_SAM_DUE)
#undef ETHERNET_USE_SAM_DUE
#endif
#define ETHERNET_USE_SAM_DUE      true
#endif

#if defined(ETHERNET_USE_SAMD)
// For SAMD

#if defined(ARDUINO_SAMD_ZERO)
#define BOARD_TYPE      "SAMD Zero"
#elif defined(ARDUINO_SAMD_MKR1000)
#define BOARD_TYPE      "SAMD MKR1000"
#elif defined(ARDUINO_SAMD_MKRWIFI1010)
#define BOARD_TYPE      "SAMD MKRWIFI1010"
#elif defined(ARDUINO_SAMD_NANO_33_IOT)
#define BOARD_TYPE      "SAMD NANO_33_IOT"
#elif defined(ARDUINO_SAMD_MKRFox1200)
#define BOARD_TYPE      "SAMD MKRFox1200"
#elif ( defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) )
#define BOARD_TYPE      "SAMD MKRWAN13X0"
#elif defined(ARDUINO_SAMD_MKRGSM1400)
#define BOARD_TYPE      "SAMD MKRGSM1400"
#elif defined(ARDUINO_SAMD_MKRNB1500)
#define BOARD_TYPE      "SAMD MKRNB1500"
#elif defined(ARDUINO_SAMD_MKRVIDOR4000)
#define BOARD_TYPE      "SAMD MKRVIDOR4000"
#elif defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS)
#define BOARD_TYPE      "SAMD ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS"
#elif defined(ADAFRUIT_ITSYBITSY_M4_EXPRESS)
#define BOARD_TYPE      "SAMD ADAFRUIT_ITSYBITSY_M4_EXPRESS"
#elif defined(__SAMD21E18A__)
#define BOARD_TYPE      "SAMD21E18A"
#elif defined(__SAMD21G18A__)
#define BOARD_TYPE      "SAMD21G18A"
#elif defined(__SAMD51G19A__)
#define BOARD_TYPE      "SAMD51G19A"
#elif defined(__SAMD51J19A__)
#define BOARD_TYPE      "SAMD51J19A"
#elif defined(__SAMD51J20A__)
#define BOARD_TYPE      "SAMD51J20A"
#elif defined(__SAMD51__)
#define BOARD_TYPE      "SAMD51"
#else
#define BOARD_TYPE      "SAMD Unknown"
#endif

#elif (ETHERNET_USE_SAM_DUE)
#define BOARD_TYPE      "SAM DUE"

#elif (ETHERNET_USE_NRF528XX)

#if defined(NRF52840_FEATHER)
#define BOARD_TYPE      "NRF52840_FEATHER"
#elif defined(NRF52832_FEATHER)
#define BOARD_TYPE      "NRF52832_FEATHER"
#elif defined(NRF52840_FEATHER_SENSE)
#define BOARD_TYPE      "NRF52840_FEATHER_SENSE"
#elif defined(NRF52840_ITSYBITSY)
#define BOARD_TYPE      "NRF52840_ITSYBITSY"
#elif defined(NRF52840_CIRCUITPLAY)
#define BOARD_TYPE      "NRF52840_CIRCUITPLAY"
#elif defined(NRF52840_CLUE)
#define BOARD_TYPE      "NRF52840_CLUE"
#elif defined(NRF52840_METRO)
#define BOARD_TYPE      "NRF52840_METRO"
#elif defined(NRF52840_PCA10056)
#define BOARD_TYPE      "NRF52840_PCA10056"
#elif defined(NINA_B302_ublox)
#define BOARD_TYPE      "NINA_B302_ublox"
#elif defined(PARTICLE_XENON)
#define BOARD_TYPE      "PARTICLE_XENON"
#elif defined(ARDUINO_NRF52_ADAFRUIT)
#define BOARD_TYPE      "ARDUINO_NRF52_ADAFRUIT"
#else
#define BOARD_TYPE      "nRF52 Unknown"
#endif

#elif ( defined(CORE_TEENSY) )
// For Teensy 4.0
#if defined(__IMXRT1062__)
#define BOARD_TYPE      "TEENSY 4.0"
#elif ( defined(__MKL26Z64__) || defined(ARDUINO_ARCH_AVR) )
#define BOARD_TYPE      "TEENSY LC or 2.0"
#else
#define BOARD_TYPE      "TEENSY 3.X"
#endif

#elif ( defined(ESP8266) )
// For ESP8266
#warning Use ESP8266 architecture
#define ETHERNET_USE_ESP8266
#define BOARD_TYPE      "ESP8266"

#elif ( defined(ESP32) )
// For ESP32
#warning Use ESP32 architecture
#define ETHERNET_USE_ESP32
#define BOARD_TYPE      "ESP32"

#define W5500_RST_PORT   21

#else
// For Mega
#define BOARD_TYPE      "AVR Mega"
#endif

#include <SPI.h>

// Use true  for ENC28J60 and UIPEthernet library (https://github.com/UIPEthernet/UIPEthernet)
// Use false for W5x00 and Ethernetx library      (https://www.arduino.cc/en/Reference/Ethernet)

#define USE_UIP_ETHERNET   false  //true

// Ethernet_Shield_W5200, EtherCard, EtherSia not supported
// Select just 1 of the following #include if uncomment #define USE_CUSTOM_ETHERNET
// Otherwise, standard Ethernet library will be used for W5x00
//#define USE_CUSTOM_ETHERNET     true
//#include <Ethernet2.h>
//#include <Ethernet3.h>
//#include <EthernetLarge.h>

#include <EthernetWebServer.h>

// Enter a MAC address and IP address for your controller below.

byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};

// Select the IP address according to your local network
IPAddress ip(192, 168, 2, 200);

EthernetWebServer server(80);

const int led = 13;

void handleRoot()
{
  String html = "Hello from EthernetWebServer running on " + String(BOARD_TYPE); 

  server.send(200, "text/plain", html);
}

void handleNotFound()
{
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i = 0; i < server.args(); i++)
  {
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
  digitalWrite(led, 0);
}

void setup(void)
{
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial);

  //delay(1000);
  Serial.println("\nStarting HelloServer on " + String(BOARD_TYPE));

  // Just info to know how to connect correctly
  Serial.println("=========================");
  Serial.println("Used/default SPI pinout:");
  Serial.print("MOSI:");
  Serial.println(MOSI);
  Serial.print("MISO:");
  Serial.println(MISO);
  Serial.print("SCK:");
  Serial.println(SCK);
  Serial.print("SS:");
  Serial.println(SS);
  Serial.println("=========================");

  // start the ethernet connection and the server:
  // Use Static IP
  Ethernet.begin(mac, ip);
  // Use DHCP dynamic IP
  //Ethernet.begin(mac);

  server.on("/", handleRoot);

  server.on("/inline", []() {
    server.send(200, "text/plain", "This works as well");
  });

  server.onNotFound(handleNotFound);

  server.begin();

  Serial.print(F("HTTP EthernetWebServer is @ IP : "));
  Serial.println(Ethernet.localIP());
}

void loop(void)
{
  server.handleClient();
}

The following are debug terminal output and screen shot when running example AdvancedWebServer on Teensy 4.0


Starting AdvancedServer on TEENSY 4.0
HTTP EthernetWebServer is @ IP : 192.168.2.100
[ETHERNET_WEBSERVER] send1: len =  289
[ETHERNET_WEBSERVER] content =  <html><head><meta http-equiv='refresh' content='5'/><title>ESP8266 Demo</title><style>body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }</style></head><body><h1>Hello from ESP8266!</h1><p>Uptime: 00:00:27</p><img src="/test.svg" /></body></html>
[ETHERNET_WEBSERVER] send1: len =  1946
[ETHERNET_WEBSERVER] content =  <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="310" height="150">
<rect width="310" height="150" fill="rgb(250, 230, 210)" stroke-width="1" stroke="rgb(0, 0, 0)" />
<g stroke="black">
<line x1="10" y1="77" x2="20" y2="67" stroke-width="1" />
<line x1="20" y1="67" x2="30" y2="98" stroke-width="1" />
<line x1="30" y1="98" x2="40" y2="111" stroke-width="1" />
<line x1="40" y1="111" x2="50" y2="90" stroke-width="1" />
<line x1="50" y1="90" x2="60" y2="22" stroke-width="1" />
<line x1="60" y1="22" x2="70" y2="98" stroke-width="1" />
<line x1="70" y1="98" x2="80" y2="64" stroke-width="1" />
<line x1="80" y1="64" x2="90" y2="104" stroke-width="1" />
<line x1="90" y1="104" x2="100" y2="31" stroke-width="1" />
<line x1="100" y1="31" x2="110" y2="59" stroke-width="1" />
<line x1="110" y1="59" x2="120" y2="139" stroke-width="1" />
<line x1="120" y1="139" x2="130" y2="117" stroke-width="1" />
<line x1="130" y1="117" x2="140" y2="75" stroke-width="1" />
<line x1="140" y1="75" x2="150" y2="72" stroke-width="1" />
<line x1="150" y1="72" x2="160" y2="137" stroke-width="1" />
<line x1="160" y1="137" x2="170" y2="20" stroke-width="1" />
<line x1="170" y1="20" x2="180" y2="94" stroke-width="1" />
<line x1="180" y1="94" x2="190" y2="81" stroke-width="1" />
<line x1="190" y1="81" x2="200" y2="38" stroke-width="1" />
<line x1="200" y1="38" x2="210" y2="33" stroke-width="1" />
<line x1="210" y1="33" x2="220" y2="53" stroke-width="1" />
<line x1="220" y1="53" x2="230" y2="88" stroke-width="1" />
<line x1="230" y1="88" x2="240" y2="32" stroke-width="1" />
<line x1="240" y1="32" x2="250" y2="110" stroke-width="1" />
<line x1="250" y1="110" x2="260" y2="87" stroke-width="1" />
<line x1="260" y1="87" x2="270" y2="11" stroke-width="1" />
<line x1="270" y1="11" x2="280" y2="98" stroke-width="1" />
<line x1="280" y1="98" x2="290" y2="76" stroke-width="1" />
<line x1="290" y1="76" x2="300" y2="121" stroke-width="1" />
</g>
</svg>

New in v1.0.6

  1. Add support to ESP32 and ESP8266 boards.

New in v1.0.5

  1. Add support to nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense, Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc.
  2. Support any future custom Ethernet library that meets the no-compiling-error requirements. Currently Ethernet2, EThernet3, EthernetLarge libraries are supported. Ethernet_Shield_W5200, EtherCard, EtherSia libraries are not supported.

New in v1.0.4

  1. Add support to SAM51 (Itsy-Bitsy M4, Metro M4, Grand Central M4, Feather M4 Express, etc.).

Version v1.0.3

  1. From v1.0.3+, the library supports many more Arduino boards ( SAM DUE, SAMD: ZERO, MKR, NANO_33_IOT, M0, M0 Pro, AdaFruit CIRCUITPLAYGROUND_EXPRESS, etc.)

Version v1.0.2

  1. From v1.0.2+, the library supports many more Arduino boards (Atmel AVR-s, Atmel SAM3X8E ARM Cortex-M3, STM32F series, ESP8266, Intel ARC32(Genuino101), Nordic nRF51(RFduino), Teensy boards, Realtek Ameba(RTL8195A,RTL8710))
  2. Support Wiznet W5x00 or ENC28J60 EThernet shields by using UIPEthernet library besides standard Ethernet, Ethernet2, Ethernet3 libraries.

Version v1.0.1

  1. Add support to Server's lambda function calls

Version v1.0.0

This is simple yet complete WebServer library for AVR, Teensy, etc. boards running Ethernet shields. The functions are similar and compatible to ESP8266/ESP32 WebServer libraries to make life much easier to port sketches from ESP8266/ESP32.

The library supports

  1. HTTP Server and Client
  2. HTTP GET and POST requests, provides argument parsing, handles one client at a time.

TO DO

  1. Bug Searching and Killing
  2. Add SSL/TLS Client and Server support
  3. Support more types of boards using Ethernet shields.
  4. Support more non-compatible Ethernet Libraries such as Ethernet_Shield_W5200, EtherCard, EtherSia

Contributions and thanks

  1. Forked from Ivan Grokhotkov's ESP8266WebServer
  2. jandrassy for UIPEthernet library
  3. Thanks to Miguel Alexandre Wisintainer for initiating, inspriring, working with, developing, debugging and testing. Without that, support to nRF52, especially U-Box B302 running as nRF52840, has never been started and finished.
  4. Thanks to Vladimir to initiate the work on ESP32 in Spiffs not work Issue #2

Contributing

If you want to contribute to this project:

  • Report bugs and errors
  • Ask for enhancements
  • Create issues and pull requests
  • Tell other people about this library

Copyright

Copyright 2020- Khoi Hoang

About

This is simple yet complete WebServer library for AVR, Portenta_H7, Teensy, SAM DUE, SAMD21/SAMD51, nRF52, STM32, RP2040-based, etc. boards running Ethernet shields. The functions are similar and compatible to ESP8266/ESP32 WebServer libraries to make life much easier to port sketches from ESP8266/ESP32.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C++ 76.0%
  • C 23.9%
  • Shell 0.1%