/*
 * Copyright 2005 Jacek Caban
 * Copyright 2007 Misha Koshelev
 *
 * 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
 */

/*
 * TODO:
 * - Handle redirects as native.
 */

#include "urlmon_main.h"
#include "wininet.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(urlmon);

/* Flags are needed for, among other things, return HRESULTs from the Read function
 * to conform to native. For example, Read returns:
 *
 * 1. E_PENDING if called before the request has completed,
 *        (flags = 0)
 * 2. S_FALSE after all data has been read and S_OK has been reported,
 *        (flags = FLAG_REQUEST_COMPLETE | FLAG_ALL_DATA_READ | FLAG_RESULT_REPORTED)
 * 3. INET_E_DATA_NOT_AVAILABLE if InternetQueryDataAvailable fails. The first time
 *    this occurs, INET_E_DATA_NOT_AVAILABLE will also be reported to the sink,
 *        (flags = FLAG_REQUEST_COMPLETE)
 *    but upon subsequent calls to Read no reporting will take place, yet
 *    InternetQueryDataAvailable will still be called, and, on failure,
 *    INET_E_DATA_NOT_AVAILABLE will still be returned.
 *        (flags = FLAG_REQUEST_COMPLETE | FLAG_RESULT_REPORTED)
 *
 * FLAG_FIRST_DATA_REPORTED and FLAG_LAST_DATA_REPORTED are needed for proper
 * ReportData reporting. For example, if OnResponse returns S_OK, Continue will
 * report BSCF_FIRSTDATANOTIFICATION, and when all data has been read Read will
 * report BSCF_INTERMEDIATEDATANOTIFICATION|BSCF_LASTDATANOTIFICATION. However,
 * if OnResponse does not return S_OK, Continue will not report data, and Read
 * will report BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION when all
 * data has been read.
 */
#define FLAG_REQUEST_COMPLETE 0x1
#define FLAG_FIRST_CONTINUE_COMPLETE 0x2
#define FLAG_FIRST_DATA_REPORTED 0x4
#define FLAG_ALL_DATA_READ 0x8
#define FLAG_LAST_DATA_REPORTED 0x10
#define FLAG_RESULT_REPORTED 0x20

typedef struct {
    const IInternetProtocolVtbl *lpInternetProtocolVtbl;
    const IInternetPriorityVtbl *lpInternetPriorityVtbl;

    DWORD flags, grfBINDF;
    BINDINFO bind_info;
    IInternetProtocolSink *protocol_sink;
    IHttpNegotiate *http_negotiate;
    HINTERNET internet, connect, request;
    LPWSTR full_header;
    HANDLE lock;
    ULONG current_position, content_length, available_bytes;
    LONG priority;

    LONG ref;
} HttpProtocol;

/* Default headers from native */
static const WCHAR wszHeaders[] = {'A','c','c','e','p','t','-','E','n','c','o','d','i','n','g',
                                   ':',' ','g','z','i','p',',',' ','d','e','f','l','a','t','e',0};

/*
 * Helpers
 */

static void HTTPPROTOCOL_ReportResult(HttpProtocol *This, HRESULT hres)
{
    if (!(This->flags & FLAG_RESULT_REPORTED) &&
        This->protocol_sink)
    {
        This->flags |= FLAG_RESULT_REPORTED;
        IInternetProtocolSink_ReportResult(This->protocol_sink, hres, 0, NULL);
    }
}

static void HTTPPROTOCOL_ReportData(HttpProtocol *This)
{
    DWORD bscf;
    if (!(This->flags & FLAG_LAST_DATA_REPORTED) &&
        This->protocol_sink)
    {
        if (This->flags & FLAG_FIRST_DATA_REPORTED)
        {
            bscf = BSCF_INTERMEDIATEDATANOTIFICATION;
        }
        else
        {
            This->flags |= FLAG_FIRST_DATA_REPORTED;
            bscf = BSCF_FIRSTDATANOTIFICATION;
        }
        if (This->flags & FLAG_ALL_DATA_READ &&
            !(This->flags & FLAG_LAST_DATA_REPORTED))
        {
            This->flags |= FLAG_LAST_DATA_REPORTED;
            bscf |= BSCF_LASTDATANOTIFICATION;
        }
        IInternetProtocolSink_ReportData(This->protocol_sink, bscf,
                                         This->current_position+This->available_bytes,
                                         This->content_length);
    }
}

