aboutsummaryrefslogtreecommitdiff
path: root/dep/gsoap/stdsoap2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dep/gsoap/stdsoap2.cpp')
-rw-r--r--dep/gsoap/stdsoap2.cpp1672
1 files changed, 989 insertions, 683 deletions
diff --git a/dep/gsoap/stdsoap2.cpp b/dep/gsoap/stdsoap2.cpp
index ed0922d86f2..36a8901dcab 100644
--- a/dep/gsoap/stdsoap2.cpp
+++ b/dep/gsoap/stdsoap2.cpp
@@ -1,17 +1,17 @@
/*
- stdsoap2.c[pp] 2.8.2
+ stdsoap2.c[pp] 2.8.10
gSOAP runtime engine
gSOAP XML Web services tools
-Copyright (C) 2000-2011, Robert van Engelen, Genivia Inc., All Rights Reserved.
+Copyright (C) 2000-2012, Robert van Engelen, Genivia Inc., All Rights Reserved.
This part of the software is released under ONE of the following licenses:
GPL, or the gSOAP public license, or Genivia's license for commercial use.
--------------------------------------------------------------------------------
Contributors:
Wind River Systems Inc., for the following additions under gSOAP public license:
- - vxWorks compatible
+ - vxWorks compatible options
--------------------------------------------------------------------------------
gSOAP public license.
@@ -24,7 +24,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the License.
The Initial Developer of the Original Code is Robert A. van Engelen.
-Copyright (C) 2000-2011, Robert van Engelen, Genivia Inc., All Rights Reserved.
+Copyright (C) 2000-2012, Robert van Engelen, Genivia Inc., All Rights Reserved.
--------------------------------------------------------------------------------
GPL license.
@@ -49,25 +49,18 @@ compiling, linking, and/or using OpenSSL is allowed.
--------------------------------------------------------------------------------
A commercial use license is available from Genivia, Inc., contact@genivia.com
--------------------------------------------------------------------------------
-
-Installation note:
-
-Win32 build needs "ws2_32.lib"
-To do this in Visual C++ 6.0, go to "Project", "settings", select the "Link"
-tab (the project file needs to be selected in the file view) and add
-"ws2_32.lib" to the "Object/library modules" entry
-
-On Mac OS X with gcc (GCC) 3.1 20020420 (prerelease) you MUST compile with
--fstack_check when using -O2 because gcc 3.1 has a bug that smashes the stack
-when locally allocated data exceeds 64K.
-
*/
+#define GSOAP_LIB_VERSION 20810
+
#ifdef AS400
# pragma convert(819) /* EBCDIC to ASCII */
#endif
#include "stdsoap2.h"
+#if GSOAP_VERSION != GSOAP_LIB_VERSION
+# error "GSOAP VERSION MISMATCH IN LIBRARY: PLEASE REINSTALL PACKAGE"
+#endif
#ifdef __BORLANDC__
# pragma warn -8060
@@ -83,10 +76,10 @@ when locally allocated data exceeds 64K.
#endif
#ifdef __cplusplus
-SOAP_SOURCE_STAMP("@(#) stdsoap2.cpp ver 2.8.2 2011-04-17 00:00:00 GMT")
+SOAP_SOURCE_STAMP("@(#) stdsoap2.cpp ver 2.8.10 2012-08-16 00:00:00 GMT")
extern "C" {
#else
-SOAP_SOURCE_STAMP("@(#) stdsoap2.c ver 2.8.2 2011-04-17 00:00:00 GMT")
+SOAP_SOURCE_STAMP("@(#) stdsoap2.c ver 2.8.10 2012-08-16 00:00:00 GMT")
#endif
/* 8bit character representing unknown/nonrepresentable character data (e.g. not supported by current locale with multibyte support enabled) */
@@ -101,7 +94,7 @@ SOAP_SOURCE_STAMP("@(#) stdsoap2.c ver 2.8.2 2011-04-17 00:00:00 GMT")
#define SOAP_QT (soap_wchar)(-5) /* XML-specific '"' */
#define SOAP_AP (soap_wchar)(-6) /* XML-specific ''' */
-#define soap_blank(c) ((c) >= 0 && (c) <= 32)
+#define soap_blank(c) ((c)+1 > 0 && (c) <= 32)
#define soap_notblank(c) ((c) > 32)
#if defined(WIN32) && !defined(UNDER_CE)
@@ -138,8 +131,10 @@ static int soap_isxdigit(int);
static void *fplugin(struct soap*, const char*);
static size_t soap_count_attachments(struct soap *soap);
static int soap_try_connect_command(struct soap*, int http_command, const char *endpoint, const char *action);
+#ifdef WITH_NTLM
+static int soap_ntlm_handshake(struct soap *soap, int command, const char *endpoint, const char *host, int port);
+#endif
#ifndef WITH_NOIDREF
-static void soap_update_ptrs(struct soap*, char*, char*, char*, char*);
static int soap_has_copies(struct soap*, const char*, const char*);
static void soap_init_iht(struct soap*);
static void soap_free_iht(struct soap*);
@@ -152,7 +147,7 @@ static void soap_free_pht(struct soap*);
static const char *soap_set_validation_fault(struct soap*, const char*, const char*);
static int soap_isnumeric(struct soap*, const char*);
static struct soap_nlist *soap_push_ns(struct soap *soap, const char *id, const char *ns, short utilized);
-static void soap_utilize_ns(struct soap *soap, const char *tag, size_t n);
+static void soap_utilize_ns(struct soap *soap, const char *tag);
#endif
#ifndef WITH_LEANER
@@ -208,9 +203,9 @@ static const char *soap_decode(char*, size_t, const char*, const char*);
#ifndef PALM_1
static soap_wchar soap_getchunkchar(struct soap*);
static const char *http_error(struct soap*, int);
-static int http_put(struct soap*);
static int http_get(struct soap*);
static int http_405(struct soap*);
+static int http_200(struct soap*);
static int http_post(struct soap*, const char*, const char*, int, const char*, const char*, size_t);
static int http_send_header(struct soap*, const char*);
static int http_post_header(struct soap*, const char*, const char*);
@@ -538,6 +533,7 @@ extern int h_errno;
static int
fsend(struct soap *soap, const char *s, size_t n)
{ register int nwritten, err;
+ SOAP_SOCKET sk;
#if defined(__cplusplus) && !defined(WITH_LEAN) && !defined(WITH_COMPAT)
if (soap->os)
{ soap->os->write(s, (std::streamsize)n);
@@ -547,23 +543,26 @@ fsend(struct soap *soap, const char *s, size_t n)
return SOAP_EOF;
}
#endif
+ sk = soap->sendsk;
+ if (!soap_valid_socket(sk))
+ sk = soap->socket;
while (n)
- { if (soap_valid_socket(soap->socket))
+ { if (soap_valid_socket(sk))
{
if (soap->send_timeout)
{ for (;;)
{ register int r;
#ifdef WITH_OPENSSL
if (soap->ssl)
- r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_ALL, soap->send_timeout);
+ r = tcp_select(soap, sk, SOAP_TCP_SELECT_ALL, soap->send_timeout);
else
#endif
#ifdef WITH_GNUTLS
if (soap->session)
- r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_ALL, soap->send_timeout);
+ r = tcp_select(soap, sk, SOAP_TCP_SELECT_ALL, soap->send_timeout);
else
#endif
- r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, soap->send_timeout);
+ r = tcp_select(soap, sk, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, soap->send_timeout);
if (r > 0)
break;
if (!r)
@@ -590,25 +589,25 @@ fsend(struct soap *soap, const char *s, size_t n)
#ifndef WITH_LEAN
if ((soap->omode & SOAP_IO_UDP))
{ if (soap->peerlen)
- nwritten = sendto(soap->socket, (char*)s, (SOAP_WINSOCKINT)n, soap->socket_flags, (struct sockaddr*)&soap->peer, (SOAP_WINSOCKINT)soap->peerlen);
+ nwritten = sendto(sk, (char*)s, (SOAP_WINSOCKINT)n, soap->socket_flags, (struct sockaddr*)&soap->peer, (SOAP_WINSOCKINT)soap->peerlen);
else
- nwritten = send(soap->socket, s, (SOAP_WINSOCKINT)n, soap->socket_flags);
+ nwritten = send(sk, s, (SOAP_WINSOCKINT)n, soap->socket_flags);
/* retry and back-off algorithm */
/* TODO: this is not very clear from specs so verify and limit conditions under which we should loop (e.g. ENOBUFS) */
if (nwritten < 0)
{ int udp_repeat;
int udp_delay;
if ((soap->connect_flags & SO_BROADCAST))
- udp_repeat = 3; /* SOAP-over-UDP MULTICAST_UDP_REPEAT - 1 */
+ udp_repeat = 2; /* SOAP-over-UDP MULTICAST_UDP_REPEAT - 1 */
else
udp_repeat = 1; /* SOAP-over-UDP UNICAST_UDP_REPEAT - 1 */
udp_delay = ((unsigned int)soap_random % 201) + 50; /* UDP_MIN_DELAY .. UDP_MAX_DELAY */
do
- { tcp_select(soap, soap->socket, SOAP_TCP_SELECT_ERR, -1000 * udp_delay);
+ { tcp_select(soap, sk, SOAP_TCP_SELECT_ERR, -1000 * udp_delay);
if (soap->peerlen)
- nwritten = sendto(soap->socket, (char*)s, (SOAP_WINSOCKINT)n, soap->socket_flags, (struct sockaddr*)&soap->peer, (SOAP_WINSOCKINT)soap->peerlen);
+ nwritten = sendto(sk, (char*)s, (SOAP_WINSOCKINT)n, soap->socket_flags, (struct sockaddr*)&soap->peer, (SOAP_WINSOCKINT)soap->peerlen);
else
- nwritten = send(soap->socket, s, (SOAP_WINSOCKINT)n, soap->socket_flags);
+ nwritten = send(sk, s, (SOAP_WINSOCKINT)n, soap->socket_flags);
udp_delay <<= 1;
if (udp_delay > 500) /* UDP_UPPER_DELAY */
udp_delay = 500;
@@ -619,14 +618,14 @@ fsend(struct soap *soap, const char *s, size_t n)
else
#endif
#if !defined(PALM) && !defined(AS400)
- nwritten = send(soap->socket, s, (int)n, soap->socket_flags);
+ nwritten = send(sk, s, (int)n, soap->socket_flags);
#else
- nwritten = send(soap->socket, (void*)s, n, soap->socket_flags);
+ nwritten = send(sk, (void*)s, n, soap->socket_flags);
#endif
if (nwritten <= 0)
{
register int r = 0;
- err = soap_socket_errno(soap->socket);
+ err = soap_socket_errno(sk);
#ifdef WITH_OPENSSL
if (soap->ssl && (r = SSL_get_error(soap->ssl, nwritten)) != SSL_ERROR_NONE && r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE)
{ soap->errnum = err;
@@ -645,14 +644,14 @@ fsend(struct soap *soap, const char *s, size_t n)
{
#if defined(WITH_OPENSSL)
if (soap->ssl && r == SSL_ERROR_WANT_READ)
- r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, soap->send_timeout ? soap->send_timeout : -10000);
+ r = tcp_select(soap, sk, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, soap->send_timeout ? soap->send_timeout : -10000);
else
#elif defined(WITH_GNUTLS)
if (soap->session && !gnutls_record_get_direction(soap->session))
- r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, soap->send_timeout ? soap->send_timeout : -10000);
+ r = tcp_select(soap, sk, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, soap->send_timeout ? soap->send_timeout : -10000);
else
#endif
- r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, soap->send_timeout ? soap->send_timeout : -10000);
+ r = tcp_select(soap, sk, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, soap->send_timeout ? soap->send_timeout : -10000);
if (!r && soap->send_timeout)
return SOAP_EOF;
if (r < 0 && soap->errnum != SOAP_EINTR)
@@ -775,7 +774,7 @@ soap_flush(struct soap *soap)
do
{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflating %u bytes\n", soap->d_stream->avail_in));
if (deflate(soap->d_stream, Z_NO_FLUSH) != Z_OK)
- { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to deflate: %s\n", soap->d_stream->msg?soap->d_stream->msg:SOAP_STR_EOS));
+ { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to deflate: %s\n", soap->d_stream->msg ? soap->d_stream->msg : SOAP_STR_EOS));
return soap->error = SOAP_ZLIB_ERROR;
}
if (!soap->d_stream->avail_out)
@@ -870,6 +869,7 @@ static size_t
frecv(struct soap *soap, char *s, size_t n)
{ register int r;
register int retries = 100; /* max 100 retries with non-blocking sockets */
+ SOAP_SOCKET sk;
soap->errnum = 0;
#if defined(__cplusplus) && !defined(WITH_LEAN) && !defined(WITH_COMPAT)
if (soap->is)
@@ -878,7 +878,10 @@ frecv(struct soap *soap, char *s, size_t n)
return 0;
}
#endif
- if (soap_valid_socket(soap->socket))
+ sk = soap->recvsk;
+ if (!soap_valid_socket(sk))
+ sk = soap->socket;
+ if (soap_valid_socket(sk))
{ for (;;)
{
#ifdef WITH_OPENSSL
@@ -890,7 +893,7 @@ frecv(struct soap *soap, char *s, size_t n)
if (soap->recv_timeout)
#endif
{ for (;;)
- { r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, soap->recv_timeout);
+ { r = tcp_select(soap, sk, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, soap->recv_timeout);
if (r > 0)
break;
if (!r)
@@ -930,7 +933,7 @@ frecv(struct soap *soap, char *s, size_t n)
if ((soap->omode & SOAP_IO_UDP))
{ SOAP_SOCKLEN_T k = (SOAP_SOCKLEN_T)sizeof(soap->peer);
memset((void*)&soap->peer, 0, sizeof(soap->peer));
- r = recvfrom(soap->socket, s, (SOAP_WINSOCKINT)n, soap->socket_flags, (struct sockaddr*)&soap->peer, &k); /* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */
+ r = recvfrom(sk, s, (SOAP_WINSOCKINT)n, soap->socket_flags, (struct sockaddr*)&soap->peer, &k); /* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */
soap->peerlen = (size_t)k;
#ifndef WITH_IPV6
soap->ip = ntohl(soap->peer.sin_addr.s_addr);
@@ -938,13 +941,13 @@ frecv(struct soap *soap, char *s, size_t n)
}
else
#endif
- r = recv(soap->socket, s, (int)n, soap->socket_flags);
+ r = recv(sk, s, (int)n, soap->socket_flags);
#ifdef PALM
/* CycleSyncDisplay(curStatusMsg); */
#endif
if (r >= 0)
return (size_t)r;
- r = soap_socket_errno(soap->socket);
+ r = soap_socket_errno(sk);
if (r != SOAP_EINTR && r != SOAP_EAGAIN && r != SOAP_EWOULDBLOCK)
{ soap->errnum = r;
return 0;
@@ -952,14 +955,14 @@ frecv(struct soap *soap, char *s, size_t n)
}
#if defined(WITH_OPENSSL)
if (soap->ssl && err == SSL_ERROR_WANT_WRITE)
- r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, soap->recv_timeout ? soap->recv_timeout : 5);
+ r = tcp_select(soap, sk, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, soap->recv_timeout ? soap->recv_timeout : 5);
else
#elif defined(WITH_GNUTLS)
if (soap->session && gnutls_record_get_direction(soap->session))
- r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, soap->recv_timeout ? soap->recv_timeout : 5);
+ r = tcp_select(soap, sk, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, soap->recv_timeout ? soap->recv_timeout : 5);
else
#endif
- r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, soap->recv_timeout ? soap->recv_timeout : 5);
+ r = tcp_select(soap, sk, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, soap->recv_timeout ? soap->recv_timeout : 5);
if (!r && soap->recv_timeout)
return 0;
if (r < 0)
@@ -970,7 +973,7 @@ frecv(struct soap *soap, char *s, size_t n)
if (retries-- <= 0)
return 0;
#ifdef PALM
- r = soap_socket_errno(soap->socket);
+ r = soap_socket_errno(sk);
if (r != SOAP_EINTR && retries-- <= 0)
{ soap->errnum = r;
return 0;
@@ -1076,10 +1079,9 @@ soap_recv_raw(struct soap *soap)
}
}
else if (r != Z_BUF_ERROR)
- { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflate error: %s\n", soap->d_stream->msg?soap->d_stream->msg:SOAP_STR_EOS));
+ { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflate error: %s\n", soap->d_stream->msg ? soap->d_stream->msg : SOAP_STR_EOS));
soap->d_stream->next_out = Z_NULL;
- soap->error = SOAP_ZLIB_ERROR;
- return EOF;
+ return soap->error = SOAP_ZLIB_ERROR;
}
}
zlib_again:
@@ -1110,7 +1112,9 @@ zlib_again:
DBGMSG(RECV, soap->buf, ret);
soap->bufidx = 0;
if (!ret)
- return soap->ahead = EOF;
+ { soap->ahead = EOF;
+ return EOF;
+ }
}
else
soap->bufidx = soap->buflen;
@@ -1118,7 +1122,9 @@ zlib_again:
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Getting chunk size (idx=%u len=%u)\n", (unsigned int)soap->bufidx, (unsigned int)soap->buflen));
while (!soap_isxdigit((int)(c = soap_getchunkchar(soap))))
{ if ((int)c == EOF)
- return soap->ahead = EOF;
+ { soap->ahead = EOF;
+ return EOF;
+ }
}
do
*t++ = (char)c;
@@ -1126,7 +1132,9 @@ zlib_again:
while ((int)c != EOF && c != '\n')
c = soap_getchunkchar(soap);
if ((int)c == EOF)
- return soap->ahead = EOF;
+ { soap->ahead = EOF;
+ return EOF;
+ }
*t = '\0';
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Chunk size = %s (hex)\n", tmp));
soap->chunksize = (size_t)soap_strtoul(tmp, &t, 16);
@@ -1194,10 +1202,9 @@ zlib_again:
#endif
}
else
- { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to inflate: (%d) %s\n", r, soap->d_stream->msg?soap->d_stream->msg:SOAP_STR_EOS));
+ { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to inflate: (%d) %s\n", r, soap->d_stream->msg ? soap->d_stream->msg : SOAP_STR_EOS));
soap->d_stream->next_out = Z_NULL;
- soap->error = SOAP_ZLIB_ERROR;
- return EOF;
+ return soap->error = SOAP_ZLIB_ERROR;
}
}
#endif
@@ -1283,19 +1290,22 @@ soap_recv(struct soap *soap)
}
}
while (soap->ffilterrecv)
- { int err = soap->filterstop;
- if (err)
+ { int err, last = soap->filterstop;
+ if (last)
soap->bufidx = soap->buflen = 0;
- else
- err = soap_recv_raw(soap); /* do not call again after EOF */
- if ((soap->error = soap->ffilterrecv(soap, soap->buf, &soap->buflen, sizeof(soap->buf))))
- return soap->error;
+ if ((err = soap->ffilterrecv(soap, soap->buf, &soap->buflen, sizeof(soap->buf))))
+ return soap->error = err;
if (soap->buflen)
- { soap->filterstop = err;
+ { soap->bufidx = 0;
+ soap->filterstop = last;
return SOAP_OK;
}
- if (err)
- return err;
+ if (last)
+ { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Returning postponed error %d\n", last));
+ soap->filterstop = SOAP_OK;
+ return last;
+ }
+ soap->filterstop = soap_recv_raw(soap); /* do not call again after EOF */
}
#endif
return soap_recv_raw(soap);
@@ -1505,7 +1515,7 @@ soap_get(struct soap *soap)
{ c = soap_get0(soap);
if (c == '>')
{ soap->cdata = 0;
- soap_get1(soap);
+ c = soap_get1(soap);
c = soap_get1(soap);
}
else
@@ -1702,12 +1712,11 @@ SOAP_FMAC2
soap_getutf8(struct soap *soap)
{ register soap_wchar c, c1, c2, c3, c4;
c = soap->ahead;
- if (c > 0x7F)
- { soap->ahead = 0;
- return c;
- }
- c = soap_get(soap);
- if (c < 0x80 || (soap->mode & SOAP_ENC_LATIN))
+ if (c)
+ soap->ahead = 0;
+ else
+ c = soap_get(soap);
+ if (c < 0x80 || c > 0xFF || (soap->mode & SOAP_ENC_LATIN))
return c;
c1 = soap_get1(soap);
if (c1 < 0x80)
@@ -1896,7 +1905,7 @@ SOAP_FMAC1
unsigned char*
SOAP_FMAC2
soap_getbase64(struct soap *soap, int *n, int malloc_flag)
-{
+{ (void)malloc_flag;
#ifdef WITH_DOM
if ((soap->mode & SOAP_XML_DOM) && soap->dom)
{ soap->dom->data = soap_string_in(soap, 0, -1, -1);
@@ -1921,6 +1930,8 @@ soap_getbase64(struct soap *soap, int *n, int malloc_flag)
register int j = 0;
do
{ register soap_wchar c = soap_get(soap);
+ if (c < SOAP_AP)
+ c &= 0x7FFFFFFF;
if (c == '=' || c < 0)
{ unsigned char *p;
switch (j)
@@ -2037,14 +2048,13 @@ SOAP_FMAC2
soap_xop_forward(struct soap *soap, unsigned char **ptr, int *size, char **id, char **type, char **options)
{ /* Check MTOM xop:Include element (within hex/base64Binary) */
/* TODO: this code to be obsoleted with new import/xop.h conventions */
- int body = soap->body; /* should save type too? */
+ short body = soap->body; /* should save type too? */
if (!soap_peek_element(soap))
{ if (!soap_element_begin_in(soap, "xop:Include", 0, NULL))
- { if (soap_dime_forward(soap, ptr, size, id, type, options))
+ { if (soap_dime_forward(soap, ptr, size, id, type, options)
+ || (soap->body && soap_element_end_in(soap, "xop:Include")))
return soap->error;
}
- if (soap->body && soap_element_end_in(soap, NULL))
- return soap->error;
}
soap->body = body;
return SOAP_OK;
@@ -2176,11 +2186,14 @@ soap_pop_block(struct soap *soap, struct soap_blist *b)
#endif
/******************************************************************************/
-#ifndef WITH_NOIDREF
#ifndef PALM_1
-static void
-soap_update_ptrs(struct soap *soap, char *start, char *end, char *p1, char *p2)
-{ int i;
+SOAP_FMAC1
+void
+SOAP_FMAC2
+soap_update_pointers(struct soap *soap, char *start, char *end, char *p1, char *p2)
+{
+#ifndef WITH_NOIDREF
+ int i;
register struct soap_ilist *ip = NULL;
register struct soap_flist *fp = NULL;
#ifndef WITH_LEANER
@@ -2218,7 +2231,7 @@ soap_update_ptrs(struct soap *soap, char *start, char *end, char *p1, char *p2)
#ifndef WITH_LEANER
for (xp = soap->xlist; xp; xp = xp->next)
{ if (xp->ptr && (char*)xp->ptr >= start && (char*)xp->ptr < end)
- { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Update id='%s' %p -> %p\n", xp->id?xp->id:SOAP_STR_EOS, xp->ptr, (char*)xp->ptr + (p1-p2)));
+ { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Update id='%s' %p -> %p\n", xp->id ? xp->id : SOAP_STR_EOS, xp->ptr, (char*)xp->ptr + (p1-p2)));
xp->ptr = (unsigned char**)((char*)xp->ptr + (p1-p2));
xp->size = (int*)((char*)xp->size + (p1-p2));
xp->type = (char**)((char*)xp->type + (p1-p2));
@@ -2226,8 +2239,10 @@ soap_update_ptrs(struct soap *soap, char *start, char *end, char *p1, char *p2)
}
}
#endif
-}
+#else
+ (void)soap; (void)start; (void)end; (void)p1; (void)p2;
#endif
+}
#endif
/******************************************************************************/
@@ -2469,11 +2484,11 @@ soap_save_block(struct soap *soap, struct soap_blist *b, char *p, int flag)
if (p)
{ for (s = p, q = soap_first_block(soap, b); q; q = soap_next_block(soap, b))
{ n = soap_block_size(soap, b);
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy %u bytes from %p to %p\n", (unsigned int)n, q, s));
#ifndef WITH_NOIDREF
if (flag)
- soap_update_ptrs(soap, q, q + n, s, q);
+ soap_update_pointers(soap, q, q + n, s, q);
#endif
- DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy %u bytes from %p to %p\n", (unsigned int)n, q, s));
memcpy(s, q, n);
s += n;
}
@@ -2701,12 +2716,7 @@ soap_push_namespace(struct soap *soap, const char *id, const char *ns)
if (p)
{ for (i = 0; p->id; p++, i++)
{ if (p->ns && !strcmp(ns, p->ns))
- { if (p->out)
- { SOAP_FREE(soap, p->out);
- p->out = NULL;
- }
break;
- }
if (p->out)
{ if (!strcmp(ns, p->out))
break;
@@ -2733,10 +2743,10 @@ soap_push_namespace(struct soap *soap, const char *id, const char *ns)
soap->nlist = np;
np->level = soap->level;
np->index = i;
- strcpy(np->id, id);
+ strcpy((char*)np->id, id);
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push namespace binding (level=%u) '%s' '%s'\n", soap->level, id, ns));
if (i < 0)
- { np->ns = strcpy(np->id + n + 1, ns);
+ { np->ns = strcpy((char*)np->id + n + 1, ns);
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push NOT OK: no match found for '%s' in namespace mapping table (added to stack anyway)\n", ns));
}
else
@@ -3067,6 +3077,7 @@ soap_ssl_init()
#ifdef WITH_OPENSSL
SSL_library_init();
OpenSSL_add_all_algorithms(); /* 2.8.1 change (wsseapi.c) */
+ OpenSSL_add_all_digests();
#ifndef WITH_LEAN
SSL_load_error_strings();
#endif
@@ -3122,7 +3133,11 @@ soap_ssl_error(struct soap *soap, int ret)
strcpy(soap->msgbuf, "EOF was observed that violates the protocol. The client probably provided invalid authentication information.");
break;
case -1:
+#ifdef HAVE_SNPRINTF
+ soap_snprintf(soap->msgbuf, sizeof(soap->msgbuf), "Error observed by underlying BIO: %s", strerror(errno));
+#else
sprintf(soap->msgbuf, "Error observed by underlying BIO: %s", strerror(errno));
+#endif
break;
}
}
@@ -3333,12 +3348,22 @@ ssl_verify_callback(int ok, X509_STORE_CTX *store)
#ifdef SOAP_DEBUG
if (!ok)
{ char buf[1024];
+ int err = X509_STORE_CTX_get_error(store);
X509 *cert = X509_STORE_CTX_get_current_cert(store);
- fprintf(stderr, "SSL verify error or warning with certificate at depth %d: %s\n", X509_STORE_CTX_get_error_depth(store), X509_verify_cert_error_string(X509_STORE_CTX_get_error(store)));
+ fprintf(stderr, "SSL verify error or warning with certificate at depth %d: %s\n", X509_STORE_CTX_get_error_depth(store), X509_verify_cert_error_string(err));
X509_NAME_oneline(X509_get_issuer_name(cert), buf, sizeof(buf));
fprintf(stderr, "certificate issuer %s\n", buf);
X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
fprintf(stderr, "certificate subject %s\n", buf);
+ /* accept self signed certificates and certificates out of date */
+ switch (err)
+ { case X509_V_ERR_CERT_NOT_YET_VALID:
+ case X509_V_ERR_CERT_HAS_EXPIRED:
+ case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+ case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
+ X509_STORE_CTX_set_error(store, X509_V_OK);
+ ok = 1;
+ }
}
#endif
/* Note: return 1 to continue, but unsafe progress will be terminated by OpenSSL */
@@ -3353,13 +3378,16 @@ ssl_verify_callback(int ok, X509_STORE_CTX *store)
static int
ssl_verify_callback_allow_expired_certificate(int ok, X509_STORE_CTX *store)
{ ok = ssl_verify_callback(ok, store);
- if (ok == 0 && X509_STORE_CTX_get_error(store) == X509_V_ERR_CERT_HAS_EXPIRED)
- {
-#ifdef SOAP_DEBUG
- fprintf(stderr, "ignoring certificate expiration\n");
-#endif
- X509_STORE_CTX_set_error(store, X509_V_OK);
- ok = 1;
+ if (!ok)
+ { /* accept self signed certificates and certificates out of date */
+ switch (X509_STORE_CTX_get_error(store))
+ { case X509_V_ERR_CERT_NOT_YET_VALID:
+ case X509_V_ERR_CERT_HAS_EXPIRED:
+ case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+ case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
+ X509_STORE_CTX_set_error(store, X509_V_OK);
+ ok = 1;
+ }
}
/* Note: return 1 to continue, but unsafe progress will be terminated by SSL */
return ok;
@@ -3414,11 +3442,11 @@ SOAP_FMAC1
int
SOAP_FMAC2
soap_ssl_accept(struct soap *soap)
-{ SOAP_SOCKET fd = soap->socket;
+{ SOAP_SOCKET sk = soap->socket;
#ifdef WITH_OPENSSL
BIO *bio;
int retries, r, s;
- if (!soap_valid_socket(fd))
+ if (!soap_valid_socket(sk))
return soap_set_receiver_error(soap, "SSL/TLS error", "No socket in soap_ssl_accept()", SOAP_SSL_ERROR);
soap->ssl_flags &= ~SOAP_SSL_CLIENT;
if (!soap->ctx && (soap->error = soap->fsslauth(soap)))
@@ -3430,12 +3458,12 @@ soap_ssl_accept(struct soap *soap)
}
else
SSL_clear(soap->ssl);
- bio = BIO_new_socket((int)fd, BIO_NOCLOSE);
+ bio = BIO_new_socket((int)sk, BIO_NOCLOSE);
SSL_set_bio(soap->ssl, bio, bio);
/* Set SSL sockets to non-blocking */
retries = 0;
if (soap->accept_timeout)
- { SOAP_SOCKNONBLOCK(fd)
+ { SOAP_SOCKNONBLOCK(sk)
retries = 10*soap->accept_timeout;
}
if (retries <= 0)
@@ -3447,14 +3475,14 @@ soap_ssl_accept(struct soap *soap)
err = SSL_get_error(soap->ssl, r);
if (err == SSL_ERROR_WANT_ACCEPT || err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
{ if (err == SSL_ERROR_WANT_READ)
- s = tcp_select(soap, fd, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, -100000);
+ s = tcp_select(soap, sk, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, -100000);
else
- s = tcp_select(soap, fd, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, -100000);
+ s = tcp_select(soap, sk, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, -100000);
if (s < 0 && soap->errnum != SOAP_EINTR)
break;
}
else
- { soap->errnum = soap_socket_errno(fd);
+ { soap->errnum = soap_socket_errno(sk);
break;
}
}
@@ -3480,17 +3508,17 @@ soap_ssl_accept(struct soap *soap)
#endif
#ifdef WITH_GNUTLS
int retries = 0, r;
- if (!soap_valid_socket(fd))
+ if (!soap_valid_socket(sk))
return soap_set_receiver_error(soap, "SSL/TLS error", "No socket in soap_ssl_accept()", SOAP_SSL_ERROR);
soap->ssl_flags &= ~SOAP_SSL_CLIENT;
if (!soap->session && (soap->error = soap->fsslauth(soap)))
{ soap_closesock(soap);
return soap->error;
}
- gnutls_transport_set_ptr(soap->session, (gnutls_transport_ptr_t)(long)fd);
+ gnutls_transport_set_ptr(soap->session, (gnutls_transport_ptr_t)(long)sk);
/* Set SSL sockets to non-blocking */
if (soap->accept_timeout)
- { SOAP_SOCKNONBLOCK(fd)
+ { SOAP_SOCKNONBLOCK(sk)
retries = 10*soap->accept_timeout;
}
if (retries <= 0)
@@ -3502,14 +3530,14 @@ soap_ssl_accept(struct soap *soap)
break;
if (r == GNUTLS_E_AGAIN || r == GNUTLS_E_INTERRUPTED)
{ if (!gnutls_record_get_direction(soap->session))
- s = tcp_select(soap, fd, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, -100000);
+ s = tcp_select(soap, sk, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, -100000);
else
- s = tcp_select(soap, fd, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, -100000);
+ s = tcp_select(soap, sk, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, -100000);
if (s < 0 && soap->errnum != SOAP_EINTR)
break;
}
else
- { soap->errnum = soap_socket_errno(fd);
+ { soap->errnum = soap_socket_errno(sk);
break;
}
}
@@ -3526,9 +3554,9 @@ soap_ssl_accept(struct soap *soap)
}
#endif
if (soap->recv_timeout || soap->send_timeout)
- SOAP_SOCKNONBLOCK(fd)
+ SOAP_SOCKNONBLOCK(sk)
else
- SOAP_SOCKBLOCK(fd)
+ SOAP_SOCKBLOCK(sk)
soap->imode |= SOAP_ENC_SSL;
soap->omode |= SOAP_ENC_SSL;
return SOAP_OK;
@@ -3672,7 +3700,7 @@ tcp_connect(struct soap *soap, const char *endpoint, const char *host, int port)
#ifdef WITH_IPV6
struct addrinfo hints, *res, *ressave;
#endif
- SOAP_SOCKET fd;
+ SOAP_SOCKET sk;
int err = 0;
#ifndef WITH_LEAN
#ifndef WIN32
@@ -3714,7 +3742,7 @@ tcp_connect(struct soap *soap, const char *endpoint, const char *host, int port)
}
ressave = res;
again:
- fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ sk = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
soap->errmode = 0;
#else
#ifndef WITH_LEAN
@@ -3722,12 +3750,12 @@ again:
#endif
#ifndef WITH_LEAN
if ((soap->omode & SOAP_IO_UDP))
- fd = socket(AF_INET, SOCK_DGRAM, 0);
+ sk = socket(AF_INET, SOCK_DGRAM, 0);
else
#endif
- fd = socket(AF_INET, SOCK_STREAM, 0);
+ sk = socket(AF_INET, SOCK_STREAM, 0);
#endif
- if (!soap_valid_socket(fd))
+ if (!soap_valid_socket(sk))
{
#ifdef WITH_IPV6
if (res->ai_next)
@@ -3735,7 +3763,7 @@ again:
goto again;
}
#endif
- soap->errnum = soap_socket_errno(fd);
+ soap->errnum = soap_socket_errno(sk);
soap_set_sender_error(soap, tcp_error(soap), "socket failed in tcp_connect()", SOAP_TCP_ERROR);
#ifdef WITH_IPV6
freeaddrinfo(ressave);
@@ -3745,10 +3773,10 @@ again:
#ifdef SOCKET_CLOSE_ON_EXEC
#ifdef WIN32
#ifndef UNDER_CE
- SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0);
+ SetHandleInformation((HANDLE)sk, HANDLE_FLAG_INHERIT, 0);
#endif
#else
- fcntl(fd, F_SETFD, 1);
+ fcntl(sk, F_SETFD, 1);
#endif
#endif
#ifndef WITH_LEAN
@@ -3757,57 +3785,57 @@ again:
memset((void*)&linger, 0, sizeof(linger));
linger.l_onoff = 1;
linger.l_linger = soap->linger_time;
- if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(struct linger)))
- { soap->errnum = soap_socket_errno(fd);
+ if (setsockopt(sk, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(struct linger)))
+ { soap->errnum = soap_socket_errno(sk);
soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_LINGER failed in tcp_connect()", SOAP_TCP_ERROR);
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
#ifdef WITH_IPV6
freeaddrinfo(ressave);
#endif
return SOAP_INVALID_SOCKET;
}
}
- else if (soap->connect_flags && setsockopt(fd, SOL_SOCKET, soap->connect_flags, (char*)&set, sizeof(int)))
- { soap->errnum = soap_socket_errno(fd);
+ else if (soap->connect_flags && setsockopt(sk, SOL_SOCKET, soap->connect_flags, (char*)&set, sizeof(int)))
+ { soap->errnum = soap_socket_errno(sk);
soap_set_sender_error(soap, tcp_error(soap), "setsockopt failed in tcp_connect()", SOAP_TCP_ERROR);
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
#ifdef WITH_IPV6
freeaddrinfo(ressave);
#endif
return SOAP_INVALID_SOCKET;
}
- if ((soap->keep_alive || soap->tcp_keep_alive) && setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int)))
- { soap->errnum = soap_socket_errno(fd);
+ if ((soap->keep_alive || soap->tcp_keep_alive) && setsockopt(sk, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int)))
+ { soap->errnum = soap_socket_errno(sk);
soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in tcp_connect()", SOAP_TCP_ERROR);
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
#ifdef WITH_IPV6
freeaddrinfo(ressave);
#endif
return SOAP_INVALID_SOCKET;
}
- if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int)))
- { soap->errnum = soap_socket_errno(fd);
+ if (setsockopt(sk, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int)))
+ { soap->errnum = soap_socket_errno(sk);
soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in tcp_connect()", SOAP_TCP_ERROR);
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
#ifdef WITH_IPV6
freeaddrinfo(ressave);
#endif
return SOAP_INVALID_SOCKET;
}
- if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int)))
- { soap->errnum = soap_socket_errno(fd);
+ if (setsockopt(sk, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int)))
+ { soap->errnum = soap_socket_errno(sk);
soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in tcp_connect()", SOAP_TCP_ERROR);
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
#ifdef WITH_IPV6
freeaddrinfo(ressave);
#endif
return SOAP_INVALID_SOCKET;
}
#ifdef TCP_KEEPIDLE
- if (soap->tcp_keep_idle && setsockopt((SOAP_SOCKET)fd, IPPROTO_TCP, TCP_KEEPIDLE, (char*)&(soap->tcp_keep_idle), sizeof(int)))
- { soap->errnum = soap_socket_errno(fd);
+ if (soap->tcp_keep_idle && setsockopt((SOAP_SOCKET)sk, IPPROTO_TCP, TCP_KEEPIDLE, (char*)&(soap->tcp_keep_idle), sizeof(int)))
+ { soap->errnum = soap_socket_errno(sk);
soap_set_sender_error(soap, tcp_error(soap), "setsockopt TCP_KEEPIDLE failed in tcp_connect()", SOAP_TCP_ERROR);
- soap->fclosesocket(soap, (SOAP_SOCKET)fd);
+ soap->fclosesocket(soap, (SOAP_SOCKET)sk);
#ifdef WITH_IPV6
freeaddrinfo(ressave);
#endif
@@ -3815,10 +3843,10 @@ again:
}
#endif
#ifdef TCP_KEEPINTVL
- if (soap->tcp_keep_intvl && setsockopt((SOAP_SOCKET)fd, IPPROTO_TCP, TCP_KEEPINTVL, (char*)&(soap->tcp_keep_intvl), sizeof(int)))
- { soap->errnum = soap_socket_errno(fd);
+ if (soap->tcp_keep_intvl && setsockopt((SOAP_SOCKET)sk, IPPROTO_TCP, TCP_KEEPINTVL, (char*)&(soap->tcp_keep_intvl), sizeof(int)))
+ { soap->errnum = soap_socket_errno(sk);
soap_set_sender_error(soap, tcp_error(soap), "setsockopt TCP_KEEPINTVL failed in tcp_connect()", SOAP_TCP_ERROR);
- soap->fclosesocket(soap, (SOAP_SOCKET)fd);
+ soap->fclosesocket(soap, (SOAP_SOCKET)sk);
#ifdef WITH_IPV6
freeaddrinfo(ressave);
#endif
@@ -3826,10 +3854,10 @@ again:
}
#endif
#ifdef TCP_KEEPCNT
- if (soap->tcp_keep_cnt && setsockopt((SOAP_SOCKET)fd, IPPROTO_TCP, TCP_KEEPCNT, (char*)&(soap->tcp_keep_cnt), sizeof(int)))
- { soap->errnum = soap_socket_errno(fd);
+ if (soap->tcp_keep_cnt && setsockopt((SOAP_SOCKET)sk, IPPROTO_TCP, TCP_KEEPCNT, (char*)&(soap->tcp_keep_cnt), sizeof(int)))
+ { soap->errnum = soap_socket_errno(sk);
soap_set_sender_error(soap, tcp_error(soap), "setsockopt TCP_KEEPCNT failed in tcp_connect()", SOAP_TCP_ERROR);
- soap->fclosesocket(soap, (SOAP_SOCKET)fd);
+ soap->fclosesocket(soap, (SOAP_SOCKET)sk);
#ifdef WITH_IPV6
freeaddrinfo(ressave);
#endif
@@ -3837,10 +3865,10 @@ again:
}
#endif
#ifdef TCP_NODELAY
- if (!(soap->omode & SOAP_IO_UDP) && setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int)))
- { soap->errnum = soap_socket_errno(fd);
+ if (!(soap->omode & SOAP_IO_UDP) && setsockopt(sk, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int)))
+ { soap->errnum = soap_socket_errno(sk);
soap_set_sender_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in tcp_connect()", SOAP_TCP_ERROR);
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
#ifdef WITH_IPV6
freeaddrinfo(ressave);
#endif
@@ -3857,29 +3885,29 @@ again:
if ((soap->omode & SOAP_IO_UDP))
{ if (soap->ipv4_multicast_ttl)
{ unsigned char ttl = soap->ipv4_multicast_ttl;
- if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ttl, sizeof(ttl)))
- { soap->errnum = soap_socket_errno(fd);
+ if (setsockopt(sk, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ttl, sizeof(ttl)))
+ { soap->errnum = soap_socket_errno(sk);
soap_set_sender_error(soap, tcp_error(soap), "setsockopt IP_MULTICAST_TTL failed in tcp_connect()", SOAP_TCP_ERROR);
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
return SOAP_INVALID_SOCKET;
}
}
if ((soap->omode & SOAP_IO_UDP) && soap->ipv4_multicast_if && !soap->ipv6_multicast_if)
- { if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (char*)soap->ipv4_multicast_if, sizeof(struct in_addr)))
+ { if (setsockopt(sk, IPPROTO_IP, IP_MULTICAST_IF, (char*)soap->ipv4_multicast_if, sizeof(struct in_addr)))
#ifndef WINDOWS
- { soap->errnum = soap_socket_errno(fd);
+ { soap->errnum = soap_socket_errno(sk);
soap_set_sender_error(soap, tcp_error(soap), "setsockopt IP_MULTICAST_IF failed in tcp_connect()", SOAP_TCP_ERROR);
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
return SOAP_INVALID_SOCKET;
}
#else
#ifndef IP_MULTICAST_IF
#define IP_MULTICAST_IF 2
#endif
- if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (char*)soap->ipv4_multicast_if, sizeof(struct in_addr)))
- { soap->errnum = soap_socket_errno(fd);
+ if (setsockopt(sk, IPPROTO_IP, IP_MULTICAST_IF, (char*)soap->ipv4_multicast_if, sizeof(struct in_addr)))
+ { soap->errnum = soap_socket_errno(sk);
soap_set_sender_error(soap, tcp_error(soap), "setsockopt IP_MULTICAST_IF failed in tcp_connect()", SOAP_TCP_ERROR);
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
return SOAP_INVALID_SOCKET;
}
#endif
@@ -3887,7 +3915,7 @@ again:
}
#endif
#endif
- DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Opening socket %d to host='%s' port=%d\n", fd, host, port));
+ DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Opening socket %d to host='%s' port=%d\n", sk, host, port));
#ifndef WITH_IPV6
soap->peerlen = sizeof(soap->peer);
memset((void*)&soap->peer, 0, sizeof(soap->peer));
@@ -3896,7 +3924,7 @@ again:
if (soap->proxy_host)
{ if (soap->fresolve(soap, soap->proxy_host, &soap->peer.sin_addr))
{ soap_set_sender_error(soap, tcp_error(soap), "get proxy host by name failed in tcp_connect()", SOAP_TCP_ERROR);
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
return SOAP_INVALID_SOCKET;
}
soap->peer.sin_port = htons((short)soap->proxy_port);
@@ -3904,7 +3932,7 @@ again:
else
{ if (soap->fresolve(soap, host, &soap->peer.sin_addr))
{ soap_set_sender_error(soap, tcp_error(soap), "get host by name failed in tcp_connect()", SOAP_TCP_ERROR);
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
return SOAP_INVALID_SOCKET;
}
soap->peer.sin_port = htons((short)port);
@@ -3912,34 +3940,34 @@ again:
soap->errmode = 0;
#ifndef WITH_LEAN
if ((soap->omode & SOAP_IO_UDP))
- return fd;
+ return sk;
#endif
#else
if ((soap->omode & SOAP_IO_UDP))
{ memcpy(&soap->peer, res->ai_addr, res->ai_addrlen);
soap->peerlen = res->ai_addrlen;
freeaddrinfo(ressave);
- return fd;
+ return sk;
}
#endif
#ifndef WITH_LEAN
if (soap->connect_timeout)
- SOAP_SOCKNONBLOCK(fd)
+ SOAP_SOCKNONBLOCK(sk)
else
- SOAP_SOCKBLOCK(fd)
+ SOAP_SOCKBLOCK(sk)
retries = 10;
#endif
for (;;)
{
#ifdef WITH_IPV6
- if (connect(fd, res->ai_addr, (int)res->ai_addrlen))
+ if (connect(sk, res->ai_addr, (int)res->ai_addrlen))
#else
- if (connect(fd, (struct sockaddr*)&soap->peer, sizeof(soap->peer)))
+ if (connect(sk, (struct sockaddr*)&soap->peer, sizeof(soap->peer)))
#endif
- { err = soap_socket_errno(fd);
+ { err = soap_socket_errno(sk);
#ifndef WITH_LEAN
if (err == SOAP_EADDRINUSE)
- { soap->fclosesocket(soap, fd);
+ { soap->fclosesocket(soap, sk);
if (retries-- > 0)
goto again;
}
@@ -3948,13 +3976,13 @@ again:
SOAP_SOCKLEN_T k;
for (;;)
{ register int r;
- r = tcp_select(soap, fd, SOAP_TCP_SELECT_SND, soap->connect_timeout);
+ r = tcp_select(soap, sk, SOAP_TCP_SELECT_SND, soap->connect_timeout);
if (r > 0)
break;
if (!r)
{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connect timeout\n"));
soap_set_sender_error(soap, "Timeout", "connect failed in tcp_connect()", SOAP_TCP_ERROR);
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
#ifdef WITH_IPV6
freeaddrinfo(ressave);
#endif
@@ -3964,7 +3992,7 @@ again:
if (r != SOAP_EINTR)
{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n"));
soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR);
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
#ifdef WITH_IPV6
freeaddrinfo(ressave);
#endif
@@ -3972,13 +4000,13 @@ again:
}
}
k = (SOAP_SOCKLEN_T)sizeof(soap->errnum);
- if (!getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&soap->errnum, &k) && !soap->errnum) /* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */
+ if (!getsockopt(sk, SOL_SOCKET, SO_ERROR, (char*)&soap->errnum, &k) && !soap->errnum) /* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */
break;
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n"));
if (!soap->errnum)
- soap->errnum = soap_socket_errno(fd);
+ soap->errnum = soap_socket_errno(sk);
soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR);
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
#ifdef WITH_IPV6
freeaddrinfo(ressave);
#endif
@@ -3988,7 +4016,7 @@ again:
#ifdef WITH_IPV6
if (res->ai_next)
{ res = res->ai_next;
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
goto again;
}
#endif
@@ -3996,7 +4024,7 @@ again:
{ soap->errnum = err;
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n"));
soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR);
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
#ifdef WITH_IPV6
freeaddrinfo(ressave);
#endif
@@ -4010,7 +4038,7 @@ again:
soap->peerlen = 0; /* IPv6: already connected so use send() */
freeaddrinfo(ressave);
#endif
- soap->socket = fd;
+ soap->socket = sk;
soap->imode &= ~SOAP_ENC_SSL;
soap->omode &= ~SOAP_ENC_SSL;
if (!soap_tag_cmp(endpoint, "https:*"))
@@ -4025,46 +4053,45 @@ again:
soap_mode om = soap->omode; /* make sure we only parse HTTP */
size_t n = soap->count; /* save the content length */
const char *userid, *passwd;
+ int status = soap->status; /* save the current status/command */
+ short keep_alive = soap->keep_alive; /* save the KA status */
soap->omode &= ~SOAP_ENC; /* mask IO and ENC */
soap->omode |= SOAP_IO_BUFFER;
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connecting to %s proxy server\n", soap->proxy_http_version));
- sprintf(soap->tmpbuf, "CONNECT %s:%d HTTP/%s", host, port, soap->proxy_http_version);
- if (soap_begin_send(soap)
- || (soap->error = soap->fposthdr(soap, soap->tmpbuf, NULL)))
- { soap->fclosesocket(soap, fd);
- return SOAP_INVALID_SOCKET;
- }
-#ifndef WITH_LEAN
- if (soap->proxy_userid && soap->proxy_passwd && strlen(soap->proxy_userid) + strlen(soap->proxy_passwd) < 761)
- { sprintf(soap->tmpbuf + 262, "%s:%s", soap->proxy_userid, soap->proxy_passwd);
- strcpy(soap->tmpbuf, "Basic ");
- soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, (int)strlen(soap->tmpbuf + 262));
- if ((soap->error = soap->fposthdr(soap, "Proxy-Authorization", soap->tmpbuf)))
- { soap->fclosesocket(soap, fd);
+#ifdef WITH_NTLM
+ if (soap->ntlm_challenge)
+ { if (soap_ntlm_handshake(soap, SOAP_CONNECT, endpoint, host, port))
return soap->error;
- }
}
#endif
- if ((soap->error = soap->fposthdr(soap, NULL, NULL))
- || soap_flush(soap))
- { soap->fclosesocket(soap, fd);
+ if (soap_begin_send(soap))
+ { soap->fclosesocket(soap, sk);
+ return SOAP_INVALID_SOCKET;
+ }
+ soap->status = SOAP_CONNECT;
+ soap->keep_alive = 1;
+ if ((soap->error = soap->fpost(soap, endpoint, host, port, NULL, NULL, 0))
+ || soap_end_send(soap))
+ { soap->fclosesocket(soap, sk);
return SOAP_INVALID_SOCKET;
}
+ soap->keep_alive = keep_alive;
soap->omode = om;
om = soap->imode;
soap->imode &= ~SOAP_ENC; /* mask IO and ENC */
userid = soap->userid; /* preserve */
passwd = soap->passwd; /* preserve */
if ((soap->error = soap->fparse(soap)))
- { soap->fclosesocket(soap, fd);
+ { soap->fclosesocket(soap, sk);
return SOAP_INVALID_SOCKET;
}
+ soap->status = status; /* restore */
soap->userid = userid; /* restore */
soap->passwd = passwd; /* restore */
soap->imode = om; /* restore */
soap->count = n; /* restore */
if (soap_begin_send(soap))
- { soap->fclosesocket(soap, fd);
+ { soap->fclosesocket(soap, sk);
return SOAP_INVALID_SOCKET;
}
if (endpoint)
@@ -4074,13 +4101,15 @@ again:
#ifdef WITH_OPENSSL
soap->ssl_flags |= SOAP_SSL_CLIENT;
if (!soap->ctx && (soap->error = soap->fsslauth(soap)))
- { soap->fclosesocket(soap, fd);
+ { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "SSL required, but no ctx set\n"));
+ soap->fclosesocket(soap, sk);
+ soap->error = SOAP_SSL_ERROR;
return SOAP_INVALID_SOCKET;
}
if (!soap->ssl)
{ soap->ssl = SSL_new(soap->ctx);
if (!soap->ssl)
- { soap->fclosesocket(soap, fd);
+ { soap->fclosesocket(soap, sk);
soap->error = SOAP_SSL_ERROR;
return SOAP_INVALID_SOCKET;
}
@@ -4095,16 +4124,16 @@ again:
}
soap->imode |= SOAP_ENC_SSL;
soap->omode |= SOAP_ENC_SSL;
- bio = BIO_new_socket((int)fd, BIO_NOCLOSE);
+ bio = BIO_new_socket((int)sk, BIO_NOCLOSE);
SSL_set_bio(soap->ssl, bio, bio);
/* Connect timeout: set SSL sockets to non-blocking */
retries = 0;
if (soap->connect_timeout)
- { SOAP_SOCKNONBLOCK(fd)
+ { SOAP_SOCKNONBLOCK(sk)
retries = 10*soap->connect_timeout;
}
else
- SOAP_SOCKBLOCK(fd)
+ SOAP_SOCKBLOCK(sk)
if (retries <= 0)
retries = 100; /* timeout: 10 sec retries, 100 times 0.1 sec */
/* Try connecting until success or timeout (when nonblocking) */
@@ -4114,37 +4143,37 @@ again:
if (err == SSL_ERROR_WANT_CONNECT || err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
{ register int s;
if (err == SSL_ERROR_WANT_READ)
- s = tcp_select(soap, fd, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, -100000);
+ s = tcp_select(soap, sk, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, -100000);
else
- s = tcp_select(soap, fd, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, -100000);
+ s = tcp_select(soap, sk, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, -100000);
if (s < 0 && soap->errnum != SOAP_EINTR)
{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "SSL_connect/select error in tcp_connect\n"));
soap_set_sender_error(soap, soap_ssl_error(soap, r), "SSL_connect failed in tcp_connect()", SOAP_TCP_ERROR);
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
return SOAP_INVALID_SOCKET;
}
if (s == 0 && retries-- <= 0)
{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "SSL/TLS connect timeout\n"));
soap_set_sender_error(soap, "Timeout", "SSL_connect failed in tcp_connect()", SOAP_TCP_ERROR);
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
return SOAP_INVALID_SOCKET;
}
}
else
{ soap_set_sender_error(soap, soap_ssl_error(soap, r), "SSL_connect error in tcp_connect()", SOAP_SSL_ERROR);
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
return SOAP_INVALID_SOCKET;
}
}
} while (!SSL_is_init_finished(soap->ssl));
/* Set SSL sockets to nonblocking */
- SOAP_SOCKNONBLOCK(fd)
+ SOAP_SOCKNONBLOCK(sk)
/* Check server credentials when required */
if ((soap->ssl_flags & SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION))
{ int err;
if ((err = SSL_get_verify_result(soap->ssl)) != X509_V_OK)
{ soap_set_sender_error(soap, X509_verify_cert_error_string(err), "SSL/TLS certificate presented by peer cannot be verified in tcp_connect()", SOAP_SSL_ERROR);
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
return SOAP_INVALID_SOCKET;
}
if (!(soap->ssl_flags & SOAP_SSL_SKIP_HOST_CHECK))
@@ -4155,7 +4184,7 @@ again:
peer = SSL_get_peer_certificate(soap->ssl);
if (!peer)
{ soap_set_sender_error(soap, "SSL/TLS error", "No SSL/TLS certificate was presented by the peer in tcp_connect()", SOAP_SSL_ERROR);
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
return SOAP_INVALID_SOCKET;
}
ext_count = X509_get_ext_count(peer);
@@ -4249,7 +4278,7 @@ again:
X509_free(peer);
if (!ok)
{ soap_set_sender_error(soap, "SSL/TLS error", "SSL/TLS certificate host name mismatch in tcp_connect()", SOAP_SSL_ERROR);
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
return SOAP_INVALID_SOCKET;
}
}
@@ -4258,17 +4287,17 @@ again:
#ifdef WITH_GNUTLS
soap->ssl_flags |= SOAP_SSL_CLIENT;
if (!soap->session && (soap->error = soap->fsslauth(soap)))
- { soap->fclosesocket(soap, fd);
+ { soap->fclosesocket(soap, sk);
return SOAP_INVALID_SOCKET;
}
- gnutls_transport_set_ptr(soap->session, (gnutls_transport_ptr_t)(long)fd);
+ gnutls_transport_set_ptr(soap->session, (gnutls_transport_ptr_t)(long)sk);
/* Set SSL sockets to non-blocking */
if (soap->connect_timeout)
- { SOAP_SOCKNONBLOCK(fd)
+ { SOAP_SOCKNONBLOCK(sk)
retries = 10*soap->connect_timeout;
}
else
- SOAP_SOCKBLOCK(fd)
+ SOAP_SOCKBLOCK(sk)
if (retries <= 0)
retries = 100; /* timeout: 10 sec retries, 100 times 0.1 sec */
while ((r = gnutls_handshake(soap->session)))
@@ -4278,42 +4307,42 @@ again:
break;
if (r == GNUTLS_E_AGAIN || r == GNUTLS_E_INTERRUPTED)
{ if (!gnutls_record_get_direction(soap->session))
- s = tcp_select(soap, fd, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, -100000);
+ s = tcp_select(soap, sk, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, -100000);
else
- s = tcp_select(soap, fd, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, -100000);
+ s = tcp_select(soap, sk, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, -100000);
if (s < 0 && soap->errnum != SOAP_EINTR)
break;
}
else
- { soap->errnum = soap_socket_errno(fd);
+ { soap->errnum = soap_socket_errno(sk);
break;
}
}
if (r)
{ soap_set_sender_error(soap, soap_ssl_error(soap, r), "SSL/TLS handshake failed", SOAP_SSL_ERROR);
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
return SOAP_INVALID_SOCKET;
}
if ((soap->ssl_flags & SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION))
{ const char *err = ssl_verify(soap, host);
if (err)
- { soap->fclosesocket(soap, fd);
+ { soap->fclosesocket(soap, sk);
soap->error = soap_set_sender_error(soap, "SSL/TLS error", err, SOAP_SSL_ERROR);
return SOAP_INVALID_SOCKET;
}
}
#endif
#else
- soap->fclosesocket(soap, fd);
+ soap->fclosesocket(soap, sk);
soap->error = SOAP_SSL_ERROR;
return SOAP_INVALID_SOCKET;
#endif
}
if (soap->recv_timeout || soap->send_timeout)
- SOAP_SOCKNONBLOCK(fd)
+ SOAP_SOCKNONBLOCK(sk)
else
- SOAP_SOCKBLOCK(fd)
- return fd;
+ SOAP_SOCKBLOCK(sk)
+ return sk;
}
#endif
#endif
@@ -4322,7 +4351,7 @@ again:
#ifndef WITH_NOIO
#ifndef PALM_1
static int
-tcp_select(struct soap *soap, SOAP_SOCKET s, int flags, int timeout)
+tcp_select(struct soap *soap, SOAP_SOCKET sk, int flags, int timeout)
{ register int r;
struct timeval tv;
fd_set fd[3], *rfd, *sfd, *efd;
@@ -4333,12 +4362,12 @@ tcp_select(struct soap *soap, SOAP_SOCKET s, int flags, int timeout)
if (1)
#else
/* if fd max set size exceeded, use poll() */
- if ((int)s >= (int)FD_SETSIZE)
+ if ((int)sk >= (int)FD_SETSIZE)
#endif
#ifdef HAVE_POLL
{ struct pollfd pollfd;
int retries = 0;
- pollfd.fd = (int)s;
+ pollfd.fd = (int)sk;
pollfd.events = 0;
if (flags & SOAP_TCP_SELECT_RCV)
pollfd.events |= POLLIN;
@@ -4379,17 +4408,17 @@ tcp_select(struct soap *soap, SOAP_SOCKET s, int flags, int timeout)
if (flags & SOAP_TCP_SELECT_RCV)
{ rfd = &fd[0];
FD_ZERO(rfd);
- FD_SET(s, rfd);
+ FD_SET(sk, rfd);
}
if (flags & SOAP_TCP_SELECT_SND)
{ sfd = &fd[1];
FD_ZERO(sfd);
- FD_SET(s, sfd);
+ FD_SET(sk, sfd);
}
if (flags & SOAP_TCP_SELECT_ERR)
{ efd = &fd[2];
FD_ZERO(efd);
- FD_SET(s, efd);
+ FD_SET(sk, efd);
}
if (timeout >= 0)
{ tv.tv_sec = timeout;
@@ -4399,14 +4428,14 @@ tcp_select(struct soap *soap, SOAP_SOCKET s, int flags, int timeout)
{ tv.tv_sec = -timeout / 1000000;
tv.tv_usec = -timeout % 1000000;
}
- r = select((int)s + 1, rfd, sfd, efd, &tv);
+ r = select((int)sk + 1, rfd, sfd, efd, &tv);
if (r > 0)
{ r = 0;
- if ((flags & SOAP_TCP_SELECT_RCV) && FD_ISSET(s, rfd))
+ if ((flags & SOAP_TCP_SELECT_RCV) && FD_ISSET(sk, rfd))
r |= SOAP_TCP_SELECT_RCV;
- if ((flags & SOAP_TCP_SELECT_SND) && FD_ISSET(s, sfd))
+ if ((flags & SOAP_TCP_SELECT_SND) && FD_ISSET(sk, sfd))
r |= SOAP_TCP_SELECT_SND;
- if ((flags & SOAP_TCP_SELECT_ERR) && FD_ISSET(s, efd))
+ if ((flags & SOAP_TCP_SELECT_ERR) && FD_ISSET(sk, efd))
r |= SOAP_TCP_SELECT_ERR;
}
else if (r < 0)
@@ -4421,18 +4450,19 @@ tcp_select(struct soap *soap, SOAP_SOCKET s, int flags, int timeout)
#ifndef PALM_1
static SOAP_SOCKET
tcp_accept(struct soap *soap, SOAP_SOCKET s, struct sockaddr *a, int *n)
-{ SOAP_SOCKET fd;
- fd = accept(s, a, (SOAP_SOCKLEN_T*)n); /* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */
+{ SOAP_SOCKET sk;
+ (void)soap;
+ sk = accept(s, a, (SOAP_SOCKLEN_T*)n); /* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */
#ifdef SOCKET_CLOSE_ON_EXEC
#ifdef WIN32
#ifndef UNDER_CE
- SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0);
+ SetHandleInformation((HANDLE)sk, HANDLE_FLAG_INHERIT, 0);
#endif
#else
- fcntl(fd, F_SETFD, FD_CLOEXEC);
+ fcntl(sk, F_SETFD, FD_CLOEXEC);
#endif
#endif
- return fd;
+ return sk;
}
#endif
#endif
@@ -4533,9 +4563,10 @@ tcp_disconnect(struct soap *soap)
#ifndef WITH_NOIO
#ifndef PALM_1
static int
-tcp_closesocket(struct soap *soap, SOAP_SOCKET fd)
-{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Close socket %d\n", (int)fd));
- return soap_closesocket(fd);
+tcp_closesocket(struct soap *soap, SOAP_SOCKET sk)
+{ (void)soap;
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Close socket %d\n", (int)sk));
+ return soap_closesocket(sk);
}
#endif
#endif
@@ -4544,9 +4575,10 @@ tcp_closesocket(struct soap *soap, SOAP_SOCKET fd)
#ifndef WITH_NOIO
#ifndef PALM_1
static int
-tcp_shutdownsocket(struct soap *soap, SOAP_SOCKET fd, int how)
-{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Shutdown socket %d how=%d\n", (int)fd, how));
- return shutdown(fd, how);
+tcp_shutdownsocket(struct soap *soap, SOAP_SOCKET sk, int how)
+{ (void)soap;
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Shutdown socket %d how=%d\n", (int)sk, how));
+ return shutdown(sk, how);
}
#endif
#endif
@@ -4569,7 +4601,7 @@ soap_bind(struct soap *soap, const char *host, int port, int backlog)
#endif
#endif
#ifndef WITH_LEAN
-#ifndef WITH_WIN32
+#ifndef WIN32
int len = SOAP_BUFLEN;
#else
int len = SOAP_BUFLEN + 1; /* speeds up windows xfer */
@@ -4623,6 +4655,7 @@ soap_bind(struct soap *soap, const char *host, int port, int backlog)
soap_set_receiver_error(soap, tcp_error(soap), "socket failed in soap_bind()", SOAP_TCP_ERROR);
return SOAP_INVALID_SOCKET;
}
+ soap->port = port;
#ifndef WITH_LEAN
if ((soap->omode & SOAP_IO_UDP))
soap->socket = soap->master;
@@ -4642,7 +4675,7 @@ soap_bind(struct soap *soap, const char *host, int port, int backlog)
soap_set_receiver_error(soap, tcp_error(soap), "setsockopt failed in soap_bind()", SOAP_TCP_ERROR);
return SOAP_INVALID_SOCKET;
}
- if (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) && setsockopt(soap->master, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int)))
+ if (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) && (!((soap->imode | soap->omode) & SOAP_IO_UDP)) && setsockopt(soap->master, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int)))
{ soap->errnum = soap_socket_errno(soap->master);
soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in soap_bind()", SOAP_TCP_ERROR);
return SOAP_INVALID_SOCKET;
@@ -4669,14 +4702,14 @@ soap_bind(struct soap *soap, const char *host, int port, int backlog)
#ifdef WITH_IPV6_V6ONLY
if (setsockopt(soap->master, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&set, sizeof(int)))
{ soap->errnum = soap_socket_errno(soap->master);
- soap_set_receiver_error(soap, tcp_error(soap), "setsockopt IPV6_V6ONLY failed in soap_bind()", SOAP_TCP_ERROR);
+ soap_set_receiver_error(soap, tcp_error(soap), "setsockopt set IPV6_V6ONLY failed in soap_bind()", SOAP_TCP_ERROR);
return SOAP_INVALID_SOCKET;
}
#endif
#ifdef WITH_NO_IPV6_V6ONLY
if (setsockopt(soap->master, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&unset, sizeof(int)))
{ soap->errnum = soap_socket_errno(soap->master);
- soap_set_receiver_error(soap, tcp_error(soap), "setsockopt IPV6_V6ONLY failed in soap_bind()", SOAP_TCP_ERROR);
+ soap_set_receiver_error(soap, tcp_error(soap), "setsockopt unset IPV6_V6ONLY failed in soap_bind()", SOAP_TCP_ERROR);
return SOAP_INVALID_SOCKET;
}
#endif
@@ -4784,8 +4817,9 @@ SOAP_SOCKET
SOAP_FMAC2
soap_accept(struct soap *soap)
{ int n = (int)sizeof(soap->peer);
+ register int err;
#ifndef WITH_LEAN
-#ifndef WITH_WIN32
+#ifndef WIN32
int len = SOAP_BUFLEN;
#else
int len = SOAP_BUFLEN + 1; /* speeds up windows xfer */
@@ -4793,124 +4827,123 @@ soap_accept(struct soap *soap)
int set = 1;
#endif
soap->error = SOAP_OK;
-#ifndef WITH_LEAN
- if ((soap->omode & SOAP_IO_UDP))
- return soap->socket = soap->master;
-#endif
memset((void*)&soap->peer, 0, sizeof(soap->peer));
soap->socket = SOAP_INVALID_SOCKET;
soap->errmode = 0;
soap->keep_alive = 0;
- if (soap_valid_socket(soap->master))
- { register int err;
- for (;;)
- { if (soap->accept_timeout || soap->send_timeout || soap->recv_timeout)
- { for (;;)
- { register int r;
- r = tcp_select(soap, soap->master, SOAP_TCP_SELECT_ALL, soap->accept_timeout ? soap->accept_timeout : 60);
- if (r > 0)
- break;
- if (!r && soap->accept_timeout)
- { soap_set_receiver_error(soap, "Timeout", "accept failed in soap_accept()", SOAP_TCP_ERROR);
+ if (!soap_valid_socket(soap->master))
+ { soap->errnum = 0;
+ soap_set_receiver_error(soap, tcp_error(soap), "no master socket in soap_accept()", SOAP_TCP_ERROR);
+ return SOAP_INVALID_SOCKET;
+ }
+#ifndef WITH_LEAN
+ if ((soap->omode & SOAP_IO_UDP))
+ return soap->socket = soap->master;
+#endif
+ for (;;)
+ { if (soap->accept_timeout || soap->send_timeout || soap->recv_timeout)
+ { for (;;)
+ { register int r;
+ r = tcp_select(soap, soap->master, SOAP_TCP_SELECT_ALL, soap->accept_timeout ? soap->accept_timeout : 60);
+ if (r > 0)
+ break;
+ if (!r && soap->accept_timeout)
+ { soap_set_receiver_error(soap, "Timeout", "accept failed in soap_accept()", SOAP_TCP_ERROR);
+ return SOAP_INVALID_SOCKET;
+ }
+ if (r < 0)
+ { r = soap->errnum;
+ if (r != SOAP_EINTR)
+ { soap_closesock(soap);
+ soap_set_sender_error(soap, tcp_error(soap), "accept failed in soap_accept()", SOAP_TCP_ERROR);
return SOAP_INVALID_SOCKET;
}
- if (r < 0)
- { r = soap->errnum;
- if (r != SOAP_EINTR)
- { soap_closesock(soap);
- soap_set_sender_error(soap, tcp_error(soap), "accept failed in soap_accept()", SOAP_TCP_ERROR);
- return SOAP_INVALID_SOCKET;
- }
- }
}
}
- if (soap->accept_timeout)
- SOAP_SOCKNONBLOCK(soap->master)
- else
- SOAP_SOCKBLOCK(soap->master)
- soap->socket = soap->faccept(soap, soap->master, (struct sockaddr*)&soap->peer, &n);
- soap->peerlen = (size_t)n;
- if (soap_valid_socket(soap->socket))
- {
+ }
+ if (soap->accept_timeout)
+ SOAP_SOCKNONBLOCK(soap->master)
+ else
+ SOAP_SOCKBLOCK(soap->master)
+ soap->socket = soap->faccept(soap, soap->master, (struct sockaddr*)&soap->peer, &n);
+ soap->peerlen = (size_t)n;
+ if (soap_valid_socket(soap->socket))
+ {
#ifdef WITH_IPV6
-/* Use soap->host to store the numeric form of the remote host */
- getnameinfo((struct sockaddr*)&soap->peer, n, soap->host, sizeof(soap->host), NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV);
- DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept socket %d from %s\n", soap->socket, soap->host));
- soap->ip = 0; /* info stored in soap->peer and soap->host */
- soap->port = 0; /* info stored in soap->peer and soap->host */
+ unsigned int ip1, ip2, ip3, ip4;
+ char port[16];
+ getnameinfo((struct sockaddr*)&soap->peer, n, soap->host, sizeof(soap->host), port, 16, NI_NUMERICHOST | NI_NUMERICSERV);
+ sscanf(soap->host, "%u.%u.%u.%u", &ip1, &ip2, &ip3, &ip4);
+ soap->ip = (unsigned long)ip1 << 24 | (unsigned long)ip2 << 16 | (unsigned long)ip3 << 8 | (unsigned long)ip4;
+ soap->port = soap_strtol(port, NULL, 10);
#else
- soap->ip = ntohl(soap->peer.sin_addr.s_addr);
- soap->port = (int)ntohs(soap->peer.sin_port); /* does not return port number on some systems */
- DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept socket %d at port %d from IP %d.%d.%d.%d\n", soap->socket, soap->port, (int)(soap->ip>>24)&0xFF, (int)(soap->ip>>16)&0xFF, (int)(soap->ip>>8)&0xFF, (int)soap->ip&0xFF));
+ soap->ip = ntohl(soap->peer.sin_addr.s_addr);
+ sprintf(soap->host, "%u.%u.%u.%u", (int)(soap->ip>>24)&0xFF, (int)(soap->ip>>16)&0xFF, (int)(soap->ip>>8)&0xFF, (int)soap->ip&0xFF);
+ soap->port = (int)ntohs(soap->peer.sin_port); /* does not return port number on some systems */
#endif
+ DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept socket %d at port %d from IP %s\n", soap->socket, soap->port, soap->host));
#ifndef WITH_LEAN
- if (soap->accept_flags == SO_LINGER)
- { struct linger linger;
- memset((void*)&linger, 0, sizeof(linger));
- linger.l_onoff = 1;
- linger.l_linger = soap->linger_time;
- if (setsockopt(soap->socket, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(struct linger)))
- { soap->errnum = soap_socket_errno(soap->socket);
- soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_LINGER failed in soap_accept()", SOAP_TCP_ERROR);
- soap_closesock(soap);
- return SOAP_INVALID_SOCKET;
- }
- }
- else if (soap->accept_flags && setsockopt(soap->socket, SOL_SOCKET, soap->accept_flags, (char*)&set, sizeof(int)))
+ if (soap->accept_flags == SO_LINGER)
+ { struct linger linger;
+ memset((void*)&linger, 0, sizeof(linger));
+ linger.l_onoff = 1;
+ linger.l_linger = soap->linger_time;
+ if (setsockopt(soap->socket, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(struct linger)))
{ soap->errnum = soap_socket_errno(soap->socket);
- soap_set_receiver_error(soap, tcp_error(soap), "setsockopt failed in soap_accept()", SOAP_TCP_ERROR);
- soap_closesock(soap);
- return SOAP_INVALID_SOCKET;
- }
- if (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) && setsockopt(soap->socket, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int)))
- { soap->errnum = soap_socket_errno(soap->socket);
- soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in soap_accept()", SOAP_TCP_ERROR);
- soap_closesock(soap);
- return SOAP_INVALID_SOCKET;
- }
- if (setsockopt(soap->socket, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int)))
- { soap->errnum = soap_socket_errno(soap->socket);
- soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in soap_accept()", SOAP_TCP_ERROR);
- soap_closesock(soap);
- return SOAP_INVALID_SOCKET;
- }
- if (setsockopt(soap->socket, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int)))
- { soap->errnum = soap_socket_errno(soap->socket);
- soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in soap_accept()", SOAP_TCP_ERROR);
+ soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_LINGER failed in soap_accept()", SOAP_TCP_ERROR);
soap_closesock(soap);
return SOAP_INVALID_SOCKET;
}
+ }
+ else if (soap->accept_flags && setsockopt(soap->socket, SOL_SOCKET, soap->accept_flags, (char*)&set, sizeof(int)))
+ { soap->errnum = soap_socket_errno(soap->socket);
+ soap_set_receiver_error(soap, tcp_error(soap), "setsockopt failed in soap_accept()", SOAP_TCP_ERROR);
+ soap_closesock(soap);
+ return SOAP_INVALID_SOCKET;
+ }
+ if (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) && setsockopt(soap->socket, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int)))
+ { soap->errnum = soap_socket_errno(soap->socket);
+ soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in soap_accept()", SOAP_TCP_ERROR);
+ soap_closesock(soap);
+ return SOAP_INVALID_SOCKET;
+ }
+ if (setsockopt(soap->socket, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int)))
+ { soap->errnum = soap_socket_errno(soap->socket);
+ soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in soap_accept()", SOAP_TCP_ERROR);
+ soap_closesock(soap);
+ return SOAP_INVALID_SOCKET;
+ }
+ if (setsockopt(soap->socket, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int)))
+ { soap->errnum = soap_socket_errno(soap->socket);
+ soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in soap_accept()", SOAP_TCP_ERROR);
+ soap_closesock(soap);
+ return SOAP_INVALID_SOCKET;
+ }
#ifdef TCP_NODELAY
- if (!(soap->omode & SOAP_IO_UDP) && setsockopt(soap->socket, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int)))
- { soap->errnum = soap_socket_errno(soap->socket);
- soap_set_receiver_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in soap_accept()", SOAP_TCP_ERROR);
- soap_closesock(soap);
- return SOAP_INVALID_SOCKET;
- }
-#endif
-#endif
- soap->keep_alive = (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) != 0);
- if (soap->send_timeout || soap->recv_timeout)
- SOAP_SOCKNONBLOCK(soap->socket)
- else
- SOAP_SOCKBLOCK(soap->socket)
- return soap->socket;
- }
- err = soap_socket_errno(soap->socket);
- if (err != 0 && err != SOAP_EINTR && err != SOAP_EAGAIN && err != SOAP_EWOULDBLOCK)
- { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept failed from %s\n", soap->host));
- soap->errnum = err;
- soap_set_receiver_error(soap, tcp_error(soap), "accept failed in soap_accept()", SOAP_TCP_ERROR);
+ if (setsockopt(soap->socket, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int)))
+ { soap->errnum = soap_socket_errno(soap->socket);
+ soap_set_receiver_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in soap_accept()", SOAP_TCP_ERROR);
soap_closesock(soap);
return SOAP_INVALID_SOCKET;
}
+#endif
+#endif
+ soap->keep_alive = (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) != 0);
+ if (soap->send_timeout || soap->recv_timeout)
+ SOAP_SOCKNONBLOCK(soap->socket)
+ else
+ SOAP_SOCKBLOCK(soap->socket)
+ return soap->socket;
+ }
+ err = soap_socket_errno(soap->socket);
+ if (err != 0 && err != SOAP_EINTR && err != SOAP_EAGAIN && err != SOAP_EWOULDBLOCK)
+ { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept failed from %s\n", soap->host));
+ soap->errnum = err;
+ soap_set_receiver_error(soap, tcp_error(soap), "accept failed in soap_accept()", SOAP_TCP_ERROR);
+ soap_closesock(soap);
+ return SOAP_INVALID_SOCKET;
}
}
- else
- { soap->errnum = 0;
- soap_set_receiver_error(soap, tcp_error(soap), "no master socket in soap_accept()", SOAP_TCP_ERROR);
- return SOAP_INVALID_SOCKET;
- }
}
#endif
#endif
@@ -4949,6 +4982,19 @@ soap_closesock(struct soap *soap)
#endif
/******************************************************************************/
+#ifndef PALM_1
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_force_closesock(struct soap *soap)
+{ soap->keep_alive = 0;
+ if (soap_valid_socket(soap->socket))
+ return soap_closesocket(soap->socket);
+ return SOAP_OK;
+}
+#endif
+
+/******************************************************************************/
#ifndef WITH_NOIO
#ifndef PALM_2
SOAP_FMAC1
@@ -5004,11 +5050,11 @@ soap_done(struct soap *soap)
soap->fmalloc = NULL;
#ifndef WITH_NOHTTP
soap->fpost = http_post;
- soap->fput = http_put;
soap->fget = http_get;
+ soap->fput = http_405;
soap->fdel = http_405;
- soap->fopt = http_405;
- soap->fhead = http_405;
+ soap->fopt = http_200;
+ soap->fhead = http_200;
soap->fform = NULL;
soap->fposthdr = http_post_header;
soap->fresponse = http_response;
@@ -5106,7 +5152,11 @@ soap_done(struct soap *soap)
}
#endif
#ifdef WITH_C_LOCALE
+# ifdef WIN32
+ _free_locale(soap->c_locale);
+# else
freelocale(soap->c_locale);
+# endif
#endif
#ifdef WITH_ZLIB
if (soap->d_stream)
@@ -5147,16 +5197,24 @@ soap_done(struct soap *soap)
int
http_parse(struct soap *soap)
{ char header[SOAP_HDRLEN], *s;
- unsigned short httpcmd = 0, status = 0;
+ unsigned short httpcmd = 0;
+ int status = 0;
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Waiting for HTTP request/response...\n"));
*soap->endpoint = '\0';
soap->length = 0;
- soap->userid = NULL;
- soap->passwd = NULL;
- soap->action = NULL;
- soap->authrealm = NULL;
+#ifdef WITH_NTLM
+ if (!soap->ntlm_challenge)
+#endif
+ { soap->userid = NULL;
+ soap->passwd = NULL;
+ soap->authrealm = NULL;
+ }
+#ifdef WITH_NTLM
+ soap->ntlm_challenge = NULL;
+#endif
soap->proxy_from = NULL;
soap->http_content = NULL;
+ soap->action = NULL;
soap->status = 0;
do
{ if (soap_getline(soap, soap->msgbuf, sizeof(soap->msgbuf)))
@@ -5245,6 +5303,8 @@ http_parse(struct soap *soap)
n = sizeof(soap->endpoint) - 1;
strncpy(soap->path, soap->msgbuf + l, n - m);
soap->path[n - m] = '\0';
+ if (*soap->path && *soap->path != '/')
+ *soap->endpoint = '\0';
strcat(soap->endpoint, soap->path);
DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Target endpoint='%s'\n", soap->endpoint));
if (httpcmd > 1)
@@ -5277,7 +5337,7 @@ http_parse(struct soap *soap)
may not have a body. When content length, content type, or chunking is
used assume there is a message to parse, either XML or HTTP.
*/
- if (soap->length > 0 || (soap->http_content && soap->recv_timeout) || (soap->imode & SOAP_IO) == SOAP_IO_CHUNK)
+ if (soap->length > 0 || (soap->http_content && (!soap->keep_alive || soap->recv_timeout)) || (soap->imode & SOAP_IO) == SOAP_IO_CHUNK)
{ if ((soap->status > 200 && soap->status <= 299)
|| soap->status == 400
|| soap->status == 500)
@@ -5392,8 +5452,14 @@ http_parse_header(struct soap *soap, const char *key, const char *val)
}
}
}
- else if (!soap_tag_cmp(key, "WWW-Authenticate"))
- { soap->authrealm = soap_strdup(soap, soap_get_header_attribute(soap, val + 6, "realm"));
+ else if (!soap_tag_cmp(key, "WWW-Authenticate") || !soap_tag_cmp(key, "Proxy-Authenticate"))
+ {
+#ifdef WITH_NTLM
+ if (!soap_tag_cmp(val, "NTLM*"))
+ soap->ntlm_challenge = soap_strdup(soap, val + 4);
+ else
+#endif
+ soap->authrealm = soap_strdup(soap, soap_get_header_attribute(soap, val + 6, "realm"));
}
else if (!soap_tag_cmp(key, "Expect"))
{ if (!soap_tag_cmp(val, "100-continue"))
@@ -5522,6 +5588,7 @@ soap_decode(char *buf, size_t len, const char *val, const char *sep)
static const char*
http_error(struct soap *soap, int status)
{ register const char *msg = SOAP_STR_EOS;
+ (void)soap;
#ifndef WITH_LEAN
msg = soap_code_str(h_http_error_codes, status);
if (!msg)
@@ -5533,21 +5600,25 @@ http_error(struct soap *soap, int status)
#endif
/******************************************************************************/
+
#ifndef WITH_NOHTTP
#ifndef PALM_1
static int
-http_put(struct soap *soap)
-{ return http_parse(soap);
+http_get(struct soap *soap)
+{ (void)soap;
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "HTTP GET request\n"));
+ return SOAP_GET_METHOD;
}
#endif
#endif
-/******************************************************************************/
+/******************************************************************************/
#ifndef WITH_NOHTTP
#ifndef PALM_1
static int
-http_get(struct soap *soap)
-{ return SOAP_GET_METHOD;
+http_405(struct soap *soap)
+{ return 405;
+ (void)soap;
}
#endif
#endif
@@ -5556,8 +5627,8 @@ http_get(struct soap *soap)
#ifndef WITH_NOHTTP
#ifndef PALM_1
static int
-http_405(struct soap *soap)
-{ return 405;
+http_200(struct soap *soap)
+{ return soap_send_empty_response(soap, 200);
}
#endif
#endif
@@ -5569,10 +5640,23 @@ static int
http_post(struct soap *soap, const char *endpoint, const char *host, int port, const char *path, const char *action, size_t count)
{ register const char *s;
register int err;
- if (soap->status == SOAP_GET)
- s = "GET";
- else
- s = "POST";
+ switch (soap->status)
+ { case SOAP_GET:
+ s = "GET";
+ break;
+ case SOAP_PUT:
+ s = "PUT";
+ break;
+ case SOAP_DEL:
+ s = "DELETE";
+ break;
+ case SOAP_CONNECT:
+ s = "CONNECT";
+ break;
+ default:
+ s = "POST";
+ }
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "HTTP %s to %s\n", s, endpoint ? endpoint : "(null)"));
#ifdef PALM
if (!endpoint || (soap_tag_cmp(endpoint, "http:*") && soap_tag_cmp(endpoint, "https:*") && strncmp(endpoint, "httpg:", 6)) && strncmp(endpoint, "_beam:", 6) && strncmp(endpoint, "_local:", 7) && strncmp(endpoint, "_btobex:", 8))
#else
@@ -5580,24 +5664,30 @@ http_post(struct soap *soap, const char *endpoint, const char *host, int port, c
#endif
return SOAP_OK;
if (strlen(endpoint) + strlen(soap->http_version) > sizeof(soap->tmpbuf) - 80)
- return soap->error = SOAP_EOM;
- if (soap->proxy_host && soap_tag_cmp(endpoint, "https:*"))
+ return soap->error = SOAP_EOM; /* prevent overrun */
+ if (soap->status == SOAP_CONNECT)
+ sprintf(soap->tmpbuf, "%s %s:%d HTTP/%s", s, soap->host, soap->port, soap->http_version);
+ else if (soap->proxy_host && endpoint)
sprintf(soap->tmpbuf, "%s %s HTTP/%s", s, endpoint, soap->http_version);
else
sprintf(soap->tmpbuf, "%s /%s HTTP/%s", s, (*path == '/' ? path + 1 : path), soap->http_version);
if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL)))
return err;
#ifdef WITH_OPENSSL
- if ((soap->ssl && soap->port != 443) || (!soap->ssl && soap->port != 80))
- sprintf(soap->tmpbuf, "%s:%d", host, port);
- else
- strcpy(soap->tmpbuf, host);
+ if ((soap->ssl && port != 443) || (!soap->ssl && port != 80))
#else
if (port != 80)
- sprintf(soap->tmpbuf, "%s:%d", host, port);
+#endif
+ {
+#ifdef WITH_IPV6
+ if (*host != '[' && strchr(host, ':'))
+ sprintf(soap->tmpbuf, "[%s]:%d", host, port); /* RFC 2732 */
+ else
+#endif
+ sprintf(soap->tmpbuf, "%s:%d", host, port);
+ }
else
strcpy(soap->tmpbuf, host);
-#endif
if ((err = soap->fposthdr(soap, "Host", soap->tmpbuf)))
return err;
if ((err = soap->fposthdr(soap, "User-Agent", "gSOAP/2.8")))
@@ -5614,16 +5704,30 @@ http_post(struct soap *soap, const char *endpoint, const char *host, int port, c
#endif
#ifndef WITH_LEAN
if (soap->userid && soap->passwd && strlen(soap->userid) + strlen(soap->passwd) < 761)
- { sprintf(soap->tmpbuf + 262, "%s:%s", soap->userid, soap->passwd);
- strcpy(soap->tmpbuf, "Basic ");
- soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, (int)strlen(soap->tmpbuf + 262));
+ {
+#ifdef WITH_NTLM
+ if (soap->ntlm_challenge && strlen(soap->ntlm_challenge) + 6 < sizeof(soap->tmpbuf))
+ sprintf(soap->tmpbuf, "NTLM %s", soap->ntlm_challenge);
+ else
+#endif
+ { strcpy(soap->tmpbuf, "Basic ");
+ sprintf(soap->tmpbuf + 262, "%s:%s", soap->userid, soap->passwd);
+ soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, (int)strlen(soap->tmpbuf + 262));
+ }
if ((err = soap->fposthdr(soap, "Authorization", soap->tmpbuf)))
return err;
}
if (soap->proxy_userid && soap->proxy_passwd && strlen(soap->proxy_userid) + strlen(soap->proxy_passwd) < 761)
- { sprintf(soap->tmpbuf + 262, "%s:%s", soap->proxy_userid, soap->proxy_passwd);
- strcpy(soap->tmpbuf, "Basic ");
- soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, (int)strlen(soap->tmpbuf + 262));
+ {
+#ifdef WITH_NTLM
+ if (soap->ntlm_challenge && strlen(soap->ntlm_challenge) + 6 < sizeof(soap->tmpbuf))
+ sprintf(soap->tmpbuf, "NTLM %s", soap->ntlm_challenge);
+ else
+#endif
+ { strcpy(soap->tmpbuf, "Basic ");
+ sprintf(soap->tmpbuf + 262, "%s:%s", soap->proxy_userid, soap->proxy_passwd);
+ soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, (int)strlen(soap->tmpbuf + 262));
+ }
if ((err = soap->fposthdr(soap, "Proxy-Authorization", soap->tmpbuf)))
return err;
}
@@ -5637,7 +5741,7 @@ http_post(struct soap *soap, const char *endpoint, const char *host, int port, c
return soap->error;
#endif
#endif
- if (soap->status != SOAP_GET && soap->version == 1)
+ if (action && soap->status != SOAP_GET && soap->status != SOAP_DEL)
{ sprintf(soap->tmpbuf, "\"%s\"", action && strlen(action) < sizeof(soap->tmpbuf) - 3 ? action : SOAP_STR_EOS);
if ((err = soap->fposthdr(soap, "SOAPAction", soap->tmpbuf)))
return err;
@@ -5699,7 +5803,7 @@ http_response(struct soap *soap, int status, size_t count)
if (count || ((soap->omode & SOAP_IO) == SOAP_IO_CHUNK))
s = "200 OK";
else
- s = "202 ACCEPTED";
+ s = "202 Accepted";
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Status = %s\n", s));
#ifdef WMW_RPM_IO
if (soap->rpmreqid || soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* RPM behaves as if standalone */
@@ -5842,9 +5946,9 @@ soap_cookie(struct soap *soap, const char *name, const char *domain, const char
path = SOAP_STR_EOS;
else if (*path == '/')
path++;
- DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Search cookie %s domain=%s path=%s\n", name, domain?domain:"(null)", path?path:"(null)"));
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Search cookie %s domain=%s path=%s\n", name, domain ? domain : "(null)", path ? path : "(null)"));
for (p = soap->cookies; p; p = p->next)
- { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Cookie in database: %s=%s domain=%s path=%s env=%hd\n", p->name, p->value?p->value:"(null)", p->domain?p->domain:"(null)", p->path?p->path:"(null)", p->env));
+ { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Cookie in database: %s=%s domain=%s path=%s env=%hd\n", p->name, p->value ? p->value : "(null)", p->domain ? p->domain : "(null)", p->path ? p->path : "(null)", p->env));
if (!strcmp(p->name, name)
&& p->domain
&& p->path
@@ -5871,7 +5975,7 @@ soap_set_cookie(struct soap *soap, const char *name, const char *value, const ch
else if (*path == '/')
path++;
q = soap_cookie(soap, name, domain, path);
- DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set %scookie: %s=%s domain=%s path=%s\n", q ? SOAP_STR_EOS : "new ", name, value?value:"(null)", domain?domain:"(null)", path?path:"(null)"));
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set %scookie: %s=%s domain=%s path=%s\n", q ? SOAP_STR_EOS : "new ", name, value ? value : "(null)", domain ? domain : "(null)", path ? path : "(null)"));
if (!q)
{ if ((q = (struct soap_cookie*)SOAP_MALLOC(soap, sizeof(struct soap_cookie))))
{ if ((q->name = (char*)SOAP_MALLOC(soap, strlen(name)+1)))
@@ -5940,13 +6044,13 @@ soap_clr_cookie(struct soap *soap, const char *name, const char *domain, const c
if (!domain)
domain = soap->cookie_domain;
if (!domain)
- { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error in clear cookie %s: cookie domain not set\n", name?name:"(null)"));
+ { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error in clear cookie %s: cookie domain not set\n", name ? name : "(null)"));
return;
}
if (!path)
path = soap->cookie_path;
if (!path)
- { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error in clear cookie %s: cookie path not set\n", name?name:"(null)"));
+ { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error in clear cookie %s: cookie path not set\n", name ? name : "(null)"));
return;
}
if (*path == '/')
@@ -6006,7 +6110,7 @@ int
SOAP_FMAC2
soap_set_cookie_expire(struct soap *soap, const char *name, long expire, const char *domain, const char *path)
{ struct soap_cookie *p;
- DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set cookie expiration max-age %ld: %s domain=%s path=%s\n", expire, name, domain?domain:"(null)", path?path:"(null)"));
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set cookie expiration max-age %ld: %s domain=%s path=%s\n", expire, name, domain ? domain : "(null)", path ? path : "(null)"));
if ((p = soap_cookie(soap, name, domain, path)))
{ p->maxage = expire;
p->modified = 1;
@@ -6123,6 +6227,9 @@ soap_putcookies(struct soap *soap, const char *domain, const char *path, int sec
unsigned int version = 0;
time_t now = time(NULL);
char *s, tmp[4096];
+ if (!domain || !path)
+ return SOAP_OK;
+ s = tmp;
p = &soap->cookies;
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Sending cookies for domain=%s path=%s\n", domain, path));
if (*path == '/')
@@ -6169,30 +6276,53 @@ soap_putcookies(struct soap *soap, const char *domain, const char *path, int sec
if (flag
&& (!q->path || !strncmp(q->path, path, strlen(q->path)))
&& (!q->secure || secure))
- { s = tmp;
+ { size_t n = 12;
+ if (q->name)
+ n += 3*strlen(q->name);
+ if (q->value && *q->value)
+ n += 3*strlen(q->value) + 1;
+ if (q->path && *q->path)
+ n += strlen(q->path) + 9;
+ if (q->domain)
+ n += strlen(q->domain) + 11;
+ if (tmp - s + n > sizeof(tmp))
+ { if (s == tmp)
+ return SOAP_OK; /* HTTP header size overflow */
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Cookie: %s\n", tmp));
+ if ((soap->error = soap->fposthdr(soap, "Cookie", tmp)))
+ return soap->error;
+ s = tmp;
+ }
+ else if (s != tmp)
+ { strcat(s, " ");
+ s++;
+ }
if (q->version != version)
{ sprintf(s, "$Version=%u;", q->version);
version = q->version;
+ s += strlen(s);
}
if (q->name)
- s += soap_encode_cookie(q->name, s, tmp-s+4080);
+ s += soap_encode_cookie(q->name, s, tmp+sizeof(tmp)-s-16);
if (q->value && *q->value)
{ *s++ = '=';
- s += soap_encode_cookie(q->value, s, tmp-s+4080);
+ s += soap_encode_cookie(q->value, s, tmp+sizeof(tmp)-s-16);
}
- if (q->path && *q->path && (int)strlen(q->path) < tmp-s+4080)
+ if (q->path)
{ sprintf(s, ";$Path=\"/%s\"", (*q->path == '/' ? q->path + 1 : q->path));
s += strlen(s);
}
- if (q->domain && (int)strlen(q->domain) < tmp-s+4080)
- sprintf(s, ";$Domain=\"%s\"", q->domain);
- DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Cookie: %s\n", tmp));
- if ((soap->error = soap->fposthdr(soap, "Cookie", tmp)))
- return soap->error;
+ if (q->domain)
+ { sprintf(s, ";$Domain=\"%s\"", q->domain);
+ s += strlen(s);
+ }
}
p = &q->next;
}
}
+ if (s != tmp)
+ if ((soap->error = soap->fposthdr(soap, "Cookie", tmp)))
+ return soap->error;
return SOAP_OK;
}
@@ -6322,7 +6452,7 @@ soap_getcookies(struct soap *soap, const char *val)
p->secure = 1;
else
{ if (p)
- { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Got environment cookie %s=%s domain=%s path=%s expire=%ld secure=%d\n", p->name, p->value?p->value:"(null)", p->domain?p->domain:"(null)", p->path?p->path:"(null)", p->expire, p->secure));
+ { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Got environment cookie %s=%s domain=%s path=%s expire=%ld secure=%d\n", p->name, p->value ? p->value : "(null)", p->domain ? p->domain : "(null)", p->path ? p->path : "(null)", p->expire, p->secure));
if ((q = soap_set_cookie(soap, p->name, p->value, p->domain, p->path)))
{ q->version = p->version;
q->expire = p->expire;
@@ -6374,7 +6504,7 @@ soap_getcookies(struct soap *soap, const char *val)
}
}
if (p)
- { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Got environment cookie %s=%s domain=%s path=%s expire=%ld secure=%d\n", p->name, p->value?p->value:"(null)", p->domain?p->domain:"(null)", p->path?p->path:"(null)", p->expire, p->secure));
+ { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Got environment cookie %s=%s domain=%s path=%s expire=%ld secure=%d\n", p->name, p->value ? p->value : "(null)", p->domain ? p->domain : "(null)", p->path ? p->path : "(null)", p->expire, p->secure));
if ((q = soap_set_cookie(soap, p->name, p->value, p->domain, p->path)))
{ q->version = p->version;
q->expire = p->expire;
@@ -6506,30 +6636,10 @@ soap_init_pht(struct soap *soap)
SOAP_FMAC1
struct soap*
SOAP_FMAC2
-soap_new1(soap_mode mode)
-{ return soap_new2(mode, mode);
-}
-#endif
-
-/******************************************************************************/
-#ifndef PALM_1
-SOAP_FMAC1
-struct soap*
-SOAP_FMAC2
-soap_new()
-{ return soap_new2(SOAP_IO_DEFAULT, SOAP_IO_DEFAULT);
-}
-#endif
-
-/******************************************************************************/
-#ifndef PALM_1
-SOAP_FMAC1
-struct soap*
-SOAP_FMAC2
-soap_new2(soap_mode imode, soap_mode omode)
+soap_versioning(soap_new)(soap_mode imode, soap_mode omode)
{ struct soap *soap = (struct soap*)malloc(sizeof(struct soap));
if (soap)
- soap_init2(soap, imode, omode);
+ soap_versioning(soap_init)(soap, imode, omode);
return soap;
}
#endif
@@ -6597,6 +6707,7 @@ soap_embed(struct soap *soap, const void *p, const struct soap_array *a, int n,
soap_set_embedded(soap, pp);
}
return i;
+ (void)soap;
}
#endif
#endif
@@ -6649,7 +6760,7 @@ soap_pointer_enter(struct soap *soap, const void *p, const struct soap_array *a,
h = soap_hash_ptr(a->__ptr);
else
h = soap_hash_ptr(p);
- DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Pointer enter location=%p array=%p size=%d dim=%d type=%d id=%d\n", p, a?a->__ptr:NULL, a?a->__size:0, n, type, soap->idnum+1));
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Pointer enter location=%p array=%p size=%d dim=%d type=%d id=%d\n", p, a ? a->__ptr : NULL, a ? a->__size : 0, n, type, soap->idnum+1));
pp->next = soap->pht[h];
pp->type = type;
pp->mark1 = 0;
@@ -6659,6 +6770,7 @@ soap_pointer_enter(struct soap *soap, const void *p, const struct soap_array *a,
soap->pht[h] = pp;
pp->id = ++soap->idnum;
return pp->id;
+ (void)n;
}
#endif
#endif
@@ -6747,6 +6859,7 @@ soap_begin_count(struct soap *soap)
soap->encoding = 0;
soap->part = SOAP_BEGIN;
soap->event = 0;
+ soap->evlev = 0;
soap->idnum = 0;
soap_clr_attr(soap);
soap_set_local_namespaces(soap);
@@ -6829,7 +6942,7 @@ soap_begin_send(struct soap *soap)
#ifdef WIN32
#ifndef UNDER_CE
#ifndef WITH_FASTCGI
- if (!soap_valid_socket(soap->socket)) /* Set win32 stdout or soap->sendfd to BINARY, e.g. to support DIME */
+ if (!soap_valid_socket(soap->socket) && !soap->os) /* Set win32 stdout or soap->sendfd to BINARY, e.g. to support DIME */
#ifdef __BORLANDC__
setmode(soap->sendfd, _O_BINARY);
#else
@@ -7084,7 +7197,7 @@ soap_attachment(struct soap *soap, const char *tag, int id, const void *p, const
int i;
if (!p || !a->__ptr || (!aid && !atype))
return soap_element_id(soap, tag, id, p, a, n, type, t);
- DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Attachment tag='%s' id='%s' (%d) type='%s'\n", tag, aid?aid:SOAP_STR_EOS, id, atype?atype:SOAP_STR_EOS));
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Attachment tag='%s' id='%s' (%d) type='%s'\n", tag, aid ? aid : SOAP_STR_EOS, id, atype ? atype : SOAP_STR_EOS));
i = soap_array_pointer_lookup(soap, p, a, n, t, &pp);
if (!i)
{ i = soap_pointer_enter(soap, p, a, n, t, &pp);
@@ -7213,7 +7326,7 @@ soap_enter(struct soap *soap, const char *id)
ip = (struct soap_ilist*)SOAP_MALLOC(soap, sizeof(struct soap_ilist) + strlen(id));
if (ip)
{ h = soap_hash(id);
- strcpy(ip->id, id);
+ strcpy((char*)ip->id, id);
ip->next = soap->iht[h];
soap->iht[h] = ip;
}
@@ -7400,13 +7513,16 @@ soap_dealloc(struct soap *soap, void *p)
SOAP_FREE(soap, q);
}
/* we must assume these were deallocated: */
+ soap->http_content = NULL;
soap->action = NULL;
soap->fault = NULL;
soap->header = NULL;
soap->userid = NULL;
soap->passwd = NULL;
soap->authrealm = NULL;
- soap->http_content = NULL;
+#ifdef WITH_NTLM
+ soap->ntlm_challenge = NULL;
+#endif
#ifndef WITH_LEANER
soap_clr_mime(soap);
#endif
@@ -7537,32 +7653,33 @@ soap_link(struct soap *soap, void *p, int t, int n, int (*fdelete)(struct soap_c
/******************************************************************************/
#ifndef PALM_2
SOAP_FMAC1
-void
+int
SOAP_FMAC2
soap_unlink(struct soap *soap, const void *p)
{ register char **q;
register struct soap_clist **cp;
- if (!soap || !p)
- return;
- for (q = (char**)&soap->alist; *q; q = *(char***)q)
- { if (p == (void*)(*q - *(size_t*)(*q + sizeof(void*))))
- { *q = **(char***)q;
- DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unlinked data %p\n", p));
+ if (soap && p)
+ { for (q = (char**)&soap->alist; *q; q = *(char***)q)
+ { if (p == (void*)(*q - *(size_t*)(*q + sizeof(void*))))
+ { *q = **(char***)q;
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unlinked data %p\n", p));
#ifdef SOAP_MEM_DEBUG
- soap_track_unlink(soap, p);
+ soap_track_unlink(soap, p);
#endif
- return;
+ return SOAP_OK; /* found and removed from dealloc chain */
+ }
}
- }
- for (cp = &soap->clist; *cp; cp = &(*cp)->next)
- { if (p == (*cp)->ptr)
- { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unlinked class instance %p\n", p));
- q = (char**)*cp;
- *cp = (*cp)->next;
- SOAP_FREE(soap, q);
- return;
+ for (cp = &soap->clist; *cp; cp = &(*cp)->next)
+ { if (p == (*cp)->ptr)
+ { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unlinked class instance %p\n", p));
+ q = (char**)*cp;
+ *cp = (*cp)->next;
+ SOAP_FREE(soap, q);
+ return SOAP_OK; /* found and removed from dealloc chain */
+ }
}
}
+ return SOAP_ERR;
}
#endif
@@ -7802,6 +7919,7 @@ SOAP_FMAC2
soap_fcopy(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n)
{ DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Copying data type=%d (target type=%d) %p -> %p (%lu bytes)\n", st, tt, q, p, (unsigned long)n));
memcpy(p, q, n);
+ (void)soap; (void)st; (void)tt; (void)len;
}
#endif
@@ -7867,7 +7985,7 @@ soap_end_send(struct soap *soap)
soap->mode &= ~SOAP_ENC_ZLIB;
soap->zlib_state = SOAP_ZLIB_NONE;
if (deflateEnd(soap->d_stream) != Z_OK || r != Z_STREAM_END)
- { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to end deflate: %s\n", soap->d_stream->msg?soap->d_stream->msg:SOAP_STR_EOS));
+ { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to end deflate: %s\n", soap->d_stream->msg ? soap->d_stream->msg : SOAP_STR_EOS));
return soap->error = SOAP_ZLIB_ERROR;
}
#ifdef WITH_GZIP
@@ -8004,7 +8122,7 @@ soap_end_recv(struct soap *soap)
for (i = 0; i < 8; i++)
{ if ((int)(c = soap_get1(soap)) == EOF)
{ DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Gzip error: unable to read crc value\n"));
- return soap->error = SOAP_EOF;
+ return soap->error = SOAP_ZLIB_ERROR;
}
soap->z_buf[i] = (char)c;
}
@@ -8232,6 +8350,7 @@ soap_copy_context(struct soap *copy, const struct soap *soap)
return NULL;
if (copy)
{ register struct soap_plugin *p = NULL;
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying context\n"));
#ifdef __cplusplus
*copy = *soap;
#else
@@ -8241,6 +8360,9 @@ soap_copy_context(struct soap *copy, const struct soap *soap)
copy->error = SOAP_OK;
copy->userid = NULL;
copy->passwd = NULL;
+#ifdef WITH_NTLM
+ copy->ntlm_challenge = NULL;
+#endif
copy->nlist = NULL;
copy->blist = NULL;
copy->clist = NULL;
@@ -8260,8 +8382,18 @@ soap_copy_context(struct soap *copy, const struct soap *soap)
soap_set_sent_logfile(copy, soap->logfile[SOAP_INDEX_SENT]);
soap_set_recv_logfile(copy, soap->logfile[SOAP_INDEX_RECV]);
#endif
+ copy->namespaces = NULL;
+ copy->local_namespaces = NULL;
+ if (soap->local_namespaces)
+ soap_set_namespaces(copy, soap->local_namespaces);
+ else
+ soap_set_namespaces(copy, soap->namespaces);
#ifdef WITH_C_LOCALE
+# ifdef WIN32
+ copy->c_locale = _create_locale(LC_ALL, "C");
+# else
copy->c_locale = duplocale(soap->c_locale);
+# endif
#else
copy->c_locale = NULL;
#endif
@@ -8326,7 +8458,10 @@ soap_copy_stream(struct soap *copy, struct soap *soap)
copy->mode = soap->mode;
copy->imode = soap->imode;
copy->omode = soap->omode;
+ copy->master = soap->master;
copy->socket = soap->socket;
+ copy->sendsk = soap->sendsk;
+ copy->recvsk = soap->recvsk;
copy->recv_timeout = soap->recv_timeout;
copy->send_timeout = soap->send_timeout;
#if defined(__cplusplus) && !defined(WITH_LEAN)
@@ -8350,23 +8485,27 @@ soap_copy_stream(struct soap *copy, struct soap *soap)
#ifndef WITH_NOIO
copy->peer = soap->peer;
copy->peerlen = soap->peerlen;
+ copy->ip = soap->ip;
+ copy->port = soap->port;
+ memcpy(copy->host, soap->host, sizeof(soap->host));
+ memcpy(copy->endpoint, soap->endpoint, sizeof(soap->endpoint));
#endif
#ifdef WITH_OPENSSL
- copy->bio = NULL;
- copy->ctx = NULL;
- copy->ssl = NULL;
- if (soap->ssl)
- copy->ssl = SSL_dup(soap->ssl);
+ copy->bio = soap->bio;
+ copy->ctx = soap->ctx;
+ copy->ssl = soap->ssl;
#endif
#ifdef WITH_GNUTLS
- copy->session = soap->session; /* TODO: Oops, GNUTLS provides a dup? */
+ copy->session = soap->session;
#endif
#ifdef WITH_ZLIB
copy->zlib_state = soap->zlib_state;
copy->zlib_in = soap->zlib_in;
copy->zlib_out = soap->zlib_out;
- copy->d_stream = (z_stream*)SOAP_MALLOC(copy, sizeof(z_stream));
- memcpy(copy->d_stream, soap->d_stream, sizeof(z_stream));
+ if (!copy->d_stream)
+ copy->d_stream = (z_stream*)SOAP_MALLOC(copy, sizeof(z_stream));
+ if (copy->d_stream)
+ memcpy(copy->d_stream, soap->d_stream, sizeof(z_stream));
copy->z_crc = soap->z_crc;
copy->z_ratio_in = soap->z_ratio_in;
copy->z_ratio_out = soap->z_ratio_out;
@@ -8375,7 +8514,8 @@ soap_copy_stream(struct soap *copy, struct soap *soap)
copy->z_level = soap->z_level;
if (soap->z_buf && soap->zlib_state != SOAP_ZLIB_NONE)
{ copy->z_buf = (char*)SOAP_MALLOC(copy, SOAP_BUFLEN);
- memcpy(copy->z_buf, soap->z_buf, sizeof(soap->z_buf));
+ if (copy->z_buf)
+ memcpy(copy->z_buf, soap->z_buf, SOAP_BUFLEN);
}
copy->z_dict = soap->z_dict;
copy->z_dict_len = soap->z_dict_len;
@@ -8411,10 +8551,18 @@ soap_copy_stream(struct soap *copy, struct soap *soap)
SOAP_FREE(copy, nq);
}
}
- copy->level = soap->level;
+ memcpy(copy->tag, soap->tag, sizeof(copy->tag));
+ memcpy(copy->id, soap->id, sizeof(copy->id));
+ memcpy(copy->href, soap->href, sizeof(copy->href));
+ memcpy(copy->type, soap->type, sizeof(copy->type));
+ copy->other = soap->other;
+ copy->root = soap->root;
+ copy->null = soap->null;
copy->body = soap->body;
+ copy->part = soap->part;
+ copy->mustUnderstand = soap->mustUnderstand;
+ copy->level = soap->level;
copy->peeked = soap->peeked;
- memcpy(copy->tag, soap->tag, sizeof(copy->tag));
/* copy attributes */
for (tq = soap->attributes; tq; tq = tq->next)
{ struct soap_attribute *tr = tp;
@@ -8440,24 +8588,22 @@ void
SOAP_FMAC2
soap_free_stream(struct soap *soap)
{ soap->socket = SOAP_INVALID_SOCKET;
+ soap->sendsk = SOAP_INVALID_SOCKET;
+ soap->recvsk = SOAP_INVALID_SOCKET;
#ifdef WITH_OPENSSL
soap->bio = NULL;
- if (soap->ssl)
- SSL_free(soap->ssl);
+ soap->ctx = NULL;
soap->ssl = NULL;
#endif
#ifdef WITH_GNUTLS
soap->xcred = NULL;
soap->acred = NULL;
soap->cache = NULL;
- soap->session = NULL; /* TODO: GNUTLS free here when dupped */
+ soap->session = NULL;
soap->dh_params = NULL;
soap->rsa_params = NULL;
#endif
#ifdef WITH_ZLIB
- if (soap->d_stream)
- SOAP_FREE(soap, soap->d_stream);
- soap->d_stream = NULL;
if (soap->z_buf)
SOAP_FREE(soap, soap->z_buf);
soap->z_buf = NULL;
@@ -8470,7 +8616,7 @@ soap_free_stream(struct soap *soap)
SOAP_FMAC1
void
SOAP_FMAC2
-soap_init(struct soap *soap)
+soap_versioning(soap_init)(struct soap *soap, soap_mode imode, soap_mode omode)
{ size_t i;
soap->state = SOAP_INIT;
#ifdef SOAP_MEM_DEBUG
@@ -8480,7 +8626,7 @@ soap_init(struct soap *soap)
soap_init_logs(soap);
#endif
#ifdef SOAP_DEBUG
-#ifdef TANDEM
+#ifdef TANDEM_NONSTOP
soap_set_test_logfile(soap, "TESTLOG");
soap_set_sent_logfile(soap, "SENTLOG");
soap_set_recv_logfile(soap, "RECVLOG");
@@ -8491,21 +8637,26 @@ soap_init(struct soap *soap)
#endif
#endif
soap->version = 0;
- soap_imode(soap, SOAP_IO_DEFAULT);
- soap_omode(soap, SOAP_IO_DEFAULT);
+ soap_mode(soap, imode);
+ soap_imode(soap, imode);
+ soap_omode(soap, omode);
soap->plugins = NULL;
soap->user = NULL;
for (i = 0; i < sizeof(soap->data)/sizeof(*soap->data); i++)
soap->data[i] = NULL;
soap->userid = NULL;
soap->passwd = NULL;
+ soap->authrealm = NULL;
+#ifdef WITH_NTLM
+ soap->ntlm_challenge = NULL;
+#endif
#ifndef WITH_NOHTTP
soap->fpost = http_post;
- soap->fput = http_put;
soap->fget = http_get;
+ soap->fput = http_405;
soap->fdel = http_405;
- soap->fopt = http_405;
- soap->fhead = http_405;
+ soap->fopt = http_200;
+ soap->fhead = http_200;
soap->fform = NULL;
soap->fposthdr = http_post_header;
soap->fresponse = http_response;
@@ -8611,6 +8762,8 @@ soap_init(struct soap *soap)
soap->fault = NULL;
soap->master = SOAP_INVALID_SOCKET;
soap->socket = SOAP_INVALID_SOCKET;
+ soap->sendsk = SOAP_INVALID_SOCKET;
+ soap->recvsk = SOAP_INVALID_SOCKET;
soap->os = NULL;
soap->is = NULL;
#ifndef WITH_LEANER
@@ -8639,7 +8792,6 @@ soap_init(struct soap *soap)
soap->proxy_port = 8080;
soap->proxy_userid = NULL;
soap->proxy_passwd = NULL;
- soap->authrealm = NULL;
soap->prolog = NULL;
#ifdef WITH_ZLIB
soap->zlib_state = SOAP_ZLIB_NONE;
@@ -8709,7 +8861,11 @@ soap_init(struct soap *soap)
soap->rsa_params = NULL;
#endif
#ifdef WITH_C_LOCALE
+# ifdef WIN32
+ soap->c_locale = _create_locale(LC_ALL, "C");
+# else
soap->c_locale = newlocale(LC_ALL_MASK, "C", NULL);
+# endif
#else
soap->c_locale = NULL;
#endif
@@ -8726,6 +8882,7 @@ soap_init(struct soap *soap)
soap->ns = 0;
soap->part = SOAP_END;
soap->event = 0;
+ soap->evlev = 0;
soap->alloced = 0;
soap->count = 0;
soap->length = 0;
@@ -8740,28 +8897,6 @@ soap_init(struct soap *soap)
#endif
/******************************************************************************/
-#ifndef PALM_1
-SOAP_FMAC1
-void
-SOAP_FMAC2
-soap_init1(struct soap *soap, soap_mode mode)
-{ soap_init2(soap, mode, mode);
-}
-#endif
-
-/******************************************************************************/
-#ifndef PALM_1
-SOAP_FMAC1
-void
-SOAP_FMAC2
-soap_init2(struct soap *soap, soap_mode imode, soap_mode omode)
-{ soap_init(soap);
- soap_imode(soap, imode);
- soap_omode(soap, omode);
-}
-#endif
-
-/******************************************************************************/
#ifndef PALM_2
SOAP_FMAC1
void
@@ -8772,7 +8907,6 @@ soap_begin(struct soap *soap)
{ soap->buflen = 0;
soap->bufidx = 0;
}
- soap->keep_alive = (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) != 0);
soap->null = 0;
soap->position = 0;
soap->encoding = 0;
@@ -8781,6 +8915,7 @@ soap_begin(struct soap *soap)
soap->ns = 0;
soap->part = SOAP_END;
soap->event = 0;
+ soap->evlev = 0;
soap->alloced = 0;
soap->count = 0;
soap->length = 0;
@@ -8903,6 +9038,8 @@ soap_set_local_namespaces(struct soap *soap)
soap->version = 2;
}
soap->local_namespaces = ns2;
+ for (; ns2->id; ns2++)
+ ns2->out = NULL;
}
}
}
@@ -8976,7 +9113,7 @@ soap_push_ns(struct soap *soap, const char *id, const char *ns, short utilized)
return NULL;
}
}
- DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Adding namespace binding (level=%u) '%s' '%s' utilized=%d\n", soap->level, id, ns?ns:"(null)", utilized));
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Adding namespace binding (level=%u) '%s' '%s' utilized=%d\n", soap->level, id, ns ? ns : "(null)", utilized));
n = strlen(id);
if (ns)
k = strlen(ns);
@@ -8989,9 +9126,9 @@ soap_push_ns(struct soap *soap, const char *id, const char *ns, short utilized)
}
np->next = soap->nlist;
soap->nlist = np;
- strcpy(np->id, id);
+ strcpy((char*)np->id, id);
if (ns)
- np->ns = strcpy(np->id + n + 1, ns);
+ np->ns = strcpy((char*)np->id + n + 1, ns);
else
np->ns = NULL;
np->level = soap->level;
@@ -9003,8 +9140,13 @@ soap_push_ns(struct soap *soap, const char *id, const char *ns, short utilized)
/******************************************************************************/
#ifndef WITH_LEAN
static void
-soap_utilize_ns(struct soap *soap, const char *tag, size_t n)
-{ register struct soap_nlist *np = soap_lookup_ns(soap, tag, n);
+soap_utilize_ns(struct soap *soap, const char *tag)
+{ register struct soap_nlist *np;
+ size_t n = 0;
+ const char *t = strchr(tag, ':');
+ if (t)
+ n = t - tag;
+ np = soap_lookup_ns(soap, tag, n);
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Utilizing namespace of '%s'\n", tag));
if (np)
{ if (np->index == 0)
@@ -9028,7 +9170,8 @@ soap_element(struct soap *soap, const char *tag, int id, const char *type)
#ifndef WITH_LEAN
register const char *s;
#endif
- DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element begin tag='%s' id='%d' type='%s'\n", tag, id, type?type:SOAP_STR_EOS));
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element begin tag='%s' level='%u' id='%d' type='%s'\n", tag, soap->level, id, type ? type : SOAP_STR_EOS));
+ soap->level++;
#ifdef WITH_DOM
#ifndef WITH_LEAN
if (soap->wsuid && soap_tagsearch(soap->wsuid, tag))
@@ -9039,12 +9182,20 @@ soap_element(struct soap *soap, const char *tag, int id, const char *type)
if (soap_set_attr(soap, "wsu:Id", soap->tag, 1))
return soap->error;
}
- if (soap->event == SOAP_SEC_BEGIN && (soap->mode & SOAP_XML_CANONICAL) && !(soap->mode & SOAP_DOM_ASIS))
- { register struct soap_nlist *np;
- /* wsu:Id found: clear xmlns renderings, so re-emit them for exc-c14n */
- for (np = soap->nlist; np; np = np->next)
- { if (np->index == 2)
- np->index = 0;
+ if ((soap->mode & SOAP_XML_CANONICAL) && !(soap->mode & SOAP_DOM_ASIS))
+ { if (soap->evlev >= soap->level)
+ soap->evlev = 0;
+ if (soap->event == SOAP_SEC_BEGIN && !soap->evlev)
+ { register struct soap_nlist *np;
+ /* non-nested wsu:Id found: clear xmlns, re-emit them for exc-c14n */
+ for (np = soap->nlist; np; np = np->next)
+ { if (np->index == 2)
+ { struct soap_nlist *np1 = soap_push_ns(soap, np->id, np->ns, 1);
+ if (np1)
+ np1->index = 0;
+ }
+ }
+ soap->evlev = soap->level;
}
}
#endif
@@ -9080,7 +9231,6 @@ soap_element(struct soap *soap, const char *tag, int id, const char *type)
else
{
#endif
- soap->level++;
#ifndef WITH_LEAN
if (!soap->ns)
{ if (!(soap->mode & SOAP_XML_CANONICAL)
@@ -9135,26 +9285,30 @@ soap_element(struct soap *soap, const char *tag, int id, const char *type)
soap->ns = 1; /* namespace table control: ns = 0 or 2 to start, then 1 to stop dumping the table */
#ifndef WITH_LEAN
if (soap->mode & SOAP_XML_CANONICAL)
- { const char *t = strchr(tag, ':');
- if (t)
- soap_utilize_ns(soap, tag, t - tag);
- }
+ soap_utilize_ns(soap, tag);
#endif
if (id > 0)
{ sprintf(soap->tmpbuf, "_%d", id);
if (soap_attribute(soap, "id", soap->tmpbuf))
return soap->error;
}
- if (type && *type && soap->part != SOAP_IN_HEADER) /* TODO: filter Header? */
- { if (soap_attribute(soap, "xsi:type", type))
- return soap->error;
+ if (type && *type && !(soap->mode & SOAP_XML_NOTYPE) && soap->part != SOAP_IN_HEADER)
+ { const char *t = type;
#ifndef WITH_LEAN
- if (soap->mode & SOAP_XML_CANONICAL)
- { const char *t = strchr(type, ':');
+ if (soap->mode & SOAP_XML_DEFAULTNS)
+ { t = strchr(type, ':');
if (t)
- soap_utilize_ns(soap, type, t - type);
+ t++;
+ else
+ t = type;
}
#endif
+ if (soap->attributes ? soap_set_attr(soap, "xsi:type", t, 1) : soap_attribute(soap, "xsi:type", t))
+ return soap->error;
+#ifndef WITH_LEAN
+ if (soap->mode & SOAP_XML_CANONICAL)
+ soap_utilize_ns(soap, type);
+#endif
}
if (soap->null && soap->position > 0)
{ register int i;
@@ -9189,8 +9343,8 @@ soap_element(struct soap *soap, const char *tag, int id, const char *type)
}
soap->null = 0;
soap->position = 0;
- if (soap->event == SOAP_SEC_BEGIN && (soap->mode & SOAP_XML_CANONICAL))
- soap->event = SOAP_SEC_SIGN;
+ if (soap->event == SOAP_SEC_BEGIN)
+ soap->event = 0;
return SOAP_OK;
}
#endif
@@ -9358,10 +9512,7 @@ soap_array_begin_out(struct soap *soap, const char *tag, int id, const char *typ
}
#ifndef WITH_LEAN
if ((soap->mode & SOAP_XML_CANONICAL))
- { const char *s = strchr(type, ':');
- if (s)
- soap_utilize_ns(soap, type, s - type);
- }
+ soap_utilize_ns(soap, type);
#endif
return soap_element_start_end_out(soap, NULL);
}
@@ -9379,14 +9530,11 @@ soap_element_start_end_out(struct soap *soap, const char *tag)
{ struct soap_nlist *np;
for (tp = soap->attributes; tp; tp = tp->next)
{ if (tp->visible && tp->name)
- { const char *s = strchr(tp->name, ':');
- if (s)
- soap_utilize_ns(soap, tp->name, s - tp->name);
- }
+ soap_utilize_ns(soap, tp->name);
}
for (np = soap->nlist; np; np = np->next)
{ if (np->index == 1 && np->ns)
- { sprintf(soap->tmpbuf, "xmlns:%s", np->id);
+ { sprintf(soap->tmpbuf, *(np->id) ? "xmlns:%s" : "xmlns", np->id);
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Enabling utilized binding (level=%u) %s='%s'\n", np->level, soap->tmpbuf, np->ns));
soap_set_attr(soap, soap->tmpbuf, np->ns, 1);
np->index = 2;
@@ -9636,6 +9784,7 @@ soap_check_result(struct soap *soap, const char *tag)
{ soap_instring(soap, ":result", NULL, NULL, 0, 2, -1, -1);
/* just ignore content for compliance reasons, but should compare tag to element's QName value? */
}
+ (void)tag;
}
#endif
@@ -9664,16 +9813,9 @@ soap_attribute(struct soap *soap, const char *name, const char *value)
#endif
#ifndef WITH_LEAN
if (soap->mode & SOAP_XML_CANONICAL)
- { /* TODO: consider using this code to handle default namespace bindings
+ { /* push namespace */
if (!strncmp(name, "xmlns", 5) && (name[5] == ':' || name[5] == '\0'))
- { if (name[5] == ':')
- soap_push_ns(soap, name + 6, value, 0);
- else
- soap_push_ns(soap, "", value, 0);
- }
- */
- if (!strncmp(name, "xmlns:", 6))
- soap_push_ns(soap, name + 6, value, 0);
+ soap_push_ns(soap, name + 5 + (name[5] == ':'), value, 0);
else if (soap_set_attr(soap, name, value, 1))
return soap->error;
}
@@ -9710,7 +9852,8 @@ soap_element_begin_in(struct soap *soap, const char *tag, int nillable, const ch
return soap->error = SOAP_NULL;
if (soap->body)
soap->level++;
- DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin element found (level=%u) '%s'='%s'\n", soap->level, soap->tag, tag?tag:SOAP_STR_EOS ));
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin element found (level=%u) '%s'='%s'\n", soap->level, soap->tag, tag ? tag : SOAP_STR_EOS ));
+ soap->error = SOAP_OK;
}
}
else if (soap->error == SOAP_NO_TAG && tag && *tag == '-')
@@ -9749,7 +9892,7 @@ soap_element_end_in(struct soap *soap, const char *tag)
do
{ while (((c = soap_get(soap)) != SOAP_TT))
{ if ((int)c == EOF)
- return soap->error = SOAP_EOF;
+ return soap->error = SOAP_CHK_EOF;
if (c == SOAP_LT)
n++;
else if (c == '/')
@@ -9769,7 +9912,7 @@ soap_element_end_in(struct soap *soap, const char *tag)
}
*s = '\0';
if ((int)c == EOF)
- return soap->error = SOAP_EOF;
+ return soap->error = SOAP_CHK_EOF;
while (soap_blank(c))
c = soap_get(soap);
if (c != SOAP_GT)
@@ -9784,12 +9927,12 @@ soap_element_end_in(struct soap *soap, const char *tag)
if (tag && (soap->mode & SOAP_XML_STRICT))
{ soap_pop_namespace(soap);
if (soap_match_tag(soap, soap->tag, tag))
- { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End element tag '%s' does not match '%s'\n", soap->tag, tag?tag:SOAP_STR_EOS));
+ { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End element tag '%s' does not match '%s'\n", soap->tag, tag ? tag : SOAP_STR_EOS));
return soap->error = SOAP_SYNTAX_ERROR;
}
}
#endif
- DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End element found (level=%u) '%s'='%s'\n", soap->level, soap->tag, tag?tag:SOAP_STR_EOS));
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End element found (level=%u) '%s'='%s'\n", soap->level, soap->tag, tag ? tag : SOAP_STR_EOS));
soap->level--;
return SOAP_OK;
}
@@ -9831,7 +9974,7 @@ soap_set_attr(struct soap *soap, const char *name, const char *value, int flag)
{ register struct soap_attribute *tp;
if (*name == '-')
return SOAP_OK;
- DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set attribute %s='%s'\n", name, value?value:SOAP_STR_EOS));
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set attribute %s='%s'\n", name, value ? value : SOAP_STR_EOS));
for (tp = soap->attributes; tp; tp = tp->next)
{ if (!strcmp(tp->name, name))
break;
@@ -9883,7 +10026,7 @@ soap_set_attr(struct soap *soap, const char *name, const char *value, int flag)
{ tp->next = soap->attributes;
soap->attributes = tp;
}
- strcpy(tp->name, name);
+ strcpy((char*)tp->name, name);
tp->value = NULL;
}
else if (tp->visible)
@@ -9906,9 +10049,9 @@ soap_set_attr(struct soap *soap, const char *name, const char *value, int flag)
if (!strncmp(tp->name, "xmlns:", 6))
tp->ns = tp->value;
tp->visible = 2;
- tp->flag = flag;
+ tp->flag = (short)flag;
#ifndef WITH_LEAN
- if (soap->event != SOAP_SEC_SIGN && !strcmp(name, "wsu:Id"))
+ if (!strcmp(name, "wsu:Id"))
{ soap->event = SOAP_SEC_BEGIN;
strncpy(soap->id, value, sizeof(soap->id));
soap->id[sizeof(soap->id)-1] = '\0';
@@ -9996,7 +10139,7 @@ soap_getattrval(struct soap *soap, char *s, size_t n, soap_wchar d)
}
default:
if ((int)c == EOF)
- return soap->error = SOAP_EOF;
+ return soap->error = SOAP_CHK_EOF;
*s++ = (char)c;
}
}
@@ -10085,8 +10228,19 @@ soap_peek_element(struct soap *soap)
soap->position = 0;
soap->null = 0;
soap->mustUnderstand = 0;
- /* skip BOM */
- if ((c = soap_getchar(soap)) != 0xEF || (c = soap_get1(soap)) != 0xBB || (c = soap_get1(soap)) != 0xBF)
+ /* UTF-8 BOM? */
+ c = soap_getchar(soap);
+ if (c == 0xEF && soap_get0(soap) == 0xBB)
+ { c = soap_get1(soap);
+ if ((c = soap_get1(soap)) == 0xBF)
+ soap->mode &= ~SOAP_ENC_LATIN;
+ else
+ soap_unget(soap, (0x0F << 12) | (0xBB << 6) | (c & 0x3F)); /* UTF-8 */
+ }
+ else if ((c == 0xFE && soap_get0(soap) == 0xFF) /* UTF-16 BE */
+ || (c == 0xFF && soap_get0(soap) == 0xFE)) /* UTF-16 LE */
+ return soap->error = SOAP_UTF_ERROR;
+ else
soap_unget(soap, c);
c = soap_get(soap);
#ifdef WITH_DOM
@@ -10116,7 +10270,7 @@ soap_peek_element(struct soap *soap)
if (c != SOAP_LT)
{ *soap->tag = '\0';
if ((int)c == EOF)
- return soap->error = SOAP_EOF;
+ return soap->error = SOAP_CHK_EOF;
soap_unget(soap, c > 0 ? c | 0x80000000 : c);
#ifdef WITH_DOM
/* whitespace leading to end tag is significant for DOM */
@@ -10221,7 +10375,7 @@ soap_peek_element(struct soap *soap)
{ tp = (struct soap_attribute*)SOAP_MALLOC(soap, sizeof(struct soap_attribute) + strlen(soap->tmpbuf));
if (!tp)
return soap->error = SOAP_EOM;
- strcpy(tp->name, soap->tmpbuf);
+ strcpy((char*)tp->name, soap->tmpbuf);
tp->value = NULL;
tp->size = 0;
tp->ns = NULL;
@@ -10254,6 +10408,7 @@ soap_peek_element(struct soap *soap)
return soap->error;
if (tp->value)
SOAP_FREE(soap, tp->value);
+ tp->value = NULL;
for (;;)
{ if (soap_getattrval(soap, soap->labbuf + soap->labidx, soap->lablen - soap->labidx, c))
{ if (soap->error != SOAP_EOM)
@@ -10333,7 +10488,7 @@ soap_peek_element(struct soap *soap)
}
#endif
if ((int)c == EOF)
- return soap->error = SOAP_EOF;
+ return soap->error = SOAP_CHK_EOF;
if (!(soap->body = (c != '/')))
do c = soap_get1(soap);
while (soap_blank(c));
@@ -10342,8 +10497,6 @@ soap_peek_element(struct soap *soap)
{ if (!soap->body && soap->dom->prnt)
soap->dom = soap->dom->prnt;
}
- if (soap->feltbegin)
- return soap->error = soap->feltbegin(soap, soap->tag);
#endif
for (tp = soap->attributes; tp; tp = tp->next)
{ if (tp->visible && tp->value)
@@ -10436,6 +10589,10 @@ soap_peek_element(struct soap *soap)
}
}
}
+#ifdef WITH_DOM
+ if (soap->feltbegin)
+ return soap->error = soap->feltbegin(soap, soap->tag);
+#endif
return soap->error = SOAP_OK;
}
#endif
@@ -10536,7 +10693,7 @@ soap_string_out(struct soap *soap, const char *s, int flag)
if (soap->mode & SOAP_C_MBSTRING)
{ wchar_t wc;
register int m = mbtowc(&wc, t - 1, MB_CUR_MAX);
- if (m > 0 && (soap_wchar)wc != c)
+ if (m > 0 && !((soap_wchar)wc == c && m == 1 && c < 0x80))
{ if (soap_send_raw(soap, s, t - s - 1) || soap_pututf8(soap, wc))
return soap->error;
s = t += m - 1;
@@ -10649,11 +10806,11 @@ soap_string_in(struct soap *soap, int flag, long minlen, long maxlen)
if ((int)c == EOF)
goto end;
if ((c >= 0x80 || c < SOAP_AP) && state != 1 && !(soap->mode & SOAP_ENC_LATIN))
- { if (c >= 0x80)
+ { if ((c & 0x7FFFFFFF) >= 0x80)
{ soap_unget(soap, c);
c = soap_getutf8(soap);
}
- if (soap->mode & SOAP_C_UTFSTRING)
+ if ((c & 0x7FFFFFFF) >= 0x80 && (soap->mode & SOAP_C_UTFSTRING))
{ c &= 0x7FFFFFFF;
t = buf;
if (c < 0x0800)
@@ -10688,17 +10845,17 @@ soap_string_in(struct soap *soap, int flag, long minlen, long maxlen)
{ case 1:
if (c == ']')
state = 4;
- *s++ = c;
+ *s++ = (char)c;
continue;
case 2:
if (c == '-')
state = 6;
- *s++ = c;
+ *s++ = (char)c;
continue;
case 3:
if (c == '?')
state = 8;
- *s++ = c;
+ *s++ = (char)c;
continue;
/* CDATA */
case 4:
@@ -10706,14 +10863,14 @@ soap_string_in(struct soap *soap, int flag, long minlen, long maxlen)
state = 5;
else
state = 1;
- *s++ = c;
+ *s++ = (char)c;
continue;
case 5:
if (c == '>')
state = 0;
else
state = 1;
- *s++ = c;
+ *s++ = (char)c;
continue;
/* comment */
case 6:
@@ -10721,14 +10878,14 @@ soap_string_in(struct soap *soap, int flag, long minlen, long maxlen)
state = 7;
else
state = 2;
- *s++ = c;
+ *s++ = (char)c;
continue;
case 7:
if (c == '>')
state = 0;
else
state = 2;
- *s++ = c;
+ *s++ = (char)c;
continue;
/* PI */
case 8:
@@ -10736,7 +10893,7 @@ soap_string_in(struct soap *soap, int flag, long minlen, long maxlen)
state = 0;
else
state = 3;
- *s++ = c;
+ *s++ = (char)c;
continue;
}
switch (c)
@@ -10830,7 +10987,7 @@ soap_string_in(struct soap *soap, int flag, long minlen, long maxlen)
#ifndef WITH_LEANER
#ifdef HAVE_WCTOMB
if (soap->mode & SOAP_C_MBSTRING)
- { m = wctomb(buf, c & 0x7FFFFFFF);
+ { m = wctomb(buf, (wchar_t)(c & 0x7FFFFFFF));
if (m >= 1 && m <= (int)MB_CUR_MAX)
{ t = buf;
*s++ = *t++;
@@ -11001,7 +11158,7 @@ soap_string_in(struct soap *soap, int flag, long minlen, long maxlen)
#ifndef WITH_LEANER
#ifdef HAVE_WCTOMB
if (soap->mode & SOAP_C_MBSTRING)
- { m = wctomb(buf, c & 0x7FFFFFFF);
+ { m = wctomb(buf, (wchar_t)(c & 0x7FFFFFFF));
if (m >= 1 && m <= (int)MB_CUR_MAX)
{ t = buf;
*s++ = *t++;
@@ -11266,7 +11423,7 @@ soap_wstring_in(struct soap *soap, int flag, long minlen, long maxlen)
if ((int)c == EOF)
goto end;
if (sizeof(wchar_t) < 4 && c > 0xFFFF)
- { wchar_t c1, c2;
+ { soap_wchar c1, c2;
/* http://unicode.org/faq/utf_bom.html#utf16-2 */
c1 = 0xD800 - (0x10000 >> 10) + (c >> 10);
c2 = 0xDC00 + (c & 0x3FF);
@@ -11511,7 +11668,7 @@ soap_s2LONG64(struct soap *soap, const char *s, LONG64 *p)
soap_reset_errno;
#endif
#endif
- *p = strtoll(s, &r, 10);
+ *p = soap_strtoll(s, &r, 10);
if (s == r || *r
#ifndef WITH_NOIO
#ifndef WITH_LEAN
@@ -11726,7 +11883,11 @@ soap_float2s(struct soap *soap, float n)
return "-INF";
s = soap->tmpbuf;
#if defined(HAVE_SPRINTF_L)
+# ifdef WIN32
+ _sprintf_s_l(s, _countof(soap->tmpbuf), soap->float_format, soap->c_locale, n);
+# else
sprintf_l(s, soap->c_locale, soap->float_format, n);
+# endif
#else
sprintf(s, soap->float_format, n);
s = strchr(s, ','); /* convert decimal comma to DP */
@@ -11772,7 +11933,11 @@ soap_s2float(struct soap *soap, const char *s, float *p)
/* On some systems strtof requires -std=c99 or does not even link: so we try to use strtod first */
#if defined(HAVE_STRTOD_L)
char *r;
+# ifdef WIN32
+ *p = (float)_strtod_l(s, &r, soap->c_locale);
+# else
*p = (float)strtod_l(s, &r, soap->c_locale);
+# endif
if (*r)
#elif defined(HAVE_STRTOD)
char *r;
@@ -11872,7 +12037,11 @@ soap_double2s(struct soap *soap, double n)
return "-INF";
s = soap->tmpbuf;
#if defined(HAVE_SPRINTF_L)
+# ifdef WIN32
+ _sprintf_s_l(s, _countof(soap->tmpbuf), soap->double_format, soap->c_locale, n);
+# else
sprintf_l(s, soap->c_locale, soap->double_format, n);
+# endif
#else
sprintf(s, soap->double_format, n);
s = strchr(s, ','); /* convert decimal comma to DP */
@@ -11917,7 +12086,11 @@ soap_s2double(struct soap *soap, const char *s, double *p)
{
#if defined(HAVE_STRTOD_L)
char *r;
+# ifdef WIN32
+ *p = _strtod_l(s, &r, soap->c_locale);
+# else
*p = strtod_l(s, &r, soap->c_locale);
+# endif
if (*r)
#elif defined(HAVE_STRTOD)
char *r;
@@ -12313,7 +12486,7 @@ soap_s2ULONG64(struct soap *soap, const char *s, ULONG64 *p)
soap_reset_errno;
#endif
#endif
- *p = strtoull(s, &r, 10);
+ *p = soap_strtoull(s, &r, 10);
if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r
#ifndef WITH_NOIO
#ifndef WITH_LEAN
@@ -12414,7 +12587,7 @@ soap_s2QName(struct soap *soap, const char *s, char **t, long minlen, long maxle
break;
/* find next QName */
n = 1;
- while (s[n] && !soap_blank(s[n]))
+ while (s[n] && !soap_blank((soap_wchar)s[n]))
n++;
np = soap->nlist;
/* if there is no namespace stack, or prefix is "xml" then copy string */
@@ -12455,7 +12628,7 @@ soap_s2QName(struct soap *soap, const char *s, char **t, long minlen, long maxle
soap_append_lab(soap, "\"", 1);
}
else
- { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\nNamespace prefix of '%s' not defined (index=%d, URI=%s)\n", s, np->index, np->ns?np->ns:SOAP_STR_EOS));
+ { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\nNamespace prefix of '%s' not defined (index=%d, URI=%s)\n", s, np->index, np->ns ? np->ns : SOAP_STR_EOS));
return soap->error = SOAP_NAMESPACE;
}
}
@@ -12506,10 +12679,7 @@ soap_QName2s(struct soap *soap, const char *s)
{ soap_append_lab(soap, s, n);
#ifndef WITH_LEAN
if ((soap->mode & SOAP_XML_CANONICAL))
- { const char *r = strchr(s, ':');
- if (r)
- soap_utilize_ns(soap, s, r - s);
- }
+ soap_utilize_ns(soap, s);
#endif
}
else /* URL-based string prefix */
@@ -12688,7 +12858,8 @@ SOAP_FMAC1
char **
SOAP_FMAC2
soap_instring(struct soap *soap, const char *tag, char **p, const char *type, int t, int flag, long minlen, long maxlen)
-{ if (soap_element_begin_in(soap, tag, 1, NULL))
+{ (void)type;
+ if (soap_element_begin_in(soap, tag, 1, NULL))
{ if (!tag || *tag != '-' || soap->error != SOAP_NO_TAG)
return NULL;
soap->error = SOAP_OK;
@@ -12754,7 +12925,8 @@ SOAP_FMAC1
wchar_t **
SOAP_FMAC2
soap_inwstring(struct soap *soap, const char *tag, wchar_t **p, const char *type, int t, long minlen, long maxlen)
-{ if (soap_element_begin_in(soap, tag, 1, NULL))
+{ (void)type;
+ if (soap_element_begin_in(soap, tag, 1, NULL))
{ if (!tag || *tag != '-' || soap->error != SOAP_NO_TAG)
return NULL;
soap->error = SOAP_OK;
@@ -13217,7 +13389,7 @@ soap_getline(struct soap *soap, char *s, int len)
if (c == '\r' || c == '\n')
break;
if ((int)c == EOF)
- return soap->error = SOAP_EOF;
+ return soap->error = SOAP_CHK_EOF;
*s++ = (char)c;
}
if (c != '\n')
@@ -13231,7 +13403,7 @@ soap_getline(struct soap *soap, char *s, int len)
break;
}
else if ((int)c == EOF)
- return soap->error = SOAP_EOF;
+ return soap->error = SOAP_CHK_EOF;
if (i < 0)
return soap->error = SOAP_HDR;
}
@@ -13346,7 +13518,7 @@ SOAP_FMAC2
soap_putdimehdr(struct soap *soap)
{ unsigned char tmp[12];
size_t optlen = 0, idlen = 0, typelen = 0;
- DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Put DIME header id='%s'\n", soap->dime.id?soap->dime.id:SOAP_STR_EOS));
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Put DIME header id='%s'\n", soap->dime.id ? soap->dime.id : SOAP_STR_EOS));
if (soap->dime.options)
optlen = (((unsigned char)soap->dime.options[2] << 8) | ((unsigned char)soap->dime.options[3])) + 4;
if (soap->dime.id)
@@ -13442,7 +13614,7 @@ soap_putdime(struct soap *soap)
bufsize = sizeof(soap->tmpbuf);
if (!(bufsize = soap->fdimeread(soap, handle, soap->tmpbuf, bufsize)))
{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimeread failed: insufficient data (%lu bytes remaining from %lu bytes)\n", (unsigned long)size, (unsigned long)content->size));
- soap->error = SOAP_EOF;
+ soap->error = SOAP_CHK_EOF;
break;
}
if (soap_send_raw(soap, soap->tmpbuf, bufsize))
@@ -13484,7 +13656,7 @@ soap_getdimefield(struct soap *soap, size_t n)
{ s = p;
for (i = n; i > 0; i--)
{ if ((int)(c = soap_get1(soap)) == EOF)
- { soap->error = SOAP_EOF;
+ { soap->error = SOAP_CHK_EOF;
return NULL;
}
*s++ = (char)c;
@@ -13518,7 +13690,7 @@ soap_getdimehdr(struct soap *soap)
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get DIME header\n"));
if (soap->dime.buflen || soap->dime.chunksize)
{ if (soap_move(soap, (long)(soap->dime.size - soap_tell(soap))))
- return soap->error = SOAP_EOF;
+ return soap->error = SOAP_CHK_EOF;
soap_unget(soap, soap_getchar(soap)); /* skip padding and get hdr */
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "... From chunked\n"));
return SOAP_OK;
@@ -13526,7 +13698,7 @@ soap_getdimehdr(struct soap *soap)
s = (char*)tmp;
for (i = 12; i > 0; i--)
{ if ((int)(c = soap_getchar(soap)) == EOF)
- return soap->error = SOAP_EOF;
+ return soap->error = SOAP_CHK_EOF;
*s++ = (char)c;
}
if ((tmp[0] & 0xF8) != SOAP_DIME_VERSION)
@@ -13543,7 +13715,7 @@ soap_getdimehdr(struct soap *soap)
return soap->error;
if (!(soap->dime.type = soap_getdimefield(soap, typelen)) && soap->error)
return soap->error;
- DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DIME id=%s, type=%s, options=%s\n", soap->dime.id?soap->dime.id:SOAP_STR_EOS, soap->dime.type?soap->dime.type:"", soap->dime.options?soap->dime.options+4:SOAP_STR_EOS));
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DIME id=%s, type=%s, options=%s\n", soap->dime.id ? soap->dime.id : SOAP_STR_EOS, soap->dime.type ? soap->dime.type : "", soap->dime.options ? soap->dime.options+4 : SOAP_STR_EOS));
if (soap->dime.flags & SOAP_DIME_ME)
soap->mode &= ~SOAP_ENC_DIME;
return SOAP_OK;
@@ -13795,7 +13967,7 @@ soap_get_mime_attachment(struct soap *soap, void *handle)
return NULL;
}
}
- DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Parsing MIME content id=%s type=%s\n", content->id?content->id:SOAP_STR_EOS, content->type?content->type:SOAP_STR_EOS));
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Parsing MIME content id=%s type=%s\n", content->id ? content->id : SOAP_STR_EOS, content->type ? content->type : SOAP_STR_EOS));
if (!content->ptr && soap_new_block(soap) == NULL)
{ soap->error = SOAP_EOM;
return NULL;
@@ -13816,7 +13988,7 @@ soap_get_mime_attachment(struct soap *soap, void *handle)
{ if (!flag)
{ c = soap_get1(soap);
if ((int)c == EOF)
- { soap->error = SOAP_EOF;
+ { soap->error = SOAP_CHK_EOF;
return NULL;
}
}
@@ -13829,7 +14001,7 @@ soap_get_mime_attachment(struct soap *soap, void *handle)
do c = soap_getchar(soap);
while (c == *t++);
if ((int)c == EOF)
- { soap->error = SOAP_EOF;
+ { soap->error = SOAP_CHK_EOF;
return NULL;
}
if (!*--t)
@@ -13954,7 +14126,7 @@ int
SOAP_FMAC2
soap_putmimehdr(struct soap *soap, struct soap_multipart *content)
{ const char *s;
- DBGLOG(TEST, SOAP_MESSAGE(fdebug, "MIME attachment type=%s\n", content->type?content->type:SOAP_STR_EOS));
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "MIME attachment type=%s\n", content->type ? content->type : SOAP_STR_EOS));
if (soap_send3(soap, "\r\n--", soap->mime.boundary, "\r\n"))
return soap->error;
if (content->type && soap_send3(soap, "Content-Type: ", content->type, "\r\n"))
@@ -14245,7 +14417,7 @@ soap_getgziphdr(struct soap *soap)
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get gzip header\n"));
for (i = 0; i < 9; i++)
{ if ((int)(c = soap_get1(soap) == EOF))
- return soap->error = SOAP_EOF;
+ return soap->error = SOAP_ZLIB_ERROR;
if (i == 1 && c == 8)
soap->z_dict = 0;
if (i == 2)
@@ -14254,7 +14426,7 @@ soap_getgziphdr(struct soap *soap)
if (f & 0x04) /* FEXTRA */
{ for (i = soap_get1(soap) | (soap_get1(soap) << 8); i; i--)
{ if ((int)soap_get1(soap) == EOF)
- return soap->error = SOAP_EOF;
+ return soap->error = SOAP_ZLIB_ERROR;
}
}
if (f & 0x08) /* skip FNAME */
@@ -14272,7 +14444,7 @@ soap_getgziphdr(struct soap *soap)
c = soap_get1(soap);
}
if ((int)c == EOF)
- return soap->error = SOAP_EOF;
+ return soap->error = SOAP_ZLIB_ERROR;
return SOAP_OK;
}
#endif
@@ -14292,7 +14464,10 @@ soap_begin_serve(struct soap *soap)
}
#endif
soap_begin(soap);
- if (soap_begin_recv(soap))
+ if (soap_begin_recv(soap)
+ || soap_envelope_begin_in(soap)
+ || soap_recv_header(soap)
+ || soap_body_begin_in(soap))
{ if (soap->error < SOAP_STOP)
{
#ifdef WITH_FASTCGI
@@ -14303,10 +14478,6 @@ soap_begin_serve(struct soap *soap)
}
return soap_closesock(soap);
}
- if (soap_envelope_begin_in(soap)
- || soap_recv_header(soap)
- || soap_body_begin_in(soap))
- return soap->error;
return SOAP_OK;
}
#endif
@@ -14317,7 +14488,7 @@ SOAP_FMAC1
int
SOAP_FMAC2
soap_begin_recv(struct soap *soap)
-{ soap_wchar c;
+{ register soap_wchar c;
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing for input\n"));
soap->error = SOAP_OK;
soap->filterstop = SOAP_OK;
@@ -14350,6 +14521,7 @@ soap_begin_recv(struct soap *soap)
soap->header = NULL;
soap->fault = NULL;
soap->status = 0;
+ soap->fform = NULL;
#ifndef WITH_LEANER
soap->dom = NULL;
soap->dime.chunksize = 0;
@@ -14366,7 +14538,7 @@ soap_begin_recv(struct soap *soap)
#ifdef WIN32
#ifndef UNDER_CE
#ifndef WITH_FASTCGI
- if (!soap_valid_socket(soap->socket))
+ if (!soap_valid_socket(soap->socket) && !soap->is) /* Set win32 stdout or soap->sendfd to BINARY, e.g. to support DIME */
#ifdef __BORLANDC__
setmode(soap->recvfd, _O_BINARY);
#else
@@ -14433,14 +14605,24 @@ soap_begin_recv(struct soap *soap)
else
#endif
{ /* skip BOM */
- if (c == 0xEF && (c = soap_getchar(soap)) == 0xBB && (c = soap_getchar(soap)) == 0xBF)
- c = soap_getchar(soap);
+ if (c == 0xEF && soap_get0(soap) == 0xBB)
+ { c = soap_get1(soap);
+ if ((c = soap_get1(soap)) == 0xBF)
+ { soap->mode &= ~SOAP_ENC_LATIN;
+ c = soap_getchar(soap);
+ }
+ else
+ c = (0x0F << 12) | (0xBB << 6) | (c & 0x3F); /* UTF-8 */
+ }
+ else if ((c == 0xFE && soap_get0(soap) == 0xFF) /* UTF-16 BE */
+ || (c == 0xFF && soap_get0(soap) == 0xFE)) /* UTF-16 LE */
+ return soap->error = SOAP_UTF_ERROR;
/* skip space */
while (soap_blank(c))
c = soap_getchar(soap);
}
if ((int)c == EOF)
- return soap->error = SOAP_EOF;
+ return soap->error = SOAP_CHK_EOF;
soap_unget(soap, c);
#ifndef WITH_NOHTTP
/* if not XML or MIME/DIME/ZLIB, assume HTTP header */
@@ -14453,7 +14635,13 @@ soap_begin_recv(struct soap *soap)
return soap->error;
}
if (soap->error == SOAP_STOP)
+ { if (soap->fform)
+ { soap->error = soap->fform(soap);
+ if (soap->error == SOAP_OK)
+ soap->error = SOAP_STOP; /* prevents further processing */
+ }
return soap->error;
+ }
soap->mode = soap->imode; /* if imode is changed, effectuate */
soap->imode = m; /* restore imode */
#ifdef WITH_ZLIB
@@ -14532,7 +14720,7 @@ soap_begin_recv(struct soap *soap)
if (soap->mode & SOAP_ENC_MIME)
{ do /* skip preamble */
{ if ((int)(c = soap_getchar(soap)) == EOF)
- return soap->error = SOAP_EOF;
+ return soap->error = SOAP_CHK_EOF;
} while (c != '-' || soap_get0(soap) != '-');
soap_unget(soap, c);
if (soap_getmimehdr(soap))
@@ -14614,7 +14802,8 @@ SOAP_FMAC1
int
SOAP_FMAC2
soap_envelope_end_out(struct soap *soap)
-{ if (soap_element_end_out(soap, "SOAP-ENV:Envelope") || soap_send_raw(soap, "\r\n", 2)) /* 2.8: always emit \r\n after SOAP Envelope */
+{ if (soap_element_end_out(soap, "SOAP-ENV:Envelope")
+ || soap_send_raw(soap, "\r\n", 2)) /* 2.8: always emit \r\n */
return soap->error;
#ifndef WITH_LEANER
if ((soap->mode & SOAP_IO_LENGTH) && (soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM))
@@ -14959,23 +15148,32 @@ soap_try_connect_command(struct soap *soap, int http_command, const char *endpoi
}
else
#endif
+ soap->action = soap_strdup(soap, action);
if (soap->fopen && *soap->host)
{ if (!soap->keep_alive || !soap_valid_socket(soap->socket) || strcmp(soap->host, host) || soap->port != port || !soap->fpoll || soap->fpoll(soap))
{ soap->error = SOAP_OK;
- soap->keep_alive = 0; /* to force close */
- soap->omode &= ~SOAP_IO_UDP; /* to force close */
- soap_closesock(soap);
- DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Connect/reconnect to host='%s' path='%s' port=%d\n", soap->host, soap->path, soap->port));
#ifndef WITH_LEAN
if (!strncmp(endpoint, "soap.udp:", 9))
soap->omode |= SOAP_IO_UDP;
+ else
#endif
- soap->socket = soap->fopen(soap, endpoint, soap->host, soap->port);
- if (soap->error)
- return soap->error;
- soap->keep_alive = ((soap->omode & SOAP_IO_KEEPALIVE) != 0);
+ { soap->keep_alive = 0; /* to force close */
+ soap->omode &= ~SOAP_IO_UDP; /* to force close */
+ }
+ soap_closesock(soap);
+ DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Connect/reconnect to '%s' host='%s' path='%s' port=%d\n", endpoint?endpoint:"(null)", soap->host, soap->path, soap->port));
+ if (!soap->keep_alive || !soap_valid_socket(soap->socket))
+ { soap->socket = soap->fopen(soap, endpoint, soap->host, soap->port);
+ if (soap->error)
+ return soap->error;
+ soap->keep_alive = ((soap->omode & SOAP_IO_KEEPALIVE) != 0);
+ }
}
}
+#ifdef WITH_NTLM
+ if (soap_ntlm_handshake(soap, SOAP_GET, endpoint, soap->host, soap->port))
+ return soap->error;
+#endif
count = soap_count_attachments(soap);
if (soap_begin_send(soap))
return soap->error;
@@ -14984,7 +15182,6 @@ soap_try_connect_command(struct soap *soap, int http_command, const char *endpoi
soap->mode |= SOAP_IO_BUFFER;
}
#ifndef WITH_NOHTTP
- soap->action = soap_strdup(soap, action);
if ((soap->mode & SOAP_IO) != SOAP_IO_STORE && !(soap->mode & SOAP_ENC_XML) && endpoint)
{ unsigned int k = soap->mode;
soap->mode &= ~(SOAP_IO | SOAP_ENC_ZLIB);
@@ -15000,7 +15197,7 @@ soap_try_connect_command(struct soap *soap, int http_command, const char *endpoi
#endif
soap->mode = k;
}
- if (http_command == SOAP_GET)
+ if (http_command == SOAP_GET || http_command == SOAP_DEL)
return soap_end_send(soap);
#endif
return SOAP_OK;
@@ -15008,6 +15205,80 @@ soap_try_connect_command(struct soap *soap, int http_command, const char *endpoi
#endif
/******************************************************************************/
+#ifdef WITH_NTLM
+#ifndef PALM_1
+static int
+soap_ntlm_handshake(struct soap *soap, int command, const char *endpoint, const char *host, int port)
+{ /* requires libntlm from http://www.nongnu.org/libntlm/ */
+ const char *userid = (soap->proxy_userid ? soap->proxy_userid : soap->userid);
+ const char *passwd = (soap->proxy_passwd ? soap->proxy_passwd : soap->passwd);
+ struct SOAP_ENV__Header *oldheader;
+ if (soap->ntlm_challenge && userid && passwd && soap->authrealm)
+ { tSmbNtlmAuthRequest req;
+ tSmbNtlmAuthResponse res;
+ tSmbNtlmAuthChallenge ch;
+ short k = soap->keep_alive;
+ size_t l = soap->length;
+ size_t c = soap->count;
+ soap_mode m = soap->mode, o = soap->omode;
+ int s = soap->status;
+ DBGLOG(TEST,SOAP_MESSAGE(fdebug, "NTLM '%s'\n", soap->ntlm_challenge));
+ if (!*soap->ntlm_challenge)
+ { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "NTLM S->C Type 1: received NTLM authentication challenge from server\n"));
+ /* S -> C 401 Unauthorized
+ WWW-Authenticate: NTLM
+ */
+ buildSmbNtlmAuthRequest(&req, userid, soap->authrealm);
+ soap->ntlm_challenge = soap_s2base64(soap, (unsigned char*)&req, NULL, SmbLength(&req));
+ DBGLOG(TEST,SOAP_MESSAGE(fdebug, "NTLM C->S Type 2: sending NTLM authorization to server\nAuthorization: NTLM %s\n", soap->ntlm_challenge));
+ /* C -> S GET ...
+ Authorization: NTLM TlRMTVNTUAABAAAAA7IAAAoACgApAAAACQAJACAAAABMSUdIVENJVFlVUlNBLU1JTk9S
+ */
+ soap->omode = SOAP_IO_BUFFER;
+ if (soap_begin_send(soap))
+ return soap->error;
+ soap->keep_alive = 1;
+ soap->status = command;
+ if (soap->fpost(soap, endpoint, host, port, soap->path, soap->action, 0)
+ || soap_end_send(soap))
+ return soap->error;
+ soap->mode = m;
+ soap->keep_alive = k;
+ DBGLOG(TEST,SOAP_MESSAGE(fdebug, "NTLM S->C Type 2: waiting on server NTLM response\n"));
+ oldheader = soap->header;
+ if (soap_begin_recv(soap))
+ if (soap->error == SOAP_EOF)
+ return soap->error;
+ soap_end_recv(soap);
+ soap->header = oldheader;
+ soap->length = l;
+ if (soap->status != 401 && soap->status != 407)
+ return soap->error = SOAP_NTLM_ERROR;
+ soap->error = SOAP_OK;
+ }
+ /* S -> C 401 Unauthorized
+ WWW-Authenticate: NTLM TlRMTVNTUAACAAAAAAAAACgAAAABggAAU3J2Tm9uY2UAAAAAAAAAAA==
+ */
+ soap_base642s(soap, soap->ntlm_challenge, (char*)&ch, sizeof(tSmbNtlmAuthChallenge), NULL);
+ buildSmbNtlmAuthResponse(&ch, &res, userid, passwd);
+ soap->ntlm_challenge = soap_s2base64(soap, (unsigned char*)&res, NULL, SmbLength(&res));
+ DBGLOG(TEST,SOAP_MESSAGE(fdebug, "NTLM C->S Type 3: sending NTLM authorization to server\nAuthorization: NTLM %s\n", soap->ntlm_challenge));
+ /* C -> S GET ...
+ Authorization: NTLM TlRMTVNTUAADAAAAGAAYAHIAAAAYABgAigAAABQAFABAAAAADAAMAFQAAAASABIAYAAAAAAAAACiAAAAAYIAAFUAUgBTAEEALQBNAEkATgBPAFIAWgBhAHAAaABvAGQATABJAEcASABUAEMASQBUAFkArYfKbe/jRoW5xDxHeoxC1gBmfWiS5+iX4OAN4xBKG/IFPwfH3agtPEia6YnhsADT
+ */
+ soap->keep_alive = k;
+ soap->length = l;
+ soap->count = c;
+ soap->mode = m;
+ soap->omode = o;
+ soap->status = s;
+ }
+ return SOAP_OK;
+}
+#endif
+#endif
+
+/******************************************************************************/
#ifndef WITH_LEAN
SOAP_FMAC1
char*
@@ -15055,7 +15326,8 @@ SOAP_FMAC1
const char*
SOAP_FMAC2
soap_base642s(struct soap *soap, const char *s, char *t, size_t l, int *n)
-{ register int i, j, c;
+{ register size_t i, j;
+ register soap_wchar c;
register unsigned long m;
register const char *p;
if (!s || !*s)
@@ -15066,7 +15338,7 @@ soap_base642s(struct soap *soap, const char *s, char *t, size_t l, int *n)
return SOAP_NON_NULL;
}
if (!t)
- { l = (strlen(s) + 3) / 4 * 3;
+ { l = (strlen(s) + 3) / 4 * 3 + 1; /* make sure enough space for \0 */
t = (char*)soap_malloc(soap, l);
}
if (!t)
@@ -15093,7 +15365,9 @@ soap_base642s(struct soap *soap, const char *s, char *t, size_t l, int *n)
i += 2;
}
if (n)
- *n += i;
+ *n += (int)i;
+ if (l >= j)
+ *t = '\0';
return p;
}
c -= '+';
@@ -15111,14 +15385,15 @@ soap_base642s(struct soap *soap, const char *s, char *t, size_t l, int *n)
return NULL;
}
}
- *t++ = (char)((m >> 16) & 0xFF);
- *t++ = (char)((m >> 8) & 0xFF);
- *t++ = (char)(m & 0xFF);
if (l < 3)
{ if (n)
- *n += i;
+ *n += (int)i;
+ *t = '\0';
return p;
}
+ *t++ = (char)((m >> 16) & 0xFF);
+ *t++ = (char)((m >> 8) & 0xFF);
+ *t++ = (char)(m & 0xFF);
l -= 3;
}
if (n)
@@ -15168,7 +15443,7 @@ soap_hex2s(struct soap *soap, const char *s, char *t, size_t l, int *n)
return SOAP_NON_NULL;
}
if (!t)
- { l = strlen(s) / 2;
+ { l = strlen(s) / 2 + 1; /* make sure enough space for \0 */
t = (char*)soap_malloc(soap, l);
}
if (!t)
@@ -15182,11 +15457,13 @@ soap_hex2s(struct soap *soap, const char *s, char *t, size_t l, int *n)
d2 = *s++;
if (!d2)
break;
- *t++ = ((d1 >= 'A' ? (d1 & 0x7) + 9 : d1 - '0') << 4) + (d2 >= 'A' ? (d2 & 0x7) + 9 : d2 - '0');
+ *t++ = (char)(((d1 >= 'A' ? (d1 & 0x7) + 9 : d1 - '0') << 4) + (d2 >= 'A' ? (d2 & 0x7) + 9 : d2 - '0'));
l--;
}
if (n)
*n = (int)(t - p);
+ if (l)
+ *t = '\0';
return p;
}
#endif
@@ -15198,13 +15475,13 @@ SOAP_FMAC1
int
SOAP_FMAC2
soap_puthttphdr(struct soap *soap, int status, size_t count)
-{ if (soap->status != SOAP_GET)
+{ if (soap->status != SOAP_GET && soap->status != SOAP_DEL && soap->status != SOAP_CONNECT)
{ register const char *s = "text/xml; charset=utf-8";
register int err = SOAP_OK;
#ifndef WITH_LEANER
register const char *r = NULL;
#endif
- if ((status == SOAP_FILE || soap->status == SOAP_POST_FILE) && soap->http_content)
+ if ((status == SOAP_FILE || soap->status == SOAP_PUT || soap->status == SOAP_POST_FILE) && soap->http_content)
s = soap->http_content;
else if (status == SOAP_HTML)
s = "text/html; charset=utf-8";
@@ -15245,12 +15522,12 @@ soap_puthttphdr(struct soap *soap, int status, size_t count)
}
s = soap->tmpbuf;
}
- if (status == SOAP_OK && soap->version == 2 && soap->action && strlen(soap->action) < sizeof(soap->tmpbuf) - 80)
- { sprintf(soap->tmpbuf, "%s; action=\"%s\"", s, soap->action);
- s = soap->tmpbuf;
- }
+ else
+ s = strcpy(soap->tmpbuf, s);
+ if (status == SOAP_OK && soap->version == 2 && soap->action && strlen(soap->action) + strlen(s) < sizeof(soap->tmpbuf) - 80)
+ sprintf(soap->tmpbuf + strlen(s), "; action=\"%s\"", soap->action);
#endif
- if (s && (err = soap->fposthdr(soap, "Content-Type", s)))
+ if ((err = soap->fposthdr(soap, "Content-Type", s)))
return err;
#ifdef WITH_ZLIB
if ((soap->omode & SOAP_ENC_ZLIB))
@@ -15286,9 +15563,17 @@ soap_puthttphdr(struct soap *soap, int status, size_t count)
static const char*
soap_set_validation_fault(struct soap *soap, const char *s, const char *t)
{ if (*soap->tag)
- sprintf(soap->msgbuf, "Validation constraint violation: %s%s in element '%s'", s, t?t:SOAP_STR_EOS, soap->tag);
+#ifdef HAVE_SNPRINTF
+ soap_snprintf(soap->msgbuf, sizeof(soap->msgbuf), "Validation constraint violation: %s%s in element '%s'", s, t ? t : SOAP_STR_EOS, soap->tag);
+#else
+ sprintf(soap->msgbuf, "Validation constraint violation: %s%s in element '%s'", s, t ? t : SOAP_STR_EOS, soap->tag);
+#endif
else
- sprintf(soap->msgbuf, "Validation constraint violation: %s%s", s, t?t:SOAP_STR_EOS);
+#ifdef HAVE_SNPRINTF
+ soap_snprintf(soap->msgbuf, sizeof(soap->msgbuf), "Validation constraint violation: %s%s", s, t ? t : SOAP_STR_EOS);
+#else
+ sprintf(soap->msgbuf, "Validation constraint violation: %s%s", s, t ? t : SOAP_STR_EOS);
+#endif
return soap->msgbuf;
}
#endif
@@ -15330,11 +15615,15 @@ soap_set_fault(struct soap *soap)
*s = "Well-formedness violation";
break;
case SOAP_NO_TAG:
- *s = "No XML root element";
+ *s = "No tag: no XML root element or missing SOAP message body element";
break;
case SOAP_MUSTUNDERSTAND:
*c = "SOAP-ENV:MustUnderstand";
+#ifdef HAVE_SNPRINTF
+ soap_snprintf(soap->msgbuf, sizeof(soap->msgbuf), "The data in element '%s' must be understood but cannot be handled", soap->tag);
+#else
sprintf(soap->msgbuf, "The data in element '%s' must be understood but cannot be handled", soap->tag);
+#endif
*s = soap->msgbuf;
break;
case SOAP_VERSIONMISMATCH:
@@ -15355,7 +15644,11 @@ soap_set_fault(struct soap *soap)
*s = "Fatal error";
break;
case SOAP_NO_METHOD:
+#ifdef HAVE_SNPRINTF
+ soap_snprintf(soap->msgbuf, sizeof(soap->msgbuf), "Method '%s' not implemented: method name or namespace not recognized", soap->tag);
+#else
sprintf(soap->msgbuf, "Method '%s' not implemented: method name or namespace not recognized", soap->tag);
+#endif
*s = soap->msgbuf;
break;
case SOAP_NO_DATA:
@@ -15386,7 +15679,7 @@ soap_set_fault(struct soap *soap)
*s = soap_set_validation_fault(soap, "nil not allowed", NULL);
break;
case SOAP_DUPLICATE_ID:
- *s = soap_set_validation_fault(soap, "multiple definitions of id ", soap->id);
+ *s = soap_set_validation_fault(soap, "multiple definitions (use the SOAP_XML_TREE flag) of the same id ", soap->id);
if (soap->version == 2)
*soap_faultsubcode(soap) = "SOAP-ENC:DuplicateID";
break;
@@ -15411,6 +15704,9 @@ soap_set_fault(struct soap *soap)
case SOAP_HTTP_ERROR:
*s = "An HTTP processing error occurred";
break;
+ case SOAP_NTLM_ERROR:
+ *s = "An HTTP NTLM authentication error occurred";
+ break;
case SOAP_SSL_ERROR:
#ifdef WITH_OPENSSL
*s = "SSL/TLS error";
@@ -15444,7 +15740,11 @@ soap_set_fault(struct soap *soap)
break;
case SOAP_ZLIB_ERROR:
#ifdef WITH_ZLIB
- sprintf(soap->msgbuf, "Zlib/gzip error: '%s'", soap->d_stream->msg?soap->d_stream->msg:SOAP_STR_EOS);
+#ifdef HAVE_SNPRINTF
+ soap_snprintf(soap->msgbuf, sizeof(soap->msgbuf), "Zlib/gzip error: '%s'", soap->d_stream->msg ? soap->d_stream->msg : SOAP_STR_EOS);
+#else
+ sprintf(soap->msgbuf, "Zlib/gzip error: '%s'", soap->d_stream->msg ? soap->d_stream->msg : SOAP_STR_EOS);
+#endif
*s = soap->msgbuf;
#else
*s = "Zlib/gzip not installed for (de)compression: recompile with -DWITH_GZIP";
@@ -15465,8 +15765,11 @@ soap_set_fault(struct soap *soap)
case SOAP_FD_EXCEEDED:
*s = "Maximum number of open connections was reached (no define HAVE_POLL): increase FD_SETSIZE";
break;
+ case SOAP_UTF_ERROR:
+ *s = "UTF content encoding error";
+ break;
case SOAP_STOP:
- *s = "Stopped: no response to be sent or received (informative)";
+ *s = "Stopped: no response sent or received (informative)";
break;
#endif
case SOAP_EOF:
@@ -15488,7 +15791,12 @@ soap_set_fault(struct soap *soap)
#ifndef WITH_NOHTTP
#ifndef WITH_LEAN
if (soap->error > 200 && soap->error < 600)
- { sprintf(soap->msgbuf, "HTTP Error: %d %s", soap->error, http_error(soap, soap->error));
+ {
+#ifdef HAVE_SNPRINTF
+ soap_snprintf(soap->msgbuf, sizeof(soap->msgbuf), "HTTP Error: %d %s", soap->error, http_error(soap, soap->error));
+#else
+ sprintf(soap->msgbuf, "HTTP Error: %d %s", soap->error, http_error(soap, soap->error));
+#endif
*s = soap->msgbuf;
}
else
@@ -15617,12 +15925,14 @@ int
SOAP_FMAC2
soap_send_empty_response(struct soap *soap, int httpstatuscode)
{ register soap_mode m = soap->omode;
- soap->count = 0;
- if ((m & SOAP_IO) == SOAP_IO_CHUNK)
- soap->omode = (m & ~SOAP_IO) | SOAP_IO_BUFFER;
- if (!soap_response(soap, httpstatuscode) && !soap_end_send(soap))
- soap->error = SOAP_STOP; /* stops the server's response */
- soap->omode = m;
+ if (!(m & SOAP_IO_UDP))
+ { soap->count = 0;
+ if ((m & SOAP_IO) == SOAP_IO_CHUNK)
+ soap->omode = (m & ~SOAP_IO) | SOAP_IO_BUFFER;
+ if (!soap_response(soap, httpstatuscode) && !soap_end_send(soap))
+ soap->error = SOAP_STOP; /* stops the server's processing of request */
+ soap->omode = m;
+ }
return soap_closesock(soap);
}
#endif
@@ -15635,10 +15945,12 @@ SOAP_FMAC1
int
SOAP_FMAC2
soap_recv_empty_response(struct soap *soap)
-{ if (!soap_begin_recv(soap))
- soap_end_recv(soap);
- else if (soap->error == SOAP_NO_DATA || soap->error == 202)
- soap->error = SOAP_OK;
+{ if (!(soap->omode & SOAP_IO_UDP))
+ { if (!soap_begin_recv(soap))
+ soap_end_recv(soap);
+ else if (soap->error == SOAP_NO_DATA || soap->error == 202)
+ soap->error = SOAP_OK;
+ }
return soap_closesock(soap);
}
#endif
@@ -15805,16 +16117,15 @@ soap_print_fault(struct soap *soap, FILE *fd)
{ if (soap_check_state(soap))
fprintf(fd, "Error: soap struct state not initialized\n");
else if (soap->error)
- { const char *c, *v = NULL, *s, **d;
- d = soap_faultcode(soap);
- if (!*d)
+ { const char **c, *v = NULL, *s, *d;
+ c = soap_faultcode(soap);
+ if (!*c)
soap_set_fault(soap);
- c = *d;
if (soap->version == 2)
- v = *soap_faultsubcode(soap);
+ v = soap_check_faultsubcode(soap);
s = *soap_faultstring(soap);
- d = soap_faultdetail(soap);
- fprintf(fd, "%s%d fault: %s [%s]\n\"%s\"\nDetail: %s\n", soap->version ? "SOAP 1." : "Error ", soap->version ? (int)soap->version : soap->error, c, v ? v : "no subcode", s ? s : "[no reason]", d && *d ? *d : "[no detail]");
+ d = soap_check_faultdetail(soap);
+ fprintf(fd, "%s%d fault: %s [%s]\n\"%s\"\nDetail: %s\n", soap->version ? "SOAP 1." : "Error ", soap->version ? (int)soap->version : soap->error, *c, v ? v : "no subcode", s ? s : "[no reason]", d ? d : "[no detail]");
}
}
#endif
@@ -15824,6 +16135,7 @@ soap_print_fault(struct soap *soap, FILE *fd)
#ifdef __cplusplus
#ifndef WITH_LEAN
#ifndef WITH_NOSTDLIB
+#ifndef WITH_COMPAT
SOAP_FMAC1
void
SOAP_FMAC2
@@ -15831,29 +16143,29 @@ soap_stream_fault(struct soap *soap, std::ostream& os)
{ if (soap_check_state(soap))
os << "Error: soap struct state not initialized\n";
else if (soap->error)
- { const char *c, *v = NULL, *s, **d;
- d = soap_faultcode(soap);
- if (!*d)
+ { const char **c, *v = NULL, *s, *d;
+ c = soap_faultcode(soap);
+ if (!*c)
soap_set_fault(soap);
- c = *d;
if (soap->version == 2)
- v = *soap_faultsubcode(soap);
+ v = soap_check_faultsubcode(soap);
s = *soap_faultstring(soap);
- d = soap_faultdetail(soap);
+ d = soap_check_faultdetail(soap);
os << (soap->version ? "SOAP 1." : "Error ")
<< (soap->version ? (int)soap->version : soap->error)
- << " fault: " << c
+ << " fault: " << *c
<< "[" << (v ? v : "no subcode") << "]"
<< std::endl
<< "\"" << (s ? s : "[no reason]") << "\""
<< std::endl
- << "Detail: " << (d && *d ? *d : "[no detail]")
+ << "Detail: " << (d ? d : "[no detail]")
<< std::endl;
}
}
#endif
#endif
#endif
+#endif
/******************************************************************************/
#ifndef WITH_LEAN
@@ -15865,27 +16177,21 @@ soap_sprint_fault(struct soap *soap, char *buf, size_t len)
{ if (soap_check_state(soap))
strncpy(buf, "Error: soap struct not initialized", len);
else if (soap->error)
- { const char *c, *v = NULL, *s, **d;
- d = soap_faultcode(soap);
- if (!*d)
+ { const char **c, *v = NULL, *s, *d;
+ c = soap_faultcode(soap);
+ if (!*c)
soap_set_fault(soap);
- c = *d;
if (soap->version == 2)
v = *soap_faultsubcode(soap);
s = *soap_faultstring(soap);
- d = soap_faultdetail(soap);
+ d = soap_check_faultdetail(soap);
#ifdef HAVE_SNPRINTF
-# ifdef WIN32
- _snprintf
-# else
- snprintf
-# endif
- (buf, len, "%s%d fault: %s [%s]\n\"%s\"\nDetail: %s\n", soap->version ? "SOAP 1." : "Error ", soap->version ? (int)soap->version : soap->error, c, v ? v : "no subcode", s ? s : "[no reason]", d && *d ? *d : "[no detail]");
+ soap_snprintf(buf, len, "%s%d fault: %s [%s]\n\"%s\"\nDetail: %s\n", soap->version ? "SOAP 1." : "Error ", soap->version ? (int)soap->version : soap->error, *c, v ? v : "no subcode", s ? s : "[no reason]", d ? d : "[no detail]");
#else
- if (len > 40 + (v ? strlen(v) : 0) + (s ? strlen(s) : 0) + (d && *d ? strlen(*d) : 0))
- sprintf(buf, "%s%d fault: %s [%s]\n\"%s\"\nDetail: %s\n", soap->version ? "SOAP 1." : "Error ", soap->version ? (int)soap->version : soap->error, c, v ? v : "no subcode", s ? s : "[no reason]", d && *d ? *d : "[no detail]");
+ if (len > 40 + (v ? strlen(v) : 0) + (s ? strlen(s) : 0) + (d ? strlen(d) : 0))
+ sprintf(buf, "%s%d fault: %s [%s]\n\"%s\"\nDetail: %s\n", soap->version ? "SOAP 1." : "Error ", soap->version ? (int)soap->version : soap->error, *c, v ? v : "no subcode", s ? s : "[no reason]", d ? d : "[no detail]");
else if (len > 40)
- sprintf(buf, "%s%d fault: %s\n", soap->version ? "SOAP 1." : "Error ", soap->version ? (int)soap->version : soap->error, c);
+ sprintf(buf, "%s%d fault: %s\n", soap->version ? "SOAP 1." : "Error ", soap->version ? (int)soap->version : soap->error, *c);
else
buf[0] = '\0';
#endif
@@ -15920,8 +16226,8 @@ soap_print_fault_location(struct soap *soap, FILE *fd)
fprintf(fd, "%s%c\n<!-- ** HERE ** -->\n", soap->buf, c1);
if (soap->bufidx < soap->buflen)
fprintf(fd, "%s\n", soap->buf + soap->bufidx);
- soap->buf[i] = c1;
- soap->buf[j] = c2;
+ soap->buf[i] = (char)c1;
+ soap->buf[j] = (char)c2;
}
#endif
}
@@ -15949,7 +16255,7 @@ soap_register_plugin_arg(struct soap *soap, int (*fcreate)(struct soap*, struct
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Registered '%s' plugin\n", p->id));
return SOAP_OK;
}
- DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not register plugin '%s': plugin returned error %d (or fdelete callback not set)\n", p->id?p->id:"?", r));
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not register plugin '%s': plugin returned error %d (or fdelete callback not set)\n", p->id ? p->id : "?", r));
SOAP_FREE(soap, p);
return r;
}