[WININET] Sync with Wine Staging 2.16. CORE-13762
authorAmine Khaldi <amine.khaldi@reactos.org>
Sun, 24 Sep 2017 11:17:59 +0000 (11:17 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sun, 24 Sep 2017 11:17:59 +0000 (11:17 +0000)
43deec9 wininet: Use standard wine_dbgstr_longlong.
085ce26 wininet: Drain content before reusing connection in open_http_connection.
59395d8 wininet: Never do blocking reads in chunked_read if zero chunk size is aready read.
4f40039 wininet: Release connection in HTTPREQ_Read only if remaining control data may be drainad without blocking.
8090d16 wininet: Store error state separately from end of stream in chunked stream.
752d078 wininet: Always use drain_content specific to stream type.
90b936f wininet: Try to read reamaining data in chunked_drain_content.
2ecdac8 wininet: Return error codes from HTTP streams.
7949a22 wininet: Correctly pass URL length to InternetCrackUrlW in get_redirect_url.
a24b826 wininet: Improved cookie debug traces.
f55a116 wininet: Fix potential use-after-free (Coverity).
89f1d8c wininet: Fixed connection_pool_cs declaration.
cee9982 wininet: Return an error on redirect with no host name specified.
61e28c0 wininet: Moved INTERNET_STATUS_REDIRECT notification to HTTP_HandleRedirect.
9c95915 wininet: Correctly handle redirects to non-http URLs.

svn path=/trunk/; revision=75946

reactos/dll/win32/wininet/cookie.c
reactos/dll/win32/wininet/http.c
reactos/dll/win32/wininet/urlcache.c
reactos/media/doc/README.WINE

index 2603caa..d06e021 100644 (file)
@@ -544,18 +544,12 @@ static DWORD get_cookie(substr_t host, substr_t path, DWORD flags, cookie_set_t
     }
 
     for(domain = get_cookie_domain(host, FALSE); domain; domain = domain->parent) {
     }
 
     for(domain = get_cookie_domain(host, FALSE); domain; domain = domain->parent) {
-        TRACE("Trying %s domain...\n", debugstr_w(domain->domain));
-
         LIST_FOR_EACH_ENTRY(container, &domain->path_list, cookie_container_t, entry) {
             struct list *cursor, *cursor2;
 
         LIST_FOR_EACH_ENTRY(container, &domain->path_list, cookie_container_t, entry) {
             struct list *cursor, *cursor2;
 
-            TRACE("path %s\n", debugstr_wn(container->path.str, container->path.len));
-
             if(!cookie_match_path(container, path))
                 continue;
 
             if(!cookie_match_path(container, path))
                 continue;
 
-            TRACE("found domain %p\n", domain->domain);
-
             LIST_FOR_EACH_SAFE(cursor, cursor2, &container->cookie_list) {
                 cookie_t *cookie_iter = LIST_ENTRY(cursor, cookie_t, entry);
 
             LIST_FOR_EACH_SAFE(cursor, cursor2, &container->cookie_list) {
                 cookie_t *cookie_iter = LIST_ENTRY(cursor, cookie_t, entry);
 
@@ -570,7 +564,6 @@ static DWORD get_cookie(substr_t host, substr_t path, DWORD flags, cookie_set_t
                 if((cookie_iter->flags & INTERNET_COOKIE_HTTPONLY) && !(flags & INTERNET_COOKIE_HTTPONLY))
                     continue;
 
                 if((cookie_iter->flags & INTERNET_COOKIE_HTTPONLY) && !(flags & INTERNET_COOKIE_HTTPONLY))
                     continue;
 
-
                 if(!res->size) {
                     res->cookies = heap_alloc(4*sizeof(*res->cookies));
                     if(!res->cookies)
                 if(!res->size) {
                     res->cookies = heap_alloc(4*sizeof(*res->cookies));
                     if(!res->cookies)
@@ -584,6 +577,9 @@ static DWORD get_cookie(substr_t host, substr_t path, DWORD flags, cookie_set_t
                     res->size *= 2;
                 }
 
                     res->size *= 2;
                 }
 
+                TRACE("%s = %s domain %s path %s\n", debugstr_w(cookie_iter->name), debugstr_w(cookie_iter->data),
+                      debugstr_w(domain->domain), debugstr_wn(container->path.str, container->path.len));
+
                 if(res->cnt)
                     res->string_len += 2; /* '; ' */
                 res->cookies[res->cnt++] = cookie_iter;
                 if(res->cnt)
                     res->string_len += 2; /* '; ' */
                 res->cookies[res->cnt++] = cookie_iter;
index 24dab81..05f1ba2 100644 (file)
@@ -180,13 +180,13 @@ static BOOL HTTP_DeleteCustomHeader(http_request_t *req, DWORD index);
 static LPWSTR HTTP_build_req( LPCWSTR *list, int len );
 static DWORD HTTP_HttpQueryInfoW(http_request_t*, DWORD, LPVOID, LPDWORD, LPDWORD);
 static UINT HTTP_DecodeBase64(LPCWSTR base64, LPSTR bin);
 static LPWSTR HTTP_build_req( LPCWSTR *list, int len );
 static DWORD HTTP_HttpQueryInfoW(http_request_t*, DWORD, LPVOID, LPDWORD, LPDWORD);
 static UINT HTTP_DecodeBase64(LPCWSTR base64, LPSTR bin);
-static BOOL drain_content(http_request_t*,BOOL);
+static DWORD drain_content(http_request_t*,BOOL);
 
 static CRITICAL_SECTION connection_pool_cs;
 static CRITICAL_SECTION_DEBUG connection_pool_debug =
 {
     0, 0, &connection_pool_cs,
 
 static CRITICAL_SECTION connection_pool_cs;
 static CRITICAL_SECTION_DEBUG connection_pool_debug =
 {
     0, 0, &connection_pool_cs,
-    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
+    { &connection_pool_debug.ProcessLocksList, &connection_pool_debug.ProcessLocksList },
       0, 0, { (DWORD_PTR)(__FILE__ ": connection_pool_cs") }
 };
 static CRITICAL_SECTION connection_pool_cs = { &connection_pool_debug, -1, 0, 0, 0, 0 };
       0, 0, { (DWORD_PTR)(__FILE__ ": connection_pool_cs") }
 };
 static CRITICAL_SECTION connection_pool_cs = { &connection_pool_debug, -1, 0, 0, 0, 0 };
@@ -367,7 +367,7 @@ static WCHAR *get_host_header( http_request_t *req )
 struct data_stream_vtbl_t {
     BOOL (*end_of_data)(data_stream_t*,http_request_t*);
     DWORD (*read)(data_stream_t*,http_request_t*,BYTE*,DWORD,DWORD*,BOOL);
 struct data_stream_vtbl_t {
     BOOL (*end_of_data)(data_stream_t*,http_request_t*);
     DWORD (*read)(data_stream_t*,http_request_t*,BYTE*,DWORD,DWORD*,BOOL);
-    BOOL (*drain_content)(data_stream_t*,http_request_t*);
+    DWORD (*drain_content)(data_stream_t*,http_request_t*,BOOL);
     void (*destroy)(data_stream_t*);
 };
 
     void (*destroy)(data_stream_t*);
 };
 
@@ -385,7 +385,8 @@ typedef struct {
         CHUNKED_STREAM_STATE_READING_CHUNK,
         CHUNKED_STREAM_STATE_DISCARD_EOL_AFTER_DATA,
         CHUNKED_STREAM_STATE_DISCARD_EOL_AT_END,
         CHUNKED_STREAM_STATE_READING_CHUNK,
         CHUNKED_STREAM_STATE_DISCARD_EOL_AFTER_DATA,
         CHUNKED_STREAM_STATE_DISCARD_EOL_AT_END,
-        CHUNKED_STREAM_STATE_END_OF_STREAM
+        CHUNKED_STREAM_STATE_END_OF_STREAM,
+        CHUNKED_STREAM_STATE_ERROR
     } state;
 } chunked_stream_t;
 
     } state;
 } chunked_stream_t;
 
@@ -493,10 +494,10 @@ static DWORD gzip_read(data_stream_t *stream, http_request_t *req, BYTE *buf, DW
     return res;
 }
 
     return res;
 }
 
-static BOOL gzip_drain_content(data_stream_t *stream, http_request_t *req)
+static DWORD gzip_drain_content(data_stream_t *stream, http_request_t *req, BOOL allow_blocking)
 {
     gzip_stream_t *gzip_stream = (gzip_stream_t*)stream;
 {
     gzip_stream_t *gzip_stream = (gzip_stream_t*)stream;
-    return gzip_stream->parent_stream->vtbl->drain_content(gzip_stream->parent_stream, req);
+    return gzip_stream->parent_stream->vtbl->drain_content(gzip_stream->parent_stream, req, allow_blocking);
 }
 
 static void gzip_destroy(data_stream_t *stream)
 }
 
 static void gzip_destroy(data_stream_t *stream)
@@ -2005,7 +2006,7 @@ static void HTTPREQ_CloseConnection(object_header_t *hdr)
 {
     http_request_t *req = (http_request_t*)hdr;
 
 {
     http_request_t *req = (http_request_t*)hdr;
 
-    http_release_netconn(req, drain_content(req, FALSE));
+    http_release_netconn(req, drain_content(req, FALSE) == ERROR_SUCCESS);
 }
 
 static DWORD str_to_buffer(const WCHAR *str, void *buffer, DWORD *size, BOOL unicode)
 }
 
 static DWORD str_to_buffer(const WCHAR *str, void *buffer, DWORD *size, BOOL unicode)
@@ -2628,7 +2629,7 @@ static DWORD netconn_read(data_stream_t *stream, http_request_t *req, BYTE *buf,
     return res;
 }
 
     return res;
 }
 
-static BOOL netconn_drain_content(data_stream_t *stream, http_request_t *req)
+static DWORD netconn_drain_content(data_stream_t *stream, http_request_t *req, BOOL allow_blocking)
 {
     netconn_stream_t *netconn_stream = (netconn_stream_t*)stream;
     BYTE buf[1024];
 {
     netconn_stream_t *netconn_stream = (netconn_stream_t*)stream;
     BYTE buf[1024];
@@ -2636,18 +2637,20 @@ static BOOL netconn_drain_content(data_stream_t *stream, http_request_t *req)
     size_t size;
 
     if(netconn_stream->content_length == ~0u)
     size_t size;
 
     if(netconn_stream->content_length == ~0u)
-        return FALSE;
+        return WSAEISCONN;
 
     while(netconn_stream->content_read < netconn_stream->content_length) {
         size = min(sizeof(buf), netconn_stream->content_length-netconn_stream->content_read);
 
     while(netconn_stream->content_read < netconn_stream->content_length) {
         size = min(sizeof(buf), netconn_stream->content_length-netconn_stream->content_read);
-        res = NETCON_recv(req->netconn, buf, size, FALSE, &len);
-        if(res || !len)
-            return FALSE;
+        res = NETCON_recv(req->netconn, buf, size, allow_blocking, &len);
+        if(res)
+            return res;
+        if(!len)
+            return WSAECONNABORTED;
 
         netconn_stream->content_read += len;
     }
 
 
         netconn_stream->content_read += len;
     }
 
-    return TRUE;
+    return ERROR_SUCCESS;
 }
 
 static void netconn_destroy(data_stream_t *stream)
 }
 
 static void netconn_destroy(data_stream_t *stream)
@@ -2672,7 +2675,14 @@ static char next_chunked_data_char(chunked_stream_t *stream)
 static BOOL chunked_end_of_data(data_stream_t *stream, http_request_t *req)
 {
     chunked_stream_t *chunked_stream = (chunked_stream_t*)stream;
 static BOOL chunked_end_of_data(data_stream_t *stream, http_request_t *req)
 {
     chunked_stream_t *chunked_stream = (chunked_stream_t*)stream;
-    return chunked_stream->state == CHUNKED_STREAM_STATE_END_OF_STREAM;
+    switch(chunked_stream->state) {
+    case CHUNKED_STREAM_STATE_DISCARD_EOL_AT_END:
+    case CHUNKED_STREAM_STATE_END_OF_STREAM:
+    case CHUNKED_STREAM_STATE_ERROR:
+        return TRUE;
+    default:
+        return FALSE;
+    }
 }
 
 static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf, DWORD size,
 }
 
 static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf, DWORD size,
@@ -2689,22 +2699,28 @@ static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf,
 
         /* Ensure that we have data in the buffer for states that need it. */
         if(!chunked_stream->buf_size) {
 
         /* Ensure that we have data in the buffer for states that need it. */
         if(!chunked_stream->buf_size) {
+            BOOL blocking_read = allow_blocking;
+
             switch(chunked_stream->state) {
             switch(chunked_stream->state) {
-            case CHUNKED_STREAM_STATE_READING_CHUNK_SIZE:
+            case CHUNKED_STREAM_STATE_DISCARD_EOL_AT_END:
             case CHUNKED_STREAM_STATE_DISCARD_EOL_AFTER_SIZE:
             case CHUNKED_STREAM_STATE_DISCARD_EOL_AFTER_SIZE:
+                /* never allow blocking after 0 chunk size */
+                if(!chunked_stream->chunk_size)
+                    blocking_read = FALSE;
+                /* fall through */
+            case CHUNKED_STREAM_STATE_READING_CHUNK_SIZE:
             case CHUNKED_STREAM_STATE_DISCARD_EOL_AFTER_DATA:
             case CHUNKED_STREAM_STATE_DISCARD_EOL_AFTER_DATA:
-            case CHUNKED_STREAM_STATE_DISCARD_EOL_AT_END:
                 chunked_stream->buf_pos = 0;
                 chunked_stream->buf_pos = 0;
-                res = NETCON_recv(req->netconn, chunked_stream->buf, sizeof(chunked_stream->buf), allow_blocking, &read_bytes);
+                res = NETCON_recv(req->netconn, chunked_stream->buf, sizeof(chunked_stream->buf), blocking_read, &read_bytes);
                 if(res == ERROR_SUCCESS && read_bytes) {
                     chunked_stream->buf_size += read_bytes;
                 }else if(res == WSAEWOULDBLOCK) {
                 if(res == ERROR_SUCCESS && read_bytes) {
                     chunked_stream->buf_size += read_bytes;
                 }else if(res == WSAEWOULDBLOCK) {
-                    if(ret_read)
+                    if(ret_read || allow_blocking)
                         res = ERROR_SUCCESS;
                     continue_read = FALSE;
                     continue;
                 }else {
                         res = ERROR_SUCCESS;
                     continue_read = FALSE;
                     continue;
                 }else {
-                    chunked_stream->state = CHUNKED_STREAM_STATE_END_OF_STREAM;
+                    chunked_stream->state = CHUNKED_STREAM_STATE_ERROR;
                 }
                 break;
             default:
                 }
                 break;
             default:
@@ -2766,7 +2782,7 @@ static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf,
                 }
 
                 if(!read_bytes) {
                 }
 
                 if(!read_bytes) {
-                    chunked_stream->state = CHUNKED_STREAM_STATE_END_OF_STREAM;
+                    chunked_stream->state = CHUNKED_STREAM_STATE_ERROR;
                     continue;
                 }
             }
                     continue;
                 }
             }
@@ -2796,6 +2812,7 @@ static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf,
             break;
 
         case CHUNKED_STREAM_STATE_END_OF_STREAM:
             break;
 
         case CHUNKED_STREAM_STATE_END_OF_STREAM:
+        case CHUNKED_STREAM_STATE_ERROR:
             continue_read = FALSE;
             break;
         }
             continue_read = FALSE;
             break;
         }
@@ -2811,10 +2828,22 @@ static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf,
     return ERROR_SUCCESS;
 }
 
     return ERROR_SUCCESS;
 }
 
