Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: MbedSmartRestMain MbedSmartRestMain
Fork of MbedSmartRest by
HTTPResponseFilter.cpp
- Committer:
- xinlei
- Date:
- 2015-03-20
- Revision:
- 19:81dfc04ce0bb
- Parent:
- 18:16192696c106
File content as of revision 19:81dfc04ce0bb:
/*
* 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()
{
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;
}
