[WININET] Sync with Wine Staging 1.7.37. CORE-9246
authorAmine Khaldi <amine.khaldi@reactos.org>
Wed, 22 Apr 2015 08:30:31 +0000 (08:30 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Wed, 22 Apr 2015 08:30:31 +0000 (08:30 +0000)
svn path=/trunk/; revision=67343

reactos/dll/win32/wininet/CMakeLists.txt
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/netconnection.c
reactos/dll/win32/wininet/urlcache.c
reactos/dll/win32/wininet/utility.c
reactos/media/doc/README.WINE

index 7f968a8..8c7e0cb 100644 (file)
@@ -1,4 +1,7 @@
 
+remove_definitions(-DWINVER=0x502)
+add_definitions(-DWINVER=0x600)
+
 add_definitions(
     -D__WINESRC__
     -D_WINE
@@ -30,6 +33,6 @@ add_library(wininet SHARED
 set_module_type(wininet win32dll)
 target_link_libraries(wininet wine ${PSEH_LIB} zlib)
 add_delay_importlibs(wininet secur32 crypt32 cryptui)
-add_importlibs(wininet mpr shlwapi shell32 user32 advapi32 ws2_32 msvcrt kernel32 ntdll)
+add_importlibs(wininet mpr shlwapi shell32 user32 advapi32 ws2_32 kernel32_vista msvcrt kernel32 ntdll)
 add_pch(wininet internet.h SOURCE)
 add_cd_file(TARGET wininet DESTINATION reactos/system32 FOR all)
index ddbc92a..2b24108 100644 (file)
@@ -342,7 +342,6 @@ static BOOL load_persistent_cookie(LPCWSTR domain, LPCWSTR path)
         *pend = 0;
         data = heap_strdupAtoW(pbeg);
 
-        pbeg = pend+1;
         pbeg = strchr(pend+1, '\n');
         if(!pbeg)
             break;
index d3b97a9..23dfecb 100644 (file)
@@ -29,6 +29,8 @@
 
 #include "internet.h"
 
+#define RESPONSE_TIMEOUT        30
+
 typedef struct _ftp_session_t ftp_session_t;
 
 typedef struct
@@ -789,6 +791,7 @@ static HINTERNET FTP_FtpFindFirstFileW(ftp_session_t *lpwfs,
     INT nResCode;
     appinfo_t *hIC = NULL;
     HINTERNET hFindNext = NULL;
+    LPWSTR lpszSearchPath = NULL;
 
     TRACE("\n");
 
@@ -804,7 +807,20 @@ static HINTERNET FTP_FtpFindFirstFileW(ftp_session_t *lpwfs,
     if (!FTP_SendPortOrPasv(lpwfs))
         goto lend;
 
-    if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_LIST, NULL,
+    /* split search path into file and path */
+    if (lpszSearchFile)
+    {
+        LPCWSTR name = lpszSearchFile, p;
+        if ((p = strrchrW( name, '\\' ))) name = p + 1;
+        if ((p = strrchrW( name, '/' ))) name = p + 1;
+        if (name != lpszSearchFile)
+        {
+            lpszSearchPath = heap_strndupW(lpszSearchFile, name - lpszSearchFile);
+            lpszSearchFile = name;
+        }
+    }
+
+    if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_LIST, lpszSearchPath,
         lpwfs->hdr.lpfnStatusCB, &lpwfs->hdr, lpwfs->hdr.dwContext))
         goto lend;
 
@@ -830,6 +846,8 @@ static HINTERNET FTP_FtpFindFirstFileW(ftp_session_t *lpwfs,
     }
 
 lend:
+    heap_free(lpszSearchPath);
+
     if (lpwfs->lstnSocket != -1)
     {
         closesocket(lpwfs->lstnSocket);
@@ -1181,7 +1199,7 @@ static DWORD FTPFILE_WriteFile(object_header_t *hdr, const void *buffer, DWORD s
     res = sock_send(lpwh->nDataSocket, buffer, size, 0);
 
     *written = res>0 ? res : 0;
-    return res >= 0 ? ERROR_SUCCESS : sock_get_error(errno);
+    return res >= 0 ? ERROR_SUCCESS : sock_get_error();
 }
 
 static void FTP_ReceiveRequestData(ftp_file_t *file, BOOL first_notif)
@@ -1216,17 +1234,14 @@ static void FTPFILE_AsyncQueryDataAvailableProc(task_header_t *task)
 static DWORD FTPFILE_QueryDataAvailable(object_header_t *hdr, DWORD *available, DWORD flags, DWORD_PTR ctx)
 {
     ftp_file_t *file = (ftp_file_t*) hdr;
-    int retval, unread = 0;
+    ULONG unread = 0;
+    int retval;
 
     TRACE("(%p %p %x %lx)\n", file, available, flags, ctx);
 
-#ifdef FIONREAD
     retval = ioctlsocket(file->nDataSocket, FIONREAD, &unread);
     if (!retval)
         TRACE("%d bytes of queued, but unread data\n", unread);
-#else
-    FIXME("FIONREAD not available\n");
-#endif
 
     *available = unread;
 
@@ -2328,11 +2343,11 @@ static void FTPSESSION_CloseConnection(object_header_t *hdr)
     if (lpwfs->download_in_progress != NULL)
         lpwfs->download_in_progress->session_deleted = TRUE;
 
-     if (lpwfs->sndSocket != -1)
-         closesocket(lpwfs->sndSocket);
+    if (lpwfs->sndSocket != -1)
+        closesocket(lpwfs->sndSocket);
 
-     if (lpwfs->lstnSocket != -1)
-         closesocket(lpwfs->lstnSocket);
+    if (lpwfs->lstnSocket != -1)
+        closesocket(lpwfs->lstnSocket);
 
     if (lpwfs->pasvSocket != -1)
         closesocket(lpwfs->pasvSocket);
@@ -2409,7 +2424,7 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName,
     socklen_t sock_namelen;
     BOOL bSuccess = FALSE;
     ftp_session_t *lpwfs = NULL;
-    char szaddr[INET_ADDRSTRLEN];
+    char szaddr[INET6_ADDRSTRLEN];
 
     TRACE("%p  Server(%s) Port(%d) User(%s) Paswd(%s)\n",
            hIC, debugstr_w(lpszServerName),
@@ -2454,7 +2469,7 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName,
         if(hIC->proxyBypass)
             FIXME("Proxy bypass is ignored.\n");
     }
-    if (!lpszUserName || !strlenW(lpszUserName)) {
+    if (!lpszUserName || !lpszUserName[0]) {
         HKEY key;
         WCHAR szPassword[MAX_PATH];
         DWORD len = sizeof(szPassword);
@@ -2497,7 +2512,7 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName,
         (LPWSTR) lpszServerName, (strlenW(lpszServerName)+1) * sizeof(WCHAR));
 
     sock_namelen = sizeof(socketAddr);
-    if (!GetAddress(lpszServerName, lpwfs->serverport, (struct sockaddr *)&socketAddr, &sock_namelen))
+    if (!GetAddress(lpszServerName, lpwfs->serverport, (struct sockaddr *)&socketAddr, &sock_namelen, szaddr))
     {
        INTERNET_SetLastError(ERROR_INTERNET_NAME_NOT_RESOLVED);
         goto lerror;
@@ -2510,10 +2525,10 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName,
         goto lerror;
     }
 
-    inet_ntop(socketAddr.sin_family, &socketAddr.sin_addr, szaddr, sizeof(szaddr));
     SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_NAME_RESOLVED,
                       szaddr, strlen(szaddr)+1);
 
+    init_winsock();
     nsocket = socket(AF_INET,SOCK_STREAM,0);
     if (nsocket == -1)
     {
@@ -2526,7 +2541,7 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName,
 
     if (connect(nsocket, (struct sockaddr *)&socketAddr, sock_namelen) < 0)
     {
-       ERR("Unable to connect (%s)\n", strerror(errno));
+       ERR("Unable to connect (%d)\n", sock_get_error());
        INTERNET_SetLastError(ERROR_INTERNET_CANNOT_CONNECT);
        closesocket(nsocket);
     }
@@ -2601,6 +2616,58 @@ lend:
     return bSuccess;
 }
 
+/***********************************************************************
+ *           FTP_GetNextLine  (internal)
+ *
+ * Parse next line in directory string listing
+ *
+ * RETURNS
+ *   Pointer to beginning of next line
+ *   NULL on failure
+ *
+ */
+
+static LPSTR FTP_GetNextLine(INT nSocket, LPDWORD dwLen)
+{
+    struct timeval tv = {RESPONSE_TIMEOUT,0};
+    FD_SET set;
+    INT nRecv = 0;
+    LPSTR lpszBuffer = INTERNET_GetResponseBuffer();
+
+    TRACE("\n");
+
+    FD_ZERO(&set);
+    FD_SET(nSocket, &set);
+
+    while (nRecv < MAX_REPLY_LEN)
+    {
+        if (select(nSocket+1, &set, NULL, NULL, &tv) > 0)
+        {
+            if (sock_recv(nSocket, &lpszBuffer[nRecv], 1, 0) <= 0)
+            {
+                INTERNET_SetLastError(ERROR_FTP_TRANSFER_IN_PROGRESS);
+                return NULL;
+            }
+
+            if (lpszBuffer[nRecv] == '\n')
+            {
+                lpszBuffer[nRecv] = '\0';
+                *dwLen = nRecv - 1;
+                TRACE(":%d %s\n", nRecv, lpszBuffer);
+                return lpszBuffer;
+            }
+            if (lpszBuffer[nRecv] != '\r')
+                nRecv++;
+        }
+       else
+       {
+            INTERNET_SetLastError(ERROR_INTERNET_TIMEOUT);
+            return NULL;
+        }
+    }
+
+    return NULL;
+}
 
 /***********************************************************************
  *           FTP_SendCommandA (internal)
@@ -2700,7 +2767,7 @@ INT FTP_ReceiveResponse(ftp_session_t *lpwfs, DWORD_PTR dwContext)
 
     while(1)
     {
-       if (!INTERNET_GetNextLine(lpwfs->sndSocket, &nRecv))
+       if (!FTP_GetNextLine(lpwfs->sndSocket, &nRecv))
            goto lerror;
 
         if (nRecv >= 3)
@@ -2873,7 +2940,8 @@ static BOOL FTP_InitListenSocket(ftp_session_t *lpwfs)
 
     TRACE("\n");
 
-    lpwfs->lstnSocket = socket(PF_INET, SOCK_STREAM, 0);
+    init_winsock();
+    lpwfs->lstnSocket = socket(AF_INET, SOCK_STREAM, 0);
     if (lpwfs->lstnSocket == -1)
     {
         TRACE("Unable to create listening socket\n");
@@ -3016,10 +3084,10 @@ static BOOL FTP_SendPort(ftp_session_t *lpwfs)
     TRACE("\n");
 
     sprintfW(szIPAddress, szIPFormat,
-        lpwfs->lstnSocketAddress.sin_addr.s_addr&0x000000FF,
-        (lpwfs->lstnSocketAddress.sin_addr.s_addr&0x0000FF00)>>8,
-        (lpwfs->lstnSocketAddress.sin_addr.s_addr&0x00FF0000)>>16,
-        (lpwfs->lstnSocketAddress.sin_addr.s_addr&0xFF000000)>>24,
+        lpwfs->lstnSocketAddress.sin_addr.S_un.S_addr&0x000000FF,
+        (lpwfs->lstnSocketAddress.sin_addr.S_un.S_addr&0x0000FF00)>>8,
+        (lpwfs->lstnSocketAddress.sin_addr.S_un.S_addr&0x00FF0000)>>16,
+        (lpwfs->lstnSocketAddress.sin_addr.S_un.S_addr&0xFF000000)>>24,
         lpwfs->lstnSocketAddress.sin_port & 0xFF,
         (lpwfs->lstnSocketAddress.sin_port & 0xFF00)>>8);
 
@@ -3092,7 +3160,7 @@ static BOOL FTP_DoPassive(ftp_session_t *lpwfs)
                f[i] = f[i] & 0xff;
 
            dataSocketAddress = lpwfs->socketAddress;
-           pAddr = (char *)&(dataSocketAddress.sin_addr.s_addr);
+           pAddr = (char *)&(dataSocketAddress.sin_addr.S_un.S_addr);
            pPort = (char *)&(dataSocketAddress.sin_port);
             pAddr[0] = f[0];
             pAddr[1] = f[1];
@@ -3155,7 +3223,7 @@ static BOOL FTP_SendPortOrPasv(ftp_session_t *lpwfs)
 static BOOL FTP_GetDataSocket(ftp_session_t *lpwfs, LPINT nDataSocket)
 {
     struct sockaddr_in saddr;
-    socklen_t addrlen = sizeof(struct sockaddr);
+    socklen_t addrlen = sizeof(saddr);
 
     TRACE("\n");
     if (lpwfs->hdr.dwFlags & INTERNET_FLAG_PASSIVE)
@@ -3559,7 +3627,7 @@ static BOOL FTP_ParseNextFile(INT nSocket, LPCWSTR lpszSearchFile, LPFILEPROPERT
     
     lpfp->lpszName = NULL;
     do {
-        if(!(pszLine = INTERNET_GetNextLine(nSocket, &nBufLen)))
+        if(!(pszLine = FTP_GetNextLine(nSocket, &nBufLen)))
             return FALSE;
     
         pszToken = strtok(pszLine, szSpace);
index e472d3e..2341914 100644 (file)
 
 #include <wine/exception.h>
 
-// ReactOS
-#include "inet_ntop.c"
-
 static const WCHAR g_szHttp1_0[] = {'H','T','T','P','/','1','.','0',0};
 static const WCHAR g_szHttp1_1[] = {'H','T','T','P','/','1','.','1',0};
 static const WCHAR szOK[] = {'O','K',0};
-static const WCHAR szDefaultHeader[] = {'H','T','T','P','/','1','.','0',' ','2','0','0',' ','O','K',0};
 static const WCHAR hostW[] = { 'H','o','s','t',0 };
 static const WCHAR szAuthorization[] = { 'A','u','t','h','o','r','i','z','a','t','i','o','n',0 };
 static const WCHAR szProxy_Authorization[] = { 'P','r','o','x','y','-','A','u','t','h','o','r','i','z','a','t','i','o','n',0 };
@@ -51,7 +47,6 @@ static const WCHAR szStatus[] = { 'S','t','a','t','u','s',0 };
 static const WCHAR szKeepAlive[] = {'K','e','e','p','-','A','l','i','v','e',0};
 static const WCHAR szGET[] = { 'G','E','T', 0 };
 static const WCHAR szHEAD[] = { 'H','E','A','D', 0 };
-static const WCHAR szCrLf[] = {'\r','\n', 0};
 
 static const WCHAR szAccept[] = { 'A','c','c','e','p','t',0 };
 static const WCHAR szAccept_Charset[] = { 'A','c','c','e','p','t','-','C','h','a','r','s','e','t', 0 };
@@ -186,7 +181,6 @@ static LPWSTR HTTP_build_req( LPCWSTR *list, int len );
 static DWORD HTTP_HttpQueryInfoW(http_request_t*, DWORD, LPVOID, LPDWORD, LPDWORD);
 static LPWSTR HTTP_GetRedirectURL(http_request_t *req, LPCWSTR lpszUrl);
 static UINT HTTP_DecodeBase64(LPCWSTR base64, LPSTR bin);
-static BOOL HTTP_VerifyValidHeader(http_request_t *req, LPCWSTR field);
 static BOOL drain_content(http_request_t*,BOOL);
 
 static CRITICAL_SECTION connection_pool_cs;
@@ -346,6 +340,11 @@ static DWORD WINAPI collect_connections_proc(void *arg)
     FreeLibraryAndExitThread(WININET_hModule, 0);
 }
 
+/***********************************************************************
+ *           HTTP_GetHeader (internal)
+ *
+ * Headers section must be held
+ */
 static LPHTTPHEADERW HTTP_GetHeader(http_request_t *req, LPCWSTR head)
 {
     int HeaderIndex = 0;
@@ -356,6 +355,17 @@ static LPHTTPHEADERW HTTP_GetHeader(http_request_t *req, LPCWSTR head)
         return &req->custHeaders[HeaderIndex];
 }
 
+static WCHAR *get_host_header( http_request_t *req )
+{
+    HTTPHEADERW *header;
+    WCHAR *ret = NULL;
+
+    EnterCriticalSection( &req->headers_section );
+    if ((header = HTTP_GetHeader( req, hostW ))) ret = heap_strdupW( header->lpszValue );
+    LeaveCriticalSection( &req->headers_section );
+    return ret;
+}
+
 struct data_stream_vtbl_t {
     DWORD (*get_avail_data)(data_stream_t*,http_request_t*);
     BOOL (*end_of_data)(data_stream_t*,http_request_t*);
@@ -387,6 +397,15 @@ static void reset_data_stream(http_request_t *req)
     req->read_chunked = req->read_gzip = FALSE;
 }
 
+static void remove_header( http_request_t *request, const WCHAR *str, BOOL from_request )
+{
+    int index;
+    EnterCriticalSection( &request->headers_section );
+    index = HTTP_GetCustomHeaderIndex( request, str, 0, from_request );
+    if (index != -1) HTTP_DeleteCustomHeader( request, index );
+    LeaveCriticalSection( &request->headers_section );
+}
+
 #ifdef HAVE_ZLIB
 
 typedef struct {
@@ -513,7 +532,7 @@ static void wininet_zfree(voidpf opaque, voidpf address)
 static DWORD init_gzip_stream(http_request_t *req, BOOL is_gzip)
 {
     gzip_stream_t *gzip_stream;
-    int index, zres;
+    int zres;
 
     gzip_stream = heap_alloc_zero(sizeof(gzip_stream_t));
     if(!gzip_stream)
@@ -530,9 +549,7 @@ static DWORD init_gzip_stream(http_request_t *req, BOOL is_gzip)
         return ERROR_OUTOFMEMORY;
     }
 
-    index = HTTP_GetCustomHeaderIndex(req, szContent_Length, 0, FALSE);
-    if(index != -1)
-        HTTP_DeleteCustomHeader(req, index);
+    remove_header(req, szContent_Length, FALSE);
 
     if(req->read_size) {
         memcpy(gzip_stream->buf, req->read_buf+req->read_pos, req->read_size);
@@ -606,19 +623,24 @@ static void HTTP_FixURL(http_request_t *request)
 static WCHAR* build_request_header(http_request_t *request, const WCHAR *verb,
         const WCHAR *path, const WCHAR *version, BOOL use_cr)
 {
+    static const WCHAR szSpace[] = {' ',0};
+    static const WCHAR szColon[] = {':',' ',0};
+    static const WCHAR szCr[] = {'\r',0};
+    static const WCHAR szLf[] = {'\n',0};
     LPWSTR requestString;
     DWORD len, n;
     LPCWSTR *req;
     UINT i;
 
-    static const WCHAR szSpace[] = { ' ',0 };
-    static const WCHAR szColon[] = { ':',' ',0 };
-    static const WCHAR szCr[] = { '\r',0 };
-    static const WCHAR szLf[] = { '\n',0 };
+    EnterCriticalSection( &request->headers_section );
 
     /* allocate space for an array of all the string pointers to be added */
-    len = (request->nCustHeaders)*5 + 10;
-    req = heap_alloc(len*sizeof(LPCWSTR));
+    len = request->nCustHeaders * 5 + 10;
+    if (!(req = heap_alloc( len * sizeof(const WCHAR *) )))
+    {
+        LeaveCriticalSection( &request->headers_section );
+        return NULL;
+    }
 
     /* add the verb, path and HTTP version string */
     n = 0;
@@ -655,6 +677,7 @@ static WCHAR* build_request_header(http_request_t *request, const WCHAR *verb,
 
     requestString = HTTP_build_req( req, 4 );
     heap_free( req );
+    LeaveCriticalSection( &request->headers_section );
     return requestString;
 }
 
@@ -664,14 +687,17 @@ static WCHAR* build_response_header(http_request_t *request, BOOL use_cr)
     static const WCHAR crW[] = { '\r',0 };
     static const WCHAR lfW[] = { '\n',0 };
     static const WCHAR status_fmt[] = { ' ','%','u',' ',0 };
-
     const WCHAR **req;
     WCHAR *ret, buf[14];
     DWORD i, n = 0;
 
-    req = heap_alloc((request->nCustHeaders*5+8)*sizeof(WCHAR*));
-    if(!req)
+    EnterCriticalSection( &request->headers_section );
+
+    if (!(req = heap_alloc( (request->nCustHeaders * 5 + 8) * sizeof(WCHAR *) )))
+    {
+        LeaveCriticalSection( &request->headers_section );
         return NULL;
+    }
 
     if (request->status_code)
     {
@@ -708,6 +734,7 @@ static WCHAR* build_response_header(http_request_t *request, BOOL use_cr)
 
     ret = HTTP_build_req(req, 0);
     heap_free(req);
+    LeaveCriticalSection( &request->headers_section );
     return ret;
 }
 
@@ -720,6 +747,8 @@ static void HTTP_ProcessCookies( http_request_t *request )
     if(request->hdr.dwFlags & INTERNET_FLAG_NO_COOKIES)
         return;
 
+    EnterCriticalSection( &request->headers_section );
+
     while((HeaderIndex = HTTP_GetCustomHeaderIndex(request, szSet_Cookie, numCookies++, FALSE)) != -1)
     {
         HTTPHEADERW *host;
@@ -747,6 +776,8 @@ static void HTTP_ProcessCookies( http_request_t *request )
         set_cookie(host->lpszValue, request->path, name, data, INTERNET_COOKIE_HTTPONLY);
         heap_free(name);
     }
+
+    LeaveCriticalSection( &request->headers_section );
 }
 
 static void strip_spaces(LPWSTR start)
@@ -754,7 +785,7 @@ static void strip_spaces(LPWSTR start)
     LPWSTR str = start;
     LPWSTR end;
 
-    while (*str == ' ' && *str != '\0')
+    while (*str == ' ')
         str++;
 
     if (str != start)
@@ -786,13 +817,13 @@ static inline BOOL is_basic_auth_value( LPCWSTR pszAuthValue, LPWSTR *pszRealm )
         if (!token)
             return TRUE;
         realm = ptr;
-        while (*realm == ' ' && *realm != '\0')
+        while (*realm == ' ')
             realm++;
         if(!strncmpiW(realm, szRealm, ARRAYSIZE(szRealm)) &&
             (realm[ARRAYSIZE(szRealm)] == ' ' || realm[ARRAYSIZE(szRealm)] == '='))
         {
             token++;
-            while (*token == ' ' && *token != '\0')
+            while (*token == ' ')
                 token++;
             if (*token == '\0')
                 return TRUE;
@@ -1266,10 +1297,8 @@ static DWORD HTTP_HttpAddRequestHeadersW(http_request_t *request,
         pFieldAndValue = HTTP_InterpretHttpHeader(lpszStart);
         if (pFieldAndValue)
         {
-            res = HTTP_VerifyValidHeader(request, pFieldAndValue[0]);
-            if (res == ERROR_SUCCESS)
-                res = HTTP_ProcessHeader(request, pFieldAndValue[0],
-                    pFieldAndValue[1], dwModifier | HTTP_ADDHDR_FLAG_REQ);
+            res = HTTP_ProcessHeader(request, pFieldAndValue[0],
+                pFieldAndValue[1], dwModifier | HTTP_ADDHDR_FLAG_REQ);
             HTTP_FreeTokens(pFieldAndValue);
         }
 
@@ -1806,8 +1835,7 @@ static BOOL HTTP_DealWithProxy(appinfo_t *hIC, http_session_t *session, http_req
 static DWORD HTTP_ResolveName(http_request_t *request)
 {
     server_t *server = request->proxy ? request->proxy : request->server;
-    socklen_t addr_len;
-    void *addr;
+    int addr_len;
 
     if(server->addr_len)
         return ERROR_SUCCESS;
@@ -1818,23 +1846,10 @@ static DWORD HTTP_ResolveName(http_request_t *request)
                           (strlenW(server->name)+1) * sizeof(WCHAR));
 
     addr_len = sizeof(server->addr);
-    if (!GetAddress(server->name, server->port, (struct sockaddr *)&server->addr, &addr_len))
+    if (!GetAddress(server->name, server->port, (SOCKADDR*)&server->addr, &addr_len, server->addr_str))
         return ERROR_INTERNET_NAME_NOT_RESOLVED;
 
-    switch(server->addr.ss_family) {
-    case AF_INET:
-        addr = &((struct sockaddr_in *)&server->addr)->sin_addr;
-        break;
-    case AF_INET6:
-        addr = &((struct sockaddr_in6 *)&server->addr)->sin6_addr;
-        break;
-    default:
-        WARN("unsupported family %d\n", server->addr.ss_family);
-        return ERROR_INTERNET_NAME_NOT_RESOLVED;
-    }
-
     server->addr_len = addr_len;
-    inet_ntop(server->addr.ss_family, addr, server->addr_str, sizeof(server->addr_str));
     INTERNET_SendCallback(&request->hdr, request->hdr.dwContext,
                           INTERNET_STATUS_NAME_RESOLVED,
                           server->addr_str, strlen(server->addr_str)+1);
@@ -1855,6 +1870,8 @@ static BOOL HTTP_GetRequestURL(http_request_t *req, LPWSTR buf)
     if(!host_header)
         return FALSE;
 
+    EnterCriticalSection( &req->headers_section );
+
     if (req->hdr.dwFlags & INTERNET_FLAG_SECURE)
         scheme = https;
     else
@@ -1864,6 +1881,8 @@ static BOOL HTTP_GetRequestURL(http_request_t *req, LPWSTR buf)
     if (req->path[0] != '/')
         strcatW(buf, slash);
     strcatW(buf, req->path);
+
+    LeaveCriticalSection( &req->headers_section );
     return TRUE;
 }
 
@@ -1886,6 +1905,8 @@ static void HTTPREQ_Destroy(object_header_t *hdr)
     if(request->req_file)
         req_file_release(request->req_file);
 
+    request->headers_section.DebugInfo->Spare[0] = 0;
+    DeleteCriticalSection( &request->headers_section );
     request->read_section.DebugInfo->Spare[0] = 0;
     DeleteCriticalSection( &request->read_section );
     WININET_Release(&request->session->hdr);
@@ -2100,17 +2121,18 @@ static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffe
         return ERROR_SUCCESS;
 
     case INTERNET_OPTION_URL: {
+        static const WCHAR httpW[] = {'h','t','t','p',':','/','/',0};
         WCHAR url[INTERNET_MAX_URL_LENGTH];
         HTTPHEADERW *host;
 
-        static const WCHAR httpW[] = {'h','t','t','p',':','/','/',0};
-
         TRACE("INTERNET_OPTION_URL\n");
 
+        EnterCriticalSection( &req->headers_section );
         host = HTTP_GetHeader(req, hostW);
         strcpyW(url, httpW);
         strcatW(url, host->lpszValue);
         strcatW(url, req->path);
+        LeaveCriticalSection( &req->headers_section );
 
         TRACE("INTERNET_OPTION_URL: %s\n",debugstr_w(url));
         return str_to_buffer(url, buffer, size, unicode);
@@ -2386,7 +2408,11 @@ static void create_cache_entry(http_request_t *req)
         b = FALSE;
 
     if(b) {
-        int header_idx = HTTP_GetCustomHeaderIndex(req, szCache_Control, 0, FALSE);
+        int header_idx;
+
+        EnterCriticalSection( &req->headers_section );
+
+        header_idx = HTTP_GetCustomHeaderIndex(req, szCache_Control, 0, FALSE);
         if(header_idx != -1) {
             WCHAR *ptr;
 
@@ -2411,6 +2437,8 @@ static void create_cache_entry(http_request_t *req)
                     ptr++;
             }
         }
+
+        LeaveCriticalSection( &req->headers_section );
     }
 
     if(!b) {
@@ -2911,17 +2939,23 @@ static DWORD set_content_length(http_request_t *request)
         static const WCHAR deflateW[] = {'d','e','f','l','a','t','e',0};
         static const WCHAR gzipW[] = {'g','z','i','p',0};
 
+        EnterCriticalSection( &request->headers_section );
+
         encoding_idx = HTTP_GetCustomHeaderIndex(request, szContent_Encoding, 0, FALSE);
         if(encoding_idx != -1) {
             if(!strcmpiW(request->custHeaders[encoding_idx].lpszValue, gzipW)) {
                 HTTP_DeleteCustomHeader(request, encoding_idx);
+                LeaveCriticalSection( &request->headers_section );
                 return init_gzip_stream(request, TRUE);
             }
             if(!strcmpiW(request->custHeaders[encoding_idx].lpszValue, deflateW)) {
                 HTTP_DeleteCustomHeader(request, encoding_idx);
+                LeaveCriticalSection( &request->headers_section );
                 return init_gzip_stream(request, FALSE);
             }
         }
+
+        LeaveCriticalSection( &request->headers_section );
     }
 
     return ERROR_SUCCESS;
@@ -3291,6 +3325,9 @@ static DWORD HTTP_HttpOpenRequestW(http_session_t *session,
     request->send_timeout = session->send_timeout;
     request->receive_timeout = session->receive_timeout;
 
+    InitializeCriticalSection( &request->headers_section );
+    request->headers_section.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": http_request_t.headers_section");
+
     InitializeCriticalSection( &request->read_section );
     request->read_section.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": http_request_t.read_section");
 
@@ -3508,11 +3545,17 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel,
     DWORD level = (dwInfoLevel & ~HTTP_QUERY_MODIFIER_FLAGS_MASK);
     INT index = -1;
 
+    EnterCriticalSection( &request->headers_section );
+
     /* Find requested header structure */
     switch (level)
     {
     case HTTP_QUERY_CUSTOM:
-        if (!lpBuffer) return ERROR_INVALID_PARAMETER;
+        if (!lpBuffer)
+        {
+            LeaveCriticalSection( &request->headers_section );
+            return ERROR_INVALID_PARAMETER;
+        }
         index = HTTP_GetCustomHeaderIndex(request, lpBuffer, requested_index, request_only);
         break;
     case HTTP_QUERY_RAW_HEADERS_CRLF:
@@ -3526,7 +3569,10 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel,
             else
                 headers = build_response_header(request, TRUE);
             if (!headers)
+            {
+                LeaveCriticalSection( &request->headers_section );
                 return ERROR_OUTOFMEMORY;
+            }
 
             len = strlenW(headers) * sizeof(WCHAR);
             if (len + sizeof(WCHAR) > *lpdwBufferLength)
@@ -3543,6 +3589,7 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel,
             *lpdwBufferLength = len;
 
             heap_free(headers);
+            LeaveCriticalSection( &request->headers_section );
             return res;
         }
     case HTTP_QUERY_RAW_HEADERS:
@@ -3554,14 +3601,19 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel,
                 headers = build_request_header(request, request->verb, request->path, request->version, FALSE);
             else
                 headers = build_response_header(request, FALSE);
+
             if (!headers)
+            {
+                LeaveCriticalSection( &request->headers_section );
                 return ERROR_OUTOFMEMORY;
+            }
 
             len = strlenW(headers) * sizeof(WCHAR);
             if (len > *lpdwBufferLength)
             {
                 *lpdwBufferLength = len;
                 heap_free(headers);
+                LeaveCriticalSection( &request->headers_section );
                 return ERROR_INSUFFICIENT_BUFFER;
             }
 
@@ -3581,6 +3633,7 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel,
             *lpdwBufferLength = len - sizeof(WCHAR);
 
             heap_free(headers);
+            LeaveCriticalSection( &request->headers_section );
             return ERROR_SUCCESS;
         }
     case HTTP_QUERY_STATUS_TEXT:
@@ -3590,6 +3643,7 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel,
             if (len + 1 > *lpdwBufferLength/sizeof(WCHAR))
             {
                 *lpdwBufferLength = (len + 1) * sizeof(WCHAR);
+                LeaveCriticalSection( &request->headers_section );
                 return ERROR_INSUFFICIENT_BUFFER;
             }
             if (lpBuffer)
@@ -3598,6 +3652,7 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel,
                 TRACE("returning data: %s\n", debugstr_wn(lpBuffer, len));
             }
             *lpdwBufferLength = len * sizeof(WCHAR);
+            LeaveCriticalSection( &request->headers_section );
             return ERROR_SUCCESS;
         }
         break;
@@ -3608,6 +3663,7 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel,
             if (len + 1 > *lpdwBufferLength/sizeof(WCHAR))
             {
                 *lpdwBufferLength = (len + 1) * sizeof(WCHAR);
+                LeaveCriticalSection( &request->headers_section );
                 return ERROR_INSUFFICIENT_BUFFER;
             }
             if (lpBuffer)
@@ -3616,6 +3672,7 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel,
                 TRACE("returning data: %s\n", debugstr_wn(lpBuffer, len));
             }
             *lpdwBufferLength = len * sizeof(WCHAR);
+            LeaveCriticalSection( &request->headers_section );
             return ERROR_SUCCESS;
         }
         break;
@@ -3627,7 +3684,10 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel,
         DWORD res = ERROR_SUCCESS;
 
         if(request_only)
+        {
+            LeaveCriticalSection( &request->headers_section );
             return ERROR_HTTP_INVALID_QUERY_REQUEST;
+        }
 
         if(requested_index)
             break;
@@ -3654,6 +3714,7 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel,
 
             *lpdwBufferLength = size;
         }
+        LeaveCriticalSection( &request->headers_section );
         return res;
     }
     default:
@@ -3672,6 +3733,7 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel,
         ((dwInfoLevel & HTTP_QUERY_FLAG_REQUEST_HEADERS) &&
          (~lphttpHdr->wFlags & HDR_ISREQUEST)))
     {
+        LeaveCriticalSection( &request->headers_section );
         return ERROR_HTTP_HEADER_NOT_FOUND;
     }
 
