// Copyright 2019 Google Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * 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.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// 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
// OWNER 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.

#include "tools/windows/converter_exe/winhttp_client.h"

#include <assert.h>
#include <stdlib.h>
#include <windows.h>
#include <winhttp.h>
#include <vector>

namespace crash {

namespace internal {

// This class implements HttpClient based on WinInet APIs.
class WinHttpClient : public HttpClient {
 public:
  virtual ~WinHttpClient() {}
  virtual bool CrackUrl(const TCHAR* url,
                        DWORD flags,
                        TCHAR* scheme,
                        size_t scheme_buffer_length,
                        TCHAR* host,
                        size_t host_buffer_length,
                        TCHAR* uri,
                        size_t uri_buffer_length,
                        int* port) const;
  virtual bool Open(const TCHAR* user_agent,
                    DWORD access_type,
                    const TCHAR* proxy_name,
                    const TCHAR* proxy_bypass,
                    HttpHandle* session_handle) const;
  virtual bool Connect(HttpHandle session_handle,
                       const TCHAR* server,
                       int port,
                       HttpHandle* connection_handle) const;
  virtual bool OpenRequest(HttpHandle connection_handle,
                           const TCHAR* verb,
                           const TCHAR* uri,
                           const TCHAR* version,
                           const TCHAR* referrer,
                           bool is_secure,
                           HttpHandle* request_handle) const;
  virtual bool SendRequest(HttpHandle request_handle,
                           const TCHAR* headers,
                           DWORD headers_length) const;
  virtual bool ReceiveResponse(HttpHandle request_handle) const;
  virtual bool GetHttpStatusCode(HttpHandle request_handle,
                                 int* status_code) const;
  virtual bool GetContentLength(HttpHandle request_handle,
                                DWORD* content_length) const;
  virtual bool ReadData(HttpHandle request_handle,
                        void* buffer,
                        DWORD buffer_length,
                        DWORD* bytes_read) const;
  virtual bool Close(HttpHandle handle) const;

