A client for the SmartREST protocol from Cumulocity.
Fork of MbedSmartRest by
HTTPResponseFilter.cpp
- Committer:
- vwochnik
- Date:
- 2014-04-16
- Revision:
- 17:57dd24cb6620
- Parent:
- 16:ee4f052c7570
File content as of revision 17:57dd24cb6620:
#include "HTTPResponseFilter.h" #include <stdlib.h> #include <string.h> #include <ctype.h> #include <stdio.h> const char *cExpectedStatus = "HTTP/1.* "; const char *cContentLength = "Content-Length: "; HTTPResponseFilter::HTTPResponseFilter(AbstractDataSource& source) : _source(source), _state(RESPF_STATE_INIT) { _length = _read = 0; } HTTPResponseFilter::~HTTPResponseFilter() { } char HTTPResponseFilter::read() { if (_state != RESPF_STATE_READ_HEADERS) return 0; if ((_length > 0) && (_length == _read)) return 0; _read++; return _source.read(); } uint8_t HTTPResponseFilter::status() { if (_state != RESPF_STATE_READ_HEADERS) return DS_STATUS_ERROR; if ((_length > 0) && (_length == _read)) return DS_STATUS_CLOSED; return _source.status(); } uint16_t HTTPResponseFilter::readStatus() { uint16_t res = 0; uint8_t state = 0; char c; size_t offset = 0; uint8_t status; if (_state != RESPF_STATE_INIT) return 0; while ((state < 3) && (((c = _source.read()) > 0) || ((status = _source.status()) == DS_STATUS_OK))) { switch (state) { case 0: // read expected status line if ((cExpectedStatus[offset] != c) && (cExpectedStatus[offset] != '*')) state = 3; offset++; if (offset == strlen(cExpectedStatus)) { state = 1; } break; case 1: if (isspace(c)) state = 2; if (isdigit(c)) res = (res * 10) + (c - '0'); break; case 2: if (c == '\n') state = 3; break; } } if ((status != DS_STATUS_OK) || (state != 3)) return 0; _state = RESPF_STATE_READ_STATUS; return res; } bool HTTPResponseFilter::skipHeaders() { uint16_t res = 0; uint8_t state = 0; char c; size_t offset = 0; uint8_t status; if (_state != RESPF_STATE_READ_STATUS) return false; while ((state < 5) && (((c = _source.read()) > 0) || ((status = _source.status()) == DS_STATUS_OK))) { switch (state) { case 0: // start of line if (offset == 0) { if (cContentLength[0] == c) state = 1; if (c == '\r') state = 4; } else { if (c == '\r') state = 3; } offset++; break; case 1: if (c == '\r') state = 3; else if (cContentLength[offset] != c) state = 0; else if (offset == strlen(cContentLength)-1) state = 2; offset++; break; case 2: if (isdigit(c)) _length = (_length * 10) + (c - '0'); else if (c == '\r') state = 3; else state = 0; offset++; break; case 3: if (c == '\n') { state = 0; offset = 0; } break; case 4: if (c == '\n') state = 5; break; } } if ((status != DS_STATUS_OK) || (state != 5)) return false; _state = RESPF_STATE_READ_HEADERS; return true; } void HTTPResponseFilter::reset() { _state = RESPF_STATE_INIT; _length = _read = 0; }