Fork of 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         have_content_length = false;
00034         is_chunked = false;
00035         is_message_completed = false;
00036         body_length = 0;
00037         body_offset = 0;
00038         body = NULL;
00039     }
00040 
00041     ~HttpResponse() {
00042         if (body != NULL) {
00043             free(body);
00044         }
00045 
00046         for (size_t ix = 0; ix < header_fields.size(); ix++) {
00047             delete header_fields[ix];
00048             delete header_values[ix];
00049         }
00050     }
00051 
00052     void set_status(int a_status_code, string a_status_message) {
00053         status_code = a_status_code;
00054         status_message = a_status_message;
00055     }
00056 
00057     int get_status_code() {
00058         return status_code;
00059     }
00060 
00061     string get_status_message() {
00062         return status_message;
00063     }
00064 
00065     void set_header_field(string field) {
00066         concat_header_value = false;
00067 
00068         if (strcicmp(field.c_str(), "content-length") == 0) {
00069             // we have a content-length
00070             have_content_length = true;
00071         }
00072 
00073         // headers can be chunked
00074         if (concat_header_field) {
00075             *header_fields[header_fields.size() - 1] = (*header_fields[header_fields.size() - 1]) + field;
00076         }
00077         else {
00078             header_fields.push_back(new string(field));
00079         }
00080 
00081         concat_header_field = true;
00082     }
00083 
00084     void set_header_value(string value) {
00085         concat_header_field = false;
00086 
00087         // headers can be chunked
00088         if (concat_header_value) {
00089             *header_values[header_values.size() - 1] = (*header_values[header_values.size() - 1]) + value;
00090         }
00091         else {
00092             header_values.push_back(new string(value));
00093         }
00094 
00095         concat_header_value = true;
00096     }
00097 
00098     void set_headers_complete() {
00099         for (size_t ix = 0; ix < header_fields.size(); ix++) {
00100             if (strcicmp(header_fields[ix]->c_str(), "content-length") == 0) {
00101                 expected_content_length = (size_t)atoi(header_values[ix]->c_str());
00102                 break;
00103             }
00104         }
00105     }
00106 
00107     size_t get_headers_length() {
00108         return header_fields.size();
00109     }
00110 
00111     vector<string*> get_headers_fields() {
00112         return header_fields;
00113     }
00114 
00115     vector<string*> get_headers_values() {
00116         return header_values;
00117     }
00118 
00119     void set_body(const char *at, size_t length) {
00120         // only malloc when this fn is called, so we don't alloc when body callback's are enabled
00121         if (body == NULL && !is_chunked) {
00122             body = (char*)malloc(expected_content_length);
00123         }
00124 
00125         if (is_chunked) {
00126             if (body == NULL) {
00127                 body = (char*)malloc(length);
00128             }
00129             else {
00130                 body = (char*)realloc(body, body_offset + length);
00131             }
00132         }
00133 
00134         memcpy(body + body_offset, at, length);
00135 
00136         body_offset += length;
00137     }
00138 
00139     void* get_body() {
00140         return (void*)body;
00141     }
00142 
00143     string get_body_as_string() {
00144         string s(body, body_offset);
00145         return s;
00146     }
00147 
00148     void increase_body_length(size_t length) {
00149         body_length += length;
00150     }
00151 
00152     size_t get_body_length() {
00153         return body_offset;
00154     }
00155 
00156     bool is_message_complete() {
00157         return is_message_completed;
00158     }
00159 
00160     void set_chunked() {
00161         is_chunked = true;
00162     }
00163 
00164     void set_message_complete() {
00165         is_message_completed = true;
00166     }
00167 
00168     bool get_have_content_length() {
00169         return have_content_length;
00170     }
00171 
00172 private:
00173     // from http://stackoverflow.com/questions/5820810/case-insensitive-string-comp-in-c
00174     int strcicmp(char const *a, char const *b) {
00175         for (;; a++, b++) {
00176             int d = tolower(*a) - tolower(*b);
00177             if (d != 0 || !*a) {
00178                 return d;
00179             }
00180         }
00181     }
00182 
00183     char tolower(char c) {
00184         if(('A' <= c) && (c <= 'Z')) {
00185             return 'a' + (c - 'A');
00186         }
00187 
00188         return c;
00189     }
00190 
00191     int status_code;
00192     string status_message;
00193 
00194     vector<string*> header_fields;
00195     vector<string*> header_values;
00196 
00197     bool concat_header_field;
00198     bool concat_header_value;
00199 
00200     size_t expected_content_length;
00201 
00202     bool is_chunked;
00203     bool have_content_length;
00204     bool is_message_completed;
00205 
00206     char * body;
00207     size_t body_length;
00208     size_t body_offset;
00209 };
00210 #endif