mbed.org implementation of the abstract SmartREST library for the Cumulocity Platform SmartREST protocol.
Dependents: MbedSmartRestMain MbedSmartRestMain
HTTPResponseFilter.cpp
- Committer:
- Cumulocity
- Date:
- 2014-07-03
- Revision:
- 0:099f76422485
File content as of revision 0:099f76422485:
/* * HTTPResponseFilter.cpp * * Created on: Feb 1, 2013 * * Authors: Vincent Wochnik <v.wochnik@gmail.com> * * Copyright (c) 2013 Cumulocity GmbH * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #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 = DS_STATUS_OK; 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 = DS_STATUS_OK; 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; }