Kernel/Parser handles sequential requests better
parent
91440090b2
commit
d1f99c069c
|
@ -1,5 +1,9 @@
|
|||
#include "RequestParser.h"
|
||||
|
||||
void RequestParser::reset() {
|
||||
_state = S_IN_METHOD;
|
||||
}
|
||||
|
||||
bool RequestParser::parse() {
|
||||
|
||||
unsigned int content_length = 0, available = 0, writable = 0;
|
||||
|
|
|
@ -28,6 +28,7 @@ class RequestParser
|
|||
|
||||
bool parse();
|
||||
bool error() { return _state == S_ERROR; };
|
||||
void reset();
|
||||
|
||||
|
||||
private:
|
||||
|
|
|
@ -2,27 +2,27 @@
|
|||
|
||||
void WebKernel::handleClients()
|
||||
{
|
||||
bool shouldYield = true;
|
||||
bool keepClient = false;
|
||||
bool shouldYield = false;
|
||||
bool keepClient = true;
|
||||
|
||||
if (_state == S_IDLE) {
|
||||
WiFiClient client = _server.available();
|
||||
if (!client) return;
|
||||
_client = _server.available();
|
||||
if (!_client) return;
|
||||
|
||||
_client = client;
|
||||
_request = HttpRequest();
|
||||
_parser.reset();
|
||||
_state = S_RECEIVING;
|
||||
_stateChange = millis();
|
||||
}
|
||||
|
||||
if (_client.connected()) {
|
||||
if (millis() - _stateChange >= WEBKERNEL_MAX_WAIT) {
|
||||
keepClient = false;
|
||||
} else if (_client.connected()) {
|
||||
switch (_state) {
|
||||
case S_IDLE:
|
||||
break;
|
||||
case S_RECEIVING:
|
||||
if (!_parser.parse()) {
|
||||
if (millis() - _stateChange <= WEBKERNEL_MAX_WAIT)
|
||||
keepClient = false;
|
||||
shouldYield = true;
|
||||
break;
|
||||
}
|
||||
|
@ -40,8 +40,6 @@ void WebKernel::handleClients()
|
|||
keepClient = false;
|
||||
}
|
||||
|
||||
if (millis() - _stateChange <= WEBKERNEL_MAX_WAIT) keepClient = false;
|
||||
|
||||
if (!keepClient) {
|
||||
_client.stop();
|
||||
_state = S_IDLE;
|
||||
|
|
|
@ -33,6 +33,7 @@ class WebKernel
|
|||
|
||||
#ifdef _TEST_
|
||||
void mock_nextClient(const char * next) { _server._next = next; }
|
||||
WiFiClient& mock_currentClient() { return _client; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
|
|
@ -42,3 +42,23 @@ TEST_CASE("Test message data","[RequestParser]")
|
|||
CHECK(request.getMessageLength() == 10);
|
||||
CHECK_THAT(request.getMessage(), Equals("1234567890"));
|
||||
}
|
||||
|
||||
TEST_CASE("Test parse multiple requests","[RequestParser]")
|
||||
{
|
||||
uint8_t buff[256] = {};
|
||||
Buffer client(buff, 256);
|
||||
HttpRequest request;
|
||||
RequestParser parser(request, client);
|
||||
|
||||
client.write("GET /foo HTTP/1.1\r\nHost: localhost\r\n\r\n");
|
||||
CHECK(parser.parse());
|
||||
CHECK_THAT(request.getUrl(), Equals("/foo"));
|
||||
parser.reset();
|
||||
|
||||
client = Buffer(buff, 256);
|
||||
request = HttpRequest();
|
||||
client.write("GET /bar HTTP/1.1\r\nHost: localhost\r\n\r\n");
|
||||
CHECK(parser.parse());
|
||||
CHECK_THAT(request.getUrl(), Equals("/bar"));
|
||||
|
||||
}
|
||||
|
|
|
@ -28,6 +28,9 @@ TEST_CASE("Test WebKernel", "[WebKernel]")
|
|||
|
||||
WebKernel kernel(80, routes, sizeof routes / sizeof routes[0]);
|
||||
|
||||
foo = 0;
|
||||
bar = 0;
|
||||
|
||||
SECTION("No client") {
|
||||
kernel.handleClients();
|
||||
}
|
||||
|
@ -43,10 +46,51 @@ TEST_CASE("Test WebKernel", "[WebKernel]")
|
|||
|
||||
SECTION("Request for bar") {
|
||||
kernel.mock_nextClient("GET /bar HTTP/1.1\r\nHost: localhost\r\n\r\n");
|
||||
REQUIRE(foo == 1);
|
||||
REQUIRE(foo == 0);
|
||||
REQUIRE(bar == 0);
|
||||
kernel.handleClients();
|
||||
CHECK(foo == 1);
|
||||
CHECK(foo == 0);
|
||||
CHECK(bar == 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("Test Partial requests", "[WebKernel]")
|
||||
{
|
||||
Route routes[] = {
|
||||
{ GET, "/foo", do_foo },
|
||||
{ GET, "/bar", do_bar }
|
||||
};
|
||||
WebKernel kernel(80, routes, 2);
|
||||
foo = bar = 0;
|
||||
|
||||
SECTION("Partial GET") {
|
||||
kernel.mock_nextClient("GET /foo");
|
||||
kernel.handleClients();
|
||||
REQUIRE(foo == 0);
|
||||
REQUIRE(bar == 0);
|
||||
WiFiClient& client = kernel.mock_currentClient();
|
||||
CHECK(client.available() == 0);
|
||||
delay(100);
|
||||
client.write(" HTTP/1.1\r\nHost:localhost\r\n\r\n");
|
||||
kernel.handleClients();
|
||||
CHECK(foo == 1);
|
||||
CHECK(client.available() > 0);
|
||||
}
|
||||
|
||||
SECTION("Timeout") {
|
||||
REQUIRE(foo == 0);
|
||||
kernel.mock_nextClient("GET /foo");
|
||||
kernel.handleClients();
|
||||
WiFiClient& client = kernel.mock_currentClient();
|
||||
kernel.mock_nextClient("GET /bar HTTP/1.1\r\nHost: localhost\r\n\r\n");
|
||||
delay(WEBKERNEL_MAX_WAIT);
|
||||
kernel.handleClients(); //
|
||||
REQUIRE(foo == 0);
|
||||
REQUIRE(bar == 0);
|
||||
CHECK(client.connected() == false);
|
||||
kernel.handleClients();
|
||||
REQUIRE(foo == 0);
|
||||
REQUIRE(bar == 1);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue