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

Revision:
0:768ae9838086
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/http_response.h	Thu Jan 23 22:18:11 2020 +0000
@@ -0,0 +1,229 @@
+/*
+ * PackageLicenseDeclared: Apache-2.0
+ * Copyright (c) 2017 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _MBED_HTTP_HTTP_RESPONSE
+#define _MBED_HTTP_HTTP_RESPONSE
+#include <string>
+#include <vector>
+#include "http_parser.h"
+
+using namespace std;
+
+class HttpResponse {
+public:
+    HttpResponse() {
+        status_code = 0;
+        concat_header_field = false;
+        concat_header_value = false;
+        expected_content_length = 0;
+        is_chunked = false;
+        is_message_completed = false;
+        body_length = 0;
+        body_offset = 0;
+        body = NULL;
+    }
+
+    ~HttpResponse() {
+        if (body != NULL) {
+            free(body);
+        }
+
+        for (uint32_t ix = 0; ix < header_fields.size(); ix++) {
+            delete header_fields[ix];
+            delete header_values[ix];
+        }
+    }
+
+    void set_status(int a_status_code, string a_status_message) {
+        status_code = a_status_code;
+        status_message = a_status_message;
+    }
+
+    int get_status_code() {
+        return status_code;
+    }
+
+    string get_status_message() {
+        return status_message;
+    }
+
+    void set_url(string a_url) {
+        url = a_url;
+    }
+
+    string get_url() {
+        return url;
+    }
+
+    void set_method(http_method a_method) {
+        method = a_method;
+    }
+
+    http_method get_method() {
+        return method;
+    }
+
+    void set_header_field(string field) {
+        concat_header_value = false;
+
+        // headers can be chunked
+        if (concat_header_field) {
+            *header_fields[header_fields.size() - 1] = (*header_fields[header_fields.size() - 1]) + field;
+        }
+        else {
+            header_fields.push_back(new string(field));
+        }
+
+        concat_header_field = true;
+    }
+
+    void set_header_value(string value) {
+        concat_header_field = false;
+
+        // headers can be chunked
+        if (concat_header_value) {
+            *header_values[header_values.size() - 1] = (*header_values[header_values.size() - 1]) + value;
+        }
+        else {
+            header_values.push_back(new string(value));
+        }
+
+        concat_header_value = true;
+    }
+
+    void set_headers_complete() {
+        for (uint32_t ix = 0; ix < header_fields.size(); ix++) {
+            if (strcicmp(header_fields[ix]->c_str(), "content-length") == 0) {
+                expected_content_length = (uint32_t)atoi(header_values[ix]->c_str());
+                break;
+            }
+        }
+    }
+
+    uint32_t get_headers_length() {
+        return header_fields.size();
+    }
+
+    vector<string*> get_headers_fields() {
+        return header_fields;
+    }
+
+    vector<string*> get_headers_values() {
+        return header_values;
+    }
+
+    void set_body(const char *at, uint32_t length) {
+        // Connection: close, could not specify Content-Length, nor chunked... So do it like this:
+        if (expected_content_length == 0 && length > 0) {
+            is_chunked = true;
+        }
+
+        // only malloc when this fn is called, so we don't alloc when body callback's are enabled
+        if (body == NULL && !is_chunked) {
+            body = (char*)malloc(expected_content_length);
+        }
+
+        if (is_chunked) {
+            if (body == NULL) {
+                body = (char*)malloc(length);
+            }
+            else {
+                char* original_body = body;
+                body = (char*)realloc(body, body_offset + length);
+                if (body == NULL) {
+                    free(original_body);
+                    return;
+                }
+            }
+        }
+
+        memcpy(body + body_offset, at, length);
+
+        body_offset += length;
+    }
+
+    void* get_body() {
+        return (void*)body;
+    }
+
+    string get_body_as_string() {
+        string s(body, body_offset);
+        return s;
+    }
+
+    void increase_body_length(uint32_t length) {
+        body_length += length;
+    }
+
+    uint32_t get_body_length() {
+        return body_offset;
+    }
+
+    bool is_message_complete() {
+        return is_message_completed;
+    }
+
+    void set_chunked() {
+        is_chunked = true;
+    }
+
+    void set_message_complete() {
+        is_message_completed = true;
+    }
+
+private:
+    // from http://stackoverflow.com/questions/5820810/case-insensitive-string-comp-in-c
+    int strcicmp(char const *a, char const *b) {
+        for (;; a++, b++) {
+            int d = tolower(*a) - tolower(*b);
+            if (d != 0 || !*a) {
+                return d;
+            }
+        }
+    }
+
+    char tolower(char c) {
+        if(('A' <= c) && (c <= 'Z')) {
+            return 'a' + (c - 'A');
+        }
+
+        return c;
+    }
+
+    int status_code;
+    string status_message;
+    string url;
+    http_method method;
+
+    vector<string*> header_fields;
+    vector<string*> header_values;
+
+    bool concat_header_field;
+    bool concat_header_value;
+
+    uint32_t expected_content_length;
+
+    bool is_chunked;
+
+    bool is_message_completed;
+
+    char * body;
+    uint32_t body_length;
+    uint32_t body_offset;
+};
+
+#endif