static void HTTPPROTOCOL_AllDataRead(HttpProtocol *This)
{
    if (!(This->flags & FLAG_ALL_DATA_READ))
        This->flags |= FLAG_ALL_DATA_READ;
    HTTPPROTOCOL_ReportData(This);
    HTTPPROTOCOL_ReportResult(This, S_OK);
}

static void HTTPPROTOCOL_Close(HttpProtocol *This)
{
    if (This->http_negotiate)
    {
        IHttpNegotiate_Release(This->http_negotiate);
        This->http_negotiate = 0;
    }
    if (This->request)
        InternetCloseHandle(This->request);
    if (This->connect)
        InternetCloseHandle(This->connect);
    if (This->internet)
    {
        InternetCloseHandle(This->internet);
        This->internet = 0;
    }
    if (This->full_header)
    {
        if (This->full_header != wszHeaders)
            heap_free(This->full_header);
        This->full_header = 0;
    }
    This->flags = 0;
}

static void CALLBACK HTTPPROTOCOL_InternetStatusCallback(
    HINTERNET hInternet, DWORD_PTR dwContext, DWORD dwInternetStatus,
    LPVOID lpvStatusInformation, DWORD dwStatusInformationLength)
{
    HttpProtocol *This = (HttpProtocol *)dwContext;
    PROTOCOLDATA data;
    ULONG ulStatusCode;

    switch (dwInternetStatus)
    {
    case INTERNET_STATUS_RESOLVING_NAME:
        ulStatusCode = BINDSTATUS_FINDINGRESOURCE;
        break;
    case INTERNET_STATUS_CONNECTING_TO_SERVER:
        ulStatusCode = BINDSTATUS_CONNECTING;
        break;
    case INTERNET_STATUS_SENDING_REQUEST:
        ulStatusCode = BINDSTATUS_SENDINGREQUEST;
        break;
    case INTERNET_STATUS_REQUEST_COMPLETE:
        This->flags |= FLAG_REQUEST_COMPLETE;
        /* PROTOCOLDATA same as native */
        memset(&data, 0, sizeof(data));
        data.dwState = 0xf1000000;
        if (This->flags & FLAG_FIRST_CONTINUE_COMPLETE)
            data.pData = (LPVOID)BINDSTATUS_ENDDOWNLOADCOMPONENTS;
        else
            data.pData = (LPVOID)BINDSTATUS_DOWNLOADINGDATA;
        if (This->grfBINDF & BINDF_FROMURLMON)
            IInternetProtocolSink_Switch(This->protocol_sink, &data);
        else
            IInternetProtocol_Continue((IInternetProtocol *)This, &data);
        return;
    case INTERNET_STATUS_HANDLE_CREATED:
        IInternetProtocol_AddRef((IInternetProtocol *)This);
        return;
    case INTERNET_STATUS_HANDLE_CLOSING:
        if (*(HINTERNET *)lpvStatusInformation == This->connect)
        {
            This->connect = 0;
        }
        else if (*(HINTERNET *)lpvStatusInformation == This->request)
        {
            This->request = 0;
            if (This->protocol_sink)
            {
                IInternetProtocolSink_Release(This->protocol_sink);
                This->protocol_sink = 0;
            }
            if (This->bind_info.cbSize)
            {
                ReleaseBindInfo(&This->bind_info);
                memset(&This->bind_info, 0, sizeof(This->bind_info));
            }
        }
        IInternetProtocol_Release((IInternetProtocol *)This);
        return;
    default:
        WARN("Unhandled Internet status callback %d\n", dwInternetStatus);
        return;
    }

    IInternetProtocolSink_ReportProgress(This->protocol_sink, ulStatusCode, (LPWSTR)lpvStatusInformation);
}

