lasselukkari / aWOT

Arduino web server library.
MIT License
292 stars 42 forks source link

400 Bad Request #15

Closed soccou closed 6 years ago

soccou commented 6 years ago

Hi,

Another question for you. On page request randomly it seems, the library returns :
400 Bad Request

If you simply refresh the browser after a short wait it works fine. There seems to be no reason to this that I can tell. It just works sometimes and not others. There is no need to reset MCU or change anything, just wait a while and the requested resource will load.

I have tried increasing RAM buffers in the header file, but that didn't really help.

Do you have any other troubleshooting steps, or ideas what might cause this?

Thanks, Sokkou

lasselukkari commented 6 years ago

Without seeing your code i can't help much. The only case when the library should send a 400 response is when the incoming HTTP request is malformed. Can you give me an example sketch that behaves like this for you? What board are you using? ESP8266 only has a single core and if you don't yield often enough the wifi stack will get unstable.

lasselukkari commented 6 years ago

I just ran Apache Benchmark with 10000 requests against the hello world example running on esp32. Here are the results:

ab -n 10000 -c 4 http://192.168.1.228/
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.1.228 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests

Server Software:        
Server Hostname:        192.168.1.228
Server Port:            80

Document Path:          /
Document Length:        105 bytes

Concurrency Level:      4
Time taken for tests:   138.007 seconds
Complete requests:      10000
Failed requests:        0
Total transferred:      1490000 bytes
HTML transferred:       1050000 bytes
Requests per second:    72.46 [#/sec] (mean)
Time per request:       55.203 [ms] (mean)
Time per request:       13.801 [ms] (mean, across all concurrent requests)
Transfer rate:          10.54 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        3    5   5.5      4     113
Processing:    15   50   8.7     50     148
Waiting:       13   49   8.8     49     148
Total:         20   55   8.8     54     207

Percentage of the requests served within a certain time (ms)
  50%     54
  66%     55
  75%     55
  80%     55
  90%     56
  95%     59
  98%     82
  99%    106
 100%    207 (longest request)
soccou commented 6 years ago

Thanks for the quick reply. That is a good suggestion on the apache benchmark. I am doing some tests with it. A recent test showed 10 failed requests out of 1000.

My code is ~1000 lines right now, so I am not sure how to pull out any meaningful excerpt here.

My development setup is different so that is more likely the potential source of the symptom I am experiencing. I am using a STM32 MCU, ENC ethernet, and alternate ethernet library

I think from your comments the problem is probably not in your library, so this is not really an open issue for your library.

One final question, which part of the code determines the request is malformed? I am wondering about adding some temporary debug code to print the request and see if i can determine what is corrupted.

lasselukkari commented 6 years ago

When the request instance is initialized to process a new request the method type is set to be INVALID: https://github.com/lasselukkari/aWOT/blob/master/aWOT.cpp#L52

If the request has a known HTTP verb the method type is set to that: https://github.com/lasselukkari/aWOT/blob/master/aWOT.cpp#L62-L79

If after calling the Request.processRequest() the type is still INVALID we send the bad request response. https://github.com/lasselukkari/aWOT/blob/master/aWOT.cpp#L958-L960

The easiest place to debug what is being read is here: https://github.com/lasselukkari/aWOT/blob/master/aWOT.cpp#L395

All other functions in the library use the Request.read() function internally when reading anything.

Can you show me the part of the loop where you check for new connections and call app.process(&client);

lasselukkari commented 6 years ago

I'm going to close this issue for now. Without more information I really can't help. Feel free to open the issue again if needed.