mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-19 23:22:16 +03:00
Add ESP8266WebServer library
This commit is contained in:
parent
c3b428162f
commit
cfda6cbd06
@ -52,4 +52,10 @@ void __cxa_deleted_virtual(void) {
|
||||
abort();
|
||||
}
|
||||
|
||||
namespace std {
|
||||
void __throw_bad_function_call() {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,54 @@
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <WiFiClient.h>
|
||||
#include <ESP8266WebServer.h>
|
||||
|
||||
const char* ssid = "...............";
|
||||
const char* password = "...............";
|
||||
|
||||
|
||||
ESP8266WebServer server(80);
|
||||
|
||||
const int led = 13;
|
||||
|
||||
void handle_root() {
|
||||
digitalWrite(led, 1);
|
||||
server.send(200, "text/plain", form);
|
||||
delay(100);
|
||||
digitalWrite(led, 0);
|
||||
}
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
Serial.begin(115200);
|
||||
pinMode(led, OUTPUT);
|
||||
digitalWrite(led, 0);
|
||||
|
||||
// Connect to WiFi network
|
||||
WiFi.begin(ssid, password);
|
||||
Serial.println("");
|
||||
|
||||
// Wait for connection
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("");
|
||||
Serial.print("Connected to ");
|
||||
Serial.println(ssid);
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
|
||||
server.on("/", handle_root);
|
||||
|
||||
server.on("/inline", [](){
|
||||
server.send(200, "text/plain", "this works as well");
|
||||
});
|
||||
|
||||
server.begin();
|
||||
Serial.println("HTTP server started");
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
server.handleClient();
|
||||
}
|
31
libraries/ESP8266WebServer/keywords.txt
Normal file
31
libraries/ESP8266WebServer/keywords.txt
Normal file
@ -0,0 +1,31 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map For Ultrasound
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
ESP8266WebServer KEYWORD1
|
||||
HTTPMethod KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
begin KEYWORD2
|
||||
handleClient KEYWORD2
|
||||
on KEYWORD2
|
||||
uri KEYWORD2
|
||||
method KEYWORD2
|
||||
client KEYWORD2
|
||||
send KEYWORD2
|
||||
arg KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
||||
HTTP_GET LITERAL1
|
||||
HTTP_POST LITERAL1
|
||||
HTTP_ANY LITERAL1
|
326
libraries/ESP8266WebServer/src/ESP8266WebServer.cpp
Normal file
326
libraries/ESP8266WebServer/src/ESP8266WebServer.cpp
Normal file
@ -0,0 +1,326 @@
|
||||
/*
|
||||
ESP8266WebServer.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.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "WiFiServer.h"
|
||||
#include "WiFiClient.h"
|
||||
#include "ESP8266WebServer.h"
|
||||
|
||||
// #define DEBUG
|
||||
|
||||
struct ESP8266WebServer::RequestHandler {
|
||||
RequestHandler(ESP8266WebServer::THandlerFunction fn, const char* uri, HTTPMethod method)
|
||||
: fn(fn)
|
||||
, uri(uri)
|
||||
, method(method)
|
||||
, next(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
ESP8266WebServer::THandlerFunction fn;
|
||||
String uri;
|
||||
HTTPMethod method;
|
||||
RequestHandler* next;
|
||||
|
||||
};
|
||||
|
||||
ESP8266WebServer::ESP8266WebServer(int port)
|
||||
: _server(port)
|
||||
, _firstHandler(0)
|
||||
, _lastHandler(0)
|
||||
, _currentArgCount(0)
|
||||
, _currentArgs(0)
|
||||
{
|
||||
}
|
||||
|
||||
ESP8266WebServer::~ESP8266WebServer()
|
||||
{
|
||||
if (!_firstHandler)
|
||||
return;
|
||||
RequestHandler* handler = _firstHandler;
|
||||
while (handler) {
|
||||
RequestHandler* next = handler->next;
|
||||
delete handler;
|
||||
handler = next;
|
||||
}
|
||||
}
|
||||
|
||||
void ESP8266WebServer::begin() {
|
||||
_server.begin();
|
||||
}
|
||||
|
||||
|
||||
void ESP8266WebServer::on(const char* uri, ESP8266WebServer::THandlerFunction handler)
|
||||
{
|
||||
on(uri, HTTP_ANY, handler);
|
||||
}
|
||||
|
||||
void ESP8266WebServer::on(const char* uri, HTTPMethod method, ESP8266WebServer::THandlerFunction fn)
|
||||
{
|
||||
RequestHandler* handler = new RequestHandler(fn, uri, method);
|
||||
if (!_lastHandler) {
|
||||
_firstHandler = handler;
|
||||
_lastHandler = handler;
|
||||
}
|
||||
else {
|
||||
_lastHandler->next = handler;
|
||||
_lastHandler = handler;
|
||||
}
|
||||
}
|
||||
|
||||
void ESP8266WebServer::handleClient()
|
||||
{
|
||||
WiFiClient client = _server.available();
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
Serial.println("New client");
|
||||
#endif
|
||||
// Wait for data from client to become available
|
||||
while(client.connected() && !client.available()){
|
||||
delay(1);
|
||||
}
|
||||
|
||||
// Read the first line of HTTP request
|
||||
String req = client.readStringUntil('\r');
|
||||
client.readStringUntil('\n');
|
||||
|
||||
HTTPMethod method = HTTP_GET;
|
||||
if (req.startsWith("POST")) {
|
||||
method = HTTP_POST;
|
||||
}
|
||||
|
||||
|
||||
// First line of HTTP request looks like "GET /path HTTP/1.1"
|
||||
// Retrieve the "/path" part by finding the spaces
|
||||
int addr_start = req.indexOf(' ');
|
||||
int addr_end = req.indexOf(' ', addr_start + 1);
|
||||
if (addr_start == -1 || addr_end == -1) {
|
||||
#ifdef DEBUG
|
||||
Serial.print("Invalid request: ");
|
||||
Serial.println(req);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
req = req.substring(addr_start + 1, addr_end);
|
||||
|
||||
String formData;
|
||||
if (method == HTTP_POST)
|
||||
{
|
||||
int contentLength = -1;
|
||||
int headerCount = 0;
|
||||
while(headerCount < 1024) { // there shouldn't be that much really
|
||||
String line = client.readStringUntil('\r');
|
||||
client.readStringUntil('\n');
|
||||
|
||||
if (line.length() > 0) { // this is a header
|
||||
++headerCount;
|
||||
if (contentLength < 0 && line.startsWith("Content-Length")) {
|
||||
// get content length from the header
|
||||
int valuePos = line.indexOf(' ', 14);
|
||||
if (valuePos > 0) {
|
||||
String valueStr = line.substring(valuePos+1);
|
||||
contentLength = valueStr.toInt();
|
||||
#ifdef DEBUG
|
||||
Serial.print("Content-Length: ");
|
||||
Serial.println(contentLength);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
Serial.print("headerCount=");
|
||||
Serial.println(headerCount);
|
||||
#endif
|
||||
if (contentLength >= 0) {
|
||||
formData = "";
|
||||
int n = 0; // timeout counter
|
||||
while (formData.length() < contentLength && ++n < 3)
|
||||
formData += client.readString();
|
||||
}
|
||||
else {
|
||||
formData = client.readStringUntil('\r'); // will return after timing out once
|
||||
}
|
||||
// read form data
|
||||
// formData =
|
||||
}
|
||||
else if (method == HTTP_GET)
|
||||
{
|
||||
int args_start = req.indexOf('?');
|
||||
if (args_start != -1)
|
||||
{
|
||||
formData = req.substring(args_start + 1);
|
||||
req = req.substring(0, args_start);
|
||||
}
|
||||
}
|
||||
|
||||
client.flush();
|
||||
|
||||
#ifdef DEBUG
|
||||
Serial.print("Request: ");
|
||||
Serial.println(req);
|
||||
Serial.print("Args: ");
|
||||
Serial.println(formData);
|
||||
#endif
|
||||
|
||||
_parseArguments(formData);
|
||||
_handleRequest(client, req, method);
|
||||
|
||||
}
|
||||
|
||||
void ESP8266WebServer::send(int code, const char* content_type, String content) {
|
||||
String response = "HTTP/1.1 ";
|
||||
response += String(code);
|
||||
response += " ";
|
||||
if (code == 200)
|
||||
response += "OK";
|
||||
else if (code == 404)
|
||||
response += "Not found";
|
||||
response += "\r\n";
|
||||
if (!content_type)
|
||||
content_type = "text/html";
|
||||
response += "Content-Type: ";
|
||||
response += content_type;
|
||||
response += "\r\n\r\n";
|
||||
response += content;
|
||||
_currentClient.print(response);
|
||||
}
|
||||
|
||||
String ESP8266WebServer::arg(const char* name)
|
||||
{
|
||||
for (int i = 0; i < _currentArgCount; ++i) {
|
||||
if (_currentArgs[i].key == name)
|
||||
return _currentArgs[i].value;
|
||||
}
|
||||
return String();
|
||||
}
|
||||
|
||||
|
||||
void ESP8266WebServer::_parseArguments(String data)
|
||||
{
|
||||
if (_currentArgs)
|
||||
delete[] _currentArgs;
|
||||
_currentArgs = 0;
|
||||
if (data.length() == 0) {
|
||||
_currentArgCount = 0;
|
||||
return;
|
||||
}
|
||||
_currentArgCount = 1;
|
||||
|
||||
for (int i = 0; i < data.length(); ) {
|
||||
i = data.indexOf('&', i);
|
||||
if (i == -1)
|
||||
break;
|
||||
++i;
|
||||
++_currentArgCount;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
Serial.print("args count: ");
|
||||
Serial.println(_currentArgCount);
|
||||
#endif
|
||||
|
||||
_currentArgs = new RequestArgument[_currentArgCount];
|
||||
int pos = 0;
|
||||
int iarg;
|
||||
for (iarg = 0; iarg < _currentArgCount;) {
|
||||
int equal_sign_index = data.indexOf('=', pos);
|
||||
int next_arg_index = data.indexOf('&', pos);
|
||||
#ifdef DEBUG
|
||||
Serial.print("pos ");
|
||||
Serial.print(pos);
|
||||
Serial.print("=@ ");
|
||||
Serial.print(equal_sign_index);
|
||||
Serial.print(" &@ ");
|
||||
Serial.println(next_arg_index);
|
||||
#endif
|
||||
if (equal_sign_index == -1 || equal_sign_index > next_arg_index && next_arg_index != -1) {
|
||||
#ifdef DEBUG
|
||||
Serial.print("arg missing value: ");
|
||||
Serial.println(iarg);
|
||||
#endif
|
||||
if (next_arg_index == -1)
|
||||
break;
|
||||
pos = next_arg_index + 1;
|
||||
continue;
|
||||
}
|
||||
RequestArgument& arg = _currentArgs[iarg];
|
||||
arg.key = data.substring(pos, equal_sign_index);
|
||||
arg.value = data.substring(equal_sign_index + 1, next_arg_index);
|
||||
#ifdef DEBUG
|
||||
Serial.print("arg ");
|
||||
Serial.print(iarg);
|
||||
Serial.print(" key: ");
|
||||
Serial.print(arg.key);
|
||||
Serial.print(" value: ");
|
||||
Serial.println(arg.value);
|
||||
#endif
|
||||
++iarg;
|
||||
if (next_arg_index == -1)
|
||||
break;
|
||||
pos = next_arg_index + 1;
|
||||
}
|
||||
_currentArgCount = iarg;
|
||||
#ifdef DEBUG
|
||||
Serial.print("args count: ");
|
||||
Serial.println(_currentArgCount);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ESP8266WebServer::_handleRequest(WiFiClient& client, String uri, HTTPMethod method) {
|
||||
_currentClient = client;
|
||||
_currentUri = uri;
|
||||
_currentMethod = method;
|
||||
|
||||
RequestHandler* handler;
|
||||
for (handler = _firstHandler; handler; handler = handler->next)
|
||||
{
|
||||
if (handler->method != HTTP_ANY && handler->method != method)
|
||||
continue;
|
||||
|
||||
if (handler->uri != uri)
|
||||
continue;
|
||||
|
||||
handler->fn();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!handler)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Serial.println("request handler not found");
|
||||
#endif
|
||||
send(404, "text/plain", String("Not found: ") + uri);
|
||||
}
|
||||
|
||||
_currentClient = WiFiClient();
|
||||
_currentUri = String();
|
||||
|
||||
}
|
83
libraries/ESP8266WebServer/src/ESP8266WebServer.h
Normal file
83
libraries/ESP8266WebServer/src/ESP8266WebServer.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
ESP8266WebServer.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.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ESP8266WEBSERVER_H
|
||||
#define ESP8266WEBSERVER_H
|
||||
|
||||
#include <functional>
|
||||
|
||||
enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_POST };
|
||||
|
||||
|
||||
class ESP8266WebServer
|
||||
{
|
||||
public:
|
||||
|
||||
ESP8266WebServer(int port = 80);
|
||||
~ESP8266WebServer();
|
||||
|
||||
void begin();
|
||||
void handleClient();
|
||||
|
||||
typedef std::function<void(void)> THandlerFunction;
|
||||
void on(const char* uri, THandlerFunction handler);
|
||||
void on(const char* uri, HTTPMethod method, THandlerFunction fn);
|
||||
|
||||
String uri() { return _currentUri; }
|
||||
HTTPMethod method() { return _currentMethod; }
|
||||
WiFiClient client() { return _currentClient; }
|
||||
|
||||
// send response to the client
|
||||
// code - HTTP response code, can be 200 or 404
|
||||
// content_type - HTTP content type, like "text/plain" or "image/png"
|
||||
// content - actual content body
|
||||
void send(int code, const char* content_type = NULL, String content = String(""));
|
||||
|
||||
// get request argument value
|
||||
String arg(const char* name);
|
||||
|
||||
protected:
|
||||
void _handleRequest(WiFiClient& client, String uri, HTTPMethod method);
|
||||
void _parseArguments(String data);
|
||||
|
||||
struct RequestHandler;
|
||||
struct RequestArgument {
|
||||
String key;
|
||||
String value;
|
||||
};
|
||||
|
||||
WiFiServer _server;
|
||||
|
||||
WiFiClient _currentClient;
|
||||
HTTPMethod _currentMethod;
|
||||
String _currentUri;
|
||||
|
||||
size_t _currentArgCount;
|
||||
RequestArgument* _currentArgs;
|
||||
|
||||
RequestHandler* _firstHandler;
|
||||
RequestHandler* _lastHandler;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //ESP8266WEBSERVER_H
|
Loading…
x
Reference in New Issue
Block a user