Giter Site home page Giter Site logo

espasyncwebserver's Issues

Feature Request: make full use of lwip's buffer size

Just for completeness, I'd like to request a feature to make AsyncServer better integrate with lwIP's stack functionality. Web browsers will immediately close a connection as soon as Content-Length bytes have been received.

Can we have AsyncServer send as much data as lwip tcp_snd_buf has currently room? Currently, the HTTP header is sent as separate packet, delaying Windows' ACK for this:
image
Also in the image above, the last two packets should have been sent in one go without waiting for the ACK... It would be very nice to have this for performance reasons since now a transfer takes 0.5s (with my setting and 5k HTML data) to Windows clients, which we could easily get down to under 100ms.

example needed for TLS

Do you have an example TLS with cer.cert and k.key are uploaded memory (with/without password) ?

serveStatic("/" ...) results in HTTP 500

readme.md says:

  // attach filesystem root at URL /fs 
  server.serveStatic("/fs", SPIFFS, "/");

I wanted to serve the root uri from /html/ on SPIFFS, so I used
server.serveStatic("/", SPIFFS, "/html/");
but this results in HTTP 500. The following syntax works though:
server.serveStatic("", SPIFFS, "/html/");

Latest Commit: 501 error...

Hmm, pulled to latest c95ac73, it compiles, but on request GET / I get a 501 Not Implemented error. I start the server like so:

AsyncWebServer webserver(80);
webserver.on("/", HTTP_GET, webserver_handleRoot);
webserver.onNotFound(webserver_handleNotFound);
webserver.begin();

void webserver_handleRoot(AsyncWebServerRequest *request) { /* ... */ }
void webserver_handleNotFound(AsyncWebServerRequest *request) { /* ... */ }

Update firmware over the FILE Upload handling.

I have a problem with updating firmware from AsyncWebServer.

void setup(){
    server.on("/upload", HTTP_POST, [](AsyncWebServerRequest *request){
        request->send(200);
    }, handleUpload);   
    server.begin();     
}
void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){
    //Handle upload 
        Serial1.println("----UPLOAD-----"); 
        Serial1.print("FILENAME: ");
        Serial1.println(filename);
            Serial1.print("INDEX: ");
            Serial1.println(index);
        Serial1.print("LENGTH: ");
        Serial1.println(len);   
        AsyncWebHeader *header = request->getHeader("X-File-Size");
        Serial1.print("File size: ");
        Serial1.println((size_t)header->value().toFloat());
        if (!Update.isRunning())
        {
            Serial1.print("Status Update.begin(): ");
            Serial1.println(Update.begin((size_t)header->value().toFloat()));
            Serial1.print("Update remaining: ");
            Serial1.println(Update.remaining());
        }
        else
        {
            Serial1.println("Status Update.begin(): RUNNING");
        }       

    Serial1.print("FLASH BYTES: ");
    ESP.wdtDisable();
    Serial1.println(Update.write(data, len));       
        Serial1.print("Update remaining: ");
    Serial1.println(Update.remaining());
    ESP.wdtEnable(10);  
    Serial1.print("HEAP: ");
    Serial1.println(ESP.getFreeHeap());
    if (final)
    {
        Update.end();
        Serial1.print("----FINAL-----");
    }   
}

In Serial I received:

----UPLOAD-----
FILENAME: AsyncWebModbusRTU.ino.bin
INDEX: 0
LENGTH: 1291
File size: 313696
Status Update.begin(): 1
Update remaining: 313696
FLASH BYTES: 1291
Update remaining: 313696
HEAP: 23816
----UPLOAD-----
FILENAME: AsyncWebModbusRTU.ino.bin
INDEX: 1291
LENGTH: 1460
File size: 313696
Status Update.begin(): RUNNING
FLASH BYTES: 1460
Update remaining: 313696
HEAP: 23816
----UPLOAD-----
FILENAME: AsyncWebModbusRTU.ino.bin
INDEX: 2751
LENGTH: 1460
File size: 313696
Status Update.begin(): RUNNING
FLASH BYTES: 
 ets Jan  8 2013,rst cause:4, boot mode:(1,6)

wdt reset

Is there some kind of solution to this problem?

PROGMEM expamle with binary array

Example code here: http://www.pastebin.ca/3595833

When using the PROGMEM example, it works great when the PROGMEM variable is declared like:
const char DataText[] PROGMEM = R"=====(Blah blah Blah)=====";

I have had no issue with it for data over 100Kb.

If however the PROGMEM variable lie like this:
const char power_png[] PROGMEM = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0xc8 }
the example fails because strlen_P always returns 9

If I replace the strlen_P with sizeof, it will work some times, but take 5-7minutes to transfer.

Is there a way to be able to use PROGMEM arrays for binary data?

code structure

During debugging I kept being confused by AsyncWebServerHandlerImpl ws WebHandlers, the sooner only containing static and callback handlers. Wouldn't it make sense to move those to the same file?

Tiny request for documentation: how to return a large PROGMEM char*?

Hi, I'm fiddeling with your work again, and while all the dynamic content works very well, my index.html is a 5k html inside a PROGMEM char[] ="...";. How do I send this in the response?

I don't want to put this into SPIFFS, since user may reformat FS and everything would be gone. Therefore this content goes into flash...

I've thought of a stream, but have not found a way to create a stream from a progmem variable. Then I thought of a callback which reads chunks of the data, but I find myself unable to save the last index I read from (bear in mind: several clients can request index at the same time. How do i elegeantly keep track of each request?)

Could you add an example of how to stream a large progmem content? Thanks.

sync connectin with GPRS

hi @me-no-dev ,sorry for trigger issue here but actually , I'm trying to establish websocketclient from GPRS connection to update remote website data, unfortunately Markus not available today's , and that's why I put my problem here, I find only this code in this github , which is no suitable for my module (SIM800L), you may know we only have AT command to control the GSM module whereas I found only one command to change HTTP parameters (AT+HTTPPARA="CONTENT",), is it possible to run websocket connection with just this command?
can you guide me to write the simple websocket client ?

thanks

WS2812B RGB LED with NeoPixelBus Animation now flickering

Hi @me-no-dev
I've just migrated my project to AsyncLib, all is working fine and it's fast. I've got one question, I had some WS2812B led breathing and it was working fine with the classic WebServer (no async) but with the async version, LED are flickering, of course I understand Async does job under the hood but is there any option to slow down this kind of network "loop task" ? I just would like testing to see if it's due to some timing problem since these LED are very stric on this point.

By the way since we do nothing in loop nor call to async, how the TCP stuff is handled (interrupts, timer, ...), just curious ?

esp8266 web server ( reading the content of web server )

I make web server on my esp8266 all i want is to read the content of this web server
i make my web server with this line of code and send to it some html and javascript
this line of HTML code i send with wifi module <div id = "dir">stop
now I need to read the content of my web page and see what in this div I am noob with this module :D

Web Server crashed

Hi,
I started Http calls continuously from an android and I see that when simultaneous calls are made esp8266 crashes. Here is the crash log

Exception (29):
epc1=0x402057fc epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

ctx: sys 
sp: 3ffff8a0 end: 3fffffb0 offset: 01a0

