added a ResponseParser
parent
2d499714d5
commit
b00c493206
|
@ -0,0 +1,92 @@
|
|||
#include "ResponseParser.h"
|
||||
|
||||
void ResponseParser::reset() {
|
||||
_state = S_IN_HTTPVER;
|
||||
_i = _buffer;
|
||||
}
|
||||
|
||||
bool ResponseParser::parse() {
|
||||
char in;
|
||||
while (server.available() && _state != S_ERROR) {
|
||||
switch (_state) {
|
||||
case S_IN_HTTPVER:
|
||||
in = server.read();
|
||||
if (in == ' ') {
|
||||
*(_i++) = '\0';
|
||||
response.setHttpVersion(_buffer);
|
||||
_i = _buffer;
|
||||
_state = S_IN_CODE;
|
||||
break;
|
||||
}
|
||||
*(_i++) = in;
|
||||
break;
|
||||
case S_IN_CODE:
|
||||
in = server.read();
|
||||
// skip preceding whitespace
|
||||
if (in == ' ') {
|
||||
if (_i == _buffer) continue;
|
||||
*(_i) = '\0';
|
||||
response.code = atoi(_buffer);
|
||||
_i = _buffer;
|
||||
_state = S_IN_REASON;
|
||||
break;
|
||||
}
|
||||
*(_i++) = in;
|
||||
break;
|
||||
case S_IN_REASON:
|
||||
in = server.read();
|
||||
if (in == '\r') continue;
|
||||
if (in == '\n') {
|
||||
*(_i) = '\0';
|
||||
response.setReason(_buffer);
|
||||
_i = _buffer;
|
||||
_state = S_IN_HEADER;
|
||||
break;
|
||||
}
|
||||
*(_i++) = in;
|
||||
break;
|
||||
case S_IN_HEADER:
|
||||
in = server.read();
|
||||
if (in == '\r') continue;
|
||||
if (in == '\n') {
|
||||
if (_i == _buffer) {
|
||||
_state = S_IN_MESSAGE;
|
||||
_i = _buffer;
|
||||
break;
|
||||
}
|
||||
*(_i) = '\0';
|
||||
char * name = _buffer;
|
||||
char * value = _buffer;
|
||||
bool s = 0;
|
||||
while (value < _i) {
|
||||
if (s) {
|
||||
if (*value == ' ') value++;
|
||||
else break;
|
||||
} else {
|
||||
if (*value == ':') {
|
||||
s = true;
|
||||
*(value++) = '\0';
|
||||
} else value++;
|
||||
}
|
||||
}
|
||||
response.headers.set(name, value);
|
||||
_i = _buffer;
|
||||
break;
|
||||
}
|
||||
*(_i++) = in;
|
||||
break;
|
||||
case S_IN_MESSAGE:
|
||||
while (server.available()) {
|
||||
response.content->write(server.read());
|
||||
}
|
||||
_state = S_COMPLETE;
|
||||
case S_COMPLETE:
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
_state = S_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return (_state == S_COMPLETE || _state == S_ERROR);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
#include "HttpResponse.h"
|
||||
#include "Arduino.h"
|
||||
#include "Stream.h"
|
||||
|
||||
#ifndef RESPONSEPARSER_BUFFER
|
||||
#define RESPONSEPARSER_BUFFER 512
|
||||
#endif
|
||||
|
||||
enum ResponseParserState {
|
||||
S_IN_HTTPVER,
|
||||
S_IN_CODE,
|
||||
S_IN_REASON,
|
||||
S_IN_HEADER,
|
||||
S_IN_MESSAGE,
|
||||
S_COMPLETE,
|
||||
S_ERROR
|
||||
};
|
||||
|
||||
class ResponseParser
|
||||
{
|
||||
public:
|
||||
ResponseParser(HttpResponse& res, Stream& server):
|
||||
response(res),
|
||||
server(server),
|
||||
_state(S_IN_HTTPVER)
|
||||
{};
|
||||
|
||||
bool parse();
|
||||
bool error() { return _state == S_ERROR; };
|
||||
void reset();
|
||||
|
||||
|
||||
private:
|
||||
char _buffer[RESPONSEPARSER_BUFFER] = {};
|
||||
char * _i = _buffer;
|
||||
HttpResponse& response;
|
||||
Stream& server;
|
||||
ResponseParserState _state;
|
||||
};
|
|
@ -0,0 +1,34 @@
|
|||
#include "catch.hpp"
|
||||
#include "ResponseParser.h"
|
||||
#include <HttpResponse.h>
|
||||
#include <Buffer.h>
|
||||
|
||||
using Catch::Matchers::Equals;
|
||||
|
||||
TEST_CASE("Test parsing a response with headers and content")
|
||||
{
|
||||
uint8_t _reqbuff[100];
|
||||
Buffer server(_reqbuff, 100);
|
||||
uint8_t _resbuff[100];
|
||||
Buffer buffer(_resbuff, 100);
|
||||
HttpResponse response;
|
||||
ResponseParser parser(response, server);
|
||||
|
||||
response.content = &buffer;
|
||||
|
||||
server.print("HTTP/1.0 200 OK\r\nCookie: foo=bar; baz=qux;\r\nContent-Length:10\r\n\r\nABCDEFGHIJ");
|
||||
|
||||
bool result = parser.parse();
|
||||
|
||||
CHECK_THAT(response.getHttpVersion(), Equals("HTTP/1.0"));
|
||||
CHECK(response.code == 200);
|
||||
CHECK_THAT(response.getReason(), Equals("OK"));
|
||||
|
||||
CHECK(response.headers.count() == 2);
|
||||
CHECK(response.headers.has("Cookie") == true);
|
||||
CHECK_THAT(response.headers.get("Cookie"), Equals("foo=bar; baz=qux;"));
|
||||
CHECK(response.headers.has("Content-Length") == true);
|
||||
CHECK_THAT(response.headers.get("Content-Length"), Equals("10"));
|
||||
CHECK_THAT((char*)_resbuff, Equals("ABCDEFGHIJ"));
|
||||
|
||||
}
|
Loading…
Reference in New Issue