-static BOOL chunked_drain_content(data_stream_t *stream, http_request_t *req)
+static DWORD chunked_drain_content(data_stream_t *stream, http_request_t *req, BOOL allow_blocking)
 {
     chunked_stream_t *chunked_stream = (chunked_stream_t*)stream;
 {
     chunked_stream_t *chunked_stream = (chunked_stream_t*)stream;
-    return chunked_stream->state == CHUNKED_STREAM_STATE_END_OF_STREAM;
+    BYTE buf[1024];
+    DWORD size, res;
+
+    while(chunked_stream->state != CHUNKED_STREAM_STATE_END_OF_STREAM
+          && chunked_stream->state != CHUNKED_STREAM_STATE_ERROR) {
+        res = chunked_read(stream, req, buf, sizeof(buf), &size, allow_blocking);
+        if(res != ERROR_SUCCESS)
+            return res;
+    }
+
+    if(chunked_stream->state != CHUNKED_STREAM_STATE_END_OF_STREAM)
+        return ERROR_NO_DATA;
+    return ERROR_SUCCESS;
 }
 
 static void chunked_destroy(data_stream_t *stream)
 }
 
 static void chunked_destroy(data_stream_t *stream)
@@ -2968,46 +2997,34 @@ static DWORD HTTPREQ_Read(http_request_t *req, void *buffer, DWORD size, DWORD *
     LeaveCriticalSection( &req->read_section );
 
     *read = ret_read;
     LeaveCriticalSection( &req->read_section );
 
     *read = ret_read;
-    TRACE( "retrieved %u bytes (%u)\n", ret_read, req->contentLength );
+    TRACE( "retrieved %u bytes (res %u)\n", ret_read, res );
 
 
-    if(res != WSAEWOULDBLOCK && (!ret_read || res != ERROR_SUCCESS))
-        http_release_netconn(req, res == ERROR_SUCCESS);
+    if(res != WSAEWOULDBLOCK) {
+        if(res != ERROR_SUCCESS)
+            http_release_netconn(req, FALSE);
+        else if(!ret_read && drain_content(req, FALSE) == ERROR_SUCCESS)
+            http_release_netconn(req, TRUE);
+    }
 
     return res;
 }
 
 
     return res;
 }
 
