This library is used to make HTTP and HTTPS calls from mbed OS 5 applications.
Fork of mbed-http by
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 (size_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 (size_t ix = 0; ix < header_fields.size(); ix++) { 00110 if (strcicmp(header_fields[ix]->c_str(), "content-length") == 0) { 00111 expected_content_length = (size_t)atoi(header_values[ix]->c_str()); 00112 break; 00113 } 00114 } 00115 } 00116 00117 size_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, size_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 printf("[HttpResponse] realloc for %d bytes failed\n", body_offset + length); 00149 free(original_body); 00150 return; 00151 } 00152 } 00153 } 00154 00155 memcpy(body + body_offset, at, length); 00156 00157 body_offset += length; 00158 } 00159 00160 void* get_body() { 00161 return (void*)body; 00162 } 00163 00164 string get_body_as_string() { 00165 string s(body, body_offset); 00166 return s; 00167 } 00168 00169 void increase_body_length(size_t length) { 00170 body_length += length; 00171 } 00172 00173 size_t get_body_length() { 00174 return body_offset; 00175 } 00176 00177 bool is_message_complete() { 00178 return is_message_completed; 00179 } 00180 00181 void set_chunked() { 00182 is_chunked = true; 00183 } 00184 00185 void set_message_complete() { 00186 is_message_completed = true; 00187 } 00188 00189 private: 00190 // from http://stackoverflow.com/questions/5820810/case-insensitive-string-comp-in-c 00191 int strcicmp(char const *a, char const *b) { 00192 for (;; a++, b++) { 00193 int d = tolower(*a) - tolower(*b); 00194 if (d != 0 || !*a) { 00195 return d; 00196 } 00197 } 00198 } 00199 00200 char tolower(char c) { 00201 if(('A' <= c) && (c <= 'Z')) { 00202 return 'a' + (c - 'A'); 00203 } 00204 00205 return c; 00206 } 00207 00208 int status_code; 00209 string status_message; 00210 string url; 00211 http_method method; 00212 00213 vector<string*> header_fields; 00214 vector<string*> header_values; 00215 00216 bool concat_header_field; 00217 bool concat_header_value; 00218 00219 size_t expected_content_length; 00220 00221 bool is_chunked; 00222 00223 bool is_message_completed; 00224 00225 char * body; 00226 size_t body_length; 00227 size_t body_offset; 00228 }; 00229 00230 #endif
Generated on Fri Jul 15 2022 18:07:13 by 1.7.2