>>>stack>>>
3ffffa40:  00000010 3fffbd88 3fffbd88 3ffe8548  
3ffffa50:  00000020 000000c8 00000000 40206b0c  
3ffffa60:  3fffbfac 00000010 3ffffabc 40206b5b  
3ffffa70:  000005b4 00000000 3ffffabc 3ffe8548  
3ffffa80:  3ffffab0 000000c8 3ffffae0 401004d8  
3ffffa90:  3fffbf24 00000076 3ffffae0 3ffe8548  
3ffffaa0:  3ffffbd8 000000c8 00000000 40204162  
3ffffab0:  00000000 00000000 00000000 3fffbfd4  
3ffffac0:  0000001f 00000010 3fffb964 40206c78  
3ffffad0:  3fffb964 000000c8 3fffb964 402041d5  
3ffffae0:  00000000 00000000 00000000 3fffbfac  
3ffffaf0:  0000001f 00000010 3ffffbfc 402023f6  
3ffffb00:  3fffb964 3ffffbd8 3fffbdf8 402026c7  
3ffffb10:  7473227b 73757461 73223a22 65636375  
3ffffb20:  2c227373 6d616e22 223a2265 6d6f7441  
3ffffb30:  33312d38 33313338 2c223732 69777322  
3ffffb40:  5f686374 74617473 3a227375 7773227b  
3ffffb50:  68637469 223a2230 222c2230 74697773  
3ffffb60:  22316863 2230223a 7773222c 68637469  
3ffffb70:  223a2232 222c2230 74697773 22336863  
3ffffb80:  2230223a 00007d7d 00000002 40101c72  
3ffffb90:  40104f34 3fff1414 3ffed930 3ffef0ec  
3ffffba0:  00000010 3ffffc88 00000000 4010053d  
3ffffbb0:  00000010 3ffffc94 00000000 3ffef0ec  
3ffffbc0:  00000010 3ffffc50 00000000 4010053d  
3ffffbd0:  00000010 3ffffc88 3fffbf24 0000007f  
3ffffbe0:  00000076 000000c7 00000076 3ffe8548  
3ffffbf0:  00000010 3fffbdec 00000200 3fffbefc  
3ffffc00:  0000001f 00000010 3ffffc50 0000001f  
3ffffc10:  000000c8 3ffffc70 3ffffc70 40206b0c  
3ffffc20:  3ffe8cd8 00000000 3ffffc70 00000002  
3ffffc30:  00000002 3fffb964 3fffb964 40207554  
3ffffc40:  3fffb978 3fffbcb4 3ffffc70 40205b49  
3ffffc50:  3ffe8cd8 3fffbcb4 3fffb978 40206aac  
3ffffc60:  3fffb978 3fff923c 3fffb978 40206d2d  
3ffffc70:  00000000 3ffea7e7 3fffb964 40204580  
3ffffc80:  00000002 3ffea7e7 3fffb978 40206d90  
3ffffc90:  3ffea7e7 00000000 00000000 00000002  
3ffffca0:  00000002 3ffea7e7 3fffb964 40204974  
3ffffcb0:  3fffb978 3fff923c 3fffb978 0000001f  
3ffffcc0:  00000021 3ffea7c8 3fffb964 402045b6  
3ffffcd0:  3fffb978 3ffea7c8 3fffb978 40206d90  
3ffffce0:  3ffea7c8 00000000 00000000 0000001f  
3ffffcf0:  00000021 3ffea7c8 3fffb964 402047a8  
3ffffd00:  3fffb978 3fff923c 3fffb978 00000036  
3ffffd10:  00000057 3ffea792 3fffb964 402045b6  
3ffffd20:  3fffb978 3ffea792 3fffb978 40206d90  
3ffffd30:  3ffea792 00000000 00000000 00000036  
3ffffd40:  00000057 3ffea792 3fffb964 402047a8  
3ffffd50:  3fffb978 00000001 3fffb978 00000018  
3ffffd60:  0000006f 3ffea77a 3fffb964 402045b6  
3ffffd70:  3fffb978 3ffea77a 3fffb978 40206d90  
3ffffd80:  3ffea77a 00000000 00000000 00000018  
3ffffd90:  0000006f 3ffea77a 3fffb964 402047a8  
3ffffda0:  3ffe8cd8 3fffb978 3fffb978 00000013  
3ffffdb0:  00000082 3ffea767 3fffb964 402045b6  
3ffffdc0:  3fffb978 3ffea767 3fffb978 40206d90  
3ffffdd0:  3ffea767 00000000 00000000 00000013  
3ffffde0:  00000082 3ffea767 3fffb964 402047a8  
3ffffdf0:  3ffe8cd8 3fffb964 3fffb978 00000015  
3ffffe00:  00000097 3ffea752 3fffb964 4020452d  
3ffffe10:  3fffb978 3ffea752 3fffb978 40206d90  
3ffffe20:  3ffea752 3ffed270 3fffb928 00000015  
3ffffe30:  00000097 3ffea752 3fffb964 402047a8  
3ffffe40:  3ffea06c 00000000 00000000 4010068c  
3ffffe50:  00000000 09ce2c9c 40102f52 00000100  
3ffffe60:  3fffb978 3ffea06c 3ffea06c 00000001  
3ffffe70:  00000001 00007fff 000004f8 3fffb900  
3ffffe80:  00000001 3fff31d4 3fffb8ac 402049a1  
3ffffe90:  3fffc278 40102cec 3fffb8ac 40202e10  
3ffffea0:  3fff9e9c 3ffeefbc 3fff9e9c 40225cf9  
3ffffeb0:  3fff09fc 3fff0a08 00000006 3fff0810  
3ffffec0:  3fff9e9c 3fff0818 3fff0814 40202e63  
3ffffed0:  3fff9e9c 3fff0818 3fff0814 4022b460  
3ffffee0:  00000097 0501a8c0 00000018 00000097  
3ffffef0:  00000018 00000000 3ffef1cc 40107304  
3fffff00:  40100000 00000000 00000064 3fff0a00  
3fffff10:  3ffea72a 3fff0a08 3fff31d4 40229969  
3fffff20:  3fff0724 3fff127c 3fff127c 3ffee390  
3fffff30:  00000000 3fff31d4 0000001c 3fff127c  
3fffff40:  3ffea71c 00000000 3fff31d4 40228d65  
3fffff50:  0201a8c0 000000f5 00000000 00000019  
3fffff60:  00000002 0000001a 4020977f 3ffed270  
3fffff70:  3ffea6f4 3fffdcc0 3ffe9908 3ffe9908  
3fffff80:  402096f2 3ffed270 00000000 3fff12ec  
3fffff90:  3fffdc80 00000000 3fff31d4 4021d7e7  
3fffffa0:  40000f49 3fffdab0 3fffdab0 40000f49  
<<<stack<<<

 ets Jan  8 2013,rst cause:2, boot mode:(3,7)

load 0x4010f000, len 1384, room 16 
tail 8
chksum 0x2d
csum 0x2d
v3de0c112
~ld

Here is my handler method

void handleDiscovery(AsyncWebServerRequest *request) {
  AsyncResponseStream *response = request->beginResponseStream("text/json");
  DynamicJsonBuffer jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  root["status"] = "success";
  root["name"] = wifiManager.getStationSSID();
  JsonObject& switchStatus = jsonBuffer.createObject();
  switchStatus["switch0"] = "0";
  switchStatus["switch1"] = "0";
  switchStatus["switch2"] = "0";
  switchStatus["switch3"] = "0";
  root["switch_status"] = switchStatus;

  char buffer[200];
  root.printTo(buffer, sizeof(buffer));
  request->send(200, "application/json", buffer);
}

Can you please help me as to how to debug/fix the issue?

Missing file "Hash.h"

At line 40 on file AsyncWebSocket.cpp, there's an include of file "Hash.h" that isn't present on the library, and isn't on it's pre-requisites. Compiling the example "as-is" generates error.

  • Using IDE PlataformIO with framework Arduino and plataform Expressif, on board NodeMCU V1.0

Problem with requestAuthentication() in Internet Explorer

Request Authentication doesn't work in Internet Explorer.
After input login and password request repeated.

server.on("/index.html", [](AsyncWebServerRequest *request)
    {       
        if (!request->authenticate(_login, _pass))          
            return request->requestAuthentication();
        AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/index.html", "text/html");
        request->send(response);
    }); 

Is it possible to send a response to client with HTTP request from another source?

I need to send a response to the client using the "answer" from another site. Is it possible with AsyncWebServer? Thanks.