@@ -3711,6 +3773,7 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel,
         if (len > *lpdwBufferLength)
         {
             *lpdwBufferLength = len;
+            LeaveCriticalSection( &request->headers_section );
             return ERROR_INSUFFICIENT_BUFFER;
         }
         if (lpBuffer)
@@ -3721,6 +3784,8 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel,
         *lpdwBufferLength = len - sizeof(WCHAR);
     }
     if (lpdwIndex) (*lpdwIndex)++;
+
+    LeaveCriticalSection( &request->headers_section );
     return ERROR_SUCCESS;
 }
 
@@ -4009,7 +4074,6 @@ static DWORD HTTP_HandleRedirect(http_request_t *request, LPCWSTR lpszUrl)
 {
     http_session_t *session = request->session;
     WCHAR path[INTERNET_MAX_PATH_LENGTH];
-    int index;
 
     if(lpszUrl[0]=='/')
     {
@@ -4073,20 +4137,9 @@ static DWORD HTTP_HandleRedirect(http_request_t *request, LPCWSTR lpszUrl)
 
         heap_free(session->hostName);
 
-        if(custom_port) {
-            int len;
-            static const WCHAR fmt[] = {'%','s',':','%','u',0};
-            len = lstrlenW(hostName);
-            len += 7; /* 5 for strlen("65535") + 1 for ":" + 1 for '\0' */
-            session->hostName = heap_alloc(len*sizeof(WCHAR));
-            sprintfW(session->hostName, fmt, hostName, urlComponents.nPort);
-        }
-        else
-            session->hostName = heap_strdupW(hostName);
+        session->hostName = heap_strdupW(hostName);
         session->hostPort = urlComponents.nPort;
 
-        HTTP_ProcessHeader(request, hostW, session->hostName, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDHDR_FLAG_REQ);
-
         heap_free(session->userName);
         session->userName = NULL;
         if (userName[0])
@@ -4101,6 +4154,11 @@ static DWORD HTTP_HandleRedirect(http_request_t *request, LPCWSTR lpszUrl)
             server_release(request->server);
             request->server = new_server;
         }
+
+        if (custom_port)
+            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);
     }
     heap_free(request->path);
     request->path=NULL;