static inline LPWSTR strndupW(LPCWSTR string, int len)
{
    LPWSTR ret = NULL;
    if (string &&
        (ret = heap_alloc((len+1)*sizeof(WCHAR))) != NULL)
    {
        memcpy(ret, string, len*sizeof(WCHAR));
        ret[len] = 0;
    }
    return ret;
}

/*
 * Interface implementations
 */

#define PROTOCOL(x)  ((IInternetProtocol*)  &(x)->lpInternetProtocolVtbl)
#define PRIORITY(x)  ((IInternetPriority*)  &(x)->lpInternetPriorityVtbl)

#define PROTOCOL_THIS(iface) DEFINE_THIS(HttpProtocol, InternetProtocol, iface)

static HRESULT WINAPI HttpProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
{
    HttpProtocol *This = PROTOCOL_THIS(iface);

    *ppv = NULL;
    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
        *ppv = PROTOCOL(This);
    }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
        TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
        *ppv = PROTOCOL(This);
    }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
        TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
        *ppv = PROTOCOL(This);
    }else if(IsEqualGUID(&IID_IInternetPriority, riid)) {
        TRACE("(%p)->(IID_IInternetPriority %p)\n", This, ppv);
        *ppv = PRIORITY(This);
    }

    if(*ppv) {
        IInternetProtocol_AddRef(iface);
        return S_OK;
    }

    WARN("not supported interface %s\n", debugstr_guid(riid));
    return E_NOINTERFACE;
}

static ULONG WINAPI HttpProtocol_AddRef(IInternetProtocol *iface)
{
    HttpProtocol *This = PROTOCOL_THIS(iface);
    LONG ref = InterlockedIncrement(&This->ref);
    TRACE("(%p) ref=%d\n", This, ref);
    return ref;
}

static ULONG WINAPI HttpProtocol_Release(IInternetProtocol *iface)
{
    HttpProtocol *This = PROTOCOL_THIS(iface);
    LONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    if(!ref) {
        HTTPPROTOCOL_Close(This);
        heap_free(This);

        URLMON_UnlockModule();
    }

    return ref;
}