setup()
{
...
server.on("/ping", pingSource);
server.begin();
}
void pingSource(AsyncWebServerRequest *request)
{
HTTPClient http;
String send = "{\"status\": \"ping\"}";
http.begin("http://some-site.net/api");
http.addHeader("Content-Type", "application/json");
request->send(200, "text/plain", String(http.POST(send));
http.end();
}

Does Async TCP break HTTP Client?

Hi,
seems to me that Async TCP breaks HTTP Client.

Is there a way to submit requests to a url? Since on the basic SyncClient this does not work in my case...

Apart from google-url, only IP based connections work with syncClient

Thanks in advance

Web Server stops responding if client dies in the middle of sending a request

My ESP async web server application (based on ESP_AsyncFSBrowser) handles thousands of requests per hour from other ESP clients day after day. However, if a client gets powered down in the middle of sending a request, the web server stops accepting requests - WifiClient.connect will fail on the clients. The web server never recovers and needs to be reset.

The web server still responds to ping, and it can connect to another web server -- I tried using using that as a self-check but it keeps working. It even accepts OTA updates. It just won't accept client connections.

I tried connecting to itself as a self-check, but strangely, I find that this always fails even if the web server is working and accepts requests from other clients.

Is there a way to recover from this state or detect that it is not accepting connections so I can initiate a self-reset?

Platformio compile fails

I've installed through the platformio library manager and build for esp12. This fails during this include:

#include <Hash.h>

Update: funny enough its fine if I compile again. So more a platformio issue? I'm confused there :O

strftime strftime strftime

Arduino/libraries/ESPAsyncWebServer-master/src/WebHandlers.cpp:67:64: error: 'strftime' was not declared in this scope
strftime (result,30,"%a, %d %b %Y %H:%M:%S %Z", last_modified);
^

Arduino/libraries/ESPAsyncWebServer-master/src/WebHandlers.cpp:72:60: error: 'strftime' was not declared in this scope
return setLastModified((struct tm *)gmtime(&last_modified));

Arduino/libraries/ESPAsyncWebServer-master/src/WebHandlers.cpp:77:25: error: 'strftime' was not declared in this scope
if(time(&last_modified) == 0) //time is not yet set

How to solve?

Cheat sheet for converting from standard esp web server library.

I am trying to convert a rather large project from the standard esp web server library to this one.

I was kind of hoping there might be a list of equivalent functions one to the other to make porting easier.

Things like server->arg("name") in the esp web server library and what there equivalent is in this one.

Error when build

Hello,
I got following error when build the ESP_AsyncFSBrowser example

Arduino: 1.6.7 (Windows 7), Board: "Generic ESP8266 Module, Serial, 80 MHz, 40MHz, DIO, 115200, 512K (64K SPIFFS), ck"

Build options changed, rebuilding all
In file included from C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/ESP8266WiFi.h:28:0,

             from C:\Program Files (x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp:32:

C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/include/wl_definitions.h:73:17: error: redeclaration of 'CLOSED'

CLOSED = 0,

             ^

In file included from C:\Program Files (x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp:27:0:

C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/lwip/tcp.h:128:3: note: previous declaration 'tcp_state CLOSED'

CLOSED = 0,

^

In file included from C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/ESP8266WiFi.h:28:0,

             from C:\Program Files (x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp:32:

C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/include/wl_definitions.h:74:17: error: redeclaration of 'LISTEN'

LISTEN = 1,

             ^

In file included from C:\Program Files (x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp:27:0:

C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/lwip/tcp.h:129:3: note: previous declaration 'tcp_state LISTEN'

LISTEN = 1,

^

In file included from C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/ESP8266WiFi.h:28:0,

             from C:\Program Files (x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp:32:

C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/include/wl_definitions.h:75:17: error: redeclaration of 'SYN_SENT'

SYN_SENT = 2,

             ^

In file included from C:\Program Files (x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp:27:0:

C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/lwip/tcp.h:130:3: note: previous declaration 'tcp_state SYN_SENT'

SYN_SENT = 2,

^

In file included from C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/ESP8266WiFi.h:28:0,

             from C:\Program Files (x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp:32:

C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/include/wl_definitions.h:76:17: error: redeclaration of 'SYN_RCVD'

SYN_RCVD = 3,

             ^

In file included from C:\Program Files (x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp:27:0:

C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/lwip/tcp.h:131:3: note: previous declaration 'tcp_state SYN_RCVD'

SYN_RCVD = 3,

^

In file included from C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/ESP8266WiFi.h:28:0,

             from C:\Program Files (x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp:32:

C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/include/wl_definitions.h:77:17: error: redeclaration of 'ESTABLISHED'

ESTABLISHED = 4,

             ^

In file included from C:\Program Files (x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp:27:0:

C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/lwip/tcp.h:132:3: note: previous declaration 'tcp_state ESTABLISHED'

ESTABLISHED = 4,

^

In file included from C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/ESP8266WiFi.h:28:0,

             from C:\Program Files (x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp:32:

C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/include/wl_definitions.h:78:17: error: redeclaration of 'FIN_WAIT_1'

FIN_WAIT_1 = 5,

             ^

In file included from C:\Program Files (x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp:27:0:

C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/lwip/tcp.h:133:3: note: previous declaration 'tcp_state FIN_WAIT_1'

FIN_WAIT_1 = 5,

^

In file included from C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/ESP8266WiFi.h:28:0,

             from C:\Program Files (x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp:32:

C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/include/wl_definitions.h:79:17: error: redeclaration of 'FIN_WAIT_2'

FIN_WAIT_2 = 6,

             ^

In file included from C:\Program Files (x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp:27:0:

C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/lwip/tcp.h:134:3: note: previous declaration 'tcp_state FIN_WAIT_2'

FIN_WAIT_2 = 6,

^

In file included from C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/ESP8266WiFi.h:28:0,

             from C:\Program Files (x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp:32:

C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/include/wl_definitions.h:80:17: error: redeclaration of 'CLOSE_WAIT'

CLOSE_WAIT = 7,

             ^

In file included from C:\Program Files (x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp:27:0:

C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/lwip/tcp.h:135:3: note: previous declaration 'tcp_state CLOSE_WAIT'

CLOSE_WAIT = 7,

^

In file included from C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/ESP8266WiFi.h:28:0,

             from C:\Program Files (x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp:32:

C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/include/wl_definitions.h:81:17: error: redeclaration of 'CLOSING'

CLOSING = 8,

             ^

In file included from C:\Program Files (x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp:27:0:

C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/lwip/tcp.h:136:3: note: previous declaration 'tcp_state CLOSING'

CLOSING = 8,

^

In file included from C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/ESP8266WiFi.h:28:0,

             from C:\Program Files (x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp:32:

C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/include/wl_definitions.h:82:17: error: redeclaration of 'LAST_ACK'

LAST_ACK = 9,

             ^

In file included from C:\Program Files (x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp:27:0:

C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/lwip/tcp.h:137:3: note: previous declaration 'tcp_state LAST_ACK'

LAST_ACK = 9,

^

In file included from C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/ESP8266WiFi.h:28:0,

             from C:\Program Files (x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp:32:

C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/include/wl_definitions.h:83:17: error: redeclaration of 'TIME_WAIT'

TIME_WAIT = 10

             ^

In file included from C:\Program Files (x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp:27:0:

C:\Users\John\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/lwip/tcp.h:138:3: note: previous declaration 'tcp_state TIME_WAIT'

TIME_WAIT = 10

^

exit status 1
Error compiling.

This report would have more information with
"Show verbose output during compilation"
enabled in File > Preferences.

Change webserver port

Is it possible to dynamically change the server port?
I want to allow configuration of the server and part of that is allowing the user to determine the port that is used.
I see that in the constructor for the server (which is a global variable) the port is hardcoded:
AsyncWebServer server(80);

How can I then change the port number in my Setup routine?

I tried adding the following in my startup (port = 8081 by the way):
server = AsyncWebServer(port);
but as soon as I try to use the server (by sending an http request) my ESP crashes:
Exception (9):
epc1=0x402129ce epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000002 depc=0x00000000

Setting the port to 8081 in the initial constructor doesn't cause me any problem.

Thanks

Case-insensitive header field names

The RFC 7230 3.2 and also the old RFC 2616 4.2 define the field name as case-insensitive. node-fetch sends the content-length header field in lower case. That means the web server doesn't go into that if branch. I tested it with a quick 'n dirty or condition. I would like to make a PR. I think a generic solution, calling .toLowerCase() after this line would be the best solution, but that would also cause changes in many other places in the code and maybe even applications that use the web server library. What do you prefer?

Enhancement: addHeader()

Please allow addHeader similar and generic to setLastModified and setCache- for static handlers and EventSource. This will e.g. allow to specify the CORS headers for Ajax.

Serial return to WebSocket client.

Hello me-no-dev.

I'm developing an html app that sends short control commands over websocket to serial>arduino. The esp8266 is obvious choice for this. I'm not a seasoned developer with much knowledge of c++ (3 months). My first web app is almost complete and at over 300KB with it's dependencies is quite large and still growing. I have played with the idea of storing this on SPIFFS using libraries and examples from Markus. I could not achieve reliable results.
However using a modified version of your ESP_AsyncFSBrowser example and libraries the results are amazing. Well done and thank you.
Now to my problem, my app requires full duplex serial <> websocket communication for the best user experience. Preferably as transparent as possible.
I modified some code by tzapu https://github.com/tzapu/WebSocketSerialMonitor and this has served me well up to now.

String inputString = "";
boolean stringComplete = false;

void setup() {

Serial.begin(115200);
delay(100);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
delay(100);
}
Serial.println(WiFi.localIP());
webSocket.begin();
webSocket.onEvent(webSocketEvent);

inputString.reserve(128);
}

void serialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read();
if (inChar == '>') {
inputString += inChar;
stringComplete = true;
return;
} else {
inputString += inChar;
}
}
}

void loop() {

serialEvent();
if (stringComplete) {
String reply = inputString;
inputString = "";
stringComplete = false;
webSocket.broadcastTXT(reply);
}
webSocket.loop();
}

The above goes below the socket handlers in my sketch.
I'm trying to include the serialEvent or something similar into your example ESP_AsyncFSBrowser but I'm encountering many problems. I don't yet fully understand the Async protocol and I know that my problem is not really an issue. I thought I would try to get your help anyway as there is next to no information available elsewhere and this could benefit others. Could you please suggest a coding example that would work in this case.
Many thanks for now.
indev2

use ESPAsyncWebServer and websocket to stream video

hi ,can I have your comments and opinion about if ESP module can handle the video stream from browser to the module . I think Arducam made good library to stream the video to client browser but I don't know whether reverse action is possible or not , if it is what would be optimum fps and frame size

Web Server Stops responding after a while

Hi All,
ESP async webserver becomes unavailable after sometime intermittently where it says
Connection to http://192.168.1.4:80 refused
org.apache.http.conn.HttpHostConnectException: Connection to http://192.168.1.4:80 refused

The same happens from the web browser and then it starts working randomly. Checking the logs of the ESP device itself there is no crash.

Am i missing something in the setup of the server which can keep it alive all the time.

Cheers,
Akash A

Only the first ~2.5KByte is served for static files

Hi me-no-dev,

I have uploaded the ESP_AsyncFSBrowser to my nodemcu but it looks like it struggles sending large files.

image

image

I have tried it with many different client (IE, firefox, chrome) but it's the same. The same SPIFFS content seems to work the default arduino webserver, but it's terribly slow. I have tried both gzipped and non gzipped version of the file but it's the same.

I am using the master/head for both the ESPAsyncWebserver and ESPAsyncTCP.

File upload: data past the boundary end

Hello, I noticed a problem with the upload of files. I used the code in the example at the readme page:

void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){
  if(!index){
    Serial.printf("UploadStart: %s\n", filename.c_str());
  }
  for(size_t i=0; i<len; i++){
    Serial.write(data[i]);
  }
  if(final){
    Serial.printf("UploadEnd: %s, %u B\n", filename.c_str(), index+len);
  }
}

On the client side a form that submits the file to upload looks like this:

<form action="upload" method="POST" enctype="multipart/form-data">
<input type="file" required name="path">
<input type="submit" name="_submit" value="Upload">
</form>

so the browser sends to the server the following data:

`Content-Type: multipart/form-data; boundary=---------------------------109992776831753
Content-Length: 1191

-----------------------------109992776831753
Content-Disposition: form-data; name="path"; filename="index.htm"
Content-Type: text/html

...(omitted data for brevity)....

-----------------------------109992776831753
Content-Disposition: form-data; name="_submit"

Upload
-----------------------------109992776831753--
`

The intended data to be received should be limited to the part after the two carriage return and before the following boundary marker, however the actual data returned by the function overflow.
This is what the function put into the file:

`

...(omitted data for brevity).... /body>

-----------------------------109992776831753
Content-Disposition: form-data; name="_submit"

Upload`

Submitted file size: 897 bytes, stored file: 1001 bytes.

2016.07.19 - UPDATE:

I have tested with a modified HTML code to submit the file in a way that just the file field is submitted pulling out the from the form:

<form id="ff" action="upload" method="POST" enctype="multipart/form-data">
<input type="file" required name="path"></form>
<button type="button" onclick="document.getElementById('ff').submit();" >Upload</button>

This time the file is uploaded missing the final part, or likely saving only the first portion of about 880 bytes, missing the final 17 or so bytes.

After reverting to the previous form, I also tried to remove the name attribute from the input tag of type submit to see what happen, and the application simply crashes (the stack is output via serial monitor).

UPDATE 2:

Crash happens when the browser send a whole block of data larger than a given amount. Example, some time it sends a first chunk of 884 bytes followed by a second final chunk of 1254 bytes, and this is completed succeessfully (though with the spurious chunk appended); some time it sends a whole block of 2139 bytes and in this case the server crashes. Note the 1 byte difference.
Crash happens at exit of the upload handling function.

How to use instructions missing

Hi,
I am seeing that ESPAsyncWebServer library is not there even in the latest version of ESP8266. Theres very little information about how to use this library.

Could you please help me out here? I will write improve the documentation once I get to know how to use this.

Cheers,
Akash A

Dump when reloading web page while requests are open

Reloading page while 1~5 requests are still pending triggers crash:

ERROR[-8] Address in use, state: Closed
Fatal exception 3(LoadStoreErrorCause):
epc1=0x4010011d, epc2=0x00000000, epc3=0x00000000, excvaddr=0x40034d08, depc=0x00000000

Exception (3):
epc1=0x4010011d epc2=0x00000000 epc3=0x00000000 excvaddr=0x40034d08 depc=0x00000000

ctx: sys 
sp: 3ffffcb0 end: 3fffffb0 offset: 01a0

>>>stack>>>
3ffffe50:  4020bff8 000000f8 3fff4f9c 401003e1  
3ffffe60:  3fff0484 000006ce 000006ce 4010020c  
3ffffe70:  3fff4c54 4020f798 3fff4c4c 401008c8  
3ffffe80:  00007526 4020f798 3fff4c54 40107158  
3ffffe90:  3fff4c54 3fff4c54 3fff54f4 40228734  
3ffffea0:  1e00a8c0 a500a8c0 00000001 3fff4f9c  
3ffffeb0:  00007526 f4a83f0d 00000050 0000c62a  
3ffffec0:  4022874a 3fff4f9c 000000ff 402268de  
3ffffed0:  4020f2e9 3fff4f9c 00000000 00000000  
3ffffee0:  4020f5cf 3fff4e54 000000ff 4020f5d9  
3ffffef0:  0000004a 3fff4f9c 00000000 4020f634  
3fffff00:  00000000 00000000 00000002 40107148  
3fffff10:  40227916 3fff4c54 3ffef684 3ffef660  
3fffff20:  3ffef684 00000000 3fff4c54 4020f6cf  
3fffff30:  402273d1 3fff4c54 00000000 40227514  
3fffff40:  f4a83f0c 000069be 00000001 00000011  
3fffff50:  00000000 00000000 4022632a 3fff4d14  
3fffff60:  3fff1ae4 3ffec336 3fff1ae4 402250bf  
3fffff70:  3fff1ae4 00000014 4022566a 3fff4d14  
3fffff80:  3fff1ae4 3fffdc80 3fff1b44 00000001  
3fffff90:  4023101f 3fff4d14 00000000 4021173f  
3fffffa0:  40000f49 3fffdab0 3fffdab0 40000f49  
<<<stack<<<


Decoding 30 results
0x4010011d: umm_assimilate_up at C:\andi\arduino\hardware\esp8266com\esp8266\cores\esp8266\umm_malloc/umm_malloc.c:1161
0x40034d08: ?? ??:0
0x4010011d: umm_assimilate_up at C:\andi\arduino\hardware\esp8266com\esp8266\cores\esp8266\umm_malloc/umm_malloc.c:1161
0x40034d08: ?? ??:0
0x4020bff8: operator() at C:\andi\arduino\hardware\esp8266com\esp8266\libraries\ESPAsyncWebServer\src/WebRequest.cpp:568
 (inlined by) _M_invoke at c:\andi\arduino\hardware\esp8266com\esp8266\tools\xtensa-lx106-elf\xtensa-lx106-elf\include\c++\4.8.2/functional:2071
0x401003e1: check_poison_block at C:\andi\arduino\hardware\esp8266com\esp8266\cores\esp8266\umm_malloc/umm_malloc.c:835
0x4010020c: _umm_free at C:\andi\arduino\hardware\esp8266com\esp8266\cores\esp8266\umm_malloc/umm_malloc.c:1285
0x4020f798: AsyncClient::_s_error(void*, signed char) at C:\andi\arduino\hardware\esp8266com\esp8266\libraries\ESPAsyncTCP\src/ESPAsyncTCP.cpp:506 (discriminator 4)
0x401008c8: free at C:\andi\arduino\hardware\esp8266com\esp8266\cores\esp8266\umm_malloc/umm_malloc.c:1731
0x4020f798: AsyncClient::_s_error(void*, signed char) at C:\andi\arduino\hardware\esp8266com\esp8266\libraries\ESPAsyncTCP\src/ESPAsyncTCP.cpp:506 (discriminator 4)
0x40107158: vPortFree at C:\andi\arduino\hardware\esp8266com\esp8266\cores\esp8266/heap.c:18
0x40228734: tcp_abandon at ??:?
0x4022874a: tcp_abort at ??:?
0x402268de: pbuf_alloc at ??:?
0x4020f2e9: AsyncClient::abort() at C:\andi\arduino\hardware\esp8266com\esp8266\libraries\ESPAsyncTCP\src/ESPAsyncTCP.cpp:506 (discriminator 4)
0x4020f5cf: AsyncClient::_close() at C:\andi\arduino\hardware\esp8266com\esp8266\libraries\ESPAsyncTCP\src/ESPAsyncTCP.cpp:506 (discriminator 4)
0x4020f5d9: AsyncClient::_close() at C:\andi\arduino\hardware\esp8266com\esp8266\libraries\ESPAsyncTCP\src/ESPAsyncTCP.cpp:506 (discriminator 4)
0x4020f634: AsyncClient::_recv(tcp_pcb*, pbuf*, signed char) at C:\andi\arduino\hardware\esp8266com\esp8266\libraries\ESPAsyncTCP\src/ESPAsyncTCP.cpp:506 (discriminator 4)
0x40107148: pvPortMalloc at C:\andi\arduino\hardware\esp8266com\esp8266\cores\esp8266/heap.c:13
0x40227916: tcp_input at ??:?
0x4020f6cf: AsyncClient::_s_recv(void*, tcp_pcb*, pbuf*, signed char) at C:\andi\arduino\hardware\esp8266com\esp8266\libraries\ESPAsyncTCP\src/ESPAsyncTCP.cpp:506 (discriminator 4)
0x402273d1: tcp_input at ??:?
0x40227514: tcp_input at ??:?
0x4022632a: ip_input at ??:?
0x402250bf: etharp_find_addr at ??:?
0x4022566a: ethernet_input at ??:?
0x4023101f: ets_snprintf at ??:?
0x4021173f: loop_task at C:\andi\arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_main.cpp:43
0x40000f49: ?? ??:0
0x40000f49: ?? ??:0

Resetting authentication

Is there a way to revoke authentication?
After authenticating with a login I need to 'sign out' and revoke the authentication but I can't see any way of doing it.

Thanks.

Problem uploading multiple files

Hi,

First, thanks for all your work on an awesome set of libraries and other contribution to ESP arduino dev!!!

I've experienced a small issue trying to upload multiple files.

Single file upload based on your examples works great (for instance, upload "one.txt"). Chrome client on windows, simple html form as follows:

<html>
<body>
<form action="/upload" method="post"
enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" ><br>
<input type="submit" name="submit" value="Submit">
</form>
</body>
</html>

Supported by this code:

void handleFileUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){
  static bool _authenticated;
  static String _username = "", _password="";

  dbg_printf("File: %s, size:%u bytes, index: %u, final: %s\n", filename.c_str(), len, index, final?"true":"false");
  if(!index){
    _authenticated = false;
    if(!_username.length() || request->authenticate(_username.c_str(),_password.c_str())){
      _authenticated = true;
      filename= "/" + filename;
      request->_tempFile = SPIFFS.open(filename, "w");
    }
  }
  if(_authenticated && request->_tempFile){
    if(len){
      request->_tempFile.write(data,len);
    }
    if(final){
      request->_tempFile.close();
    }
  }
}

However, if I try to modify the HTML to support selecting multiple files (so I can upload "one.txt" followed by "two.txt" in one go, eg:

<html>
<body>

<form action="/upload" method="post"
enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" **multiple**><br>
<input type="submit" name="submit" value="Submit">
</form>
</body>
</html>

Then I get a fatal exception:

Fatal exception 3(LoadStoreErrorCause):
epc1=0x4010011d, epc2=0x00000000, epc3=0x40000f68, excvaddr=0x40036c00, depc=0x00000000

Exception (3):
epc1=0x4010011d epc2=0x00000000 epc3=0x40000f68 excvaddr=0x40036c00 depc=0x00000000

ctx: sys
sp: 3ffffbf0 end: 3fffffb0 offset: 01a0

The debug output from the above sprintf is:
File: two.txt, size:3 bytes, index: 0, final: true
... which is identical to what I see if I upload just one file.

Any suggestions as to what I'm doing wrong (apart from trying to upload two files :P )?

Thanks again!!

Can't build the example

Hi,
I got following error when build the ESP_AsyncFSBrowser example.

I'm using PlatformIO 2.9.1, checked that Platformio ESP core == https://github.com/esp8266/Arduino master branch.

(penv) r:\test>pio run
[05/13/16 20:26:00] Processing d1_mini (platform: espressif, board: d1_mini, framework: arduino)
---------------------------------------------------------------------------------------------------------------------------------------------------------------
xtensa-lx106-elf-ar rcs .pioenvs\d1_mini\libFrameworkArduinoVariant.a
xtensa-lx106-elf-g++ -o .pioenvs\d1_mini\src\tmp_ino_to.o -c -fno-rtti -fno-exceptions -std=c++11 -Os -mlongcalls -mtext-section-literals -falign-functions=4 -f
function-sections -fdata-sections -MMD -DF_CPU=80000000L -D__ets__ -DICACHE_FLASH -DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_NODEMCU -DARDUINO=20200 -DP
LATFORMIO=020901 -U__STRICT_ANSI__ -IC:\users\hazar\.platformio\packages\framework-arduinoespressif\tools\sdk\include -IC:\users\hazar\.platformio\packages\fram
ework-arduinoespressif\tools\sdk\lwip\include -I.pioenvs\d1_mini\FrameworkArduino -I.pioenvs\d1_mini\FrameworkArduinoVariant -I.pioenvs\d1_mini\ESP8266WiFi -I.p
ioenvs\d1_mini\ESP8266mDNS -I.pioenvs\d1_mini\ArduinoOTA -I.pioenvs\d1_mini\Hash -I.pioenvs\d1_mini\ESPAsyncTCP_ID305 -I.pioenvs\d1_mini\ESPAsyncWebServer_ID306
 src\tmp_ino_to.cpp
xtensa-lx106-elf-g++ -o .pioenvs\d1_mini\FrameworkArduino\Esp.o -c -fno-rtti -fno-exceptions -std=c++11 -Os -mlongcalls -mtext-section-literals -falign-function
s=4 -ffunction-sections -fdata-sections -MMD -DF_CPU=80000000L -D__ets__ -DICACHE_FLASH -DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_NODEMCU -DARDUINO=202
00 -U__STRICT_ANSI__ -IC:\users\hazar\.platformio\packages\framework-arduinoespressif\tools\sdk\include -IC:\users\hazar\.platformio\packages\framework-arduinoe
spressif\tools\sdk\lwip\include -I.pioenvs\d1_mini\FrameworkArduino -I.pioenvs\d1_mini\FrameworkArduinoVariant .pioenvs\d1_mini\FrameworkArduino\Esp.cpp
xtensa-lx106-elf-g++ -o .pioenvs\d1_mini\FrameworkArduino\FS.o -c -fno-rtti -fno-exceptions -std=c++11 -Os -mlongcalls -mtext-section-literals -falign-functions
=4 -ffunction-sections -fdata-sections -MMD -DF_CPU=80000000L -D__ets__ -DICACHE_FLASH -DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_NODEMCU -DARDUINO=2020
0 -U__STRICT_ANSI__ -IC:\users\hazar\.platformio\packages\framework-arduinoespressif\tools\sdk\include -IC:\users\hazar\.platformio\packages\framework-arduinoes
pressif\tools\sdk\lwip\include -I.pioenvs\d1_mini\FrameworkArduino -I.pioenvs\d1_mini\FrameworkArduinoVariant .pioenvs\d1_mini\FrameworkArduino\FS.cpp
xtensa-lx106-elf-g++ -o .pioenvs\d1_mini\FrameworkArduino\HardwareSerial.o -c -fno-rtti -fno-exceptions -std=c++11 -Os -mlongcalls -mtext-section-literals -fali
gn-functions=4 -ffunction-sections -fdata-sections -MMD -DF_CPU=80000000L -D__ets__ -DICACHE_FLASH -DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_NODEMCU -D
ARDUINO=20200 -U__STRICT_ANSI__ -IC:\users\hazar\.platformio\packages\framework-arduinoespressif\tools\sdk\include -IC:\users\hazar\.platformio\packages\framewo
rk-arduinoespressif\tools\sdk\lwip\include -I.pioenvs\d1_mini\FrameworkArduino -I.pioenvs\d1_mini\FrameworkArduinoVariant .pioenvs\d1_mini\FrameworkArduino\Hard
wareSerial.cpp
xtensa-lx106-elf-g++ -o .pioenvs\d1_mini\FrameworkArduino\IPAddress.o -c -fno-rtti -fno-exceptions -std=c++11 -Os -mlongcalls -mtext-section-literals -falign-fu
nctions=4 -ffunction-sections -fdata-sections -MMD -DF_CPU=80000000L -D__ets__ -DICACHE_FLASH -DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_NODEMCU -DARDUI
NO=20200 -U__STRICT_ANSI__ -IC:\users\hazar\.platformio\packages\framework-arduinoespressif\tools\sdk\include -IC:\users\hazar\.platformio\packages\framework-ar
duinoespressif\tools\sdk\lwip\include -I.pioenvs\d1_mini\FrameworkArduino -I.pioenvs\d1_mini\FrameworkArduinoVariant .pioenvs\d1_mini\FrameworkArduino\IPAddress
.cpp
xtensa-lx106-elf-g++ -o .pioenvs\d1_mini\FrameworkArduino\MD5Builder.o -c -fno-rtti -fno-exceptions -std=c++11 -Os -mlongcalls -mtext-section-literals -falign-f
unctions=4 -ffunction-sections -fdata-sections -MMD -DF_CPU=80000000L -D__ets__ -DICACHE_FLASH -DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_NODEMCU -DARDU
INO=20200 -U__STRICT_ANSI__ -IC:\users\hazar\.platformio\packages\framework-arduinoespressif\tools\sdk\include -IC:\users\hazar\.platformio\packages\framework-a
rduinoespressif\tools\sdk\lwip\include -I.pioenvs\d1_mini\FrameworkArduino -I.pioenvs\d1_mini\FrameworkArduinoVariant .pioenvs\d1_mini\FrameworkArduino\MD5Build
er.cpp
xtensa-lx106-elf-g++ -o .pioenvs\d1_mini\FrameworkArduino\Print.o -c -fno-rtti -fno-exceptions -std=c++11 -Os -mlongcalls -mtext-section-literals -falign-functi
ons=4 -ffunction-sections -fdata-sections -MMD -DF_CPU=80000000L -D__ets__ -DICACHE_FLASH -DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_NODEMCU -DARDUINO=2
0200 -U__STRICT_ANSI__ -IC:\users\hazar\.platformio\packages\framework-arduinoespressif\tools\sdk\include -IC:\users\hazar\.platformio\packages\framework-arduin
oespressif\tools\sdk\lwip\include -I.pioenvs\d1_mini\FrameworkArduino -I.pioenvs\d1_mini\FrameworkArduinoVariant .pioenvs\d1_mini\FrameworkArduino\Print.cpp
xtensa-lx106-elf-g++ -o .pioenvs\d1_mini\FrameworkArduino\Stream.o -c -fno-rtti -fno-exceptions -std=c++11 -Os -mlongcalls -mtext-section-literals -falign-funct
ions=4 -ffunction-sections -fdata-sections -MMD -DF_CPU=80000000L -D__ets__ -DICACHE_FLASH -DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_NODEMCU -DARDUINO=
20200 -U__STRICT_ANSI__ -IC:\users\hazar\.platformio\packages\framework-arduinoespressif\tools\sdk\include -IC:\users\hazar\.platformio\packages\framework-ardui
noespressif\tools\sdk\lwip\include -I.pioenvs\d1_mini\FrameworkArduino -I.pioenvs\d1_mini\FrameworkArduinoVariant .pioenvs\d1_mini\FrameworkArduino\Stream.cpp
xtensa-lx106-elf-g++ -o .pioenvs\d1_mini\FrameworkArduino\StreamString.o -c -fno-rtti -fno-exceptions -std=c++11 -Os -mlongcalls -mtext-section-literals -falign
-functions=4 -ffunction-sections -fdata-sections -MMD -DF_CPU=80000000L -D__ets__ -DICACHE_FLASH -DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_NODEMCU -DAR
DUINO=20200 -U__STRICT_ANSI__ -IC:\users\hazar\.platformio\packages\framework-arduinoespressif\tools\sdk\include -IC:\users\hazar\.platformio\packages\framework
-arduinoespressif\tools\sdk\lwip\include -I.pioenvs\d1_mini\FrameworkArduino -I.pioenvs\d1_mini\FrameworkArduinoVariant .pioenvs\d1_mini\FrameworkArduino\Stream
String.cpp
R:/test/src/ESP_AsyncFSBrowser.ino:18:6: error: 'bool SPIFFSEditor::canHandle(AsyncWebServerRequest*)' cannot be overloaded
if(request->method() == HTTP_GET && request->url() == "/edit" && (SPIFFS.exists("/edit.htm") || SPIFFS.exists("/edit.htm.gz")))
^
R:/test/src/ESP_AsyncFSBrowser.ino:17:10: error: with 'bool SPIFFSEditor::canHandle(AsyncWebServerRequest*)'
bool canHandle(AsyncWebServerRequest *request){
^
R:/test/src/ESP_AsyncFSBrowser.ino:34:10: error: 'void SPIFFSEditor::handleRequest(AsyncWebServerRequest*)' cannot be overloaded
if(_username.length() && (request->method() != HTTP_GET || request->url() == "/edit" || request->url() == "/list") && !request->authenticate(_username.c_str(),_
password.c_str()))
^
R:/test/src/ESP_AsyncFSBrowser.ino:19:10: error: with 'void SPIFFSEditor::handleRequest(AsyncWebServerRequest*)'
return true;
^
R:/test/src/ESP_AsyncFSBrowser.ino:99:10: error: 'void SPIFFSEditor::handleUpload(AsyncWebServerRequest*, String, size_t, uint8_t*, size_t, bool)' cannot be ove
rloaded
if(!index){
^
R:/test/src/ESP_AsyncFSBrowser.ino:21:10: error: with 'void SPIFFSEditor::handleUpload(AsyncWebServerRequest*, String, size_t, uint8_t*, size_t, bool)'
return true;
^
scons: *** [.pioenvs\d1_mini\src\tmp_ino_to.o] Error 1
xtensa-lx106-elf-g++ -o .pioenvs\d1_mini\FrameworkArduino\Tone.o -c -fno-rtti -fno-exceptions -std=c++11 -Os -mlongcalls -mtext-section-literals -falign-functio
ns=4 -ffunction-sections -fdata-sections -MMD -DF_CPU=80000000L -D__ets__ -DICACHE_FLASH -DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_NODEMCU -DARDUINO=20
200 -U__STRICT_ANSI__ -IC:\users\hazar\.platformio\packages\framework-arduinoespressif\tools\sdk\include -IC:\users\hazar\.platformio\packages\framework-arduino
espressif\tools\sdk\lwip\include -I.pioenvs\d1_mini\FrameworkArduino -I.pioenvs\d1_mini\FrameworkArduinoVariant .pioenvs\d1_mini\FrameworkArduino\Tone.cpp
================================================================= [ ERROR ] Took 1.71 seconds =================================================================

async server shows crash with heap4c

Trying to track down some crashes I've implemented heap4c and a simple sketch:

#include <ESP8266WiFi.h>
#include <ESPAsyncWebServer.h>

AsyncWebServer g_server(80);

void setup() {
  Serial.begin(115200);
  WiFi.begin();
  while (WiFi.status() != WL_CONNECTED)
    delay(100);
  g_server.begin();
}

void loop() {
  delay(100);
}

When putting a little load, this will crash pretty immediately if heap4c present and run fine for ages (as does a more complex sketch) as long as ESPAsyncWebServer is not started. As you can see there are no handlers attached, start of ESPAsyncWebServer alone is enough to cause the crash.

Use this for load:

while (true); do curl -m 1 http://192.168.0.30; done

Crash (update- deleted everything before wifi is up):

ip:192.168.0.30,mask:255.255.255.0,gw:192.168.0.1f 112 153 <
m 5 64 154 <

f 64 154 <
m 16 64 155 <
f 64 149 <
m 120 168 156 <
m 16 64 157 <
f 96 152 <
f 152 151 <
f 168 156 <
f 64 157 <
m 16 64 158 <
f 64 158 <
m 16 64 159 <
f 64 159 <
m 16 64 160 <
f 64 160 <
m 16 64 161 <
f 64 155 <
m 16 64 162 <
f 64 161 <
m 16 64 163 <
m 20 72 164 <
f 72 164 <
f 64 163 <
m 16 64 165 <
f 64 165 <
m 16 64 166 <
f 64 166 <
m 16 64 167 <
f 64 167 <
m 16 64 168 <
f 64 150 <
m 16 64 169 <
f 64 162 <
m 16 64 170 <
f 64 168 <
m 16 64 171 <
m 20 72 172 <
f 72 172 <
m 20 72 173 <
f 72 173 <
f 64 171 <
m 16 64 174 <
f 64 174 <
m 16 64 175 <
f 64 175 <
m 16 64 176 <
f 64 176 <
m 16 64 177 <
m 20 72 178 <
f 72 178 <
f 64 170 <
m 16 64 179 <
f 64 177 <
m 16 64 180 <
f 64 180 <
m 16 64 181 <
f 64 181 <
m 16 64 182 <
f 64 182 <
m 16 64 183 <
f 64 183 <
m 16 64 184 <
f 64 1 <
m 16 64 185 <
f 64 169 <
m 16 64 186 <
f 64 179 <
m 16 64 187 <
f 64 184 <
m 16 64 188 <
m 20 72 189 <
m 176 224 190 <
m 16 64 191 <
m 116 168 192 <
m 20 72 193 <
m 100 152 194 <
m 116 168 195 <
m 8 64 196 <
f 72 189 <
f 152 194 <
f 64 188 <
m 16 64 197 <
m 20 72 198 <
f 64 196 <
f 72 198 <
f 168 195 <
f 64 191 <
m 16 64 199 <
m 20 72 200 <
m 176 224 201 <
m 220 272 202 <
m 4 64 203 <
m 16 64 204 <
m 16 64 205 <
m 16 64 206 <
m 16 64 207 <
m 16 64 208 <
m 16 64 209 <
m 16 64 210 <
m 16 64 211 <
m 16 64 212 <
m 16 64 213 <
m 4 56 214 <
m 4 56 215 <
f 56 214 <
m 4 56 216 <
m 4 56 217 <
f 56 216 <
m 4 56 218 <
m 4 56 219 <
f 56 218 <
m 4 56 220 <
m 4 56 221 <
f 56 220 <
m 4 56 222 <
m 4 56 223 <
f 56 222 <
m 4 56 224 <
m 4 56 225 <
f 56 224 <
f 168 192 <
f 72 193 <
f 72 200 <
m 20 72 226 <
m 32 80 227 <
f 64 204 <
m 16 88 228 <
m 16 72 229 <
m 32 80 230 <
f 72 229 <
f 80 230 <
m 16 72 231 <
m 16 64 232 <
m 16 64 233 <
f 64 233 <
f 64 232 <
f 72 231 <
f 88 228 <
m 32 88 234 <
m 28 80 235 <
m 16 72 236 <
m 16 64 237 <
m 16 64 238 <
f 64 238 <
m 16 64 239 <
f 64 239 <
f 88 234 <
m 16 88 240 <
f 88 240 <
m 16 88 241 <
f 88 241 <
f 64 237 <
f 72 236 <
f 80 235 <
m 16 88 242 <
f 88 242 <
m 48 96 243 <
f 80 227 <
m 64 112 244 <
f 96 243 <
m 80 128 245 <
f 112 244 <
m 96 168 246 <
f 128 245 <
m 96 144 247 <
m 28 80 248 <
m 16 72 249 <
m 16 64 250 <
m 16 64 251 <
f 64 251 <
m 16 64 252 <
m 80 128 253 <
f 64 252 <
f 64 250 <
f 144 247 <
m 16 64 254 <
f 64 254 <
m 16 64 255 <
f 64 255 <
m 16 64 256 <
f 64 256 <
m 16 64 257 <
f 64 257 <
m 16 64 258 <
f 64 258 <
m 16 64 259 <
m 16 64 260 <
f 64 260 <
f 64 259 <
f 128 253 <
f 72 249 <
f 80 248 <
m 16 72 261 <
f 72 261 <
m 16 72 262 <
m 28 80 263 <
m 16 64 264 <
m 16 64 265 <
m 16 64 266 <
f 64 266 <
m 16 64 267 <
f 64 267 <
f 72 262 <
m 16 72 268 <
f 72 268 <
m 16 72 269 <
f 72 269 <
m 16 72 270 <
f 72 270 <
m 16 72 271 <
f 72 271 <
m 16 72 272 <
f 72 272 <
m 16 72 273 <
m 16 64 274 <
f 64 274 <
f 72 273 <
f 64 265 <
f 64 264 <
f 80 263 <
m 16 72 275 <
f 72 275 <
m 48 96 276 <
m 28 80 277 <
m 16 72 278 <
m 16 64 279 <
m 16 64 280 <
f 64 280 <
m 16 64 281 <
m 32 80 282 <
f 64 281 <
f 64 279 <
f 96 276 <
m 16 64 283 <
f 64 283 <
m 16 64 284 <
f 64 284 <
m 16 64 285 <
f 64 285 <
m 16 64 286 <
f 64 286 <
m 16 64 287 <
f 64 287 <
m 16 64 288 <
m 16 96 289 <
f 96 289 <
f 64 288 <
f 80 282 <
f 72 278 <
f 80 277 <
m 16 72 290 <
f 72 290 <
m 32 80 291 <
m 28 80 292 <
m 16 72 293 <
m 16 64 294 <
m 16 64 295 <
f 64 295 <
m 16 64 296 <
f 64 296 <
f 80 291 <
m 16 80 297 <
f 80 297 <
m 16 80 298 <
f 80 298 <
m 16 80 299 <
f 80 299 <
m 16 80 300 <
f 80 300 <
m 16 80 301 <
f 80 301 <
m 16 80 302 <
m 16 64 303 <
f 64 303 <
f 80 302 <
f 64 294 <
f 72 293 <
f 80 292 <
m 16 72 304 <
f 72 304 <
m 48 96 305 <
m 28 80 306 <
m 16 72 307 <
m 16 64 308 <
m 16 64 309 <
f 64 309 <
m 16 64 310 <
m 48 96 311 <
f 64 310 <
f 64 308 <
f 96 305 <
m 16 64 312 <
f 64 312 <
m 16 64 313 <
f 64 313 <
m 16 64 314 <
f 64 314 <
m 16 64 315 <
f 64 315 <
m 16 64 316 <
f 64 316 <
m 16 64 317 <
m 16 96 318 <
f 96 318 <
f 64 317 <
f 96 311 <
f 72 307 <
f 80 306 <
m 16 72 319 <
f 72 319 <
m 32 80 320 <
m 28 80 321 <
m 16 72 322 <
m 16 64 323 <
m 16 64 324 <
f 64 324 <
m 16 64 325 <
m 32 80 326 <
f 64 325 <
f 64 323 <
f 80 320 <
m 16 64 327 <
f 64 327 <
m 16 64 328 <
f 64 328 <
m 16 64 329 <
f 64 329 <
m 16 64 330 <
f 64 330 <
m 16 64 331 <
f 64 331 <
m 16 64 332 <
m 16 80 333 <
f 80 333 <
f 64 332 <
f 80 326 <
f 72 322 <
f 80 321 <
m 16 72 334 <
f 72 334 <
m 32 80 335 <
m 28 80 336 <
m 16 72 337 <
m 16 64 338 <
m 16 64 339 <
f 64 339 <
m 16 64 340 <
f 64 340 <
f 80 335 <
m 16 80 341 <
f 80 341 <
m 16 80 342 <
f 80 342 <
m 16 80 343 <
f 80 343 <
m 16 80 344 <
f 80 344 <
m 16 80 345 <
f 80 345 <
m 16 80 346 <
m 16 64 347 <
f 64 347 <
f 80 346 <
f 64 338 <
f 72 337 <
f 80 336 <
m 16 72 348 <
f 72 348 <
m 16 72 349 <
m 16 64 350 <
m 16 64 351 <
m 16 64 352 <
m 56 104 353 <
m 16 64 354 <
m 16 64 355 <
m 16 64 356 <
m 16 64 357 <
m 16 64 358 <
m 28 80 359 <
m 16 64 360 <
m 16 64 361 <
f 64 358 <
f 64 357 <
f 64 356 <
f 64 355 <
m 32 80 362 <
m 16 64 363 <
m 32 112 364 <
m 16 64 365 <
m 28 80 366 <
m 32 80 367 <
m 16 64 368 <
f 64 365 <
f 112 364 <
f 64 363 <
f 80 362 <
m 16 64 369 <
m 16 64 370 <
m 16 64 371 <
m 48 96 372 <
f 64 370 <
m 48 96 373 <
f 64 371 <
f 96 372 <
m 32 80 374 <
m 16 64 375 <
m 64 112 376 <
f 96 373 <
f 64 375 <
f 80 374 <
m 16 64 377 <
m 32 80 378 <
f 64 377 <
m 32 80 379 <
f 80 378 <
m 80 128 380 <
f 112 376 <
f 80 379 <
f 64 361 <
f 64 360 <
f 80 359 <
m 32 80 381 <
m 48 96 382 <
f 80 381 <
m 48 96 383 <
f 96 382 <
m 112 176 384 <
f 128 380 <
f 96 383 <
f 64 368 <
f 80 367 <
f 80 366 <
m 1572 1624 385 <
m 20 72 386 <
f 176 384 <
f 64 352 <
f 64 351 <
f 64 350 <
f 72 349 <
f 72 226 <
m 20 72 387 <
f 64 197 <
m 16 64 388 <
f 64 199 <
m 16 64 389 <
f 64 388 <
m 16 64 390 <
f 64 389 <
m 16 64 391 <
f 64 390 <
m 16 64 392 <
f 64 187 <
m 16 64 393 <
f 64 391 <
m 16 64 394 <
f 64 392 <
m 16 64 395 <
f 72 387 <
m 20 72 396 <
f 1624 385 <
f 72 386 <
m 112 160 397 <
m 20 72 398 <
f 160 397 <
f 72 398 <
m 112 160 399 <
f 224 190 <
f 56 225 <
f 56 221 <
f 56 223 <
f 56 215 <
f 56 217 <
f 56 219 <
f 224 201 <
f 64 203 <
f 64 369 <
f 64 354 <
f 104 353 <
f 64 213 <
f 64 212 <
f 64 211 <
f 64 210 <
f 64 209 <
f 64 208 <
f 64 207 <
f 64 206 <
f 64 205 <
f 168 246 <
f 272 202 <
m 21 72 400 <
Fatal exception 28f 72 400 <
m 25 80 401 <
(LoadProhibitedCause):
f 80 401 <
m 69 120 402 <
epc1=0x4021dec7, epc2=0x00000000, epc3=0x00000000, excvaddr=0x007e8000, depc=0x00000000
f 120 402 <

Exception (28):
epc1=0x4021dec7 epc2=0x00000000 epc3=0x00000000 excvaddr=0x007e8000 depc=0x00000000

ctx: sys 
sp: 3ffffd70 end: 3fffffb0 offset: 01a0

>>>stack>>>
3fffff10:  4021bee2 3fff0d20 3fff1358 3ffee820  
3fffff20:  3ffee844 4021baf1 3fff0d20 00000000  
3fffff30:  3ffee844 3ffee820 0000cccc 4021bae0  
3fffff40:  69b13f15 000019dc 00000001 00000011  
3fffff50:  00000000 00000000 4021a8f6 3fff0cd8  
3fffff60:  3fff0b98 3ffe9be6 3fff0b98 4021968b  
3fffff70:  3fff0b98 00000014 40219c36 3fff0cd8  
3fffff80:  3fff0b98 3fffdc80 3fff0c38 00000001  
3fffff90:  402255ef 3fff0cd8 00000000 40205bdb  
3fffffa0:  40000f49 3fffdab0 3fffdab0 40000f49  
<<<stack<<<

 ets Jan  8 2013,rst cause:1, boot mode:(1,7)


 ets Jan  8 2013,rst cause:4, boot mode:(1,7)

wdt reset

AsyncServer and OTA

When OTA starts it blocks the synchronous web server. The async server however seems to keep running according to my logs. As both async server and ota may e.g. update spiffs that seems to call for trouble.
Should async server be stopped on OTA start? How?

AsyncWebSocket printf bug

I found a bug in AsyncWebSocket printf function: wrong argument printed, perhaps invalid pointer.
The problem seems to happen with .printf(client_id, arguments...) but not with client->printf(arguments...).
Example code to reproduce the problem (code of the setup function omitted):

const char WSErr[] PROGMEM = "{\"type\":\"STATUS\",\"response\":\"Error at %d\"}";
int clientID;
bool readyToTest = false;

AsyncWebSocket ws("/.ws"); // access at ws://[esp ip]/.ws

void onEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len)
{
  //Handle WebSocket event
  if(type == WS_EVT_CONNECT) {
    Serial.printf("ws[%s][%u] connect\n", server->url(), client->id());
    client->printf("{\"type\":\"ACK\",\"response\":\"HELO\",\"client-id\":%u}", client->id());
    client->ping();
    clientID = client->id();
  } else if(type == WS_EVT_DISCONNECT) {
    Serial.printf("ws[%s][%u] disconnect: u\n", server->url(), client->id());
  } else if(type == WS_EVT_ERROR) {
    Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data);
  } else if(type == WS_EVT_PONG) {
    Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len)?(char*)data:"");
    readyToTest = true;
  } else if(type == WS_EVT_DATA) {
  }
}

void testWS() {
   char tmp[100];
   unsigned char testvalue = 2;

   strcpy_P(tmp, WSErr);
   Serial.printf(tmp, testvalue);
   ws.printf(clientID, tmp, testvalue);
}

void loop {
   if(readyToTest) {
     readyToTest = false;
     testWS();
   }
}

Output at serial monitor:

{"type":"STATUS","response":"Error at 2"}

Output at browser console (see script below)

{"type":"STATUS","response":"Error at 1073698976"}

This is the javascript that handles websocket connections and report to console:

        ws = new WebSocket("ws://10.0.22.101/.ws", WSPROTO);
    ws.onopen = function(event) {  
        connected = true;
    };
    ws.onclose = function(event) {
        connected = false;
    };
    ws.onmessage = function (event) {
           console.log(event.data);
        }

AsyncWebSocket memory leak?

Each time I connected then disconnected to the Websocket server, ESP.getFreeHeap() decreases by 184.

Example code: ESPAsyncWebServer/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino with one modification to demonstrate this issue:

Line 121:
Change
client->printf("Hello Client %u :)", client->id());

To
client->printf("Hello Client %u :), %u", client->id(), ESP.getFreeHeap());

Websocket client log:

CONNECTED

RESPONSE: Hello Client 1 :), 38696

DISCONNECTED

CONNECTED

RESPONSE: Hello Client 2 :), 38512

DISCONNECTED

CONNECTED

RESPONSE: Hello Client 3 :), 38328

DISCONNECTED

...

WebSocket Buffer Len for WS_TEXT message

When receiving WS_TEXT from websocket handler, if my text is for example foo the associated len received is 3. Does the buffer as 1 more size not counted by len ? because setting data[len] = 0; may have unpredictable effects ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.