Commit 7483f975 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

urlmon: Fixed handling binding reading immediately from cache.

parent 9e019c9b
...@@ -445,11 +445,18 @@ static HRESULT HttpProtocol_open_request(Protocol *prot, IUri *uri, DWORD reques ...@@ -445,11 +445,18 @@ static HRESULT HttpProtocol_open_request(Protocol *prot, IUri *uri, DWORD reques
do { do {
error = send_http_request(This); error = send_http_request(This);
if(error == ERROR_IO_PENDING || error == ERROR_SUCCESS) switch(error) {
case ERROR_IO_PENDING:
return S_OK; return S_OK;
case ERROR_SUCCESS:
hres = handle_http_error(This, error); /*
* 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); } while(hres == RPC_E_RETRY);
WARN("HttpSendRequest failed: %d\n", error); WARN("HttpSendRequest failed: %d\n", error);
......
...@@ -70,6 +70,55 @@ static void all_data_read(Protocol *protocol) ...@@ -70,6 +70,55 @@ static void all_data_read(Protocol *protocol)
report_result(protocol, S_OK); 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) static void request_complete(Protocol *protocol, INTERNET_ASYNC_RESULT *ar)
{ {
PROTOCOLDATA data; PROTOCOLDATA data;
...@@ -298,12 +347,7 @@ HRESULT protocol_continue(Protocol *protocol, PROTOCOLDATA *data) ...@@ -298,12 +347,7 @@ HRESULT protocol_continue(Protocol *protocol, PROTOCOLDATA *data)
BOOL is_start; BOOL is_start;
HRESULT hres; HRESULT hres;
if (!data) { is_start = !data || data->pData == UlongToPtr(BINDSTATUS_DOWNLOADINGDATA);
WARN("Expected pProtocolData to be non-NULL\n");
return S_OK;
}
is_start = data->pData == UlongToPtr(BINDSTATUS_DOWNLOADINGDATA);
if(!protocol->request) { if(!protocol->request) {
WARN("Expected request to be non-NULL\n"); WARN("Expected request to be non-NULL\n");
...@@ -325,29 +369,12 @@ HRESULT protocol_continue(Protocol *protocol, PROTOCOLDATA *data) ...@@ -325,29 +369,12 @@ HRESULT protocol_continue(Protocol *protocol, PROTOCOLDATA *data)
return write_post_stream(protocol); return write_post_stream(protocol);
if(is_start) { if(is_start) {
hres = protocol->vtbl->start_downloading(protocol); hres = start_downloading(protocol);
if(FAILED(hres)) { if(FAILED(hres))
protocol_close_connection(protocol);
report_result(protocol, hres);
return S_OK; 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->available_bytes) {
if(protocol->query_available) { if(protocol->query_available) {
protocol->available_bytes = 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 ...@@ -400,7 +427,7 @@ HRESULT protocol_read(Protocol *protocol, void *buf, ULONG size, ULONG *read_ret
return S_FALSE; 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; *read_ret = 0;
return E_PENDING; return E_PENDING;
} }
......
...@@ -149,6 +149,7 @@ struct ProtocolVtbl { ...@@ -149,6 +149,7 @@ struct ProtocolVtbl {
#define FLAG_LAST_DATA_REPORTED 0x0010 #define FLAG_LAST_DATA_REPORTED 0x0010
#define FLAG_RESULT_REPORTED 0x0020 #define FLAG_RESULT_REPORTED 0x0020
#define FLAG_ERROR 0x0040 #define FLAG_ERROR 0x0040
#define FLAG_SYNC_READ 0x0080
HRESULT protocol_start(Protocol*,IInternetProtocol*,IUri*,IInternetProtocolSink*,IInternetBindInfo*) DECLSPEC_HIDDEN; HRESULT protocol_start(Protocol*,IInternetProtocol*,IUri*,IInternetProtocolSink*,IInternetBindInfo*) DECLSPEC_HIDDEN;
HRESULT protocol_continue(Protocol*,PROTOCOLDATA*) DECLSPEC_HIDDEN; HRESULT protocol_continue(Protocol*,PROTOCOLDATA*) DECLSPEC_HIDDEN;
...@@ -156,6 +157,7 @@ HRESULT protocol_read(Protocol*,void*,ULONG,ULONG*) DECLSPEC_HIDDEN; ...@@ -156,6 +157,7 @@ HRESULT protocol_read(Protocol*,void*,ULONG,ULONG*) DECLSPEC_HIDDEN;
HRESULT protocol_lock_request(Protocol*) DECLSPEC_HIDDEN; HRESULT protocol_lock_request(Protocol*) DECLSPEC_HIDDEN;
HRESULT protocol_unlock_request(Protocol*) DECLSPEC_HIDDEN; HRESULT protocol_unlock_request(Protocol*) DECLSPEC_HIDDEN;
HRESULT protocol_abort(Protocol*,HRESULT) DECLSPEC_HIDDEN; HRESULT protocol_abort(Protocol*,HRESULT) DECLSPEC_HIDDEN;
HRESULT protocol_syncbinding(Protocol*) DECLSPEC_HIDDEN;
void protocol_close_connection(Protocol*) DECLSPEC_HIDDEN; void protocol_close_connection(Protocol*) DECLSPEC_HIDDEN;
void find_domain_name(const WCHAR*,DWORD,INT*) DECLSPEC_HIDDEN; void find_domain_name(const WCHAR*,DWORD,INT*) DECLSPEC_HIDDEN;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment