summaryrefslogtreecommitdiff
path: root/http.h
diff options
context:
space:
mode:
authorGlenn Smith <glenn@vector35.com>2021-08-13 16:14:48 -0400
committerGlenn Smith <glenn@vector35.com>2021-08-17 16:50:10 -0400
commit54c78775ab4eb53c991ed17e4317bf876dea5bb0 (patch)
treee3852837d01b1c1b6d683692a5ec92b764724195 /http.h
parent176cc79219cdf015cbcf7f90bb6eb5f6a8c59940 (diff)
HTTP C++ library via downloadprovider
Diffstat (limited to 'http.h')
-rw-r--r--http.h361
1 files changed, 361 insertions, 0 deletions
diff --git a/http.h b/http.h
new file mode 100644
index 00000000..c3f0b5a9
--- /dev/null
+++ b/http.h
@@ -0,0 +1,361 @@
+// Copyright (c) 2015-2021 Vector 35 Inc
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#pragma once
+
+#include <vector>
+#include <string>
+#include <optional>
+#include <unordered_map>
+#include <functional>
+#include <utility>
+#include <stdint.h>
+#include "binaryninjaapi.h"
+
+
+namespace BinaryNinja::Http
+{
+
+ enum ResponseCode
+ {
+ Continue = 100,
+ SwitchingProtocols = 101,
+ OK = 200,
+ Created = 201,
+ Accepted = 202,
+ NonAuthoritativeInformation = 203,
+ NoContent = 204,
+ ResetContent = 205,
+ PartialContent = 206,
+ MultipleChoices = 300,
+ MovedPermanently = 301,
+ Found = 302,
+ SeeOther = 303,
+ NotModified = 304,
+ UseProxy = 305,
+ TemporaryRedirect = 307,
+ BadRequest = 400,
+ Unauthorized = 401,
+ PaymentRequired = 402,
+ Forbidden = 403,
+ NotFound = 404,
+ MethodNotAllowed = 405,
+ NotAcceptable = 406,
+ ProxyAuthenticationRequired = 407,
+ RequestTimeout = 408,
+ Conflict = 409,
+ Gone = 410,
+ LengthRequired = 411,
+ PreconditionFailed = 412,
+ RequestEntityTooLarge = 413,
+ RequestURITooLong = 414,
+ UnsupportedMediaType = 415,
+ RequestedRangeNotSatisfiable = 416,
+ ExpectationFailed = 417,
+ ImATeapot = 418,
+ InternalServerError = 500,
+ NotImplemented = 501,
+ BadGateway = 502,
+ ServiceUnavailable = 503,
+ GatewayTimeout = 504,
+ HTTPVersionNotSupported = 505,
+ };
+
+
+ /*!
+ Basic HTTP response structure
+ */
+ struct Response
+ {
+ BinaryNinja::DownloadInstance::Response response;
+ std::vector<uint8_t> body;
+ std::string error;
+
+ /*!
+ Get response body as uint8_t vector
+ \return Response body bytes
+ */
+ std::vector<uint8_t> GetRaw() const noexcept;
+ /*!
+ Get response body as text string
+ \return Response body string
+ */
+ std::string GetString() const noexcept;
+ /*!
+ Get response body as a json value
+ \return Response body json
+ \throws runtime_error On JSON parse error
+ */
+ Json::Value GetJson() const;
+ /*!
+ Get response body as a json value without throwing
+ \param value Output json value
+ \return True if successful
+ */
+ bool GetJson(Json::Value& value) const noexcept;
+ };
+
+
+ /*!
+ Structure for multipart form fields
+ */
+ struct MultipartField
+ {
+ std::string name;
+ std::vector<uint8_t> content;
+ std::optional<std::string> filename;
+
+ /*!
+ Construct a Multipart Field structure with a UTF-8 string encoded body
+ \param name Name of the field to be sent in a POST request
+ \param content Contents of the field
+ */
+ MultipartField(std::string name, const std::string& content):
+ name(std::move(name)), content({}), filename({})
+ {
+ std::copy(content.begin(), content.end(), std::back_inserter(this->content));
+ }
+
+ /*!
+ Construct a Multipart Field structure for a file with a UTF-8 string encoded body
+ \param name Name of the field to be sent in a POST request
+ \param content Contents of the field
+ \param filename Filename associated with the contents
+ */
+ MultipartField(std::string name, const std::string& content, std::string filename):
+ name(std::move(name)), content({}), filename(std::move(filename))
+ {
+ std::copy(content.begin(), content.end(), std::back_inserter(this->content));
+ }
+
+ /*!
+ Construct a Multipart Field structure with a binary blob body
+ \param name Name of the field to be sent in a POST request
+ \param content Contents of the field
+ */
+ MultipartField(std::string name, std::vector<uint8_t> content):
+ name(std::move(name)), content(std::move(content)), filename({})
+ {
+
+ }
+
+ /*!
+ Construct a Multipart Field structure for a file with a binary blob body
+ \param name Name of the field to be sent in a POST request
+ \param content Contents of the field
+ \param filename Filename associated with the contents
+ */
+ MultipartField(std::string name, std::vector<uint8_t> content, std::string filename):
+ name(std::move(name)), content(std::move(content)), filename(std::move(filename))
+ {
+
+ }
+ };
+
+
+ /*!
+ Structure containing HTTP metadata for requests
+ */
+ struct Request
+ {
+ std::string m_method;
+ std::string m_url;
+ std::unordered_map<std::string, std::string> m_headers;
+ std::vector<uint8_t> m_body;
+
+ std::function<bool(size_t, size_t)> m_downloadProgress;
+ std::function<bool(size_t, size_t)> m_uploadProgress;
+
+ /*!
+ Construct an arbitrary HTTP request with an empty body
+ \param method Request method eg GET
+ \param url Target URL eg https://binary.ninja
+ \param headers Header keys/values
+ \param params Query parameters, keys/values
+ \param downloadProgress Function to call for download progress updates
+ \param uploadProgress Function to call for upload progress updates
+ */
+ Request(std::string method, std::string url,
+ std::unordered_map<std::string, std::string> headers = {},
+ std::vector<std::pair<std::string, std::string>> params = {},
+ std::function<bool(size_t, size_t)> downloadProgress = {},
+ std::function<bool(size_t, size_t)> uploadProgress = {});
+
+
+ /*!
+ Construct an arbitrary HTTP request with a binary data body
+ \param method Request method eg GET
+ \param url Target URL eg https://binary.ninja
+ \param headers Header keys/values
+ \param params Query parameters, keys/values
+ \param body Content body (binary data)
+ \param downloadProgress Function to call for download progress updates
+ \param uploadProgress Function to call for upload progress updates
+ */
+ Request(std::string method, std::string url,
+ std::unordered_map<std::string, std::string> headers,
+ std::vector<std::pair<std::string, std::string>> params,
+ std::vector<uint8_t> body,
+ std::function<bool(size_t, size_t)> downloadProgress = {},
+ std::function<bool(size_t, size_t)> uploadProgress = {});
+
+
+ /*!
+ Construct an arbitrary HTTP request with url encoded form fields as the body
+ \param method Request method eg GET
+ \param url Target URL eg https://binary.ninja
+ \param headers Header keys/values
+ \param params Query parameters, keys/values
+ \param formFields HTTP form fields, keys/values (both must be strings)
+ \param downloadProgress Function to call for download progress updates
+ \param uploadProgress Function to call for upload progress updates
+ */
+ Request(std::string method, std::string url,
+ std::unordered_map<std::string, std::string> headers,
+ std::vector<std::pair<std::string, std::string>> params,
+ std::vector<std::pair<std::string, std::string>> formFields,
+ std::function<bool(size_t, size_t)> downloadProgress = {},
+ std::function<bool(size_t, size_t)> uploadProgress = {});
+
+
+ /*!
+ Construct an arbitrary HTTP request with Multipart encoded form fields as the body
+ \param method Request method eg GET
+ \param url Target URL eg https://binary.ninja
+ \param headers Header keys/values
+ \param params Query parameters, keys/values
+ \param formFields HTTP form fields, keys/values (values can be arbitrary data)
+ \param downloadProgress Function to call for download progress updates
+ \param uploadProgress Function to call for upload progress updates
+ */
+ Request(std::string method, std::string url,
+ std::unordered_map<std::string, std::string> headers,
+ std::vector<std::pair<std::string, std::string>> params,
+ std::vector<MultipartField> formFields,
+ std::function<bool(size_t, size_t)> downloadProgress = {},
+ std::function<bool(size_t, size_t)> uploadProgress = {});
+
+
+ /*!
+ Construct an HTTP GET request
+ \param url Target URL eg https://binary.ninja
+ \param headers Header keys/values
+ \param params Query parameters, keys/values
+ \param downloadProgress Function to call for download progress updates
+ \param uploadProgress Function to call for upload progress updates
+ \return Request structure with specified fields
+ */
+ static Request Get(std::string url,
+ std::unordered_map<std::string, std::string> headers = {},
+ std::vector<std::pair<std::string, std::string>> params = {},
+ std::function<bool(size_t, size_t)> downloadProgress = {},
+ std::function<bool(size_t, size_t)> uploadProgress = {});
+
+
+ /*!
+ Construct an HTTP POST request with a binary data body
+ \param url Target URL eg https://binary.ninja
+ \param headers Header keys/values
+ \param params Query parameters, keys/values
+ \param body Request body data
+ \param downloadProgress Function to call for download progress updates
+ \param uploadProgress Function to call for upload progress updates
+ \return Request structure with specified fields
+ */
+ static Request Post(std::string url,
+ std::unordered_map<std::string, std::string> headers = {},
+ std::vector<std::pair<std::string, std::string>> params = {},
+ std::vector<uint8_t> body = {},
+ std::function<bool(size_t, size_t)> downloadProgress = {},
+ std::function<bool(size_t, size_t)> uploadProgress = {});
+
+
+ /*!
+ Construct an HTTP POST request with url encoded form fields as the body
+ \param url Target URL eg https://binary.ninja
+ \param headers Header keys/values
+ \param params Query parameters, keys/values
+ \param formFields HTTP form fields, keys/values (both must be strings)
+ \param downloadProgress Function to call for download progress updates
+ \param uploadProgress Function to call for upload progress updates
+ \return Request structure with specified fields
+ */
+ static Request Post(std::string url,
+ std::unordered_map<std::string, std::string> headers,
+ std::vector<std::pair<std::string, std::string>> params,
+ std::vector<std::pair<std::string, std::string>> formFields,
+ std::function<bool(size_t, size_t)> downloadProgress = {},
+ std::function<bool(size_t, size_t)> uploadProgress = {});
+
+
+ /*!
+ Construct an HTTP POST request with Multipart encoded form fields as the body
+ \param url Target URL eg https://binary.ninja
+ \param headers Header keys/values
+ \param params Query parameters, keys/values
+ \param formFields HTTP form fields, keys/values (values can be arbitrary data)
+ \param downloadProgress Function to call for download progress updates
+ \param uploadProgress Function to call for upload progress updates
+ \return Request structure with specified fields
+ */
+ static Request Post(std::string url,
+ std::unordered_map<std::string, std::string> headers,
+ std::vector<std::pair<std::string, std::string>> params,
+ std::vector<MultipartField> formFields,
+ std::function<bool(size_t, size_t)> downloadProgress = {},
+ std::function<bool(size_t, size_t)> uploadProgress = {});
+ };
+
+
+ /*!
+ Convert a string to a URLEncoded form-field safe form
+ \param str Input string
+ \return URLEncoded string
+ */
+ std::string UrlEncode(const std::string& str);
+
+
+ /*!
+ Convert a list of key/value pair strings into a URLEncoded form body
+ \param fields Input key/value pairs
+ \return URLEncoded form body
+ */
+ std::string UrlEncode(const std::vector<std::pair<std::string, std::string>>& fields);
+
+
+ /*!
+ Convert a list of form fields (potentially containing binary data) into a multipart encoded
+ form body
+ \param fields Input fields
+ \param boundary Output boundary between fields in the body (for Content-Type header)
+ \return Multipart encoded form body
+ */
+ std::vector<uint8_t> MultipartEncode(const std::vector<MultipartField>& fields, std::string& boundary);
+
+
+ /*!
+ Perform an HTTP request as specified by a Request, storing results in a Response
+ \param instance DownloadInstance instance
+ \param request Input Request structure with fields
+ \param response Output Response structure with body
+ \return Zero or greater on success
+ */
+ int Perform(const BinaryNinja::Ref<BinaryNinja::DownloadInstance>& instance, const Request& request, Response& response);
+} \ No newline at end of file