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