Module: wine Branch: master Commit: 8077480b0e793219216b336c8d241a676afb4986 URL: http://source.winehq.org/git/wine.git/?a=commit;h=8077480b0e793219216b336c8d...
Author: Hans Leidekker hans@meelstraat.net Date: Wed Apr 8 15:22:44 2009 +0200
wininet: Support asynchronous HttpEndRequest.
---
dlls/wininet/http.c | 168 ++++++++++++++++++++++++----------------------- dlls/wininet/internet.h | 7 ++ 2 files changed, 93 insertions(+), 82 deletions(-)
diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index 3777d4c..8d03b61 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -714,57 +714,87 @@ BOOL WINAPI HttpAddRequestHeadersA(HINTERNET hHttpRequest, BOOL WINAPI HttpEndRequestA(HINTERNET hRequest, LPINTERNET_BUFFERSA lpBuffersOut, DWORD dwFlags, DWORD_PTR dwContext) { - LPINTERNET_BUFFERSA ptr; - LPINTERNET_BUFFERSW lpBuffersOutW,ptrW; + TRACE("(%p, %p, %08x, %08lx)\n", hRequest, lpBuffersOut, dwFlags, dwContext); + + if (lpBuffersOut) + { + INTERNET_SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + return HttpEndRequestW(hRequest, NULL, dwFlags, dwContext); +} + +static BOOL HTTP_HttpEndRequestW(LPWININETHTTPREQW lpwhr, DWORD dwFlags, DWORD_PTR dwContext) +{ BOOL rc = FALSE; + INT responseLen; + DWORD dwBufferSize; + INTERNET_ASYNC_RESULT iar;
- TRACE("(%p, %p, %08x, %08lx): stub\n", hRequest, lpBuffersOut, dwFlags, - dwContext); + INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, + INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
- ptr = lpBuffersOut; - if (ptr) - lpBuffersOutW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(INTERNET_BUFFERSW)); - else - lpBuffersOutW = NULL; + responseLen = HTTP_GetResponseHeaders(lpwhr, TRUE); + if (responseLen) + rc = TRUE;
- ptrW = lpBuffersOutW; - while (ptr) - { - if (ptr->lpvBuffer && ptr->dwBufferLength) - ptrW->lpvBuffer = HeapAlloc(GetProcessHeap(),0,ptr->dwBufferLength); - ptrW->dwBufferLength = ptr->dwBufferLength; - ptrW->dwBufferTotal= ptr->dwBufferTotal; + INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, + INTERNET_STATUS_RESPONSE_RECEIVED, &responseLen, sizeof(DWORD));
- if (ptr->Next) - ptrW->Next = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, - sizeof(INTERNET_BUFFERSW)); + /* process cookies here. Is this right? */ + HTTP_ProcessCookies(lpwhr);
- ptr = ptr->Next; - ptrW = ptrW->Next; - } + dwBufferSize = sizeof(lpwhr->dwContentLength); + if (!HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH, + &lpwhr->dwContentLength, &dwBufferSize, NULL)) + lpwhr->dwContentLength = -1;
- rc = HttpEndRequestW(hRequest, lpBuffersOutW, dwFlags, dwContext); + if (lpwhr->dwContentLength == 0) + HTTP_FinishedReading(lpwhr);
- if (lpBuffersOutW) + if (!(lpwhr->hdr.dwFlags & INTERNET_FLAG_NO_AUTO_REDIRECT)) { - ptrW = lpBuffersOutW; - while (ptrW) + DWORD dwCode,dwCodeLength = sizeof(DWORD); + if (HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE, &dwCode, &dwCodeLength, NULL) && + (dwCode == 302 || dwCode == 301 || dwCode == 303)) { - LPINTERNET_BUFFERSW ptrW2; - - FIXME("Do we need to translate info out of these buffer?\n"); - - HeapFree(GetProcessHeap(),0,ptrW->lpvBuffer); - ptrW2 = ptrW->Next; - HeapFree(GetProcessHeap(),0,ptrW); - ptrW = ptrW2; + WCHAR szNewLocation[INTERNET_MAX_URL_LENGTH]; + dwBufferSize=sizeof(szNewLocation); + if (HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_LOCATION, szNewLocation, &dwBufferSize, NULL)) + { + /* redirects are always GETs */ + HeapFree(GetProcessHeap(), 0, lpwhr->lpszVerb); + lpwhr->lpszVerb = WININET_strdupW(szGET); + HTTP_DrainContent(lpwhr); + INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, + INTERNET_STATUS_REDIRECT, szNewLocation, dwBufferSize); + rc = HTTP_HandleRedirect(lpwhr, szNewLocation); + if (rc) + rc = HTTP_HttpSendRequestW(lpwhr, NULL, 0, NULL, 0, 0, TRUE); + } } }
+ iar.dwResult = (DWORD_PTR)lpwhr->hdr.hInternet; + iar.dwError = rc ? 0 : INTERNET_GetLastError(); + + INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, + INTERNET_STATUS_REQUEST_COMPLETE, &iar, + sizeof(INTERNET_ASYNC_RESULT)); return rc; }
+static void AsyncHttpEndRequestProc(WORKREQUEST *work) +{ + struct WORKREQ_HTTPENDREQUESTW const *req = &work->u.HttpEndRequestW; + LPWININETHTTPREQW lpwhr = (LPWININETHTTPREQW)work->hdr; + + TRACE("%p\n", lpwhr); + + HTTP_HttpEndRequestW(lpwhr, req->dwFlags, req->dwContext); +} + /*********************************************************************** * HttpEndRequestW (WININET.@) * @@ -780,10 +810,15 @@ BOOL WINAPI HttpEndRequestW(HINTERNET hRequest, { BOOL rc = FALSE; LPWININETHTTPREQW lpwhr; - INT responseLen; - DWORD dwBufferSize;
TRACE("-->\n"); + + if (lpBuffersOut) + { + INTERNET_SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + lpwhr = (LPWININETHTTPREQW) WININET_GetObject( hRequest );
if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ) @@ -791,58 +826,27 @@ BOOL WINAPI HttpEndRequestW(HINTERNET hRequest, INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); if (lpwhr) WININET_Release( &lpwhr->hdr ); - return FALSE; + return FALSE; } - lpwhr->hdr.dwFlags |= dwFlags; - lpwhr->hdr.dwContext = dwContext;
- /* We appear to do nothing with lpBuffersOut.. is that correct? */ - - SendAsyncCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, - INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0); - - responseLen = HTTP_GetResponseHeaders(lpwhr, TRUE); - if (responseLen) - rc = TRUE; - - SendAsyncCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, - INTERNET_STATUS_RESPONSE_RECEIVED, &responseLen, sizeof(DWORD)); - - /* process cookies here. Is this right? */ - HTTP_ProcessCookies(lpwhr); + if (lpwhr->lpHttpSession->lpAppInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC) + { + WORKREQUEST work; + struct WORKREQ_HTTPENDREQUESTW *request;
- dwBufferSize = sizeof(lpwhr->dwContentLength); - if (!HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH, - &lpwhr->dwContentLength,&dwBufferSize,NULL)) - lpwhr->dwContentLength = -1; + work.asyncproc = AsyncHttpEndRequestProc; + work.hdr = WININET_AddRef( &lpwhr->hdr );
- if (lpwhr->dwContentLength == 0) - HTTP_FinishedReading(lpwhr); + request = &work.u.HttpEndRequestW; + request->dwFlags = dwFlags; + request->dwContext = dwContext;
- if(!(lpwhr->hdr.dwFlags & INTERNET_FLAG_NO_AUTO_REDIRECT)) - { - DWORD dwCode,dwCodeLength=sizeof(DWORD); - if(HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE,&dwCode,&dwCodeLength,NULL) && - (dwCode==302 || dwCode==301 || dwCode==303)) - { - WCHAR szNewLocation[INTERNET_MAX_URL_LENGTH]; - dwBufferSize=sizeof(szNewLocation); - if(HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_LOCATION,szNewLocation,&dwBufferSize,NULL)) - { - /* redirects are always GETs */ - HeapFree(GetProcessHeap(),0,lpwhr->lpszVerb); - lpwhr->lpszVerb = WININET_strdupW(szGET); - HTTP_DrainContent(lpwhr); - INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, - INTERNET_STATUS_REDIRECT, szNewLocation, - dwBufferSize); - rc = HTTP_HandleRedirect(lpwhr, szNewLocation); - if (rc) - rc = HTTP_HttpSendRequestW(lpwhr, NULL, 0, NULL, 0, 0, TRUE); - } - } + INTERNET_AsyncCall(&work); + INTERNET_SetLastError(ERROR_IO_PENDING); } + else + rc = HTTP_HttpEndRequestW(lpwhr, dwFlags, dwContext);
WININET_Release( &lpwhr->hdr ); TRACE("%i <--\n",rc); diff --git a/dlls/wininet/internet.h b/dlls/wininet/internet.h index 8e92788..f69c424 100644 --- a/dlls/wininet/internet.h +++ b/dlls/wininet/internet.h @@ -291,6 +291,12 @@ struct WORKREQ_HTTPSENDREQUESTW BOOL bEndRequest; };
+struct WORKREQ_HTTPENDREQUESTW +{ + DWORD dwFlags; + DWORD_PTR dwContext; +}; + struct WORKREQ_SENDCALLBACK { DWORD_PTR dwContext; @@ -337,6 +343,7 @@ typedef struct WORKREQ struct WORKREQ_FTPRENAMEFILEW FtpRenameFileW; struct WORKREQ_FTPFINDNEXTW FtpFindNextW; struct WORKREQ_HTTPSENDREQUESTW HttpSendRequestW; + struct WORKREQ_HTTPENDREQUESTW HttpEndRequestW; struct WORKREQ_SENDCALLBACK SendCallback; struct WORKREQ_INTERNETOPENURLW InternetOpenUrlW; struct WORKREQ_INTERNETREADFILEEXA InternetReadFileExA;