static HRESULT WINAPI HttpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
        IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
        DWORD grfPI, DWORD dwReserved)
{
    HttpProtocol *This = PROTOCOL_THIS(iface);
    URL_COMPONENTSW url;
    DWORD len = 0, request_flags = INTERNET_FLAG_KEEP_CONNECTION;
    ULONG num = 0;
    IServiceProvider *service_provider = 0;
    IHttpNegotiate2 *http_negotiate2 = 0;
    LPWSTR host = 0, path = 0, user = 0, pass = 0, addl_header = 0,
        post_cookie = 0, optional = 0;
    BYTE security_id[512];
    LPOLESTR user_agent, accept_mimes[257];
    HRESULT hres;

    static const WCHAR wszHttp[] = {'h','t','t','p',':'};
    static const WCHAR wszBindVerb[BINDVERB_CUSTOM][5] =
        {{'G','E','T',0},
         {'P','O','S','T',0},
         {'P','U','T',0}};

    TRACE("(%p)->(%s %p %p %08x %d)\n", This, debugstr_w(szUrl), pOIProtSink,
            pOIBindInfo, grfPI, dwReserved);

    IInternetProtocolSink_AddRef(pOIProtSink);
    This->protocol_sink = pOIProtSink;

    memset(&This->bind_info, 0, sizeof(This->bind_info));
    This->bind_info.cbSize = sizeof(BINDINFO);
    hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &This->grfBINDF, &This->bind_info);
    if (hres != S_OK)
    {
        WARN("GetBindInfo failed: %08x\n", hres);
        goto done;
    }

    if (lstrlenW(szUrl) < sizeof(wszHttp)/sizeof(WCHAR)
        || memcmp(szUrl, wszHttp, sizeof(wszHttp)))
    {
        hres = MK_E_SYNTAX;
        goto done;
    }

    memset(&url, 0, sizeof(url));
    url.dwStructSize = sizeof(url);
    url.dwSchemeLength = url.dwHostNameLength = url.dwUrlPathLength = url.dwUserNameLength =
        url.dwPasswordLength = 1;
    if (!InternetCrackUrlW(szUrl, 0, 0, &url))
    {
        hres = MK_E_SYNTAX;
        goto done;
    }
    host = strndupW(url.lpszHostName, url.dwHostNameLength);
    path = strndupW(url.lpszUrlPath, url.dwUrlPathLength);
    user = strndupW(url.lpszUserName, url.dwUserNameLength);
    pass = strndupW(url.lpszPassword, url.dwPasswordLength);
    if (!url.nPort)
        url.nPort = INTERNET_DEFAULT_HTTP_PORT;

    if(!(This->grfBINDF & BINDF_FROMURLMON))
        IInternetProtocolSink_ReportProgress(This->protocol_sink, BINDSTATUS_DIRECTBIND, NULL);

    hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_USER_AGENT, &user_agent,
                                           1, &num);
    if (hres != S_OK || !num)
    {
        CHAR null_char = 0;
        LPSTR user_agenta = NULL;
        len = 0;
        if ((hres = ObtainUserAgentString(0, &null_char, &len)) != E_OUTOFMEMORY)
        {
            WARN("ObtainUserAgentString failed: %08x\n", hres);
        }
        else if (!(user_agenta = heap_alloc(len*sizeof(CHAR))))
        {
            WARN("Out of memory\n");
        }
        else if ((hres = ObtainUserAgentString(0, user_agenta, &len)) != S_OK)
        {
            WARN("ObtainUserAgentString failed: %08x\n", hres);
        }
        else
        {
            if (!(user_agent = CoTaskMemAlloc((len)*sizeof(WCHAR))))
                WARN("Out of memory\n");
            else
                MultiByteToWideChar(CP_ACP, 0, user_agenta, -1, user_agent, len*sizeof(WCHAR));
        }
        heap_free(user_agenta);
    }

    This->internet = InternetOpenW(user_agent, 0, NULL, NULL, INTERNET_FLAG_ASYNC);
    if (!This->internet)
    {
        WARN("InternetOpen failed: %d\n", GetLastError());
        hres = INET_E_NO_SESSION;
        goto done;
    }

    /* Native does not check for success of next call, so we won't either */
    InternetSetStatusCallbackW(This->internet, HTTPPROTOCOL_InternetStatusCallback);

    This->connect = InternetConnectW(This->internet, host, url.nPort, user,
                                     pass, INTERNET_SERVICE_HTTP, 0, (DWORD)This);
    if (!This->connect)
    {
        WARN("InternetConnect failed: %d\n", GetLastError());
        hres = INET_E_CANNOT_CONNECT;
        goto done;
    }

    num = sizeof(accept_mimes)/sizeof(accept_mimes[0])-1;
    hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_ACCEPT_MIMES,
                                           accept_mimes,
                                           num, &num);
    if (hres != S_OK)
    {
        WARN("GetBindString BINDSTRING_ACCEPT_MIMES failed: %08x\n", hres);
        hres = INET_E_NO_VALID_MEDIA;
        goto done;
    }
    accept_mimes[num] = 0;

    if (This->grfBINDF & BINDF_NOWRITECACHE)
        request_flags |= INTERNET_FLAG_NO_CACHE_WRITE;
    This->request = HttpOpenRequestW(This->connect, This->bind_info.dwBindVerb < BINDVERB_CUSTOM ?
                                     wszBindVerb[This->bind_info.dwBindVerb] :
                                     This->bind_info.szCustomVerb,
                                     path, NULL, NULL, (LPCWSTR *)accept_mimes,
                                     request_flags, (DWORD)This);
    if (!This->request)
    {
        WARN("HttpOpenRequest failed: %d\n", GetLastError());
        hres = INET_E_RESOURCE_NOT_FOUND;
        goto done;
    }

    hres = IInternetProtocolSink_QueryInterface(This->protocol_sink, &IID_IServiceProvider,
                                                (void **)&service_provider);
    if (hres != S_OK)
    {
        WARN("IInternetProtocolSink_QueryInterface IID_IServiceProvider failed: %08x\n", hres);
        goto done;
    }

    hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
                                         &IID_IHttpNegotiate, (void **)&This->http_negotiate);
    if (hres != S_OK)
    {
        WARN("IServiceProvider_QueryService IID_IHttpNegotiate failed: %08x\n", hres);
        goto done;
    }

    hres = IHttpNegotiate_BeginningTransaction(This->http_negotiate, szUrl, wszHeaders,
                                               0, &addl_header);
    if (hres != S_OK)
    {
        WARN("IHttpNegotiate_BeginningTransaction failed: %08x\n", hres);
        goto done;
    }
    else if (addl_header == NULL)
    {
        This->full_header = (LPWSTR)wszHeaders;
    }
    else
    {
        int len_addl_header = lstrlenW(addl_header);
        This->full_header = heap_alloc(len_addl_header*sizeof(WCHAR)+sizeof(wszHeaders));
        if (!This->full_header)
        {
            WARN("Out of memory\n");
            hres = E_OUTOFMEMORY;
            goto done;
        }
        lstrcpyW(This->full_header, addl_header);
        lstrcpyW(&This->full_header[len_addl_header], wszHeaders);
    }

    hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate2,
                                         &IID_IHttpNegotiate2, (void **)&http_negotiate2);
    if (hres != S_OK)
    {
        WARN("IServiceProvider_QueryService IID_IHttpNegotiate2 failed: %08x\n", hres);
        /* No goto done as per native */
    }
    else
    {
        len = sizeof(security_id)/sizeof(security_id[0]);
        hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, security_id, &len, 0);
        if (hres != S_OK)
        {
            WARN("IHttpNegotiate2_GetRootSecurityId failed: %08x\n", hres);
            /* No goto done as per native */
        }
    }

    /* FIXME: Handle security_id. Native calls undocumented function IsHostInProxyBypassList. */

    if (This->bind_info.dwBindVerb == BINDVERB_POST)
    {
        num = 0;
        hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_POST_COOKIE, &post_cookie,
                                               1, &num);
        if (hres == S_OK && num &&
            !InternetSetOptionW(This->request, INTERNET_OPTION_SECONDARY_CACHE_KEY,
                                post_cookie, lstrlenW(post_cookie)))
        {
            WARN("InternetSetOption INTERNET_OPTION_SECONDARY_CACHE_KEY failed: %d\n",
                 GetLastError());
        }
    }

    if (This->bind_info.dwBindVerb != BINDVERB_GET)
    {
        /* Native does not use GlobalLock/GlobalUnlock, so we won't either */
        if (This->bind_info.stgmedData.tymed != TYMED_HGLOBAL)
            WARN("Expected This->bind_info.stgmedData.tymed to be TYMED_HGLOBAL, not %d\n",
                 This->bind_info.stgmedData.tymed);
        else
            optional = (LPWSTR)This->bind_info.stgmedData.u.hGlobal;
    }
    if (!HttpSendRequestW(This->request, This->full_header, lstrlenW(This->full_header),
                          optional,
                          optional ? This->bind_info.cbstgmedData : 0) &&
        GetLastError() != ERROR_IO_PENDING)
    {
        WARN("HttpSendRequest failed: %d\n", GetLastError());
        hres = INET_E_DOWNLOAD_FAILURE;
        goto done;
    }

    hres = S_OK;
