/* * This file is a part of Winix * and is distributed under the 2-Clause BSD licence. * Author: Tomasz Sowa */ /* * Copyright (c) 2010-2022, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #ifndef headerfile_winix_utils_http #define headerfile_winix_utils_http #include #include #include "core/synchro.h" #include "textstream/textstream.h" #include "core/winixbase.h" namespace Winix { class Http : public WinixBase { public: static const long HTTP_STATUS_200_OK = 200; Http(); ~Http(); Http(const Http &) = delete; Http(Http &&) = delete; /* * we do not copy the space structure but only get a pointer to it * so you have to preserve the structure until get()/put() is called */ Http & add_input_headers(pt::Space * headers); /* * output headers will be provided in a Space structure as key/value pairs (object) * * the first line (http status) will be inserted too (the value part will be empty), e.g. * key="http/1.1 200 ok" * value="" * */ Http & get_output_headers_to(pt::Space * out_headers, bool change_names_to_lower = true); /* * if we don't need all headers but just content-type */ Http & get_output_content_type_to(std::wstring * out_content_type); /* * you don't have to call these methods * if the curl is not initialized it will be initialized automatically from get/put methods */ void initialize_curl_if_needed(); void uninitialize_curl(); /* * we do not copy the string but only get a pointer to its c_str() * so you have to preserve the string until get()/put() is called */ Http & add_bearer_token(const wchar_t * token); Http & add_bearer_token(const std::wstring & token); bool get(const wchar_t * url, std::wstring & out, bool clear_str = true); bool get(const std::wstring & url, std::wstring & out, bool clear_str = true); bool get(const pt::WTextStream & url, std::wstring & out, bool clear_str = true); bool get(const wchar_t * url, pt::WTextStream & out, bool clear_stream = true); bool get(const std::wstring & url, pt::WTextStream & out, bool clear_stream = true); bool get(const pt::WTextStream & url, pt::WTextStream & out, bool clear_stream = true); bool put(const wchar_t * url, const std::string & in, pt::WTextStream & out, bool clear_stream = true); bool put(const std::wstring & url, const std::string & in, pt::WTextStream & out, bool clear_stream = true); bool put(const wchar_t * url, pt::WTextStream & in, pt::WTextStream & out, bool clear_stream = true); /* * return the last http status */ long get_status(); private: CURL * curl; char error_buf[CURL_ERROR_SIZE]; std::string browser_name; int conn_timeout; // timeout in seconds size_t read_function_index; const std::string * read_function_input; curl_slist * http_headers; pt::Space * additional_headers_to_send; pt::Space * output_headers_space; const wchar_t * bearer_token = nullptr; pt::TextStream out_headers_stream; bool change_header_names_to_lower; std::wstring * output_content_type; std::wstring temp_header; std::string temp_header_ascii; std::wstring temp_header_value; std::string temp_header_value_ascii; bool fetch_internal(const char * url, const std::string * in, pt::TextStream & out); static size_t fetch_read_function(char * ptr, size_t size, size_t nmemb, void * userdata); static size_t fetch_write_function(char * ptr, size_t size, size_t nmemb, void * userdata); static size_t fetch_header_function(char * ptr, size_t size, size_t nmemb, void * userdata); void reset_headers(); void add_additional_headers(); void add_bearer_token(); void add_header(const pt::WTextStream & header); void add_header(const std::wstring & header); void skip_white(pt::TextStream::iterator & i); void parse_header_name(pt::TextStream::iterator & i, std::string & name); void parse_header_value(pt::TextStream::iterator & i, std::string & value); void parse_headers(); }; } #endif