-static BOOL drain_content(http_request_t *req, BOOL blocking)
+static DWORD drain_content(http_request_t *req, BOOL blocking)
 {
 {
-    BOOL ret;
+    DWORD res;
 
 
-    if(!is_valid_netconn(req->netconn) || req->contentLength == -1)
-        return FALSE;
+    TRACE("%p\n", req->netconn);
 
 
-    if(!strcmpW(req->verb, szHEAD))
-        return TRUE;
+    if(!is_valid_netconn(req->netconn))
+        return ERROR_NO_DATA;
 
 
-    if(!blocking)
-        return req->data_stream->vtbl->drain_content(req->data_stream, req);
+    if(!strcmpW(req->verb, szHEAD))
+        return ERROR_SUCCESS;
 
     EnterCriticalSection( &req->read_section );
 
     EnterCriticalSection( &req->read_section );
-
-    while(1) {
-        DWORD bytes_read, res;
-        BYTE buf[4096];
-
-        res = HTTPREQ_Read(req, buf, sizeof(buf), &bytes_read, TRUE);
-        if(res != ERROR_SUCCESS) {
-            ret = FALSE;
-            break;
-        }
-        if(!bytes_read) {
-            ret = TRUE;
-            break;
-        }
-    }
-
+    res = req->data_stream->vtbl->drain_content(req->data_stream, req, blocking);
     LeaveCriticalSection( &req->read_section );
     LeaveCriticalSection( &req->read_section );
-    return ret;
+    return res;
 }
 
 typedef struct {
 }
 
 typedef struct {
@@ -3042,7 +3059,7 @@ static void async_read_file_proc(task_header_t *hdr)
         if(task->ret_read)
             complete_arg = read; /* QueryDataAvailable reports read bytes in request complete notification */
         if(res != ERROR_SUCCESS || !read)
         if(task->ret_read)
             complete_arg = read; /* QueryDataAvailable reports read bytes in request complete notification */
         if(res != ERROR_SUCCESS || !read)
-            http_release_netconn(req, drain_content(req, FALSE));
+            http_release_netconn(req, drain_content(req, FALSE) == ERROR_SUCCESS);
     }
 
     TRACE("res %u read %u\n", res, read);
     }
 
     TRACE("res %u read %u\n", res, read);
