HTTP and HTTPS library for Mbed OS 5

Dependents:   MQTTGateway2 MQTTGatewayK64 http-example-wnc GuardRoom ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers http_response.h Source File

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