mbed-http

Fork of mbed-http by sandbox

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 (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