[WININET] Sync with Wine Staging 1.9.16. CORE-11866
authorAmine Khaldi <amine.khaldi@reactos.org>
Fri, 19 Aug 2016 09:45:28 +0000 (09:45 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Fri, 19 Aug 2016 09:45:28 +0000 (09:45 +0000)
svn path=/trunk/; revision=72356

reactos/dll/win32/wininet/cookie.c
reactos/dll/win32/wininet/ftp.c
reactos/dll/win32/wininet/http.c
reactos/dll/win32/wininet/internet.c
reactos/dll/win32/wininet/internet.h
reactos/dll/win32/wininet/utility.c
reactos/media/doc/README.WINE

index cf4ae88..2603caa 100644 (file)
@@ -668,6 +668,33 @@ DWORD get_cookie_header(const WCHAR *host, const WCHAR *path, WCHAR **ret)
     return res;
 }
 
+static void free_cookie_domain_list(struct list *list)
+{
+    cookie_container_t *container;
+    cookie_domain_t *domain;
+
+    while(!list_empty(list)) {
+        domain = LIST_ENTRY(list_head(list), cookie_domain_t, entry);
+
+        free_cookie_domain_list(&domain->subdomain_list);
+
+        while(!list_empty(&domain->path_list)) {
+            container = LIST_ENTRY(list_head(&domain->path_list), cookie_container_t, entry);
+
+            while(!list_empty(&container->cookie_list))
+                delete_cookie(LIST_ENTRY(list_head(&container->cookie_list), cookie_t, entry));
+
+            heap_free(container->cookie_url);
+            list_remove(&container->entry);
+            heap_free(container);
+        }
+
+        heap_free(domain->domain);
+        list_remove(&domain->entry);
+        heap_free(domain);
+    }
+}
+
 /***********************************************************************
  *           InternetGetCookieExW (WININET.@)
  *
@@ -765,7 +792,7 @@ BOOL WINAPI InternetGetCookieExA(LPCSTR lpszUrl, LPCSTR lpszCookieName,
         LPSTR lpCookieData, LPDWORD lpdwSize, DWORD flags, void *reserved)
 {
     WCHAR *url, *name;
-    DWORD len, size;
+    DWORD len, size = 0;
     BOOL r;
 
     TRACE("(%s %s %p %p(%u) %x %p)\n", debugstr_a(lpszUrl), debugstr_a(lpszCookieName),
@@ -798,12 +825,12 @@ BOOL WINAPI InternetGetCookieExA(LPCSTR lpszUrl, LPCSTR lpszCookieName,
                         r = FALSE;
                     }
                 }
-                *lpdwSize = size;
             }
 
             heap_free( szCookieData );
         }
     }
+    *lpdwSize = size;
     heap_free( name );
     heap_free( url );
     return r;
@@ -895,6 +922,7 @@ DWORD set_cookie(substr_t domain, substr_t path, substr_t name, substr_t data, D
         static const WCHAR szSecure[] = {'s','e','c','u','r','e'};
         static const WCHAR szHttpOnly[] = {'h','t','t','p','o','n','l','y'};
         static const WCHAR szVersion[] = {'v','e','r','s','i','o','n','='};
+        static const WCHAR max_ageW[] = {'m','a','x','-','a','g','e','='};
 
         /* Skip ';' */
         if(data.len)
@@ -960,9 +988,11 @@ DWORD set_cookie(substr_t domain, substr_t path, substr_t name, substr_t data, D
             substr_skip(&data, len);
 
             FIXME("version not handled (%s)\n",debugstr_wn(data.str, data.len));
+        }else if(data.len >= (len = sizeof(max_ageW)/sizeof(WCHAR)) && !strncmpiW(data.str, max_ageW, len)) {
+            /* Native doesn't support Max-Age attribute. */
+            WARN("Max-Age ignored\n");
         }else if(data.len) {
             FIXME("Unknown additional option %s\n", debugstr_wn(data.str, data.len));
-            break;
         }
 
         substr_skip(&data, end_ptr - data.str);