@@ -3987,7 +4004,16 @@ static WCHAR *get_redirect_url(http_request_t *request)
         return NULL;
     }
 
         return NULL;
     }
 
+    urlComponents.dwSchemeLength = 1;
+    b = InternetCrackUrlW(redirect_url, url_length / sizeof(WCHAR), 0, &urlComponents);
+    if(b && urlComponents.dwSchemeLength &&
+       urlComponents.nScheme != INTERNET_SCHEME_HTTP && urlComponents.nScheme != INTERNET_SCHEME_HTTPS) {
+        TRACE("redirect to non-http URL\n");
+        return NULL;
+    }
+
     urlComponents.lpszScheme = (request->hdr.dwFlags & INTERNET_FLAG_SECURE) ? szHttps : szHttp;
     urlComponents.lpszScheme = (request->hdr.dwFlags & INTERNET_FLAG_SECURE) ? szHttps : szHttp;
+    urlComponents.dwSchemeLength = 0;
     urlComponents.lpszHostName = request->server->name;
     urlComponents.nPort = request->server->port;
     urlComponents.lpszUserName = session->userName;
     urlComponents.lpszHostName = request->server->name;
     urlComponents.nPort = request->server->port;
     urlComponents.lpszUserName = session->userName;
@@ -4024,30 +4050,36 @@ static WCHAR *get_redirect_url(http_request_t *request)
 /***********************************************************************
  *           HTTP_HandleRedirect (internal)
  */
 /***********************************************************************
  *           HTTP_HandleRedirect (internal)
  */
