Library for Firebase, PUT, PATCH, POST, GET, DELETE operations supported, (others are available, todo). Based on Mbed's https-example. Tested on STM32F767 using ETHERNET and ESP8266 WIFI interfaces and STM32F446 using ESP8266 WIFI interface.

Dependents:   Firebase-Example

Committer:
star297
Date:
Sun May 10 08:08:23 2020 +0000
Revision:
3:4d7c08734a91
Parent:
0:768ae9838086
added PATCH function

Who changed what in which revision?

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