@@ -987,6 +1017,7 @@ DWORD set_cookie(substr_t domain, substr_t path, substr_t name, substr_t data, D
         if ((thisCookie->flags & INTERNET_COOKIE_HTTPONLY) && !(flags & INTERNET_COOKIE_HTTPONLY)) {
             WARN("An attempt to override httponly cookie\n");
             SetLastError(ERROR_INVALID_OPERATION);
+            LeaveCriticalSection(&cookie_cs);
             return COOKIE_STATE_REJECT;
         }
 
@@ -1219,5 +1250,9 @@ BOOL WINAPI InternetSetPerSiteCookieDecisionW( LPCWSTR pchHostName, DWORD dwDeci
 
 void free_cookie(void)
 {
-    DeleteCriticalSection(&cookie_cs);
+    EnterCriticalSection(&cookie_cs);
+
+    free_cookie_domain_list(&domain_list);
+
+    LeaveCriticalSection(&cookie_cs);
 }
index d62f87e..a807535 100644 (file)
@@ -336,7 +336,7 @@ static BOOL FTP_FtpPutFileW(ftp_session_t *lpwfs, LPCWSTR lpszLocalFile,
 
     hIC = lpwfs->lpAppInfo;
 
-    SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_SENDING_REQUEST, NULL, 0);
+    INTERNET_SendCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_SENDING_REQUEST, NULL, 0);
 
     if (FTP_SendStore(lpwfs, lpszNewRemoteFile, dwFlags))
     {
@@ -370,7 +370,7 @@ static BOOL FTP_FtpPutFileW(ftp_session_t *lpwfs, LPCWSTR lpszLocalFile,
 
         iar.dwResult = (DWORD)bSuccess;
         iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
-        SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
+        INTERNET_SendCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
             &iar, sizeof(INTERNET_ASYNC_RESULT));
     }
 
@@ -520,7 +520,7 @@ lend:
 
         iar.dwResult = bSuccess;
         iar.dwError = bSuccess ? ERROR_SUCCESS : ERROR_INTERNET_EXTENDED_ERROR;
-        SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
+        INTERNET_SendCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
             &iar, sizeof(INTERNET_ASYNC_RESULT));
     }
     return bSuccess;
@@ -663,7 +663,7 @@ lend:
 
         iar.dwResult = (DWORD)bSuccess;
         iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
-        SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
+        INTERNET_SendCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
             &iar, sizeof(INTERNET_ASYNC_RESULT));
     }
 
@@ -863,13 +863,13 @@ lend:
        {
             iar.dwResult = (DWORD_PTR)hFindNext;
             iar.dwError = ERROR_SUCCESS;
-            SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_HANDLE_CREATED,
+            INTERNET_SendCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_HANDLE_CREATED,
                 &iar, sizeof(INTERNET_ASYNC_RESULT));
        }
 
         iar.dwResult = (DWORD_PTR)hFindNext;
         iar.dwError = hFindNext ? ERROR_SUCCESS : INTERNET_GetLastError();
-        SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
+        INTERNET_SendCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
             &iar, sizeof(INTERNET_ASYNC_RESULT));
     }
 
@@ -1073,7 +1073,7 @@ lend:
 
         iar.dwResult = bSuccess;
         iar.dwError = bSuccess ? ERROR_SUCCESS : ERROR_INTERNET_EXTENDED_ERROR;
-        SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
+        INTERNET_SendCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
             &iar, sizeof(INTERNET_ASYNC_RESULT));
     }
 
@@ -1389,7 +1389,7 @@ static HINTERNET FTP_FtpOpenFileW(ftp_session_t *lpwfs,
        {
             iar.dwResult = (DWORD_PTR)lpwh->hdr.hInternet;
             iar.dwError = ERROR_SUCCESS;
-            SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_HANDLE_CREATED,
+            INTERNET_SendCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_HANDLE_CREATED,
                 &iar, sizeof(INTERNET_ASYNC_RESULT));
        }
 
@@ -1398,7 +1398,7 @@ static HINTERNET FTP_FtpOpenFileW(ftp_session_t *lpwfs,
         }else {
             iar.dwResult = 0;
             iar.dwError = INTERNET_GetLastError();
-            SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
+            INTERNET_SendCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
                     &iar, sizeof(INTERNET_ASYNC_RESULT));
         }
     }
@@ -1723,7 +1723,7 @@ static BOOL FTP_FtpGetFileW(ftp_session_t *lpwfs, LPCWSTR lpszRemoteFile, LPCWST
 
         iar.dwResult = (DWORD)bSuccess;
         iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
-        SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
+        INTERNET_SendCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
             &iar, sizeof(INTERNET_ASYNC_RESULT));
     }
 
@@ -1883,7 +1883,7 @@ lend:
 
         iar.dwResult = (DWORD)bSuccess;
         iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
-        SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
+        INTERNET_SendCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
             &iar, sizeof(INTERNET_ASYNC_RESULT));
     }
 
@@ -2026,7 +2026,7 @@ lend:
 
         iar.dwResult = (DWORD)bSuccess;
         iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
