Reem M / Mbed OS http-server-example1
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                 body = (char*)realloc(body, body_offset + length);
00146             }
00147         }
00148 
00149         memcpy(body + body_offset, at, length);
00150 
00151         body_offset += length;
00152     }
00153 
00154     void* get_body() {
00155         return (void*)body;
00156     }
00157 
00158     string get_body_as_string() {
00159         string s(body, body_offset);
00160         return s;
00161     }
00162 
00163     void increase_body_length(size_t length) {
00164         body_length += length;
00165     }
00166 
00167     size_t get_body_length() {
00168         return body_offset;
00169     }
00170 
00171     bool is_message_complete() {
00172         return is_message_completed;
00173     }
00174 
00175     void set_chunked() {
00176         is_chunked = true;
00177     }
00178 
00179     void set_message_complete() {
00180         is_message_completed = true;
00181     }
00182 
00183 private:
00184     // from http://stackoverflow.com/questions/5820810/case-insensitive-string-comp-in-c
00185     int strcicmp(char const *a, char const *b) {
00186         for (;; a++, b++) {
00187             int d = tolower(*a) - tolower(*b);
00188             if (d != 0 || !*a) {
00189                 return d;
00190             }
00191         }
00192     }
00193 
00194     char tolower(char c) {
00195         if(('A' <= c) && (c <= 'Z')) {
00196             return 'a' + (c - 'A');
00197         }
00198 
00199         return c;
00200     }
00201 
00202     int status_code;
00203     string status_message;
00204     string url;
00205     http_method method;
00206 
00207     vector<string*> header_fields;
00208     vector<string*> header_values;
00209 
00210     bool concat_header_field;
00211     bool concat_header_value;
00212 
00213     size_t expected_content_length;
00214 
00215     bool is_chunked;
00216 
00217     bool is_message_completed;
00218 
00219     char * body;
00220     size_t body_length;
00221     size_t body_offset;
00222 };
00223 
00224 #endif