diff --git a/libwvdrmengine/cdm/core/test/http_socket.cpp b/libwvdrmengine/cdm/core/test/http_socket.cpp index 19a3b908..762830ab 100644 --- a/libwvdrmengine/cdm/core/test/http_socket.cpp +++ b/libwvdrmengine/cdm/core/test/http_socket.cpp @@ -7,18 +7,27 @@ #include #include #include -#include -#include #include #include -#include -#include + +#ifdef _WIN32 +# include "winsock2.h" +# include "ws2tcpip.h" +# define ERROR_ASYNC_COMPLETE WSAEWOULDBLOCK +#else +# include +# include +# include +# include +# define ERROR_ASYNC_COMPLETE EINPROGRESS +#endif #include #include #include #include "log.h" +#include "platform.h" namespace wvcdm { @@ -117,6 +126,35 @@ bool SocketWait(int fd, bool for_read, int timeout_in_ms) { return true; } +int GetError() { +#ifdef _WIN32 + return WSAGetLastError(); +#else + return errno; +#endif +} + +void ClearError() { +#ifdef _WIN32 + WSASetLastError(0); +#else + errno = 0; +#endif +} + +const char* GetErrorString() { +#ifdef _WIN32 + static char buffer[2048]; + const int flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS; + const int code = WSAGetLastError(); + if (!FormatMessage(flags, nullptr, code, 0, buffer, sizeof(buffer), nullptr)) + return "Unknown error"; + return buffer; +#else + return strerror(errno); +#endif +} + } // namespace // Parses the URL and extracts all relevant information. @@ -181,7 +219,11 @@ HttpSocket::~HttpSocket() { CloseSocket(); } void HttpSocket::CloseSocket() { if (socket_fd_ != -1) { +#ifdef _WIN32 + closesocket(socket_fd_); +#else close(socket_fd_); +#endif socket_fd_ = -1; } if (ssl_) { @@ -199,6 +241,19 @@ bool HttpSocket::Connect(int timeout_in_ms) { return false; } +#ifdef _WIN32 + static bool initialized = false; + if (!initialized) { + WSADATA ignored_data; + int err = WSAStartup(MAKEWORD(2, 2), &ignored_data); + if (err != 0) { + LOGE("Error in WSAStartup: %d", err); + return false; + } + initialized = true; + } +#endif + // lookup the server IP struct addrinfo hints; memset(&hints, 0, sizeof(hints)); @@ -218,11 +273,19 @@ bool HttpSocket::Connect(int timeout_in_ms) { socket_fd_ = socket(addr_info->ai_family, addr_info->ai_socktype, addr_info->ai_protocol); if (socket_fd_ < 0) { - LOGE("cannot open socket, errno = %d", errno); + LOGE("cannot open socket, errno = %d", GetError()); return false; } // set the socket in non-blocking mode +#ifdef _WIN32 + u_long mode = 1; // Non-blocking mode. + if (ioctlsocket(socket_fd_, FIONBIO, &mode) != 0) { + LOGE("ioctlsocket error, wsa error = %d", WSAGetLastError()); + CloseSocket(); + return false; + } +#else int original_flags = fcntl(socket_fd_, F_GETFL, 0); if (original_flags == -1) { LOGE("fcntl error, errno = %d", errno); @@ -234,6 +297,7 @@ bool HttpSocket::Connect(int timeout_in_ms) { CloseSocket(); return false; } +#endif // connect to the server ret = connect(socket_fd_, addr_info->ai_addr, addr_info->ai_addrlen); @@ -242,9 +306,9 @@ bool HttpSocket::Connect(int timeout_in_ms) { if (ret == 0) { // connected right away. } else { - if (errno != EINPROGRESS) { + if (GetError() != ERROR_ASYNC_COMPLETE) { // failed right away. - LOGE("cannot connect to %s, errno = %d", domain_name_.c_str(), errno); + LOGE("cannot connect to %s, errno = %d", domain_name_.c_str(), GetError()); CloseSocket(); return false; } else { @@ -320,7 +384,7 @@ int HttpSocket::Read(char* data, int len, int timeout_in_ms) { return -1; } - errno = 0; // Reset errno, as we will depend on its value shortly. + ClearError(); // Reset errors, as we will depend on its value shortly. int read; if (secure_connect_) { read = SSL_read(ssl_, data, to_read); @@ -337,7 +401,7 @@ int HttpSocket::Read(char* data, int len, int timeout_in_ms) { int ssl_error = SSL_get_error(ssl_, read); if (ssl_error == SSL_ERROR_ZERO_RETURN || - (ssl_error == SSL_ERROR_SYSCALL && errno == 0)) { + (ssl_error == SSL_ERROR_SYSCALL && GetError() == 0)) { // The connection has been closed. No more data. break; } else if (IsRetryableSslError(ssl_error)) { @@ -347,7 +411,7 @@ int HttpSocket::Read(char* data, int len, int timeout_in_ms) { // Unrecoverable error. Log and abort. LOGE("SSL_read returned %d, LibSSL Error = %d", read, ssl_error); if (ssl_error == SSL_ERROR_SYSCALL) { - LOGE(" errno = %d = %s", errno, strerror(errno)); + LOGE(" errno = %d = %s", GetError(), GetErrorString()); } ERR_print_errors_cb(LogBoringSslError, NULL); return -1; @@ -359,7 +423,8 @@ int HttpSocket::Read(char* data, int len, int timeout_in_ms) { break; } else { // Log the error received - LOGE("recv returned %d, errno = %d = %s", read, errno, strerror(errno)); + LOGE("recv returned %d, errno = %d = %s", read, GetError(), + GetErrorString()); return -1; } } @@ -397,7 +462,7 @@ int HttpSocket::Write(const char* data, int len, int timeout_in_ms) { return -1; } } else { - LOGE("send returned %d, errno = %d", sent, errno); + LOGE("send returned %d, errno = %d", sent, GetError()); return -1; } }