HttpRequest message api and RequestParser message

feature/UrlUtils
Kenneth Barbour 2018-03-08 19:36:47 -05:00 committed by Kenneth Barbour
parent c92d39ddb1
commit a94184905c
5 changed files with 47 additions and 8 deletions

View File

@ -137,7 +137,7 @@ const char * HttpRequest::setMessage(const char * message)
return this->setMessage(message, len);
}
const char * HttpRequest::setMessage(const char * message, size_t n)
const char * HttpRequest::setMessage(const char * message, unsigned int n)
{
if (this->message) free(this->message);
this->message = (char *) malloc(n + 1);

View File

@ -33,16 +33,17 @@ class HttpRequest
const char * setHttpVer(const char *);
const char * getHttpVer();
const char * setMessage(const char *);
const char * setMessage(const char *, size_t);
const char * setMessage(const char *, unsigned int);
const char * getMessage();
unsigned int getMessageLength() { return message_length; };
char method [HTTPREQUEST_METHOD_SIZE];
char * url;
char httpver [HTTPREQUEST_HTTPVER_SIZE];
HttpHeaders headers;
long int message_length;
char * message;
protected:
char client_read(Stream&);
long int message_length;
char * message;
char client_peek(Stream&);
unsigned long _timeout_millis;
};

View File

@ -2,11 +2,14 @@
bool RequestParser::parse() {
unsigned int content_length = 0, available = 0, writable = 0;
char in;
while (client.available() && _state != S_ERROR) {
char in = client.read();
switch (_state) {
case S_IN_METHOD:
in = client.read();
if (in == ' ') {
*(_i++) = '\0';
request.setMethod(_buffer);
@ -17,6 +20,7 @@ bool RequestParser::parse() {
*(_i++) = in;
break;
case S_IN_URL:
in = client.read();
// skip preceding whitespace
if (in == ' ') {
if (_i == _buffer) continue;
@ -29,6 +33,7 @@ bool RequestParser::parse() {
*(_i++) = in;
break;
case S_IN_HTTPVER:
in = client.read();
if (in == '\r') continue;
if (in == '\n') {
*(_i) = '\0';
@ -40,11 +45,15 @@ bool RequestParser::parse() {
*(_i++) = in;
break;
case S_IN_HEADER:
in = client.read();
if (in == '\r') continue;
if (in == '\n') {
if (_i == _buffer) {
if (request.headers.has("Content-Length"))
if (request.headers.has("Content-Length")) {
content_length = atoi(request.headers.get("Content-Length"));
_state = S_IN_MESSAGE;
_i = _buffer;
}
else _state = S_COMPLETE;
break;
}
@ -68,8 +77,25 @@ bool RequestParser::parse() {
}
*(_i++) = in;
break;
case S_IN_MESSAGE:
available = client.available();
writable = content_length - (_i - _buffer);
while (writable && available) {
*(_i++) = client.read();
writable--;
available--;
}
if (!writable) {
if (available) client.flush();
*(_i++) = '\0';
request.setMessage(_buffer, content_length);
_state = S_COMPLETE;
break;
}
break;
case S_COMPLETE:
return true;
break;
default:
_state = S_ERROR;

View File

@ -27,7 +27,7 @@ TEST_CASE("Capture a complicated HTTP Request","[HttpRequest]") {
CHECK_THAT(req.url, Equals("/foo"));
CHECK_THAT(req.headers.get("Content-Length"), Equals("11"));
CHECK_THAT(req.message, Equals("foo=bar&baz"));
CHECK_THAT(req.getMessage(), Equals("foo=bar&baz"));
}
TEST_CASE("Test get/set method","[HttpRequest]")
@ -56,7 +56,7 @@ TEST_CASE("Test get/set message","[HttpRequest]")
HttpRequest req;
req.setMessage("FooBarBaz");
CHECK_THAT(req.getMessage(), Equals("FooBarBaz"));
CHECK(req.message_length == 9);
CHECK(req.getMessageLength() == 9);
}
TEST_CASE("HttpRequest reassignment", "[HttpRequest]")

View File

@ -30,3 +30,15 @@ TEST_CASE("Test GET","[RequestParser]")
CHECK(parser.parse());
CHECK(!parser.error());
}
TEST_CASE("Test message data","[RequestParser]")
{
uint8_t _buff[256] = {};
Buffer client(_buff, 256);
HttpRequest request;
RequestParser parser(request, client);
client.write("POST /foo HTTP/1.1\r\nHost: localhost\r\nContent-Length: 10\r\n\r\n1234567890");
CHECK(parser.parse());
CHECK(request.getMessageLength() == 10);
CHECK_THAT(request.getMessage(), Equals("1234567890"));
}