/*
 * HTTP handling functions.
 *
 * Copyright 2003 Ferenc Wagner
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <winsock2.h>
#include <wininet.h>
#include <stdio.h>
#include <errno.h>

#include "winetest.h"

#define USER_AGENT  "Winetest Shell"
#define SERVER_NAME "test.winehq.org"
#define URL_PATH "/submit"
#define SEP "--8<--cut-here--8<--"
#define CONTENT_HEADERS "Content-Type: multipart/form-data; boundary=\"" SEP "\"\r\n" \
                        "Content-Length: %u\r\n\r\n"
static const char body1[] = "--" SEP "\r\n"
    "Content-Disposition: form-data; name=\"reportfile\"; filename=\"%s\"\r\n"
    "Content-Type: application/octet-stream\r\n\r\n";
static const char body2[] = "\r\n--" SEP "\r\n"
    "Content-Disposition: form-data; name=\"submit\"\r\n\r\n"
    "Upload File\r\n"
    "--" SEP "--\r\n";

static SOCKET
open_http (const char *server)
{
    WSADATA wsad;
    struct sockaddr_in sa;
    SOCKET s;

    report (R_STATUS, "Opening HTTP connection to %s", server);
    if (WSAStartup (MAKEWORD (2,2), &wsad)) return INVALID_SOCKET;

    sa.sin_family = AF_INET;
    sa.sin_port = htons (80);
    sa.sin_addr.s_addr = inet_addr (server);
    if (sa.sin_addr.s_addr == INADDR_NONE) {
        struct hostent *host = gethostbyname (server);
        if (!host) {
            report (R_ERROR, "Hostname lookup failed for %s", server);
            goto failure;
        }
        sa.sin_addr.s_addr = ((struct in_addr *)host->h_addr)->s_addr;
    }
    s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (s == INVALID_SOCKET) {
        report (R_ERROR, "Can't open network socket: %d",
                WSAGetLastError ());
        goto failure;
    }
    if (!connect (s, (struct sockaddr*)&sa, sizeof (struct sockaddr_in)))
        return s;

    report (R_ERROR, "Can't connect: %d", WSAGetLastError ());
    closesocket (s);
 failure:
    WSACleanup ();
    return INVALID_SOCKET;
}

static int
close_http (SOCKET s)
{
    int ret;

    ret = closesocket (s);
    return (WSACleanup () || ret);
}

static int
send_buf (SOCKET s, const char *buf, size_t length)
{
    int sent;

    while (length > 0) {
        sent = send (s, buf, length, 0);
        if (sent == SOCKET_ERROR) {
            if (errno == EINTR) continue;
            return 1;
        }
        buf += sent;
        length -= sent;
    }
    return 0;
}

static int
send_str (SOCKET s, ...)
{
    va_list ap;
    char *p;
    int ret;
    size_t len;

    va_start (ap, s);
    p = vstrmake (&len, ap);
    va_end (ap);
    if (!p) return 1;
    ret = send_buf (s, p, len);
    heap_free (p);
    return ret;
}

static int
send_file_direct (const char *name)
{
    SOCKET s;
    HANDLE file;
#define BUFLEN 8192
    char buffer[BUFLEN+1];
    DWORD bytes_read, filesize;
    size_t total, count;
    char *str;
    int ret;

    /* RFC 2616 */
    static const char head[] = "POST " URL_PATH " HTTP/1.0\r\n"
        "Host: " SERVER_NAME "\r\n"
        "User-Agent: " USER_AGENT "\r\n"
        CONTENT_HEADERS
        "\r\n";

    s = open_http (SERVER_NAME);
    if (s == INVALID_SOCKET) return 1;

    file = CreateFileA( name, GENERIC_READ,
                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                        NULL, OPEN_EXISTING, 0, NULL );

    if ((file == INVALID_HANDLE_VALUE) &&
        (GetLastError() == ERROR_INVALID_PARAMETER)) {
        /* FILE_SHARE_DELETE not supported on win9x */
        file = CreateFileA( name, GENERIC_READ,
                            FILE_SHARE_READ | FILE_SHARE_WRITE,
                            NULL, OPEN_EXISTING, 0, NULL );
    }
    if (file == INVALID_HANDLE_VALUE)
    {
        report (R_WARNING, "Can't open file '%s': %u", name, GetLastError());
        goto abort1;
    }
    filesize = GetFileSize( file, NULL );
    if (filesize > 1.5*1024*1024) {
        report (R_WARNING,
                "File too big (%.1f MB > 1.5 MB); submitting partial report.",
                filesize/1024.0/1024);
        filesize = (DWORD) 1.5*1024*1024;
    }

    report (R_STATUS, "Sending header");
    str = strmake (&total, body1, name);
    ret = send_str (s, head, filesize + total + sizeof body2 - 1) ||
        send_buf (s, str, total);
    heap_free (str);
    if (ret) {
        report (R_WARNING, "Error sending header: %d, %d",
                errno, WSAGetLastError ());
        goto abort2;
    }

    report (R_STATUS, "Sending %u bytes of data", filesize);
    report (R_PROGRESS, 2, filesize);
    total = 0;
    while (total < filesize && ReadFile( file, buffer, BUFLEN/2, &bytes_read, NULL )) {
        if (aborting) goto abort2;
        if (!bytes_read) break;
        total += bytes_read;
        if (total > filesize) bytes_read -= total - filesize;
        if (send_buf (s, buffer, bytes_read)) {
            report (R_WARNING, "Error sending body: %d, %d",
                    errno, WSAGetLastError ());
            goto abort2;
        }
        report (R_DELTA, bytes_read, "Network transfer: In progress");
    }
    CloseHandle( file );

    if (send_buf (s, body2, sizeof body2 - 1)) {
        report (R_WARNING, "Error sending trailer: %d, %d",
                errno, WSAGetLastError ());
        goto abort1;
    }
    report (R_DELTA, 0, "Network transfer: Done");

    total = 0;
    while ((bytes_read = recv (s, buffer+total, BUFLEN-total, 0))) {
        if ((signed)bytes_read == SOCKET_ERROR) {
            if (errno == EINTR) continue;
            report (R_WARNING, "Error receiving reply: %d, %d",
                    errno, WSAGetLastError ());
            goto abort1;
        }
        total += bytes_read;
        if (total == BUFLEN) {
            report (R_WARNING, "Buffer overflow");
            goto abort1;
        }
    }
    if (close_http (s)) {
        report (R_WARNING, "Error closing connection: %d, %d",
                errno, WSAGetLastError ());
        return 1;
    }

    str = strmake (&count, "Received %s (%d bytes).\n",
                   name, filesize);
    ret = total < count || memcmp (str, buffer + total - count, count) != 0;
    heap_free (str);
    if (ret) {
        buffer[total] = 0;
        str = strstr (buffer, "\r\n\r\n");
        if (!str) str = buffer;
        else str = str + 4;
        report (R_ERROR, "Can't submit logfile '%s'. "
                "Server response: %s", name, str);
    }
    return ret;

 abort2:
    CloseHandle( file );
 abort1:
    close_http (s);
    return 1;
}