@@ -4123,12 +4181,8 @@ static DWORD HTTP_HandleRedirect(http_request_t *request, LPCWSTR lpszUrl)
     }
 
     /* Remove custom content-type/length headers on redirects.  */
-    index = HTTP_GetCustomHeaderIndex(request, szContent_Type, 0, TRUE);
-    if (0 <= index)
-        HTTP_DeleteCustomHeader(request, index);
-    index = HTTP_GetCustomHeaderIndex(request, szContent_Length, 0, TRUE);
-    if (0 <= index)
-        HTTP_DeleteCustomHeader(request, index);
+    remove_header(request, szContent_Type, TRUE);
+    remove_header(request, szContent_Length, TRUE);
 
     return ERROR_SUCCESS;
 }
@@ -4586,6 +4640,8 @@ static void HTTP_ProcessExpires(http_request_t *request)
     BOOL expirationFound = FALSE;
     int headerIndex;
 
+    EnterCriticalSection( &request->headers_section );
+
     /* Look for a Cache-Control header with a max-age directive, as it takes
      * precedence over the Expires header.
      */
@@ -4666,12 +4722,16 @@ static void HTTP_ProcessExpires(http_request_t *request)
         request->expires.dwLowDateTime = t.u.LowPart;
         request->expires.dwHighDateTime = t.u.HighPart;
     }