done:
    if (hres != S_OK)
    {
        IInternetProtocolSink_ReportResult(This->protocol_sink, hres, 0, NULL);
        HTTPPROTOCOL_Close(This);
    }

    CoTaskMemFree(post_cookie);
    CoTaskMemFree(addl_header);
    if (http_negotiate2)
        IHttpNegotiate2_Release(http_negotiate2);
    if (service_provider)
        IServiceProvider_Release(service_provider);

    while (num<sizeof(accept_mimes)/sizeof(accept_mimes[0]) &&
           accept_mimes[num])
        CoTaskMemFree(accept_mimes[num++]);
    CoTaskMemFree(user_agent);

    heap_free(pass);
    heap_free(user);
    heap_free(path);
    heap_free(host);

    return hres;
}

static HRESULT WINAPI HttpProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData)
{
    HttpProtocol *This = PROTOCOL_THIS(iface);
    DWORD len = sizeof(DWORD), status_code;
    LPWSTR response_headers = 0, content_type = 0, content_length = 0;

    static const WCHAR wszDefaultContentType[] =
        {'t','e','x','t','/','h','t','m','l',0};

    TRACE("(%p)->(%p)\n", This, pProtocolData);

    if (!pProtocolData)
    {
        WARN("Expected pProtocolData to be non-NULL\n");
        return S_OK;
    }
    else if (!This->request)
    {
        WARN("Expected request to be non-NULL\n");
        return S_OK;
    }
    else if (!This->http_negotiate)
    {
        WARN("Expected IHttpNegotiate pointer to be non-NULL\n");
        return S_OK;
    }
    else if (!This->protocol_sink)
    {
        WARN("Expected IInternetProtocolSink pointer to be non-NULL\n");
        return S_OK;
    }

    if (pProtocolData->pData == (LPVOID)BINDSTATUS_DOWNLOADINGDATA)
    {
        if (!HttpQueryInfoW(This->request, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER,
                            &status_code, &len, NULL))
        {
            WARN("HttpQueryInfo failed: %d\n", GetLastError());
        }
        else
        {
            len = 0;
            if ((!HttpQueryInfoW(This->request, HTTP_QUERY_RAW_HEADERS_CRLF, response_headers, &len,
                                 NULL) &&
                 GetLastError() != ERROR_INSUFFICIENT_BUFFER) ||
                !(response_headers = heap_alloc(len)) ||
                !HttpQueryInfoW(This->request, HTTP_QUERY_RAW_HEADERS_CRLF, response_headers, &len,
                                NULL))
            {
                WARN("HttpQueryInfo failed: %d\n", GetLastError());
            }
            else
            {
                HRESULT hres = IHttpNegotiate_OnResponse(This->http_negotiate, status_code,
                                                         response_headers, NULL, NULL);
                if (hres != S_OK)
                {
                    WARN("IHttpNegotiate_OnResponse failed: %08x\n", hres);
                    goto done;
                }
            }
        }

        len = 0;
        if ((!HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_TYPE, content_type, &len, NULL) &&
             GetLastError() != ERROR_INSUFFICIENT_BUFFER) ||
            !(content_type = heap_alloc(len)) ||
            !HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_TYPE, content_type, &len, NULL))
        {
            WARN("HttpQueryInfo failed: %d\n", GetLastError());
            IInternetProtocolSink_ReportProgress(This->protocol_sink,
                                                 (This->grfBINDF & BINDF_FROMURLMON) ?
                                                 BINDSTATUS_MIMETYPEAVAILABLE :
                                                 BINDSTATUS_RAWMIMETYPE,
                                                 wszDefaultContentType);
        }
        else
        {
            /* remove the charset, if present */
            LPWSTR p = strchrW(content_type, ';');
            if (p) *p = '\0';

            IInternetProtocolSink_ReportProgress(This->protocol_sink,
                                                 (This->grfBINDF & BINDF_FROMURLMON) ?
                                                 BINDSTATUS_MIMETYPEAVAILABLE :
                                                 BINDSTATUS_RAWMIMETYPE,
                                                 content_type);
        }

        len = 0;
        if ((!HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_LENGTH, content_length, &len, NULL) &&
             GetLastError() != ERROR_INSUFFICIENT_BUFFER) ||
            !(content_length = heap_alloc(len)) ||
            !HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_LENGTH, content_length, &len, NULL))
        {
            WARN("HttpQueryInfo failed: %d\n", GetLastError());
            This->content_length = 0;
        }
        else
        {
            This->content_length = atoiW(content_length);
        }

        This->flags |= FLAG_FIRST_CONTINUE_COMPLETE;
    }

    if (pProtocolData->pData >= (LPVOID)BINDSTATUS_DOWNLOADINGDATA)
    {
        /* InternetQueryDataAvailable may immediately fork and perform its asynchronous
         * read, so clear the flag _before_ calling so it does not incorrectly get cleared
         * after the status callback is called */
        This->flags &= ~FLAG_REQUEST_COMPLETE;
        if (!InternetQueryDataAvailable(This->request, &This->available_bytes, 0, 0))
        {
            if (GetLastError() != ERROR_IO_PENDING)
            {
                This->flags |= FLAG_REQUEST_COMPLETE;
                WARN("InternetQueryDataAvailable failed: %d\n", GetLastError());
                HTTPPROTOCOL_ReportResult(This, INET_E_DATA_NOT_AVAILABLE);
            }
        }
        else
        {
            This->flags |= FLAG_REQUEST_COMPLETE;
            HTTPPROTOCOL_ReportData(This);
        }
    }