 private:
  static DWORD MapAccessType(DWORD access_type);
  static HINTERNET ToHINTERNET(HttpHandle handle);
  static HttpHandle FromHINTERNET(HINTERNET handle);
};

bool WinHttpClient::CrackUrl(const TCHAR* url,
                             DWORD flags,
                             TCHAR* scheme,
                             size_t scheme_buffer_length,
                             TCHAR* host,
                             size_t host_buffer_length,
                             TCHAR* uri,
                             size_t uri_buffer_length,
                             int* port) const {
  assert(url);
  assert(scheme);
  assert(host);
  assert(uri);
  assert(port);

  URL_COMPONENTS url_comp = {0};
  url_comp.dwStructSize = sizeof(url_comp);
  url_comp.lpszScheme = scheme;
  url_comp.dwSchemeLength = static_cast<DWORD>(scheme_buffer_length);
  url_comp.lpszHostName = host;
  url_comp.dwHostNameLength = static_cast<DWORD>(host_buffer_length);
  url_comp.lpszUrlPath = uri;
  url_comp.dwUrlPathLength = static_cast<DWORD>(uri_buffer_length);

  bool result = !!::WinHttpCrackUrl(url, 0, flags, &url_comp);
  if (result) {
    *port = static_cast<int>(url_comp.nPort);
  }
  return result;
}

bool WinHttpClient::Open(const TCHAR* user_agent,
                         DWORD access_type,
                         const TCHAR* proxy_name,
                         const TCHAR* proxy_bypass,
                         HttpHandle* session_handle)  const {
  *session_handle = FromHINTERNET(::WinHttpOpen(user_agent,
                                                MapAccessType(access_type),
                                                proxy_name,
                                                proxy_bypass,
                                                0));

  return !!(*session_handle);
}

bool WinHttpClient::Connect(HttpHandle session_handle,
                            const TCHAR* server,
                            int port,
                            HttpHandle* connection_handle) const {
  assert(server);

  // Uses NULL user name and password to connect.
  *connection_handle = FromHINTERNET(::WinHttpConnect(
                                         ToHINTERNET(session_handle),
                                         server,
                                         static_cast<INTERNET_PORT>(port),
                                         NULL));
  return !!(*connection_handle);
}

bool WinHttpClient::OpenRequest(HttpHandle connection_handle,
                                const TCHAR* verb,
                                const TCHAR* uri,
                                const TCHAR* version,
                                const TCHAR* referrer,
                                bool is_secure,
                                HttpHandle* request_handle) const {
  assert(connection_handle);
  assert(verb);
  assert(uri);
  assert(request_handle);

  *request_handle = FromHINTERNET(::WinHttpOpenRequest(
                                      ToHINTERNET(connection_handle),
                                      verb,
                                      uri,
                                      version,
                                      referrer,
                                      WINHTTP_DEFAULT_ACCEPT_TYPES,
                                      is_secure ? WINHTTP_FLAG_SECURE : 0));
  return !!(*request_handle);
}

bool WinHttpClient::SendRequest(HttpHandle request_handle,
                                const TCHAR* headers,
                                DWORD headers_length) const {
  assert(request_handle);

  return !!::WinHttpSendRequest(ToHINTERNET(request_handle),
                                headers,
                                headers_length,
                                NULL,
                                0,
                                WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH,
                                NULL);
}

bool WinHttpClient::ReceiveResponse(HttpHandle request_handle) const {
  assert(request_handle);

  return !!::WinHttpReceiveResponse(ToHINTERNET(request_handle), NULL);
}

bool WinHttpClient::GetHttpStatusCode(HttpHandle request_handle,
                                      int* status_code) const {
  TCHAR http_status_string[4] = {0};
  DWORD http_status_string_size = sizeof(http_status_string);
  if (!::WinHttpQueryHeaders(ToHINTERNET(request_handle),
                             WINHTTP_QUERY_STATUS_CODE,
                             WINHTTP_HEADER_NAME_BY_INDEX,
                             static_cast<void *>(&http_status_string),
                             &http_status_string_size, 0)) {
    return false;
  }

  *status_code = static_cast<DWORD>(_tcstol(http_status_string, NULL, 10));
  return true;
}

bool WinHttpClient::GetContentLength(HttpHandle request_handle,
                                     DWORD* content_length) const {
  assert(request_handle);
  assert(content_length);

  TCHAR content_length_string[11] = {0};
  DWORD content_length_string_size = sizeof(content_length_string);
  if (!::WinHttpQueryHeaders(ToHINTERNET(request_handle),
                             WINHTTP_QUERY_CONTENT_LENGTH,
                             WINHTTP_HEADER_NAME_BY_INDEX,
                             static_cast<void *>(&content_length_string),
                             &content_length_string_size, 0)) {
    *content_length = kUnknownContentLength;
  } else {
    *content_length =
        static_cast<DWORD>(wcstol(content_length_string, NULL, 10));
  }
  return true;
}

bool WinHttpClient::ReadData(HttpHandle request_handle,
                             void* buffer,
                             DWORD buffer_length,
                             DWORD* bytes_read) const {
  assert(request_handle);
  assert(buffer);
  assert(bytes_read);

  DWORD bytes_read_local = 0;
  if (!::WinHttpReadData(ToHINTERNET(request_handle),
                         buffer,
                         buffer_length,
                         &bytes_read_local)) {
    return false;
  }
  *bytes_read = bytes_read_local;
  return true;
}

bool WinHttpClient::Close(HttpHandle handle) const {
  assert(handle);
  return !!::WinHttpCloseHandle(ToHINTERNET(handle));
}

DWORD WinHttpClient::MapAccessType(DWORD access_type) {
  switch (static_cast<AccessType>(access_type)) {
    case ACCESS_TYPE_PRECONFIG:
    default:
      return WINHTTP_ACCESS_TYPE_DEFAULT_PROXY;
    case ACCESS_TYPE_DIRECT:
      return WINHTTP_ACCESS_TYPE_NO_PROXY;
    case ACCESS_TYPE_PROXY:
      return WINHTTP_ACCESS_TYPE_NAMED_PROXY;
  }
}


HINTERNET WinHttpClient::ToHINTERNET(HttpHandle handle) {
  return static_cast<HINTERNET>(handle);
}

HttpHandle WinHttpClient::FromHINTERNET(HINTERNET handle) {
  return static_cast<HttpHandle>(handle);
}

}  // namespace internal

HttpClient* CreateWinHttpClient(const TCHAR* url) {
  assert(url);

  internal::WinHttpClient winhttp;
  wchar_t scheme[16] = {0};
  wchar_t host[256] = {0};
  wchar_t path[256] = {0};
  int port = 0;

  if (!winhttp.CrackUrl(url,
                        0,
                        scheme,
                        sizeof(scheme)/sizeof(scheme[0]),
                        host,
                        sizeof(host)/sizeof(host[0]),
                        path,
                        sizeof(path)/sizeof(path[0]),
                        &port)) {
    return NULL;
  }

  if (_wcsicmp(scheme, L"https") == 0) {
    // Winhttp under WINE doesn't support wildcard certificates, so avoid 
    // to use it if the scheme is https. The caller should fall back to
    // use wininet if NULL is returned.
    return NULL;
  }

  return new internal::WinHttpClient();
}

}  // namespace crash