+
+    LeaveCriticalSection( &request->headers_section );
 }
 
 static void HTTP_ProcessLastModified(http_request_t *request)
 {
     int headerIndex;
 
+    EnterCriticalSection( &request->headers_section );
+
     headerIndex = HTTP_GetCustomHeaderIndex(request, szLast_Modified, 0, FALSE);
     if (headerIndex != -1)
     {
@@ -4681,18 +4741,24 @@ static void HTTP_ProcessLastModified(http_request_t *request)
         if (HTTP_ParseDate(expiresHeader->lpszValue, &ft))
             request->last_modified = ft;
     }
+
+    LeaveCriticalSection( &request->headers_section );
 }
 
 static void http_process_keep_alive(http_request_t *req)
 {
     int index;
 
+    EnterCriticalSection( &req->headers_section );
+
     if ((index = HTTP_GetCustomHeaderIndex(req, szConnection, 0, FALSE)) != -1)
         req->netconn->keep_alive = !strcmpiW(req->custHeaders[index].lpszValue, szKeepAlive);
     else if ((index = HTTP_GetCustomHeaderIndex(req, szProxy_Connection, 0, FALSE)) != -1)
         req->netconn->keep_alive = !strcmpiW(req->custHeaders[index].lpszValue, szKeepAlive);
     else
         req->netconn->keep_alive = !strcmpiW(req->version, g_szHttp1_1);
+
+    LeaveCriticalSection( &req->headers_section );
 }
 
 static DWORD open_http_connection(http_request_t *request, BOOL *reusing)
@@ -4864,8 +4930,12 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
 
         if (TRACE_ON(wininet))
         {
-            LPHTTPHEADERW Host = HTTP_GetHeader(request, hostW);
-            TRACE("Going to url %s %s\n", debugstr_w(Host->lpszValue), debugstr_w(request->path));
+            HTTPHEADERW *host;
+
+            EnterCriticalSection( &request->headers_section );
+            host = HTTP_GetHeader( request, hostW );
+            TRACE("Going to url %s %s\n", debugstr_w(host->lpszValue), debugstr_w(request->path));
+            LeaveCriticalSection( &request->headers_section );
         }
 
         HTTP_FixURL(request);
@@ -5019,15 +5089,14 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
                 dwBufferSize=2048;
                 if (request->status_code == HTTP_STATUS_DENIED)
                 {
-                    LPHTTPHEADERW Host = HTTP_GetHeader(request, hostW);
+                    WCHAR *host = get_host_header( request );
                     DWORD dwIndex = 0;
                     while (HTTP_HttpQueryInfoW(request,HTTP_QUERY_WWW_AUTHENTICATE,szAuthValue,&dwBufferSize,&dwIndex) == ERROR_SUCCESS)
                     {
                         if (HTTP_DoAuthorization(request, szAuthValue,
                                                  &request->authInfo,
                                                  request->session->userName,
-                                                 request->session->password,
-                                                 Host->lpszValue))
+                                                 request->session->password, host))
                         {
                             heap_free(requestString);
                             if(!drain_content(request, TRUE)) {
@@ -5038,6 +5107,7 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
                             break;
                         }
                     }