-        SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
+        INTERNET_SendCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
             &iar, sizeof(INTERNET_ASYNC_RESULT));
     }
 
@@ -2185,7 +2185,7 @@ lend:
 
         iar.dwResult = (DWORD)bSuccess;
         iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
-        SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
+        INTERNET_SendCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
             &iar, sizeof(INTERNET_ASYNC_RESULT));
     }
 
@@ -2337,7 +2337,7 @@ static void FTPSESSION_CloseConnection(object_header_t *hdr)
 
     TRACE("\n");
 
-    SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext,
+    INTERNET_SendCallback(&lpwfs->hdr, lpwfs->hdr.dwContext,
                       INTERNET_STATUS_CLOSING_CONNECTION, 0, 0);
 
     if (lpwfs->download_in_progress != NULL)
@@ -2352,7 +2352,7 @@ static void FTPSESSION_CloseConnection(object_header_t *hdr)
     if (lpwfs->pasvSocket != -1)
         closesocket(lpwfs->pasvSocket);
 
-    SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext,
+    INTERNET_SendCallback(&lpwfs->hdr, lpwfs->hdr.dwContext,
                       INTERNET_STATUS_CONNECTION_CLOSED, 0, 0);
 }
 
@@ -2503,12 +2503,12 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName,
         iar.dwResult = (DWORD_PTR)lpwfs->hdr.hInternet;
         iar.dwError = ERROR_SUCCESS;
 
-        SendAsyncCallback(&hIC->hdr, dwContext,
+        INTERNET_SendCallback(&hIC->hdr, dwContext,
                       INTERNET_STATUS_HANDLE_CREATED, &iar,
                       sizeof(INTERNET_ASYNC_RESULT));
     }
         
-    SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_RESOLVING_NAME,
+    INTERNET_SendCallback(&hIC->hdr, dwContext, INTERNET_STATUS_RESOLVING_NAME,
         (LPWSTR) lpszServerName, (strlenW(lpszServerName)+1) * sizeof(WCHAR));
 
     sock_namelen = sizeof(socketAddr);
@@ -2525,7 +2525,7 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName,
         goto lerror;
     }
 
-    SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_NAME_RESOLVED,
+    INTERNET_SendCallback(&hIC->hdr, dwContext, INTERNET_STATUS_NAME_RESOLVED,
                       szaddr, strlen(szaddr)+1);
 
     init_winsock();
@@ -2536,7 +2536,7 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName,
         goto lerror;
     }
 
-    SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_CONNECTING_TO_SERVER,
+    INTERNET_SendCallback(&hIC->hdr, dwContext, INTERNET_STATUS_CONNECTING_TO_SERVER,
                       szaddr, strlen(szaddr)+1);
 
     if (connect(nsocket, (struct sockaddr *)&socketAddr, sock_namelen) < 0)
