/*
 * 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 <winsock.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) 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 (!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) {
            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 = LoadLibrary ("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 (!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 );
}
