1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-22 21:23:07 +03:00

Merge pull request #1 from esp8266/esp8266

pull changes from master
This commit is contained in:
ficeto 2015-05-01 12:28:56 +03:00
commit 517b234e2a
5 changed files with 299 additions and 278 deletions

View File

@ -154,7 +154,15 @@ extern void __detachInterrupt(uint8_t pin) {
}
void initPins() {
ETS_GPIO_INTR_ATTACH(interrupt_handlers, &interrupt_reg);
for (int i = 0; i <= 5; ++i) {
pinMode(i, INPUT);
}
// pins 6-11 are used for the SPI flash interface
for (int i = 12; i <= 16; ++i) {
pinMode(i, INPUT);
}
ETS_GPIO_INTR_ATTACH(interrupt_handler, &interrupt_reg);
ETS_GPIO_INTR_ENABLE();
}

View File

@ -9,24 +9,23 @@ MDNSResponder mdns;
ESP8266WebServer server(80);
void handle_root() {
void handleRoot() {
server.send(200, "text/plain", "hello from esp8266!");
}
bool handle_not_found(){
void handleNotFound(){
String message = "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET)?"GET":"POST";
message += "\nNot Found!\n\n";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i=0; i<server.args(); i++){
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
message += "\nNotFound!";
server.send(404, "text/plain", message);
return true;
}
void setup(void){
@ -45,15 +44,17 @@ void setup(void){
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (mdns.begin("esp8266", WiFi.localIP())) Serial.println("MDNS responder started");
if (mdns.begin("esp8266", WiFi.localIP())) {
Serial.println("MDNS responder started");
}
server.on("/", handle_root);
server.on("/", handleRoot);
server.on("/inline", [](){
server.send(200, "text/plain", "this works as well");
});
server.onNotFound(handle_not_found);
server.onNotFound(handleNotFound);
server.begin();
Serial.println("HTTP server started");

View File

@ -21,6 +21,10 @@ method KEYWORD2
client KEYWORD2
send KEYWORD2
arg KEYWORD2
argName KEYWORD2
args KEYWORD2
hasArg KEYWORD2
onNotFound KEYWORD2
#######################################
# Constants (LITERAL1)

View File

@ -28,18 +28,18 @@
// #define DEBUG
struct ESP8266WebServer::RequestHandler {
RequestHandler(ESP8266WebServer::THandlerFunction fn, const char* uri, HTTPMethod method)
: fn(fn)
, uri(uri)
, method(method)
, next(NULL)
{
}
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::THandlerFunction fn;
String uri;
HTTPMethod method;
RequestHandler* next;
};
@ -54,302 +54,309 @@ ESP8266WebServer::ESP8266WebServer(int port)
ESP8266WebServer::~ESP8266WebServer()
{
if (!_firstHandler)
return;
RequestHandler* handler = _firstHandler;
while (handler) {
RequestHandler* next = handler->next;
delete handler;
handler = next;
}
if (!_firstHandler)
return;
RequestHandler* handler = _firstHandler;
while (handler) {
RequestHandler* next = handler->next;
delete handler;
handler = next;
}
}
void ESP8266WebServer::begin() {
_server.begin();
_server.begin();
}
void ESP8266WebServer::on(const char* uri, ESP8266WebServer::THandlerFunction handler)
{
on(uri, HTTP_ANY, 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;
}
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;
}
WiFiClient client = _server.available();
if (!client) {
return;
}
#ifdef DEBUG
Serial.println("New client");
Serial.println("New client");
#endif
// Wait for data from client to become available
while(client.connected() && !client.available()){
delay(1);
}
// 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');
// 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;
}
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) {
// 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);
Serial.print("Invalid request: ");
Serial.println(req);
#endif
return;
}
return;
}
req = req.substring(addr_start + 1, addr_end);
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');
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();
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);
Serial.print("Content-Length: ");
Serial.println(contentLength);
#endif
}
}
}
else {
break;
}
}
}
}
}
else {
break;
}
}
#ifdef DEBUG
Serial.print("headerCount=");
Serial.println(headerCount);
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);
}
}
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
}
}
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();
client.flush();
#ifdef DEBUG
Serial.print("Request: ");
Serial.println(req);
Serial.print("Args: ");
Serial.println(formData);
Serial.print("Request: ");
Serial.println(req);
Serial.print("Args: ");
Serial.println(formData);
#endif
_parseArguments(formData);
_handleRequest(client, req, method);
_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 response = "HTTP/1.1 ";
response += String(code);
response += " ";
response += _responseCodeToString(code);
response += "\r\n";
if (!content_type)
content_type = "text/html";
_appendHeader(response, "Content-Type", content_type);
response += "\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();
String ESP8266WebServer::arg(const char* name) {
for (int i = 0; i < _currentArgCount; ++i) {
if (_currentArgs[i].key == name)
return _currentArgs[i].value;
}
return String();
}
String ESP8266WebServer::arg(int i)
{
if (i < _currentArgCount)
return _currentArgs[i].value;
return String();
String ESP8266WebServer::arg(int i) {
if (i < _currentArgCount)
return _currentArgs[i].value;
return String();
}
String ESP8266WebServer::argName(int i)
{
if (i < _currentArgCount)
return _currentArgs[i].key;
return String();
String ESP8266WebServer::argName(int i) {
if (i < _currentArgCount)
return _currentArgs[i].key;
return String();
}
int ESP8266WebServer::args(){
int ESP8266WebServer::args() {
return _currentArgCount;
}
bool ESP8266WebServer::hasArg(const char* name)
{
for (int i = 0; i < _currentArgCount; ++i) {
if (_currentArgs[i].key == name)
return true;
}
return false;
bool ESP8266WebServer::hasArg(const char* name) {
for (int i = 0; i < _currentArgCount; ++i) {
if (_currentArgs[i].key == name)
return true;
}
return false;
}
void ESP8266WebServer::_parseArguments(String data)
{
if (_currentArgs)
delete[] _currentArgs;
_currentArgs = 0;
if (data.length() == 0) {
_currentArgCount = 0;
return;
}
_currentArgCount = 1;
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;
}
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);
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);
_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);
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))) {
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);
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);
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);
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;
++iarg;
if (next_arg_index == -1)
break;
pos = next_arg_index + 1;
}
_currentArgCount = iarg;
#ifdef DEBUG
Serial.print("args count: ");
Serial.println(_currentArgCount);
Serial.print("args count: ");
Serial.println(_currentArgCount);
#endif
}
void ESP8266WebServer::onNotFound(TNotFoundHandlerFunction fn){
void ESP8266WebServer::onNotFound(THandlerFunction fn) {
_notFoundHandler = fn;
}
void ESP8266WebServer::_handleRequest(WiFiClient& client, String uri, HTTPMethod method) {
_currentClient = client;
_currentUri = uri;
_currentMethod = 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;
RequestHandler* handler;
for (handler = _firstHandler; handler; handler = handler->next)
{
if (handler->method != HTTP_ANY && handler->method != method)
continue;
if (handler->uri != uri)
continue;
if (handler->uri != uri)
continue;
handler->fn();
break;
}
handler->fn();
break;
}
if (!handler){
if (!handler){
#ifdef DEBUG
Serial.println("request handler not found");
Serial.println("request handler not found");
#endif
if(!_notFoundHandler || !_notFoundHandler())
send(404, "text/plain", String("Not found: ") + uri);
}
_currentClient = WiFiClient();
_currentUri = String();
if(_notFoundHandler) {
_notFoundHandler();
}
else {
send(404, "text/plain", String("Not found: ") + uri);
}
}
_currentClient = WiFiClient();
_currentUri = String();
}
const char* ESP8266WebServer::_responseCodeToString(int code) {
switch (code) {
case 200: return "OK";
case 404: return "Not found";
default: return "";
}
}
void ESP8266WebServer::_appendHeader(String& response, const char* name, const char* value) {
response += name;
response += ": ";
response += value;
response += "\r\n";
}

