Module: wine Branch: master Commit: 7483f975de90cf13028c689460145d1a92f18ae5 URL: http://source.winehq.org/git/wine.git/?a=commit;h=7483f975de90cf13028c689460...
Author: Jacek Caban jacek@codeweavers.com Date: Thu Mar 7 16:29:48 2013 +0100
urlmon: Fixed handling binding reading immediately from cache.
---
dlls/urlmon/http.c | 15 ++++++-- dlls/urlmon/protocol.c | 81 ++++++++++++++++++++++++++++++--------------- dlls/urlmon/urlmon_main.h | 2 + 3 files changed, 67 insertions(+), 31 deletions(-)
diff --git a/dlls/urlmon/http.c b/dlls/urlmon/http.c index b2c3d10..d5cef5c 100644 --- a/dlls/urlmon/http.c +++ b/dlls/urlmon/http.c @@ -445,11 +445,18 @@ static HRESULT HttpProtocol_open_request(Protocol *prot, IUri *uri, DWORD reques do { error = send_http_request(This);
- if(error == ERROR_IO_PENDING || error == ERROR_SUCCESS) + switch(error) { + case ERROR_IO_PENDING: return S_OK; - - hres = handle_http_error(This, error); - + case ERROR_SUCCESS: + /* + * If sending response ended synchronously, it means that we have the whole data + * available locally (most likely in cache). + */ + return protocol_syncbinding(&This->base); + default: + hres = handle_http_error(This, error); + } } while(hres == RPC_E_RETRY);
WARN("HttpSendRequest failed: %d\n", error); diff --git a/dlls/urlmon/protocol.c b/dlls/urlmon/protocol.c index 890d013..5598780 100644 --- a/dlls/urlmon/protocol.c +++ b/dlls/urlmon/protocol.c @@ -70,6 +70,55 @@ static void all_data_read(Protocol *protocol) report_result(protocol, S_OK); }
+static HRESULT start_downloading(Protocol *protocol) +{ + HRESULT hres; + + hres = protocol->vtbl->start_downloading(protocol); + if(FAILED(hres)) { + protocol_close_connection(protocol); + report_result(protocol, hres); + return S_OK; + } + + if(protocol->bindf & BINDF_NEEDFILE) { + WCHAR cache_file[MAX_PATH]; + DWORD buflen = sizeof(cache_file); + + if(InternetQueryOptionW(protocol->request, INTERNET_OPTION_DATAFILE_NAME, cache_file, &buflen)) { + report_progress(protocol, BINDSTATUS_CACHEFILENAMEAVAILABLE, cache_file); + }else { + FIXME("Could not get cache file\n"); + } + } + + protocol->flags |= FLAG_FIRST_CONTINUE_COMPLETE; + return S_OK; +} + +HRESULT protocol_syncbinding(Protocol *protocol) +{ + BOOL res; + HRESULT hres; + + protocol->flags |= FLAG_SYNC_READ; + + hres = start_downloading(protocol); + if(FAILED(hres)) + return hres; + + res = InternetQueryDataAvailable(protocol->request, &protocol->query_available, 0, 0); + if(res) + protocol->available_bytes = protocol->query_available; + else + WARN("InternetQueryDataAvailable failed: %u\n", GetLastError()); + + protocol->flags |= FLAG_FIRST_DATA_REPORTED|FLAG_LAST_DATA_REPORTED; + IInternetProtocolSink_ReportData(protocol->protocol_sink, BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE, + protocol->available_bytes, protocol->content_length); + return S_OK; +} + static void request_complete(Protocol *protocol, INTERNET_ASYNC_RESULT *ar) { PROTOCOLDATA data; @@ -298,12 +347,7 @@ HRESULT protocol_continue(Protocol *protocol, PROTOCOLDATA *data) BOOL is_start; HRESULT hres;
- if (!data) { - WARN("Expected pProtocolData to be non-NULL\n"); - return S_OK; - } - - is_start = data->pData == UlongToPtr(BINDSTATUS_DOWNLOADINGDATA); + is_start = !data || data->pData == UlongToPtr(BINDSTATUS_DOWNLOADINGDATA);
if(!protocol->request) { WARN("Expected request to be non-NULL\n"); @@ -325,29 +369,12 @@ HRESULT protocol_continue(Protocol *protocol, PROTOCOLDATA *data) return write_post_stream(protocol);
if(is_start) { - hres = protocol->vtbl->start_downloading(protocol); - if(FAILED(hres)) { - protocol_close_connection(protocol); - report_result(protocol, hres); + hres = start_downloading(protocol); + if(FAILED(hres)) return S_OK; - } - - if(protocol->bindf & BINDF_NEEDFILE) { - WCHAR cache_file[MAX_PATH]; - DWORD buflen = sizeof(cache_file); - - if(InternetQueryOptionW(protocol->request, INTERNET_OPTION_DATAFILE_NAME, - cache_file, &buflen)) { - report_progress(protocol, BINDSTATUS_CACHEFILENAMEAVAILABLE, cache_file); - }else { - FIXME("Could not get cache file\n"); - } - } - - protocol->flags |= FLAG_FIRST_CONTINUE_COMPLETE; }
- if(data->pData >= UlongToPtr(BINDSTATUS_DOWNLOADINGDATA)) { + if(!data || data->pData >= UlongToPtr(BINDSTATUS_DOWNLOADINGDATA)) { if(!protocol->available_bytes) { if(protocol->query_available) { protocol->available_bytes = protocol->query_available; @@ -400,7 +427,7 @@ HRESULT protocol_read(Protocol *protocol, void *buf, ULONG size, ULONG *read_ret return S_FALSE; }
- if(!(protocol->flags & FLAG_REQUEST_COMPLETE) || !protocol->available_bytes) { + if(!(protocol->flags & FLAG_SYNC_READ) && (!(protocol->flags & FLAG_REQUEST_COMPLETE) || !protocol->available_bytes)) { *read_ret = 0; return E_PENDING; } diff --git a/dlls/urlmon/urlmon_main.h b/dlls/urlmon/urlmon_main.h index ba23e74..faab45a 100644 --- a/dlls/urlmon/urlmon_main.h +++ b/dlls/urlmon/urlmon_main.h @@ -149,6 +149,7 @@ struct ProtocolVtbl { #define FLAG_LAST_DATA_REPORTED 0x0010 #define FLAG_RESULT_REPORTED 0x0020 #define FLAG_ERROR 0x0040 +#define FLAG_SYNC_READ 0x0080
HRESULT protocol_start(Protocol*,IInternetProtocol*,IUri*,IInternetProtocolSink*,IInternetBindInfo*) DECLSPEC_HIDDEN; HRESULT protocol_continue(Protocol*,PROTOCOLDATA*) DECLSPEC_HIDDEN; @@ -156,6 +157,7 @@ HRESULT protocol_read(Protocol*,void*,ULONG,ULONG*) DECLSPEC_HIDDEN; HRESULT protocol_lock_request(Protocol*) DECLSPEC_HIDDEN; HRESULT protocol_unlock_request(Protocol*) DECLSPEC_HIDDEN; HRESULT protocol_abort(Protocol*,HRESULT) DECLSPEC_HIDDEN; +HRESULT protocol_syncbinding(Protocol*) DECLSPEC_HIDDEN; void protocol_close_connection(Protocol*) DECLSPEC_HIDDEN;
void find_domain_name(const WCHAR*,DWORD,INT*) DECLSPEC_HIDDEN;