A client for the SmartREST protocol from Cumulocity.
Fork of MbedSmartRest by
HTTPResponseFilter.cpp@17:57dd24cb6620, 2014-04-16 (annotated)
- Committer:
- vwochnik
- Date:
- Wed Apr 16 08:30:54 2014 +0000
- Revision:
- 17:57dd24cb6620
- Parent:
- 16:ee4f052c7570
fix
Who changed what in which revision?
User | Revision | Line number | New 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 | } |