View File

@ -32,56 +32,57 @@ class ESP8266WebServer
{
public:
ESP8266WebServer(int port = 80);
~ESP8266WebServer();
ESP8266WebServer(int port = 80);
~ESP8266WebServer();
void begin();
void handleClient();
void begin();
void handleClient();
typedef std::function<void(void)> THandlerFunction;
typedef std::function<bool(void)> TNotFoundHandlerFunction;
void on(const char* uri, THandlerFunction handler);
void on(const char* uri, HTTPMethod method, THandlerFunction fn);
void onNotFound(TNotFoundHandlerFunction fn);//called when handler is not assigned
typedef std::function<void(void)> THandlerFunction;
void on(const char* uri, THandlerFunction handler);
void on(const char* uri, HTTPMethod method, THandlerFunction fn);
void onNotFound(THandlerFunction fn); //called when handler is not assigned
String uri() { return _currentUri; }
HTTPMethod method() { return _currentMethod; }
WiFiClient client() { return _currentClient; }
String uri() { return _currentUri; }
HTTPMethod method() { return _currentMethod; }
WiFiClient client() { return _currentClient; }
String arg(const char* name);// get request argument value
String arg(int i);// get request argument value buy number
String argName(int i);// get request argument name buy number
int args();//get arguments count
bool hasArg(const char* name);//check if argument exists
String arg(const char* name); // get request argument value by name
String arg(int i); // get request argument value by number
String argName(int i); // get request argument name by number
int args(); // get arguments count
bool hasArg(const char* name); // check if argument exists
// 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(""));
// 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(""));
protected:
void _handleRequest(WiFiClient& client, String uri, HTTPMethod method);
void _parseArguments(String data);
void _handleRequest(WiFiClient& client, String uri, HTTPMethod method);
void _parseArguments(String data);
static const char* _responseCodeToString(int code);
static void _appendHeader(String& response, const char* name, const char* value);
struct RequestHandler;
struct RequestArgument {
String key;
String value;
};
struct RequestHandler;
struct RequestArgument {
String key;
String value;
};
WiFiServer _server;
WiFiServer _server;
WiFiClient _currentClient;
HTTPMethod _currentMethod;
String _currentUri;
WiFiClient _currentClient;
HTTPMethod _currentMethod;
String _currentUri;
size_t _currentArgCount;
RequestArgument* _currentArgs;
size_t _currentArgCount;
RequestArgument* _currentArgs;
RequestHandler* _firstHandler;
RequestHandler* _lastHandler;
TNotFoundHandlerFunction _notFoundHandler;
RequestHandler* _firstHandler;
RequestHandler* _lastHandler;
THandlerFunction _notFoundHandler;
};