Fork of mbed-http

Fork of mbed-http by sandbox

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers http_request_builder.h Source File

http_request_builder.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_REQUEST_BUILDER_H_
00019 #define _MBED_HTTP_REQUEST_BUILDER_H_
00020 
00021 #include <string>
00022 #include <map>
00023 #include "http_parser.h"
00024 #include "http_parsed_url.h"
00025 
00026 class HttpRequestBuilder {
00027 public:
00028     HttpRequestBuilder(http_method a_method, ParsedUrl* a_parsed_url)
00029         : method(a_method), parsed_url(a_parsed_url)
00030     {
00031         set_header("Host", string(parsed_url->host()));
00032     }
00033 
00034     /**
00035      * Set a header for the request
00036      * If the key already exists, it will be overwritten...
00037      */
00038     void set_header(string key, string value) {
00039         map<string, string>::iterator it = headers.find(key);
00040 
00041         if (it != headers.end()) {
00042             it->second = value;
00043         }
00044         else {
00045             headers.insert(headers.end(), pair<string, string>(key, value));
00046         }
00047     }
00048 
00049     char* build(const void* body, size_t body_size, size_t &size) {
00050         const char* method_str = http_method_str(method);
00051 
00052         if (method == HTTP_POST || method == HTTP_PUT || method == HTTP_DELETE || body_size > 0) {
00053             char buffer[10];
00054             snprintf(buffer, 10, "%d", body_size);
00055             set_header("Content-Length", string(buffer));
00056         }
00057 
00058         size = 0;
00059 
00060         // first line is METHOD PATH+QUERY HTTP/1.1\r\n
00061         size += strlen(method_str) + 1 + strlen(parsed_url->path()) + (strlen(parsed_url->query()) ? strlen(parsed_url->query()) + 1 : 0) + 1 + 8 + 2;
00062 
00063         // after that we'll do the headers
00064         typedef map<string, string>::iterator it_type;
00065         for(it_type it = headers.begin(); it != headers.end(); it++) {
00066             // line is KEY: VALUE\r\n
00067             size += it->first.length() + 1 + 1 + it->second.length() + 2;
00068         }
00069 
00070         // then the body, first an extra newline
00071         size += 2;
00072 
00073         // body
00074         size += body_size;
00075 
00076         // extra newline
00077         size += 2;
00078 
00079         // Now let's print it
00080         char* req = (char*)calloc(size + 1, 1);
00081         char* originalReq = req;
00082 
00083         if (strlen(parsed_url->query())) {
00084             sprintf(req, "%s %s?%s HTTP/1.1\r\n", method_str, parsed_url->path(), parsed_url->query());
00085         } else {
00086             sprintf(req, "%s %s%s HTTP/1.1\r\n", method_str, parsed_url->path(), parsed_url->query());
00087         }
00088         req += strlen(method_str) + 1 + strlen(parsed_url->path()) + (strlen(parsed_url->query()) ? strlen(parsed_url->query()) + 1 : 0) + 1 + 8 + 2;
00089 
00090         typedef map<string, string>::iterator it_type;
00091         for(it_type it = headers.begin(); it != headers.end(); it++) {
00092             // line is KEY: VALUE\r\n
00093             sprintf(req, "%s: %s\r\n", it->first.c_str(), it->second.c_str());
00094             req += it->first.length() + 1 + 1 + it->second.length() + 2;
00095         }
00096 
00097         sprintf(req, "\r\n");
00098         req += 2;
00099 
00100         if (body_size > 0) {
00101             memcpy(req, body, body_size);
00102         }
00103         req += body_size;
00104 
00105         sprintf(req, "\r\n");
00106         req += 2;
00107 
00108         // Uncomment to debug...
00109         // printf("----- BEGIN REQUEST -----\n");
00110         // printf("%s", originalReq);
00111         // printf("----- END REQUEST -----\n");
00112 
00113         return originalReq;
00114     }
00115 
00116 private:
00117     http_method method;
00118     ParsedUrl* parsed_url;
00119     map<string, string> headers;
00120 };
00121 
00122 #endif // _MBED_HTTP_REQUEST_BUILDER_H_