@@ -2549,7 +2549,7 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName,
     {
         TRACE("Connected to server\n");
        lpwfs->sndSocket = nsocket;
-        SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_CONNECTED_TO_SERVER,
+        INTERNET_SendCallback(&hIC->hdr, dwContext, INTERNET_STATUS_CONNECTED_TO_SERVER,
                           szaddr, strlen(szaddr)+1);
 
        sock_namelen = sizeof(lpwfs->socketAddress);
@@ -2763,7 +2763,7 @@ INT FTP_ReceiveResponse(ftp_session_t *lpwfs, DWORD_PTR dwContext)
 
     TRACE("socket(%d)\n", lpwfs->sndSocket);
 
-    SendAsyncCallback(&lpwfs->hdr, dwContext, INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
+    INTERNET_SendCallback(&lpwfs->hdr, dwContext, INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
 
     while(1)
     {
@@ -2796,7 +2796,7 @@ INT FTP_ReceiveResponse(ftp_session_t *lpwfs, DWORD_PTR dwContext)
     {
         rc = atoi(lpszResponse);
 
-        SendAsyncCallback(&lpwfs->hdr, dwContext, INTERNET_STATUS_RESPONSE_RECEIVED,
+        INTERNET_SendCallback(&lpwfs->hdr, dwContext, INTERNET_STATUS_RESPONSE_RECEIVED,
                    &nRecv, sizeof(DWORD));
     }
 
index eb1edf0..c858250 100644 (file)
@@ -388,7 +388,15 @@ typedef struct {
     DWORD buf_size;
     DWORD buf_pos;
     DWORD chunk_size;
-    BOOL end_of_data;
+
+    enum {
+        CHUNKED_STREAM_STATE_READING_CHUNK_SIZE,
+        CHUNKED_STREAM_STATE_DISCARD_EOL_AFTER_SIZE,
+        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
+    } state;
 } chunked_stream_t;
 
 static inline void destroy_data_stream(data_stream_t *stream)
@@ -1766,7 +1774,7 @@ static BOOL HTTP_ShouldBypassProxy(appinfo_t *lpwai, LPCWSTR server)
         if (!ptr)
             ptr = strchrW( tmp, ' ' );
         if (!ptr)
-            ptr = tmp + strlenW(ptr);
+            ptr = tmp + strlenW(tmp);
         ret = HTTP_DomainMatches( server, substr(tmp, ptr-tmp) );
         if (ret || !*ptr)
             break;
@@ -1793,8 +1801,10 @@ static BOOL HTTP_DealWithProxy(appinfo_t *hIC, http_session_t *session, http_req
     if(CSTR_EQUAL != CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE,
                                     proxy, strlenW(szHttp), szHttp, strlenW(szHttp))) {
         WCHAR *proxy_url = heap_alloc(strlenW(proxy)*sizeof(WCHAR) + sizeof(szHttp));
-        if(!proxy_url)
+        if(!proxy_url) {
+            heap_free(proxy);
             return FALSE;
+        }
         strcpyW(proxy_url, szHttp);
         strcatW(proxy_url, proxy);
         heap_free(proxy);
@@ -2691,191 +2701,179 @@ static const data_stream_vtbl_t netconn_stream_vtbl = {
     netconn_destroy
 };
 
-/* read some more data into the read buffer (the read section must be held) */
-static DWORD read_more_chunked_data(chunked_stream_t *stream, http_request_t *req, int maxlen)
+static char next_chunked_data_char(chunked_stream_t *stream)
 {
-    DWORD res;
-    int len;
-
-    assert(!stream->end_of_data);
-
-    if (stream->buf_pos)
-    {
-        /* move existing data to the start of the buffer */
-        if(stream->buf_size)
-            memmove(stream->buf, stream->buf + stream->buf_pos, stream->buf_size);
-        stream->buf_pos = 0;
-    }
-
-    if (maxlen == -1) maxlen = sizeof(stream->buf);
-
-    res = NETCON_recv( req->netconn, stream->buf + stream->buf_size,
-                       maxlen - stream->buf_size, TRUE, &len );
-    if(res == ERROR_SUCCESS)
-        stream->buf_size += len;
+    assert(stream->buf_size);
 
-    return res;
+    stream->buf_size--;
+    return stream->buf[stream->buf_pos++];
 }
 
-/* remove some amount of data from the read buffer (the read section must be held) */
-static void remove_chunked_data(chunked_stream_t *stream, int count)
+static BOOL chunked_end_of_data(data_stream_t *stream, http_request_t *req)
 {
-    if (!(stream->buf_size -= count)) stream->buf_pos = 0;
-    else stream->buf_pos += count;
+    chunked_stream_t *chunked_stream = (chunked_stream_t*)stream;
+    return chunked_stream->state == CHUNKED_STREAM_STATE_END_OF_STREAM;
 }
 
-/* discard data contents until we reach end of line (the read section must be held) */
-static DWORD discard_chunked_eol(chunked_stream_t *stream, http_request_t *req)
+static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf, DWORD size,
+        DWORD *read, blocking_mode_t blocking_mode)
 {
-    DWORD res;
+    chunked_stream_t *chunked_stream = (chunked_stream_t*)stream;
+    DWORD ret_read = 0, res = ERROR_SUCCESS;
+    BOOL continue_read = TRUE;
+    int read_bytes;
+    char ch;
 
-    do
-    {
-        BYTE *eol = memchr(stream->buf + stream->buf_pos, '\n', stream->buf_size);
-        if (eol)
-        {
-            remove_chunked_data(stream, (eol + 1) - (stream->buf + stream->buf_pos));
-            break;
+    do {
+        TRACE("state %d\n", chunked_stream->state);
+
+        /* Ensure that we have data in the buffer for states that need it. */
+        if(!chunked_stream->buf_size) {
+            switch(chunked_stream->state) {
+            case CHUNKED_STREAM_STATE_READING_CHUNK_SIZE:
+            case CHUNKED_STREAM_STATE_DISCARD_EOL_AFTER_SIZE:
+            case CHUNKED_STREAM_STATE_DISCARD_EOL_AFTER_DATA:
+            case CHUNKED_STREAM_STATE_DISCARD_EOL_AT_END:
+                chunked_stream->buf_pos = 0;
+                res = NETCON_recv(req->netconn, chunked_stream->buf, sizeof(chunked_stream->buf), blocking_mode != BLOCKING_DISALLOW, &read_bytes);
+                if(res == ERROR_SUCCESS && read_bytes) {
+                    chunked_stream->buf_size += read_bytes;
+                }else if(res == WSAEWOULDBLOCK) {
+                    continue_read = FALSE;
+                    continue;
+                }else {
+                    chunked_stream->state = CHUNKED_STREAM_STATE_END_OF_STREAM;
+                }
+                break;
+            default:
+                break;
+            }
         }
-        stream->buf_pos = stream->buf_size = 0;  /* discard everything */
-        if ((res = read_more_chunked_data(stream, req, -1)) != ERROR_SUCCESS) return res;
-    } while (stream->buf_size);
-    return ERROR_SUCCESS;
-}
 
-/* read the size of the next chunk (the read section must be held) */
-static DWORD start_next_chunk(chunked_stream_t *stream, http_request_t *req)
-{
-    DWORD chunk_size = 0, res;
+        switch(chunked_stream->state) {
+        case CHUNKED_STREAM_STATE_READING_CHUNK_SIZE:
+            ch = next_chunked_data_char(chunked_stream);
+
+            if(ch >= '0' && ch <= '9') {
+                chunked_stream->chunk_size = chunked_stream->chunk_size * 16 + ch - '0';
+            }else if(ch >= 'a' && ch <= 'f') {
+                chunked_stream->chunk_size = chunked_stream->chunk_size * 16 + ch - 'a' + 10;
+            }else if (ch >= 'A' && ch <= 'F') {
+                chunked_stream->chunk_size = chunked_stream->chunk_size * 16 + ch - 'A' + 10;
+            }else if (ch == ';' || ch == '\r' || ch == '\n') {
+                TRACE("reading %u byte chunk\n", chunked_stream->chunk_size);
+                chunked_stream->buf_size++;
+                chunked_stream->buf_pos--;
+                if(req->contentLength == ~0u) req->contentLength = chunked_stream->chunk_size;
+                else req->contentLength += chunked_stream->chunk_size;
+                chunked_stream->state = CHUNKED_STREAM_STATE_DISCARD_EOL_AFTER_SIZE;
+            }
+            break;
 
-    assert(!stream->chunk_size || stream->chunk_size == ~0u);
+        case CHUNKED_STREAM_STATE_DISCARD_EOL_AFTER_SIZE:
+            ch = next_chunked_data_char(chunked_stream);
+            if(ch == '\n')
+                chunked_stream->state = chunked_stream->chunk_size
+                    ? CHUNKED_STREAM_STATE_READING_CHUNK
+                    : CHUNKED_STREAM_STATE_DISCARD_EOL_AT_END;
+            else if(ch != '\r')
+                WARN("unexpected char '%c'\n", ch);
+            break;
 
-    if (stream->end_of_data) return ERROR_SUCCESS;
+        case CHUNKED_STREAM_STATE_READING_CHUNK:
+            assert(chunked_stream->chunk_size);
+            if(!size) {
+                continue_read = FALSE;
+                break;
+            }
+            read_bytes = min(size, chunked_stream->chunk_size);
 
-    /* read terminator for the previous chunk */
-    if(!stream->chunk_size && (res = discard_chunked_eol(stream, req)) != ERROR_SUCCESS)
-        return res;
+            if(chunked_stream->buf_size) {
+                if(read_bytes > chunked_stream->buf_size)
+                    read_bytes = chunked_stream->buf_size;
 
-    for (;;)
-    {
-        while (stream->buf_size)
-        {
-            char ch = stream->buf[stream->buf_pos];
-            if (ch >= '0' && ch <= '9') chunk_size = chunk_size * 16 + ch - '0';
-            else if (ch >= 'a' && ch <= 'f') chunk_size = chunk_size * 16 + ch - 'a' + 10;
-            else if (ch >= 'A' && ch <= 'F') chunk_size = chunk_size * 16 + ch - 'A' + 10;
-            else if (ch == ';' || ch == '\r' || ch == '\n')
-            {
-                TRACE( "reading %u byte chunk\n", chunk_size );
-                stream->chunk_size = chunk_size;
-                if (req->contentLength == ~0u) req->contentLength = chunk_size;
-                else req->contentLength += chunk_size;
+                memcpy(buf+ret_read, chunked_stream->buf+chunked_stream->buf_pos, read_bytes);
+                chunked_stream->buf_pos += read_bytes;
+                chunked_stream->buf_size -= read_bytes;
+            }else {
+                res = NETCON_recv(req->netconn, (char*)buf+ret_read, read_bytes,
+                                  blocking_mode != BLOCKING_DISALLOW, (int*)&read_bytes);
+                if(res != ERROR_SUCCESS) {
+                    continue_read = FALSE;
+                    break;
+                }
 
-                /* eat the rest of this line */
-                if ((res = discard_chunked_eol(stream, req)) != ERROR_SUCCESS)
-                    return res;
+                if(!read_bytes) {
+                    chunked_stream->state = CHUNKED_STREAM_STATE_END_OF_STREAM;
+                    continue;
+                }
+            }
 
-                /* if there's chunk data, return now */
-                if (chunk_size) return ERROR_SUCCESS;
+            chunked_stream->chunk_size -= read_bytes;
+            size -= read_bytes;
+            ret_read += read_bytes;
+            if(!chunked_stream->chunk_size)
+                chunked_stream->state = CHUNKED_STREAM_STATE_DISCARD_EOL_AFTER_DATA;
+            if(blocking_mode == BLOCKING_ALLOW)
+                blocking_mode = BLOCKING_DISALLOW;
+            break;
 
-                /* otherwise, eat the terminator for this chunk */
-                if ((res = discard_chunked_eol(stream, req)) != ERROR_SUCCESS)
-                    return res;
+        case CHUNKED_STREAM_STATE_DISCARD_EOL_AFTER_DATA:
+            ch = next_chunked_data_char(chunked_stream);
+            if(ch == '\n')
+                chunked_stream->state = CHUNKED_STREAM_STATE_READING_CHUNK_SIZE;
+            else if(ch != '\r')
+                WARN("unexpected char '%c'\n", ch);
+            break;
 
-                stream->end_of_data = TRUE;
-                return ERROR_SUCCESS;
-            }
-            remove_chunked_data(stream, 1);
-        }
-        if ((res = read_more_chunked_data(stream, req, -1)) != ERROR_SUCCESS) return res;
-        if (!stream->buf_size)
-        {
-            stream->chunk_size = 0;
-            return ERROR_SUCCESS;
+        case CHUNKED_STREAM_STATE_DISCARD_EOL_AT_END:
+            ch = next_chunked_data_char(chunked_stream);
+            if(ch == '\n')
+                chunked_stream->state = CHUNKED_STREAM_STATE_END_OF_STREAM;
+            else if(ch != '\r')
+                WARN("unexpected char '%c'\n", ch);
+            break;
+
+        case CHUNKED_STREAM_STATE_END_OF_STREAM:
+            continue_read = FALSE;
+            break;
         }
-    }
-}
+    } while(continue_read);
 
-static DWORD chunked_get_avail_data(data_stream_t *stream, http_request_t *req)
-{
-    /* Allow reading only from read buffer */
-    return 0;
-}
+    if(ret_read)
+        res = ERROR_SUCCESS;
+    if(res != ERROR_SUCCESS && res != WSAEWOULDBLOCK)
+        return res;
 
-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->end_of_data;
+    TRACE("read %d bytes\n", ret_read);
+    *read = ret_read;
+    return ERROR_SUCCESS;
 }
 
-static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf, DWORD size,
-        DWORD *read, blocking_mode_t blocking_mode)
+static DWORD chunked_get_avail_data(data_stream_t *stream, http_request_t *req)
 {
     chunked_stream_t *chunked_stream = (chunked_stream_t*)stream;
-    DWORD read_bytes = 0, ret_read = 0, res = ERROR_SUCCESS;
-
-    if(!chunked_stream->chunk_size || chunked_stream->chunk_size == ~0u) {
-        res = start_next_chunk(chunked_stream, req);
-        if(res != ERROR_SUCCESS)
-            return res;
-    }
-
-    while(size && chunked_stream->chunk_size && !chunked_stream->end_of_data) {
-        if(chunked_stream->buf_size) {
-            read_bytes = min(size, min(chunked_stream->buf_size, chunked_stream->chunk_size));
-
-            /* this could block */
-            if(blocking_mode == BLOCKING_DISALLOW && read_bytes == chunked_stream->chunk_size)
-                break;
-
-            memcpy(buf+ret_read, chunked_stream->buf+chunked_stream->buf_pos, read_bytes);
-            remove_chunked_data(chunked_stream, read_bytes);
-        }else {
-            read_bytes = min(size, chunked_stream->chunk_size);
-
-            if(blocking_mode == BLOCKING_DISALLOW) {
-                DWORD avail;
-
-                if(!is_valid_netconn(req->netconn) || !NETCON_query_data_available(req->netconn, &avail) || !avail)
-                    break;
-                if(read_bytes > avail)
-                    read_bytes = avail;
-
-                /* this could block */
-                if(read_bytes == chunked_stream->chunk_size)
-                    break;
-            }
-
-            res = NETCON_recv(req->netconn, (char *)buf+ret_read, read_bytes, TRUE, (int*)&read_bytes);
-            if(res != ERROR_SUCCESS)
-                break;
-        }
+    DWORD avail = 0;
 
-        chunked_stream->chunk_size -= read_bytes;
-        size -= read_bytes;
-        ret_read += read_bytes;
-        if(size && !chunked_stream->chunk_size) {
-            assert(blocking_mode != BLOCKING_DISALLOW);
-            res = start_next_chunk(chunked_stream, req);
-            if(res != ERROR_SUCCESS)
-                break;
-        }
+    if(chunked_stream->state != CHUNKED_STREAM_STATE_READING_CHUNK) {
+        DWORD res, read;
 
-        if(blocking_mode == BLOCKING_ALLOW)
-            blocking_mode = BLOCKING_DISALLOW;
+        /* try to process to the next chunk */
+        res = chunked_read(stream, req, NULL, 0, &read, BLOCKING_DISALLOW);
+        if(res != ERROR_SUCCESS || chunked_stream->state != CHUNKED_STREAM_STATE_READING_CHUNK)
+            return 0;
     }
 
-    TRACE("read %u bytes\n", ret_read);
-    *read = ret_read;
-    return res;
+    if(is_valid_netconn(req->netconn) && chunked_stream->buf_size < chunked_stream->chunk_size)
+        NETCON_query_data_available(req->netconn, &avail);
+
+    return min(avail + chunked_stream->buf_size, chunked_stream->chunk_size);
 }
 
 static BOOL chunked_drain_content(data_stream_t *stream, http_request_t *req)
 {
     chunked_stream_t *chunked_stream = (chunked_stream_t*)stream;
-
-    remove_chunked_data(chunked_stream, chunked_stream->buf_size);
-    return chunked_stream->end_of_data;
+    return chunked_stream->state == CHUNKED_STREAM_STATE_END_OF_STREAM;
 }
 
 static void chunked_destroy(data_stream_t *stream)
@@ -2924,8 +2922,8 @@ static DWORD set_content_length(http_request_t *request)
 
         chunked_stream->data_stream.vtbl = &chunked_stream_vtbl;
         chunked_stream->buf_size = chunked_stream->buf_pos = 0;
-        chunked_stream->chunk_size = ~0u;
-        chunked_stream->end_of_data = FALSE;
+        chunked_stream->chunk_size = 0;
+        chunked_stream->state = CHUNKED_STREAM_STATE_READING_CHUNK_SIZE;
 
         if(request->read_size) {
             memcpy(chunked_stream->buf, request->read_buf+request->read_pos, request->read_size);
index dd3a83d..5717254 100644 (file)
@@ -113,7 +113,7 @@ void *alloc_object(object_header_t *parent, const object_vtbl_t *vtbl, size_t si
         handle_table[handle] = ret;
         ret->valid_handle = TRUE;
 
-        while(handle_table[next_handle] && next_handle < handle_table_size)
+        while(next_handle < handle_table_size && handle_table[next_handle])
             next_handle++;
     }
 
@@ -1896,11 +1896,7 @@ BOOL WINAPI InternetCrackUrlW(const WCHAR *lpszUrl, DWORD dwUrlLength, DWORD dwF
     }
     else
     {
-        if (lpUC->lpszUrlPath && (lpUC->dwUrlPathLength > 0))
-            lpUC->lpszUrlPath[0] = 0;
-        else if (lpUC->dwUrlPathLength > 0)
-            lpUC->lpszUrlPath = (WCHAR*)lpszcp;
-        lpUC->dwUrlPathLength = 0;
+        set_url_component(&lpUC->lpszUrlPath, &lpUC->dwUrlPathLength, lpszcp, 0);
     }
 
     TRACE("%s: scheme(%s) host(%s) path(%s) extra(%s)\n", debugstr_wn(lpszUrl,dwUrlLength),
@@ -2787,7 +2783,8 @@ BOOL WINAPI InternetSetOptionW(HINTERNET hInternet, DWORD dwOption,
         FIXME("Option INTERNET_OPTION_RESET_URLCACHE_SESSION: STUB\n");
         break;
     case INTERNET_OPTION_END_BROWSER_SESSION:
-        FIXME("Option INTERNET_OPTION_END_BROWSER_SESSION: STUB\n");
+        FIXME("Option INTERNET_OPTION_END_BROWSER_SESSION: semi-stub\n");
+        free_cookie();
         break;
     case INTERNET_OPTION_CONNECTED_STATE:
         FIXME("Option INTERNET_OPTION_CONNECTED_STATE: STUB\n");
index 9567f58..a6ef1c7 100644 (file)
@@ -500,10 +500,6 @@ DWORD INTERNET_GetLastError(void) DECLSPEC_HIDDEN;
 DWORD INTERNET_AsyncCall(task_header_t*) DECLSPEC_HIDDEN;
 LPSTR INTERNET_GetResponseBuffer(void) DECLSPEC_HIDDEN;
 
-VOID SendAsyncCallback(object_header_t *hdr, DWORD_PTR dwContext,
-                       DWORD dwInternetStatus, LPVOID lpvStatusInfo,
-                       DWORD dwStatusInfoLength) DECLSPEC_HIDDEN;
-
 VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext,
                            DWORD dwInternetStatus, LPVOID lpvStatusInfo,
                            DWORD dwStatusInfoLength) DECLSPEC_HIDDEN;
index ad441d7..ca7a768 100644 (file)
@@ -263,60 +263,3 @@ void INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR context, DWORD status
     if(new_info != info)
         heap_free(new_info);
 }
-
-typedef struct {
-    task_header_t hdr;
-    DWORD_PTR context;
-    DWORD     status;
-    LPVOID    status_info;
-    DWORD     status_info_len;
-} send_callback_task_t;
-
-static void SendAsyncCallbackProc(task_header_t *hdr)
-{
-    send_callback_task_t *task = (send_callback_task_t*)hdr;
-
-    TRACE("%p\n", task->hdr.hdr);
-
-    INTERNET_SendCallback(task->hdr.hdr, task->context, task->status, task->status_info, task->status_info_len);
-
-    /* And frees the copy of the status info */
-    heap_free(task->status_info);
-}
-
-void SendAsyncCallback(object_header_t *hdr, DWORD_PTR dwContext,
-                       DWORD dwInternetStatus, LPVOID lpvStatusInfo,
-                       DWORD dwStatusInfoLength)
-{
-    TRACE("(%p, %08lx, %d (%s), %p, %d): %sasync call with callback %p\n",
-         hdr, dwContext, dwInternetStatus, get_callback_name(dwInternetStatus),
-         lpvStatusInfo, dwStatusInfoLength,
-         hdr->dwFlags & INTERNET_FLAG_ASYNC ? "" : "non ",
-         hdr->lpfnStatusCB);
-    
-    if (!(hdr->lpfnStatusCB))
-       return;
-    
-    if (hdr->dwFlags & INTERNET_FLAG_ASYNC)
-    {
-        send_callback_task_t *task;
-        void *lpvStatusInfo_copy = lpvStatusInfo;
-
-        if (lpvStatusInfo)
-        {
-            lpvStatusInfo_copy = heap_alloc(dwStatusInfoLength);
-            memcpy(lpvStatusInfo_copy, lpvStatusInfo, dwStatusInfoLength);
-        }
-
-        task = alloc_async_task(hdr, SendAsyncCallbackProc, sizeof(*task));
-        task->context = dwContext;
-        task->status = dwInternetStatus;
-        task->status_info = lpvStatusInfo_copy;
-        task->status_info_len = dwStatusInfoLength;
-       
-        INTERNET_AsyncCall(&task->hdr);
-    }
-    else
-       INTERNET_SendCallback(hdr, dwContext, dwInternetStatus,
-                             lpvStatusInfo, dwStatusInfoLength);
-}
index a1f08e9..b0ed3cf 100644 (file)
@@ -205,7 +205,7 @@ reactos/dll/win32/windowscodecsext    # Synced to WineStaging-1.9.11
 reactos/dll/win32/winemp3.acm         # Synced to WineStaging-1.9.11
 reactos/dll/win32/wing32              # Synced to WineStaging-1.9.11
 reactos/dll/win32/winhttp             # Synced to WineStaging-1.9.16
-reactos/dll/win32/wininet             # Synced to WineStaging-1.9.11
+reactos/dll/win32/wininet             # Synced to WineStaging-1.9.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