-static DWORD HTTP_HandleRedirect(http_request_t *request, LPCWSTR lpszUrl)
+static DWORD HTTP_HandleRedirect(http_request_t *request, WCHAR *url)
 {
 {
+    URL_COMPONENTSW urlComponents = { sizeof(urlComponents) };
     http_session_t *session = request->session;
     http_session_t *session = request->session;
-    WCHAR *path;
+    size_t url_len = strlenW(url);
 
 
-    if(lpszUrl[0]=='/')
+    if(url[0] == '/')
     {
         /* if it's an absolute path, keep the same session info */
     {
         /* if it's an absolute path, keep the same session info */
-        path = heap_strdupW(lpszUrl);
+        urlComponents.lpszUrlPath = url;
+        urlComponents.dwUrlPathLength = url_len;
     }
     else
     {
     }
     else
     {
-        URL_COMPONENTSW urlComponents = { sizeof(urlComponents) };
-        BOOL custom_port = FALSE;
-        substr_t host;
-
         urlComponents.dwHostNameLength = 1;
         urlComponents.dwUserNameLength = 1;
         urlComponents.dwUrlPathLength = 1;
         urlComponents.dwHostNameLength = 1;
         urlComponents.dwUserNameLength = 1;
         urlComponents.dwUrlPathLength = 1;
-        if(!InternetCrackUrlW(lpszUrl, strlenW(lpszUrl), 0, &urlComponents))
+        if(!InternetCrackUrlW(url, url_len, 0, &urlComponents))
             return INTERNET_GetLastError();
 
             return INTERNET_GetLastError();
 
-        if (!urlComponents.dwHostNameLength)
+        if(!urlComponents.dwHostNameLength)
             return ERROR_INTERNET_INVALID_URL;
             return ERROR_INTERNET_INVALID_URL;
+    }
+
+    INTERNET_SendCallback(&request->hdr, request->hdr.dwContext, INTERNET_STATUS_REDIRECT,
+                          url, (url_len + 1) * sizeof(WCHAR));
+
+    if(urlComponents.dwHostNameLength) {
+        BOOL custom_port = FALSE;
+        substr_t host;
 
         if(urlComponents.nScheme == INTERNET_SCHEME_HTTP) {
             if(request->hdr.dwFlags & INTERNET_FLAG_SECURE) {
 
         if(urlComponents.nScheme == INTERNET_SCHEME_HTTP) {
             if(request->hdr.dwFlags & INTERNET_FLAG_SECURE) {
@@ -4094,17 +4126,18 @@ static DWORD HTTP_HandleRedirect(http_request_t *request, LPCWSTR lpszUrl)
             HTTP_ProcessHeader(request, hostW, request->server->host_port, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDHDR_FLAG_REQ);
         else
             HTTP_ProcessHeader(request, hostW, request->server->name, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDHDR_FLAG_REQ);
             HTTP_ProcessHeader(request, hostW, request->server->host_port, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDHDR_FLAG_REQ);
         else
             HTTP_ProcessHeader(request, hostW, request->server->name, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDHDR_FLAG_REQ);
-
-        path = heap_strndupW(urlComponents.lpszUrlPath, urlComponents.dwUrlPathLength);
     }
     }
+
     heap_free(request->path);
     request->path = NULL;
     heap_free(request->path);
     request->path = NULL;
-    if (*path)
+    if(urlComponents.dwUrlPathLength)
     {
         DWORD needed = 1;
         HRESULT rc;
         WCHAR dummy = 0;
     {
         DWORD needed = 1;
         HRESULT rc;
         WCHAR dummy = 0;
+        WCHAR *path;
 
 
+        path = heap_strndupW(urlComponents.lpszUrlPath, urlComponents.dwUrlPathLength);
         rc = UrlEscapeW(path, &dummy, &needed, URL_ESCAPE_SPACES_ONLY);
         if (rc != E_POINTER)
             ERR("Unable to escape string!(%s) (%d)\n",debugstr_w(path),rc);
         rc = UrlEscapeW(path, &dummy, &needed, URL_ESCAPE_SPACES_ONLY);
         if (rc != E_POINTER)
             ERR("Unable to escape string!(%s) (%d)\n",debugstr_w(path),rc);
@@ -4116,10 +4149,9 @@ static DWORD HTTP_HandleRedirect(http_request_t *request, LPCWSTR lpszUrl)
             ERR("Unable to escape string!(%s) (%d)\n",debugstr_w(path),rc);
             strcpyW(request->path, path);
         }
             ERR("Unable to escape string!(%s) (%d)\n",debugstr_w(path),rc);
             strcpyW(request->path, path);
         }
+        heap_free(path);
     }
 
     }
 
-    heap_free(path);
-
     /* Remove custom content-type/length headers on redirects.  */
     remove_header(request, szContent_Type, TRUE);
     remove_header(request, szContent_Length, TRUE);
     /* Remove custom content-type/length headers on redirects.  */
     remove_header(request, szContent_Type, TRUE);
     remove_header(request, szContent_Length, TRUE);
@@ -4707,22 +4739,22 @@ static DWORD open_http_connection(http_request_t *request, BOOL *reusing)
     netconn_t *netconn = NULL;
     DWORD res;
 
     netconn_t *netconn = NULL;
     DWORD res;
 
-    reset_data_stream(request);
-
     if (request->netconn)
     {
     if (request->netconn)
     {
-        if (is_valid_netconn(request->netconn) && NETCON_is_alive(request->netconn))
+        if (NETCON_is_alive(request->netconn) && drain_content(request, TRUE) == ERROR_SUCCESS)
         {
         {
+            reset_data_stream(request);
             *reusing = TRUE;
             return ERROR_SUCCESS;
         }
             *reusing = TRUE;
             return ERROR_SUCCESS;
         }
-        else
-        {
-            free_netconn(request->netconn);
-            request->netconn = NULL;
-        }
+
+        TRACE("freeing netconn\n");
+        free_netconn(request->netconn);
+        request->netconn = NULL;
     }
 
     }
 
+    reset_data_stream(request);
+
     res = HTTP_ResolveName(request);
     if(res != ERROR_SUCCESS)
         return res;
     res = HTTP_ResolveName(request);
     if(res != ERROR_SUCCESS)
         return res;
@@ -5027,9 +5059,7 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
                         heap_free(request->verb);
                         request->verb = heap_strdupW(szGET);
                     }
                         heap_free(request->verb);
                         request->verb = heap_strdupW(szGET);
                     }
-                    http_release_netconn(request, drain_content(request, FALSE));
-                    INTERNET_SendCallback(&request->hdr, request->hdr.dwContext, INTERNET_STATUS_REDIRECT,
-                                          new_url, (strlenW(new_url) + 1) * sizeof(WCHAR));
+                    http_release_netconn(request, drain_content(request, FALSE) == ERROR_SUCCESS);
                     res = HTTP_HandleRedirect(request, new_url);
                     heap_free(new_url);
                     if (res == ERROR_SUCCESS) {
                     res = HTTP_HandleRedirect(request, new_url);
                     heap_free(new_url);
                     if (res == ERROR_SUCCESS) {
@@ -5055,7 +5085,7 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
                                                  request->session->password, host))
                         {
                             heap_free(requestString);
                                                  request->session->password, host))
                         {
                             heap_free(requestString);
-                            if(!drain_content(request, TRUE)) {
+                            if(!drain_content(request, TRUE) == ERROR_SUCCESS) {
                                 FIXME("Could not drain content\n");
                                 http_release_netconn(request, FALSE);
                             }
                                 FIXME("Could not drain content\n");
                                 http_release_netconn(request, FALSE);
                             }
@@ -5083,7 +5113,7 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
                                                  NULL))
                         {
                             heap_free(requestString);
                                                  NULL))
                         {
                             heap_free(requestString);
-                            if(!drain_content(request, TRUE)) {
+                            if(!drain_content(request, TRUE) == ERROR_SUCCESS) {
                                 FIXME("Could not drain content\n");
                                 http_release_netconn(request, FALSE);
                             }
                                 FIXME("Could not drain content\n");
                                 http_release_netconn(request, FALSE);
                             }
@@ -5225,9 +5255,7 @@ static DWORD HTTP_HttpEndRequestW(http_request_t *request, DWORD dwFlags, DWORD_
                 heap_free(request->verb);
                 request->verb = heap_strdupW(szGET);
             }
                 heap_free(request->verb);
                 request->verb = heap_strdupW(szGET);
             }
