A client for the SmartREST protocol from Cumulocity.

Dependencies:   SmartRest

Fork of MbedSmartRest by Vincent Wochnik

Committer:
vwochnik
Date:
Mon May 26 08:25:44 2014 +0000
Revision:
18:f76f9ae79195
Parent:
16:ee4f052c7570
fix for bootstrapping

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vwochnik 14:dc3f8dd5c02b 1 #include "HTTPResponseFilter.h"
vwochnik 14:dc3f8dd5c02b 2 #include <stdlib.h>
vwochnik 14:dc3f8dd5c02b 3 #include <string.h>
vwochnik 14:dc3f8dd5c02b 4 #include <ctype.h>
vwochnik 14:dc3f8dd5c02b 5 #include <stdio.h>
vwochnik 14:dc3f8dd5c02b 6
vwochnik 14:dc3f8dd5c02b 7 const char *cExpectedStatus = "HTTP/1.* ";
vwochnik 15:0ce90c525e7a 8 const char *cContentLength = "Content-Length: ";
vwochnik 14:dc3f8dd5c02b 9
vwochnik 14:dc3f8dd5c02b 10 HTTPResponseFilter::HTTPResponseFilter(AbstractDataSource& source) : _source(source), _state(RESPF_STATE_INIT)
vwochnik 14:dc3f8dd5c02b 11 {
vwochnik 15:0ce90c525e7a 12 _length = _read = 0;
vwochnik 14:dc3f8dd5c02b 13 }
vwochnik 14:dc3f8dd5c02b 14
vwochnik 14:dc3f8dd5c02b 15 HTTPResponseFilter::~HTTPResponseFilter()
vwochnik 14:dc3f8dd5c02b 16 {
vwochnik 14:dc3f8dd5c02b 17 }
vwochnik 14:dc3f8dd5c02b 18
vwochnik 14:dc3f8dd5c02b 19 char HTTPResponseFilter::read()
vwochnik 14:dc3f8dd5c02b 20 {
vwochnik 14:dc3f8dd5c02b 21 if (_state != RESPF_STATE_READ_HEADERS)
vwochnik 14:dc3f8dd5c02b 22 return 0;
vwochnik 16:ee4f052c7570 23 if ((_length > 0) && (_length == _read))
vwochnik 16:ee4f052c7570 24 return 0;
vwochnik 16:ee4f052c7570 25 _read++;
vwochnik 14:dc3f8dd5c02b 26 return _source.read();
vwochnik 14:dc3f8dd5c02b 27 }
vwochnik 14:dc3f8dd5c02b 28
vwochnik 14:dc3f8dd5c02b 29 uint8_t HTTPResponseFilter::status()
vwochnik 14:dc3f8dd5c02b 30 {
vwochnik 14:dc3f8dd5c02b 31 if (_state != RESPF_STATE_READ_HEADERS)
vwochnik 14:dc3f8dd5c02b 32 return DS_STATUS_ERROR;
vwochnik 16:ee4f052c7570 33 if ((_length > 0) && (_length == _read))
vwochnik 16:ee4f052c7570 34 return DS_STATUS_CLOSED;
vwochnik 14:dc3f8dd5c02b 35 return _source.status();
vwochnik 14:dc3f8dd5c02b 36 }
vwochnik 14:dc3f8dd5c02b 37
vwochnik 14:dc3f8dd5c02b 38 uint16_t HTTPResponseFilter::readStatus()
vwochnik 14:dc3f8dd5c02b 39 {
vwochnik 14:dc3f8dd5c02b 40 uint16_t res = 0; uint8_t state = 0; char c; size_t offset = 0; uint8_t status;
vwochnik 14:dc3f8dd5c02b 41
vwochnik 14:dc3f8dd5c02b 42 if (_state != RESPF_STATE_INIT)
vwochnik 14:dc3f8dd5c02b 43 return 0;
vwochnik 14:dc3f8dd5c02b 44
vwochnik 14:dc3f8dd5c02b 45 while ((state < 3) && (((c = _source.read()) > 0) || ((status = _source.status()) == DS_STATUS_OK))) {
vwochnik 14:dc3f8dd5c02b 46 switch (state) {
vwochnik 14:dc3f8dd5c02b 47 case 0: // read expected status line
vwochnik 14:dc3f8dd5c02b 48 if ((cExpectedStatus[offset] != c) && (cExpectedStatus[offset] != '*'))
vwochnik 14:dc3f8dd5c02b 49 state = 3;
vwochnik 14:dc3f8dd5c02b 50 offset++;
vwochnik 14:dc3f8dd5c02b 51 if (offset == strlen(cExpectedStatus)) {
vwochnik 14:dc3f8dd5c02b 52 state = 1;
vwochnik 14:dc3f8dd5c02b 53 }
vwochnik 14:dc3f8dd5c02b 54 break;
vwochnik 14:dc3f8dd5c02b 55 case 1:
vwochnik 14:dc3f8dd5c02b 56 if (isspace(c))
vwochnik 14:dc3f8dd5c02b 57 state = 2;
vwochnik 14:dc3f8dd5c02b 58 if (isdigit(c))
vwochnik 14:dc3f8dd5c02b 59 res = (res * 10) + (c - '0');
vwochnik 14:dc3f8dd5c02b 60 break;
vwochnik 14:dc3f8dd5c02b 61 case 2:
vwochnik 14:dc3f8dd5c02b 62 if (c == '\n')
vwochnik 14:dc3f8dd5c02b 63 state = 3;
vwochnik 14:dc3f8dd5c02b 64 break;
vwochnik 14:dc3f8dd5c02b 65 }
vwochnik 14:dc3f8dd5c02b 66 }
vwochnik 14:dc3f8dd5c02b 67
vwochnik 14:dc3f8dd5c02b 68 if ((status != DS_STATUS_OK) || (state != 3))
vwochnik 14:dc3f8dd5c02b 69 return 0;
vwochnik 14:dc3f8dd5c02b 70
vwochnik 14:dc3f8dd5c02b 71 _state = RESPF_STATE_READ_STATUS;
vwochnik 14:dc3f8dd5c02b 72 return res;
vwochnik 14:dc3f8dd5c02b 73 }
vwochnik 14:dc3f8dd5c02b 74
vwochnik 14:dc3f8dd5c02b 75 bool HTTPResponseFilter::skipHeaders()
vwochnik 14:dc3f8dd5c02b 76 {
vwochnik 14:dc3f8dd5c02b 77 uint16_t res = 0; uint8_t state = 0; char c; size_t offset = 0; uint8_t status;
vwochnik 14:dc3f8dd5c02b 78
vwochnik 14:dc3f8dd5c02b 79 if (_state != RESPF_STATE_READ_STATUS)
vwochnik 14:dc3f8dd5c02b 80 return false;
vwochnik 14:dc3f8dd5c02b 81
vwochnik 15:0ce90c525e7a 82 while ((state < 5) && (((c = _source.read()) > 0) || ((status = _source.status()) == DS_STATUS_OK))) {
vwochnik 14:dc3f8dd5c02b 83 switch (state) {
vwochnik 14:dc3f8dd5c02b 84 case 0: // start of line
vwochnik 15:0ce90c525e7a 85 if (offset == 0) {
vwochnik 15:0ce90c525e7a 86 if (cContentLength[0] == c)
vwochnik 14:dc3f8dd5c02b 87 state = 1;
vwochnik 15:0ce90c525e7a 88 if (c == '\r')
vwochnik 15:0ce90c525e7a 89 state = 4;
vwochnik 14:dc3f8dd5c02b 90 } else {
vwochnik 15:0ce90c525e7a 91 if (c == '\r')
vwochnik 15:0ce90c525e7a 92 state = 3;
vwochnik 14:dc3f8dd5c02b 93 }
vwochnik 15:0ce90c525e7a 94 offset++;
vwochnik 14:dc3f8dd5c02b 95 break;
vwochnik 14:dc3f8dd5c02b 96 case 1:
vwochnik 16:ee4f052c7570 97 if (c == '\r')
vwochnik 15:0ce90c525e7a 98 state = 3;
vwochnik 15:0ce90c525e7a 99 else if (cContentLength[offset] != c)
vwochnik 15:0ce90c525e7a 100 state = 0;
vwochnik 16:ee4f052c7570 101 else if (offset == strlen(cContentLength)-1)
vwochnik 16:ee4f052c7570 102 state = 2;
vwochnik 15:0ce90c525e7a 103 offset++;
vwochnik 15:0ce90c525e7a 104 break;
vwochnik 15:0ce90c525e7a 105 case 2:
vwochnik 15:0ce90c525e7a 106 if (isdigit(c))
vwochnik 15:0ce90c525e7a 107 _length = (_length * 10) + (c - '0');
vwochnik 15:0ce90c525e7a 108 else if (c == '\r')
vwochnik 15:0ce90c525e7a 109 state = 3;
vwochnik 15:0ce90c525e7a 110 else
vwochnik 15:0ce90c525e7a 111 state = 0;
vwochnik 15:0ce90c525e7a 112 offset++;
vwochnik 15:0ce90c525e7a 113 break;
vwochnik 15:0ce90c525e7a 114 case 3:
vwochnik 14:dc3f8dd5c02b 115 if (c == '\n') {
vwochnik 14:dc3f8dd5c02b 116 state = 0;
vwochnik 14:dc3f8dd5c02b 117 offset = 0;
vwochnik 14:dc3f8dd5c02b 118 }
vwochnik 14:dc3f8dd5c02b 119 break;
vwochnik 15:0ce90c525e7a 120 case 4:
vwochnik 14:dc3f8dd5c02b 121 if (c == '\n')
vwochnik 15:0ce90c525e7a 122 state = 5;
vwochnik 14:dc3f8dd5c02b 123 break;
vwochnik 14:dc3f8dd5c02b 124 }
vwochnik 14:dc3f8dd5c02b 125 }
vwochnik 14:dc3f8dd5c02b 126
vwochnik 16:ee4f052c7570 127 if ((status != DS_STATUS_OK) || (state != 5))
vwochnik 14:dc3f8dd5c02b 128 return false;
vwochnik 16:ee4f052c7570 129
vwochnik 14:dc3f8dd5c02b 130 _state = RESPF_STATE_READ_HEADERS;
vwochnik 14:dc3f8dd5c02b 131 return true;
vwochnik 14:dc3f8dd5c02b 132 }
vwochnik 14:dc3f8dd5c02b 133
vwochnik 14:dc3f8dd5c02b 134 void HTTPResponseFilter::reset()
vwochnik 14:dc3f8dd5c02b 135 {
vwochnik 14:dc3f8dd5c02b 136 _state = RESPF_STATE_INIT;
vwochnik 15:0ce90c525e7a 137 _length = _read = 0;
vwochnik 14:dc3f8dd5c02b 138 }