1 /* 2 Copyright (c) DataStax, Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 #ifndef DATASTAX_INTERNAL_HTTP_CLIENT_HPP 18 #define DATASTAX_INTERNAL_HTTP_CLIENT_HPP 19 20 #include "address.hpp" 21 #include "callback.hpp" 22 #include "cloud_secure_connection_config.hpp" 23 #include "event_loop.hpp" 24 #include "http_parser.h" 25 #include "ref_counted.hpp" 26 #include "socket_connector.hpp" 27 #include "string.hpp" 28 29 namespace datastax { namespace internal { namespace core { 30 31 class HttpClient : public RefCounted<HttpClient> { 32 public: 33 typedef SharedRefPtr<HttpClient> Ptr; 34 typedef internal::Callback<void, HttpClient*> Callback; 35 36 enum HttpClientError { 37 HTTP_CLIENT_OK, 38 HTTP_CLIENT_CANCELED, 39 HTTP_CLIENT_ERROR_SOCKET, 40 HTTP_CLIENT_ERROR_PARSING, 41 HTTP_CLIENT_ERROR_HTTP_STATUS, 42 HTTP_CLIENT_ERROR_TIMEOUT, 43 HTTP_CLIENT_ERROR_CLOSED 44 }; 45 46 HttpClient(const Address& address, const String& path, const Callback& callback); 47 48 HttpClient* with_settings(const SocketSettings& settings); 49 50 HttpClient* with_request_timeout_ms(uint64_t request_timeout_ms); 51 is_ok() const52 bool is_ok() const { return error_code_ == HTTP_CLIENT_OK; } is_error_status_code() const53 bool is_error_status_code() const { return error_code_ == HTTP_CLIENT_ERROR_HTTP_STATUS; } is_canceled() const54 bool is_canceled() const { return error_code_ == HTTP_CLIENT_CANCELED; } error_code() const55 HttpClientError error_code() const { return error_code_; } error_message() const56 String error_message() const { return error_message_; } status_code() const57 unsigned status_code() const { return status_code_; } content_type() const58 const String& content_type() const { return content_type_; } response_body() const59 const String& response_body() const { return response_body_; } 60 61 void request(uv_loop_t* loop); 62 void cancel(); 63 64 private: 65 friend class HttpClientSocketHandler; 66 friend class HttpClientSslSocketHandler; 67 68 private: 69 void on_socket_connect(SocketConnector* connector); 70 void on_read(char* buf, ssize_t nread); 71 void on_timeout(Timer* timer); 72 73 static int on_status(http_parser* parser, const char* buf, size_t len); 74 int handle_status(unsigned status_code); 75 static int on_header_field(http_parser* parser, const char* buf, size_t len); 76 int handle_header_field(const char* buf, size_t len); 77 static int on_header_value(http_parser* parser, const char* buf, size_t len); 78 int handle_header_value(const char* buf, size_t len); 79 static int on_body(http_parser* parser, const char* buf, size_t len); 80 int handle_body(const char* buf, size_t len); 81 static int on_message_complete(http_parser* parser); 82 int handle_message_complete(); 83 84 void finish(); 85 86 private: 87 HttpClientError error_code_; 88 String error_message_; 89 Address address_; 90 String path_; 91 Callback callback_; 92 SocketConnector::Ptr socket_connector_; 93 Socket::Ptr socket_; 94 Timer request_timer_; 95 uint64_t request_timeout_ms_; 96 http_parser parser_; 97 http_parser_settings parser_settings_; 98 String current_header_; 99 unsigned status_code_; 100 String content_type_; 101 String response_body_; 102 }; 103 104 }}} // namespace datastax::internal::core 105 106 #endif 107