-            http_release_netconn(request, drain_content(request, FALSE));
-            INTERNET_SendCallback(&request->hdr, request->hdr.dwContext, INTERNET_STATUS_REDIRECT,
-                                  new_url, (strlenW(new_url) + 1) * sizeof(WCHAR));
+            http_release_netconn(request, drain_content(request, FALSE) == ERROR_SUCCESS);
             res = HTTP_HandleRedirect(request, new_url);
             heap_free(new_url);
             if (res == ERROR_SUCCESS)
             res = HTTP_HandleRedirect(request, new_url);
             heap_free(new_url);
             if (res == ERROR_SUCCESS)
index 6121b65..11c1329 100644 (file)
@@ -3424,8 +3424,8 @@ HANDLE WINAPI FindFirstUrlCacheEntryExA(
   LPVOID lpReserved3
 )
 {
   LPVOID lpReserved3
 )
 {
-    FIXME("(%s, 0x%08x, 0x%08x, 0x%08x%08x, %p, %p, %p, %p, %p) stub\n", debugstr_a(lpszUrlSearchPattern),
-          dwFlags, dwFilter, (ULONG)(GroupId >> 32), (ULONG)GroupId, lpFirstCacheEntryInfo,
+    FIXME("(%s, 0x%08x, 0x%08x, 0x%s, %p, %p, %p, %p, %p) stub\n", debugstr_a(lpszUrlSearchPattern),
+          dwFlags, dwFilter, wine_dbgstr_longlong(GroupId), lpFirstCacheEntryInfo,
           lpdwFirstCacheEntryInfoBufferSize, lpReserved, pcbReserved2,lpReserved3);
     SetLastError(ERROR_FILE_NOT_FOUND);
     return NULL;
           lpdwFirstCacheEntryInfoBufferSize, lpReserved, pcbReserved2,lpReserved3);
     SetLastError(ERROR_FILE_NOT_FOUND);
     return NULL;
@@ -3443,8 +3443,8 @@ HANDLE WINAPI FindFirstUrlCacheEntryExW(
   LPVOID lpReserved3
 )
 {
   LPVOID lpReserved3
 )
 {
-    FIXME("(%s, 0x%08x, 0x%08x, 0x%08x%08x, %p, %p, %p, %p, %p) stub\n", debugstr_w(lpszUrlSearchPattern),
-          dwFlags, dwFilter, (ULONG)(GroupId >> 32), (ULONG)GroupId, lpFirstCacheEntryInfo,
+    FIXME("(%s, 0x%08x, 0x%08x, 0x%s, %p, %p, %p, %p, %p) stub\n", debugstr_w(lpszUrlSearchPattern),
+          dwFlags, dwFilter, wine_dbgstr_longlong(GroupId), lpFirstCacheEntryInfo,
           lpdwFirstCacheEntryInfoBufferSize, lpReserved, pcbReserved2,lpReserved3);
     SetLastError(ERROR_FILE_NOT_FOUND);
     return NULL;
           lpdwFirstCacheEntryInfoBufferSize, lpReserved, pcbReserved2,lpReserved3);
     SetLastError(ERROR_FILE_NOT_FOUND);
     return NULL;
@@ -3720,8 +3720,8 @@ INTERNETAPI GROUPID WINAPI CreateUrlCacheGroup(DWORD dwFlags, LPVOID lpReserved)
  */
 BOOL WINAPI DeleteUrlCacheGroup(GROUPID GroupId, DWORD dwFlags, LPVOID lpReserved)
 {
  */
 BOOL WINAPI DeleteUrlCacheGroup(GROUPID GroupId, DWORD dwFlags, LPVOID lpReserved)
 {
-    FIXME("(0x%08x%08x, 0x%08x, %p) stub\n",
-          (ULONG)(GroupId >> 32), (ULONG)GroupId, dwFlags, lpReserved);
+    FIXME("(0x%s, 0x%08x, %p) stub\n",
+          wine_dbgstr_longlong(GroupId), dwFlags, lpReserved);
     return FALSE;
 }
 
     return FALSE;
 }
 
@@ -3743,8 +3743,8 @@ BOOL WINAPI SetUrlCacheEntryGroupA(LPCSTR lpszUrlName, DWORD dwFlags,
   GROUPID GroupId, LPBYTE pbGroupAttributes, DWORD cbGroupAttributes,
   LPVOID lpReserved)
 {
   GROUPID GroupId, LPBYTE pbGroupAttributes, DWORD cbGroupAttributes,
   LPVOID lpReserved)
 {
-    FIXME("(%s, 0x%08x, 0x%08x%08x, %p, 0x%08x, %p) stub\n",
-          debugstr_a(lpszUrlName), dwFlags, (ULONG)(GroupId >> 32), (ULONG)GroupId,
+    FIXME("(%s, 0x%08x, 0x%s, %p, 0x%08x, %p) stub\n",
+          debugstr_a(lpszUrlName), dwFlags, wine_dbgstr_longlong(GroupId),
           pbGroupAttributes, cbGroupAttributes, lpReserved);
     SetLastError(ERROR_FILE_NOT_FOUND);
     return FALSE;
           pbGroupAttributes, cbGroupAttributes, lpReserved);
     SetLastError(ERROR_FILE_NOT_FOUND);
     return FALSE;
@@ -3758,8 +3758,8 @@ BOOL WINAPI SetUrlCacheEntryGroupW(LPCWSTR lpszUrlName, DWORD dwFlags,
   GROUPID GroupId, LPBYTE pbGroupAttributes, DWORD cbGroupAttributes,
   LPVOID lpReserved)
 {
   GROUPID GroupId, LPBYTE pbGroupAttributes, DWORD cbGroupAttributes,
   LPVOID lpReserved)
 {
-    FIXME("(%s, 0x%08x, 0x%08x%08x, %p, 0x%08x, %p) stub\n",
-          debugstr_w(lpszUrlName), dwFlags, (ULONG)(GroupId >> 32), (ULONG)GroupId,
+    FIXME("(%s, 0x%08x, 0x%s, %p, 0x%08x, %p) stub\n",
+          debugstr_w(lpszUrlName), dwFlags, wine_dbgstr_longlong(GroupId),
           pbGroupAttributes, cbGroupAttributes, lpReserved);
     SetLastError(ERROR_FILE_NOT_FOUND);
     return FALSE;
           pbGroupAttributes, cbGroupAttributes, lpReserved);
     SetLastError(ERROR_FILE_NOT_FOUND);
     return FALSE;
@@ -3789,8 +3789,8 @@ BOOL WINAPI GetUrlCacheGroupAttributeA( GROUPID gid, DWORD dwFlags, DWORD dwAttr
                                         LPINTERNET_CACHE_GROUP_INFOA lpGroupInfo,
                                         LPDWORD lpdwGroupInfo, LPVOID lpReserved )
 {
                                         LPINTERNET_CACHE_GROUP_INFOA lpGroupInfo,
                                         LPDWORD lpdwGroupInfo, LPVOID lpReserved )
 {
-    FIXME("(0x%08x%08x, 0x%08x, 0x%08x, %p, %p, %p) stub\n",
-          (ULONG)(gid >> 32), (ULONG)gid, dwFlags, dwAttributes, lpGroupInfo,
+    FIXME("(0x%s, 0x%08x, 0x%08x, %p, %p, %p) stub\n",
+          wine_dbgstr_longlong(gid), dwFlags, dwAttributes, lpGroupInfo,
           lpdwGroupInfo, lpReserved);
     return FALSE;
 }
           lpdwGroupInfo, lpReserved);
     return FALSE;
 }
@@ -3799,8 +3799,8 @@ BOOL WINAPI GetUrlCacheGroupAttributeW( GROUPID gid, DWORD dwFlags, DWORD dwAttr
                                         LPINTERNET_CACHE_GROUP_INFOW lpGroupInfo,
                                         LPDWORD lpdwGroupInfo, LPVOID lpReserved )
 {
                                         LPINTERNET_CACHE_GROUP_INFOW lpGroupInfo,
                                         LPDWORD lpdwGroupInfo, LPVOID lpReserved )
 {
-    FIXME("(0x%08x%08x, 0x%08x, 0x%08x, %p, %p, %p) stub\n",
-          (ULONG)(gid >> 32), (ULONG)gid, dwFlags, dwAttributes, lpGroupInfo,
+    FIXME("(0x%s, 0x%08x, 0x%08x, %p, %p, %p) stub\n",
+          wine_dbgstr_longlong(gid), dwFlags, dwAttributes, lpGroupInfo,
           lpdwGroupInfo, lpReserved);
     return FALSE;
 }
           lpdwGroupInfo, lpReserved);
     return FALSE;
 }
@@ -3808,16 +3808,16 @@ BOOL WINAPI GetUrlCacheGroupAttributeW( GROUPID gid, DWORD dwFlags, DWORD dwAttr
 BOOL WINAPI SetUrlCacheGroupAttributeA( GROUPID gid, DWORD dwFlags, DWORD dwAttributes,
                                         LPINTERNET_CACHE_GROUP_INFOA lpGroupInfo, LPVOID lpReserved )
 {
 BOOL WINAPI SetUrlCacheGroupAttributeA( GROUPID gid, DWORD dwFlags, DWORD dwAttributes,
                                         LPINTERNET_CACHE_GROUP_INFOA lpGroupInfo, LPVOID lpReserved )
 {
-    FIXME("(0x%08x%08x, 0x%08x, 0x%08x, %p, %p) stub\n",
-          (ULONG)(gid >> 32), (ULONG)gid, dwFlags, dwAttributes, lpGroupInfo, lpReserved);
+    FIXME("(0x%s, 0x%08x, 0x%08x, %p, %p) stub\n",
+          wine_dbgstr_longlong(gid), dwFlags, dwAttributes, lpGroupInfo, lpReserved);
     return TRUE;
 }
 
 BOOL WINAPI SetUrlCacheGroupAttributeW( GROUPID gid, DWORD dwFlags, DWORD dwAttributes,
                                         LPINTERNET_CACHE_GROUP_INFOW lpGroupInfo, LPVOID lpReserved )
 {
     return TRUE;
 }
 
 BOOL WINAPI SetUrlCacheGroupAttributeW( GROUPID gid, DWORD dwFlags, DWORD dwAttributes,
                                         LPINTERNET_CACHE_GROUP_INFOW lpGroupInfo, LPVOID lpReserved )
 {
-    FIXME("(0x%08x%08x, 0x%08x, 0x%08x, %p, %p) stub\n",
-          (ULONG)(gid >> 32), (ULONG)gid, dwFlags, dwAttributes, lpGroupInfo, lpReserved);
+    FIXME("(0x%s, 0x%08x, 0x%08x, %p, %p) stub\n",
+          wine_dbgstr_longlong(gid), dwFlags, dwAttributes, lpGroupInfo, lpReserved);
     return TRUE;
 }
 
     return TRUE;
 }
 
index 396ca32..d94c5da 100644 (file)
@@ -201,7 +201,7 @@ reactos/dll/win32/windowscodecsext    # Synced to WineStaging-2.9
 reactos/dll/win32/winemp3.acm         # Synced to WineStaging-2.16
 reactos/dll/win32/wing32              # Synced to WineStaging-2.9
 reactos/dll/win32/winhttp             # Synced to WineStaging-2.16
 reactos/dll/win32/winemp3.acm         # Synced to WineStaging-2.16
 reactos/dll/win32/wing32              # Synced to WineStaging-2.9
 reactos/dll/win32/winhttp             # Synced to WineStaging-2.16
-reactos/dll/win32/wininet             # Synced to WineStaging-2.9
+reactos/dll/win32/wininet             # Synced to WineStaging-2.16
 reactos/dll/win32/winmm               # Forked at Wine-20050628
 reactos/dll/win32/winmm/midimap       # Forked at Wine-20050628
 reactos/dll/win32/winmm/wavemap       # Forked at Wine-20050628
 reactos/dll/win32/winmm               # Forked at Wine-20050628
 reactos/dll/win32/winmm/midimap       # Forked at Wine-20050628
 reactos/dll/win32/winmm/wavemap       # Forked at Wine-20050628