+                    heap_free( host );
 
                     if(!loop_next) {
                         TRACE("Cleaning wrong authorization data\n");
@@ -5075,8 +5145,6 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
             }
             if (secure_proxy_connect && request->status_code == HTTP_STATUS_OK)
             {
-                int index;
-
                 res = NETCON_secure_connect(request->netconn, request->server);
                 if (res != ERROR_SUCCESS)
                 {
@@ -5084,8 +5152,7 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
                     http_release_netconn( request, FALSE );
                     break;
                 }
-                index = HTTP_GetCustomHeaderIndex(request, szProxy_Authorization, 0, TRUE);
-                if (index != -1) HTTP_DeleteCustomHeader(request, index);
+                remove_header(request, szProxy_Authorization, TRUE);
                 destroy_authinfo(request->proxyAuthInfo);
                 request->proxyAuthInfo = NULL;
 
@@ -5794,6 +5861,8 @@ static void HTTP_clear_response_headers( http_request_t *request )
 {
     DWORD i;
 
+    EnterCriticalSection( &request->headers_section );
+
     for( i=0; i<request->nCustHeaders; i++)
     {
         if( !request->custHeaders[i].lpszField )
@@ -5805,6 +5874,8 @@ static void HTTP_clear_response_headers( http_request_t *request )
         HTTP_DeleteCustomHeader( request, i );
         i--;
     }
+
+    LeaveCriticalSection( &request->headers_section );
 }
 
 /***********************************************************************
@@ -6005,12 +6076,14 @@ static LPWSTR * HTTP_InterpretHttpHeader(LPCWSTR buffer)
 static DWORD HTTP_ProcessHeader(http_request_t *request, LPCWSTR field, LPCWSTR value, DWORD dwModifier)
 {
     LPHTTPHEADERW lphttpHdr = NULL;
-    INT index = -1;
+    INT index;
     BOOL request_only = dwModifier & HTTP_ADDHDR_FLAG_REQ;
     DWORD res = ERROR_HTTP_INVALID_HEADER;
 
     TRACE("--> %s: %s - 0x%08x\n", debugstr_w(field), debugstr_w(value), dwModifier);
 
+    EnterCriticalSection( &request->headers_section );
+
     /* REPLACE wins out over ADD */
     if (dwModifier & HTTP_ADDHDR_FLAG_REPLACE)
         dwModifier &= ~HTTP_ADDHDR_FLAG_ADD;
@@ -6023,7 +6096,10 @@ static DWORD HTTP_ProcessHeader(http_request_t *request, LPCWSTR field, LPCWSTR
     if (index >= 0)
     {
         if (dwModifier & HTTP_ADDHDR_FLAG_ADD_IF_NEW)
+        {
+            LeaveCriticalSection( &request->headers_section );
             return ERROR_HTTP_INVALID_HEADER;
+        }
         lphttpHdr = &request->custHeaders[index];
     }
     else if (value)
@@ -6037,10 +6113,16 @@ static DWORD HTTP_ProcessHeader(http_request_t *request, LPCWSTR field, LPCWSTR
         if (dwModifier & HTTP_ADDHDR_FLAG_REQ)
             hdr.wFlags |= HDR_ISREQUEST;
 
-        return HTTP_InsertCustomHeader(request, &hdr);
+        res = HTTP_InsertCustomHeader(request, &hdr);
+        LeaveCriticalSection( &request->headers_section );
+        return res;
     }
     /* no value to delete */
-    else return ERROR_SUCCESS;
+    else
+    {
+        LeaveCriticalSection( &request->headers_section );
+        return ERROR_SUCCESS;
+    }
 
     if (dwModifier & HTTP_ADDHDR_FLAG_REQ)
            lphttpHdr->wFlags |= HDR_ISREQUEST;
@@ -6062,9 +6144,12 @@ static DWORD HTTP_ProcessHeader(http_request_t *request, LPCWSTR field, LPCWSTR
             if (dwModifier & HTTP_ADDHDR_FLAG_REQ)
                 hdr.wFlags |= HDR_ISREQUEST;
 
-            return HTTP_InsertCustomHeader(request, &hdr);
+            res = HTTP_InsertCustomHeader(request, &hdr);
+            LeaveCriticalSection( &request->headers_section );
+            return res;
         }
 
+        LeaveCriticalSection( &request->headers_section );
         return ERROR_SUCCESS;
     }
     else if (dwModifier & COALESCEFLAGS)
@@ -6112,6 +6197,7 @@ static DWORD HTTP_ProcessHeader(http_request_t *request, LPCWSTR field, LPCWSTR
         }
     }
     TRACE("<-- %d\n", res);
+    LeaveCriticalSection( &request->headers_section );
     return res;
 }
 
