diff --git a/README.md b/README.md
index aeb46b3e6..fbd66bedf 100644
--- a/README.md
+++ b/README.md
@@ -23,12 +23,12 @@ If you find this ESP8266 board manager useful, please consider supporting it wit
##### Stable version 
Boards manager link: `http://arduino.esp8266.com/stable/package_esp8266com_index.json`
-Documentation: [Reference](http://arduino.esp8266.com/stable/doc/reference.html)
+Documentation: [http://esp8266.github.io/Arduino/versions/2.0.0/](http://esp8266.github.io/Arduino/versions/2.0.0/)
##### Staging version 
Boards manager link: `http://arduino.esp8266.com/staging/package_esp8266com_index.json`
-Documentation: [Reference](http://arduino.esp8266.com/staging/doc/reference.html)
+Documentation: [http://esp8266.github.io/Arduino/versions/2.0.0-rc2/](http://esp8266.github.io/Arduino/versions/2.0.0-rc2/)
### Using git version [](https://travis-ci.org/esp8266/Arduino)
@@ -51,9 +51,11 @@ python get.py
Documentation for latest development version:
- [Reference](doc/reference.md)
+- [Libraries](doc/libraries.md)
+- [File system](doc/filesystem.md)
+- [OTA update](doc/ota_updates/ota_updates.md)
- [Supported boards](doc/boards.md)
- [Change log](doc/changes.md)
-- [OTA Update](doc/ota_updates/ota_updates.md)
### Issues and support ###
diff --git a/cores/esp8266/core_esp8266_features.h b/cores/esp8266/core_esp8266_features.h
new file mode 100644
index 000000000..bafcd3aee
--- /dev/null
+++ b/cores/esp8266/core_esp8266_features.h
@@ -0,0 +1,32 @@
+/*
+ core_esp8266_features.h - list of features integrated in to ESP8266 core
+
+ Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
+ This file is part of the esp8266 core 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
+ 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 CORE_ESP8266_FEATURES_H
+#define CORE_ESP8266_FEATURES_H
+
+
+#define CORE_HAS_LIBB64
+
+
+#endif
+
diff --git a/cores/esp8266/core_esp8266_main.cpp b/cores/esp8266/core_esp8266_main.cpp
index 92c48312d..5913fa5c2 100644
--- a/cores/esp8266/core_esp8266_main.cpp
+++ b/cores/esp8266/core_esp8266_main.cpp
@@ -98,11 +98,11 @@ extern "C" void optimistic_yield(uint32_t interval_us) {
static void loop_wrapper() {
static bool setup_done = false;
+ preloop_update_frequency();
if(!setup_done) {
setup();
setup_done = true;
}
- preloop_update_frequency();
loop();
esp_schedule();
}
diff --git a/cores/esp8266/libb64/AUTHORS b/cores/esp8266/libb64/AUTHORS
new file mode 100755
index 000000000..af6873756
--- /dev/null
+++ b/cores/esp8266/libb64/AUTHORS
@@ -0,0 +1,7 @@
+libb64: Base64 Encoding/Decoding Routines
+======================================
+
+Authors:
+-------
+
+Chris Venter chris.venter@gmail.com http://rocketpod.blogspot.com
diff --git a/cores/esp8266/libb64/LICENSE b/cores/esp8266/libb64/LICENSE
new file mode 100755
index 000000000..a6b56069e
--- /dev/null
+++ b/cores/esp8266/libb64/LICENSE
@@ -0,0 +1,29 @@
+Copyright-Only Dedication (based on United States law)
+or Public Domain Certification
+
+The person or persons who have associated work with this document (the
+"Dedicator" or "Certifier") hereby either (a) certifies that, to the best of
+his knowledge, the work of authorship identified is in the public domain of the
+country from which the work is published, or (b) hereby dedicates whatever
+copyright the dedicators holds in the work of authorship identified below (the
+"Work") to the public domain. A certifier, moreover, dedicates any copyright
+interest he may have in the associated work, and for these purposes, is
+described as a "dedicator" below.
+
+A certifier has taken reasonable steps to verify the copyright status of this
+work. Certifier recognizes that his good faith efforts may not shield him from
+liability if in fact the work certified is not in the public domain.
+
+Dedicator makes this dedication for the benefit of the public at large and to
+the detriment of the Dedicator's heirs and successors. Dedicator intends this
+dedication to be an overt act of relinquishment in perpetuity of all present
+and future rights under copyright law, whether vested or contingent, in the
+Work. Dedicator understands that such relinquishment of all rights includes
+the relinquishment of all rights to enforce (by lawsuit or otherwise) those
+copyrights in the Work.
+
+Dedicator recognizes that, once placed in the public domain, the Work may be
+freely reproduced, distributed, transmitted, used, modified, built upon, or
+otherwise exploited by anyone for any purpose, commercial or non-commercial,
+and in any way, including by methods that have not yet been invented or
+conceived.
\ No newline at end of file
diff --git a/cores/esp8266/libb64/cdecode.c b/cores/esp8266/libb64/cdecode.c
new file mode 100755
index 000000000..25e5c384c
--- /dev/null
+++ b/cores/esp8266/libb64/cdecode.c
@@ -0,0 +1,86 @@
+/*
+cdecoder.c - c source to a base64 decoding algorithm implementation
+
+This is part of the libb64 project, and has been placed in the public domain.
+For details, see http://sourceforge.net/projects/libb64
+*/
+
+#include "cdecode.h"
+
+int base64_decode_value(char value_in){
+ static const char decoding[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51};
+ static const char decoding_size = sizeof(decoding);
+ value_in -= 43;
+ if (value_in < 0 || value_in > decoding_size) return -1;
+ return decoding[(int)value_in];
+}
+
+void base64_init_decodestate(base64_decodestate* state_in){
+ state_in->step = step_a;
+ state_in->plainchar = 0;
+}
+
+int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in){
+ const char* codechar = code_in;
+ char* plainchar = plaintext_out;
+ char fragment;
+
+ *plainchar = state_in->plainchar;
+
+ switch (state_in->step){
+ while (1){
+ case step_a:
+ do {
+ if (codechar == code_in+length_in){
+ state_in->step = step_a;
+ state_in->plainchar = *plainchar;
+ return plainchar - plaintext_out;
+ }
+ fragment = (char)base64_decode_value(*codechar++);
+ } while (fragment < 0);
+ *plainchar = (fragment & 0x03f) << 2;
+ case step_b:
+ do {
+ if (codechar == code_in+length_in){
+ state_in->step = step_b;
+ state_in->plainchar = *plainchar;
+ return plainchar - plaintext_out;
+ }
+ fragment = (char)base64_decode_value(*codechar++);
+ } while (fragment < 0);
+ *plainchar++ |= (fragment & 0x030) >> 4;
+ *plainchar = (fragment & 0x00f) << 4;
+ case step_c:
+ do {
+ if (codechar == code_in+length_in){
+ state_in->step = step_c;
+ state_in->plainchar = *plainchar;
+ return plainchar - plaintext_out;
+ }
+ fragment = (char)base64_decode_value(*codechar++);
+ } while (fragment < 0);
+ *plainchar++ |= (fragment & 0x03c) >> 2;
+ *plainchar = (fragment & 0x003) << 6;
+ case step_d:
+ do {
+ if (codechar == code_in+length_in){
+ state_in->step = step_d;
+ state_in->plainchar = *plainchar;
+ return plainchar - plaintext_out;
+ }
+ fragment = (char)base64_decode_value(*codechar++);
+ } while (fragment < 0);
+ *plainchar++ |= (fragment & 0x03f);
+ }
+ }
+ /* control should not reach here */
+ return plainchar - plaintext_out;
+}
+
+int base64_decode_chars(const char* code_in, const int length_in, char* plaintext_out){
+ base64_decodestate _state;
+ base64_init_decodestate(&_state);
+ int len = base64_decode_block(code_in, length_in, plaintext_out, &_state);
+ if(len > 0) plaintext_out[len] = 0;
+ return len;
+}
diff --git a/cores/esp8266/libb64/cdecode.h b/cores/esp8266/libb64/cdecode.h
new file mode 100755
index 000000000..d75b327a8
--- /dev/null
+++ b/cores/esp8266/libb64/cdecode.h
@@ -0,0 +1,38 @@
+/*
+cdecode.h - c header for a base64 decoding algorithm
+
+This is part of the libb64 project, and has been placed in the public domain.
+For details, see http://sourceforge.net/projects/libb64
+*/
+
+#ifndef BASE64_CDECODE_H
+#define BASE64_CDECODE_H
+
+#define base64_decode_expected_len(n) ((n * 3) / 4)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ step_a, step_b, step_c, step_d
+} base64_decodestep;
+
+typedef struct {
+ base64_decodestep step;
+ char plainchar;
+} base64_decodestate;
+
+void base64_init_decodestate(base64_decodestate* state_in);
+
+int base64_decode_value(char value_in);
+
+int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in);
+
+int base64_decode_chars(const char* code_in, const int length_in, char* plaintext_out);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* BASE64_CDECODE_H */
diff --git a/cores/esp8266/libb64/cencode.c b/cores/esp8266/libb64/cencode.c
new file mode 100755
index 000000000..4631f09ed
--- /dev/null
+++ b/cores/esp8266/libb64/cencode.c
@@ -0,0 +1,104 @@
+/*
+cencoder.c - c source to a base64 encoding algorithm implementation
+
+This is part of the libb64 project, and has been placed in the public domain.
+For details, see http://sourceforge.net/projects/libb64
+*/
+
+#include "cencode.h"
+
+const int CHARS_PER_LINE = 72;
+
+void base64_init_encodestate(base64_encodestate* state_in){
+ state_in->step = step_A;
+ state_in->result = 0;
+ state_in->stepcount = 0;
+}
+
+char base64_encode_value(char value_in){
+ static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ if (value_in > 63) return '=';
+ return encoding[(int)value_in];
+}
+
+int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in){
+ const char* plainchar = plaintext_in;
+ const char* const plaintextend = plaintext_in + length_in;
+ char* codechar = code_out;
+ char result;
+ char fragment;
+
+ result = state_in->result;
+
+ switch (state_in->step){
+ while (1){
+ case step_A:
+ if (plainchar == plaintextend){
+ state_in->result = result;
+ state_in->step = step_A;
+ return codechar - code_out;
+ }
+ fragment = *plainchar++;
+ result = (fragment & 0x0fc) >> 2;
+ *codechar++ = base64_encode_value(result);
+ result = (fragment & 0x003) << 4;
+ case step_B:
+ if (plainchar == plaintextend){
+ state_in->result = result;
+ state_in->step = step_B;
+ return codechar - code_out;
+ }
+ fragment = *plainchar++;
+ result |= (fragment & 0x0f0) >> 4;
+ *codechar++ = base64_encode_value(result);
+ result = (fragment & 0x00f) << 2;
+ case step_C:
+ if (plainchar == plaintextend){
+ state_in->result = result;
+ state_in->step = step_C;
+ return codechar - code_out;
+ }
+ fragment = *plainchar++;
+ result |= (fragment & 0x0c0) >> 6;
+ *codechar++ = base64_encode_value(result);
+ result = (fragment & 0x03f) >> 0;
+ *codechar++ = base64_encode_value(result);
+
+ ++(state_in->stepcount);
+ if (state_in->stepcount == CHARS_PER_LINE/4){
+ *codechar++ = '\n';
+ state_in->stepcount = 0;
+ }
+ }
+ }
+ /* control should not reach here */
+ return codechar - code_out;
+}
+
+int base64_encode_blockend(char* code_out, base64_encodestate* state_in){
+ char* codechar = code_out;
+
+ switch (state_in->step){
+ case step_B:
+ *codechar++ = base64_encode_value(state_in->result);
+ *codechar++ = '=';
+ *codechar++ = '=';
+ break;
+ case step_C:
+ *codechar++ = base64_encode_value(state_in->result);
+ *codechar++ = '=';
+ break;
+ case step_A:
+ break;
+ }
+ *codechar = 0x00;
+
+ return codechar - code_out;
+}
+
+int base64_encode_chars(const char* plaintext_in, int length_in, char* code_out){
+ base64_encodestate _state;
+ base64_init_encodestate(&_state);
+ int len = base64_encode_block(plaintext_in, length_in, code_out, &_state);
+ return len + base64_encode_blockend((code_out + len), &_state);
+}
diff --git a/cores/esp8266/libb64/cencode.h b/cores/esp8266/libb64/cencode.h
new file mode 100755
index 000000000..058cc5d1a
--- /dev/null
+++ b/cores/esp8266/libb64/cencode.h
@@ -0,0 +1,41 @@
+/*
+cencode.h - c header for a base64 encoding algorithm
+
+This is part of the libb64 project, and has been placed in the public domain.
+For details, see http://sourceforge.net/projects/libb64
+*/
+
+#ifndef BASE64_CENCODE_H
+#define BASE64_CENCODE_H
+
+#define base64_encode_expected_len(n) ((((4 * n) / 3) + 3) & ~3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ step_A, step_B, step_C
+} base64_encodestep;
+
+typedef struct {
+ base64_encodestep step;
+ char result;
+ int stepcount;
+} base64_encodestate;
+
+void base64_init_encodestate(base64_encodestate* state_in);
+
+char base64_encode_value(char value_in);
+
+int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in);
+
+int base64_encode_blockend(char* code_out, base64_encodestate* state_in);
+
+int base64_encode_chars(const char* plaintext_in, int length_in, char* code_out);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* BASE64_CENCODE_H */
diff --git a/doc/boards.md b/doc/boards.md
index 5c3104be6..e92c4c591 100644
--- a/doc/boards.md
+++ b/doc/boards.md
@@ -3,27 +3,27 @@ title: Supported Hardware
---
## Table of contents
- * [Adafruit HUZZAH ESP8266 (ESP\-12)](#adafruit-huzzah-esp8266-esp-12)
- * [NodeMCU 0\.9 ](#nodemcu-09-)
- * [Pin mapping](#pin-mapping)
- * [NodeMCU 1\.0](#nodemcu-10)
- * [Olimex MOD\-WIFI\-ESP8266\-DEV](#olimex-mod-wifi-esp8266-dev)
- * [Olimex MOD\-WIFI\-ESP8266](#olimex-mod-wifi-esp8266)
- * [SparkFun ESP8266 Thing](#sparkfun-esp8266-thing)
- * [SweetPea ESP\-210](#sweetpea-esp-210)
- * [Generic ESP8266 modules](#generic-esp8266-modules)
- * [Serial Adapter](#serial-adapter)
- * [Minimal Hardware Setup for Bootloading and Usage](#minimal-hardware-setup-for-bootloading-and-usage)
- * [ESP to Serial](#esp-to-serial)
- * [Minimal Hardware Setup for Bootloading only](#minimal-hardware-setup-for-bootloading-only)
- * [Minimal Hardware Setup for Running only](#minimal-hardware-setup-for-running-only)
- * [Minimal](#minimal)
- * [Improved Stability](#improved-stability)
- * [Boot Messages and Modes](#boot-messages-and-modes)
- * [rst cause](#rst-cause)
- * [boot mode](#boot-mode)
- * [WeMos D1](#wemos-d1)
- * [WeMos D1 mini](#wemos-d1-mini)
+ * [Adafruit HUZZAH ESP8266 (ESP\-12)](#adafruit-huzzah-esp8266-esp-12)
+ * [NodeMCU 0\.9 ](#nodemcu-09-)
+ * [Pin mapping](#pin-mapping)
+ * [NodeMCU 1\.0](#nodemcu-10)
+ * [Olimex MOD\-WIFI\-ESP8266\-DEV](#olimex-mod-wifi-esp8266-dev)
+ * [Olimex MOD\-WIFI\-ESP8266](#olimex-mod-wifi-esp8266)
+ * [SparkFun ESP8266 Thing](#sparkfun-esp8266-thing)
+ * [SweetPea ESP\-210](#sweetpea-esp-210)
+ * [Generic ESP8266 modules](#generic-esp8266-modules)
+ * [Serial Adapter](#serial-adapter)
+ * [Minimal Hardware Setup for Bootloading and Usage](#minimal-hardware-setup-for-bootloading-and-usage)
+ * [ESP to Serial](#esp-to-serial)
+ * [Minimal Hardware Setup for Bootloading only](#minimal-hardware-setup-for-bootloading-only)
+ * [Minimal Hardware Setup for Running only](#minimal-hardware-setup-for-running-only)
+ * [Minimal](#minimal)
+ * [Improved Stability](#improved-stability)
+ * [Boot Messages and Modes](#boot-messages-and-modes)
+ * [rst cause](#rst-cause)
+ * [boot mode](#boot-mode)
+ * [WeMos D1](#wemos-d1)
+ * [WeMos D1 mini](#wemos-d1-mini)
## Adafruit HUZZAH ESP8266 (ESP-12)
diff --git a/doc/changes.md b/doc/changes.md
index b9b440c91..7d19d6166 100644
--- a/doc/changes.md
+++ b/doc/changes.md
@@ -2,7 +2,19 @@
title: Change Log
---
-*Current release*
+## Current version
+
+### Core
+
+### Libraries
+
+### Tools
+
+---
+## 2.0.0
+November 30, 2015
+
+Package link: `http://arduino.esp8266.com/versions/2.0.0/package_esp8266com_index.json`.
### Core
@@ -13,6 +25,26 @@ title: Change Log
- Update documentation for NodeMCU and Olimex boards
- Disable interrupts inside ESP.getVcc (#567)
- Erase RTC RAM only if RF mode looks invalid (#619)
+- Get pin levels at time of interrupt, rather than the time of calling the handler.
+- Move interrupt handlers to ram.
+- Improve debug output on critical errors
+- Add ArduinoOTA library and docs
+- Add WeMos D1 & D1 mini boards
+- Add documentation about boot messages and mode meaning
+- Disable sleep mode before doing OTA (#1005)
+- Add the ability to be called back when the device is about to reset
+- Add "Reset Method" menu
+- Add MD5 to core
+- I2C: generate STOP in case of NACK (fix #698, #254)
+- Add libc time functions
+- Fix linker script for 512k(no SPIFFS) variant (#966)
+- I2S optimizations
+- Support Sketch > Export compiled binary
+- Update SPIFFS wrapper for 0.3.3
+- Fix placement of code into RAM, enable gc-sections
+- Make soft wdt reset more obvious
+- Force disable IOSWAP for UART0 in HardwareSerial initialization (#744)
+- Add IPAddress::toString()
### Libraries
@@ -23,6 +55,30 @@ title: Change Log
- ESP8266mDNS: allow to work on SoftAP interface
- EEPROM: round requested size to 4 bytes (#659)
- Add ESP8266AVRISP library
+- Add ESP8266HTTPUpdate library
+- Add HTTPClient library
+- Add WiFiClientSecure
+- ESP8266WiFi library: add persistent option, fix #1054
+- Make RequestHandler handle uploads
+- Add Digest Authentication to OTA and espota.py
+- Don't close UDP pcbs when WiFi connection drops (#969)
+- Add espsoftwareserial library
+- Add HTTP Updater library
+- Add Ethernet library for W5100
+- Add SPIFFS WebServer Example
+- add dnsIP() to ESP8266WiFi class
+- OTA support encapsulated to ArduinoOTA class
+- Add gdb stub library
+- Extracted the WebUpdate example into a library.
+- Fix to Servo allowing write() to be called before attach()
+- ESP8266WiFi: add function `begin` without any parameters and add `psk` function to return current PSK form sdk config
+- Fix a crash due to abort() called from TCP error callback (#428)
+- Adding support for OPTIONS requests to ESP8266WebServer
+- Add HTTPS request sample (#43)
+- Fix _useClientMode & _useApMode in SDK auto connect mode (#754)
+- Add ESP8266WebServer::sendContent_P with 'size_t size' argument for binary content
+- Fix bug in WiFiClient::write_P when content was binary
+- Add WiFiClient::write_P to be used with PROGMEM
### Tools
diff --git a/doc/filesystem.md b/doc/filesystem.md
index 31aa148ab..4beae1e15 100644
--- a/doc/filesystem.md
+++ b/doc/filesystem.md
@@ -3,25 +3,25 @@ title: File System
---
## Table of Contents
- * [Flash layout](#flash-layout)
- * [Uploading files to file system](#uploading-files-to-file-system)
- * [File system object (SPIFFS)](#file-system-object-spiffs)
- * [begin](#begin)
- * [format](#format)
- * [open](#open)
- * [exists](#exists)
- * [openDir](#opendir)
- * [remove](#remove)
- * [rename](#rename)
- * [info](#info)
- * [Filesystem information structure](#filesystem-information-structure)
- * [Directory object (Dir)](#directory-object-dir)
- * [File object](#file-object)
- * [seek](#seek)
- * [position](#position)
- * [size](#size)
- * [name](#name)
- * [close](#close)
+ * [Flash layout](#flash-layout)
+ * [Uploading files to file system](#uploading-files-to-file-system)
+ * [File system object (SPIFFS)](#file-system-object-spiffs)
+ * [begin](#begin)
+ * [format](#format)
+ * [open](#open)
+ * [exists](#exists)
+ * [openDir](#opendir)
+ * [remove](#remove)
+ * [rename](#rename)
+ * [info](#info)
+ * [Filesystem information structure](#filesystem-information-structure)
+ * [Directory object (Dir)](#directory-object-dir)
+ * [File object](#file-object)
+ * [seek](#seek)
+ * [position](#position)
+ * [size](#size)
+ * [name](#name)
+ * [close](#close)
## Flash layout
@@ -127,9 +127,7 @@ Returns *true* if a file with given path exists, *false* otherwise.
SPIFFS.openDir(path)
```
-Opens a directory given its absolute path. Returns a *Dir* object. To check if
-directory was opened successfully, use the boolean operator, similar to opening
-a file.
+Opens a directory given its absolute path. Returns a *Dir* object.
### remove
diff --git a/doc/libraries.md b/doc/libraries.md
index 210ef2f81..314b1aa51 100644
--- a/doc/libraries.md
+++ b/doc/libraries.md
@@ -3,19 +3,19 @@ title: Libraries
---
## Table of Contents
- * [WiFi(ESP8266WiFi library)](#wifiesp8266wifi-library)
- * [Ticker](#ticker)
- * [EEPROM](#eeprom)
- * [I2C (Wire library)](#i2c-wire-library)
- * [SPI](#spi)
- * [SoftwareSerial](#softwareserial)
- * [ESP\-specific APIs](#esp-specific-apis)
- * [OneWire](#onewire)
- * [mDNS and DNS\-SD responder (ESP8266mDNS library)](#mdns-and-dns-sd-responder-esp8266mdns-library)
- * [SSDP responder (ESP8266SSDP)](#ssdp-responder-esp8266ssdp)
- * [DNS server (DNSServer library)](#dns-server-dnsserver-library)
- * [Servo](#servo)
- * [Other libraries (not included with the IDE)](#other-libraries-not-included-with-the-ide)
+ * [WiFi(ESP8266WiFi library)](#wifiesp8266wifi-library)
+ * [Ticker](#ticker)
+ * [EEPROM](#eeprom)
+ * [I2C (Wire library)](#i2c-wire-library)
+ * [SPI](#spi)
+ * [SoftwareSerial](#softwareserial)
+ * [ESP\-specific APIs](#esp-specific-apis)
+ * [OneWire](#onewire)
+ * [mDNS and DNS\-SD responder (ESP8266mDNS library)](#mdns-and-dns-sd-responder-esp8266mdns-library)
+ * [SSDP responder (ESP8266SSDP)](#ssdp-responder-esp8266ssdp)
+ * [DNS server (DNSServer library)](#dns-server-dnsserver-library)
+ * [Servo](#servo)
+ * [Other libraries (not included with the IDE)](#other-libraries-not-included-with-the-ide)
## WiFi(ESP8266WiFi library)
@@ -151,3 +151,4 @@ Libraries that don't rely on low-level access to AVR registers should work well.
- [RTC](https://github.com/Makuna/Rtc) - Arduino Library for Ds1307 & Ds3231 compatible with ESP8266.
- [Souliss, Smart Home](https://github.com/souliss/souliss) - Framework for Smart Home based on Arduino, Android and openHAB.
- [ST7735](https://github.com/nzmichaelh/Adafruit-ST7735-Library) - Adafruit's ST7735 library modified to be compatible with ESP8266. Just make sure to modify the pins in the examples as they are still AVR specific.
+- [UTFT-ESP8266](https://github.com/gnulabis/UTFT-ESP8266) - UTFT display library with support for ESP8266. Only serial interface (SPI) displays are supported for now (no 8-bit parallel mode, etc). Also includes support for the hardware SPI controller of the ESP8266.
diff --git a/doc/ota_updates/ota_updates.md b/doc/ota_updates/ota_updates.md
index 8af5be15a..42bcb06ac 100644
--- a/doc/ota_updates/ota_updates.md
+++ b/doc/ota_updates/ota_updates.md
@@ -3,29 +3,29 @@ title: OTA Update
---
## Table of Contents
- * [Introduction](#introduction)
- * [Security](#security)
- * [Safety](#safety)
- * [Basic Requirements](#basic-requirements)
- * [Arduino IDE](#arduino-ide)
- * [Requirements](#requirements)
- * [Application Example](#application-example)
- * [Classic OTA](#classic-ota)
- * [ArduinoOTA](#arduinoota)
- * [Web Browser](#web-browser)
- * [Requirements](#requirements-1)
- * [Implementation Overview](#implementation-overview)
- * [Application Example](#application-example-1)
- * [HTTP Server](#http-server)
- * [Requirements](#requirements-2)
- * [Arduino code](#arduino-code)
- * [Simple updater](#simple-updater)
- * [Advanced updater](#advanced-updater)
- * [Server request handling](#server-request-handling)
- * [Simple updater](#simple-updater-1)
- * [Advanced updater](#advanced-updater-1)
- * [Stream Interface](#stream-interface)
- * [Updater class](#updater-class)
+ * [Introduction](#introduction)
+ * [Security](#security)
+ * [Safety](#safety)
+ * [Basic Requirements](#basic-requirements)
+ * [Arduino IDE](#arduino-ide)
+ * [Requirements](#requirements)
+ * [Application Example](#application-example)
+ * [Classic OTA](#classic-ota)
+ * [ArduinoOTA](#arduinoota)
+ * [Web Browser](#web-browser)
+ * [Requirements](#requirements-1)
+ * [Implementation Overview](#implementation-overview)
+ * [Application Example](#application-example-1)
+ * [HTTP Server](#http-server)
+ * [Requirements](#requirements-2)
+ * [Arduino code](#arduino-code)
+ * [Simple updater](#simple-updater)
+ * [Advanced updater](#advanced-updater)
+ * [Server request handling](#server-request-handling)
+ * [Simple updater](#simple-updater-1)
+ * [Advanced updater](#advanced-updater-1)
+ * [Stream Interface](#stream-interface)
+ * [Updater class](#updater-class)
## Introduction
@@ -79,7 +79,13 @@ void onError(OTA_CALLBACK_ERROR (fn));
### Basic Requirements
-- Flash chip size is 2x the size of the sketch.
+Flash chip size needs a size thats is able to hold the old sketch (currently running) and the new sketch (OTA) at the same time.
+keep in mind that the File system and EEPROM for example needs space too (one time) see [flash layout](../filesystem.md#flash-layout).
+```cpp
+ESP.getFreeSketchSpace();
+```
+can be used for checking the free space for the new sketch.
+
The following chapters provide more details and specific methods of doing OTA.
@@ -121,8 +127,9 @@ Instructions below demonstrate how to configure both [Classic OTA](#classic-ota-
2. Now prepare the sketch and configuration for the upload over a serial port.
- Start Arduino IDE and load sketch DNS_SD_Arduino_OTA.ino available under File > Examples > ESP8266mDNS

+
**Note:** This sketch is available only for 1.6.5-947-g39819f0 (of July 23, 2015) and 1.6.5-1160-gef26c5f (of Sep 30, 2015) versions of platform packages installed in Arduino IDE using https://github.com/esp8266/Arduino#installing-with-boards-manager. It was removed in [#980](https://github.com/esp8266/Arduino/pull/980) from GitHub repository.
- - Update ssid and pass in the sketch so the module can join your Wi-Fi network
+ - Update SSID and password in the sketch so the module can join your Wi-Fi network

- Configure upload parameters as below (you may need to adjust configuration if you are using a different module):

@@ -133,7 +140,7 @@ Instructions below demonstrate how to configure both [Classic OTA](#classic-ota-
4. Only if module is connected to network, after a couple of seconds, the esp8266-ota port will show up in Arduino IDE:
- 
+ 
5. Now get ready for your first OTA upload by changing configuration settings as follows:
@@ -145,7 +152,7 @@ Instructions below demonstrate how to configure both [Classic OTA](#classic-ota-

-**Note** To be able to upload your sketch over and over again using OTA, you need to embed OTA routines inside. Please use DNS_SD_Arduino_OTA.ino as an example.
+**Note:** To be able to upload your sketch over and over again using OTA, you need to embed OTA routines inside. Please use DNS_SD_Arduino_OTA.ino as an example.
#### ArduinoOTA
@@ -217,15 +224,21 @@ You can use another module if it meets “Flash chip size is 2x the size of the
- Start Arduino IDE and load sketch WebUpdater.ino available under File > Examples > ESP8266HTTPUpdateServer.
- Update ssid and pass in the sketch so the module can join your Wi-Fi network.
- Open File > Preferences, look for “Show verbose output during:” and check out “compilation” option.
+

+
**Note:** This setting will be required in step 5 below. You can uncheck this setting afterwards.
3. Upload sketch (Ctrl+U). Once done open Serial Monitor (Ctrl+Shift+M) and check if you see the following message displayed, that contains url for OTA update.
+

- **Note:** Such message will be shown only after module successfully joins network and is ready for an OTA upload:
+
+ **Note:** Such message will be shown only after module successfully joins network and is ready for an OTA upload.
4. Now open web browser and enter the url provided on Serial Monitor, i.e. http://esp8266-webupdate.local/update. Once entered, browser should display a form like below that has been served by your module. The form invites you to choose a file for update.
+

+
**Note:** If entering “http://esp8266-webupdate.local/update” does not work, try replacing “esp8266-webupdate” with module’s IP address. For example, if your module IP is “192.168.1.100” then url should be “http://192.168.1.100/update”. This workaround is useful in case the host software installed in step 2 does not work. If still nothing works and there are no clues on Serial Monitor, try to diagnose issue by opening provided url in Google Chrome, pressing F12 and checking contents of “Console” and “Network” tabs. Chrome provides some advanced logging on these tabs.
@@ -241,7 +254,7 @@ You can use another module if it meets “Flash chip size is 2x the size of the

-Just after reboot you should see exactly the same message “HTTPUpdateServer ready! Open http:// esp8266-webupdate.local /update in your browser” like in step 3. This is because module has been loaded again with the same code – first using serial port, and then using OTA.
+ Just after reboot you should see exactly the same message “HTTPUpdateServer ready! Open http:// esp8266-webupdate.local /update in your browser” like in step 3. This is because module has been loaded again with the same code – first using serial port, and then using OTA.
Once you are comfortable with this procedure go ahead and modify WebUpdater.ino sketch to print some additional messages, compile it, locate new binary file and upload it using web browser to see entered changes on a Serial Monitor.
@@ -311,7 +324,7 @@ Example header data:
[HTTP_X_ESP8266_AP_MAC] => 1A:FE:AA:AA:AA:AA
[HTTP_X_ESP8266_FREE_SPACE] => 671744
[HTTP_X_ESP8266_SKETCH_SIZE] => 373940
- [HTTP_X_ESP8266_CHIP_SIZE] => 524288
+ [HTTP_X_ESP8266_CHIP_SIZE] => 4194304
[HTTP_X_ESP8266_SDK_VERSION] => 1.3.0
[HTTP_X_ESP8266_VERSION] => DOOR-7-g14f53a19
```
diff --git a/doc/reference.md b/doc/reference.md
index 1138950e7..24cfaa58b 100644
--- a/doc/reference.md
+++ b/doc/reference.md
@@ -3,13 +3,13 @@ title: Reference
---
## Table of Contents
- * [Table of Contents](#table-of-contents)
- * [Digital IO](#digital-io)
- * [Analog input](#analog-input)
- * [Analog output](#analog-output)
- * [Timing and delays](#timing-and-delays)
- * [Serial](#serial)
- * [Progmem](#progmem)
+ * [Table of Contents](#table-of-contents)
+ * [Digital IO](#digital-io)
+ * [Analog input](#analog-input)
+ * [Analog output](#analog-output)
+ * [Timing and delays](#timing-and-delays)
+ * [Serial](#serial)
+ * [Progmem](#progmem)
## Digital IO
diff --git a/libraries/ArduinoOTA/examples/BasicOTA/BasicOTA.ino b/libraries/ArduinoOTA/examples/BasicOTA/BasicOTA.ino
index ec621bb79..50e926efe 100644
--- a/libraries/ArduinoOTA/examples/BasicOTA/BasicOTA.ino
+++ b/libraries/ArduinoOTA/examples/BasicOTA/BasicOTA.ino
@@ -30,10 +30,10 @@ void setup() {
Serial.println("Start");
});
ArduinoOTA.onEnd([]() {
- Serial.println("End");
+ Serial.println("\nEnd");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
- Serial.printf("Progress: %u%%\n", (progress / (total / 100)));
+ Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
diff --git a/libraries/ESP8266httpClient/examples/BasicHttpClient/BasicHttpClient.ino b/libraries/ESP8266HTTPClient/examples/BasicHttpClient/BasicHttpClient.ino
similarity index 91%
rename from libraries/ESP8266httpClient/examples/BasicHttpClient/BasicHttpClient.ino
rename to libraries/ESP8266HTTPClient/examples/BasicHttpClient/BasicHttpClient.ino
index 15526e096..3c722556b 100644
--- a/libraries/ESP8266httpClient/examples/BasicHttpClient/BasicHttpClient.ino
+++ b/libraries/ESP8266HTTPClient/examples/BasicHttpClient/BasicHttpClient.ino
@@ -1,68 +1,68 @@
-/**
- * BasicHttpClient.ino
- *
- * Created on: 24.05.2015
- *
- */
-
-#include
-
-#include
-#include
-
-#include
-
-#define USE_SERIAL Serial
-
-ESP8266WiFiMulti WiFiMulti;
-
-void setup() {
-
- USE_SERIAL.begin(115200);
- // USE_SERIAL.setDebugOutput(true);
-
- USE_SERIAL.println();
- USE_SERIAL.println();
- USE_SERIAL.println();
-
- for(uint8_t t = 4; t > 0; t--) {
- USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
- USE_SERIAL.flush();
- delay(1000);
- }
-
- WiFiMulti.addAP("SSID", "PASSWORD");
-
-}
-
-void loop() {
- // wait for WiFi connection
- if((WiFiMulti.run() == WL_CONNECTED)) {
-
- httpClient http;
-
- USE_SERIAL.print("[HTTP] begin...\n");
- // configure traged server and url
- //http.begin("192.168.1.12", 443, "/test.html", true, "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS
- http.begin("192.168.1.12", 80, "/test.html"); //HTTP
-
- USE_SERIAL.print("[HTTP] GET...\n");
- // start connection and send HTTP header
- int httpCode = http.GET();
- if(httpCode) {
- // HTTP header has been send and Server response header has been handled
- USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
-
- // file found at server
- if(httpCode == 200) {
- String payload = http.getString();
- USE_SERIAL.println(payload);
- }
- } else {
- USE_SERIAL.print("[HTTP] GET... failed, no connection or no HTTP server\n");
- }
- }
-
- delay(10000);
-}
-
+/**
+ * BasicHTTPClient.ino
+ *
+ * Created on: 24.05.2015
+ *
+ */
+
+#include
+
+#include
+#include
+
+#include
+
+#define USE_SERIAL Serial
+
+ESP8266WiFiMulti WiFiMulti;
+
+void setup() {
+
+ USE_SERIAL.begin(115200);
+ // USE_SERIAL.setDebugOutput(true);
+
+ USE_SERIAL.println();
+ USE_SERIAL.println();
+ USE_SERIAL.println();
+
+ for(uint8_t t = 4; t > 0; t--) {
+ USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
+ USE_SERIAL.flush();
+ delay(1000);
+ }
+
+ WiFiMulti.addAP("SSID", "PASSWORD");
+
+}
+
+void loop() {
+ // wait for WiFi connection
+ if((WiFiMulti.run() == WL_CONNECTED)) {
+
+ HTTPClient http;
+
+ USE_SERIAL.print("[HTTP] begin...\n");
+ // configure traged server and url
+ //http.begin("192.168.1.12", 443, "/test.html", true, "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS
+ http.begin("192.168.1.12", 80, "/test.html"); //HTTP
+
+ USE_SERIAL.print("[HTTP] GET...\n");
+ // start connection and send HTTP header
+ int httpCode = http.GET();
+ if(httpCode) {
+ // HTTP header has been send and Server response header has been handled
+ USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
+
+ // file found at server
+ if(httpCode == 200) {
+ String payload = http.getString();
+ USE_SERIAL.println(payload);
+ }
+ } else {
+ USE_SERIAL.print("[HTTP] GET... failed, no connection or no HTTP server\n");
+ }
+ }
+
+ delay(10000);
+}
+
diff --git a/libraries/ESP8266httpClient/examples/reuseConnection/reuseConnection.ino b/libraries/ESP8266HTTPClient/examples/ReuseConnection/ReuseConnection.ino
similarity index 90%
rename from libraries/ESP8266httpClient/examples/reuseConnection/reuseConnection.ino
rename to libraries/ESP8266HTTPClient/examples/ReuseConnection/ReuseConnection.ino
index 4610cb972..e725a1f76 100644
--- a/libraries/ESP8266httpClient/examples/reuseConnection/reuseConnection.ino
+++ b/libraries/ESP8266HTTPClient/examples/ReuseConnection/ReuseConnection.ino
@@ -1,65 +1,65 @@
-/**
- * reuseConnection.ino
- *
- * Created on: 22.11.2015
- *
- */
-
-
-#include
-
-#include
-#include
-
-#include
-
-#define USE_SERIAL Serial
-
-ESP8266WiFiMulti WiFiMulti;
-
-httpClient http;
-
-void setup() {
-
- USE_SERIAL.begin(115200);
- // USE_SERIAL.setDebugOutput(true);
-
- USE_SERIAL.println();
- USE_SERIAL.println();
- USE_SERIAL.println();
-
- for(uint8_t t = 4; t > 0; t--) {
- USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
- USE_SERIAL.flush();
- delay(1000);
- }
-
- WiFiMulti.addAP("SSID", "PASSWORD");
-
-
-}
-
-void loop() {
- // wait for WiFi connection
- if((WiFiMulti.run() == WL_CONNECTED)) {
-
- http.begin("192.168.1.12", 80, "/test.html");
-
- int httpCode = http.GET();
- if(httpCode) {
- USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
-
- // file found at server
- if(httpCode == 200) {
- http.writeToStream(&USE_SERIAL);
- }
- } else {
- USE_SERIAL.print("[HTTP] GET... failed, no connection or no HTTP server\n");
- }
- }
-
- delay(1000);
-}
-
-
-
+/**
+ * reuseConnection.ino
+ *
+ * Created on: 22.11.2015
+ *
+ */
+
+
+#include
+
+#include
+#include
+
+#include
+
+#define USE_SERIAL Serial
+
+ESP8266WiFiMulti WiFiMulti;
+
+HTTPClient http;
+
+void setup() {
+
+ USE_SERIAL.begin(115200);
+ // USE_SERIAL.setDebugOutput(true);
+
+ USE_SERIAL.println();
+ USE_SERIAL.println();
+ USE_SERIAL.println();
+
+ for(uint8_t t = 4; t > 0; t--) {
+ USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
+ USE_SERIAL.flush();
+ delay(1000);
+ }
+
+ WiFiMulti.addAP("SSID", "PASSWORD");
+
+
+}
+
+void loop() {
+ // wait for WiFi connection
+ if((WiFiMulti.run() == WL_CONNECTED)) {
+
+ http.begin("192.168.1.12", 80, "/test.html");
+
+ int httpCode = http.GET();
+ if(httpCode) {
+ USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
+
+ // file found at server
+ if(httpCode == 200) {
+ http.writeToStream(&USE_SERIAL);
+ }
+ } else {
+ USE_SERIAL.print("[HTTP] GET... failed, no connection or no HTTP server\n");
+ }
+ }
+
+ delay(1000);
+}
+
+
+
diff --git a/libraries/ESP8266httpClient/examples/StreamHttpClient/StreamHttpClient.ino b/libraries/ESP8266HTTPClient/examples/StreamHttpClient/StreamHttpClient.ino
similarity index 93%
rename from libraries/ESP8266httpClient/examples/StreamHttpClient/StreamHttpClient.ino
rename to libraries/ESP8266HTTPClient/examples/StreamHttpClient/StreamHttpClient.ino
index 43b6d4d8b..442fa6547 100644
--- a/libraries/ESP8266httpClient/examples/StreamHttpClient/StreamHttpClient.ino
+++ b/libraries/ESP8266HTTPClient/examples/StreamHttpClient/StreamHttpClient.ino
@@ -1,98 +1,98 @@
-/**
- * StreamHttpClient.ino
- *
- * Created on: 24.05.2015
- *
- */
-
-#include
-
-#include
-#include
-
-#include
-
-#define USE_SERIAL Serial
-
-ESP8266WiFiMulti WiFiMulti;
-
-void setup() {
-
- USE_SERIAL.begin(115200);
- // USE_SERIAL.setDebugOutput(true);
-
- USE_SERIAL.println();
- USE_SERIAL.println();
- USE_SERIAL.println();
-
- for(uint8_t t = 4; t > 0; t--) {
- USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
- USE_SERIAL.flush();
- delay(1000);
- }
-
- WiFiMulti.addAP("SSID", "PASSWORD");
-
-}
-
-void loop() {
- // wait for WiFi connection
- if((WiFiMulti.run() == WL_CONNECTED)) {
-
- httpClient http;
-
- USE_SERIAL.print("[HTTP] begin...\n");
- // configure traged server and url
- http.begin("192.168.1.12", 80, "/test.html");
-
- USE_SERIAL.print("[HTTP] GET...\n");
- // start connection and send HTTP header
- int httpCode = http.GET();
- if(httpCode) {
- // HTTP header has been send and Server response header has been handled
-
- USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
-
- // file found at server
- if(httpCode == 200) {
-
- // get lenght of document (is -1 when Server sends no Content-Length header)
- int len = http.getSize();
-
- // create buffer for read
- uint8_t buff[128] = { 0 };
-
- // get tcp stream
- WiFiClient * stream = http.getStreamPtr();
-
- // read all data from server
- while(http.connected() && (len > 0 || len == -1)) {
- // get available data size
- size_t size = stream->available();
-
- if(size) {
- // read up to 128 byte
- int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size));
-
- // write it to Serial
- USE_SERIAL.write(buff, c);
-
- if(len > 0) {
- len -= c;
- }
- }
- delay(1);
- }
-
- USE_SERIAL.println();
- USE_SERIAL.print("[HTTP] connection closed or file end.\n");
-
- }
- } else {
- USE_SERIAL.print("[HTTP] GET... failed, no connection or no HTTP server\n");
- }
- }
-
- delay(10000);
-}
-
+/**
+ * StreamHTTPClient.ino
+ *
+ * Created on: 24.05.2015
+ *
+ */
+
+#include
+
+#include
+#include
+
+#include
+
+#define USE_SERIAL Serial
+
+ESP8266WiFiMulti WiFiMulti;
+
+void setup() {
+
+ USE_SERIAL.begin(115200);
+ // USE_SERIAL.setDebugOutput(true);
+
+ USE_SERIAL.println();
+ USE_SERIAL.println();
+ USE_SERIAL.println();
+
+ for(uint8_t t = 4; t > 0; t--) {
+ USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
+ USE_SERIAL.flush();
+ delay(1000);
+ }
+
+ WiFiMulti.addAP("SSID", "PASSWORD");
+
+}
+
+void loop() {
+ // wait for WiFi connection
+ if((WiFiMulti.run() == WL_CONNECTED)) {
+
+ HTTPClient http;
+
+ USE_SERIAL.print("[HTTP] begin...\n");
+ // configure traged server and url
+ http.begin("192.168.1.12", 80, "/test.html");
+
+ USE_SERIAL.print("[HTTP] GET...\n");
+ // start connection and send HTTP header
+ int httpCode = http.GET();
+ if(httpCode) {
+ // HTTP header has been send and Server response header has been handled
+
+ USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
+
+ // file found at server
+ if(httpCode == 200) {
+
+ // get lenght of document (is -1 when Server sends no Content-Length header)
+ int len = http.getSize();
+
+ // create buffer for read
+ uint8_t buff[128] = { 0 };
+
+ // get tcp stream
+ WiFiClient * stream = http.getStreamPtr();
+
+ // read all data from server
+ while(http.connected() && (len > 0 || len == -1)) {
+ // get available data size
+ size_t size = stream->available();
+
+ if(size) {
+ // read up to 128 byte
+ int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size));
+
+ // write it to Serial
+ USE_SERIAL.write(buff, c);
+
+ if(len > 0) {
+ len -= c;
+ }
+ }
+ delay(1);
+ }
+
+ USE_SERIAL.println();
+ USE_SERIAL.print("[HTTP] connection closed or file end.\n");
+
+ }
+ } else {
+ USE_SERIAL.print("[HTTP] GET... failed, no connection or no HTTP server\n");
+ }
+ }
+
+ delay(10000);
+}
+
diff --git a/libraries/ESP8266httpClient/library.properties b/libraries/ESP8266HTTPClient/library.properties
similarity index 60%
rename from libraries/ESP8266httpClient/library.properties
rename to libraries/ESP8266HTTPClient/library.properties
index 55110c143..ab96e9a9e 100644
--- a/libraries/ESP8266httpClient/library.properties
+++ b/libraries/ESP8266HTTPClient/library.properties
@@ -1,9 +1,9 @@
-name=ESP8266httpClient
+name=ESP8266HTTPClient
version=1.0
author=Markus Sattler
maintainer=Markus Sattler
sentence=http Client for ESP8266
paragraph=
category=Communication
-url=https://github.com/Links2004/Arduino/tree/libraries/ESP8266httpClient
+url=https://github.com/Links2004/Arduino/tree/libraries/ESP8266HTTPClient
architectures=esp8266
diff --git a/libraries/ESP8266httpClient/src/ESP8266httpClient.cpp b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp
similarity index 87%
rename from libraries/ESP8266httpClient/src/ESP8266httpClient.cpp
rename to libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp
index af2e235a5..37b71dbc1 100644
--- a/libraries/ESP8266httpClient/src/ESP8266httpClient.cpp
+++ b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp
@@ -1,665 +1,665 @@
-/**
- * ESP8266httpClient.cpp
- *
- * Created on: 02.11.2015
- *
- * Copyright (c) 2015 Markus Sattler. All rights reserved.
- * This file is part of the ESP8266httpClient for Arduino.
- *
- * 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
-#include
-#include
-#include
-
-#include "ESP8266httpClient.h"
-
-/**
- * constractor
- */
-httpClient::httpClient() {
- _tcp = NULL;
- _tcps = NULL;
-
- _port = 0;
-
- _reuse = false;
- _https = false;
-
- _userAgent = "ESP8266httpClient";
-
- _headerKeysCount = 0;
- _currentHeaders = NULL;
-
- _returnCode = 0;
- _size = -1;
- _canReuse = false;
-
-}
-
-/**
- * deconstractor
- */
-httpClient::~httpClient() {
-
- if(_tcps) {
- _tcps->stop();
- delete _tcps;
- _tcps = NULL;
- _tcp = NULL;
- } else if(_tcp) {
- _tcp->stop();
- delete _tcp;
- _tcp = NULL;
- }
-
- if(_currentHeaders) {
- delete[] _currentHeaders;
- }
-}
-
-/**
- * phasing the url for all needed informations
- * @param url const char *
- * @param httpsFingerprint const char *
- */
-void httpClient::begin(const char *url, const char * httpsFingerprint) {
- begin(String(url), String(httpsFingerprint));
-}
-
-/**
- * phasing the url for all needed informations
- * @param url String
- * @param httpsFingerprint String
- */
-void httpClient::begin(String url, String httpsFingerprint) {
-
- DEBUG_HTTPCLIENT("[HTTP-Client][begin] url: %s\n", url.c_str());
-
- _httpsFingerprint = httpsFingerprint;
- _returnCode = 0;
- _size = -1;
-
- _Headers = "";
-
- String protocol;
- // check for : (http: or https:
- int index = url.indexOf(':');
- int index2;
- bool hasPort = false;
- if(index) {
- protocol = url.substring(0, index);
- url.remove(0, (index + 3)); // remove http:// or https://
-
- index = url.indexOf(':');
- index2 = url.indexOf('/');
-
- if(index >= 0 && ((index2 >= 0 && index < index2) || index2 == 0)) { // do we have a port?
- _host = url.substring(0, index); // hostname
- url.remove(0, (index + 1)); // remove hostname + :
-
- index = url.indexOf('/');
- _port = url.substring(0, index).toInt(); // get port
- url.remove(0, index); // remove port
- hasPort = true;
- } else {
- index = index2;
- _host = url.substring(0, index);
- url.remove(0, index); // remove hostname
- }
-
- _url = url;
-
- if(protocol.equalsIgnoreCase("http")) {
- _https = false;
- if(!hasPort) {
- _port = 80;
- }
- } else if(protocol.equalsIgnoreCase("https")) {
- _https = true;
- if(!hasPort) {
- _port = 443;
- }
- } else {
- DEBUG_HTTPCLIENT("[HTTP-Client][begin] protocol: %s unknown?!\n", protocol.c_str());
- return;
- }
- }
-
- DEBUG_HTTPCLIENT("[HTTP-Client][begin] host: %s port: %d url: %s https: %d httpsFingerprint: %s\n", _host.c_str(), _port, _url.c_str(), _https, _httpsFingerprint.c_str());
-
-}
-
-/**
- * begin
- * @param host const char *
- * @param port uint16_t
- * @param url const char *
- * @param https bool
- * @param httpsFingerprint const char *
- */
-void httpClient::begin(const char *host, uint16_t port, const char * url, bool https, const char * httpsFingerprint) {
-
- DEBUG_HTTPCLIENT("[HTTP-Client][begin] host: %s port:%d url: %s https: %d httpsFingerprint: %s\n", host, port, url, https, httpsFingerprint);
-
- _host = host;
- _port = port;
- _url = url;
- _https = https;
- _httpsFingerprint = httpsFingerprint;
-
- _returnCode = 0;
- _size = -1;
-
- _Headers = "";
-
-}
-
-void httpClient::begin(String host, uint16_t port, String url, bool https, String httpsFingerprint) {
- begin(host.c_str(), port, url.c_str(), https, httpsFingerprint.c_str());
-}
-
-/**
- * end
- * called after the payload is handled
- */
-void httpClient::end(void) {
- if(connected()) {
- if(_reuse && _canReuse) {
- DEBUG_HTTPCLIENT("[HTTP-Client][end] tcp keep open for reuse\n");
- } else {
- DEBUG_HTTPCLIENT("[HTTP-Client][end] tcp stop\n");
- _tcp->stop();
- }
- } else {
- DEBUG_HTTPCLIENT("[HTTP-Client][end] tcp is closed\n");
- }
-}
-
-/**
- * connected
- * @return connected status
- */
-bool httpClient::connected() {
- if(_tcp) {
- return (_tcp->connected() || (_tcp->available() > 0));
- }
- return false;
-}
-
-/**
- * try to reuse the connection to the server
- * keep-alive
- * @param reuse bool
- */
-void httpClient::setReuse(bool reuse) {
- _reuse = reuse;
-}
-
-/**
- * set User Agent
- * @param userAgent const char *
- */
-void httpClient::setUserAgent(const char * userAgent) {
- _userAgent = userAgent;
-}
-
-/**
- * send a GET request
- * @return http code
- */
-int httpClient::GET() {
- return sendRequest("GET");
-}
-
-/**
- * sends a post request to the server
- * @param payload uint8_t *
- * @param size size_t
- * @return http code
- */
-int httpClient::POST(uint8_t * payload, size_t size) {
- return sendRequest("POST", payload, size);
-}
-
-int httpClient::POST(String payload) {
- return POST((uint8_t *) payload.c_str(), payload.length());
-}
-
-/**
- * sendRequest
- * @param type const char * "GET", "POST", ....
- * @param payload uint8_t * data for the message body if null not send
- * @param size size_t size for the message body if 0 not send
- * @return -1 if no info or > 0 when Content-Length is set by server
- */
-int httpClient::sendRequest(const char * type, uint8_t * payload, size_t size) {
- // connect to server
- if(!connect()) {
- return HTTPC_ERROR_CONNECTION_REFUSED;
- }
-
- if(payload && size > 0) {
- addHeader("Content-Length", String(size));
- }
-
- // send Header
- if(!sendHeader(type)) {
- return HTTPC_ERROR_SEND_HEADER_FAILED;
- }
-
- // send Payload if needed
- if(payload && size > 0) {
- if(_tcp->write(&payload[0], size) != size) {
- return HTTPC_ERROR_SEND_PAYLOAD_FAILED;
- }
- }
-
- // handle Server Response (Header)
- return handleHeaderResponse();
-}
-
-/**
- * sendRequest
- * @param type const char * "GET", "POST", ....
- * @param stream Stream * data stream for the message body
- * @param size size_t size for the message body if 0 not Content-Length is send
- * @return -1 if no info or > 0 when Content-Length is set by server
- */
-int httpClient::sendRequest(const char * type, Stream * stream, size_t size) {
-
- if(!stream) {
- return HTTPC_ERROR_NO_STREAM;
- }
-
- // connect to server
- if(!connect()) {
- return HTTPC_ERROR_CONNECTION_REFUSED;
- }
-
- if(size > 0) {
- addHeader("Content-Length", String(size));
- }
-
- // send Header
- if(!sendHeader(type)) {
- return HTTPC_ERROR_SEND_HEADER_FAILED;
- }
-
- // create buffer for read
- uint8_t buff[1460] = { 0 };
-
- int len = size;
- int bytesWritten = 0;
-
- if(len == 0) {
- len = -1;
- }
-
- // read all data from stream and send it to server
- while(connected() && stream->available() && (len > 0 || len == -1)) {
-
- // get available data size
- size_t s = stream->available();
-
- if(s) {
- int c = stream->readBytes(buff, ((s > sizeof(buff)) ? sizeof(buff) : s));
-
- // write it to Stream
- bytesWritten += _tcp->write((const uint8_t *)buff, c);
-
- if(len > 0) {
- len -= c;
- }
-
- delay(0);
- } else {
- delay(1);
- }
- }
-
- if(size && (int)size != bytesWritten) {
- DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] Stream payload bytesWritten %d and size %d mismatch!.\n", bytesWritten, _size);
- DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] ERROR SEND PAYLOAD FAILED!");
- return HTTPC_ERROR_SEND_PAYLOAD_FAILED;
- } else {
- DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] Stream payload written: %d\n", bytesWritten);
- }
-
- // handle Server Response (Header)
- return handleHeaderResponse();
-}
-
-/**
- * size of message body / payload
- * @return -1 if no info or > 0 when Content-Length is set by server
- */
-int httpClient::getSize(void) {
- return _size;
-}
-
-/**
- * deprecated Note: this is not working with https!
- * returns the stream of the tcp connection
- * @return WiFiClient
- */
-WiFiClient & httpClient::getStream(void) {
- if(connected()) {
- return *_tcp;
- }
-
- DEBUG_HTTPCLIENT("[HTTP-Client] no stream to return!?\n");
-
- // todo return error?
-}
-
-/**
- * returns the stream of the tcp connection
- * @return WiFiClient *
- */
-WiFiClient * httpClient::getStreamPtr(void) {
- if(connected()) {
- return _tcp;
- }
-
- DEBUG_HTTPCLIENT("[HTTP-Client] no stream to return!?\n");
- return NULL;
-}
-
-/**
- * write all message body / payload to Stream
- * @param stream Stream *
- * @return bytes written ( negative values are error codes )
- */
-int httpClient::writeToStream(Stream * stream) {
-
- if(!stream) {
- return HTTPC_ERROR_NO_STREAM;
- }
-
- if(!connected()) {
- return HTTPC_ERROR_NOT_CONNECTED;
- }
-
- // get length of document (is -1 when Server sends no Content-Length header)
- int len = _size;
- int bytesWritten = 0;
-
- // create buffer for read
- uint8_t buff[1460] = { 0 };
-
- // read all data from server
- while(connected() && (len > 0 || len == -1)) {
-
- // get available data size
- size_t size = _tcp->available();
-
- if(size) {
- int c = _tcp->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size));
-
- // write it to Stream
- bytesWritten += stream->write(buff, c);
-
- if(len > 0) {
- len -= c;
- }
-
- delay(0);
- } else {
- delay(1);
- }
- }
-
- DEBUG_HTTPCLIENT("[HTTP-Client][writeToStream] connection closed or file end (written: %d).\n", bytesWritten);
-
- if(_size && _size != bytesWritten) {
- DEBUG_HTTPCLIENT("[HTTP-Client][writeToStream] bytesWritten %d and size %d mismatch!.\n", bytesWritten, _size);
- }
-
- end();
- return bytesWritten;
-}
-
-/**
- * return all payload as String (may need lot of ram or trigger out of memory!)
- * @return String
- */
-String httpClient::getString(void) {
- StreamString sstring;
-
- if(_size) {
- // try to reserve needed memmory
- if(!sstring.reserve((_size + 1))) {
- DEBUG_HTTPCLIENT("[HTTP-Client][getString] too less memory to reserve as string! need: %d\n", (_size + 1));
- return String("--too less memory--");
- }
- }
-
- writeToStream(&sstring);
- return sstring;
-}
-
-/**
- * adds Header to the request
- * @param name
- * @param value
- * @param first
- */
-void httpClient::addHeader(const String& name, const String& value, bool first) {
-
- // not allow set of Header handled by code
- if(!name.equalsIgnoreCase("Connection") && !name.equalsIgnoreCase("User-Agent") && !name.equalsIgnoreCase("Host")) {
- String headerLine = name;
- headerLine += ": ";
- headerLine += value;
- headerLine += "\r\n";
-
- if(first) {
- _Headers = headerLine + _Headers;
- } else {
- _Headers += headerLine;
- }
- }
-
-}
-
-void httpClient::collectHeaders(const char* headerKeys[], const size_t headerKeysCount) {
- _headerKeysCount = headerKeysCount;
- if(_currentHeaders)
- delete[] _currentHeaders;
- _currentHeaders = new RequestArgument[_headerKeysCount];
- for(size_t i = 0; i < _headerKeysCount; i++) {
- _currentHeaders[i].key = headerKeys[i];
- }
-}
-
-String httpClient::header(const char* name) {
- for(size_t i = 0; i < _headerKeysCount; ++i) {
- if(_currentHeaders[i].key == name)
- return _currentHeaders[i].value;
- }
- return String();
-}
-
-String httpClient::header(size_t i) {
- if(i < _headerKeysCount)
- return _currentHeaders[i].value;
- return String();
-}
-
-String httpClient::headerName(size_t i) {
- if(i < _headerKeysCount)
- return _currentHeaders[i].key;
- return String();
-}
-
-int httpClient::headers() {
- return _headerKeysCount;
-}
-
-bool httpClient::hasHeader(const char* name) {
- for(size_t i = 0; i < _headerKeysCount; ++i) {
- if((_currentHeaders[i].key == name) && (_currentHeaders[i].value.length() > 0))
- return true;
- }
- return false;
-}
-
-/**
- * init TCP connection and handle ssl verify if needed
- * @return true if connection is ok
- */
-bool httpClient::connect(void) {
-
- if(connected()) {
- DEBUG_HTTPCLIENT("[HTTP-Client] connect. already connected, try reuse!\n");
- return true;
- }
-
- if(_https) {
- DEBUG_HTTPCLIENT("[HTTP-Client] connect https...\n");
- if(_tcps) {
- delete _tcps;
- _tcps = NULL;
- _tcp = NULL;
- }
- _tcps = new WiFiClientSecure();
- _tcp = _tcps;
- } else {
- DEBUG_HTTPCLIENT("[HTTP-Client] connect http...\n");
- if(_tcp) {
- delete _tcp;
- _tcp = NULL;
- }
- _tcp = new WiFiClient();
- }
-
- if(!_tcp->connect(_host.c_str(), _port)) {
- DEBUG_HTTPCLIENT("[HTTP-Client] failed connect to %s:%u\n", _host.c_str(), _port);
- return false;
- }
-
- DEBUG_HTTPCLIENT("[HTTP-Client] connected to %s:%u\n", _host.c_str(), _port);
-
- if(_https && _httpsFingerprint.length() > 0) {
- if(_tcps->verify(_httpsFingerprint.c_str(), _host.c_str())) {
- DEBUG_HTTPCLIENT("[HTTP-Client] https certificate matches\n");
- } else {
- DEBUG_HTTPCLIENT("[HTTP-Client] https certificate doesn't match!\n");
- _tcp->stop();
- return false;
- }
- }
-
- // set Timeout for readBytesUntil and readStringUntil
- _tcp->setTimeout(HTTPCLIENT_TCP_TIMEOUT);
-
-#ifdef ESP8266
- _tcp->setNoDelay(true);
-#endif
- return connected();
-}
-
-/**
- * sends HTTP request header
- * @param type (GET, POST, ...)
- * @return status
- */
-bool httpClient::sendHeader(const char * type) {
- if(!connected()) {
- return false;
- }
-
- String header = String(type) + " " + _url + " HTTP/1.1\r\n"
- "Host: " + _host + "\r\n"
- "User-Agent: " + _userAgent + "\r\n"
- "Connection: ";
-
- if(_reuse) {
- header += "keep-alive";
- } else {
- header += "close";
- }
- header += "\r\n" + _Headers + "\r\n";
-
- return (_tcp->write(header.c_str(), header.length()) == header.length());
-}
-
-/**
- * reads the response from the server
- * @return int http code
- */
-int httpClient::handleHeaderResponse() {
-
- if(!connected()) {
- return HTTPC_ERROR_NOT_CONNECTED;
- }
-
- _returnCode = -1;
- _size = -1;
-
- while(connected()) {
- size_t len = _tcp->available();
- if(len > 0) {
- String headerLine = _tcp->readStringUntil('\n');
- headerLine.trim(); // remove \r
-
- DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] RX: '%s'\n", headerLine.c_str());
-
- if(headerLine.startsWith("HTTP/1.")) {
- _returnCode = headerLine.substring(9, headerLine.indexOf(' ', 9)).toInt();
- } else if(headerLine.indexOf(':')) {
- String headerName = headerLine.substring(0, headerLine.indexOf(':'));
- String headerValue = headerLine.substring(headerLine.indexOf(':') + 2);
-
- if(headerName.equalsIgnoreCase("Content-Length")) {
- _size = headerValue.toInt();
- }
-
- if(headerName.equalsIgnoreCase("Connection")) {
- _canReuse = headerValue.equalsIgnoreCase("keep-alive");
- }
-
- for(size_t i = 0; i < _headerKeysCount; i++) {
- if(_currentHeaders[i].key.equalsIgnoreCase(headerName)) {
- _currentHeaders[i].value = headerValue;
- break;
- }
- }
- }
-
- if(headerLine == "") {
- DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] code: %d\n", _returnCode);
- if(_size) {
- DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] size: %d\n", _size);
- }
- if(_returnCode) {
- return _returnCode;
- } else {
- DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] Remote host is not an HTTP Server!");
- return HTTPC_ERROR_NO_HTTP_SERVER;
- }
- }
-
- } else {
- delay(0);
- }
- }
-
- return HTTPC_ERROR_CONNECTION_LOST;
-}
+/**
+ * ESP8266HTTPClient.cpp
+ *
+ * Created on: 02.11.2015
+ *
+ * Copyright (c) 2015 Markus Sattler. All rights reserved.
+ * This file is part of the ESP8266HTTPClient for Arduino.
+ *
+ * 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
+#include
+#include
+#include
+
+#include "ESP8266HTTPClient.h"
+
+/**
+ * constractor
+ */
+HTTPClient::HTTPClient() {
+ _tcp = NULL;
+ _tcps = NULL;
+
+ _port = 0;
+
+ _reuse = false;
+ _https = false;
+
+ _userAgent = "ESP8266HTTPClient";
+
+ _headerKeysCount = 0;
+ _currentHeaders = NULL;
+
+ _returnCode = 0;
+ _size = -1;
+ _canReuse = false;
+
+}
+
+/**
+ * deconstractor
+ */
+HTTPClient::~HTTPClient() {
+
+ if(_tcps) {
+ _tcps->stop();
+ delete _tcps;
+ _tcps = NULL;
+ _tcp = NULL;
+ } else if(_tcp) {
+ _tcp->stop();
+ delete _tcp;
+ _tcp = NULL;
+ }
+
+ if(_currentHeaders) {
+ delete[] _currentHeaders;
+ }
+}
+
+/**
+ * phasing the url for all needed informations
+ * @param url const char *
+ * @param httpsFingerprint const char *
+ */
+void HTTPClient::begin(const char *url, const char * httpsFingerprint) {
+ begin(String(url), String(httpsFingerprint));
+}
+
+/**
+ * phasing the url for all needed informations
+ * @param url String
+ * @param httpsFingerprint String
+ */
+void HTTPClient::begin(String url, String httpsFingerprint) {
+
+ DEBUG_HTTPCLIENT("[HTTP-Client][begin] url: %s\n", url.c_str());
+
+ _httpsFingerprint = httpsFingerprint;
+ _returnCode = 0;
+ _size = -1;
+
+ _Headers = "";
+
+ String protocol;
+ // check for : (http: or https:
+ int index = url.indexOf(':');
+ int index2;
+ bool hasPort = false;
+ if(index) {
+ protocol = url.substring(0, index);
+ url.remove(0, (index + 3)); // remove http:// or https://
+
+ index = url.indexOf(':');
+ index2 = url.indexOf('/');
+
+ if(index >= 0 && ((index2 >= 0 && index < index2) || index2 == 0)) { // do we have a port?
+ _host = url.substring(0, index); // hostname
+ url.remove(0, (index + 1)); // remove hostname + :
+
+ index = url.indexOf('/');
+ _port = url.substring(0, index).toInt(); // get port
+ url.remove(0, index); // remove port
+ hasPort = true;
+ } else {
+ index = index2;
+ _host = url.substring(0, index);
+ url.remove(0, index); // remove hostname
+ }
+
+ _url = url;
+
+ if(protocol.equalsIgnoreCase("http")) {
+ _https = false;
+ if(!hasPort) {
+ _port = 80;
+ }
+ } else if(protocol.equalsIgnoreCase("https")) {
+ _https = true;
+ if(!hasPort) {
+ _port = 443;
+ }
+ } else {
+ DEBUG_HTTPCLIENT("[HTTP-Client][begin] protocol: %s unknown?!\n", protocol.c_str());
+ return;
+ }
+ }
+
+ DEBUG_HTTPCLIENT("[HTTP-Client][begin] host: %s port: %d url: %s https: %d httpsFingerprint: %s\n", _host.c_str(), _port, _url.c_str(), _https, _httpsFingerprint.c_str());
+
+}
+
+/**
+ * begin
+ * @param host const char *
+ * @param port uint16_t
+ * @param url const char *
+ * @param https bool
+ * @param httpsFingerprint const char *
+ */
+void HTTPClient::begin(const char *host, uint16_t port, const char * url, bool https, const char * httpsFingerprint) {
+
+ DEBUG_HTTPCLIENT("[HTTP-Client][begin] host: %s port:%d url: %s https: %d httpsFingerprint: %s\n", host, port, url, https, httpsFingerprint);
+
+ _host = host;
+ _port = port;
+ _url = url;
+ _https = https;
+ _httpsFingerprint = httpsFingerprint;
+
+ _returnCode = 0;
+ _size = -1;
+
+ _Headers = "";
+
+}
+
+void HTTPClient::begin(String host, uint16_t port, String url, bool https, String httpsFingerprint) {
+ begin(host.c_str(), port, url.c_str(), https, httpsFingerprint.c_str());
+}
+
+/**
+ * end
+ * called after the payload is handled
+ */
+void HTTPClient::end(void) {
+ if(connected()) {
+ if(_reuse && _canReuse) {
+ DEBUG_HTTPCLIENT("[HTTP-Client][end] tcp keep open for reuse\n");
+ } else {
+ DEBUG_HTTPCLIENT("[HTTP-Client][end] tcp stop\n");
+ _tcp->stop();
+ }
+ } else {
+ DEBUG_HTTPCLIENT("[HTTP-Client][end] tcp is closed\n");
+ }
+}
+
+/**
+ * connected
+ * @return connected status
+ */
+bool HTTPClient::connected() {
+ if(_tcp) {
+ return (_tcp->connected() || (_tcp->available() > 0));
+ }
+ return false;
+}
+
+/**
+ * try to reuse the connection to the server
+ * keep-alive
+ * @param reuse bool
+ */
+void HTTPClient::setReuse(bool reuse) {
+ _reuse = reuse;
+}
+
+/**
+ * set User Agent
+ * @param userAgent const char *
+ */
+void HTTPClient::setUserAgent(const char * userAgent) {
+ _userAgent = userAgent;
+}
+
+/**
+ * send a GET request
+ * @return http code
+ */
+int HTTPClient::GET() {
+ return sendRequest("GET");
+}
+
+/**
+ * sends a post request to the server
+ * @param payload uint8_t *
+ * @param size size_t
+ * @return http code
+ */
+int HTTPClient::POST(uint8_t * payload, size_t size) {
+ return sendRequest("POST", payload, size);
+}
+
+int HTTPClient::POST(String payload) {
+ return POST((uint8_t *) payload.c_str(), payload.length());
+}
+
+/**
+ * sendRequest
+ * @param type const char * "GET", "POST", ....
+ * @param payload uint8_t * data for the message body if null not send
+ * @param size size_t size for the message body if 0 not send
+ * @return -1 if no info or > 0 when Content-Length is set by server
+ */
+int HTTPClient::sendRequest(const char * type, uint8_t * payload, size_t size) {
+ // connect to server
+ if(!connect()) {
+ return HTTPC_ERROR_CONNECTION_REFUSED;
+ }
+
+ if(payload && size > 0) {
+ addHeader("Content-Length", String(size));
+ }
+
+ // send Header
+ if(!sendHeader(type)) {
+ return HTTPC_ERROR_SEND_HEADER_FAILED;
+ }
+
+ // send Payload if needed
+ if(payload && size > 0) {
+ if(_tcp->write(&payload[0], size) != size) {
+ return HTTPC_ERROR_SEND_PAYLOAD_FAILED;
+ }
+ }
+
+ // handle Server Response (Header)
+ return handleHeaderResponse();
+}
+
+/**
+ * sendRequest
+ * @param type const char * "GET", "POST", ....
+ * @param stream Stream * data stream for the message body
+ * @param size size_t size for the message body if 0 not Content-Length is send
+ * @return -1 if no info or > 0 when Content-Length is set by server
+ */
+int HTTPClient::sendRequest(const char * type, Stream * stream, size_t size) {
+
+ if(!stream) {
+ return HTTPC_ERROR_NO_STREAM;
+ }
+
+ // connect to server
+ if(!connect()) {
+ return HTTPC_ERROR_CONNECTION_REFUSED;
+ }
+
+ if(size > 0) {
+ addHeader("Content-Length", String(size));
+ }
+
+ // send Header
+ if(!sendHeader(type)) {
+ return HTTPC_ERROR_SEND_HEADER_FAILED;
+ }
+
+ // create buffer for read
+ uint8_t buff[1460] = { 0 };
+
+ int len = size;
+ int bytesWritten = 0;
+
+ if(len == 0) {
+ len = -1;
+ }
+
+ // read all data from stream and send it to server
+ while(connected() && stream->available() && (len > 0 || len == -1)) {
+
+ // get available data size
+ size_t s = stream->available();
+
+ if(s) {
+ int c = stream->readBytes(buff, ((s > sizeof(buff)) ? sizeof(buff) : s));
+
+ // write it to Stream
+ bytesWritten += _tcp->write((const uint8_t *)buff, c);
+
+ if(len > 0) {
+ len -= c;
+ }
+
+ delay(0);
+ } else {
+ delay(1);
+ }
+ }
+
+ if(size && (int)size != bytesWritten) {
+ DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] Stream payload bytesWritten %d and size %d mismatch!.\n", bytesWritten, _size);
+ DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] ERROR SEND PAYLOAD FAILED!");
+ return HTTPC_ERROR_SEND_PAYLOAD_FAILED;
+ } else {
+ DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] Stream payload written: %d\n", bytesWritten);
+ }
+
+ // handle Server Response (Header)
+ return handleHeaderResponse();
+}
+
+/**
+ * size of message body / payload
+ * @return -1 if no info or > 0 when Content-Length is set by server
+ */
+int HTTPClient::getSize(void) {
+ return _size;
+}
+
+/**
+ * deprecated Note: this is not working with https!
+ * returns the stream of the tcp connection
+ * @return WiFiClient
+ */
+WiFiClient & HTTPClient::getStream(void) {
+ if(connected()) {
+ return *_tcp;
+ }
+
+ DEBUG_HTTPCLIENT("[HTTP-Client] no stream to return!?\n");
+
+ // todo return error?
+}
+
+/**
+ * returns the stream of the tcp connection
+ * @return WiFiClient *
+ */
+WiFiClient * HTTPClient::getStreamPtr(void) {
+ if(connected()) {
+ return _tcp;
+ }
+
+ DEBUG_HTTPCLIENT("[HTTP-Client] no stream to return!?\n");
+ return NULL;
+}
+
+/**
+ * write all message body / payload to Stream
+ * @param stream Stream *
+ * @return bytes written ( negative values are error codes )
+ */
+int HTTPClient::writeToStream(Stream * stream) {
+
+ if(!stream) {
+ return HTTPC_ERROR_NO_STREAM;
+ }
+
+ if(!connected()) {
+ return HTTPC_ERROR_NOT_CONNECTED;
+ }
+
+ // get length of document (is -1 when Server sends no Content-Length header)
+ int len = _size;
+ int bytesWritten = 0;
+
+ // create buffer for read
+ uint8_t buff[1460] = { 0 };
+
+ // read all data from server
+ while(connected() && (len > 0 || len == -1)) {
+
+ // get available data size
+ size_t size = _tcp->available();
+
+ if(size) {
+ int c = _tcp->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size));
+
+ // write it to Stream
+ bytesWritten += stream->write(buff, c);
+
+ if(len > 0) {
+ len -= c;
+ }
+
+ delay(0);
+ } else {
+ delay(1);
+ }
+ }
+
+ DEBUG_HTTPCLIENT("[HTTP-Client][writeToStream] connection closed or file end (written: %d).\n", bytesWritten);
+
+ if(_size && _size != bytesWritten) {
+ DEBUG_HTTPCLIENT("[HTTP-Client][writeToStream] bytesWritten %d and size %d mismatch!.\n", bytesWritten, _size);
+ }
+
+ end();
+ return bytesWritten;
+}
+
+/**
+ * return all payload as String (may need lot of ram or trigger out of memory!)
+ * @return String
+ */
+String HTTPClient::getString(void) {
+ StreamString sstring;
+
+ if(_size) {
+ // try to reserve needed memmory
+ if(!sstring.reserve((_size + 1))) {
+ DEBUG_HTTPCLIENT("[HTTP-Client][getString] too less memory to reserve as string! need: %d\n", (_size + 1));
+ return String("--too less memory--");
+ }
+ }
+
+ writeToStream(&sstring);
+ return sstring;
+}
+
+/**
+ * adds Header to the request
+ * @param name
+ * @param value
+ * @param first
+ */
+void HTTPClient::addHeader(const String& name, const String& value, bool first) {
+
+ // not allow set of Header handled by code
+ if(!name.equalsIgnoreCase("Connection") && !name.equalsIgnoreCase("User-Agent") && !name.equalsIgnoreCase("Host")) {
+ String headerLine = name;
+ headerLine += ": ";
+ headerLine += value;
+ headerLine += "\r\n";
+
+ if(first) {
+ _Headers = headerLine + _Headers;
+ } else {
+ _Headers += headerLine;
+ }
+ }
+
+}
+
+void HTTPClient::collectHeaders(const char* headerKeys[], const size_t headerKeysCount) {
+ _headerKeysCount = headerKeysCount;
+ if(_currentHeaders)
+ delete[] _currentHeaders;
+ _currentHeaders = new RequestArgument[_headerKeysCount];
+ for(size_t i = 0; i < _headerKeysCount; i++) {
+ _currentHeaders[i].key = headerKeys[i];
+ }
+}
+
+String HTTPClient::header(const char* name) {
+ for(size_t i = 0; i < _headerKeysCount; ++i) {
+ if(_currentHeaders[i].key == name)
+ return _currentHeaders[i].value;
+ }
+ return String();
+}
+
+String HTTPClient::header(size_t i) {
+ if(i < _headerKeysCount)
+ return _currentHeaders[i].value;
+ return String();
+}
+
+String HTTPClient::headerName(size_t i) {
+ if(i < _headerKeysCount)
+ return _currentHeaders[i].key;
+ return String();
+}
+
+int HTTPClient::headers() {
+ return _headerKeysCount;
+}
+
+bool HTTPClient::hasHeader(const char* name) {
+ for(size_t i = 0; i < _headerKeysCount; ++i) {
+ if((_currentHeaders[i].key == name) && (_currentHeaders[i].value.length() > 0))
+ return true;
+ }
+ return false;
+}
+
+/**
+ * init TCP connection and handle ssl verify if needed
+ * @return true if connection is ok
+ */
+bool HTTPClient::connect(void) {
+
+ if(connected()) {
+ DEBUG_HTTPCLIENT("[HTTP-Client] connect. already connected, try reuse!\n");
+ return true;
+ }
+
+ if(_https) {
+ DEBUG_HTTPCLIENT("[HTTP-Client] connect https...\n");
+ if(_tcps) {
+ delete _tcps;
+ _tcps = NULL;
+ _tcp = NULL;
+ }
+ _tcps = new WiFiClientSecure();
+ _tcp = _tcps;
+ } else {
+ DEBUG_HTTPCLIENT("[HTTP-Client] connect http...\n");
+ if(_tcp) {
+ delete _tcp;
+ _tcp = NULL;
+ }
+ _tcp = new WiFiClient();
+ }
+
+ if(!_tcp->connect(_host.c_str(), _port)) {
+ DEBUG_HTTPCLIENT("[HTTP-Client] failed connect to %s:%u\n", _host.c_str(), _port);
+ return false;
+ }
+
+ DEBUG_HTTPCLIENT("[HTTP-Client] connected to %s:%u\n", _host.c_str(), _port);
+
+ if(_https && _httpsFingerprint.length() > 0) {
+ if(_tcps->verify(_httpsFingerprint.c_str(), _host.c_str())) {
+ DEBUG_HTTPCLIENT("[HTTP-Client] https certificate matches\n");
+ } else {
+ DEBUG_HTTPCLIENT("[HTTP-Client] https certificate doesn't match!\n");
+ _tcp->stop();
+ return false;
+ }
+ }
+
+ // set Timeout for readBytesUntil and readStringUntil
+ _tcp->setTimeout(HTTPCLIENT_TCP_TIMEOUT);
+
+#ifdef ESP8266
+ _tcp->setNoDelay(true);
+#endif
+ return connected();
+}
+
+/**
+ * sends HTTP request header
+ * @param type (GET, POST, ...)
+ * @return status
+ */
+bool HTTPClient::sendHeader(const char * type) {
+ if(!connected()) {
+ return false;
+ }
+
+ String header = String(type) + " " + _url + " HTTP/1.1\r\n"
+ "Host: " + _host + "\r\n"
+ "User-Agent: " + _userAgent + "\r\n"
+ "Connection: ";
+
+ if(_reuse) {
+ header += "keep-alive";
+ } else {
+ header += "close";
+ }
+ header += "\r\n" + _Headers + "\r\n";
+
+ return (_tcp->write(header.c_str(), header.length()) == header.length());
+}
+
+/**
+ * reads the response from the server
+ * @return int http code
+ */
+int HTTPClient::handleHeaderResponse() {
+
+ if(!connected()) {
+ return HTTPC_ERROR_NOT_CONNECTED;
+ }
+
+ _returnCode = -1;
+ _size = -1;
+
+ while(connected()) {
+ size_t len = _tcp->available();
+ if(len > 0) {
+ String headerLine = _tcp->readStringUntil('\n');
+ headerLine.trim(); // remove \r
+
+ DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] RX: '%s'\n", headerLine.c_str());
+
+ if(headerLine.startsWith("HTTP/1.")) {
+ _returnCode = headerLine.substring(9, headerLine.indexOf(' ', 9)).toInt();
+ } else if(headerLine.indexOf(':')) {
+ String headerName = headerLine.substring(0, headerLine.indexOf(':'));
+ String headerValue = headerLine.substring(headerLine.indexOf(':') + 2);
+
+ if(headerName.equalsIgnoreCase("Content-Length")) {
+ _size = headerValue.toInt();
+ }
+
+ if(headerName.equalsIgnoreCase("Connection")) {
+ _canReuse = headerValue.equalsIgnoreCase("keep-alive");
+ }
+
+ for(size_t i = 0; i < _headerKeysCount; i++) {
+ if(_currentHeaders[i].key.equalsIgnoreCase(headerName)) {
+ _currentHeaders[i].value = headerValue;
+ break;
+ }
+ }
+ }
+
+ if(headerLine == "") {
+ DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] code: %d\n", _returnCode);
+ if(_size) {
+ DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] size: %d\n", _size);
+ }
+ if(_returnCode) {
+ return _returnCode;
+ } else {
+ DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] Remote host is not an HTTP Server!");
+ return HTTPC_ERROR_NO_HTTP_SERVER;
+ }
+ }
+
+ } else {
+ delay(0);
+ }
+ }
+
+ return HTTPC_ERROR_CONNECTION_LOST;
+}
diff --git a/libraries/ESP8266httpClient/src/ESP8266httpClient.h b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h
similarity index 90%
rename from libraries/ESP8266httpClient/src/ESP8266httpClient.h
rename to libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h
index 7fad644e4..2d1312a29 100644
--- a/libraries/ESP8266httpClient/src/ESP8266httpClient.h
+++ b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h
@@ -1,129 +1,129 @@
-/**
- * ESP8266httpClient.h
- *
- * Created on: 02.11.2015
- *
- * Copyright (c) 2015 Markus Sattler. All rights reserved.
- * This file is part of the ESP8266httpClient for Arduino.
- *
- * 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 ESP8266HTTPCLIENT_H_
-#define ESP8266HTTPCLIENT_H_
-
-//#define DEBUG_HTTPCLIENT(...) Serial1.printf( __VA_ARGS__ )
-
-#ifndef DEBUG_HTTPCLIENT
-#define DEBUG_HTTPCLIENT(...)
-#endif
-
-#define HTTPCLIENT_TCP_TIMEOUT (1000)
-
-/// HTTP client errors
-#define HTTPC_ERROR_CONNECTION_REFUSED (-1)
-#define HTTPC_ERROR_SEND_HEADER_FAILED (-2)
-#define HTTPC_ERROR_SEND_PAYLOAD_FAILED (-3)
-#define HTTPC_ERROR_NOT_CONNECTED (-4)
-#define HTTPC_ERROR_CONNECTION_LOST (-5)
-#define HTTPC_ERROR_NO_STREAM (-6)
-#define HTTPC_ERROR_NO_HTTP_SERVER (-7)
-
-
-class httpClient {
- public:
- httpClient();
- ~httpClient();
-
- void begin(const char *url, const char * httpsFingerprint = "");
- void begin(String url, String httpsFingerprint = "");
-
- void begin(const char *host, uint16_t port, const char * url = "/", bool https = false, const char * httpsFingerprint = "");
- void begin(String host, uint16_t port, String url = "/", bool https = false, String httpsFingerprint = "");
-
- void end(void);
-
- bool connected(void);
-
- void setReuse(bool reuse); /// keep-alive
- void setUserAgent(const char * userAgent);
-
- /// request handling
- int GET();
- int POST(uint8_t * payload, size_t size);
- int POST(String payload);
- int sendRequest(const char * type, uint8_t * payload = NULL, size_t size = 0);
- int sendRequest(const char * type, Stream * stream, size_t size = 0);
-
- void addHeader(const String& name, const String& value, bool first = false);
-
- /// Response handling
- void collectHeaders(const char* headerKeys[], const size_t headerKeysCount);
- String header(const char* name); // get request header value by name
- String header(size_t i); // get request header value by number
- String headerName(size_t i); // get request header name by number
- int headers(); // get header count
- bool hasHeader(const char* name); // check if header exists
-
-
- int getSize(void);
-
- WiFiClient & getStream(void) __attribute__ ((deprecated)) ;
- WiFiClient * getStreamPtr(void);
- int writeToStream(Stream * stream);
- String getString(void);
-
- protected:
-
- struct RequestArgument {
- String key;
- String value;
- };
-
-
- WiFiClient * _tcp;
- WiFiClientSecure * _tcps;
-
- /// request handling
- String _host;
- uint16_t _port;
- bool _reuse;
-
-
- String _url;
- bool _https;
- String _httpsFingerprint;
-
- String _Headers;
- String _userAgent;
-
- /// Response handling
- RequestArgument* _currentHeaders;
- size_t _headerKeysCount;
-
- int _returnCode;
- int _size;
- bool _canReuse;
-
- bool connect(void);
- bool sendHeader(const char * type);
- int handleHeaderResponse();
-
-};
-
-
-
-#endif /* ESP8266HTTPCLIENT_H_ */
+/**
+ * ESP8266HTTPClient.h
+ *
+ * Created on: 02.11.2015
+ *
+ * Copyright (c) 2015 Markus Sattler. All rights reserved.
+ * This file is part of the ESP8266HTTPClient for Arduino.
+ *
+ * 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 ESP8266HTTPClient_H_
+#define ESP8266HTTPClient_H_
+
+//#define DEBUG_HTTPCLIENT(...) Serial1.printf( __VA_ARGS__ )
+
+#ifndef DEBUG_HTTPCLIENT
+#define DEBUG_HTTPCLIENT(...)
+#endif
+
+#define HTTPCLIENT_TCP_TIMEOUT (1000)
+
+/// HTTP client errors
+#define HTTPC_ERROR_CONNECTION_REFUSED (-1)
+#define HTTPC_ERROR_SEND_HEADER_FAILED (-2)
+#define HTTPC_ERROR_SEND_PAYLOAD_FAILED (-3)
+#define HTTPC_ERROR_NOT_CONNECTED (-4)
+#define HTTPC_ERROR_CONNECTION_LOST (-5)
+#define HTTPC_ERROR_NO_STREAM (-6)
+#define HTTPC_ERROR_NO_HTTP_SERVER (-7)
+
+
+class HTTPClient {
+ public:
+ HTTPClient();
+ ~HTTPClient();
+
+ void begin(const char *url, const char * httpsFingerprint = "");
+ void begin(String url, String httpsFingerprint = "");
+
+ void begin(const char *host, uint16_t port, const char * url = "/", bool https = false, const char * httpsFingerprint = "");
+ void begin(String host, uint16_t port, String url = "/", bool https = false, String httpsFingerprint = "");
+
+ void end(void);
+
+ bool connected(void);
+
+ void setReuse(bool reuse); /// keep-alive
+ void setUserAgent(const char * userAgent);
+
+ /// request handling
+ int GET();
+ int POST(uint8_t * payload, size_t size);
+ int POST(String payload);
+ int sendRequest(const char * type, uint8_t * payload = NULL, size_t size = 0);
+ int sendRequest(const char * type, Stream * stream, size_t size = 0);
+
+ void addHeader(const String& name, const String& value, bool first = false);
+
+ /// Response handling
+ void collectHeaders(const char* headerKeys[], const size_t headerKeysCount);
+ String header(const char* name); // get request header value by name
+ String header(size_t i); // get request header value by number
+ String headerName(size_t i); // get request header name by number
+ int headers(); // get header count
+ bool hasHeader(const char* name); // check if header exists
+
+
+ int getSize(void);
+
+ WiFiClient & getStream(void) __attribute__ ((deprecated)) ;
+ WiFiClient * getStreamPtr(void);
+ int writeToStream(Stream * stream);
+ String getString(void);
+
+ protected:
+
+ struct RequestArgument {
+ String key;
+ String value;
+ };
+
+
+ WiFiClient * _tcp;
+ WiFiClientSecure * _tcps;
+
+ /// request handling
+ String _host;
+ uint16_t _port;
+ bool _reuse;
+
+
+ String _url;
+ bool _https;
+ String _httpsFingerprint;
+
+ String _Headers;
+ String _userAgent;
+
+ /// Response handling
+ RequestArgument* _currentHeaders;
+ size_t _headerKeysCount;
+
+ int _returnCode;
+ int _size;
+ bool _canReuse;
+
+ bool connect(void);
+ bool sendHeader(const char * type);
+ int handleHeaderResponse();
+
+};
+
+
+
+#endif /* ESP8266HTTPClient_H_ */
diff --git a/libraries/ESP8266WebServer/examples/HttpBasicAuth/HttpBasicAuth.ino b/libraries/ESP8266WebServer/examples/HttpBasicAuth/HttpBasicAuth.ino
new file mode 100644
index 000000000..4a68478eb
--- /dev/null
+++ b/libraries/ESP8266WebServer/examples/HttpBasicAuth/HttpBasicAuth.ino
@@ -0,0 +1,40 @@
+#include
+#include
+#include
+#include
+
+const char* ssid = "........";
+const char* password = "........";
+
+ESP8266WebServer server(80);
+
+const char* www_username = "admin";
+const char* www_password = "esp8266";
+
+void setup() {
+ Serial.begin(115200);
+ WiFi.mode(WIFI_STA);
+ WiFi.begin(ssid, password);
+ if(WiFi.waitForConnectResult() != WL_CONNECTED) {
+ Serial.println("WiFi Connect Failed! Rebooting...");
+ delay(1000);
+ ESP.restart();
+ }
+ ArduinoOTA.begin();
+
+ server.on("/", [](){
+ if(!server.authenticate(www_username, www_password))
+ return server.requestAuthentication();
+ server.send(200, "text/plain", "Login OK");
+ });
+ server.begin();
+
+ Serial.print("Open http://");
+ Serial.print(WiFi.localIP());
+ Serial.println("/ in your browser to see it working");
+}
+
+void loop() {
+ ArduinoOTA.handle();
+ server.handleClient();
+}
diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp b/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp
index fbc23016f..cecc8eabc 100644
--- a/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp
+++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp
@@ -22,6 +22,7 @@
#include
+#include
#include "WiFiServer.h"
#include "WiFiClient.h"
#include "ESP8266WebServer.h"
@@ -30,6 +31,7 @@
// #define DEBUG
#define DEBUG_OUTPUT Serial
+const char * AUTHORIZATION_HEADER = "Authorization";
ESP8266WebServer::ESP8266WebServer(IPAddress addr, int port)
: _server(addr, port)
@@ -73,6 +75,46 @@ ESP8266WebServer::~ESP8266WebServer() {
void ESP8266WebServer::begin() {
_server.begin();
+ if(!_headerKeysCount)
+ collectHeaders(0, 0);
+}
+
+bool ESP8266WebServer::authenticate(const char * username, const char * password){
+ if(hasHeader(AUTHORIZATION_HEADER)){
+ String authReq = header(AUTHORIZATION_HEADER);
+ if(authReq.startsWith("Basic")){
+ authReq = authReq.substring(6);
+ authReq.trim();
+ char toencodeLen = strlen(username)+strlen(password)+1;
+ char *toencode = new char[toencodeLen];
+ if(toencode == NULL){
+ authReq = String();
+ return false;
+ }
+ char *encoded = new char[base64_encode_expected_len(toencodeLen)+1];
+ if(encoded == NULL){
+ authReq = String();
+ delete[] toencode;
+ return false;
+ }
+ sprintf(toencode, "%s:%s", username, password);
+ if(base64_encode_chars(toencode, toencodeLen, encoded) > 0 && authReq.equals(encoded)){
+ authReq = String();
+ delete[] toencode;
+ delete[] encoded;
+ return true;
+ }
+ delete[] toencode;
+ delete[] encoded;
+ }
+ authReq = String();
+ }
+ return false;
+}
+
+void ESP8266WebServer::requestAuthentication(){
+ sendHeader("WWW-Authenticate", "Basic realm=\"Login Required\"");
+ send(401);
}
void ESP8266WebServer::on(const char* uri, ESP8266WebServer::THandlerFunction handler) {
@@ -316,12 +358,13 @@ String ESP8266WebServer::header(const char* name) {
}
void ESP8266WebServer::collectHeaders(const char* headerKeys[], const size_t headerKeysCount) {
- _headerKeysCount = headerKeysCount;
+ _headerKeysCount = headerKeysCount + 1;
if (_currentHeaders)
delete[]_currentHeaders;
_currentHeaders = new RequestArgument[_headerKeysCount];
- for (int i = 0; i < _headerKeysCount; i++){
- _currentHeaders[i].key = headerKeys[i];
+ _currentHeaders[0].key = AUTHORIZATION_HEADER;
+ for (int i = 1; i < _headerKeysCount; i++){
+ _currentHeaders[i].key = headerKeys[i-1];
}
}
@@ -362,19 +405,28 @@ void ESP8266WebServer::onNotFound(THandlerFunction fn) {
}
void ESP8266WebServer::_handleRequest() {
+ bool handled = false;
if (!_currentHandler){
#ifdef DEBUG
DEBUG_OUTPUT.println("request handler not found");
#endif
+ }
+ else {
+ handled = _currentHandler->handle(*this, _currentMethod, _currentUri);
+#ifdef DEBUG
+ if (!handled) {
+ DEBUG_OUTPUT.println("request handler failed to handle request");
+ }
+#endif
+ }
+ if (!handled) {
if(_notFoundHandler) {
_notFoundHandler();
}
else {
send(404, "text/plain", String("Not found: ") + _currentUri);
}
- } else {
- _currentHandler->handle(*this, _currentMethod, _currentUri);
}
uint16_t maxWait = HTTP_MAX_CLOSE_WAIT;
diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.h b/libraries/ESP8266WebServer/src/ESP8266WebServer.h
index 35287f307..40172e92a 100644
--- a/libraries/ESP8266WebServer/src/ESP8266WebServer.h
+++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.h
@@ -65,7 +65,10 @@ public:
void begin();
void handleClient();
-
+
+ bool authenticate(const char * username, const char * password);
+ void requestAuthentication();
+
typedef std::function THandlerFunction;
void on(const char* uri, THandlerFunction handler);
void on(const char* uri, HTTPMethod method, THandlerFunction fn);
diff --git a/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h b/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h
index ae94b259f..b808607e5 100644
--- a/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h
+++ b/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h
@@ -60,7 +60,7 @@ public:
{
_isFile = fs.exists(path);
DEBUGV("StaticRequestHandler: path=%s uri=%s isFile=%d, cache_header=%s\r\n", path, uri, _isFile, cache_header);
- _baseUriLength = _uri.length();
+ _baseUriLength = _uri.length();
}
bool canHandle(HTTPMethod requestMethod, String requestUri) override {
@@ -75,28 +75,29 @@ public:
bool handle(ESP8266WebServer& server, HTTPMethod requestMethod, String requestUri) override {
if (!canHandle(requestMethod, requestUri))
- return false;
-
+ return false;
+
DEBUGV("StaticRequestHandler::handle: request=%s _uri=%s\r\n", requestUri.c_str(), _uri.c_str());
- String path(_path);
+ String path(_path);
- if(path.endsWith("/")) path += "index.htm";
+ if (!_isFile) {
+ // Base URI doesn't point to a file.
+ // If a directory is requested, look for index file.
+ if (requestUri.endsWith("/")) requestUri += "index.htm";
- if (!_isFile) {
- // Base URI doesn't point to a file. Append whatever follows this
- // URI in request to get the file path.
- path += requestUri.substring(_baseUriLength);
+ // Append whatever follows this URI in request to get the file path.
+ path += requestUri.substring(_baseUriLength);
}
DEBUGV("StaticRequestHandler::handle: path=%s, isFile=%d\r\n", path.c_str(), _isFile);
String contentType = getContentType(path);
-
+
// look for gz file, only if the original specified path is not a gz. So part only works to send gzip via content encoding when a non compressed is asked for
- // if you point the the path to gzip you will serve the gzip as content type "application/x-gzip", not text or javascript etc...
- if (!path.endsWith(".gz") && !SPIFFS.exists(path)) {
+ // if you point the the path to gzip you will serve the gzip as content type "application/x-gzip", not text or javascript etc...
+ if (!path.endsWith(".gz") && !_fs.exists(path)) {
String pathWithGz = path + ".gz";
- if(SPIFFS.exists(pathWithGz))
+ if(_fs.exists(pathWithGz))
path += ".gz";
}
@@ -104,9 +105,9 @@ public:
if (!f)
return false;
- if (_cache_header.length() != 0)
+ if (_cache_header.length() != 0)
server.sendHeader("Cache-Control", _cache_header);
-
+
server.streamFile(f, contentType);
return true;
}
@@ -133,7 +134,7 @@ protected:
FS _fs;
String _uri;
String _path;
- String _cache_header;
+ String _cache_header;
bool _isFile;
size_t _baseUriLength;
};
diff --git a/libraries/ESP8266httpUpdate/examples/httpUpdate/httpUpdate.ino b/libraries/ESP8266httpUpdate/examples/httpUpdate/httpUpdate.ino
index 99e99c86b..bc9160a6e 100644
--- a/libraries/ESP8266httpUpdate/examples/httpUpdate/httpUpdate.ino
+++ b/libraries/ESP8266httpUpdate/examples/httpUpdate/httpUpdate.ino
@@ -10,7 +10,7 @@
#include
#include
-#include
+#include
#include
#define USE_SERIAL Serial
diff --git a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp
index fb0572417..39ba0555c 100644
--- a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp
+++ b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp
@@ -41,7 +41,7 @@ ESP8266HTTPUpdate::~ESP8266HTTPUpdate(void) {
* @return t_httpUpdate_return
*/
t_httpUpdate_return ESP8266HTTPUpdate::update(const char * url, const char * current_version, const char * httpsFingerprint) {
- httpClient http;
+ HTTPClient http;
http.begin(url, httpsFingerprint);
return handleUpdate(&http, current_version);
}
@@ -56,24 +56,24 @@ t_httpUpdate_return ESP8266HTTPUpdate::update(const char * url, const char * cur
* @return
*/
t_httpUpdate_return ESP8266HTTPUpdate::update(const char * host, uint16_t port, const char * url, const char * current_version, bool https, const char * httpsFingerprint) {
- httpClient http;
+ HTTPClient http;
http.begin(host, port, url, https, httpsFingerprint);
return handleUpdate(&http, current_version);
}
t_httpUpdate_return ESP8266HTTPUpdate::update(String host, uint16_t port, String url, String current_version, bool https, String httpsFingerprint) {
- httpClient http;
+ HTTPClient http;
http.begin(host, port, url, https, httpsFingerprint);
return handleUpdate(&http, current_version.c_str());
}
/**
*
- * @param http httpClient *
+ * @param http HTTPClient *
* @param current_version const char *
* @return t_httpUpdate_return
*/
-t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(httpClient * http, const char * current_version) {
+t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const char * current_version) {
t_httpUpdate_return ret = HTTP_UPDATE_FAILED;
diff --git a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h
index 406d8de3f..a494695ff 100644
--- a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h
+++ b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h
@@ -30,7 +30,7 @@
#include
#include
#include
-#include
+#include
//#define DEBUG_HTTP_UPDATE(...) Serial1.printf( __VA_ARGS__ )
@@ -54,7 +54,7 @@ class ESP8266HTTPUpdate {
t_httpUpdate_return update(String host, uint16_t port, String url = "/", String current_version = "", bool https = false, String httpsFingerprint = "");
protected:
- t_httpUpdate_return handleUpdate(httpClient * http, const char * current_version);
+ t_httpUpdate_return handleUpdate(HTTPClient * http, const char * current_version);
bool runUpdate(Stream& in, uint32_t size, String md5);
};
diff --git a/tools/sdk/lib/libaxtls.a b/tools/sdk/lib/libaxtls.a
index e8c08dc1e..b74d97cc4 100644
Binary files a/tools/sdk/lib/libaxtls.a and b/tools/sdk/lib/libaxtls.a differ