mbed.org implementation of the abstract SmartREST library for the Cumulocity Platform SmartREST protocol.
Dependents: MbedSmartRestMain MbedSmartRestMain
HTTPResponseFilter.cpp
00001 /* 00002 * HTTPResponseFilter.cpp 00003 * 00004 * Created on: Feb 1, 2013 00005 * * Authors: Vincent Wochnik <v.wochnik@gmail.com> 00006 * 00007 * Copyright (c) 2013 Cumulocity GmbH 00008 * 00009 * Permission is hereby granted, free of charge, to any person obtaining 00010 * a copy of this software and associated documentation files (the 00011 * "Software"), to deal in the Software without restriction, including 00012 * without limitation the rights to use, copy, modify, merge, publish, 00013 * distribute, sublicense, and/or sell copies of the Software, and to 00014 * permit persons to whom the Software is furnished to do so, subject to 00015 * the following conditions: 00016 * 00017 * The above copyright notice and this permission notice shall be 00018 * included in all copies or substantial portions of the Software. 00019 * 00020 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00021 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00022 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00023 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 00024 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 00025 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 00026 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00027 */ 00028 00029 #include "HTTPResponseFilter.h" 00030 #include <stdlib.h> 00031 #include <string.h> 00032 #include <ctype.h> 00033 #include <stdio.h> 00034 00035 const char *cExpectedStatus = "HTTP/1.* "; 00036 const char *cContentLength = "Content-Length: "; 00037 00038 HTTPResponseFilter::HTTPResponseFilter(AbstractDataSource& source) : _source(source), _state(RESPF_STATE_INIT) 00039 { 00040 _length = _read = 0; 00041 } 00042 00043 HTTPResponseFilter::~HTTPResponseFilter() 00044 { 00045 } 00046 00047 char HTTPResponseFilter::read() 00048 { 00049 if (_state != RESPF_STATE_READ_HEADERS) 00050 return 0; 00051 if ((_length > 0) && (_length == _read)) 00052 return 0; 00053 _read++; 00054 return _source.read(); 00055 } 00056 00057 uint8_t HTTPResponseFilter::status() 00058 { 00059 if (_state != RESPF_STATE_READ_HEADERS) 00060 return DS_STATUS_ERROR; 00061 if ((_length > 0) && (_length == _read)) 00062 return DS_STATUS_CLOSED; 00063 return _source.status(); 00064 } 00065 00066 uint16_t HTTPResponseFilter::readStatus() 00067 { 00068 uint16_t res = 0; 00069 uint8_t state = 0; 00070 char c; 00071 size_t offset = 0; 00072 uint8_t status = DS_STATUS_OK; 00073 00074 if (_state != RESPF_STATE_INIT) 00075 return 0; 00076 00077 while ((state < 3) && (((c = _source.read()) > 0) || ((status = _source.status()) == DS_STATUS_OK))) { 00078 switch (state) { 00079 case 0: // read expected status line 00080 if ((cExpectedStatus[offset] != c) && (cExpectedStatus[offset] != '*')) 00081 state = 3; 00082 offset++; 00083 if (offset == strlen(cExpectedStatus)) { 00084 state = 1; 00085 } 00086 break; 00087 case 1: 00088 if (isspace(c)) 00089 state = 2; 00090 if (isdigit(c)) 00091 res = (res * 10) + (c - '0'); 00092 break; 00093 case 2: 00094 if (c == '\n') 00095 state = 3; 00096 break; 00097 } 00098 } 00099 00100 if ((status != DS_STATUS_OK) || (state != 3)) 00101 return 0; 00102 00103 _state = RESPF_STATE_READ_STATUS; 00104 return res; 00105 } 00106 00107 bool HTTPResponseFilter::skipHeaders() 00108 { 00109 uint16_t res = 0; 00110 uint8_t state = 0; 00111 char c; 00112 size_t offset = 0; 00113 uint8_t status = DS_STATUS_OK; 00114 00115 if (_state != RESPF_STATE_READ_STATUS) 00116 return false; 00117 00118 while ((state < 5) && (((c = _source.read()) > 0) || ((status = _source.status()) == DS_STATUS_OK))) { 00119 switch (state) { 00120 case 0: // start of line 00121 if (offset == 0) { 00122 if (cContentLength[0] == c) 00123 state = 1; 00124 if (c == '\r') 00125 state = 4; 00126 } else { 00127 if (c == '\r') 00128 state = 3; 00129 } 00130 offset++; 00131 break; 00132 case 1: 00133 if (c == '\r') 00134 state = 3; 00135 else if (cContentLength[offset] != c) 00136 state = 0; 00137 else if (offset == strlen(cContentLength)-1) 00138 state = 2; 00139 offset++; 00140 break; 00141 case 2: 00142 if (isdigit(c)) 00143 _length = (_length * 10) + (c - '0'); 00144 else if (c == '\r') 00145 state = 3; 00146 else 00147 state = 0; 00148 offset++; 00149 break; 00150 case 3: 00151 if (c == '\n') { 00152 state = 0; 00153 offset = 0; 00154 } 00155 break; 00156 case 4: 00157 if (c == '\n') 00158 state = 5; 00159 break; 00160 } 00161 } 00162 00163 if ((status != DS_STATUS_OK) || (state != 5)) 00164 return false; 00165 00166 _state = RESPF_STATE_READ_HEADERS; 00167 return true; 00168 } 00169 00170 void HTTPResponseFilter::reset() 00171 { 00172 _state = RESPF_STATE_INIT; 00173 _length = _read = 0; 00174 }
Generated on Tue Jul 12 2022 15:21:50 by 1.7.2