wifi webserver works again

This commit is contained in:
technyon
2022-04-29 20:48:33 +02:00
parent 0dd94a97a3
commit 0e9baed3a4
50 changed files with 440 additions and 466 deletions

View File

@@ -1,29 +0,0 @@
#include "EthernetServerImpl.h"
EthernetServerImpl::EthernetServerImpl(IPAddress addr, int port)
: EthernetServer(port)
{}
EthernetServerImpl::EthernetServerImpl(int port)
: EthernetServer(port)
{}
void EthernetServerImpl::begin(uint16_t port)
{
EthernetServer::begin();
}
void EthernetServerImpl::begin()
{
EthernetServer::begin();
}
void EthernetServerImpl::close()
{
}
int EthernetServerImpl::setNoDelay(bool nodelay)
{
return 0;
}

View File

@@ -1,15 +0,0 @@
#pragma once
#include <EthernetServer.h>
class EthernetServerImpl : public EthernetServer
{
public:
EthernetServerImpl(IPAddress addr, int port);
EthernetServerImpl(int port);
void begin();
void begin(uint16_t port);
void close();
int setNoDelay(bool nodelay);
};

View File

@@ -30,7 +30,7 @@
#include <WiFi.h>
#include <WiFiClient.h>
#include <EthernetWebServer.h>
#include <WebServer.h>
#include <ESPmDNS.h>
const char *ssid = "YourSSIDHere";

View File

@@ -1,7 +1,7 @@
/*
FSWebServer - Example EthernetWebServer with FS backend for esp8266/esp32
FSWebServer - Example WebServer with FS backend for esp8266/esp32
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
This file is part of the EthernetWebServer library for Arduino environment.
This file is part of the WebServer library for Arduino environment.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -24,7 +24,7 @@
*/
#include <WiFi.h>
#include <WiFiClient.h>
#include <EthernetWebServer.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#define FILESYSTEM SPIFFS

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,7 +1,7 @@
<!--
FSWebServer - Example Index Page
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
This file is part of the EthernetWebServer library for Arduino environment.
This file is part of the WebServer library for Arduino environment.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public

View File

@@ -1,6 +1,6 @@
#include <WiFi.h>
#include <WiFiClient.h>
#include <EthernetWebServer.h>
#include <WebServer.h>
#include <ESPmDNS.h>
const char* ssid = "........";

View File

@@ -7,7 +7,7 @@
#include <WiFi.h>
#include <ESPmDNS.h>
#include <ArduinoOTA.h>
#include <EthernetWebServer.h>
#include <WebServer.h>
const char* ssid = "........";
const char* password = "........";

View File

@@ -1,7 +1,7 @@
#include <WiFi.h>
#include <ESPmDNS.h>
#include <ArduinoOTA.h>
#include <EthernetWebServer.h>
#include <WebServer.h>
const char* ssid = "........";
const char* password = "........";

View File

@@ -1,6 +1,6 @@
#include <WiFi.h>
#include <WiFiClient.h>
#include <EthernetWebServer.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <uri/UriBraces.h>

View File

@@ -1,8 +1,8 @@
/*
SDWebServer - Example EthernetWebServer with SD Card backend for esp8266
SDWebServer - Example WebServer with SD Card backend for esp8266
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
This file is part of the EthernetWebServer library for Arduino environment.
This file is part of the WebServer library for Arduino environment.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -29,7 +29,7 @@
*/
#include <WiFi.h>
#include <WiFiClient.h>
#include <EthernetWebServer.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <SPI.h>
#include <SD.h>

View File

Before

Width:  |  Height:  |  Size: 174 KiB

After

Width:  |  Height:  |  Size: 174 KiB

View File

@@ -1,6 +1,6 @@
#include <WiFi.h>
#include <WiFiClient.h>
#include <EthernetWebServer.h>
#include <WebServer.h>
const char* ssid = "........";
const char* password = "........";

View File

@@ -4,7 +4,7 @@
#include <WiFi.h>
#include <WiFiClient.h>
#include <EthernetWebServer.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <Update.h>

View File

@@ -0,0 +1,22 @@
#pragma once
#include <stdint.h>
#include <cstddef>
class EthClient
{
public:
virtual uint8_t connected() = 0;
virtual int available() = 0;
virtual unsigned long getTimeout(void) = 0;
virtual int setTimeout(uint32_t seconds) = 0;
virtual int read() = 0;
virtual size_t write(const char *buffer, size_t size) = 0;
virtual size_t write_P(PGM_P buf, size_t size) = 0;
virtual size_t write(Stream &stream) = 0;
virtual String readStringUntil(char terminator) = 0;
virtual size_t readBytes(char *buffer, size_t length) = 0;
virtual IPAddress localIP() = 0;
virtual void stop() = 0;
virtual void flush() = 0;
};

View File

@@ -0,0 +1,20 @@
#pragma once
#include <IPAddress.h>
#include <WiFiClient.h>
#include "EthClient.h"
class EthServer
{
public:
EthServer(IPAddress address, int port) { }
EthServer(int port) { }
virtual EthClient* available() = 0;
virtual void discardClient() = 0;
virtual void close() = 0;
virtual void begin(const int port = 80) = 0;
virtual void setNoDelay(const bool value) = 0;
};

View File

