- implemented support for https protocol
- fixes to the http protocol
This commit is contained in:
parent
4ee8290b96
commit
852c7ae404
133
configure
vendored
133
configure
vendored
@ -6672,7 +6672,6 @@ done
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
XFILES=""
|
XFILES=""
|
||||||
|
|
||||||
OPENGLFILES=""
|
OPENGLFILES=""
|
||||||
@ -12848,6 +12847,136 @@ cat >>confdefs.h <<_ACEOF
|
|||||||
#define SONAME_LIBJACK "$ac_cv_lib_soname_jack"
|
#define SONAME_LIBJACK "$ac_cv_lib_soname_jack"
|
||||||
_ACEOF
|
_ACEOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo "$as_me:$LINENO: checking for -lssl soname" >&5
|
||||||
|
echo $ECHO_N "checking for -lssl soname... $ECHO_C" >&6
|
||||||
|
if test "${ac_cv_lib_soname_ssl+set}" = set; then
|
||||||
|
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||||
|
else
|
||||||
|
ac_get_soname_save_LIBS=$LIBS
|
||||||
|
LIBS="-lssl $LIBS"
|
||||||
|
cat >conftest.$ac_ext <<_ACEOF
|
||||||
|
#line $LINENO "configure"
|
||||||
|
/* confdefs.h. */
|
||||||
|
_ACEOF
|
||||||
|
cat confdefs.h >>conftest.$ac_ext
|
||||||
|
cat >>conftest.$ac_ext <<_ACEOF
|
||||||
|
/* end confdefs.h. */
|
||||||
|
|
||||||
|
/* Override any gcc2 internal prototype to avoid an error. */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
#endif
|
||||||
|
/* We use char because int might match the return type of a gcc2
|
||||||
|
builtin and then its argument prototype would still apply. */
|
||||||
|
char SSL_library_init ();
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
SSL_library_init ();
|
||||||
|
;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_ACEOF
|
||||||
|
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||||
|
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||||
|
(eval $ac_link) 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); } &&
|
||||||
|
{ ac_try='test -s conftest$ac_exeext'
|
||||||
|
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||||
|
(eval $ac_try) 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); }; }; then
|
||||||
|
ac_cv_lib_soname_ssl=`$ac_cv_path_LDD conftest$ac_exeext | grep libssl\\.so | sed 's/^[ ]*\([^ ]*\)[ ]*=>.*$/\1/'`
|
||||||
|
if test "x$ac_cv_lib_soname_ssl" = "x"
|
||||||
|
then
|
||||||
|
ac_cv_lib_soname_ssl="libssl.so"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "$as_me: failed program was:" >&5
|
||||||
|
sed 's/^/| /' conftest.$ac_ext >&5
|
||||||
|
|
||||||
|
ac_cv_lib_soname_ssl="libssl.so"
|
||||||
|
fi
|
||||||
|
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
|
||||||
|
LIBS=$ac_get_soname_save_LIBS
|
||||||
|
fi
|
||||||
|
echo "$as_me:$LINENO: result: $ac_cv_lib_soname_ssl" >&5
|
||||||
|
echo "${ECHO_T}$ac_cv_lib_soname_ssl" >&6
|
||||||
|
if test "x$ac_cv_lib_soname_ssl" != xNONE
|
||||||
|
then
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define SONAME_LIBSSL "$ac_cv_lib_soname_ssl"
|
||||||
|
_ACEOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$as_me:$LINENO: checking for -lcrypto soname" >&5
|
||||||
|
echo $ECHO_N "checking for -lcrypto soname... $ECHO_C" >&6
|
||||||
|
if test "${ac_cv_lib_soname_crypto+set}" = set; then
|
||||||
|
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||||
|
else
|
||||||
|
ac_get_soname_save_LIBS=$LIBS
|
||||||
|
LIBS="-lcrypto $LIBS"
|
||||||
|
cat >conftest.$ac_ext <<_ACEOF
|
||||||
|
#line $LINENO "configure"
|
||||||
|
/* confdefs.h. */
|
||||||
|
_ACEOF
|
||||||
|
cat confdefs.h >>conftest.$ac_ext
|
||||||
|
cat >>conftest.$ac_ext <<_ACEOF
|
||||||
|
/* end confdefs.h. */
|
||||||
|
|
||||||
|
/* Override any gcc2 internal prototype to avoid an error. */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
#endif
|
||||||
|
/* We use char because int might match the return type of a gcc2
|
||||||
|
builtin and then its argument prototype would still apply. */
|
||||||
|
char BIO_new_socket ();
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
BIO_new_socket ();
|
||||||
|
;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_ACEOF
|
||||||
|
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||||
|
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||||
|
(eval $ac_link) 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); } &&
|
||||||
|
{ ac_try='test -s conftest$ac_exeext'
|
||||||
|
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||||
|
(eval $ac_try) 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); }; }; then
|
||||||
|
ac_cv_lib_soname_crypto=`$ac_cv_path_LDD conftest$ac_exeext | grep libcrypto\\.so | sed 's/^[ ]*\([^ ]*\)[ ]*=>.*$/\1/'`
|
||||||
|
if test "x$ac_cv_lib_soname_crypto" = "x"
|
||||||
|
then
|
||||||
|
ac_cv_lib_soname_crypto="libcrypto.so"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "$as_me: failed program was:" >&5
|
||||||
|
sed 's/^/| /' conftest.$ac_ext >&5
|
||||||
|
|
||||||
|
ac_cv_lib_soname_crypto="libcrypto.so"
|
||||||
|
fi
|
||||||
|
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
|
||||||
|
LIBS=$ac_get_soname_save_LIBS
|
||||||
|
fi
|
||||||
|
echo "$as_me:$LINENO: result: $ac_cv_lib_soname_crypto" >&5
|
||||||
|
echo "${ECHO_T}$ac_cv_lib_soname_crypto" >&6
|
||||||
|
if test "x$ac_cv_lib_soname_crypto" != xNONE
|
||||||
|
then
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define SONAME_LIBCRYPTO "$ac_cv_lib_soname_crypto"
|
||||||
|
_ACEOF
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
@ -13443,6 +13572,7 @@ done
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for ac_header in \
|
for ac_header in \
|
||||||
@ -13473,6 +13603,7 @@ for ac_header in \
|
|||||||
netinet/in_systm.h \
|
netinet/in_systm.h \
|
||||||
netinet/tcp.h \
|
netinet/tcp.h \
|
||||||
netinet/tcp_fsm.h \
|
netinet/tcp_fsm.h \
|
||||||
|
openssl/ssl.h \
|
||||||
pty.h \
|
pty.h \
|
||||||
pwd.h \
|
pwd.h \
|
||||||
regex.h \
|
regex.h \
|
||||||
|
@ -161,7 +161,6 @@ AC_CHECK_HEADERS(gif_lib.h,
|
|||||||
[AC_DEFINE(HAVE_LIBGIF,1)
|
[AC_DEFINE(HAVE_LIBGIF,1)
|
||||||
GIFLIB="-lgif"])]))
|
GIFLIB="-lgif"])]))
|
||||||
|
|
||||||
|
|
||||||
AC_SUBST(XLIB)
|
AC_SUBST(XLIB)
|
||||||
AC_SUBST(XFILES)
|
AC_SUBST(XFILES)
|
||||||
XFILES=""
|
XFILES=""
|
||||||
@ -910,6 +909,8 @@ then
|
|||||||
WINE_GET_SONAME(GL,glXQueryExtension,[$X_LIBS $X_EXTRA_LIBS])
|
WINE_GET_SONAME(GL,glXQueryExtension,[$X_LIBS $X_EXTRA_LIBS])
|
||||||
WINE_GET_SONAME(cups,cupsGetDefault)
|
WINE_GET_SONAME(cups,cupsGetDefault)
|
||||||
WINE_GET_SONAME(jack,jack_client_new)
|
WINE_GET_SONAME(jack,jack_client_new)
|
||||||
|
WINE_GET_SONAME(ssl,SSL_library_init)
|
||||||
|
WINE_GET_SONAME(crypto,BIO_new_socket)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
@ -1004,6 +1005,7 @@ AC_CHECK_HEADERS(\
|
|||||||
netinet/in_systm.h \
|
netinet/in_systm.h \
|
||||||
netinet/tcp.h \
|
netinet/tcp.h \
|
||||||
netinet/tcp_fsm.h \
|
netinet/tcp_fsm.h \
|
||||||
|
openssl/ssl.h \
|
||||||
pty.h \
|
pty.h \
|
||||||
pwd.h \
|
pwd.h \
|
||||||
regex.h \
|
regex.h \
|
||||||
|
@ -11,9 +11,11 @@ LDDLLFLAGS = @LDDLLFLAGS@
|
|||||||
SYMBOLFILE = $(MODULE).tmp.o
|
SYMBOLFILE = $(MODULE).tmp.o
|
||||||
|
|
||||||
C_SRCS = \
|
C_SRCS = \
|
||||||
|
cookie.c \
|
||||||
ftp.c \
|
ftp.c \
|
||||||
http.c \
|
http.c \
|
||||||
internet.c \
|
internet.c \
|
||||||
|
netconnection.c \
|
||||||
urlcache.c \
|
urlcache.c \
|
||||||
utility.c \
|
utility.c \
|
||||||
wininet_main.c
|
wininet_main.c
|
||||||
|
490
dlls/wininet/cookie.c
Normal file
490
dlls/wininet/cookie.c
Normal file
@ -0,0 +1,490 @@
|
|||||||
|
/*
|
||||||
|
* Wininet - cookie handling stuff
|
||||||
|
*
|
||||||
|
* Copyright 2002 TransGaming Technologies Inc.
|
||||||
|
*
|
||||||
|
* David Hammerton
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "windef.h"
|
||||||
|
#include "winbase.h"
|
||||||
|
#include "wininet.h"
|
||||||
|
#include "winerror.h"
|
||||||
|
|
||||||
|
#include "wine/debug.h"
|
||||||
|
#include "internet.h"
|
||||||
|
|
||||||
|
#define RESPONSE_TIMEOUT 30 /* FROM internet.c */
|
||||||
|
|
||||||
|
|
||||||
|
WINE_DEFAULT_DEBUG_CHANNEL(wininet);
|
||||||
|
|
||||||
|
/* FIXME
|
||||||
|
* Cookies are currently memory only.
|
||||||
|
* Cookies are NOT THREAD SAFE
|
||||||
|
* Cookies could use ALOT OF MEMORY. We need some kind of memory management here!
|
||||||
|
* Cookies should care about the expiry time
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct _cookie_domain cookie_domain;
|
||||||
|
typedef struct _cookie cookie;
|
||||||
|
|
||||||
|
struct _cookie
|
||||||
|
{
|
||||||
|
struct _cookie *next;
|
||||||
|
struct _cookie *prev;
|
||||||
|
|
||||||
|
struct _cookie_domain *parent;
|
||||||
|
|
||||||
|
LPSTR lpCookieName;
|
||||||
|
LPSTR lpCookieData;
|
||||||
|
time_t expiry; /* FIXME: not used */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _cookie_domain
|
||||||
|
{
|
||||||
|
struct _cookie_domain *next;
|
||||||
|
struct _cookie_domain *prev;
|
||||||
|
|
||||||
|
LPSTR lpCookieDomain;
|
||||||
|
LPSTR lpCookiePath;
|
||||||
|
cookie *cookie_tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
static cookie_domain *cookieDomainTail;
|
||||||
|
|
||||||
|
static cookie *COOKIE_addCookie(cookie_domain *domain, LPCSTR name, LPCSTR data);
|
||||||
|
static cookie *COOKIE_findCookie(cookie_domain *domain, LPCSTR lpszCookieName);
|
||||||
|
static void COOKIE_deleteCookie(cookie *deadCookie, BOOL deleteDomain);
|
||||||
|
static cookie_domain *COOKIE_addDomain(LPCSTR domain, LPCSTR path);
|
||||||
|
static cookie_domain *COOKIE_addDomainFromUrl(LPCSTR lpszUrl);
|
||||||
|
static cookie_domain *COOKIE_findNextDomain(LPCSTR lpszCookieDomain, LPCSTR lpszCookiePath,
|
||||||
|
cookie_domain *prev_domain, BOOL allow_partial);
|
||||||
|
static cookie_domain *COOKIE_findNextDomainFromUrl(LPCSTR lpszUrl, cookie_domain *prev_domain,
|
||||||
|
BOOL allow_partial);
|
||||||
|
static void COOKIE_deleteDomain(cookie_domain *deadDomain);
|
||||||
|
|
||||||
|
|
||||||
|
/* adds a cookie to the domain */
|
||||||
|
static cookie *COOKIE_addCookie(cookie_domain *domain, LPCSTR name, LPCSTR data)
|
||||||
|
{
|
||||||
|
cookie *newCookie = HeapAlloc(GetProcessHeap(), 0, sizeof(cookie));
|
||||||
|
|
||||||
|
newCookie->next = NULL;
|
||||||
|
newCookie->prev = NULL;
|
||||||
|
newCookie->lpCookieName = NULL;
|
||||||
|
newCookie->lpCookieData = NULL;
|
||||||
|
|
||||||
|
if (name)
|
||||||
|
{
|
||||||
|
newCookie->lpCookieName = HeapAlloc(GetProcessHeap(), 0, strlen(name) + 1);
|
||||||
|
strcpy(newCookie->lpCookieName, name);
|
||||||
|
}
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
newCookie->lpCookieData = HeapAlloc(GetProcessHeap(), 0, strlen(data) + 1);
|
||||||
|
strcpy(newCookie->lpCookieData, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("added cookie %p (data is %s)\n", newCookie, data);
|
||||||
|
|
||||||
|
newCookie->prev = domain->cookie_tail;
|
||||||
|
newCookie->parent = domain;
|
||||||
|
domain->cookie_tail = newCookie;
|
||||||
|
return newCookie;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* finds a cookie in the domain matching the cookie name */
|
||||||
|
static cookie *COOKIE_findCookie(cookie_domain *domain, LPCSTR lpszCookieName)
|
||||||
|
{
|
||||||
|
cookie *searchCookie = domain->cookie_tail;
|
||||||
|
TRACE("(%p, %s)\n", domain, debugstr_a(lpszCookieName));
|
||||||
|
|
||||||
|
while (searchCookie)
|
||||||
|
{
|
||||||
|
BOOL candidate = TRUE;
|
||||||
|
if (candidate && lpszCookieName)
|
||||||
|
{
|
||||||
|
if (candidate && !searchCookie->lpCookieName)
|
||||||
|
candidate = FALSE;
|
||||||
|
if (candidate && strcmp(lpszCookieName, searchCookie->lpCookieName) != 0)
|
||||||
|
candidate = FALSE;
|
||||||
|
}
|
||||||
|
if (candidate)
|
||||||
|
return searchCookie;
|
||||||
|
searchCookie = searchCookie->prev;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* removes a cookie from the list, if its the last cookie we also remove the domain */
|
||||||
|
static void COOKIE_deleteCookie(cookie *deadCookie, BOOL deleteDomain)
|
||||||
|
{
|
||||||
|
if (deadCookie->lpCookieName)
|
||||||
|
HeapFree(GetProcessHeap(), 0, deadCookie->lpCookieName);
|
||||||
|
if (deadCookie->lpCookieData)
|
||||||
|
HeapFree(GetProcessHeap(), 0, deadCookie->lpCookieData);
|
||||||
|
if (deadCookie->prev)
|
||||||
|
deadCookie->prev->next = deadCookie->next;
|
||||||
|
if (deadCookie->next)
|
||||||
|
deadCookie->next->prev = deadCookie->prev;
|
||||||
|
|
||||||
|
if (deadCookie == deadCookie->parent->cookie_tail)
|
||||||
|
{
|
||||||
|
/* special case: last cookie, lets remove the domain to save memory */
|
||||||
|
deadCookie->parent->cookie_tail = deadCookie->prev;
|
||||||
|
if (!deadCookie->parent->cookie_tail && deleteDomain)
|
||||||
|
COOKIE_deleteDomain(deadCookie->parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocates a domain and adds it to the end */
|
||||||
|
static cookie_domain *COOKIE_addDomain(LPCSTR domain, LPCSTR path)
|
||||||
|
{
|
||||||
|
cookie_domain *newDomain = HeapAlloc(GetProcessHeap(), 0, sizeof(cookie_domain));
|
||||||
|
|
||||||
|
newDomain->next = NULL;
|
||||||
|
newDomain->prev = NULL;
|
||||||
|
newDomain->cookie_tail = NULL;
|
||||||
|
newDomain->lpCookieDomain = NULL;
|
||||||
|
newDomain->lpCookiePath = NULL;
|
||||||
|
|
||||||
|
if (domain)
|
||||||
|
{
|
||||||
|
newDomain->lpCookieDomain = HeapAlloc(GetProcessHeap(), 0, strlen(domain) + 1);
|
||||||
|
strcpy(newDomain->lpCookieDomain, domain);
|
||||||
|
}
|
||||||
|
if (path)
|
||||||
|
{
|
||||||
|
newDomain->lpCookiePath = HeapAlloc(GetProcessHeap(), 0, strlen(path) + 1);
|
||||||
|
strcpy(newDomain->lpCookiePath, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
newDomain->prev = cookieDomainTail;
|
||||||
|
cookieDomainTail = newDomain;
|
||||||
|
TRACE("Adding domain: %p\n", newDomain);
|
||||||
|
return newDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cookie_domain *COOKIE_addDomainFromUrl(LPCSTR lpszUrl)
|
||||||
|
{
|
||||||
|
char hostName[2048], path[2048];
|
||||||
|
URL_COMPONENTSA UrlComponents;
|
||||||
|
|
||||||
|
UrlComponents.lpszExtraInfo = NULL;
|
||||||
|
UrlComponents.lpszPassword = NULL;
|
||||||
|
UrlComponents.lpszScheme = NULL;
|
||||||
|
UrlComponents.lpszUrlPath = path;
|
||||||
|
UrlComponents.lpszUserName = NULL;
|
||||||
|
UrlComponents.lpszHostName = hostName;
|
||||||
|
UrlComponents.dwHostNameLength = 2048;
|
||||||
|
UrlComponents.dwUrlPathLength = 2048;
|
||||||
|
|
||||||
|
InternetCrackUrlA(lpszUrl, 0, 0, &UrlComponents);
|
||||||
|
|
||||||
|
TRACE("Url cracked. Domain: %s, Path: %s.\n", debugstr_a(UrlComponents.lpszHostName),
|
||||||
|
debugstr_a(UrlComponents.lpszUrlPath));
|
||||||
|
|
||||||
|
/* hack for now - FIXME - There seems to be a bug in InternetCrackUrl?? */
|
||||||
|
UrlComponents.lpszUrlPath = NULL;
|
||||||
|
|
||||||
|
return COOKIE_addDomain(UrlComponents.lpszHostName, UrlComponents.lpszUrlPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find a domain. domain must match if its not NULL. path must match if its not NULL */
|
||||||
|
static cookie_domain *COOKIE_findNextDomain(LPCSTR lpszCookieDomain, LPCSTR lpszCookiePath,
|
||||||
|
cookie_domain *prev_domain, BOOL allow_partial)
|
||||||
|
{
|
||||||
|
cookie_domain *searchDomain;
|
||||||
|
|
||||||
|
if (prev_domain)
|
||||||
|
{
|
||||||
|
if(!prev_domain->prev)
|
||||||
|
{
|
||||||
|
TRACE("no more domains available, it would seem.\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
searchDomain = prev_domain->prev;
|
||||||
|
}
|
||||||
|
else searchDomain = cookieDomainTail;
|
||||||
|
|
||||||
|
while (searchDomain)
|
||||||
|
{
|
||||||
|
BOOL candidate = TRUE;
|
||||||
|
TRACE("searching on domain %p\n", searchDomain);
|
||||||
|
if (candidate && lpszCookieDomain)
|
||||||
|
{
|
||||||
|
if (candidate && !searchDomain->lpCookieDomain)
|
||||||
|
candidate = FALSE;
|
||||||
|
TRACE("candidate! (%p)\n", searchDomain->lpCookieDomain);
|
||||||
|
TRACE("comparing domain %s with %s\n", lpszCookieDomain, searchDomain->lpCookieDomain);
|
||||||
|
if (candidate && allow_partial && !strstr(lpszCookieDomain, searchDomain->lpCookieDomain))
|
||||||
|
candidate = FALSE;
|
||||||
|
else if (candidate && !allow_partial &&
|
||||||
|
strcmp(lpszCookieDomain, searchDomain->lpCookieDomain) != 0)
|
||||||
|
candidate = FALSE;
|
||||||
|
}
|
||||||
|
if (candidate && lpszCookiePath)
|
||||||
|
{ TRACE("comparing paths\n");
|
||||||
|
if (candidate && !searchDomain->lpCookiePath)
|
||||||
|
candidate = FALSE;
|
||||||
|
if (candidate && strcmp(lpszCookiePath, searchDomain->lpCookiePath) != 0)
|
||||||
|
candidate = FALSE;
|
||||||
|
}
|
||||||
|
if (candidate)
|
||||||
|
{
|
||||||
|
TRACE("returning the domain %p\n", searchDomain);
|
||||||
|
return searchDomain;
|
||||||
|
}
|
||||||
|
searchDomain = searchDomain->prev;
|
||||||
|
}
|
||||||
|
TRACE("found no domain, returning NULL\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cookie_domain *COOKIE_findNextDomainFromUrl(LPCSTR lpszUrl, cookie_domain *previous_domain,
|
||||||
|
BOOL allow_partial)
|
||||||
|
{
|
||||||
|
char hostName[2048], path[2048];
|
||||||
|
URL_COMPONENTSA UrlComponents;
|
||||||
|
|
||||||
|
UrlComponents.lpszExtraInfo = NULL;
|
||||||
|
UrlComponents.lpszPassword = NULL;
|
||||||
|
UrlComponents.lpszScheme = NULL;
|
||||||
|
UrlComponents.lpszUrlPath = path;
|
||||||
|
UrlComponents.lpszUserName = NULL;
|
||||||
|
UrlComponents.lpszHostName = hostName;
|
||||||
|
UrlComponents.dwHostNameLength = 2048;
|
||||||
|
UrlComponents.dwUrlPathLength = 2048;
|
||||||
|
|
||||||
|
InternetCrackUrlA(lpszUrl, 0, 0, &UrlComponents);
|
||||||
|
|
||||||
|
TRACE("Url cracked. Domain: %s, Path: %s.\n", debugstr_a(UrlComponents.lpszHostName),
|
||||||
|
debugstr_a(UrlComponents.lpszUrlPath));
|
||||||
|
|
||||||
|
/* hack for now - FIXME - There seems to be a bug in InternetCrackUrl?? */
|
||||||
|
UrlComponents.lpszUrlPath = NULL;
|
||||||
|
|
||||||
|
return COOKIE_findNextDomain(UrlComponents.lpszHostName, UrlComponents.lpszUrlPath,
|
||||||
|
previous_domain, allow_partial);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remove a domain from the list and delete it */
|
||||||
|
static void COOKIE_deleteDomain(cookie_domain *deadDomain)
|
||||||
|
{
|
||||||
|
while (deadDomain->cookie_tail)
|
||||||
|
COOKIE_deleteCookie(deadDomain->cookie_tail, FALSE);
|
||||||
|
if (deadDomain->lpCookieDomain)
|
||||||
|
HeapFree(GetProcessHeap(), 0, deadDomain->lpCookieDomain);
|
||||||
|
if (deadDomain->lpCookiePath)
|
||||||
|
HeapFree(GetProcessHeap(), 0, deadDomain->lpCookiePath);
|
||||||
|
if (deadDomain->prev)
|
||||||
|
deadDomain->prev->next = deadDomain->next;
|
||||||
|
if (deadDomain->next)
|
||||||
|
deadDomain->next->prev = deadDomain->prev;
|
||||||
|
|
||||||
|
if (cookieDomainTail == deadDomain)
|
||||||
|
cookieDomainTail = deadDomain->prev;
|
||||||
|
HeapFree(GetProcessHeap(), 0, deadDomain);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* InternetGetCookieA (WININET.@)
|
||||||
|
*
|
||||||
|
* Retrieve cookie from the specified url
|
||||||
|
*
|
||||||
|
* It should be noted that on windows the lpszCookieName parameter is "not implemented".
|
||||||
|
* So it won't be implemented here.
|
||||||
|
*
|
||||||
|
* RETURNS
|
||||||
|
* TRUE on success
|
||||||
|
* FALSE on failure
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
BOOL WINAPI InternetGetCookieA(LPCSTR lpszUrl, LPCSTR lpszCookieName,
|
||||||
|
LPSTR lpCookieData, LPDWORD lpdwSize)
|
||||||
|
{
|
||||||
|
cookie_domain *cookiesDomain = NULL;
|
||||||
|
cookie *thisCookie;
|
||||||
|
int cnt = 0, domain_count = 0;
|
||||||
|
/* Ok, this is just ODD!. During my tests, it appears M$ like to send out
|
||||||
|
* a cookie called 'MtrxTracking' to some urls. Also returns it from InternetGetCookie.
|
||||||
|
* I'm not exactly sure what to make of this, so its here for now.
|
||||||
|
* It'd be nice to know what exactly is going on, M$ tracking users? Does this need
|
||||||
|
* to be unique? Should I generate a random number here? etc.
|
||||||
|
*/
|
||||||
|
char *TrackingString = "MtrxTrackingID=01234567890123456789012345678901";
|
||||||
|
|
||||||
|
TRACE("(%s, %s, %p, %p)\n", debugstr_a(lpszUrl),debugstr_a(lpszCookieName),
|
||||||
|
lpCookieData, lpdwSize);
|
||||||
|
|
||||||
|
if (lpCookieData)
|
||||||
|
cnt += snprintf(lpCookieData + cnt, *lpdwSize - cnt, "%s", TrackingString);
|
||||||
|
else
|
||||||
|
cnt += strlen(TrackingString);
|
||||||
|
|
||||||
|
while ((cookiesDomain = COOKIE_findNextDomainFromUrl(lpszUrl, cookiesDomain, TRUE)))
|
||||||
|
{
|
||||||
|
domain_count++;
|
||||||
|
TRACE("found domain %p\n", cookiesDomain);
|
||||||
|
|
||||||
|
thisCookie = cookiesDomain->cookie_tail;
|
||||||
|
if (lpCookieData == NULL) /* return the size of the buffer required to lpdwSize */
|
||||||
|
{
|
||||||
|
while (thisCookie)
|
||||||
|
{
|
||||||
|
cnt += 2; /* '; ' */
|
||||||
|
cnt += strlen(thisCookie->lpCookieName);
|
||||||
|
cnt += 1; /* = */
|
||||||
|
cnt += strlen(thisCookie->lpCookieData);
|
||||||
|
|
||||||
|
thisCookie = thisCookie->prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (thisCookie)
|
||||||
|
{
|
||||||
|
cnt += snprintf(lpCookieData + cnt, *lpdwSize - cnt, "; ");
|
||||||
|
cnt += snprintf(lpCookieData + cnt, *lpdwSize - cnt, "%s=%s", thisCookie->lpCookieName,
|
||||||
|
thisCookie->lpCookieData);
|
||||||
|
|
||||||
|
thisCookie = thisCookie->prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lpCookieData == NULL)
|
||||||
|
{
|
||||||
|
cnt += 1; /* NULL */
|
||||||
|
*lpdwSize = cnt;
|
||||||
|
TRACE("returning\n");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!domain_count)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
*lpdwSize = cnt + 1;
|
||||||
|
|
||||||
|
TRACE("Returning %i (from %i domains): %s\n", cnt, domain_count, lpCookieData);
|
||||||
|
|
||||||
|
return (cnt ? TRUE : FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* InternetGetCookieW (WININET.@)
|
||||||
|
*
|
||||||
|
* Retrieve cookie from the specified url
|
||||||
|
*
|
||||||
|
* RETURNS
|
||||||
|
* TRUE on success
|
||||||
|
* FALSE on failure
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
BOOL WINAPI InternetGetCookieW(LPCSTR lpszUrl, LPCWSTR lpszCookieName,
|
||||||
|
LPWSTR lpCookieData, LPDWORD lpdwSize)
|
||||||
|
{
|
||||||
|
FIXME("STUB\n");
|
||||||
|
TRACE("(%s,%s,%p)\n", debugstr_a(lpszUrl), debugstr_w(lpszCookieName),
|
||||||
|
lpCookieData);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* InternetSetCookieA (WININET.@)
|
||||||
|
*
|
||||||
|
* Sets cookie for the specified url
|
||||||
|
*
|
||||||
|
* RETURNS
|
||||||
|
* TRUE on success
|
||||||
|
* FALSE on failure
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
BOOL WINAPI InternetSetCookieA(LPCSTR lpszUrl, LPCSTR lpszCookieName,
|
||||||
|
LPCSTR lpCookieData)
|
||||||
|
{
|
||||||
|
cookie *thisCookie;
|
||||||
|
cookie_domain *thisCookieDomain;
|
||||||
|
|
||||||
|
TRACE("(%s,%s,%s)\n", debugstr_a(lpszUrl),
|
||||||
|
debugstr_a(lpszCookieName), lpCookieData);
|
||||||
|
|
||||||
|
if (!lpCookieData || !strlen(lpCookieData))
|
||||||
|
{
|
||||||
|
TRACE("no cookie data, not adding\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (!lpszCookieName)
|
||||||
|
{
|
||||||
|
/* some apps (or is it us??) try to add a cookie with no cookie name, but
|
||||||
|
* the cookie data in the form of name=data. */
|
||||||
|
/* FIXME, probably a bug here, for now I don't care */
|
||||||
|
char *ourCookieName, *ourCookieData;
|
||||||
|
int ourCookieNameSize;
|
||||||
|
BOOL ret;
|
||||||
|
if (!(ourCookieData = strchr(lpCookieData, '=')))
|
||||||
|
{
|
||||||
|
TRACE("something terribly wrong with cookie data %s\n", ourCookieData);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
ourCookieNameSize = ourCookieData - lpCookieData;
|
||||||
|
ourCookieData += 1;
|
||||||
|
ourCookieName = HeapAlloc(GetProcessHeap(), 0, ourCookieNameSize + 1);
|
||||||
|
strncpy(ourCookieName, ourCookieData, ourCookieNameSize);
|
||||||
|
ourCookieName[ourCookieNameSize] = '\0';
|
||||||
|
TRACE("setting (hacked) cookie of %s, %s\n", ourCookieName, ourCookieData);
|
||||||
|
ret = InternetSetCookieA(lpszUrl, ourCookieName, ourCookieData);
|
||||||
|
HeapFree(GetProcessHeap(), 0, ourCookieName);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(thisCookieDomain = COOKIE_findNextDomainFromUrl(lpszUrl, NULL, FALSE)))
|
||||||
|
thisCookieDomain = COOKIE_addDomainFromUrl(lpszUrl);
|
||||||
|
|
||||||
|
if ((thisCookie = COOKIE_findCookie(thisCookieDomain, lpszCookieName)))
|
||||||
|
COOKIE_deleteCookie(thisCookie, FALSE);
|
||||||
|
|
||||||
|
thisCookie = COOKIE_addCookie(thisCookieDomain, lpszCookieName, lpCookieData);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* InternetSetCookieW (WININET.@)
|
||||||
|
*
|
||||||
|
* Sets cookie for the specified url
|
||||||
|
*
|
||||||
|
* RETURNS
|
||||||
|
* TRUE on success
|
||||||
|
* FALSE on failure
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
BOOL WINAPI InternetSetCookieW(LPCSTR lpszUrl, LPCWSTR lpszCookieName,
|
||||||
|
LPCWSTR lpCookieData)
|
||||||
|
{
|
||||||
|
FIXME("STUB\n");
|
||||||
|
TRACE("(%s,%s,%s)\n", debugstr_a(lpszUrl),
|
||||||
|
debugstr_w(lpszCookieName), debugstr_w(lpCookieData));
|
||||||
|
return FALSE;
|
||||||
|
}
|
@ -3,9 +3,11 @@
|
|||||||
*
|
*
|
||||||
* Copyright 1999 Corel Corporation
|
* Copyright 1999 Corel Corporation
|
||||||
* Copyright 2002 CodeWeavers Inc.
|
* Copyright 2002 CodeWeavers Inc.
|
||||||
|
* Copyright 2002 TransGaming Technologies Inc.
|
||||||
*
|
*
|
||||||
* Ulrich Czekalla
|
* Ulrich Czekalla
|
||||||
* Aric Stewart
|
* Aric Stewart
|
||||||
|
* David Hammerton
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@ -111,7 +113,9 @@ BOOL WINAPI HttpAddRequestHeadersA(HINTERNET hHttpRequest,
|
|||||||
BOOL bSuccess = FALSE;
|
BOOL bSuccess = FALSE;
|
||||||
LPWININETHTTPREQA lpwhr = (LPWININETHTTPREQA) hHttpRequest;
|
LPWININETHTTPREQA lpwhr = (LPWININETHTTPREQA) hHttpRequest;
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("%p, %s, %li, %li\n", hHttpRequest, lpszHeader, dwHeaderLength,
|
||||||
|
dwModifier);
|
||||||
|
|
||||||
|
|
||||||
if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ)
|
if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ)
|
||||||
{
|
{
|
||||||
@ -121,6 +125,8 @@ BOOL WINAPI HttpAddRequestHeadersA(HINTERNET hHttpRequest,
|
|||||||
|
|
||||||
if (!lpszHeader)
|
if (!lpszHeader)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
TRACE("copying header: %s\n", lpszHeader);
|
||||||
buffer = HTTP_strdup(lpszHeader);
|
buffer = HTTP_strdup(lpszHeader);
|
||||||
lpszStart = buffer;
|
lpszStart = buffer;
|
||||||
|
|
||||||
@ -140,6 +146,7 @@ BOOL WINAPI HttpAddRequestHeadersA(HINTERNET hHttpRequest,
|
|||||||
|
|
||||||
*lpszEnd = '\0';
|
*lpszEnd = '\0';
|
||||||
|
|
||||||
|
TRACE("interpreting header %s\n", debugstr_a(lpszStart));
|
||||||
if (HTTP_InterpretHttpHeader(lpszStart, field, MAX_FIELD_LEN, value, MAX_FIELD_VALUE_LEN))
|
if (HTTP_InterpretHttpHeader(lpszStart, field, MAX_FIELD_LEN, value, MAX_FIELD_VALUE_LEN))
|
||||||
bSuccess = HTTP_ProcessHeader(lpwhr, field, value, dwModifier | HTTP_ADDHDR_FLAG_REQ);
|
bSuccess = HTTP_ProcessHeader(lpwhr, field, value, dwModifier | HTTP_ADDHDR_FLAG_REQ);
|
||||||
|
|
||||||
@ -203,7 +210,10 @@ HINTERNET WINAPI HttpOpenRequestA(HINTERNET hHttpSession,
|
|||||||
LPWININETHTTPSESSIONA lpwhs = (LPWININETHTTPSESSIONA) hHttpSession;
|
LPWININETHTTPSESSIONA lpwhs = (LPWININETHTTPSESSIONA) hHttpSession;
|
||||||
LPWININETAPPINFOA hIC = NULL;
|
LPWININETAPPINFOA hIC = NULL;
|
||||||
|
|
||||||
TRACE("(%s, %s, %s, %s, %ld, %ld)\n", lpszVerb, lpszObjectName, lpszVersion, lpszReferrer, dwFlags, dwContext);
|
TRACE("(%p, %s, %s, %s, %s, %p, %08lx, %08lx)\n", hHttpSession,
|
||||||
|
debugstr_a(lpszVerb), lpszObjectName,
|
||||||
|
debugstr_a(lpszVersion), debugstr_a(lpszReferrer), lpszAcceptTypes,
|
||||||
|
dwFlags, dwContext);
|
||||||
if(lpszAcceptTypes!=NULL)
|
if(lpszAcceptTypes!=NULL)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -249,15 +259,20 @@ HINTERNET WINAPI HttpOpenRequestA(HINTERNET hHttpSession,
|
|||||||
workRequest.DWCONTEXT = dwContext;
|
workRequest.DWCONTEXT = dwContext;
|
||||||
|
|
||||||
INTERNET_AsyncCall(&workRequest);
|
INTERNET_AsyncCall(&workRequest);
|
||||||
|
TRACE ("returning NULL\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return HTTP_HttpOpenRequestA(hHttpSession, lpszVerb, lpszObjectName,
|
HINTERNET rec = HTTP_HttpOpenRequestA(hHttpSession, lpszVerb, lpszObjectName,
|
||||||
lpszVersion, lpszReferrer, lpszAcceptTypes, dwFlags, dwContext);
|
lpszVersion, lpszReferrer, lpszAcceptTypes,
|
||||||
|
dwFlags, dwContext);
|
||||||
|
TRACE("returning %p\n", rec);
|
||||||
|
return rec;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* HttpOpenRequestW (WININET.@)
|
* HttpOpenRequestW (WININET.@)
|
||||||
*
|
*
|
||||||
@ -267,27 +282,95 @@ HINTERNET WINAPI HttpOpenRequestA(HINTERNET hHttpSession,
|
|||||||
* HINTERNET a HTTP request handle on success
|
* HINTERNET a HTTP request handle on success
|
||||||
* NULL on failure
|
* NULL on failure
|
||||||
*
|
*
|
||||||
|
* FIXME: This should be the other way around (A should call W)
|
||||||
*/
|
*/
|
||||||
HINTERNET WINAPI HttpOpenRequestW(HINTERNET hHttpSession,
|
HINTERNET WINAPI HttpOpenRequestW(HINTERNET hHttpSession,
|
||||||
LPCWSTR lpszVerb, LPCWSTR lpszObjectName, LPCWSTR lpszVersion,
|
LPCWSTR lpszVerb, LPCWSTR lpszObjectName, LPCWSTR lpszVersion,
|
||||||
LPCWSTR lpszReferrer , LPCWSTR *lpszAcceptTypes,
|
LPCWSTR lpszReferrer , LPCWSTR *lpszAcceptTypes,
|
||||||
DWORD dwFlags, DWORD dwContext)
|
DWORD dwFlags, DWORD dwContext)
|
||||||
{
|
{
|
||||||
char szVerb[20],
|
CHAR *szVerb = NULL, *szObjectName = NULL;
|
||||||
szObjectName[INTERNET_MAX_PATH_LENGTH];
|
CHAR *szVersion = NULL, *szReferrer = NULL, **szAcceptTypes = NULL;
|
||||||
TRACE("(%s, %s, %s, %s, %ld, %ld)\n", debugstr_w(lpszVerb), debugstr_w(lpszObjectName), debugstr_w(lpszVersion), debugstr_w(lpszReferrer), dwFlags, dwContext);
|
INT len;
|
||||||
|
INT acceptTypesCount;
|
||||||
|
HINTERNET rc = FALSE;
|
||||||
|
TRACE("(%p, %s, %s, %s, %s, %p, %08lx, %08lx)\n", hHttpSession,
|
||||||
|
debugstr_w(lpszVerb), debugstr_w(lpszObjectName),
|
||||||
|
debugstr_w(lpszVersion), debugstr_w(lpszReferrer), lpszAcceptTypes,
|
||||||
|
dwFlags, dwContext);
|
||||||
|
|
||||||
if(lpszVerb!=NULL)
|
if (lpszVerb)
|
||||||
WideCharToMultiByte(CP_ACP,0,lpszVerb,-1,szVerb,20,NULL,NULL);
|
{
|
||||||
else
|
len = lstrlenW(lpszVerb)+1;
|
||||||
szVerb[0]=0;
|
if (!(szVerb = (CHAR *) HeapAlloc(GetProcessHeap(), 0, len * sizeof(CHAR))))
|
||||||
if(lpszObjectName!=NULL)
|
goto end;
|
||||||
WideCharToMultiByte(CP_ACP,0,lpszObjectName,-1,szObjectName,INTERNET_MAX_PATH_LENGTH,NULL,NULL);
|
WideCharToMultiByte(CP_ACP, -1, lpszVerb, -1, szVerb, len, NULL, NULL);
|
||||||
else
|
}
|
||||||
szObjectName[0]=0;
|
|
||||||
TRACE("object name=%s\n",szObjectName);
|
if (lpszObjectName)
|
||||||
FIXME("lpszVersion, lpszReferrer and lpszAcceptTypes ignored\n");
|
{
|
||||||
return HttpOpenRequestA(hHttpSession, szVerb[0]?szVerb:NULL, szObjectName, NULL, NULL, NULL, dwFlags, dwContext);
|
len = lstrlenW(lpszObjectName)+1;
|
||||||
|
if (!(szObjectName = (CHAR *) HeapAlloc(GetProcessHeap(), 0, len * sizeof(CHAR))))
|
||||||
|
goto end;
|
||||||
|
WideCharToMultiByte(CP_ACP, -1, lpszObjectName, -1, szObjectName, len, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpszVersion)
|
||||||
|
{
|
||||||
|
len = lstrlenW(lpszVersion)+1;
|
||||||
|
if (!(szVersion = (CHAR *) HeapAlloc(GetProcessHeap(), 0, len * sizeof(CHAR))))
|
||||||
|
goto end;
|
||||||
|
WideCharToMultiByte(CP_ACP, -1, lpszVersion, -1, szVersion, len, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpszReferrer)
|
||||||
|
{
|
||||||
|
len = lstrlenW(lpszReferrer)+1;
|
||||||
|
if (!(szReferrer = (CHAR *) HeapAlloc(GetProcessHeap(), 0, len * sizeof(CHAR))))
|
||||||
|
goto end;
|
||||||
|
WideCharToMultiByte(CP_ACP, -1, lpszReferrer, -1, szReferrer, len, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
acceptTypesCount = 0;
|
||||||
|
if (lpszAcceptTypes)
|
||||||
|
{
|
||||||
|
while (lpszAcceptTypes[acceptTypesCount]) { acceptTypesCount++; } /* find out how many there are */
|
||||||
|
szAcceptTypes = HeapAlloc(GetProcessHeap(), 0, sizeof(CHAR *) * acceptTypesCount);
|
||||||
|
acceptTypesCount = 0;
|
||||||
|
while (lpszAcceptTypes[acceptTypesCount])
|
||||||
|
{
|
||||||
|
len = lstrlenW(lpszAcceptTypes[acceptTypesCount])+1;
|
||||||
|
if (!(szAcceptTypes[acceptTypesCount] = (CHAR *) HeapAlloc(GetProcessHeap(),
|
||||||
|
0, len * sizeof(CHAR))))
|
||||||
|
goto end;
|
||||||
|
WideCharToMultiByte(CP_ACP, -1, lpszAcceptTypes[acceptTypesCount],
|
||||||
|
-1, szAcceptTypes[acceptTypesCount], len, NULL, NULL);
|
||||||
|
acceptTypesCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else szAcceptTypes = 0;
|
||||||
|
|
||||||
|
rc = HttpOpenRequestA(hHttpSession, (LPCSTR)szVerb, (LPCSTR)szObjectName,
|
||||||
|
(LPCSTR)szVersion, (LPCSTR)szReferrer,
|
||||||
|
(LPCSTR *)szAcceptTypes, dwFlags, dwContext);
|
||||||
|
|
||||||
|
end:
|
||||||
|
if (szAcceptTypes)
|
||||||
|
{
|
||||||
|
acceptTypesCount = 0;
|
||||||
|
while (szAcceptTypes[acceptTypesCount])
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, szAcceptTypes[acceptTypesCount]);
|
||||||
|
acceptTypesCount++;
|
||||||
|
}
|
||||||
|
HeapFree(GetProcessHeap(), 0, szAcceptTypes);
|
||||||
|
}
|
||||||
|
if (szReferrer) HeapFree(GetProcessHeap(), 0, szReferrer);
|
||||||
|
if (szVersion) HeapFree(GetProcessHeap(), 0, szVersion);
|
||||||
|
if (szObjectName) HeapFree(GetProcessHeap(), 0, szObjectName);
|
||||||
|
if (szVerb) HeapFree(GetProcessHeap(), 0, szVerb);
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@ -308,6 +391,9 @@ HINTERNET WINAPI HTTP_HttpOpenRequestA(HINTERNET hHttpSession,
|
|||||||
LPWININETHTTPSESSIONA lpwhs = (LPWININETHTTPSESSIONA) hHttpSession;
|
LPWININETHTTPSESSIONA lpwhs = (LPWININETHTTPSESSIONA) hHttpSession;
|
||||||
LPWININETAPPINFOA hIC = NULL;
|
LPWININETAPPINFOA hIC = NULL;
|
||||||
LPWININETHTTPREQA lpwhr;
|
LPWININETHTTPREQA lpwhr;
|
||||||
|
LPSTR lpszCookies;
|
||||||
|
LPSTR lpszUrl = NULL;
|
||||||
|
DWORD nCookieSize;
|
||||||
|
|
||||||
TRACE("--> \n");
|
TRACE("--> \n");
|
||||||
|
|
||||||
@ -330,7 +416,7 @@ HINTERNET WINAPI HTTP_HttpOpenRequestA(HINTERNET hHttpSession,
|
|||||||
lpwhr->hdr.lpwhparent = hHttpSession;
|
lpwhr->hdr.lpwhparent = hHttpSession;
|
||||||
lpwhr->hdr.dwFlags = dwFlags;
|
lpwhr->hdr.dwFlags = dwFlags;
|
||||||
lpwhr->hdr.dwContext = dwContext;
|
lpwhr->hdr.dwContext = dwContext;
|
||||||
lpwhr->nSocketFD = -1;
|
NETCON_init(&lpwhr->netConnection, dwFlags & INTERNET_FLAG_SECURE);
|
||||||
|
|
||||||
if (NULL != lpszObjectName && strlen(lpszObjectName)) {
|
if (NULL != lpszObjectName && strlen(lpszObjectName)) {
|
||||||
DWORD needed = 0;
|
DWORD needed = 0;
|
||||||
@ -348,11 +434,8 @@ HINTERNET WINAPI HTTP_HttpOpenRequestA(HINTERNET hHttpSession,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL != hIC->lpszAgent && strlen(hIC->lpszAgent))
|
|
||||||
HTTP_ProcessHeader(lpwhr, HTTP_USERAGENT, hIC->lpszAgent, HTTP_ADDHDR_FLAG_REQ|HTTP_ADDREQ_FLAG_REPLACE|HTTP_ADDHDR_FLAG_ADD_IF_NEW);
|
|
||||||
|
|
||||||
if (NULL != lpszReferrer && strlen(lpszReferrer))
|
if (NULL != lpszReferrer && strlen(lpszReferrer))
|
||||||
HTTP_ProcessHeader(lpwhr, HTTP_REFERER, lpszReferrer, HTTP_ADDHDR_FLAG_REQ|HTTP_ADDREQ_FLAG_REPLACE|HTTP_ADDHDR_FLAG_ADD_IF_NEW);
|
HTTP_ProcessHeader(lpwhr, HTTP_REFERER, lpszReferrer, HTTP_ADDHDR_FLAG_COALESCE);
|
||||||
|
|
||||||
if(lpszAcceptTypes!=NULL)
|
if(lpszAcceptTypes!=NULL)
|
||||||
{
|
{
|
||||||
@ -366,7 +449,7 @@ HINTERNET WINAPI HTTP_HttpOpenRequestA(HINTERNET hHttpSession,
|
|||||||
else if (strlen(lpszVerb))
|
else if (strlen(lpszVerb))
|
||||||
lpwhr->lpszVerb = HTTP_strdup(lpszVerb);
|
lpwhr->lpszVerb = HTTP_strdup(lpszVerb);
|
||||||
|
|
||||||
if (NULL != lpszReferrer)
|
if (NULL != lpszReferrer && strlen(lpszReferrer))
|
||||||
{
|
{
|
||||||
char buf[MAXHOSTNAME];
|
char buf[MAXHOSTNAME];
|
||||||
URL_COMPONENTSA UrlComponents;
|
URL_COMPONENTSA UrlComponents;
|
||||||
@ -420,6 +503,36 @@ HINTERNET WINAPI HTTP_HttpOpenRequestA(HINTERNET hHttpSession,
|
|||||||
lpwhr->lpszHostName = HTTP_strdup(lpwhs->lpszServerName);
|
lpwhr->lpszHostName = HTTP_strdup(lpwhs->lpszServerName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hIC->lpszAgent)
|
||||||
|
{
|
||||||
|
char *agent_header = HeapAlloc(GetProcessHeap(), 0, strlen(hIC->lpszAgent) + 1 + 14);
|
||||||
|
sprintf(agent_header, "User-Agent: %s\r\n", hIC->lpszAgent);
|
||||||
|
HttpAddRequestHeadersA((HINTERNET)lpwhr, agent_header, strlen(agent_header),
|
||||||
|
HTTP_ADDREQ_FLAG_ADD);
|
||||||
|
HeapFree(GetProcessHeap(), 0, agent_header);
|
||||||
|
}
|
||||||
|
|
||||||
|
lpszUrl = HeapAlloc(GetProcessHeap(), 0, strlen(lpwhr->lpszHostName) + 1 + 7);
|
||||||
|
sprintf(lpszUrl, "http://%s", lpwhr->lpszHostName);
|
||||||
|
if (InternetGetCookieA(lpszUrl, NULL, NULL, &nCookieSize))
|
||||||
|
{
|
||||||
|
int cnt = 0;
|
||||||
|
|
||||||
|
lpszCookies = HeapAlloc(GetProcessHeap(), 0, nCookieSize + 1 + 8);
|
||||||
|
|
||||||
|
cnt += sprintf(lpszCookies, "Cookie: ");
|
||||||
|
InternetGetCookieA(lpszUrl, NULL, lpszCookies + cnt, &nCookieSize);
|
||||||
|
cnt += nCookieSize - 1;
|
||||||
|
sprintf(lpszCookies + cnt, "\r\n");
|
||||||
|
|
||||||
|
HttpAddRequestHeadersA((HINTERNET)lpwhr, lpszCookies, strlen(lpszCookies),
|
||||||
|
HTTP_ADDREQ_FLAG_ADD);
|
||||||
|
HeapFree(GetProcessHeap(), 0, lpszCookies);
|
||||||
|
}
|
||||||
|
HeapFree(GetProcessHeap(), 0, lpszUrl);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (hIC->lpfnStatusCB)
|
if (hIC->lpfnStatusCB)
|
||||||
{
|
{
|
||||||
INTERNET_ASYNC_RESULT iar;
|
INTERNET_ASYNC_RESULT iar;
|
||||||
@ -443,7 +556,6 @@ HINTERNET WINAPI HTTP_HttpOpenRequestA(HINTERNET hHttpSession,
|
|||||||
INTERNET_STATUS_RESOLVING_NAME,
|
INTERNET_STATUS_RESOLVING_NAME,
|
||||||
lpwhs->lpszServerName,
|
lpwhs->lpszServerName,
|
||||||
strlen(lpwhs->lpszServerName)+1);
|
strlen(lpwhs->lpszServerName)+1);
|
||||||
|
|
||||||
if (!GetAddress(lpwhs->lpszServerName, lpwhs->nServerPort,
|
if (!GetAddress(lpwhs->lpszServerName, lpwhs->nServerPort,
|
||||||
&lpwhs->phostent, &lpwhs->socketAddress))
|
&lpwhs->phostent, &lpwhs->socketAddress))
|
||||||
{
|
{
|
||||||
@ -906,6 +1018,8 @@ BOOL WINAPI HTTP_HttpSendRequestA(HINTERNET hHttpRequest, LPCSTR lpszHeaders,
|
|||||||
LPWININETHTTPREQA lpwhr = (LPWININETHTTPREQA) hHttpRequest;
|
LPWININETHTTPREQA lpwhr = (LPWININETHTTPREQA) hHttpRequest;
|
||||||
LPWININETHTTPSESSIONA lpwhs = NULL;
|
LPWININETHTTPSESSIONA lpwhs = NULL;
|
||||||
LPWININETAPPINFOA hIC = NULL;
|
LPWININETAPPINFOA hIC = NULL;
|
||||||
|
BOOL loop_next = FALSE;
|
||||||
|
int CustHeaderIndex;
|
||||||
|
|
||||||
TRACE("--> 0x%08lx\n", (ULONG)hHttpRequest);
|
TRACE("--> 0x%08lx\n", (ULONG)hHttpRequest);
|
||||||
|
|
||||||
@ -940,6 +1054,11 @@ BOOL WINAPI HTTP_HttpSendRequestA(HINTERNET hHttpRequest, LPCSTR lpszHeaders,
|
|||||||
goto lend;
|
goto lend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
TRACE("Going to url %s %s\n", debugstr_a(lpwhr->lpszHostName), debugstr_a(lpwhr->lpszPath));
|
||||||
|
loop_next = FALSE;
|
||||||
|
|
||||||
/* If we don't have a path we set it to root */
|
/* If we don't have a path we set it to root */
|
||||||
if (NULL == lpwhr->lpszPath)
|
if (NULL == lpwhr->lpszPath)
|
||||||
lpwhr->lpszPath = HTTP_strdup("/");
|
lpwhr->lpszPath = HTTP_strdup("/");
|
||||||
@ -958,7 +1077,6 @@ BOOL WINAPI HTTP_HttpSendRequestA(HINTERNET hHttpRequest, LPCSTR lpszHeaders,
|
|||||||
requestStringLen =
|
requestStringLen =
|
||||||
strlen(lpwhr->lpszVerb) +
|
strlen(lpwhr->lpszVerb) +
|
||||||
strlen(lpwhr->lpszPath) +
|
strlen(lpwhr->lpszPath) +
|
||||||
(lpwhr->lpszHostName ? (strlen(HTTPHOSTHEADER) + strlen(lpwhr->lpszHostName)) : 0) +
|
|
||||||
strlen(HTTPHEADER) +
|
strlen(HTTPHEADER) +
|
||||||
5; /* " \r\n\r\n" */
|
5; /* " \r\n\r\n" */
|
||||||
|
|
||||||
@ -989,6 +1107,10 @@ BOOL WINAPI HTTP_HttpSendRequestA(HINTERNET hHttpRequest, LPCSTR lpszHeaders,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lpwhr->lpszHostName)
|
||||||
|
requestStringLen += (strlen(HTTPHOSTHEADER) + strlen(lpwhr->lpszHostName));
|
||||||
|
|
||||||
|
|
||||||
/* Allocate string to hold entire request */
|
/* Allocate string to hold entire request */
|
||||||
requestString = HeapAlloc(GetProcessHeap(), 0, requestStringLen + 1);
|
requestString = HeapAlloc(GetProcessHeap(), 0, requestStringLen + 1);
|
||||||
if (NULL == requestString)
|
if (NULL == requestString)
|
||||||
@ -998,11 +1120,10 @@ BOOL WINAPI HTTP_HttpSendRequestA(HINTERNET hHttpRequest, LPCSTR lpszHeaders,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Build request string */
|
/* Build request string */
|
||||||
cnt = sprintf(requestString, "%s %s%s%s",
|
cnt = sprintf(requestString, "%s %s%s",
|
||||||
lpwhr->lpszVerb,
|
lpwhr->lpszVerb,
|
||||||
lpwhr->lpszPath,
|
lpwhr->lpszPath,
|
||||||
lpwhr->lpszHostName ? (HTTPHEADER HTTPHOSTHEADER) : HTTPHEADER,
|
HTTPHEADER);
|
||||||
lpwhr->lpszHostName ? lpwhr->lpszHostName : "");
|
|
||||||
|
|
||||||
/* Append standard request headers */
|
/* Append standard request headers */
|
||||||
for (i = 0; i <= HTTP_QUERY_MAX; i++)
|
for (i = 0; i <= HTTP_QUERY_MAX; i++)
|
||||||
@ -1026,6 +1147,9 @@ BOOL WINAPI HTTP_HttpSendRequestA(HINTERNET hHttpRequest, LPCSTR lpszHeaders,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lpwhr->lpszHostName)
|
||||||
|
cnt += sprintf(requestString + cnt, "%s%s", HTTPHOSTHEADER, lpwhr->lpszHostName);
|
||||||
|
|
||||||
/* Append passed request headers */
|
/* Append passed request headers */
|
||||||
if (lpszHeaders)
|
if (lpszHeaders)
|
||||||
{
|
{
|
||||||
@ -1046,7 +1170,9 @@ BOOL WINAPI HTTP_HttpSendRequestA(HINTERNET hHttpRequest, LPCSTR lpszHeaders,
|
|||||||
SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext,
|
SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext,
|
||||||
INTERNET_STATUS_SENDING_REQUEST, NULL, 0);
|
INTERNET_STATUS_SENDING_REQUEST, NULL, 0);
|
||||||
|
|
||||||
cnt = send(lpwhr->nSocketFD, requestString, requestStringLen, 0);
|
NETCON_send(&lpwhr->netConnection, requestString, requestStringLen,
|
||||||
|
0, &cnt);
|
||||||
|
|
||||||
|
|
||||||
SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext,
|
SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext,
|
||||||
INTERNET_STATUS_REQUEST_SENT,
|
INTERNET_STATUS_REQUEST_SENT,
|
||||||
@ -1066,6 +1192,135 @@ BOOL WINAPI HTTP_HttpSendRequestA(HINTERNET hHttpRequest, LPCSTR lpszHeaders,
|
|||||||
INTERNET_STATUS_RESPONSE_RECEIVED, &responseLen,
|
INTERNET_STATUS_RESPONSE_RECEIVED, &responseLen,
|
||||||
sizeof(DWORD));
|
sizeof(DWORD));
|
||||||
|
|
||||||
|
/* process headers here. Is this right? */
|
||||||
|
CustHeaderIndex = HTTP_GetCustomHeaderIndex(lpwhr, "Set-Cookie");
|
||||||
|
if (CustHeaderIndex >= 0)
|
||||||
|
{
|
||||||
|
LPHTTPHEADERA setCookieHeader;
|
||||||
|
int nPosStart = 0, nPosEnd = 0;
|
||||||
|
|
||||||
|
setCookieHeader = &lpwhr->pCustHeaders[CustHeaderIndex];
|
||||||
|
|
||||||
|
while (setCookieHeader->lpszValue[nPosEnd] != '\0')
|
||||||
|
{
|
||||||
|
LPSTR buf_cookie, cookie_name, cookie_data;
|
||||||
|
LPSTR buf_url;
|
||||||
|
LPSTR domain = NULL;
|
||||||
|
int nEqualPos = 0;
|
||||||
|
while (setCookieHeader->lpszValue[nPosEnd] != ';' && setCookieHeader->lpszValue[nPosEnd] != ',' &&
|
||||||
|
setCookieHeader->lpszValue[nPosEnd] != '\0')
|
||||||
|
{
|
||||||
|
nPosEnd++;
|
||||||
|
}
|
||||||
|
if (setCookieHeader->lpszValue[nPosEnd] == ';')
|
||||||
|
{
|
||||||
|
/* fixme: not case sensitive, strcasestr is gnu only */
|
||||||
|
int nDomainPosEnd = 0;
|
||||||
|
int nDomainPosStart = 0, nDomainLength = 0;
|
||||||
|
LPSTR lpszDomain = strstr(&setCookieHeader->lpszValue[nPosEnd], "domain=");
|
||||||
|
if (lpszDomain)
|
||||||
|
{ /* they have specified their own domain, lets use it */
|
||||||
|
while (lpszDomain[nDomainPosEnd] != ';' && lpszDomain[nDomainPosEnd] != ',' &&
|
||||||
|
lpszDomain[nDomainPosEnd] != '\0')
|
||||||
|
{
|
||||||
|
nDomainPosEnd++;
|
||||||
|
}
|
||||||
|
nDomainPosStart = strlen("domain=");
|
||||||
|
nDomainLength = (nDomainPosEnd - nDomainPosStart) + 1;
|
||||||
|
domain = HeapAlloc(GetProcessHeap(), 0, nDomainLength + 1);
|
||||||
|
strncpy(domain, &lpszDomain[nDomainPosStart], nDomainLength);
|
||||||
|
domain[nDomainLength] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (setCookieHeader->lpszValue[nPosEnd] == '\0') break;
|
||||||
|
buf_cookie = HeapAlloc(GetProcessHeap(), 0, (nPosEnd - nPosStart) + 1);
|
||||||
|
strncpy(buf_cookie, &setCookieHeader->lpszValue[nPosStart], (nPosEnd - nPosStart));
|
||||||
|
buf_cookie[(nPosEnd - nPosStart)] = '\0';
|
||||||
|
TRACE("%s\n", buf_cookie);
|
||||||
|
while (buf_cookie[nEqualPos] != '=' && buf_cookie[nEqualPos] != '\0')
|
||||||
|
{
|
||||||
|
nEqualPos++;
|
||||||
|
}
|
||||||
|
if (buf_cookie[nEqualPos] == '\0' || buf_cookie[nEqualPos + 1] == '\0')
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, buf_cookie);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cookie_name = HeapAlloc(GetProcessHeap(), 0, nEqualPos + 1);
|
||||||
|
strncpy(cookie_name, buf_cookie, nEqualPos);
|
||||||
|
cookie_name[nEqualPos] = '\0';
|
||||||
|
cookie_data = &buf_cookie[nEqualPos + 1];
|
||||||
|
|
||||||
|
|
||||||
|
buf_url = HeapAlloc(GetProcessHeap(), 0, strlen((domain ? domain : lpwhr->lpszHostName)) + strlen(lpwhr->lpszPath) + 9);
|
||||||
|
sprintf(buf_url, "http://%s/", (domain ? domain : lpwhr->lpszHostName)); /* FIXME PATH!!! */
|
||||||
|
InternetSetCookieA(buf_url, cookie_name, cookie_data);
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, buf_url);
|
||||||
|
HeapFree(GetProcessHeap(), 0, buf_cookie);
|
||||||
|
HeapFree(GetProcessHeap(), 0, cookie_name);
|
||||||
|
if (domain) HeapFree(GetProcessHeap(), 0, domain);
|
||||||
|
nPosStart = nPosEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: is this right? I'm not sure if this should be here or elsewhere (the loop, too)
|
||||||
|
* FIXME: don't do this if they specify INTERNET_FLAG_NO_AUTO_REDIRECT */
|
||||||
|
if (lpwhr->StdHeaders[HTTP_QUERY_LOCATION].lpszValue)
|
||||||
|
{
|
||||||
|
URL_COMPONENTSA urlComponents;
|
||||||
|
char protocol[32], hostName[MAXHOSTNAME], userName[1024];
|
||||||
|
char password[1024], path[2048], extra[1024];
|
||||||
|
|
||||||
|
TRACE("Got a Location header: Going around to a new location: %s",
|
||||||
|
debugstr_a(lpwhr->StdHeaders[HTTP_QUERY_LOCATION].lpszValue));
|
||||||
|
|
||||||
|
urlComponents.dwStructSize = sizeof(URL_COMPONENTSA);
|
||||||
|
urlComponents.lpszScheme = protocol;
|
||||||
|
urlComponents.dwSchemeLength = 32;
|
||||||
|
urlComponents.lpszHostName = hostName;
|
||||||
|
urlComponents.dwHostNameLength = MAXHOSTNAME;
|
||||||
|
urlComponents.lpszUserName = userName;
|
||||||
|
urlComponents.dwUserNameLength = 1024;
|
||||||
|
urlComponents.lpszPassword = password;
|
||||||
|
urlComponents.dwPasswordLength = 1024;
|
||||||
|
urlComponents.lpszUrlPath = path;
|
||||||
|
urlComponents.dwUrlPathLength = 2048;
|
||||||
|
urlComponents.lpszExtraInfo = extra;
|
||||||
|
urlComponents.dwExtraInfoLength = 1024;
|
||||||
|
if (!InternetCrackUrlA(lpwhr->StdHeaders[HTTP_QUERY_LOCATION].lpszValue,
|
||||||
|
strlen(lpwhr->StdHeaders[HTTP_QUERY_LOCATION].lpszValue),
|
||||||
|
0, &urlComponents))
|
||||||
|
goto lend;
|
||||||
|
|
||||||
|
if (urlComponents.nScheme != INTERNET_SCHEME_HTTP)
|
||||||
|
{
|
||||||
|
FIXME("cannot redirect to non HTTP page\n");
|
||||||
|
goto lend;
|
||||||
|
}
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, lpwhr->lpszPath);
|
||||||
|
HeapAlloc(GetProcessHeap(), 0, strlen(path) + 1);
|
||||||
|
strcpy(lpwhr->lpszPath, path);
|
||||||
|
|
||||||
|
if (urlComponents.dwHostNameLength)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, lpwhr->lpszHostName);
|
||||||
|
HeapAlloc(GetProcessHeap(), 0, strlen(hostName) + 1);
|
||||||
|
strcpy(lpwhr->lpszHostName, hostName);
|
||||||
|
}
|
||||||
|
|
||||||
|
SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext,
|
||||||
|
INTERNET_STATUS_REDIRECT, NULL, 0);
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, lpwhr->StdHeaders[HTTP_QUERY_LOCATION].lpszValue);
|
||||||
|
lpwhr->StdHeaders[HTTP_QUERY_LOCATION].lpszValue = NULL;
|
||||||
|
loop_next = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (loop_next);
|
||||||
|
|
||||||
lend:
|
lend:
|
||||||
|
|
||||||
if (requestString)
|
if (requestString)
|
||||||
@ -1192,7 +1447,7 @@ lerror:
|
|||||||
* windows
|
* windows
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TRACE("<--\n");
|
TRACE("%p -->\n", hInternet);
|
||||||
return (HINTERNET)lpwhs;
|
return (HINTERNET)lpwhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1210,7 +1465,6 @@ TRACE("<--\n");
|
|||||||
BOOL HTTP_OpenConnection(LPWININETHTTPREQA lpwhr)
|
BOOL HTTP_OpenConnection(LPWININETHTTPREQA lpwhr)
|
||||||
{
|
{
|
||||||
BOOL bSuccess = FALSE;
|
BOOL bSuccess = FALSE;
|
||||||
INT result;
|
|
||||||
LPWININETHTTPSESSIONA lpwhs;
|
LPWININETHTTPSESSIONA lpwhs;
|
||||||
LPWININETAPPINFOA hIC = NULL;
|
LPWININETAPPINFOA hIC = NULL;
|
||||||
|
|
||||||
@ -1231,17 +1485,15 @@ BOOL HTTP_OpenConnection(LPWININETHTTPREQA lpwhr)
|
|||||||
&(lpwhs->socketAddress),
|
&(lpwhs->socketAddress),
|
||||||
sizeof(struct sockaddr_in));
|
sizeof(struct sockaddr_in));
|
||||||
|
|
||||||
lpwhr->nSocketFD = socket(lpwhs->phostent->h_addrtype,SOCK_STREAM,0);
|
if (!NETCON_create(&lpwhr->netConnection, lpwhs->phostent->h_addrtype,
|
||||||
if (lpwhr->nSocketFD == -1)
|
SOCK_STREAM, 0))
|
||||||
{
|
{
|
||||||
WARN("Socket creation failed\n");
|
WARN("Socket creation failed\n");
|
||||||
goto lend;
|
goto lend;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = connect(lpwhr->nSocketFD, (struct sockaddr *)&lpwhs->socketAddress,
|
if (!NETCON_connect(&lpwhr->netConnection, (struct sockaddr *)&lpwhs->socketAddress,
|
||||||
sizeof(lpwhs->socketAddress));
|
sizeof(lpwhs->socketAddress)))
|
||||||
|
|
||||||
if (result == -1)
|
|
||||||
{
|
{
|
||||||
WARN("Unable to connect to host (%s)\n", strerror(errno));
|
WARN("Unable to connect to host (%s)\n", strerror(errno));
|
||||||
goto lend;
|
goto lend;
|
||||||
@ -1281,19 +1533,20 @@ BOOL HTTP_GetResponseHeaders(LPWININETHTTPREQA lpwhr)
|
|||||||
|
|
||||||
TRACE("-->\n");
|
TRACE("-->\n");
|
||||||
|
|
||||||
if (lpwhr->nSocketFD == -1)
|
if (!NETCON_connected(&lpwhr->netConnection))
|
||||||
goto lend;
|
goto lend;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* HACK peek at the buffer
|
* HACK peek at the buffer
|
||||||
*/
|
*/
|
||||||
rc = recv(lpwhr->nSocketFD,buffer,buflen,MSG_PEEK);
|
NETCON_recv(&lpwhr->netConnection, buffer, buflen, MSG_PEEK, &rc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We should first receive 'HTTP/1.x nnn' where nnn is the status code.
|
* We should first receive 'HTTP/1.x nnn' where nnn is the status code.
|
||||||
*/
|
*/
|
||||||
buflen = MAX_REPLY_LEN;
|
buflen = MAX_REPLY_LEN;
|
||||||
if (!INTERNET_GetNextLine(lpwhr->nSocketFD, buffer, &buflen))
|
memset(buffer, 0, MAX_REPLY_LEN);
|
||||||
|
if (!NETCON_getNextLine(&lpwhr->netConnection, buffer, &buflen))
|
||||||
goto lend;
|
goto lend;
|
||||||
|
|
||||||
if (strncmp(buffer, "HTTP", 4) != 0)
|
if (strncmp(buffer, "HTTP", 4) != 0)
|
||||||
@ -1306,8 +1559,9 @@ BOOL HTTP_GetResponseHeaders(LPWININETHTTPREQA lpwhr)
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
buflen = MAX_REPLY_LEN;
|
buflen = MAX_REPLY_LEN;
|
||||||
if (INTERNET_GetNextLine(lpwhr->nSocketFD, buffer, &buflen))
|
if (NETCON_getNextLine(&lpwhr->netConnection, buffer, &buflen))
|
||||||
{
|
{
|
||||||
|
TRACE("got line %s, now interpretting\n", debugstr_a(buffer));
|
||||||
if (!HTTP_InterpretHttpHeader(buffer, field, MAX_FIELD_LEN, value, MAX_FIELD_VALUE_LEN))
|
if (!HTTP_InterpretHttpHeader(buffer, field, MAX_FIELD_LEN, value, MAX_FIELD_VALUE_LEN))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1637,10 +1891,9 @@ VOID HTTP_CloseConnection(LPWININETHTTPREQA lpwhr)
|
|||||||
SendAsyncCallback(hIC, lpwhr, lpwhr->hdr.dwContext,
|
SendAsyncCallback(hIC, lpwhr, lpwhr->hdr.dwContext,
|
||||||
INTERNET_STATUS_CLOSING_CONNECTION, 0, 0);
|
INTERNET_STATUS_CLOSING_CONNECTION, 0, 0);
|
||||||
|
|
||||||
if (lpwhr->nSocketFD != -1)
|
if (NETCON_connected(&lpwhr->netConnection))
|
||||||
{
|
{
|
||||||
close(lpwhr->nSocketFD);
|
NETCON_close(&lpwhr->netConnection);
|
||||||
lpwhr->nSocketFD = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SendAsyncCallback(hIC, lpwhr, lpwhr->hdr.dwContext,
|
SendAsyncCallback(hIC, lpwhr, lpwhr->hdr.dwContext,
|
||||||
@ -1662,7 +1915,7 @@ void HTTP_CloseHTTPRequestHandle(LPWININETHTTPREQA lpwhr)
|
|||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
||||||
if (lpwhr->nSocketFD != -1)
|
if (NETCON_connected(&lpwhr->netConnection))
|
||||||
HTTP_CloseConnection(lpwhr);
|
HTTP_CloseConnection(lpwhr);
|
||||||
|
|
||||||
lpwhs = (LPWININETHTTPSESSIONA) lpwhr->hdr.lpwhparent;
|
lpwhs = (LPWININETHTTPSESSIONA) lpwhr->hdr.lpwhparent;
|
||||||
@ -1709,7 +1962,7 @@ void HTTP_CloseHTTPRequestHandle(LPWININETHTTPREQA lpwhr)
|
|||||||
void HTTP_CloseHTTPSessionHandle(LPWININETHTTPSESSIONA lpwhs)
|
void HTTP_CloseHTTPSessionHandle(LPWININETHTTPSESSIONA lpwhs)
|
||||||
{
|
{
|
||||||
LPWININETAPPINFOA hIC = NULL;
|
LPWININETAPPINFOA hIC = NULL;
|
||||||
TRACE("\n");
|
TRACE("%p\n", lpwhs);
|
||||||
|
|
||||||
hIC = (LPWININETAPPINFOA) lpwhs->hdr.lpwhparent;
|
hIC = (LPWININETAPPINFOA) lpwhs->hdr.lpwhparent;
|
||||||
|
|
||||||
|
@ -3,11 +3,12 @@
|
|||||||
*
|
*
|
||||||
* Copyright 1999 Corel Corporation
|
* Copyright 1999 Corel Corporation
|
||||||
* Copyright 2002 CodeWeavers Inc.
|
* Copyright 2002 CodeWeavers Inc.
|
||||||
|
* Copyright 2002 Jaco Greeff
|
||||||
|
* Copyright 2002 TransGaming Technologies Inc.
|
||||||
*
|
*
|
||||||
* Ulrich Czekalla
|
* Ulrich Czekalla
|
||||||
* Aric Stewart
|
* Aric Stewart
|
||||||
*
|
* David Hammerton
|
||||||
* Copyright 2002 Jaco Greeff
|
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@ -222,7 +223,8 @@ HINTERNET WINAPI InternetOpenA(LPCSTR lpszAgent, DWORD dwAccessType,
|
|||||||
{
|
{
|
||||||
LPWININETAPPINFOA lpwai = NULL;
|
LPWININETAPPINFOA lpwai = NULL;
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("(%s, %li, %s, %s, %li)\n", debugstr_a(lpszAgent), dwAccessType,
|
||||||
|
debugstr_a(lpszProxy), debugstr_a(lpszProxyBypass), dwFlags);
|
||||||
|
|
||||||
/* Clear any error information */
|
/* Clear any error information */
|
||||||
INTERNET_SetLastError(0);
|
INTERNET_SetLastError(0);
|
||||||
@ -278,6 +280,7 @@ HINTERNET WINAPI InternetOpenA(LPCSTR lpszAgent, DWORD dwAccessType,
|
|||||||
lpwai->dwAccessType = dwAccessType;
|
lpwai->dwAccessType = dwAccessType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("returning %p\n", (HINTERNET)lpwai);
|
||||||
return (HINTERNET)lpwai;
|
return (HINTERNET)lpwai;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,9 +302,9 @@ HINTERNET WINAPI InternetOpenW(LPCWSTR lpszAgent, DWORD dwAccessType,
|
|||||||
INT lenAgent = lstrlenW(lpszAgent)+1;
|
INT lenAgent = lstrlenW(lpszAgent)+1;
|
||||||
INT lenProxy = lstrlenW(lpszProxy)+1;
|
INT lenProxy = lstrlenW(lpszProxy)+1;
|
||||||
INT lenBypass = lstrlenW(lpszProxyBypass)+1;
|
INT lenBypass = lstrlenW(lpszProxyBypass)+1;
|
||||||
CHAR *szAgent = (CHAR *)malloc(lenAgent*sizeof(CHAR));
|
CHAR *szAgent = (CHAR *)HeapAlloc(GetProcessHeap(), 0, lenAgent*sizeof(CHAR));
|
||||||
CHAR *szProxy = (CHAR *)malloc(lenProxy*sizeof(CHAR));
|
CHAR *szProxy = (CHAR *)HeapAlloc(GetProcessHeap(), 0, lenProxy*sizeof(CHAR));
|
||||||
CHAR *szBypass = (CHAR *)malloc(lenBypass*sizeof(CHAR));
|
CHAR *szBypass = (CHAR *)HeapAlloc(GetProcessHeap(), 0, lenBypass*sizeof(CHAR));
|
||||||
|
|
||||||
if (!szAgent || !szProxy || !szBypass)
|
if (!szAgent || !szProxy || !szBypass)
|
||||||
{
|
{
|
||||||
@ -323,9 +326,9 @@ HINTERNET WINAPI InternetOpenW(LPCWSTR lpszAgent, DWORD dwAccessType,
|
|||||||
|
|
||||||
rc = InternetOpenA(szAgent, dwAccessType, szProxy, szBypass, dwFlags);
|
rc = InternetOpenA(szAgent, dwAccessType, szProxy, szBypass, dwFlags);
|
||||||
|
|
||||||
free(szAgent);
|
HeapFree(GetProcessHeap(), 0, szAgent);
|
||||||
free(szProxy);
|
HeapFree(GetProcessHeap(), 0, szProxy);
|
||||||
free(szBypass);
|
HeapFree(GetProcessHeap(), 0, szBypass);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -422,7 +425,9 @@ HINTERNET WINAPI InternetConnectA(HINTERNET hInternet,
|
|||||||
{
|
{
|
||||||
HINTERNET rc = (HINTERNET) NULL;
|
HINTERNET rc = (HINTERNET) NULL;
|
||||||
|
|
||||||
TRACE("ServerPort %i\n",nServerPort);
|
TRACE("(%p, %s, %i, %s, %s, %li, %li, %li)\n", hInternet, debugstr_a(lpszServerName),
|
||||||
|
nServerPort, debugstr_a(lpszUserName), debugstr_a(lpszPassword),
|
||||||
|
dwService, dwFlags, dwContext);
|
||||||
|
|
||||||
/* Clear any error information */
|
/* Clear any error information */
|
||||||
INTERNET_SetLastError(0);
|
INTERNET_SetLastError(0);
|
||||||
@ -444,6 +449,7 @@ HINTERNET WINAPI InternetConnectA(HINTERNET hInternet,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("returning %p\n", rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -464,37 +470,42 @@ HINTERNET WINAPI InternetConnectW(HINTERNET hInternet,
|
|||||||
DWORD dwService, DWORD dwFlags, DWORD dwContext)
|
DWORD dwService, DWORD dwFlags, DWORD dwContext)
|
||||||
{
|
{
|
||||||
HINTERNET rc = (HINTERNET)NULL;
|
HINTERNET rc = (HINTERNET)NULL;
|
||||||
INT lenServer = lstrlenW(lpszServerName)+1;
|
INT lenServer = 0;
|
||||||
INT lenUser = lstrlenW(lpszUserName)+1;
|
INT lenUser = 0;
|
||||||
INT lenPass = lstrlenW(lpszPassword)+1;
|
INT lenPass = 0;
|
||||||
CHAR *szServerName = (CHAR *)malloc(lenServer*sizeof(CHAR));
|
CHAR *szServerName = NULL;
|
||||||
CHAR *szUserName = (CHAR *)malloc(lenUser*sizeof(CHAR));
|
CHAR *szUserName = NULL;
|
||||||
CHAR *szPassword = (CHAR *)malloc(lenPass*sizeof(CHAR));
|
CHAR *szPassword = NULL;
|
||||||
|
|
||||||
if (!szServerName || !szUserName || !szPassword)
|
if (lpszServerName)
|
||||||
{
|
{
|
||||||
if (szServerName)
|
lenServer = lstrlenW(lpszServerName)+1;
|
||||||
free(szServerName);
|
szServerName = (CHAR *)HeapAlloc(GetProcessHeap(), 0, lenServer*sizeof(CHAR));
|
||||||
if (szUserName)
|
|
||||||
free(szUserName);
|
|
||||||
if (szPassword)
|
|
||||||
free(szPassword);
|
|
||||||
return (HINTERNET)NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
WideCharToMultiByte(CP_ACP, -1, lpszServerName, -1, szServerName, lenServer,
|
WideCharToMultiByte(CP_ACP, -1, lpszServerName, -1, szServerName, lenServer,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
}
|
||||||
|
if (lpszUserName)
|
||||||
|
{
|
||||||
|
lenUser = lstrlenW(lpszUserName)+1;
|
||||||
|
szUserName = (CHAR *)HeapAlloc(GetProcessHeap(), 0, lenUser*sizeof(CHAR));
|
||||||
WideCharToMultiByte(CP_ACP, -1, lpszUserName, -1, szUserName, lenUser,
|
WideCharToMultiByte(CP_ACP, -1, lpszUserName, -1, szUserName, lenUser,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
}
|
||||||
|
if (lpszPassword)
|
||||||
|
{
|
||||||
|
lenPass = lstrlenW(lpszPassword)+1;
|
||||||
|
szPassword = (CHAR *)HeapAlloc(GetProcessHeap(), 0, lenPass*sizeof(CHAR));
|
||||||
WideCharToMultiByte(CP_ACP, -1, lpszPassword, -1, szPassword, lenPass,
|
WideCharToMultiByte(CP_ACP, -1, lpszPassword, -1, szPassword, lenPass,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
rc = InternetConnectA(hInternet, szServerName, nServerPort,
|
rc = InternetConnectA(hInternet, szServerName, nServerPort,
|
||||||
szUserName, szPassword, dwService, dwFlags, dwContext);
|
szUserName, szPassword, dwService, dwFlags, dwContext);
|
||||||
|
|
||||||
free(szServerName);
|
if (szServerName) HeapFree(GetProcessHeap(), 0, szServerName);
|
||||||
free(szUserName);
|
if (szUserName) HeapFree(GetProcessHeap(), 0, szUserName);
|
||||||
free(szPassword);
|
if (szPassword) HeapFree(GetProcessHeap(), 0, szPassword);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -870,7 +881,7 @@ BOOL SetUrlComponentValueW(LPWSTR* lppszComponent, LPDWORD dwComponentLen, LPCWS
|
|||||||
{
|
{
|
||||||
TRACE("%s (%d)\n", debugstr_wn(lpszStart,len), len);
|
TRACE("%s (%d)\n", debugstr_wn(lpszStart,len), len);
|
||||||
|
|
||||||
if (*dwComponentLen != 0)
|
if (*dwComponentLen != 0 || *lppszComponent == NULL)
|
||||||
{
|
{
|
||||||
if (*lppszComponent == NULL)
|
if (*lppszComponent == NULL)
|
||||||
{
|
{
|
||||||
@ -1244,7 +1255,10 @@ BOOL WINAPI InternetWriteFile(HINTERNET hFile, LPCVOID lpBuffer ,
|
|||||||
switch (lpwh->htype)
|
switch (lpwh->htype)
|
||||||
{
|
{
|
||||||
case WH_HHTTPREQ:
|
case WH_HHTTPREQ:
|
||||||
nSocket = ((LPWININETHTTPREQA)hFile)->nSocketFD;
|
FIXME("This shouldn't be here! We don't support this kind"
|
||||||
|
" of connection anymore. Must use NETCON functions,"
|
||||||
|
" especially if using SSL\n");
|
||||||
|
nSocket = ((LPWININETHTTPREQA)hFile)->netConnection.socketFD;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WH_HFILE:
|
case WH_HFILE:
|
||||||
@ -1288,14 +1302,29 @@ BOOL WINAPI InternetReadFile(HINTERNET hFile, LPVOID lpBuffer,
|
|||||||
if (NULL == lpwh)
|
if (NULL == lpwh)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
/* FIXME: this should use NETCON functions! */
|
||||||
switch (lpwh->htype)
|
switch (lpwh->htype)
|
||||||
{
|
{
|
||||||
case WH_HHTTPREQ:
|
case WH_HHTTPREQ:
|
||||||
nSocket = ((LPWININETHTTPREQA)hFile)->nSocketFD;
|
if (!NETCON_recv(&((LPWININETHTTPREQA)hFile)->netConnection, lpBuffer,
|
||||||
|
dwNumOfBytesToRead, 0, (int *)dwNumOfBytesRead))
|
||||||
|
{
|
||||||
|
*dwNumOfBytesRead = 0;
|
||||||
|
retval = TRUE; /* Under windows, it seems to return 0 even if nothing was read... */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retval = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WH_HFILE:
|
case WH_HFILE:
|
||||||
|
/* FIXME: FTP should use NETCON_ stuff */
|
||||||
nSocket = ((LPWININETFILE)hFile)->nDataSocket;
|
nSocket = ((LPWININETFILE)hFile)->nDataSocket;
|
||||||
|
if (nSocket != -1)
|
||||||
|
{
|
||||||
|
int res = recv(nSocket, lpBuffer, dwNumOfBytesToRead, 0);
|
||||||
|
retval = (res >= 0);
|
||||||
|
*dwNumOfBytesRead = retval ? res : 0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1356,7 +1385,7 @@ static BOOL INET_QueryOptionHelper(BOOL bIsUnicode, HINTERNET hInternet, DWORD d
|
|||||||
LPWININETHANDLEHEADER lpwhh;
|
LPWININETHANDLEHEADER lpwhh;
|
||||||
BOOL bSuccess = FALSE;
|
BOOL bSuccess = FALSE;
|
||||||
|
|
||||||
TRACE("0x%08lx\n", dwOption);
|
TRACE("(%p, 0x%08lx, %p, %p)\n", hInternet, dwOption, lpBuffer, lpdwBufferLength);
|
||||||
|
|
||||||
if (NULL == hInternet)
|
if (NULL == hInternet)
|
||||||
{
|
{
|
||||||
@ -1630,86 +1659,6 @@ BOOL WINAPI InternetSetOptionExW(HINTERNET hInternet, DWORD dwOption,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* InternetGetCookieA (WININET.@)
|
|
||||||
*
|
|
||||||
* Retrieve cookie from the specified url
|
|
||||||
*
|
|
||||||
* RETURNS
|
|
||||||
* TRUE on success
|
|
||||||
* FALSE on failure
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
BOOL WINAPI InternetGetCookieA(LPCSTR lpszUrl, LPCSTR lpszCookieName,
|
|
||||||
LPSTR lpCookieData, LPDWORD lpdwSize)
|
|
||||||
{
|
|
||||||
FIXME("STUB\n");
|
|
||||||
TRACE("(%s,%s,%p)\n", debugstr_a(lpszUrl),debugstr_a(lpszCookieName),
|
|
||||||
lpCookieData);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* InternetGetCookieW (WININET.@)
|
|
||||||
*
|
|
||||||
* Retrieve cookie from the specified url
|
|
||||||
*
|
|
||||||
* RETURNS
|
|
||||||
* TRUE on success
|
|
||||||
* FALSE on failure
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
BOOL WINAPI InternetGetCookieW(LPCSTR lpszUrl, LPCWSTR lpszCookieName,
|
|
||||||
LPWSTR lpCookieData, LPDWORD lpdwSize)
|
|
||||||
{
|
|
||||||
FIXME("STUB\n");
|
|
||||||
TRACE("(%s,%s,%p)\n", debugstr_a(lpszUrl), debugstr_w(lpszCookieName),
|
|
||||||
lpCookieData);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* InternetSetCookieA (WININET.@)
|
|
||||||
*
|
|
||||||
* Sets cookie for the specified url
|
|
||||||
*
|
|
||||||
* RETURNS
|
|
||||||
* TRUE on success
|
|
||||||
* FALSE on failure
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
BOOL WINAPI InternetSetCookieA(LPCSTR lpszUrl, LPCSTR lpszCookieName,
|
|
||||||
LPCSTR lpCookieData)
|
|
||||||
{
|
|
||||||
FIXME("STUB\n");
|
|
||||||
TRACE("(%s,%s,%s)\n", debugstr_a(lpszUrl),
|
|
||||||
debugstr_a(lpszCookieName), debugstr_a(lpCookieData));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* InternetSetCookieW (WININET.@)
|
|
||||||
*
|
|
||||||
* Sets cookie for the specified url
|
|
||||||
*
|
|
||||||
* RETURNS
|
|
||||||
* TRUE on success
|
|
||||||
* FALSE on failure
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
BOOL WINAPI InternetSetCookieW(LPCSTR lpszUrl, LPCWSTR lpszCookieName,
|
|
||||||
LPCWSTR lpCookieData)
|
|
||||||
{
|
|
||||||
FIXME("STUB\n");
|
|
||||||
TRACE("(%s,%s,%s)\n", debugstr_a(lpszUrl),
|
|
||||||
debugstr_w(lpszCookieName), debugstr_w(lpCookieData));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* InternetCheckConnectionA (WININET.@)
|
* InternetCheckConnectionA (WININET.@)
|
||||||
*
|
*
|
||||||
@ -1807,11 +1756,11 @@ BOOL WINAPI InternetCheckConnectionW(LPCWSTR lpszUrl, DWORD dwFlags, DWORD dwRes
|
|||||||
BOOL rc;
|
BOOL rc;
|
||||||
|
|
||||||
len = lstrlenW(lpszUrl)+1;
|
len = lstrlenW(lpszUrl)+1;
|
||||||
if (!(szUrl = (CHAR *)malloc(len*sizeof(CHAR))))
|
if (!(szUrl = (CHAR *)HeapAlloc(GetProcessHeap(), 0, len*sizeof(CHAR))))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
WideCharToMultiByte(CP_ACP, -1, lpszUrl, -1, szUrl, len, NULL, NULL);
|
WideCharToMultiByte(CP_ACP, -1, lpszUrl, -1, szUrl, len, NULL, NULL);
|
||||||
rc = InternetCheckConnectionA((LPCSTR)szUrl, dwFlags, dwReserved);
|
rc = InternetCheckConnectionA((LPCSTR)szUrl, dwFlags, dwReserved);
|
||||||
free(szUrl);
|
HeapFree(GetProcessHeap(), 0, szUrl);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -1832,6 +1781,10 @@ HINTERNET WINAPI InternetOpenUrlA(HINTERNET hInternet, LPCSTR lpszUrl,
|
|||||||
char protocol[32], hostName[MAXHOSTNAME], userName[1024];
|
char protocol[32], hostName[MAXHOSTNAME], userName[1024];
|
||||||
char password[1024], path[2048], extra[1024];
|
char password[1024], path[2048], extra[1024];
|
||||||
HINTERNET client = NULL, client1 = NULL;
|
HINTERNET client = NULL, client1 = NULL;
|
||||||
|
|
||||||
|
TRACE("(%p, %s, %s, %08lx, %08lx, %08lx\n", hInternet, debugstr_a(lpszUrl), debugstr_a(lpszHeaders),
|
||||||
|
dwHeadersLength, dwFlags, dwContext);
|
||||||
|
|
||||||
urlComponents.dwStructSize = sizeof(URL_COMPONENTSA);
|
urlComponents.dwStructSize = sizeof(URL_COMPONENTSA);
|
||||||
urlComponents.lpszScheme = protocol;
|
urlComponents.lpszScheme = protocol;
|
||||||
urlComponents.dwSchemeLength = 32;
|
urlComponents.dwSchemeLength = 32;
|
||||||
@ -1907,15 +1860,15 @@ HINTERNET WINAPI InternetOpenUrlW(HINTERNET hInternet, LPCWSTR lpszUrl,
|
|||||||
|
|
||||||
INT lenUrl = lstrlenW(lpszUrl)+1;
|
INT lenUrl = lstrlenW(lpszUrl)+1;
|
||||||
INT lenHeaders = lstrlenW(lpszHeaders)+1;
|
INT lenHeaders = lstrlenW(lpszHeaders)+1;
|
||||||
CHAR *szUrl = (CHAR *)malloc(lenUrl*sizeof(CHAR));
|
CHAR *szUrl = (CHAR *)HeapAlloc(GetProcessHeap(), 0, lenUrl*sizeof(CHAR));
|
||||||
CHAR *szHeaders = (CHAR *)malloc(lenHeaders*sizeof(CHAR));
|
CHAR *szHeaders = (CHAR *)HeapAlloc(GetProcessHeap(), 0, lenHeaders*sizeof(CHAR));
|
||||||
|
|
||||||
if (!szUrl || !szHeaders)
|
if (!szUrl || !szHeaders)
|
||||||
{
|
{
|
||||||
if (szUrl)
|
if (szUrl)
|
||||||
free(szUrl);
|
HeapFree(GetProcessHeap(), 0, szUrl);
|
||||||
if (szHeaders)
|
if (szHeaders)
|
||||||
free(szHeaders);
|
HeapFree(GetProcessHeap(), 0, szHeaders);
|
||||||
return (HINTERNET)NULL;
|
return (HINTERNET)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1927,8 +1880,8 @@ HINTERNET WINAPI InternetOpenUrlW(HINTERNET hInternet, LPCWSTR lpszUrl,
|
|||||||
rc = InternetOpenUrlA(hInternet, szUrl, szHeaders,
|
rc = InternetOpenUrlA(hInternet, szUrl, szHeaders,
|
||||||
dwHeadersLength, dwFlags, dwContext);
|
dwHeadersLength, dwFlags, dwContext);
|
||||||
|
|
||||||
free(szUrl);
|
HeapFree(GetProcessHeap(), 0, szUrl);
|
||||||
free(szHeaders);
|
HeapFree(GetProcessHeap(), 0, szHeaders);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -2266,7 +2219,6 @@ LPSTR INTERNET_GetResponseBuffer()
|
|||||||
return lpwite->response;
|
return lpwite->response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* INTERNET_GetNextLine (internal)
|
* INTERNET_GetNextLine (internal)
|
||||||
*
|
*
|
||||||
@ -2340,7 +2292,7 @@ BOOL WINAPI InternetQueryDataAvailable( HINTERNET hFile,
|
|||||||
{
|
{
|
||||||
LPWININETHTTPREQA lpwhr = (LPWININETHTTPREQA) hFile;
|
LPWININETHTTPREQA lpwhr = (LPWININETHTTPREQA) hFile;
|
||||||
INT retval = -1;
|
INT retval = -1;
|
||||||
int nSocket = -1;
|
char buffer[4048];
|
||||||
|
|
||||||
|
|
||||||
if (NULL == lpwhr)
|
if (NULL == lpwhr)
|
||||||
@ -2349,34 +2301,26 @@ BOOL WINAPI InternetQueryDataAvailable( HINTERNET hFile,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("--> %p %i %i\n",lpwhr,lpwhr->hdr.htype,lpwhr->nSocketFD);
|
TRACE("--> %p %i\n",lpwhr,lpwhr->hdr.htype);
|
||||||
|
|
||||||
switch (lpwhr->hdr.htype)
|
switch (lpwhr->hdr.htype)
|
||||||
{
|
{
|
||||||
case WH_HHTTPREQ:
|
case WH_HHTTPREQ:
|
||||||
nSocket = lpwhr->nSocketFD;
|
if (!NETCON_recv(&((LPWININETHTTPREQA)hFile)->netConnection, buffer,
|
||||||
|
4048, MSG_PEEK, (int *)lpdwNumberOfBytesAvailble))
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_NO_MORE_FILES);
|
||||||
|
retval = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retval = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
FIXME("unsuported file type\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nSocket != -1)
|
|
||||||
{
|
|
||||||
char buffer[4048];
|
|
||||||
|
|
||||||
retval = recv(nSocket,buffer,4048,MSG_PEEK);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_NO_MORE_FILES);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lpdwNumberOfBytesAvailble)
|
|
||||||
{
|
|
||||||
(*lpdwNumberOfBytesAvailble) = retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("<-- %i\n",retval);
|
TRACE("<-- %i\n",retval);
|
||||||
return (retval+1);
|
return (retval+1);
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,20 @@
|
|||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
# include <netinet/in.h>
|
# include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_OPENSSL_SSL_H
|
||||||
|
# include <openssl/ssl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* used for netconnection.c stuff */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
BOOL useSSL;
|
||||||
|
int socketFD;
|
||||||
|
#ifdef HAVE_OPENSSL_SSL_H
|
||||||
|
SSL *ssl_s;
|
||||||
|
int ssl_sock;
|
||||||
|
#endif
|
||||||
|
} WININET_NETCONNECTION;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
@ -93,7 +107,7 @@ typedef struct
|
|||||||
LPSTR lpszPath;
|
LPSTR lpszPath;
|
||||||
LPSTR lpszVerb;
|
LPSTR lpszVerb;
|
||||||
LPSTR lpszHostName;
|
LPSTR lpszHostName;
|
||||||
INT nSocketFD;
|
WININET_NETCONNECTION netConnection;
|
||||||
HTTPHEADERA StdHeaders[HTTP_QUERY_MAX+1];
|
HTTPHEADERA StdHeaders[HTTP_QUERY_MAX+1];
|
||||||
HTTPHEADERA *pCustHeaders;
|
HTTPHEADERA *pCustHeaders;
|
||||||
INT nCustHeaders;
|
INT nCustHeaders;
|
||||||
@ -265,6 +279,19 @@ VOID SendAsyncCallbackInt(LPWININETAPPINFOA hIC, HINTERNET hHttpSession,
|
|||||||
lpvStatusInfo , DWORD dwStatusInfoLength);
|
lpvStatusInfo , DWORD dwStatusInfoLength);
|
||||||
|
|
||||||
|
|
||||||
|
BOOL NETCON_connected(WININET_NETCONNECTION *connection);
|
||||||
|
void NETCON_init(WININET_NETCONNECTION *connnection, BOOL useSSL);
|
||||||
|
BOOL NETCON_create(WININET_NETCONNECTION *connection, int domain,
|
||||||
|
int type, int protocol);
|
||||||
|
BOOL NETCON_close(WININET_NETCONNECTION *connection);
|
||||||
|
BOOL NETCON_connect(WININET_NETCONNECTION *connection, const struct sockaddr *serv_addr,
|
||||||
|
socklen_t addrlen);
|
||||||
|
BOOL NETCON_send(WININET_NETCONNECTION *connection, const void *msg, size_t len, int flags,
|
||||||
|
int *sent /* out */);
|
||||||
|
BOOL NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int flags,
|
||||||
|
int *recvd /* out */);
|
||||||
|
BOOL NETCON_getNextLine(WININET_NETCONNECTION *connection, LPSTR lpszBuffer, LPDWORD dwBuffer);
|
||||||
|
|
||||||
#define MAX_REPLY_LEN 0x5B4
|
#define MAX_REPLY_LEN 0x5B4
|
||||||
|
|
||||||
|
|
||||||
|
490
dlls/wininet/netconnection.c
Normal file
490
dlls/wininet/netconnection.c
Normal file
@ -0,0 +1,490 @@
|
|||||||
|
/*
|
||||||
|
* Wininet - networking layer. Uses unix sockets or OpenSSL.
|
||||||
|
*
|
||||||
|
* Copyright 2002 TransGaming Technologies Inc.
|
||||||
|
*
|
||||||
|
* David Hammerton
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "wine/port.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
# include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "wine/library.h"
|
||||||
|
#include "windef.h"
|
||||||
|
#include "winbase.h"
|
||||||
|
#include "wininet.h"
|
||||||
|
#include "winerror.h"
|
||||||
|
|
||||||
|
#include "wine/debug.h"
|
||||||
|
#include "internet.h"
|
||||||
|
|
||||||
|
#define RESPONSE_TIMEOUT 30 /* FROM internet.c */
|
||||||
|
|
||||||
|
|
||||||
|
WINE_DEFAULT_DEBUG_CHANNEL(wininet);
|
||||||
|
|
||||||
|
/* FIXME!!!!!!
|
||||||
|
* This should use winsock - To use winsock the funtions will have to change a bit
|
||||||
|
* as they are designed for unix sockets.
|
||||||
|
* SSL stuff should use crypt32.dll
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_OPENSSL_SSL_H
|
||||||
|
|
||||||
|
#ifndef SONAME_LIBSSL
|
||||||
|
#define SONAME_LIBSSL "libssl.so"
|
||||||
|
#endif
|
||||||
|
#ifndef SONAME_LIBCRYPTO
|
||||||
|
#define SONAME_LIBCRYPTO "libcrypto.so"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void *OpenSSL_ssl_handle;
|
||||||
|
static void *OpenSSL_crypto_handle;
|
||||||
|
|
||||||
|
static SSL_METHOD *meth;
|
||||||
|
static SSL_CTX *ctx;
|
||||||
|
|
||||||
|
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
|
||||||
|
|
||||||
|
/* OpenSSL funtions that we use */
|
||||||
|
MAKE_FUNCPTR(SSL_library_init);
|
||||||
|
MAKE_FUNCPTR(SSL_load_error_strings);
|
||||||
|
MAKE_FUNCPTR(SSLv23_method);
|
||||||
|
MAKE_FUNCPTR(SSL_CTX_new);
|
||||||
|
MAKE_FUNCPTR(SSL_new);
|
||||||
|
MAKE_FUNCPTR(SSL_set_bio);
|
||||||
|
MAKE_FUNCPTR(SSL_connect);
|
||||||
|
MAKE_FUNCPTR(SSL_write);
|
||||||
|
MAKE_FUNCPTR(SSL_read);
|
||||||
|
MAKE_FUNCPTR(SSL_CTX_get_timeout);
|
||||||
|
MAKE_FUNCPTR(SSL_CTX_set_timeout);
|
||||||
|
|
||||||
|
/* OpenSSL's libcrypto functions that we use */
|
||||||
|
MAKE_FUNCPTR(BIO_new_socket);
|
||||||
|
MAKE_FUNCPTR(BIO_new_fp);
|
||||||
|
#undef MAKE_FUNCPTR
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL)
|
||||||
|
{
|
||||||
|
connection->useSSL = useSSL;
|
||||||
|
connection->socketFD = -1;
|
||||||
|
if (connection->useSSL)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_OPENSSL_SSL_H
|
||||||
|
TRACE("using SSL connection\n");
|
||||||
|
connection->ssl_sock = -1;
|
||||||
|
if (OpenSSL_ssl_handle) /* already initilzed everything */
|
||||||
|
return;
|
||||||
|
OpenSSL_ssl_handle = wine_dlopen(SONAME_LIBSSL, RTLD_NOW, NULL, 0);
|
||||||
|
if (!OpenSSL_ssl_handle)
|
||||||
|
{
|
||||||
|
ERR("trying to use a SSL connection, but couldn't load %s. Expect trouble.\n",
|
||||||
|
SONAME_LIBSSL);
|
||||||
|
connection->useSSL = FALSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
OpenSSL_crypto_handle = wine_dlopen(SONAME_LIBCRYPTO, RTLD_NOW, NULL, 0);
|
||||||
|
if (!OpenSSL_crypto_handle)
|
||||||
|
{
|
||||||
|
ERR("trying to use a SSL connection, but couldn't load %s. Expect trouble.\n",
|
||||||
|
SONAME_LIBCRYPTO);
|
||||||
|
connection->useSSL = FALSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mmm nice ugly macroness */
|
||||||
|
#define DYNSSL(x) \
|
||||||
|
p##x = wine_dlsym(OpenSSL_ssl_handle, #x, NULL, 0); \
|
||||||
|
if (!p##x) \
|
||||||
|
{ \
|
||||||
|
ERR("failed to load symbol %s\n", #x); \
|
||||||
|
connection->useSSL = FALSE; \
|
||||||
|
return; \
|
||||||
|
}
|
||||||
|
|
||||||
|
DYNSSL(SSL_library_init);
|
||||||
|
DYNSSL(SSL_load_error_strings);
|
||||||
|
DYNSSL(SSLv23_method);
|
||||||
|
DYNSSL(SSL_CTX_new);
|
||||||
|
DYNSSL(SSL_new);
|
||||||
|
DYNSSL(SSL_set_bio);
|
||||||
|
DYNSSL(SSL_connect);
|
||||||
|
DYNSSL(SSL_write);
|
||||||
|
DYNSSL(SSL_read);
|
||||||
|
DYNSSL(SSL_CTX_get_timeout);
|
||||||
|
DYNSSL(SSL_CTX_set_timeout);
|
||||||
|
#undef DYNSSL
|
||||||
|
|
||||||
|
#define DYNCRYPTO(x) \
|
||||||
|
p##x = wine_dlsym(OpenSSL_crypto_handle, #x, NULL, 0); \
|
||||||
|
if (!p##x) \
|
||||||
|
{ \
|
||||||
|
ERR("failed to load symbol %s\n", #x); \
|
||||||
|
connection->useSSL = FALSE; \
|
||||||
|
return; \
|
||||||
|
}
|
||||||
|
DYNCRYPTO(BIO_new_fp);
|
||||||
|
DYNCRYPTO(BIO_new_socket);
|
||||||
|
#undef DYNCRYPTO
|
||||||
|
|
||||||
|
pSSL_library_init();
|
||||||
|
pSSL_load_error_strings();
|
||||||
|
pBIO_new_fp(stderr, BIO_NOCLOSE); /* FIXME: should use winedebug stuff */
|
||||||
|
|
||||||
|
meth = pSSLv23_method();
|
||||||
|
/* FIXME: SECURITY PROBLEM! WE ARN'T VERIFYING THE HOSTS CERTIFICATES OR ANYTHING */
|
||||||
|
#else
|
||||||
|
FIXME("can't use SSL, not compiled in.\n");
|
||||||
|
connection->useSSL = FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL NETCON_connected(WININET_NETCONNECTION *connection)
|
||||||
|
{
|
||||||
|
if (!connection->useSSL)
|
||||||
|
{
|
||||||
|
if (connection->socketFD == -1)
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef HAVE_OPENSSL_SSL_H
|
||||||
|
if (connection->ssl_sock == -1)
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
#else
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* NETCON_create
|
||||||
|
* Basically calls 'socket()' unless useSSL is supplised,
|
||||||
|
* in which case we do other things.
|
||||||
|
*/
|
||||||
|
BOOL NETCON_create(WININET_NETCONNECTION *connection, int domain,
|
||||||
|
int type, int protocol)
|
||||||
|
{
|
||||||
|
if (!connection->useSSL)
|
||||||
|
{
|
||||||
|
connection->socketFD = socket(domain, type, protocol);
|
||||||
|
if (connection->socketFD == -1)
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef HAVE_OPENSSL_SSL_H
|
||||||
|
connection->ssl_sock = socket(domain, type, protocol);
|
||||||
|
return TRUE;
|
||||||
|
#else
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* NETCON_close
|
||||||
|
* Basically calls 'close()' unless we should use SSL
|
||||||
|
*/
|
||||||
|
BOOL NETCON_close(WININET_NETCONNECTION *connection)
|
||||||
|
{
|
||||||
|
if (!NETCON_connected) return FALSE;
|
||||||
|
if (!connection->useSSL)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
result = close(connection->socketFD);
|
||||||
|
connection->socketFD = -1;
|
||||||
|
if (result == -1)
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef HAVE_OPENSSL_SSL_H
|
||||||
|
close(connection->ssl_sock);
|
||||||
|
connection->ssl_sock = -1;
|
||||||
|
/* FIXME should we call SSL_shutdown here?? Probably on whatever is the
|
||||||
|
* opposite of NETCON_init.... */
|
||||||
|
return TRUE;
|
||||||
|
#else
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* NETCON_connect
|
||||||
|
* Basically calls 'connect()' unless we should use SSL
|
||||||
|
*/
|
||||||
|
BOOL NETCON_connect(WININET_NETCONNECTION *connection, const struct sockaddr *serv_addr,
|
||||||
|
socklen_t addrlen)
|
||||||
|
{
|
||||||
|
if (!NETCON_connected) return FALSE;
|
||||||
|
if (!connection->useSSL)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
result = connect(connection->socketFD, serv_addr, addrlen);
|
||||||
|
if (result == -1)
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef HAVE_OPENSSL_SSL_H
|
||||||
|
BIO *sbio;
|
||||||
|
|
||||||
|
ctx = pSSL_CTX_new(meth);
|
||||||
|
connection->ssl_s = pSSL_new(ctx);
|
||||||
|
|
||||||
|
if (connect(connection->ssl_sock, serv_addr, addrlen) == -1)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
sbio = pBIO_new_socket(connection->ssl_sock, BIO_NOCLOSE);
|
||||||
|
pSSL_set_bio(connection->ssl_s, sbio, sbio);
|
||||||
|
if (pSSL_connect(connection->ssl_s) <= 0)
|
||||||
|
{
|
||||||
|
ERR("ssl couldn't connect\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
#else
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* NETCON_send
|
||||||
|
* Basically calls 'send()' unless we should use SSL
|
||||||
|
* number of chars send is put in *sent
|
||||||
|
*/
|
||||||
|
BOOL NETCON_send(WININET_NETCONNECTION *connection, const void *msg, size_t len, int flags,
|
||||||
|
int *sent /* out */)
|
||||||
|
{
|
||||||
|
if (!NETCON_connected) return FALSE;
|
||||||
|
if (!connection->useSSL)
|
||||||
|
{
|
||||||
|
*sent = send(connection->socketFD, msg, len, flags);
|
||||||
|
if (*sent == -1)
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef HAVE_OPENSSL_SSL_H
|
||||||
|
if (flags)
|
||||||
|
FIXME("SSL_write doesn't support any flags (%08x)\n", flags);
|
||||||
|
*sent = pSSL_write(connection->ssl_s, msg, len);
|
||||||
|
if (*sent < 1 && len)
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
#else
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* NETCON_recv
|
||||||
|
* Basically calls 'recv()' unless we should use SSL
|
||||||
|
* number of chars receieved is put in *recvd
|
||||||
|
*/
|
||||||
|
BOOL NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int flags,
|
||||||
|
int *recvd /* out */)
|
||||||
|
{
|
||||||
|
if (!NETCON_connected) return FALSE;
|
||||||
|
if (!connection->useSSL)
|
||||||
|
{
|
||||||
|
*recvd = recv(connection->socketFD, buf, len, flags);
|
||||||
|
if (*recvd == -1)
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef HAVE_OPENSSL_SSL_H
|
||||||
|
static char *peek_msg = NULL;
|
||||||
|
static char *peek_msg_mem = NULL;
|
||||||
|
|
||||||
|
if (flags & (~MSG_PEEK))
|
||||||
|
FIXME("SSL_read does not support the following flag: %08x\n", flags);
|
||||||
|
|
||||||
|
/* this ugly hack is all for MSG_PEEK. eww gross */
|
||||||
|
if (flags & MSG_PEEK && !peek_msg)
|
||||||
|
{
|
||||||
|
peek_msg = peek_msg_mem = HeapAlloc(GetProcessHeap(), 0, (sizeof(char) * len) + 1);
|
||||||
|
}
|
||||||
|
else if (flags & MSG_PEEK && peek_msg)
|
||||||
|
{
|
||||||
|
if (len < strlen(peek_msg))
|
||||||
|
FIXME("buffer isn't big enough. Do the expect us to wrap?\n");
|
||||||
|
strncpy(buf, peek_msg, len);
|
||||||
|
*recvd = (strlen(peek_msg) <= len ? strlen(peek_msg) : len);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else if (peek_msg)
|
||||||
|
{
|
||||||
|
strncpy(buf, peek_msg, len);
|
||||||
|
peek_msg += *recvd = min(len, strlen(peek_msg));
|
||||||
|
if (*peek_msg == '\0' || *(peek_msg - 1) == '\0')
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, peek_msg_mem);
|
||||||
|
peek_msg_mem = NULL;
|
||||||
|
peek_msg = NULL;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
*recvd = pSSL_read(connection->ssl_s, buf, len);
|
||||||
|
if (flags & MSG_PEEK) /* must copy stuff into buffer */
|
||||||
|
{
|
||||||
|
if (!*recvd)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, peek_msg_mem);
|
||||||
|
peek_msg_mem = NULL;
|
||||||
|
peek_msg = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strncpy(peek_msg, buf, *recvd);
|
||||||
|
peek_msg[*recvd] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*recvd < 1 && len)
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
#else
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* NETCON_getNextLine
|
||||||
|
*/
|
||||||
|
BOOL NETCON_getNextLine(WININET_NETCONNECTION *connection, LPSTR lpszBuffer, LPDWORD dwBuffer)
|
||||||
|
{
|
||||||
|
|
||||||
|
TRACE("\n");
|
||||||
|
|
||||||
|
if (!NETCON_connected(connection)) return FALSE;
|
||||||
|
|
||||||
|
if (!connection->useSSL)
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
fd_set infd;
|
||||||
|
BOOL bSuccess = FALSE;
|
||||||
|
INT nRecv = 0;
|
||||||
|
|
||||||
|
FD_ZERO(&infd);
|
||||||
|
FD_SET(connection->socketFD, &infd);
|
||||||
|
tv.tv_sec=RESPONSE_TIMEOUT;
|
||||||
|
tv.tv_usec=0;
|
||||||
|
|
||||||
|
while (nRecv < *dwBuffer)
|
||||||
|
{
|
||||||
|
if (select(connection->socketFD+1,&infd,NULL,NULL,&tv) > 0)
|
||||||
|
{
|
||||||
|
if (recv(connection->socketFD, &lpszBuffer[nRecv], 1, 0) <= 0)
|
||||||
|
{
|
||||||
|
INTERNET_SetLastError(ERROR_CONNECTION_ABORTED); /* fixme: right error? */
|
||||||
|
goto lend;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpszBuffer[nRecv] == '\n')
|
||||||
|
{
|
||||||
|
bSuccess = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (lpszBuffer[nRecv] != '\r')
|
||||||
|
nRecv++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
INTERNET_SetLastError(ERROR_INTERNET_TIMEOUT);
|
||||||
|
goto lend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lend: /* FIXME: don't use labels */
|
||||||
|
if (bSuccess)
|
||||||
|
{
|
||||||
|
lpszBuffer[nRecv] = '\0';
|
||||||
|
*dwBuffer = nRecv - 1;
|
||||||
|
TRACE(":%d %s\n", nRecv, lpszBuffer);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef HAVE_OPENSSL_SSL_H
|
||||||
|
long prev_timeout;
|
||||||
|
INT nRecv = 0;
|
||||||
|
BOOL success = TRUE;
|
||||||
|
|
||||||
|
prev_timeout = pSSL_CTX_get_timeout(ctx);
|
||||||
|
pSSL_CTX_set_timeout(ctx, RESPONSE_TIMEOUT);
|
||||||
|
|
||||||
|
while (nRecv < *dwBuffer)
|
||||||
|
{
|
||||||
|
int recv = 1;
|
||||||
|
if (!NETCON_recv(connection, &lpszBuffer[nRecv], 1, 0, &recv))
|
||||||
|
{
|
||||||
|
INTERNET_SetLastError(ERROR_CONNECTION_ABORTED);
|
||||||
|
success = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpszBuffer[nRecv] == '\n')
|
||||||
|
{
|
||||||
|
success = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (lpszBuffer[nRecv] != '\r')
|
||||||
|
nRecv++;
|
||||||
|
}
|
||||||
|
|
||||||
|
pSSL_CTX_set_timeout(ctx, prev_timeout);
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
lpszBuffer[nRecv] = '\0';
|
||||||
|
*dwBuffer = nRecv - 1;
|
||||||
|
TRACE("_SSL:%d %s\n", nRecv, lpszBuffer);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
#else
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
@ -371,6 +371,9 @@
|
|||||||
/* Define if OpenGL is present on the system */
|
/* Define if OpenGL is present on the system */
|
||||||
#undef HAVE_OPENGL
|
#undef HAVE_OPENGL
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <openssl/ssl.h> header file. */
|
||||||
|
#undef HAVE_OPENSSL_SSL_H
|
||||||
|
|
||||||
/* Define if you have the Open Sound system */
|
/* Define if you have the Open Sound system */
|
||||||
#undef HAVE_OSS
|
#undef HAVE_OSS
|
||||||
|
|
||||||
@ -761,6 +764,9 @@
|
|||||||
/* The size of a `long long', as computed by sizeof. */
|
/* The size of a `long long', as computed by sizeof. */
|
||||||
#undef SIZEOF_LONG_LONG
|
#undef SIZEOF_LONG_LONG
|
||||||
|
|
||||||
|
/* Define to the soname of the libcrypto library. */
|
||||||
|
#undef SONAME_LIBCRYPTO
|
||||||
|
|
||||||
/* Define to the soname of the libcups library. */
|
/* Define to the soname of the libcups library. */
|
||||||
#undef SONAME_LIBCUPS
|
#undef SONAME_LIBCUPS
|
||||||
|
|
||||||
@ -773,6 +779,9 @@
|
|||||||
/* Define to the soname of the libjack library. */
|
/* Define to the soname of the libjack library. */
|
||||||
#undef SONAME_LIBJACK
|
#undef SONAME_LIBJACK
|
||||||
|
|
||||||
|
/* Define to the soname of the libssl library. */
|
||||||
|
#undef SONAME_LIBSSL
|
||||||
|
|
||||||
/* Define to the soname of the libX11 library. */
|
/* Define to the soname of the libX11 library. */
|
||||||
#undef SONAME_LIBX11
|
#undef SONAME_LIBX11
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user