@@ -6119,7 +6205,7 @@ static DWORD HTTP_ProcessHeader(http_request_t *request, LPCWSTR field, LPCWSTR
  *           HTTP_GetCustomHeaderIndex (internal)
  *
  * Return index of custom header from header array
- *
+ * Headers section must be held
  */
 static INT HTTP_GetCustomHeaderIndex(http_request_t *request, LPCWSTR lpszField,
                                      int requested_index, BOOL request_only)
@@ -6156,7 +6242,7 @@ static INT HTTP_GetCustomHeaderIndex(http_request_t *request, LPCWSTR lpszField,
  *           HTTP_InsertCustomHeader (internal)
  *
  * Insert header into array
- *
+ * Headers section must be held
  */
 static DWORD HTTP_InsertCustomHeader(http_request_t *request, LPHTTPHEADERW lpHdr)
 {
@@ -6188,7 +6274,8 @@ static DWORD HTTP_InsertCustomHeader(http_request_t *request, LPHTTPHEADERW lpHd
  *           HTTP_DeleteCustomHeader (internal)
  *
  * Delete header from array
- *  If this function is called, the indexs may change.
+ * If this function is called, the index may change.
+ * Headers section must be held
  */
 static BOOL HTTP_DeleteCustomHeader(http_request_t *request, DWORD index)
 {
@@ -6209,21 +6296,6 @@ static BOOL HTTP_DeleteCustomHeader(http_request_t *request, DWORD index)
 }
 
 
-/***********************************************************************
- *           HTTP_VerifyValidHeader (internal)
- *
- * Verify the given header is not invalid for the given http request
- *
- */
-static BOOL HTTP_VerifyValidHeader(http_request_t *request, LPCWSTR field)
-{
-    /* Accept-Encoding is stripped from HTTP/1.0 requests. It is invalid */
-    if (!strcmpW(request->version, g_szHttp1_0) && !strcmpiW(field, szAccept_Encoding))
-        return ERROR_HTTP_INVALID_HEADER;
-
-    return ERROR_SUCCESS;
-}
-
 /***********************************************************************
  *          IsHostInProxyBypassList (@)
  *
index 8eb4fa5..f60d29a 100644 (file)
@@ -28,8 +28,6 @@
 
 #include "internet.h"
 
-#define RESPONSE_TIMEOUT        30
-
 typedef struct
 {
     DWORD  dwError;
@@ -487,11 +485,12 @@ static void free_global_proxy( void )
 static BOOL parse_proxy_url( proxyinfo_t *info, const WCHAR *url )
 {
     static const WCHAR fmt[] = {'%','s',':','%','u',0};
-    WCHAR hostname[INTERNET_MAX_HOST_NAME_LENGTH] = {0};
-    WCHAR username[INTERNET_MAX_USER_NAME_LENGTH] = {0};
-    WCHAR password[INTERNET_MAX_PASSWORD_LENGTH] = {0};
+    WCHAR hostname[INTERNET_MAX_HOST_NAME_LENGTH];
+    WCHAR username[INTERNET_MAX_USER_NAME_LENGTH];
+    WCHAR password[INTERNET_MAX_PASSWORD_LENGTH];
     URL_COMPONENTSW uc;
 
+    hostname[0] = username[0] = password[0] = 0;
     memset( &uc, 0, sizeof(uc) );
     uc.dwStructSize      = sizeof(uc);
     uc.lpszHostName      = hostname;
@@ -801,9 +800,6 @@ static VOID APPINFO_Destroy(object_header_t *hdr)
     heap_free(lpwai->proxyBypass);
     heap_free(lpwai->proxyUsername);
     heap_free(lpwai->proxyPassword);
-#ifdef __REACTOS__
-    WSACleanup();
-#endif
 }
 
 static DWORD APPINFO_QueryOption(object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
@@ -999,11 +995,6 @@ HINTERNET WINAPI InternetOpenW(LPCWSTR lpszAgent, DWORD dwAccessType,
     LPCWSTR lpszProxy, LPCWSTR lpszProxyBypass, DWORD dwFlags)
 {
     appinfo_t *lpwai = NULL;
-#ifdef __REACTOS__
-    WSADATA wsaData;
-    int error = WSAStartup(MAKEWORD(2, 2), &wsaData);
-    if (error) ERR("WSAStartup failed: %d\n", error);
-#endif
 
     if (TRACE_ON(wininet)) {
 #define FE(x) { x, #x }
@@ -1227,13 +1218,21 @@ BOOL WINAPI InternetGetConnectedStateExW(LPDWORD lpdwStatus, LPWSTR lpszConnecti
 
     /* Must be zero */
     if(dwReserved)
-       return FALSE;
+        return FALSE;
 
     if (lpdwStatus) {
         WARN("always returning LAN connection.\n");
         *lpdwStatus = INTERNET_CONNECTION_LAN;
     }
-    return LoadStringW(WININET_hModule, IDS_LANCONNECTION, lpszConnectionName, dwNameLen) > 0;
+
+    /* When the buffer size is zero LoadStringW fills the buffer with a pointer to
+     * the resource, avoid it as we must not change the buffer in this case */
+    if(lpszConnectionName && dwNameLen) {
+        *lpszConnectionName = '\0';
+        LoadStringW(WININET_hModule, IDS_LANCONNECTION, lpszConnectionName, dwNameLen);
+    }
+
+    return TRUE;
 }
 
 
@@ -3418,14 +3417,15 @@ BOOL WINAPI InternetCheckConnectionW( LPCWSTR lpszUrl, DWORD dwFlags, DWORD dwRe
       socklen_t sa_len = sizeof(saddr);
       int fd;
 
-      if (!GetAddress(hostW, port, (struct sockaddr *)&saddr, &sa_len))
+      if (!GetAddress(hostW, port, (struct sockaddr *)&saddr, &sa_len, NULL))
           goto End;
+      init_winsock();
       fd = socket(saddr.ss_family, SOCK_STREAM, 0);
       if (fd != -1)
       {
           if (connect(fd, (struct sockaddr *)&saddr, sa_len) == 0)
               rc = TRUE;
-          close(fd);
+          closesocket(fd);
       }
   }
   else
@@ -3860,72 +3860,6 @@ LPSTR INTERNET_GetResponseBuffer(void)
     return lpwite->response;
 }
 
-/***********************************************************************
- *           INTERNET_GetNextLine  (internal)
- *
- * Parse next line in directory string listing
- *
- * RETURNS
- *   Pointer to beginning of next line
- *   NULL on failure
- *
- */
-
-LPSTR INTERNET_GetNextLine(INT nSocket, LPDWORD dwLen)
-{
-    /* ReactOS: use select instead of poll */
-    fd_set infd;
-    struct timeval tv;
-    BOOL bSuccess = FALSE;
-    INT nRecv = 0;
-    LPSTR lpszBuffer = INTERNET_GetResponseBuffer();
-
-    TRACE("\n");
-
-    FD_ZERO(&infd);
-    FD_SET(nSocket,&infd);
-    tv.tv_sec = RESPONSE_TIMEOUT;
-    tv.tv_usec = 0;
-
-    while (nRecv < MAX_REPLY_LEN)
-    {
-        if (select(0, &infd, NULL, NULL, &tv) > 0)
-        {
-            if (sock_recv(nSocket, &lpszBuffer[nRecv], 1, 0) <= 0)
-            {
-                INTERNET_SetLastError(ERROR_FTP_TRANSFER_IN_PROGRESS);
-                goto lend;
-            }
-
-            if (lpszBuffer[nRecv] == '\n')
-           {
-               bSuccess = TRUE;
-                break;
-           }
-            if (lpszBuffer[nRecv] != '\r')
-                nRecv++;
-        }
-       else
-       {
-            INTERNET_SetLastError(ERROR_INTERNET_TIMEOUT);
-            goto lend;
-        }
-    }
-
-lend:
-    if (bSuccess)
-    {
-        lpszBuffer[nRecv] = '\0';
-       *dwLen = nRecv - 1;
-        TRACE(":%d %s\n", nRecv, lpszBuffer);
-        return lpszBuffer;
-    }
-    else
-    {
-        return NULL;
-    }
-}
-
 /**********************************************************
  *     InternetQueryDataAvailable (WININET.@)
  *
index 6bafbfa..7d0cac8 100644 (file)
@@ -98,7 +98,7 @@ typedef struct {
     INTERNET_PORT port;
     BOOL is_https;
     struct sockaddr_storage addr;
-    socklen_t addr_len;
+    int addr_len;
     char addr_str[INET6_ADDRSTRLEN];
 
     WCHAR *scheme_host_port;
@@ -402,8 +402,11 @@ typedef struct
     LPWSTR statusText;
     DWORD bytesToWrite;
     DWORD bytesWritten;
+
+    CRITICAL_SECTION headers_section;  /* section to protect the headers array */
     HTTPHEADERW *custHeaders;
     DWORD nCustHeaders;
+
     FILETIME last_modified;
     HANDLE hCacheFile;
     req_file_t *req_file;
@@ -455,8 +458,7 @@ DWORD HTTP_Connect(appinfo_t*,LPCWSTR,
         LPCWSTR lpszPassword, DWORD dwFlags, DWORD_PTR dwContext,
         DWORD dwInternalFlags, HINTERNET*) DECLSPEC_HIDDEN;
 
-BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort,
-       struct sockaddr *psa, socklen_t *sa_len) DECLSPEC_HIDDEN;
+BOOL GetAddress(const WCHAR*,INTERNET_PORT,SOCKADDR*,int*,char*) DECLSPEC_HIDDEN;
 
 DWORD get_cookie_header(const WCHAR*,const WCHAR*,WCHAR**) DECLSPEC_HIDDEN;
 DWORD set_cookie(const WCHAR*,const WCHAR*,const WCHAR*,const WCHAR*,DWORD) DECLSPEC_HIDDEN;
@@ -465,7 +467,6 @@ void INTERNET_SetLastError(DWORD dwError) DECLSPEC_HIDDEN;
 DWORD INTERNET_GetLastError(void) DECLSPEC_HIDDEN;
 DWORD INTERNET_AsyncCall(task_header_t*) DECLSPEC_HIDDEN;
 LPSTR INTERNET_GetResponseBuffer(void) DECLSPEC_HIDDEN;
-LPSTR INTERNET_GetNextLine(INT nSocket, LPDWORD dwLen) DECLSPEC_HIDDEN;
 
 VOID SendAsyncCallback(object_header_t *hdr, DWORD_PTR dwContext,
                        DWORD dwInternetStatus, LPVOID lpvStatusInfo,
@@ -494,33 +495,7 @@ BOOL NETCON_is_alive(netconn_t*) DECLSPEC_HIDDEN;
 LPCVOID NETCON_GetCert(netconn_t *connection) DECLSPEC_HIDDEN;
 int NETCON_GetCipherStrength(netconn_t*) DECLSPEC_HIDDEN;
 DWORD NETCON_set_timeout(netconn_t *connection, BOOL send, DWORD value) DECLSPEC_HIDDEN;
-#ifndef __REACTOS__
-int sock_get_error(int) DECLSPEC_HIDDEN;
-#else
-
-#define sock_get_error(x) WSAGetLastError()
-const char *inet_ntop(int, const void *, char *, socklen_t);
-
-static inline long unix_recv(int socket, void *buffer, size_t length, int flags)
-{
-    return recv(socket, buffer, length, flags);
-}
-#define recv unix_recv
-
-static inline int unix_ioctl(int filedes, long request, void *arg)
-{
-    return ioctlsocket(filedes, request, arg);
-}
-#define ioctlsocket unix_ioctl
-
-static inline int unix_getsockopt(int socket, int level, int option_name, void *option_value, socklen_t *option_len)
-{
-    return getsockopt(socket, level, option_name, option_value, option_len);
-}
-#define getsockopt unix_getsockopt
-
-#endif /* !__REACTOS__ */
-
+int sock_get_error(void) DECLSPEC_HIDDEN;
 int sock_send(int fd, const void *msg, size_t len, int flags) DECLSPEC_HIDDEN;
 int sock_recv(int fd, void *msg, size_t len, int flags) DECLSPEC_HIDDEN;
 
@@ -539,6 +514,8 @@ BOOL init_urlcache(void) DECLSPEC_HIDDEN;
 void free_urlcache(void) DECLSPEC_HIDDEN;
 void free_cookie(void) DECLSPEC_HIDDEN;
 
+void init_winsock(void) DECLSPEC_HIDDEN;
+
 #define MAX_REPLY_LEN          0x5B4
 
 /* Used for debugging - maybe need to be shared in the Wine debugging code ? */
index 5366c60..55b1bfe 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Wininet - networking layer. Uses unix sockets.
+ * Wininet - networking layer
  *
  * Copyright 2002 TransGaming Technologies Inc.
  * Copyright 2013 Jacek Caban for CodeWeavers
 
 #include <errno.h>
 
-#define RESPONSE_TIMEOUT        30            /* FROM internet.c */
-
-#ifdef MSG_DONTWAIT
-#define WINE_MSG_DONTWAIT MSG_DONTWAIT
-#else
-#define WINE_MSG_DONTWAIT 0
-#endif
-
-/* FIXME!!!!!!
- *    This should use winsock - To use winsock the functions will have to change a bit
- *        as they are designed for unix sockets.
- */
-
 static DWORD netconn_verify_cert(netconn_t *conn, PCCERT_CONTEXT cert, HCERTSTORE store)
 {
     BOOL ret;
@@ -62,6 +49,7 @@ static DWORD netconn_verify_cert(netconn_t *conn, PCCERT_CONTEXT cert, HCERTSTOR
         CERT_TRUST_IS_NOT_TIME_VALID |
         CERT_TRUST_IS_UNTRUSTED_ROOT |
         CERT_TRUST_IS_PARTIAL_CHAIN |
+        CERT_TRUST_IS_NOT_SIGNATURE_VALID |
         CERT_TRUST_IS_NOT_VALID_FOR_USAGE;
 
     TRACE("verifying %s\n", debugstr_w(conn->server->name));
@@ -128,6 +116,17 @@ static DWORD netconn_verify_cert(netconn_t *conn, PCCERT_CONTEXT cert, HCERTSTOR
             errors &= ~CERT_TRUST_IS_PARTIAL_CHAIN;
         }
 
+        if(errors & CERT_TRUST_IS_NOT_SIGNATURE_VALID) {
+            WARN("CERT_TRUST_IS_NOT_SIGNATURE_VALID\n");
+            if(!(conn->security_flags & SECURITY_FLAG_IGNORE_UNKNOWN_CA)) {
+                err = conn->mask_errors && err ? ERROR_INTERNET_SEC_CERT_ERRORS : ERROR_INTERNET_INVALID_CA;
+                if(!conn->mask_errors)
+                    break;
+                conn->security_flags |= _SECURITY_FLAG_CERT_INVALID_CA;
+            }
+            errors &= ~CERT_TRUST_IS_NOT_SIGNATURE_VALID;
+        }
+
         if(errors & CERT_TRUST_IS_NOT_VALID_FOR_USAGE) {
             WARN("CERT_TRUST_IS_NOT_VALID_FOR_USAGE\n");
             if(!(conn->security_flags & SECURITY_FLAG_IGNORE_WRONG_USAGE)) {
@@ -253,43 +252,65 @@ static BOOL ensure_cred_handle(void)
     return TRUE;
 }
 
+static BOOL winsock_loaded = FALSE;
+
+static BOOL WINAPI winsock_startup(INIT_ONCE *once, void *param, void **context)
+{
+    WSADATA wsa_data;
+    DWORD res;
+
+    res = WSAStartup(MAKEWORD(1,1), &wsa_data);
+    if(res == ERROR_SUCCESS)
+        winsock_loaded = TRUE;
+    else
+        ERR("WSAStartup failed: %u\n", res);
+    return TRUE;
+}
+
+void init_winsock(void)
+{
+    static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
+    InitOnceExecuteOnce(&init_once, winsock_startup, NULL, NULL);
+}
+
+static void set_socket_blocking(int socket, blocking_mode_t mode)
+{
+    ULONG arg = mode == BLOCKING_DISALLOW;
+    ioctlsocket(socket, FIONBIO, &arg);
+}
+
 static DWORD create_netconn_socket(server_t *server, netconn_t *netconn, DWORD timeout)
 {
     int result;
     ULONG flag;
+    DWORD res;
+
+    init_winsock();
 
     assert(server->addr_len);
     result = netconn->socket = socket(server->addr.ss_family, SOCK_STREAM, 0);
     if(result != -1) {
-        flag = 1;
-        ioctlsocket(netconn->socket, FIONBIO, &flag);
+        set_socket_blocking(netconn->socket, BLOCKING_DISALLOW);
         result = connect(netconn->socket, (struct sockaddr*)&server->addr, server->addr_len);
         if(result == -1)
         {
-            if (sock_get_error(errno) == WSAEINPROGRESS) {
-                /* ReactOS: use select instead of poll */
-                fd_set outfd;
-                struct timeval tv;
+            res = sock_get_error();
+            if (res == WSAEINPROGRESS || res == WSAEWOULDBLOCK) {
+                FD_SET set;
                 int res;
+                socklen_t len = sizeof(res);
+                TIMEVAL timeout_timeval = {0, timeout*1000};
 
-                FD_ZERO(&outfd);
-                FD_SET(netconn->socket, &outfd);
-                tv.tv_sec = timeout / 1000;
-                tv.tv_usec = (timeout % 1000) * 1000;
-                res = select(0, NULL, &outfd, NULL, &tv);
-                if (!res)
-                {
+                FD_ZERO(&set);
+                FD_SET(netconn->socket, &set);
+                res = select(netconn->socket+1, NULL, &set, NULL, &timeout_timeval);
+                if(!res || res == SOCKET_ERROR) {
                     closesocket(netconn->socket);
                     netconn->socket = -1;
                     return ERROR_INTERNET_CANNOT_CONNECT;
                 }
-                else if (res > 0)
-                {
-                    int err;
-                    socklen_t len = sizeof(err);
-                    if (!getsockopt(netconn->socket, SOL_SOCKET, SO_ERROR, (void *)&err, &len) && !err)
-                        result = 0;
-                }
+                if (!getsockopt(netconn->socket, SOL_SOCKET, SO_ERROR, (void *)&res, &len) && !res)
+                    result = 0;
             }
         }
         if(result == -1)
@@ -298,19 +319,16 @@ static DWORD create_netconn_socket(server_t *server, netconn_t *netconn, DWORD t
             netconn->socket = -1;
         }
         else {
-            flag = 0;
-            ioctlsocket(netconn->socket, FIONBIO, &flag);
+            set_socket_blocking(netconn->socket, BLOCKING_ALLOW);
         }
     }
     if(result == -1)
         return ERROR_INTERNET_CANNOT_CONNECT;
 
-#ifdef TCP_NODELAY
     flag = 1;
     result = setsockopt(netconn->socket, IPPROTO_TCP, TCP_NODELAY, (void*)&flag, sizeof(flag));
     if(result < 0)
         WARN("setsockopt(TCP_NODELAY) failed\n");
-#endif
 
     return ERROR_SUCCESS;
 }
@@ -381,76 +399,14 @@ void NETCON_unload(void)
     if(have_compat_cred_handle)
         FreeCredentialsHandle(&compat_cred_handle);
     DeleteCriticalSection(&init_sechandle_cs);
+    WSACleanup();
 }
 
-#ifndef __REACTOS__
 /* translate a unix error code into a winsock one */
-int sock_get_error( int err )
+int sock_get_error(void)
 {
-#if !defined(__MINGW32__) && !defined (_MSC_VER)
-    switch (err)
-    {
-        case EINTR:             return WSAEINTR;
-        case EBADF:             return WSAEBADF;
-        case EPERM:
-        case EACCES:            return WSAEACCES;
-        case EFAULT:            return WSAEFAULT;
-        case EINVAL:            return WSAEINVAL;
-        case EMFILE:            return WSAEMFILE;
-        case EWOULDBLOCK:       return WSAEWOULDBLOCK;
-        case EINPROGRESS:       return WSAEINPROGRESS;
-        case EALREADY:          return WSAEALREADY;
-        case ENOTSOCK:          return WSAENOTSOCK;
-        case EDESTADDRREQ:      return WSAEDESTADDRREQ;
-        case EMSGSIZE:          return WSAEMSGSIZE;
-        case EPROTOTYPE:        return WSAEPROTOTYPE;
-        case ENOPROTOOPT:       return WSAENOPROTOOPT;
-        case EPROTONOSUPPORT:   return WSAEPROTONOSUPPORT;
-        case ESOCKTNOSUPPORT:   return WSAESOCKTNOSUPPORT;
-        case EOPNOTSUPP:        return WSAEOPNOTSUPP;
-        case EPFNOSUPPORT:      return WSAEPFNOSUPPORT;
-        case EAFNOSUPPORT:      return WSAEAFNOSUPPORT;
-        case EADDRINUSE:        return WSAEADDRINUSE;
-        case EADDRNOTAVAIL:     return WSAEADDRNOTAVAIL;
-        case ENETDOWN:          return WSAENETDOWN;
-        case ENETUNREACH:       return WSAENETUNREACH;
-        case ENETRESET:         return WSAENETRESET;
-        case ECONNABORTED:      return WSAECONNABORTED;
-        case EPIPE:
-        case ECONNRESET:        return WSAECONNRESET;
-        case ENOBUFS:           return WSAENOBUFS;
-        case EISCONN:           return WSAEISCONN;
-        case ENOTCONN:          return WSAENOTCONN;
-        case ESHUTDOWN:         return WSAESHUTDOWN;
-        case ETOOMANYREFS:      return WSAETOOMANYREFS;
-        case ETIMEDOUT:         return WSAETIMEDOUT;
-        case ECONNREFUSED:      return WSAECONNREFUSED;
-        case ELOOP:             return WSAELOOP;
-        case ENAMETOOLONG:      return WSAENAMETOOLONG;
-        case EHOSTDOWN:         return WSAEHOSTDOWN;
-        case EHOSTUNREACH:      return WSAEHOSTUNREACH;
-        case ENOTEMPTY:         return WSAENOTEMPTY;
-#ifdef EPROCLIM
-        case EPROCLIM:          return WSAEPROCLIM;
-#endif
-#ifdef EUSERS
-        case EUSERS:            return WSAEUSERS;
-#endif
-#ifdef EDQUOT
-        case EDQUOT:            return WSAEDQUOT;
-#endif
-#ifdef ESTALE
-        case ESTALE:            return WSAESTALE;
-#endif
-#ifdef EREMOTE
-        case EREMOTE:           return WSAEREMOTE;
-#endif
-    default: errno=err; perror("sock_set_error"); return WSAEFAULT;
-    }
-#endif
-    return err;
+    return WSAGetLastError();
 }
-#endif /* !__REACTOS__ */
 
 int sock_send(int fd, const void *msg, size_t len, int flags)
 {
@@ -459,7 +415,7 @@ int sock_send(int fd, const void *msg, size_t len, int flags)
     {
         ret = send(fd, msg, len, flags);
     }
-    while(ret == -1 && errno == EINTR);
+    while(ret == -1 && sock_get_error() == WSAEINTR);
     return ret;
 }
 
@@ -470,18 +426,10 @@ int sock_recv(int fd, void *msg, size_t len, int flags)
     {
         ret = recv(fd, msg, len, flags);
     }
-    while(ret == -1 && errno == EINTR);
+    while(ret == -1 && sock_get_error() == WSAEINTR);
     return ret;
 }
 
-static void set_socket_blocking(int socket, blocking_mode_t mode)
-{
-#if defined(__MINGW32__) || defined (_MSC_VER)
-    ULONG arg = mode == BLOCKING_DISALLOW;
-    ioctlsocket(socket, FIONBIO, &arg);
-#endif
-}
-
 static DWORD netcon_secure_connect_setup(netconn_t *connection, BOOL compat_mode)
 {
     SecBuffer out_buf = {0, SECBUFFER_TOKEN, NULL}, in_bufs[2] = {{0, SECBUFFER_TOKEN}, {0, SECBUFFER_EMPTY}};
@@ -715,9 +663,7 @@ DWORD NETCON_send(netconn_t *connection, const void *msg, size_t len, int flags,
     if(!connection->secure)
     {
        *sent = sock_send(connection->socket, msg, len, flags);
-       if (*sent == -1)
-           return sock_get_error(errno);
-        return ERROR_SUCCESS;
+        return *sent == -1 ? sock_get_error() : ERROR_SUCCESS;
     }
     else
     {
@@ -766,10 +712,10 @@ static BOOL read_ssl_chunk(netconn_t *conn, void *buf, SIZE_T buf_size, blocking
 
     tmp_mode = buf_len ? BLOCKING_DISALLOW : mode;
     set_socket_blocking(conn->socket, tmp_mode);
-    size = sock_recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, tmp_mode == BLOCKING_ALLOW ? 0 : WINE_MSG_DONTWAIT);
+    size = sock_recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, 0);
     if(size < 0) {
         if(!buf_len) {
-            if(errno == EAGAIN || errno == EWOULDBLOCK) {
+            if(sock_get_error() == WSAEWOULDBLOCK) {
                 TRACE("would block\n");
                 return WSAEWOULDBLOCK;
             }
@@ -807,9 +753,9 @@ static BOOL read_ssl_chunk(netconn_t *conn, void *buf, SIZE_T buf_size, blocking
             assert(buf_len < ssl_buf_size);
 
             set_socket_blocking(conn->socket, mode);
-            size = sock_recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, mode == BLOCKING_ALLOW ? 0 : WINE_MSG_DONTWAIT);
+            size = sock_recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, 0);
             if(size < 1) {
-                if(size < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
+                if(size < 0 && sock_get_error() == WSAEWOULDBLOCK) {
                     TRACE("would block\n");
 
                     /* FIXME: Optimize extra_buf usage. */
@@ -879,20 +825,12 @@ DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, blocking_mode_t
     {
         int flags = 0;
 
-        switch(mode) {
-        case BLOCKING_ALLOW:
-            break;
-        case BLOCKING_DISALLOW:
-            flags = WINE_MSG_DONTWAIT;
-            break;
-        case BLOCKING_WAITALL:
+        if(mode == BLOCKING_WAITALL)
             flags = MSG_WAITALL;
-            break;
-        }
 
         set_socket_blocking(connection->socket, mode);
        *recvd = sock_recv(connection->socket, buf, len, flags);
-       return *recvd == -1 ? sock_get_error(errno) :  ERROR_SUCCESS;
+       return *recvd == -1 ? sock_get_error() :  ERROR_SUCCESS;
     }
     else
     {
@@ -956,7 +894,6 @@ BOOL NETCON_query_data_available(netconn_t *connection, DWORD *available)
 
     if(!connection->secure)
     {
-#ifdef FIONREAD
         ULONG unread;
         int retval = ioctlsocket(connection->socket, FIONREAD, &unread);
         if (!retval)
@@ -964,7 +901,6 @@ BOOL NETCON_query_data_available(netconn_t *connection, DWORD *available)
             TRACE("%d bytes of queued, but unread data\n", unread);
             *available += unread;
         }
-#endif
     }
     else
     {
@@ -975,32 +911,14 @@ BOOL NETCON_query_data_available(netconn_t *connection, DWORD *available)
 
 BOOL NETCON_is_alive(netconn_t *netconn)
 {
-#ifdef MSG_DONTWAIT
-    ssize_t len;
-    BYTE b;
-
-    len = sock_recv(netconn->socket, &b, 1, MSG_PEEK|MSG_DONTWAIT);
-    return len == 1 || (len == -1 && errno == EWOULDBLOCK);
-#elif defined(__MINGW32__) || defined(_MSC_VER)
-    ULONG mode;
     int len;
     char b;
 
-    mode = 1;
-    if(!ioctlsocket(netconn->socket, FIONBIO, &mode))
-        return FALSE;
-
+    set_socket_blocking(netconn->socket, BLOCKING_DISALLOW);
     len = sock_recv(netconn->socket, &b, 1, MSG_PEEK);
+    set_socket_blocking(netconn->socket, BLOCKING_ALLOW);
 
-    mode = 0;
-    if(!ioctlsocket(netconn->socket, FIONBIO, &mode))
-        return FALSE;
-
-    return len == 1 || (len == -1 && errno == WSAEWOULDBLOCK);
-#else
-    FIXME("not supported on this platform\n");
-    return TRUE;
-#endif
+    return len == 1 || (len == -1 && sock_get_error() == WSAEWOULDBLOCK);
 }
 
 LPCVOID NETCON_GetCert(netconn_t *connection)
@@ -1047,8 +965,8 @@ DWORD NETCON_set_timeout(netconn_t *connection, BOOL send, DWORD value)
                         sizeof(tv));
     if (result == -1)
     {
-        WARN("setsockopt failed (%s)\n", strerror(errno));
-        return sock_get_error(errno);
+        WARN("setsockopt failed\n");
+        return sock_get_error();
     }
     return ERROR_SUCCESS;
 }
index f39aa2c..3a22eb3 100644 (file)
@@ -1205,7 +1205,6 @@ static void dos_date_time_to_file_time(WORD fatdate, WORD fattime,
 
 static int urlcache_decode_url(const char *url, WCHAR *decoded_url, int decoded_len)
 {
-#ifndef __REACTOS__ /* FIXME: Vista+ */
     URL_COMPONENTSA uc;
     DWORD len, part_len;
     WCHAR *host_name;
@@ -1217,10 +1216,8 @@ static int urlcache_decode_url(const char *url, WCHAR *decoded_url, int decoded_
         uc.nScheme = INTERNET_SCHEME_UNKNOWN;
 
     if(uc.nScheme!=INTERNET_SCHEME_HTTP && uc.nScheme!=INTERNET_SCHEME_HTTPS)
-#endif
         return MultiByteToWideChar(CP_UTF8, 0, url, -1, decoded_url, decoded_len);
 
-#ifndef __REACTOS__ /* FIXME: Vista+ */
     if(!decoded_url)
         decoded_len = 0;
 
@@ -1257,7 +1254,6 @@ static int urlcache_decode_url(const char *url, WCHAR *decoded_url, int decoded_
     len += part_len;
 
     return len;
-#endif /* !__REACTOS__ */
 }
 
 /***********************************************************************
@@ -1873,7 +1869,6 @@ BOOL WINAPI GetUrlCacheEntryInfoA(LPCSTR lpszUrlName,
 
 static int urlcache_encode_url(const WCHAR *url, char *encoded_url, int encoded_len)
 {
-#ifndef __REACTOS__ /* FIXME: Vista+ */
     URL_COMPONENTSW uc;
     DWORD len, part_len;
     WCHAR *punycode;
@@ -1887,10 +1882,8 @@ static int urlcache_encode_url(const WCHAR *url, char *encoded_url, int encoded_
         uc.nScheme = INTERNET_SCHEME_UNKNOWN;
 
     if(uc.nScheme!=INTERNET_SCHEME_HTTP && uc.nScheme!=INTERNET_SCHEME_HTTPS)
-#endif
         return WideCharToMultiByte(CP_UTF8, 0, url, -1, encoded_url, encoded_len, NULL, NULL);
 
-#ifndef __REACTOS__ /* FIXME: Vista+ */
     len = WideCharToMultiByte(CP_UTF8, 0, url, uc.lpszHostName-url,
             encoded_url, encoded_len, NULL, NULL);
     if(!len)
@@ -1931,7 +1924,6 @@ static int urlcache_encode_url(const WCHAR *url, char *encoded_url, int encoded_
 
     TRACE("got (%d)%s\n", len, debugstr_a(encoded_url));
     return len;
-#endif /* !__REACTOS__ */
 }
 
 static BOOL urlcache_encode_url_alloc(const WCHAR *url, char **encoded_url)
index 826418d..ad441d7 100644 (file)
 
 #include "internet.h"
 
-#ifndef HAVE_GETADDRINFO
-
-/* critical section to protect non-reentrant gethostbyname() */
-static CRITICAL_SECTION cs_gethostbyname;
-static CRITICAL_SECTION_DEBUG critsect_debug =
-{
-    0, 0, &cs_gethostbyname,
-    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
-      0, 0, { (DWORD_PTR)(__FILE__ ": cs_gethostbyname") }
-};
-static CRITICAL_SECTION cs_gethostbyname = { &critsect_debug, -1, 0, 0, 0, 0 };
-
-#endif
+// ReactOS
+#include "inet_ntop.c"
 
 #define TIME_STRING_LEN  30
 
@@ -124,62 +113,36 @@ time_t ConvertTimeString(LPCWSTR asctime)
 }
 
 
-BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort,
-       struct sockaddr *psa, socklen_t *sa_len)
+BOOL GetAddress(const WCHAR *name, INTERNET_PORT port, struct sockaddr *psa, int *sa_len, char *addr_str)
 {
-    WCHAR *found;
-    char *name;
-    int len, sz;
-#ifdef HAVE_GETADDRINFO
-    struct addrinfo *res, hints;
+    ADDRINFOW *res, hints;
+    void *addr = NULL;
     int ret;
-#else
-    struct hostent *phe;
-    struct sockaddr_in *sin = (struct sockaddr_in *)psa;
-#endif
-
-    TRACE("%s\n", debugstr_w(lpszServerName));
 
-    /* Validate server name first
-     * Check if there is something like
-     * pinger.macromedia.com:80
-     * if yes, eliminate the :80....
-     */
-    found = strchrW(lpszServerName, ':');
-    if (found)
-        len = found - lpszServerName;
-    else
-        len = strlenW(lpszServerName);
+    TRACE("%s\n", debugstr_w(name));
 
-    sz = WideCharToMultiByte( CP_UNIXCP, 0, lpszServerName, len, NULL, 0, NULL, NULL );
-    if (!(name = heap_alloc(sz + 1))) return FALSE;
-    WideCharToMultiByte( CP_UNIXCP, 0, lpszServerName, len, name, sz, NULL, NULL );
-    name[sz] = 0;
-
-#ifdef HAVE_GETADDRINFO
-    memset( &hints, 0, sizeof(struct addrinfo) );
+    memset( &hints, 0, sizeof(hints) );
     /* Prefer IPv4 to IPv6 addresses, since some servers do not listen on
      * their IPv6 addresses even though they have IPv6 addresses in the DNS.
      */
     hints.ai_family = AF_INET;
 
-    ret = getaddrinfo( name, NULL, &hints, &res );
+    ret = GetAddrInfoW(name, NULL, &hints, &res);
     if (ret != 0)
     {
-        TRACE("failed to get IPv4 address of %s (%s), retrying with IPv6\n", debugstr_w(lpszServerName), gai_strerror(ret));
+        TRACE("failed to get IPv4 address of %s, retrying with IPv6\n", debugstr_w(name));
         hints.ai_family = AF_INET6;
-        ret = getaddrinfo( name, NULL, &hints, &res );
+        ret = GetAddrInfoW(name, NULL, &hints, &res);
     }
-    heap_free( name );
     if (ret != 0)
     {
-        TRACE("failed to get address of %s (%s)\n", debugstr_w(lpszServerName), gai_strerror(ret));
+        TRACE("failed to get address of %s\n", debugstr_w(name));
         return FALSE;
     }
     if (*sa_len < res->ai_addrlen)
     {
         WARN("address too small\n");
-        freeaddrinfo( res );
+        FreeAddrInfoW(res);
         return FALSE;
     }
     *sa_len = res->ai_addrlen;
@@ -188,39 +151,18 @@ BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort,
     switch (res->ai_family)
     {
     case AF_INET:
-        ((struct sockaddr_in *)psa)->sin_port = htons(nServerPort);
+        addr = &((struct sockaddr_in *)psa)->sin_addr;
+        ((struct sockaddr_in *)psa)->sin_port = htons(port);
         break;
     case AF_INET6:
-        ((struct sockaddr_in6 *)psa)->sin6_port = htons(nServerPort);
+        addr = &((struct sockaddr_in6 *)psa)->sin6_addr;
+        ((struct sockaddr_in6 *)psa)->sin6_port = htons(port);
         break;
     }
 
-    freeaddrinfo( res );
-#else
-    EnterCriticalSection( &cs_gethostbyname );
-    phe = gethostbyname(name);
-    heap_free( name );
-
-    if (NULL == phe)
-    {
-        TRACE("failed to get address of %s (%d)\n", debugstr_w(lpszServerName), h_errno);
-        LeaveCriticalSection( &cs_gethostbyname );
-        return FALSE;
-    }
-    if (*sa_len < sizeof(struct sockaddr_in))
-    {
-        WARN("address too small\n");
-        LeaveCriticalSection( &cs_gethostbyname );
-        return FALSE;
-    }
-    *sa_len = sizeof(struct sockaddr_in);
-    memset(sin,0,sizeof(struct sockaddr_in));
-    memcpy((char *)&sin->sin_addr, phe->h_addr, phe->h_length);
-    sin->sin_family = phe->h_addrtype;
-    sin->sin_port = htons(nServerPort);
-
-    LeaveCriticalSection( &cs_gethostbyname );
-#endif
+    if(addr_str)
+        inet_ntop(res->ai_family, addr, addr_str, INET6_ADDRSTRLEN);
+    FreeAddrInfoW(res);
     return TRUE;
 }
 
index 6ef13a9..e6aa470 100644 (file)
@@ -207,7 +207,7 @@ reactos/dll/win32/windowscodecsext    # Synced to Wine-1.7.27
 reactos/dll/win32/winemp3.acm         # Synced to Wine-1.7.27
 reactos/dll/win32/wing32              # Out of sync
 reactos/dll/win32/winhttp             # Synced to WineStaging-1.7.37
-reactos/dll/win32/wininet             # Synced to Wine-1.7.27
+reactos/dll/win32/wininet             # Synced to WineStaging-1.7.37
 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