done:
    heap_free(response_headers);
    heap_free(content_type);
    heap_free(content_length);

    /* Returns S_OK on native */
    return S_OK;
}

static HRESULT WINAPI HttpProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
        DWORD dwOptions)
{
    HttpProtocol *This = PROTOCOL_THIS(iface);
    FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
    return E_NOTIMPL;
}

static HRESULT WINAPI HttpProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
{
    HttpProtocol *This = PROTOCOL_THIS(iface);

    TRACE("(%p)->(%08x)\n", This, dwOptions);
    HTTPPROTOCOL_Close(This);

    return S_OK;
}

static HRESULT WINAPI HttpProtocol_Suspend(IInternetProtocol *iface)
{
    HttpProtocol *This = PROTOCOL_THIS(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI HttpProtocol_Resume(IInternetProtocol *iface)
{
    HttpProtocol *This = PROTOCOL_THIS(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI HttpProtocol_Read(IInternetProtocol *iface, void *pv,
        ULONG cb, ULONG *pcbRead)
{
    HttpProtocol *This = PROTOCOL_THIS(iface);
    ULONG read = 0, len = 0;
    HRESULT hres = S_FALSE;

    TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);

    if (!(This->flags & FLAG_REQUEST_COMPLETE))
    {
        hres = E_PENDING;
    }
    else while (!(This->flags & FLAG_ALL_DATA_READ) &&
                read < cb)
    {
        if (This->available_bytes == 0)
        {
            /* InternetQueryDataAvailable may immediately fork and perform its asynchronous
             * read, so clear the flag _before_ calling so it does not incorrectly get cleared
             * after the status callback is called */
            This->flags &= ~FLAG_REQUEST_COMPLETE;
            if (!InternetQueryDataAvailable(This->request, &This->available_bytes, 0, 0))
            {
                if (GetLastError() == ERROR_IO_PENDING)
                {
                    hres = E_PENDING;
                }
                else
                {
                    WARN("InternetQueryDataAvailable failed: %d\n", GetLastError());
                    hres = INET_E_DATA_NOT_AVAILABLE;
                    HTTPPROTOCOL_ReportResult(This, hres);
                }
                goto done;
            }
            else if (This->available_bytes == 0)
            {
                HTTPPROTOCOL_AllDataRead(This);
            }
        }
        else
        {
            if (!InternetReadFile(This->request, ((BYTE *)pv)+read,
                                  This->available_bytes > cb-read ?
                                  cb-read : This->available_bytes, &len))
            {
                WARN("InternetReadFile failed: %d\n", GetLastError());
                hres = INET_E_DOWNLOAD_FAILURE;
                HTTPPROTOCOL_ReportResult(This, hres);
                goto done;
            }
            else if (len == 0)
            {
                HTTPPROTOCOL_AllDataRead(This);
            }
            else
            {
                read += len;
                This->current_position += len;
                This->available_bytes -= len;
            }
        }
    }

    /* Per MSDN this should be if (read == cb), but native returns S_OK
     * if any bytes were read, so we will too */
    if (read)
        hres = S_OK;

done:
    if (pcbRead)
        *pcbRead = read;

    if (hres != E_PENDING)
        This->flags |= FLAG_REQUEST_COMPLETE;

    return hres;
}

static HRESULT WINAPI HttpProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
        DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
{
    HttpProtocol *This = PROTOCOL_THIS(iface);
    FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
    return E_NOTIMPL;
}

static HRESULT WINAPI HttpProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
{
    HttpProtocol *This = PROTOCOL_THIS(iface);

    TRACE("(%p)->(%08x)\n", This, dwOptions);

    if (!InternetLockRequestFile(This->request, &This->lock))
        WARN("InternetLockRequest failed: %d\n", GetLastError());

    return S_OK;
}

static HRESULT WINAPI HttpProtocol_UnlockRequest(IInternetProtocol *iface)
{
    HttpProtocol *This = PROTOCOL_THIS(iface);

    TRACE("(%p)\n", This);

    if (This->lock)
    {
        if (!InternetUnlockRequestFile(This->lock))
            WARN("InternetUnlockRequest failed: %d\n", GetLastError());
        This->lock = 0;
    }

    return S_OK;
}

#undef PROTOCOL_THIS

#define PRIORITY_THIS(iface) DEFINE_THIS(HttpProtocol, InternetPriority, iface)

static HRESULT WINAPI HttpPriority_QueryInterface(IInternetPriority *iface, REFIID riid, void **ppv)
{
    HttpProtocol *This = PRIORITY_THIS(iface);
    return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
}

static ULONG WINAPI HttpPriority_AddRef(IInternetPriority *iface)
{
    HttpProtocol *This = PRIORITY_THIS(iface);
    return IInternetProtocol_AddRef(PROTOCOL(This));
}

static ULONG WINAPI HttpPriority_Release(IInternetPriority *iface)
{
    HttpProtocol *This = PRIORITY_THIS(iface);
    return IInternetProtocol_Release(PROTOCOL(This));
}

static HRESULT WINAPI HttpPriority_SetPriority(IInternetPriority *iface, LONG nPriority)
{
    HttpProtocol *This = PRIORITY_THIS(iface);

    TRACE("(%p)->(%d)\n", This, nPriority);

    This->priority = nPriority;
    return S_OK;
}

static HRESULT WINAPI HttpPriority_GetPriority(IInternetPriority *iface, LONG *pnPriority)
{
    HttpProtocol *This = PRIORITY_THIS(iface);

    TRACE("(%p)->(%p)\n", This, pnPriority);

    *pnPriority = This->priority;
    return S_OK;
}

#undef PRIORITY_THIS

static const IInternetPriorityVtbl HttpPriorityVtbl = {
    HttpPriority_QueryInterface,
    HttpPriority_AddRef,
    HttpPriority_Release,
    HttpPriority_SetPriority,
    HttpPriority_GetPriority
};

static const IInternetProtocolVtbl HttpProtocolVtbl = {
    HttpProtocol_QueryInterface,
    HttpProtocol_AddRef,
    HttpProtocol_Release,
    HttpProtocol_Start,
    HttpProtocol_Continue,
    HttpProtocol_Abort,
    HttpProtocol_Terminate,
    HttpProtocol_Suspend,
    HttpProtocol_Resume,
    HttpProtocol_Read,
    HttpProtocol_Seek,
    HttpProtocol_LockRequest,
    HttpProtocol_UnlockRequest
};

HRESULT HttpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
{
    HttpProtocol *ret;

    TRACE("(%p %p)\n", pUnkOuter, ppobj);

    URLMON_LockModule();

    ret = heap_alloc(sizeof(HttpProtocol));

    ret->lpInternetProtocolVtbl = &HttpProtocolVtbl;
    ret->lpInternetPriorityVtbl = &HttpPriorityVtbl;
    ret->flags = ret->grfBINDF = 0;
    memset(&ret->bind_info, 0, sizeof(ret->bind_info));
    ret->protocol_sink = 0;
    ret->http_negotiate = 0;
    ret->internet = ret->connect = ret->request = 0;
    ret->full_header = 0;
    ret->lock = 0;
    ret->current_position = ret->content_length = ret->available_bytes = 0;
    ret->priority = 0;
    ret->ref = 1;

    *ppobj = PROTOCOL(ret);
    
    return S_OK;
}

HRESULT HttpSProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
{
    FIXME("(%p %p)\n", pUnkOuter, ppobj);
    return E_NOINTERFACE;
}
