HTTP and HTTPS library for Mbed OS 5
Dependents: MQTTGateway2 MQTTGatewayK64 http-example-wnc GuardRoom ... more
http_response.h
00001 /* 00002 * PackageLicenseDeclared: Apache-2.0 00003 * Copyright (c) 2017 ARM Limited 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #ifndef _MBED_HTTP_HTTP_RESPONSE 00019 #define _MBED_HTTP_HTTP_RESPONSE 00020 #include <string> 00021 #include <vector> 00022 #include "http_parser.h" 00023 00024 using namespace std; 00025 00026 class HttpResponse { 00027 public: 00028 HttpResponse() { 00029 status_code = 0; 00030 concat_header_field = false; 00031 concat_header_value = false; 00032 expected_content_length = 0; 00033 is_chunked = false; 00034 is_message_completed = false; 00035 body_length = 0; 00036 body_offset = 0; 00037 body = NULL; 00038 } 00039 00040 ~HttpResponse() { 00041 if (body != NULL) { 00042 free(body); 00043 } 00044 00045 for (uint32_t ix = 0; ix < header_fields.size(); ix++) { 00046 delete header_fields[ix]; 00047 delete header_values[ix]; 00048 } 00049 } 00050 00051 void set_status(int a_status_code, string a_status_message) { 00052 status_code = a_status_code; 00053 status_message = a_status_message; 00054 } 00055 00056 int get_status_code() { 00057 return status_code; 00058 } 00059 00060 string get_status_message() { 00061 return status_message; 00062 } 00063 00064 void set_url(string a_url) { 00065 url = a_url; 00066 } 00067 00068 string get_url() { 00069 return url; 00070 } 00071 00072 void set_method(http_method a_method) { 00073 method = a_method; 00074 } 00075 00076 http_method get_method() { 00077 return method; 00078 } 00079 00080 void set_header_field(string field) { 00081 concat_header_value = false; 00082 00083 // headers can be chunked 00084 if (concat_header_field) { 00085 *header_fields[header_fields.size() - 1] = (*header_fields[header_fields.size() - 1]) + field; 00086 } 00087 else { 00088 header_fields.push_back(new string(field)); 00089 } 00090 00091 concat_header_field = true; 00092 } 00093 00094 void set_header_value(string value) { 00095 concat_header_field = false; 00096 00097 // headers can be chunked 00098 if (concat_header_value) { 00099 *header_values[header_values.size() - 1] = (*header_values[header_values.size() - 1]) + value; 00100 } 00101 else { 00102 header_values.push_back(new string(value)); 00103 } 00104 00105 concat_header_value = true; 00106 } 00107 00108 void set_headers_complete() { 00109 for (uint32_t ix = 0; ix < header_fields.size(); ix++) { 00110 if (strcicmp(header_fields[ix]->c_str(), "content-length") == 0) { 00111 expected_content_length = (uint32_t)atoi(header_values[ix]->c_str()); 00112 break; 00113 } 00114 } 00115 } 00116 00117 uint32_t get_headers_length() { 00118 return header_fields.size(); 00119 } 00120 00121 vector<string*> get_headers_fields() { 00122 return header_fields; 00123 } 00124 00125 vector<string*> get_headers_values() { 00126 return header_values; 00127 } 00128 00129 void set_body(const char *at, uint32_t length) { 00130 // Connection: close, could not specify Content-Length, nor chunked... So do it like this: 00131 if (expected_content_length == 0 && length > 0) { 00132 is_chunked = true; 00133 } 00134 00135 // only malloc when this fn is called, so we don't alloc when body callback's are enabled 00136 if (body == NULL && !is_chunked) { 00137 body = (char*)malloc(expected_content_length); 00138 } 00139 00140 if (is_chunked) { 00141 if (body == NULL) { 00142 body = (char*)malloc(length); 00143 } 00144 else { 00145 char* original_body = body; 00146 body = (char*)realloc(body, body_offset + length); 00147 if (body == NULL) { 00148 free(original_body); 00149 return; 00150 } 00151 } 00152 } 00153 00154 memcpy(body + body_offset, at, length); 00155 00156 body_offset += length; 00157 } 00158 00159 void* get_body() { 00160 return (void*)body; 00161 } 00162 00163 string get_body_as_string() { 00164 string s(body, body_offset); 00165 return s; 00166 } 00167 00168 void increase_body_length(uint32_t length) { 00169 body_length += length; 00170 } 00171 00172 uint32_t get_body_length() { 00173 return body_offset; 00174 } 00175 00176 bool is_message_complete() { 00177 return is_message_completed; 00178 } 00179 00180 void set_chunked() { 00181 is_chunked = true; 00182 } 00183 00184 void set_message_complete() { 00185 is_message_completed = true; 00186 } 00187 00188 private: 00189 // from http://stackoverflow.com/questions/5820810/case-insensitive-string-comp-in-c 00190 int strcicmp(char const *a, char const *b) { 00191 for (;; a++, b++) { 00192 int d = tolower(*a) - tolower(*b); 00193 if (d != 0 || !*a) { 00194 return d; 00195 } 00196 } 00197 } 00198 00199 char tolower(char c) { 00200 if(('A' <= c) && (c <= 'Z')) { 00201 return 'a' + (c - 'A'); 00202 } 00203 00204 return c; 00205 } 00206 00207 int status_code; 00208 string status_message; 00209 string url; 00210 http_method method; 00211 00212 vector<string*> header_fields; 00213 vector<string*> header_values; 00214 00215 bool concat_header_field; 00216 bool concat_header_value; 00217 00218 uint32_t expected_content_length; 00219 00220 bool is_chunked; 00221 00222 bool is_message_completed; 00223 00224 char * body; 00225 uint32_t body_length; 00226 uint32_t body_offset; 00227 }; 00228 00229 #endif
Generated on Wed Jul 13 2022 00:40:26 by 1.7.2