http

Committer:
DuaaAbusharkh
Date:
Mon Apr 15 08:30:22 2019 +0000
Revision:
0:a49e37a83a7a
blink

Who changed what in which revision?

UserRevisionLine numberNew contents of line
DuaaAbusharkh 0:a49e37a83a7a 1 /*
DuaaAbusharkh 0:a49e37a83a7a 2 * PackageLicenseDeclared: Apache-2.0
DuaaAbusharkh 0:a49e37a83a7a 3 * Copyright (c) 2017 ARM Limited
DuaaAbusharkh 0:a49e37a83a7a 4 *
DuaaAbusharkh 0:a49e37a83a7a 5 * Licensed under the Apache License, Version 2.0 (the "License");
DuaaAbusharkh 0:a49e37a83a7a 6 * you may not use this file except in compliance with the License.
DuaaAbusharkh 0:a49e37a83a7a 7 * You may obtain a copy of the License at
DuaaAbusharkh 0:a49e37a83a7a 8 *
DuaaAbusharkh 0:a49e37a83a7a 9 * http://www.apache.org/licenses/LICENSE-2.0
DuaaAbusharkh 0:a49e37a83a7a 10 *
DuaaAbusharkh 0:a49e37a83a7a 11 * Unless required by applicable law or agreed to in writing, software
DuaaAbusharkh 0:a49e37a83a7a 12 * distributed under the License is distributed on an "AS IS" BASIS,
DuaaAbusharkh 0:a49e37a83a7a 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
DuaaAbusharkh 0:a49e37a83a7a 14 * See the License for the specific language governing permissions and
DuaaAbusharkh 0:a49e37a83a7a 15 * limitations under the License.
DuaaAbusharkh 0:a49e37a83a7a 16 */
DuaaAbusharkh 0:a49e37a83a7a 17
DuaaAbusharkh 0:a49e37a83a7a 18 #ifndef _MBED_HTTP_HTTP_RESPONSE
DuaaAbusharkh 0:a49e37a83a7a 19 #define _MBED_HTTP_HTTP_RESPONSE
DuaaAbusharkh 0:a49e37a83a7a 20 #include <string>
DuaaAbusharkh 0:a49e37a83a7a 21 #include <vector>
DuaaAbusharkh 0:a49e37a83a7a 22 #include "http_parser.h"
DuaaAbusharkh 0:a49e37a83a7a 23
DuaaAbusharkh 0:a49e37a83a7a 24 using namespace std;
DuaaAbusharkh 0:a49e37a83a7a 25
DuaaAbusharkh 0:a49e37a83a7a 26 class HttpResponse {
DuaaAbusharkh 0:a49e37a83a7a 27 public:
DuaaAbusharkh 0:a49e37a83a7a 28 HttpResponse() {
DuaaAbusharkh 0:a49e37a83a7a 29 status_code = 0;
DuaaAbusharkh 0:a49e37a83a7a 30 concat_header_field = false;
DuaaAbusharkh 0:a49e37a83a7a 31 concat_header_value = false;
DuaaAbusharkh 0:a49e37a83a7a 32 expected_content_length = 0;
DuaaAbusharkh 0:a49e37a83a7a 33 is_chunked = false;
DuaaAbusharkh 0:a49e37a83a7a 34 is_message_completed = false;
DuaaAbusharkh 0:a49e37a83a7a 35 body_length = 0;
DuaaAbusharkh 0:a49e37a83a7a 36 body_offset = 0;
DuaaAbusharkh 0:a49e37a83a7a 37 body = NULL;
DuaaAbusharkh 0:a49e37a83a7a 38 }
DuaaAbusharkh 0:a49e37a83a7a 39
DuaaAbusharkh 0:a49e37a83a7a 40 ~HttpResponse() {
DuaaAbusharkh 0:a49e37a83a7a 41 if (body != NULL) {
DuaaAbusharkh 0:a49e37a83a7a 42 free(body);
DuaaAbusharkh 0:a49e37a83a7a 43 }
DuaaAbusharkh 0:a49e37a83a7a 44
DuaaAbusharkh 0:a49e37a83a7a 45 for (size_t ix = 0; ix < header_fields.size(); ix++) {
DuaaAbusharkh 0:a49e37a83a7a 46 delete header_fields[ix];
DuaaAbusharkh 0:a49e37a83a7a 47 delete header_values[ix];
DuaaAbusharkh 0:a49e37a83a7a 48 }
DuaaAbusharkh 0:a49e37a83a7a 49 }
DuaaAbusharkh 0:a49e37a83a7a 50
DuaaAbusharkh 0:a49e37a83a7a 51 void set_status(int a_status_code, string a_status_message) {
DuaaAbusharkh 0:a49e37a83a7a 52 status_code = a_status_code;
DuaaAbusharkh 0:a49e37a83a7a 53 status_message = a_status_message;
DuaaAbusharkh 0:a49e37a83a7a 54 }
DuaaAbusharkh 0:a49e37a83a7a 55
DuaaAbusharkh 0:a49e37a83a7a 56 int get_status_code() {
DuaaAbusharkh 0:a49e37a83a7a 57 return status_code;
DuaaAbusharkh 0:a49e37a83a7a 58 }
DuaaAbusharkh 0:a49e37a83a7a 59
DuaaAbusharkh 0:a49e37a83a7a 60 string get_status_message() {
DuaaAbusharkh 0:a49e37a83a7a 61 return status_message;
DuaaAbusharkh 0:a49e37a83a7a 62 }
DuaaAbusharkh 0:a49e37a83a7a 63
DuaaAbusharkh 0:a49e37a83a7a 64 void set_url(string a_url) {
DuaaAbusharkh 0:a49e37a83a7a 65 url = a_url;
DuaaAbusharkh 0:a49e37a83a7a 66 }
DuaaAbusharkh 0:a49e37a83a7a 67
DuaaAbusharkh 0:a49e37a83a7a 68 string get_url() {
DuaaAbusharkh 0:a49e37a83a7a 69 return url;
DuaaAbusharkh 0:a49e37a83a7a 70 }
DuaaAbusharkh 0:a49e37a83a7a 71
DuaaAbusharkh 0:a49e37a83a7a 72 void set_method(http_method a_method) {
DuaaAbusharkh 0:a49e37a83a7a 73 method = a_method;
DuaaAbusharkh 0:a49e37a83a7a 74 }
DuaaAbusharkh 0:a49e37a83a7a 75
DuaaAbusharkh 0:a49e37a83a7a 76 http_method get_method() {
DuaaAbusharkh 0:a49e37a83a7a 77 return method;
DuaaAbusharkh 0:a49e37a83a7a 78 }
DuaaAbusharkh 0:a49e37a83a7a 79
DuaaAbusharkh 0:a49e37a83a7a 80 void set_header_field(string field) {
DuaaAbusharkh 0:a49e37a83a7a 81 concat_header_value = false;
DuaaAbusharkh 0:a49e37a83a7a 82
DuaaAbusharkh 0:a49e37a83a7a 83 // headers can be chunked
DuaaAbusharkh 0:a49e37a83a7a 84 if (concat_header_field) {
DuaaAbusharkh 0:a49e37a83a7a 85 *header_fields[header_fields.size() - 1] = (*header_fields[header_fields.size() - 1]) + field;
DuaaAbusharkh 0:a49e37a83a7a 86 }
DuaaAbusharkh 0:a49e37a83a7a 87 else {
DuaaAbusharkh 0:a49e37a83a7a 88 header_fields.push_back(new string(field));
DuaaAbusharkh 0:a49e37a83a7a 89 }
DuaaAbusharkh 0:a49e37a83a7a 90
DuaaAbusharkh 0:a49e37a83a7a 91 concat_header_field = true;
DuaaAbusharkh 0:a49e37a83a7a 92 }
DuaaAbusharkh 0:a49e37a83a7a 93
DuaaAbusharkh 0:a49e37a83a7a 94 void set_header_value(string value) {
DuaaAbusharkh 0:a49e37a83a7a 95 concat_header_field = false;
DuaaAbusharkh 0:a49e37a83a7a 96
DuaaAbusharkh 0:a49e37a83a7a 97 // headers can be chunked
DuaaAbusharkh 0:a49e37a83a7a 98 if (concat_header_value) {
DuaaAbusharkh 0:a49e37a83a7a 99 *header_values[header_values.size() - 1] = (*header_values[header_values.size() - 1]) + value;
DuaaAbusharkh 0:a49e37a83a7a 100 }
DuaaAbusharkh 0:a49e37a83a7a 101 else {
DuaaAbusharkh 0:a49e37a83a7a 102 header_values.push_back(new string(value));
DuaaAbusharkh 0:a49e37a83a7a 103 }
DuaaAbusharkh 0:a49e37a83a7a 104
DuaaAbusharkh 0:a49e37a83a7a 105 concat_header_value = true;
DuaaAbusharkh 0:a49e37a83a7a 106 }
DuaaAbusharkh 0:a49e37a83a7a 107
DuaaAbusharkh 0:a49e37a83a7a 108 void set_headers_complete() {
DuaaAbusharkh 0:a49e37a83a7a 109 for (size_t ix = 0; ix < header_fields.size(); ix++) {
DuaaAbusharkh 0:a49e37a83a7a 110 if (strcicmp(header_fields[ix]->c_str(), "content-length") == 0) {
DuaaAbusharkh 0:a49e37a83a7a 111 expected_content_length = (size_t)atoi(header_values[ix]->c_str());
DuaaAbusharkh 0:a49e37a83a7a 112 break;
DuaaAbusharkh 0:a49e37a83a7a 113 }
DuaaAbusharkh 0:a49e37a83a7a 114 }
DuaaAbusharkh 0:a49e37a83a7a 115 }
DuaaAbusharkh 0:a49e37a83a7a 116
DuaaAbusharkh 0:a49e37a83a7a 117 size_t get_headers_length() {
DuaaAbusharkh 0:a49e37a83a7a 118 return header_fields.size();
DuaaAbusharkh 0:a49e37a83a7a 119 }
DuaaAbusharkh 0:a49e37a83a7a 120
DuaaAbusharkh 0:a49e37a83a7a 121 vector<string*> get_headers_fields() {
DuaaAbusharkh 0:a49e37a83a7a 122 return header_fields;
DuaaAbusharkh 0:a49e37a83a7a 123 }
DuaaAbusharkh 0:a49e37a83a7a 124
DuaaAbusharkh 0:a49e37a83a7a 125 vector<string*> get_headers_values() {
DuaaAbusharkh 0:a49e37a83a7a 126 return header_values;
DuaaAbusharkh 0:a49e37a83a7a 127 }
DuaaAbusharkh 0:a49e37a83a7a 128
DuaaAbusharkh 0:a49e37a83a7a 129 void set_body(const char *at, size_t length) {
DuaaAbusharkh 0:a49e37a83a7a 130 // Connection: close, could not specify Content-Length, nor chunked... So do it like this:
DuaaAbusharkh 0:a49e37a83a7a 131 if (expected_content_length == 0 && length > 0) {
DuaaAbusharkh 0:a49e37a83a7a 132 is_chunked = true;
DuaaAbusharkh 0:a49e37a83a7a 133 }
DuaaAbusharkh 0:a49e37a83a7a 134
DuaaAbusharkh 0:a49e37a83a7a 135 // only malloc when this fn is called, so we don't alloc when body callback's are enabled
DuaaAbusharkh 0:a49e37a83a7a 136 if (body == NULL && !is_chunked) {
DuaaAbusharkh 0:a49e37a83a7a 137 body = (char*)malloc(expected_content_length);
DuaaAbusharkh 0:a49e37a83a7a 138 }
DuaaAbusharkh 0:a49e37a83a7a 139
DuaaAbusharkh 0:a49e37a83a7a 140 if (is_chunked) {
DuaaAbusharkh 0:a49e37a83a7a 141 if (body == NULL) {
DuaaAbusharkh 0:a49e37a83a7a 142 body = (char*)malloc(length);
DuaaAbusharkh 0:a49e37a83a7a 143 }
DuaaAbusharkh 0:a49e37a83a7a 144 else {
DuaaAbusharkh 0:a49e37a83a7a 145 body = (char*)realloc(body, body_offset + length);
DuaaAbusharkh 0:a49e37a83a7a 146 }
DuaaAbusharkh 0:a49e37a83a7a 147 }
DuaaAbusharkh 0:a49e37a83a7a 148
DuaaAbusharkh 0:a49e37a83a7a 149 memcpy(body + body_offset, at, length);
DuaaAbusharkh 0:a49e37a83a7a 150
DuaaAbusharkh 0:a49e37a83a7a 151 body_offset += length;
DuaaAbusharkh 0:a49e37a83a7a 152 }
DuaaAbusharkh 0:a49e37a83a7a 153
DuaaAbusharkh 0:a49e37a83a7a 154 void* get_body() {
DuaaAbusharkh 0:a49e37a83a7a 155 return (void*)body;
DuaaAbusharkh 0:a49e37a83a7a 156 }
DuaaAbusharkh 0:a49e37a83a7a 157
DuaaAbusharkh 0:a49e37a83a7a 158 string get_body_as_string() {
DuaaAbusharkh 0:a49e37a83a7a 159 string s(body, body_offset);
DuaaAbusharkh 0:a49e37a83a7a 160 return s;
DuaaAbusharkh 0:a49e37a83a7a 161 }
DuaaAbusharkh 0:a49e37a83a7a 162
DuaaAbusharkh 0:a49e37a83a7a 163 void increase_body_length(size_t length) {
DuaaAbusharkh 0:a49e37a83a7a 164 body_length += length;
DuaaAbusharkh 0:a49e37a83a7a 165 }
DuaaAbusharkh 0:a49e37a83a7a 166
DuaaAbusharkh 0:a49e37a83a7a 167 size_t get_body_length() {
DuaaAbusharkh 0:a49e37a83a7a 168 return body_offset;
DuaaAbusharkh 0:a49e37a83a7a 169 }
DuaaAbusharkh 0:a49e37a83a7a 170
DuaaAbusharkh 0:a49e37a83a7a 171 bool is_message_complete() {
DuaaAbusharkh 0:a49e37a83a7a 172 return is_message_completed;
DuaaAbusharkh 0:a49e37a83a7a 173 }
DuaaAbusharkh 0:a49e37a83a7a 174
DuaaAbusharkh 0:a49e37a83a7a 175 void set_chunked() {
DuaaAbusharkh 0:a49e37a83a7a 176 is_chunked = true;
DuaaAbusharkh 0:a49e37a83a7a 177 }
DuaaAbusharkh 0:a49e37a83a7a 178
DuaaAbusharkh 0:a49e37a83a7a 179 void set_message_complete() {
DuaaAbusharkh 0:a49e37a83a7a 180 is_message_completed = true;
DuaaAbusharkh 0:a49e37a83a7a 181 }
DuaaAbusharkh 0:a49e37a83a7a 182
DuaaAbusharkh 0:a49e37a83a7a 183 private:
DuaaAbusharkh 0:a49e37a83a7a 184 // from http://stackoverflow.com/questions/5820810/case-insensitive-string-comp-in-c
DuaaAbusharkh 0:a49e37a83a7a 185 int strcicmp(char const *a, char const *b) {
DuaaAbusharkh 0:a49e37a83a7a 186 for (;; a++, b++) {
DuaaAbusharkh 0:a49e37a83a7a 187 int d = tolower(*a) - tolower(*b);
DuaaAbusharkh 0:a49e37a83a7a 188 if (d != 0 || !*a) {
DuaaAbusharkh 0:a49e37a83a7a 189 return d;
DuaaAbusharkh 0:a49e37a83a7a 190 }
DuaaAbusharkh 0:a49e37a83a7a 191 }
DuaaAbusharkh 0:a49e37a83a7a 192 }
DuaaAbusharkh 0:a49e37a83a7a 193
DuaaAbusharkh 0:a49e37a83a7a 194 char tolower(char c) {
DuaaAbusharkh 0:a49e37a83a7a 195 if(('A' <= c) && (c <= 'Z')) {
DuaaAbusharkh 0:a49e37a83a7a 196 return 'a' + (c - 'A');
DuaaAbusharkh 0:a49e37a83a7a 197 }
DuaaAbusharkh 0:a49e37a83a7a 198
DuaaAbusharkh 0:a49e37a83a7a 199 return c;
DuaaAbusharkh 0:a49e37a83a7a 200 }
DuaaAbusharkh 0:a49e37a83a7a 201
DuaaAbusharkh 0:a49e37a83a7a 202 int status_code;
DuaaAbusharkh 0:a49e37a83a7a 203 string status_message;
DuaaAbusharkh 0:a49e37a83a7a 204 string url;
DuaaAbusharkh 0:a49e37a83a7a 205 http_method method;
DuaaAbusharkh 0:a49e37a83a7a 206
DuaaAbusharkh 0:a49e37a83a7a 207 vector<string*> header_fields;
DuaaAbusharkh 0:a49e37a83a7a 208 vector<string*> header_values;
DuaaAbusharkh 0:a49e37a83a7a 209
DuaaAbusharkh 0:a49e37a83a7a 210 bool concat_header_field;
DuaaAbusharkh 0:a49e37a83a7a 211 bool concat_header_value;
DuaaAbusharkh 0:a49e37a83a7a 212
DuaaAbusharkh 0:a49e37a83a7a 213 size_t expected_content_length;
DuaaAbusharkh 0:a49e37a83a7a 214
DuaaAbusharkh 0:a49e37a83a7a 215 bool is_chunked;
DuaaAbusharkh 0:a49e37a83a7a 216
DuaaAbusharkh 0:a49e37a83a7a 217 bool is_message_completed;
DuaaAbusharkh 0:a49e37a83a7a 218
DuaaAbusharkh 0:a49e37a83a7a 219 char * body;
DuaaAbusharkh 0:a49e37a83a7a 220 size_t body_length;
DuaaAbusharkh 0:a49e37a83a7a 221 size_t body_offset;
DuaaAbusharkh 0:a49e37a83a7a 222 };
DuaaAbusharkh 0:a49e37a83a7a 223
DuaaAbusharkh 0:a49e37a83a7a 224 #endif