static int
send_file_wininet (const char *name)
{
    int ret = 0;
    HMODULE wininet_mod = NULL;
    HINTERNET (WINAPI *pInternetOpen)(LPCSTR agent, DWORD access_type, LPCSTR proxy_name, LPCSTR proxy_bypass, DWORD flags);
    HINTERNET (WINAPI *pInternetConnect)(HINTERNET session, LPCSTR server_name, INTERNET_PORT server_port, LPCSTR username, LPCSTR password, DWORD service, DWORD flags, DWORD_PTR *context);
    HINTERNET (WINAPI *pHttpOpenRequest)(HINTERNET connection, LPCSTR verb, LPCSTR object_name, LPCSTR version, LPCSTR referer, LPCSTR *accept_types, DWORD flags, DWORD_PTR context);
    BOOL (WINAPI *pHttpSendRequestEx)(HINTERNET request, LPINTERNET_BUFFERSA buffers_in, LPINTERNET_BUFFERSA buffers_out, DWORD flags, DWORD_PTR context);
    BOOL (WINAPI *pInternetWriteFile)(HINTERNET file, LPCVOID buffer, DWORD number_of_bytes_to_write, LPDWORD number_of_bytes_written);
    BOOL (WINAPI *pHttpEndRequest)(HINTERNET request, LPINTERNET_BUFFERSA buffers_out, DWORD flags, DWORD_PTR context);
    BOOL (WINAPI *pInternetReadFile)(HINTERNET file, LPCVOID buffer, DWORD number_of_bytes_to_read, LPDWORD number_of_bytes_read);
    BOOL (WINAPI *pInternetCloseHandle)(HINTERNET Handle) = NULL;
    HANDLE file = INVALID_HANDLE_VALUE;
    DWORD filesize, bytes_read, bytes_written;
    size_t total, count;
    char *str = NULL;
    HINTERNET session = NULL;
    HINTERNET connection = NULL;
    HINTERNET request = NULL;
    INTERNET_BUFFERSA buffers_in = { 0 };
    char buffer[BUFLEN+1];

    static const char extra_headers[] =
        CONTENT_HEADERS;

    wininet_mod = LoadLibraryA("wininet.dll");
    if (wininet_mod == NULL)
        goto done;
    pInternetOpen = (void *)GetProcAddress(wininet_mod, "InternetOpenA");
    pInternetConnect = (void *)GetProcAddress(wininet_mod, "InternetConnectA");
    pHttpOpenRequest = (void *)GetProcAddress(wininet_mod, "HttpOpenRequestA");
    pHttpSendRequestEx = (void *)GetProcAddress(wininet_mod, "HttpSendRequestExA");
    pInternetWriteFile = (void *)GetProcAddress(wininet_mod, "InternetWriteFile");
    pHttpEndRequest = (void *)GetProcAddress(wininet_mod, "HttpEndRequestA");
    pInternetReadFile = (void *)GetProcAddress(wininet_mod, "InternetReadFile");
    pInternetCloseHandle = (void *)GetProcAddress(wininet_mod, "InternetCloseHandle");
    if (pInternetOpen == NULL || pInternetConnect == NULL || pHttpOpenRequest == NULL || pHttpSendRequestEx == NULL || pHttpEndRequest == NULL ||
        pInternetWriteFile == NULL || pInternetReadFile == NULL || pInternetCloseHandle == NULL) {
        goto done;
    }

    ret = 1;

    file = CreateFileA( name, GENERIC_READ,
                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                        NULL, OPEN_EXISTING, 0, NULL );

    if ((file == INVALID_HANDLE_VALUE) &&
        (GetLastError() == ERROR_INVALID_PARAMETER)) {
        /* FILE_SHARE_DELETE not supported on win9x */
        file = CreateFileA( name, GENERIC_READ,
                            FILE_SHARE_READ | FILE_SHARE_WRITE,
                            NULL, OPEN_EXISTING, 0, NULL );
    }
    if (file == INVALID_HANDLE_VALUE) {
        report (R_WARNING, "Can't open file '%s': %u", name, GetLastError());
        goto done;
    }

    filesize = GetFileSize( file, NULL );
    if (filesize > 1.5*1024*1024) {
        report (R_WARNING,
                "File too big (%.1f MB > 1.5 MB); submitting partial report.",
                filesize/1024.0/1024);
        filesize = 1.5*1024*1024;
    }

    report (R_STATUS, "Opening HTTP connection to " SERVER_NAME);
    session = pInternetOpen (USER_AGENT, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    if (session == NULL) {
        report (R_WARNING, "Unable to open connection, error %u", GetLastError());
        goto done;
    }
    connection = pInternetConnect (session, SERVER_NAME, INTERNET_DEFAULT_HTTP_PORT, "", "", INTERNET_SERVICE_HTTP, 0, 0);
    if (connection == NULL) {
        report (R_WARNING, "Unable to connect, error %u", GetLastError());
        goto done;
    }
    request = pHttpOpenRequest (connection, "POST", URL_PATH, NULL, NULL, NULL,
                                INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_NO_UI |
                                INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_RELOAD, 0);
    if (request == NULL) {
        report (R_WARNING, "Unable to open request, error %u", GetLastError());
        goto done;
    }

    report (R_STATUS, "Sending request");
    str = strmake (&total, body1, name);
    memset(&buffers_in, 0, sizeof(INTERNET_BUFFERSA));
    buffers_in.dwStructSize = sizeof(INTERNET_BUFFERSA);
    buffers_in.dwBufferTotal = filesize + total + sizeof body2 - 1;
    buffers_in.lpcszHeader = strmake (&count, extra_headers, buffers_in.dwBufferTotal);
    buffers_in.dwHeadersLength = count;
    if (! pHttpSendRequestEx(request, &buffers_in, NULL, 0, 0)) {
        report (R_WARNING, "Unable to send request, error %u", GetLastError());
        goto done;
    }

    if (! pInternetWriteFile(request, str, total, &bytes_written) || bytes_written != total) {
        report (R_WARNING, "Unable to write body data, error %u", GetLastError());
        goto done;
    }

    report (R_STATUS, "Sending %u bytes of data", filesize);
    report (R_PROGRESS, 2, filesize);
    total = 0;
    while (total < filesize && ReadFile( file, buffer, BUFLEN/2, &bytes_read, NULL )) {
        if (aborting) goto done;
        if (!bytes_read) break;
        total += bytes_read;
        if (total > filesize) bytes_read -= total - filesize;
        if (! pInternetWriteFile (request, buffer, bytes_read, &bytes_written) || bytes_written != bytes_read) {
            report (R_WARNING, "Error sending body: %u", GetLastError ());
            goto done;
        }
        report (R_DELTA, bytes_read, "Network transfer: In progress");
    }

    if (! pInternetWriteFile(request, body2, sizeof body2 - 1, &bytes_written) || bytes_written != sizeof body2 - 1) {
        report (R_WARNING, "Unable to write final body data, error %u", GetLastError());
        goto done;
    }
    if (! pHttpEndRequest(request, NULL, 0, 0)) {
        report (R_WARNING, "Unable to end request, error %u", GetLastError());
        goto done;
    }
    report (R_DELTA, 0, "Network transfer: Done");

    total = 0;
    do
    {
        if (! pInternetReadFile(request, buffer+total, BUFLEN-total, &bytes_read)) {
            report (R_WARNING, "Error receiving reply: %u", GetLastError ());
            goto done;
        }
        total += bytes_read;
        if (total == BUFLEN) {
            report (R_WARNING, "Buffer overflow");
            goto done;
        }
    }
    while (bytes_read != 0);

    heap_free (str);
    str = strmake (&count, "Received %s (%d bytes).\n",
                   name, filesize);
    if (total < count || memcmp (str, buffer + total - count, count) != 0) {
        buffer[total] = 0;
        report (R_ERROR, "Can't submit logfile '%s'. "
                "Server response: %s", name, buffer);
    }

 done:
    if (buffers_in.lpcszHeader != NULL)
        heap_free((void *) buffers_in.lpcszHeader);
    if (str != NULL)
        heap_free (str);
    if (pInternetCloseHandle != NULL && request != NULL)
        pInternetCloseHandle (request);
    if (pInternetCloseHandle != NULL && connection != NULL)
        pInternetCloseHandle (connection);
    if (pInternetCloseHandle != NULL && session != NULL)
        pInternetCloseHandle (session);
    if (file != INVALID_HANDLE_VALUE)
        CloseHandle (file);
    if (wininet_mod != NULL)
        FreeLibrary (wininet_mod);

    return ret;
}

int
send_file (const char *name)
{
    return send_file_wininet( name ) || send_file_direct( name );
}
