/*
 * 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 = NULL, 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);
        }
        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;
    if (This->grfBINDF & BINDF_NEEDFILE)
        request_flags |= INTERNET_FLAG_NEED_FILE;
    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);
        }

    if(This->grfBINDF & BINDF_NEEDFILE) {
        WCHAR cache_file[MAX_PATH];
        DWORD buflen = sizeof(cache_file);

        if(InternetQueryOptionW(This->request, INTERNET_OPTION_DATAFILE_NAME,
                                cache_file, &buflen))
        {
            IInternetProtocolSink_ReportProgress(This->protocol_sink,
                                                 BINDSTATUS_CACHEFILENAMEAVAILABLE,
                                                 cache_file);
        }else {
            FIXME("Could not get cache file\n");
        }
    }

        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;
}
