// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary // source code may only be used and distributed under the Widevine License // Agreement. #ifndef CDM_TEST_HTTP_SOCKET_H_ #define CDM_TEST_HTTP_SOCKET_H_ #include #include #include #include "wv_class_utils.h" namespace wvcdm { // Provides basic Linux based TCP socket interface. class HttpSocket { public: using TimePoint = std::chrono::time_point; static TimePoint GetNowTimePoint() { return std::chrono::system_clock::now(); } static constexpr int kClosedFd = -1; HttpSocket() = delete; WVCDM_DISALLOW_COPY_AND_MOVE(HttpSocket); // A scheme (http:// or https://) is required for the URL. explicit HttpSocket(const std::string& url); ~HttpSocket(); bool ConnectAndLogErrors(int timeout_in_ms); void CloseSocket(); const std::string& scheme() const { return scheme_; } bool secure_connect() const { return secure_connect_; } const std::string& domain_name() const { return domain_name_; } int port() const { return atoi(port_.c_str()); } const std::string& resource_path() const { return resource_path_; } const std::string& url() const { return url_; } int ReadAndLogErrors(char* data, int len, int timeout_in_ms); int WriteAndLogErrors(const char* data, int len, int timeout_in_ms); // Allows for testing ParseUrl. Do not rely on this for other // test code. static bool ParseUrlForTest(const std::string& url, std::string* scheme, bool* secure_connect, std::string* domain_name, std::string* port, std::string* path) { return ParseUrl(url, scheme, secure_connect, domain_name, port, path); } private: static bool ParseUrl(const std::string& url, std::string* scheme, bool* secure_connect, std::string* domain_name, std::string* port, std::string* path); // The following three functions do the work without logging errors. bool Connect(int timeout_in_ms); int Read(char* data, int len, int timeout_in_ms); int Write(const char* data, int len, int timeout_in_ms); // Log times with a note as an error. void LogTime(const char* note, const TimePoint& start_time, const TimePoint& end_time) const; // Wait for a socket to be ready for reading or writing. // Establishing a connection counts as "ready for write". // Returns false on select error or timeout. // Returns true when the socket is ready. bool Wait(bool for_read, int timeout_in_ms); std::string url_; std::string scheme_; bool secure_connect_ = false; std::string domain_name_; std::string port_; std::string resource_path_; bool valid_url_ = false; int socket_fd_ = kClosedFd; SSL* ssl_ = nullptr; SSL_CTX* ssl_ctx_ = nullptr; // When the socket was created. Logged on error to help debug flaky // tests. e.g. b/186031735 TimePoint create_time_ = GetNowTimePoint(); }; // class HttpSocket } // namespace wvcdm #endif // CDM_TEST_HTTP_SOCKET_H_