@@ -22,8 +22,8 @@
#include <Arduino.h>
#include <esp32-hal-log.h>
#include "WiFiServer.h"
#include "EthernetClient.h"
#include "EthernetWebServer.h"
#include "WiFiClient.h"
#include "WebServer.h"
#include "detail/mimetable.h"
#ifndef WEBSERVER_MAX_POST_ARGS
@@ -32,7 +32,7 @@
#define __STR(a) #a
#define _STR(a) __STR(a)
const char * _eth_http_method_str[] = {
const char * _http_method_str[] = {
#define XX(num, name, string) _STR(name),
HTTP_METHOD_MAP(XX)
#undef XX
@@ -41,14 +41,14 @@ const char * _eth_http_method_str[] = {
static const char Content_Type[] PROGMEM = "Content-Type";
static const char filename[] PROGMEM = "filename";
static char* readBytesWithTimeout(EthernetClient& client, size_t maxLength, size_t& dataLength, int timeout_ms)
static char* readBytesWithTimeout(EthClient* client, size_t maxLength, size_t& dataLength, int timeout_ms)
{
char *buf = nullptr;
dataLength = 0;
while (dataLength < maxLength) {
int tries = timeout_ms;
size_t newLength;
while (!(newLength = client.available()) && tries--) delay(1);
while (!(newLength = client->available()) && tries--) delay(1);
if (!newLength) {
break;
}
@@ -66,17 +66,17 @@ static char* readBytesWithTimeout(EthernetClient& client, size_t maxLength, size
}
buf = newBuf;
}
client.readBytes(buf + dataLength, newLength);
client->readBytes(buf + dataLength, newLength);
dataLength += newLength;
buf[dataLength] = '\0';
}
return buf;
}
bool EthernetWebServer::_parseRequest(EthernetClient& client) {
bool WebServer::_parseRequest(EthClient* client) {
// Read the first line of HTTP request
String req = client.readStringUntil('\r');
client.readStringUntil('\n');
String req = client->readStringUntil('\r');
client->readStringUntil('\n');
//reset header value
for (int i = 0; i < _headerKeysCount; ++i) {
_currentHeaders[i].value =String();
@@ -105,9 +105,9 @@ bool EthernetWebServer::_parseRequest(EthernetClient& client) {
_chunked = false;
HTTPMethod method = HTTP_ANY;
size_t num_methods = sizeof(_eth_http_method_str) / sizeof(const char *);
size_t num_methods = sizeof(_http_method_str) / sizeof(const char *);
for (size_t i=0; i<num_methods; i++) {
if (methodStr == _eth_http_method_str[i]) {
if (methodStr == _http_method_str[i]) {
method = (HTTPMethod)i;
break;
}
@@ -139,8 +139,8 @@ bool EthernetWebServer::_parseRequest(EthernetClient& client) {
uint32_t contentLength = 0;
//parse headers
while(1){
req = client.readStringUntil('\r');
client.readStringUntil('\n');
req = client->readStringUntil('\r');
client->readStringUntil('\n');
if (req == "") break;//no moar headers
int headerDiv = req.indexOf(':');
if (headerDiv == -1){
@@ -213,8 +213,8 @@ bool EthernetWebServer::_parseRequest(EthernetClient& client) {
String headerValue;
//parse headers
while(1){
req = client.readStringUntil('\r');
client.readStringUntil('\n');
req = client->readStringUntil('\r');
client->readStringUntil('\n');
if (req == "") break;//no moar headers
int headerDiv = req.indexOf(':');
if (headerDiv == -1){
@@ -233,7 +233,7 @@ bool EthernetWebServer::_parseRequest(EthernetClient& client) {
}
_parseArguments(searchStr);
}
client.flush();
client->flush();
log_v("Request: %s", url.c_str());
log_v(" Arguments: %s", searchStr.c_str());
@@ -241,7 +241,7 @@ bool EthernetWebServer::_parseRequest(EthernetClient& client) {
return true;
}
bool EthernetWebServer::_collectHeader(const char* headerName, const char* headerValue) {
bool WebServer::_collectHeader(const char* headerName, const char* headerValue) {
for (int i = 0; i < _headerKeysCount; i++) {
if (_currentHeaders[i].key.equalsIgnoreCase(headerName)) {
_currentHeaders[i].value=headerValue;
@@ -251,7 +251,7 @@ bool EthernetWebServer::_collectHeader(const char* headerName, const char* heade
return false;
}
void EthernetWebServer::_parseArguments(String data) {
void WebServer::_parseArguments(String data) {
log_v("args: %s", data.c_str());
if (_currentArgs)
delete[] _currentArgs;
@@ -300,7 +300,7 @@ void EthernetWebServer::_parseArguments(String data) {
}
void EthernetWebServer::_uploadWriteByte(uint8_t b){
void WebServer::_uploadWriteByte(uint8_t b){
if (_currentUpload->currentSize == HTTP_UPLOAD_BUFLEN){
if(_currentHandler && _currentHandler->canUpload(_currentUri))
_currentHandler->upload(*this, _currentUri, *_currentUpload);
@@ -310,30 +310,30 @@ void EthernetWebServer::_uploadWriteByte(uint8_t b){
_currentUpload->buf[_currentUpload->currentSize++] = b;
}
int EthernetWebServer::_uploadReadByte(EthernetClient& client){
int res = client.read();
int WebServer::_uploadReadByte(EthClient* client){
int res = client->read();
if(res < 0) {
// keep trying until you either read a valid byte or timeout
unsigned long startMillis = millis();
long timeoutIntervalMillis = client.getTimeout();
long timeoutIntervalMillis = client->getTimeout();
boolean timedOut = false;
for(;;) {
if (!client.connected()) return -1;
if (!client->connected()) return -1;
// loosely modeled after blinkWithoutDelay pattern
while(!timedOut && !client.available() && client.connected()){
while(!timedOut && !client->available() && client->connected()){
delay(2);
timedOut = millis() - startMillis >= timeoutIntervalMillis;
}
res = client.read();
res = client->read();
if(res >= 0) {
return res; // exit on a valid read
}
// NOTE: it is possible to get here and have all of the following
// assertions hold true
//
// -- client.available() > 0
// -- client.connected == true
// -- client->available() > 0
// -- client->connected == true
// -- res == -1
//
// a simple retry strategy overcomes this which is to say the
@@ -351,17 +351,17 @@ int EthernetWebServer::_uploadReadByte(EthernetClient& client){
return res;
}
bool EthernetWebServer::_parseForm(EthernetClient& client, String boundary, uint32_t len){
bool WebServer::_parseForm(EthClient* client, String boundary, uint32_t len){
(void) len;
log_v("Parse Form: Boundary: %s Length: %d", boundary.c_str(), len);
String line;
int retry = 0;
do {
line = client.readStringUntil('\r');
line = client->readStringUntil('\r');
++retry;
} while (line.length() == 0 && retry < 3);
client.readStringUntil('\n');
client->readStringUntil('\n');
//start reading the form
if (line == ("--"+boundary)){
if(_postArgs) delete[] _postArgs;
@@ -374,8 +374,8 @@ bool EthernetWebServer::_parseForm(EthernetClient& client, String boundary, uint
String argFilename;
bool argIsFile = false;
line = client.readStringUntil('\r');
client.readStringUntil('\n');
line = client->readStringUntil('\r');
client->readStringUntil('\n');
if (line.length() > 19 && line.substring(0, 19).equalsIgnoreCase(F("Content-Disposition"))){
int nameStart = line.indexOf('=');
if (nameStart != -1){
@@ -395,19 +395,19 @@ bool EthernetWebServer::_parseForm(EthernetClient& client, String boundary, uint
log_v("PostArg Name: %s", argName.c_str());
using namespace mime;
argType = FPSTR(mimeTable[txt].mimeType);
line = client.readStringUntil('\r');
client.readStringUntil('\n');
line = client->readStringUntil('\r');
client->readStringUntil('\n');
if (line.length() > 12 && line.substring(0, 12).equalsIgnoreCase(FPSTR(Content_Type))){
argType = line.substring(line.indexOf(':')+2);
//skip next line
client.readStringUntil('\r');
client.readStringUntil('\n');
client->readStringUntil('\r');
client->readStringUntil('\n');
}
log_v("PostArg Type: %s", argType.c_str());
if (!argIsFile){
while(1){
line = client.readStringUntil('\r');
client.readStringUntil('\n');
line = client->readStringUntil('\r');
client->readStringUntil('\n');
if (line.startsWith("--"+boundary)) break;
if (argValue.length() > 0) argValue += "\n";
argValue += line;
@@ -495,8 +495,8 @@ readfile:
if(_currentHandler && _currentHandler->canUpload(_currentUri))
_currentHandler->upload(*this, _currentUri, *_currentUpload);
log_v("End File: %s Type: %s Size: %d", _currentUpload->filename.c_str(), _currentUpload->type.c_str(), _currentUpload->totalSize);
line = client.readStringUntil(0x0D);
client.readStringUntil(0x0A);
line = client->readStringUntil(0x0D);
client->readStringUntil(0x0A);
if (line == "--"){
log_v("Done Parsing POST");
break;
@@ -550,7 +550,7 @@ readfile:
return false;
}
String EthernetWebServer::urlDecode(const String& text)
String WebServer::urlDecode(const String& text)
{
String decoded = "";
char temp[] = "0x00";
@@ -581,7 +581,7 @@ String EthernetWebServer::urlDecode(const String& text)
return decoded;
}
bool EthernetWebServer::_parseFormUploadAborted(){
bool WebServer::_parseFormUploadAborted(){
_currentUpload->status = UPLOAD_FILE_ABORTED;
if(_currentHandler && _currentHandler->canUpload(_currentUri))
_currentHandler->upload(*this, _currentUri, *_currentUpload);

View File

@@ -1,5 +1,5 @@
/*
EthernetWebServer.cpp - Dead simple web-server.
Webserver->cpp - Dead simple web-server->
Supports only one simultaneous client, knows how to handle GET and POST.
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
@@ -24,9 +24,8 @@
#include <Arduino.h>
#include <esp32-hal-log.h>
#include <libb64/cencode.h>
#include "WiFiServer.h"
#include "EthernetClient.h"
#include "EthernetWebServer.h"
#include "WiFiClient.h"
#include "WebServer.h"
#include "FS.h"
#include "detail/RequestHandlersImpl.h"
#include "mbedtls/md5.h"
@@ -39,9 +38,10 @@ static const char WWW_Authenticate[] = "WWW-Authenticate";
static const char Content_Length[] = "Content-Length";
EthernetWebServer::EthernetWebServer(IPAddress addr, int port)
//WebServer::WebServer(IPAddress addr, int port)
WebServer::WebServer(EthServer* server)
: _corsEnabled(false)
, _server(addr, port)
, _server(server)
, _currentMethod(HTTP_ANY)
, _currentVersion(0)
, _currentStatus(HC_NONE)
@@ -61,30 +61,8 @@ EthernetWebServer::EthernetWebServer(IPAddress addr, int port)
{
}
EthernetWebServer::EthernetWebServer(int port)
: _corsEnabled(false)
, _server(port)
, _currentMethod(HTTP_ANY)
, _currentVersion(0)
, _currentStatus(HC_NONE)
, _statusChange(0)
, _nullDelay(true)
, _currentHandler(nullptr)
, _firstHandler(nullptr)
, _lastHandler(nullptr)
, _currentArgCount(0)
, _currentArgs(nullptr)
, _postArgsLen(0)
, _postArgs(nullptr)
, _headerKeysCount(0)
, _currentHeaders(nullptr)
, _contentLength(0)
, _chunked(false)
{
}
EthernetWebServer::~EthernetWebServer() {
_server.close();
WebServer::~WebServer() {
_server->close();
if (_currentHeaders)
delete[]_currentHeaders;
RequestHandler* handler = _firstHandler;
@@ -95,19 +73,19 @@ EthernetWebServer::~EthernetWebServer() {
}
}
void EthernetWebServer::begin() {
void WebServer::begin() {
close();
_server.begin();
_server.setNoDelay(true);
_server->begin();
_server->setNoDelay(true);
}
void EthernetWebServer::begin(uint16_t port) {
void WebServer::begin(uint16_t port) {
close();
_server.begin(port);
_server.setNoDelay(true);
_server->begin(port);
_server->setNoDelay(true);
}
String EthernetWebServer::_extractParam(String& authReq, const String& param, const char delimit){
String WebServer::_extractParam(String& authReq,const String& param,const char delimit){
int _begin = authReq.indexOf(param);
if (_begin == -1)
return "";
@@ -134,7 +112,7 @@ static String md5str(String &in){
return String(out);
}
bool EthernetWebServer::authenticate(const char * username, const char * password){
bool WebServer::authenticate(const char * username, const char * password){
if(hasHeader(FPSTR(AUTHORIZATION_HEADER))) {
String authReq = header(FPSTR(AUTHORIZATION_HEADER));
if(authReq.startsWith(F("Basic"))){
@@ -222,7 +200,7 @@ bool EthernetWebServer::authenticate(const char * username, const char * passwor
return false;
}
String EthernetWebServer::_getRandomHexString() {
String WebServer::_getRandomHexString() {
char buffer[33]; // buffer to hold 32 Hex Digit + /0
int i;
for(i = 0; i < 4; i++) {
@@ -231,7 +209,7 @@ String EthernetWebServer::_getRandomHexString() {
return String(buffer);
}
void EthernetWebServer::requestAuthentication(HTTPAuthMethod mode, const char* realm, const String& authFailMsg) {
void WebServer::requestAuthentication(HTTPAuthMethod mode, const char* realm, const String& authFailMsg) {
if(realm == NULL) {
_srealm = String(F("Login Required"));
} else {
@@ -248,23 +226,23 @@ void EthernetWebServer::requestAuthentication(HTTPAuthMethod mode, const char* r
send(401, String(FPSTR(mimeTable[html].mimeType)), authFailMsg);
}
void EthernetWebServer::on(const Uri &uri, EthernetWebServer::THandlerFunction handler) {
void WebServer::on(const Uri &uri, WebServer::THandlerFunction handler) {
on(uri, HTTP_ANY, handler);
}
void EthernetWebServer::on(const Uri &uri, HTTPMethod method, EthernetWebServer::THandlerFunction fn) {
void WebServer::on(const Uri &uri, HTTPMethod method, WebServer::THandlerFunction fn) {
on(uri, method, fn, _fileUploadHandler);
}
void EthernetWebServer::on(const Uri &uri, HTTPMethod method, EthernetWebServer::THandlerFunction fn, EthernetWebServer::THandlerFunction ufn) {
void WebServer::on(const Uri &uri, HTTPMethod method, WebServer::THandlerFunction fn, WebServer::THandlerFunction ufn) {
_addRequestHandler(new FunctionRequestHandler(fn, ufn, uri, method));
}
void EthernetWebServer::addHandler(RequestHandler* handler) {
void WebServer::addHandler(RequestHandler* handler) {
_addRequestHandler(handler);
}
void EthernetWebServer::_addRequestHandler(RequestHandler* handler) {
void WebServer::_addRequestHandler(RequestHandler* handler) {
if (!_lastHandler) {
_firstHandler = handler;
_lastHandler = handler;
@@ -275,20 +253,19 @@ void EthernetWebServer::_addRequestHandler(RequestHandler* handler) {
}
}
void EthernetWebServer::serveStatic(const char* uri, FS& fs, const char* path, const char* cache_header) {
void WebServer::serveStatic(const char* uri, FS& fs, const char* path, const char* cache_header) {
_addRequestHandler(new StaticRequestHandler(fs, path, uri, cache_header));
}
void EthernetWebServer::handleClient() {
void WebServer::handleClient() {
if (_currentStatus == HC_NONE) {
EthernetClient client = _server.available();
if (!client) {
EthClient* client = _server->available();
if (!client->connected()) {
if (_nullDelay) {
delay(1);
}
return;
}
log_v("New client");
_currentClient = client;
@@ -299,29 +276,23 @@ void EthernetWebServer::handleClient() {
bool keepCurrentClient = false;
bool callYield = false;
if (_currentClient.connected()) {
if (_currentClient->connected()) {
switch (_currentStatus) {
case HC_NONE:
// No-op to avoid C++ compiler warning
break;
case HC_WAIT_READ:
// Wait for data from client to become available
if (_currentClient.available()) {
if (_currentClient->available()) {
if (_parseRequest(_currentClient)) {
// because HTTP_MAX_SEND_WAIT is expressed in milliseconds,
// it must be divided by 1000
_currentClient.setTimeout(HTTP_MAX_SEND_WAIT / 1000);
// it must be divided by 1000
_currentClient->setTimeout(HTTP_MAX_SEND_WAIT / 1000);
_contentLength = CONTENT_LENGTH_NOT_SET;
_handleRequest();
// Fix for issue with Chrome based browsers: https://github.com/espressif/arduino-esp32/issues/3652
// if (_currentClient.connected()) {
// _currentStatus = HC_WAIT_CLOSE;
// _statusChange = millis();
// keepCurrentClient = true;
// }
}
} else { // !_currentClient.available()
} else { // !_currentClient->available()
if (millis() - _statusChange <= HTTP_MAX_DATA_WAIT) {
keepCurrentClient = true;
}
@@ -337,8 +308,10 @@ void EthernetWebServer::handleClient() {
}
}
// TODO
if (!keepCurrentClient) {
_currentClient = EthernetClient();
_server->discardClient();
_currentClient = _server->available();
_currentStatus = HC_NONE;
_currentUpload.reset();
}
@@ -348,18 +321,18 @@ void EthernetWebServer::handleClient() {
}
}
void EthernetWebServer::close() {
_server.close();
void WebServer::close() {
_server->close();
_currentStatus = HC_NONE;
if(!_headerKeysCount)
collectHeaders(0, 0);
}
void EthernetWebServer::stop() {
void WebServer::stop() {
close();
}
void EthernetWebServer::sendHeader(const String& name, const String& value, bool first) {
void WebServer::sendHeader(const String& name, const String& value, bool first) {
String headerLine = name;
headerLine += F(": ");
headerLine += value;
@@ -373,23 +346,23 @@ void EthernetWebServer::sendHeader(const String& name, const String& value, bool
}
}
void EthernetWebServer::setContentLength(const size_t contentLength) {
void WebServer::setContentLength(const size_t contentLength) {
_contentLength = contentLength;
}
void EthernetWebServer::enableDelay(boolean value) {
void WebServer::enableDelay(boolean value) {
_nullDelay = value;
}
void EthernetWebServer::enableCORS(boolean value) {
void WebServer::enableCORS(boolean value) {
_corsEnabled = value;
}
void EthernetWebServer::enableCrossOrigin(boolean value) {
void WebServer::enableCrossOrigin(boolean value) {
enableCORS(value);
}
void EthernetWebServer::_prepareHeader(String& response, int code, const char* content_type, size_t contentLength) {
void WebServer::_prepareHeader(String& response, int code, const char* content_type, size_t contentLength) {
response = String(F("HTTP/1.")) + String(_currentVersion) + ' ';
response += String(code);
response += ' ';
@@ -423,7 +396,7 @@ void EthernetWebServer::_prepareHeader(String& response, int code, const char* c
_responseHeaders = "";
}
void EthernetWebServer::send(int code, const char* content_type, const String& content) {
void WebServer::send(int code, const char* content_type, const String& content) {
String header;
// Can we asume the following?
//if(code == 200 && content.length() == 0 && _contentLength == CONTENT_LENGTH_NOT_SET)
@@ -434,7 +407,7 @@ void EthernetWebServer::send(int code, const char* content_type, const String& c
sendContent(content);
}
void EthernetWebServer::send_P(int code, PGM_P content_type, PGM_P content) {
void WebServer::send_P(int code, PGM_P content_type, PGM_P content) {
size_t contentLength = 0;
if (content != NULL) {
@@ -449,7 +422,7 @@ void EthernetWebServer::send_P(int code, PGM_P content_type, PGM_P content) {
sendContent_P(content);
}
void EthernetWebServer::send_P(int code, PGM_P content_type, PGM_P content, size_t contentLength) {
void WebServer::send_P(int code, PGM_P content_type, PGM_P content, size_t contentLength) {
String header;
char type[64];
memccpy_P((void*)type, (PGM_VOID_P)content_type, 0, sizeof(type));
@@ -458,19 +431,19 @@ void EthernetWebServer::send_P(int code, PGM_P content_type, PGM_P content, size
sendContent_P(content, contentLength);
}
void EthernetWebServer::send(int code, char* content_type, const String& content) {
void WebServer::send(int code, char* content_type, const String& content) {
send(code, (const char*)content_type, content);
}
void EthernetWebServer::send(int code, const String& content_type, const String& content) {
void WebServer::send(int code, const String& content_type, const String& content) {
send(code, (const char*)content_type.c_str(), content);
}
void EthernetWebServer::sendContent(const String& content) {
void WebServer::sendContent(const String& content) {
sendContent(content.c_str(), content.length());
}
void EthernetWebServer::sendContent(const char* content, size_t contentLength) {
void WebServer::sendContent(const char* content, size_t contentLength) {
const char * footer = "\r\n";
if(_chunked) {
char * chunkSize = (char *)malloc(11);
@@ -482,18 +455,18 @@ void EthernetWebServer::sendContent(const char* content, size_t contentLength) {
}
_currentClientWrite(content, contentLength);
if(_chunked){
_currentClient.write(footer, 2);
_currentClient->write(footer, 2);
if (contentLength == 0) {
_chunked = false;
}
}
}
void EthernetWebServer::sendContent_P(PGM_P content) {
void WebServer::sendContent_P(PGM_P content) {
sendContent_P(content, strlen_P(content));
}
void EthernetWebServer::sendContent_P(PGM_P content, size_t size) {
void WebServer::sendContent_P(PGM_P content, size_t size) {
const char * footer = "\r\n";
if(_chunked) {
char * chunkSize = (char *)malloc(11);
@@ -505,7 +478,7 @@ void EthernetWebServer::sendContent_P(PGM_P content, size_t size) {
}
_currentClientWrite_P(content, size);
if(_chunked){
_currentClient.write(footer, 2);
_currentClient->write(footer, 2);
if (size == 0) {
_chunked = false;
}
@@ -513,7 +486,7 @@ void EthernetWebServer::sendContent_P(PGM_P content, size_t size) {
}
void EthernetWebServer::_streamFileCore(const size_t fileSize, const String & fileName, const String & contentType)
void WebServer::_streamFileCore(const size_t fileSize, const String & fileName, const String & contentType)
{
using namespace mime;
setContentLength(fileSize);
@@ -525,13 +498,13 @@ void EthernetWebServer::_streamFileCore(const size_t fileSize, const String & fi
send(200, contentType, "");
}
String EthernetWebServer::pathArg(unsigned int i) {
String WebServer::pathArg(unsigned int i) {
if (_currentHandler != nullptr)
return _currentHandler->pathArg(i);
return "";
}
String EthernetWebServer::arg(String name) {
String WebServer::arg(String name) {
for (int j = 0; j < _postArgsLen; ++j) {
if ( _postArgs[j].key == name )
return _postArgs[j].value;
@@ -543,23 +516,23 @@ String EthernetWebServer::arg(String name) {
return "";
}
String EthernetWebServer::arg(int i) {
String WebServer::arg(int i) {
if (i < _currentArgCount)
return _currentArgs[i].value;
return "";
}
String EthernetWebServer::argName(int i) {
String WebServer::argName(int i) {
if (i < _currentArgCount)
return _currentArgs[i].key;
return "";
}
int EthernetWebServer::args() {
int WebServer::args() {
return _currentArgCount;
}
bool EthernetWebServer::hasArg(String name) {
bool WebServer::hasArg(String name) {
for (int j = 0; j < _postArgsLen; ++j) {
if (_postArgs[j].key == name)
return true;
@@ -572,7 +545,7 @@ bool EthernetWebServer::hasArg(String name) {
}
String EthernetWebServer::header(String name) {
String WebServer::header(String name) {
for (int i = 0; i < _headerKeysCount; ++i) {
if (_currentHeaders[i].key.equalsIgnoreCase(name))
return _currentHeaders[i].value;
@@ -580,7 +553,7 @@ String EthernetWebServer::header(String name) {
return "";
}
void EthernetWebServer::collectHeaders(const char* headerKeys[], const size_t headerKeysCount) {
void WebServer::collectHeaders(const char* headerKeys[], const size_t headerKeysCount) {
_headerKeysCount = headerKeysCount + 1;
if (_currentHeaders)
delete[]_currentHeaders;
@@ -591,23 +564,23 @@ void EthernetWebServer::collectHeaders(const char* headerKeys[], const size_t he
}
}
String EthernetWebServer::header(int i) {
String WebServer::header(int i) {
if (i < _headerKeysCount)
return _currentHeaders[i].value;
return "";
}
String EthernetWebServer::headerName(int i) {
String WebServer::headerName(int i) {
if (i < _headerKeysCount)
return _currentHeaders[i].key;
return "";
}
int EthernetWebServer::headers() {
int WebServer::headers() {
return _headerKeysCount;
}
bool EthernetWebServer::hasHeader(String name) {
bool WebServer::hasHeader(String name) {
for (int i = 0; i < _headerKeysCount; ++i) {
if ((_currentHeaders[i].key.equalsIgnoreCase(name)) && (_currentHeaders[i].value.length() > 0))
return true;
@@ -615,19 +588,19 @@ bool EthernetWebServer::hasHeader(String name) {
return false;
}
String EthernetWebServer::hostHeader() {
String WebServer::hostHeader() {
return _hostHeader;
}
void EthernetWebServer::onFileUpload(THandlerFunction fn) {
void WebServer::onFileUpload(THandlerFunction fn) {
_fileUploadHandler = fn;
}
void EthernetWebServer::onNotFound(THandlerFunction fn) {
void WebServer::onNotFound(THandlerFunction fn) {
_notFoundHandler = fn;
}
void EthernetWebServer::_handleRequest() {
void WebServer::_handleRequest() {
bool handled = false;
if (!_currentHandler){
log_e("request handler not found");
@@ -654,13 +627,13 @@ void EthernetWebServer::_handleRequest() {
}
void EthernetWebServer::_finalizeResponse() {
void WebServer::_finalizeResponse() {
if (_chunked) {
sendContent("");
}
}
String EthernetWebServer::_responseCodeToString(int code) {
String WebServer::_responseCodeToString(int code) {
switch (code) {
case 100: return F("Continue");
case 101: return F("Switching Protocols");
@@ -705,8 +678,3 @@ String EthernetWebServer::_responseCodeToString(int code) {
default: return F("");
}
}
size_t EthernetWebServer::write_P(const char *buf, size_t size)
{
return _currentClient.write(buf, size);
}

View File

@@ -1,5 +1,5 @@
/*
EthernetWebServer.h - Dead simple web-server.
WebServer.h - Dead simple web-server.
Supports only one simultaneous client, knows how to handle GET and POST.
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
@@ -27,7 +27,6 @@
#include <functional>
#include <memory>
#include <WiFi.h>
#include <EthernetServer.h>
#include "HTTP_Method.h"
#include "Uri.h"
@@ -50,7 +49,7 @@ enum HTTPAuthMethod { BASIC_AUTH, DIGEST_AUTH };
#define CONTENT_LENGTH_UNKNOWN ((size_t) -1)
#define CONTENT_LENGTH_NOT_SET ((size_t) -2)
class EthernetWebServer;
class WebServer;
typedef struct {
HTTPUploadStatus status;
@@ -63,18 +62,18 @@ typedef struct {
} HTTPUpload;
#include "detail/RequestHandler.h"
#include "EthernetServerImpl.h"
#include "EthServer.h"
#include "EthClient.h"
namespace fs {
class FS;
}
class EthernetWebServer
class WebServer
{
public:
EthernetWebServer(IPAddress addr, int port = 80);
EthernetWebServer(int port = 80);
virtual ~EthernetWebServer();
WebServer(EthServer* server);
virtual ~WebServer();
virtual void begin();
virtual void begin(uint16_t port);
@@ -97,7 +96,7 @@ public:
String uri() { return _currentUri; }
HTTPMethod method() { return _currentMethod; }
virtual EthernetClient client() { return _currentClient; }
virtual EthClient* client() { return _currentClient; }
HTTPUpload& upload() { return *_currentUpload; }
String pathArg(unsigned int i); // get request path argument by number
@@ -141,23 +140,22 @@ public:
template<typename T>
size_t streamFile(T &file, const String& contentType) {
_streamFileCore(file.size(), file.name(), contentType);
return _currentClient.write(file);
return _currentClient->write(file);
}
protected:
size_t write_P(PGM_P buf, size_t size);
virtual size_t _currentClientWrite(const char* b, size_t l) { return _currentClient.write( b, l ); }
virtual size_t _currentClientWrite_P(PGM_P b, size_t l) { return write_P( b, l ); }
virtual size_t _currentClientWrite(const char* b, size_t l) { return _currentClient->write( b, l ); }
virtual size_t _currentClientWrite_P(PGM_P b, size_t l) { return _currentClient->write_P( b, l ); }
void _addRequestHandler(RequestHandler* handler);
void _handleRequest();
void _finalizeResponse();
bool _parseRequest(EthernetClient& client);
bool _parseRequest(EthClient* client);
void _parseArguments(String data);
static String _responseCodeToString(int code);
bool _parseForm(EthernetClient& client, String boundary, uint32_t len);
bool _parseForm(EthClient* client, String boundary, uint32_t len);
bool _parseFormUploadAborted();
void _uploadWriteByte(uint8_t b);
int _uploadReadByte(EthernetClient& client);
int _uploadReadByte(EthClient* client);
void _prepareHeader(String& response, int code, const char* content_type, size_t contentLength);
bool _collectHeader(const char* headerName, const char* headerValue);
@@ -173,9 +171,9 @@ protected:
};
boolean _corsEnabled;
EthernetServerImpl _server;
EthServer* _server;
EthernetClient _currentClient;
EthClient* _currentClient = nullptr;
HTTPMethod _currentMethod;
String _currentUri;
uint8_t _currentVersion;

View File

@@ -0,0 +1,77 @@
#include "WifiEthClient.h"
WifiEthClient::WifiEthClient(WiFiClient *wifiClient)
: _wifiClient(wifiClient)
{
}
WifiEthClient::~WifiEthClient()
{
_wifiClient = nullptr;
}
uint8_t WifiEthClient::connected()
{
return _wifiClient->connected();
}
int WifiEthClient::setTimeout(uint32_t seconds)
{
return _wifiClient->setTimeout(seconds);
}
size_t WifiEthClient::write(const char *buffer, size_t size)
{
return _wifiClient->write(buffer, size);
}
IPAddress WifiEthClient::localIP()
{
return _wifiClient->localIP();
}
void WifiEthClient::stop()
{
_wifiClient->stop();
}
size_t WifiEthClient::write_P(const char *buf, size_t size)
{
return _wifiClient->write_P(buf, size);
}
int WifiEthClient::available()
{
return _wifiClient->available();
}
String WifiEthClient::readStringUntil(char terminator)
{
return _wifiClient->readStringUntil(terminator);
}
size_t WifiEthClient::readBytes(char *buffer, size_t length)
{
return _wifiClient->readBytes(buffer, length);
}
void WifiEthClient::flush()
{
_wifiClient->flush();
}
int WifiEthClient::read()
{
return _wifiClient->read();
}
unsigned long WifiEthClient::getTimeout(void)
{
return _wifiClient->getTimeout();
}
size_t WifiEthClient::write(Stream &stream)
{
return _wifiClient->write(stream);
}

View File

@@ -0,0 +1,28 @@
#pragma once
#include <WiFiClient.h>
#include "EthClient.h"
class WifiEthClient : public EthClient
{
public:
explicit WifiEthClient(WiFiClient* wifiClient);
virtual ~WifiEthClient();
uint8_t connected() override;
int available() override;
unsigned long getTimeout(void) override;
int setTimeout(uint32_t seconds) override;
int read() override;
size_t write(const char *buffer, size_t size) override;
size_t write(Stream &stream) override;
size_t write_P(const char *buf, size_t size) override;
String readStringUntil(char terminator) override;
size_t readBytes(char *buffer, size_t length) override;
IPAddress localIP() override;
void stop() override;
void flush() override;
private:
WiFiClient* _wifiClient;
};

View File

@@ -0,0 +1,56 @@
#include "WifiEthServer.h"
WifiEthServer::WifiEthServer(IPAddress address, int port)
: EthServer(address, port),
_wifiServer(address, port)
{
}
WifiEthServer::WifiEthServer(int port)
: EthServer(port),
_wifiServer(port)
{
}
void WifiEthServer::close()
{
_wifiServer.close();
}
void WifiEthServer::begin(const int port)
{
_wifiServer.begin(port);
}
void WifiEthServer::setNoDelay(const bool value)
{
_wifiServer.setNoDelay(value);
}
EthClient* WifiEthServer::available()
{
if(_wifiEthClient != nullptr)
{
delete _wifiEthClient;
_wifiEthClient = nullptr;
}
_wifiClient = _wifiServer.available();
_wifiEthClient = new WifiEthClient(&_wifiClient);
return _wifiEthClient;
}
void WifiEthServer::discardClient()
{
if(_wifiEthClient != nullptr)
{
delete _wifiEthClient;
_wifiEthClient = nullptr;
}
_wifiClient = WiFiClient();
}

View File

@@ -0,0 +1,25 @@
#pragma once
#include "EthServer.h"
#include "WifiEthClient.h"
#include <WiFiServer.h>
class WifiEthServer : public EthServer
{
public:
WifiEthServer(IPAddress address, int port);
explicit WifiEthServer(int port);
virtual EthClient* available();
virtual void discardClient();
virtual void begin(const int port = 80);
virtual void close();
virtual void setNoDelay(const bool value);
private:
WiFiServer _wifiServer;
WiFiClient _wifiClient;
WifiEthClient* _wifiEthClient = nullptr;
};

View File

@@ -9,8 +9,8 @@ public:
virtual ~RequestHandler() { }
virtual bool canHandle(HTTPMethod method, String uri) { (void) method; (void) uri; return false; }
virtual bool canUpload(String uri) { (void) uri; return false; }
virtual bool handle(EthernetWebServer& server, HTTPMethod requestMethod, String requestUri) { (void) server; (void) requestMethod; (void) requestUri; return false; }
virtual void upload(EthernetWebServer& server, String requestUri, HTTPUpload& upload) { (void) server; (void) requestUri; (void) upload; }
virtual bool handle(WebServer& server, HTTPMethod requestMethod, String requestUri) { (void) server; (void) requestMethod; (void) requestUri; return false; }
virtual void upload(WebServer& server, String requestUri, HTTPUpload& upload) { (void) server; (void) requestUri; (void) upload; }
RequestHandler* next() { return _next; }
void next(RequestHandler* r) { _next = r; }

View File

@@ -10,7 +10,7 @@ using namespace mime;
class FunctionRequestHandler : public RequestHandler {
public:
FunctionRequestHandler(EthernetWebServer::THandlerFunction fn, EthernetWebServer::THandlerFunction ufn, const Uri &uri, HTTPMethod method)
FunctionRequestHandler(WebServer::THandlerFunction fn, WebServer::THandlerFunction ufn, const Uri &uri, HTTPMethod method)
: _fn(fn)
, _ufn(ufn)
, _uri(uri.clone())
@@ -37,7 +37,7 @@ public:
return true;
}
bool handle(EthernetWebServer& server, HTTPMethod requestMethod, String requestUri) override {
bool handle(WebServer& server, HTTPMethod requestMethod, String requestUri) override {
(void) server;
if (!canHandle(requestMethod, requestUri))
return false;
@@ -46,7 +46,7 @@ public:
return true;
}
void upload(EthernetWebServer& server, String requestUri, HTTPUpload& upload) override {
void upload(WebServer& server, String requestUri, HTTPUpload& upload) override {
(void) server;
(void) upload;
if (canUpload(requestUri))
@@ -54,8 +54,8 @@ public:
}
protected:
EthernetWebServer::THandlerFunction _fn;
EthernetWebServer::THandlerFunction _ufn;
WebServer::THandlerFunction _fn;
WebServer::THandlerFunction _ufn;
Uri *_uri;
HTTPMethod _method;
};
@@ -83,7 +83,7 @@ public:
return true;
}
bool handle(EthernetWebServer& server, HTTPMethod requestMethod, String requestUri) override {
bool handle(WebServer& server, HTTPMethod requestMethod, String requestUri) override {
if (!canHandle(requestMethod, requestUri))
return false;

View File

@@ -11,6 +11,7 @@
*/
#include "WiFiManager.h"
#include "WifiEthServer.h"
#if defined(ESP8266) || defined(ESP32)
@@ -586,7 +587,7 @@ void WiFiManager::setupHTTPServer(){
#endif
}
server.reset(new WM_WebServer(_httpPort));
server.reset(new WM_WebServer(new WifiEthServer(80)));
// This is not the safest way to reset the webserver, it can cause crashes on callbacks initilized before this and since its a shared pointer...
if ( _webservercallback != NULL) {
@@ -2290,7 +2291,7 @@ boolean WiFiManager::captivePortal() {
if(!_enableCaptivePortal) return false; // skip redirections, @todo maybe allow redirection even when no cp ? might be useful
String serverLoc = toStringIp(server->client().localIP());
String serverLoc = toStringIp(server->client()->localIP());
if(_httpPort != 80) serverLoc += ":" + (String)_httpPort; // add port if not default
bool doredirect = serverLoc != server->hostHeader(); // redirect if hostheader not server ip, prevent redirect loops
// doredirect = !isIp(server->hostHeader()) // old check
@@ -2301,7 +2302,7 @@ boolean WiFiManager::captivePortal() {
#endif
server->sendHeader(F("Location"), (String)F("http://") + serverLoc, true); // @HTTPHEAD send redirect
server->send ( 302, FPSTR(HTTP_HEAD_CT2), ""); // Empty content inhibits Content-length header so we have to close the socket ourselves.
server->client().stop(); // Stop is needed because we sent no content length
server->client()->stop(); // Stop is needed because we sent no content length
return true;
}
return false;

View File

@@ -20,7 +20,7 @@ void callback(char* topic, byte* payload, unsigned int length) {
// handle message arrived
}
EthernetClient ethClient;
server-> ethClient;
PubSubClient client(server, 1883, callback, ethClient);
void setup()