?? stdsoap2.c
字號:
/* stdsoap2.c[pp] 2.1.6The contents of this file are subject to the gSOAP Public License Version 1.0(the "License"); you may not use this file except in compliance with theLicense. You may obtain a copy of the License athttp://www.cs.fsu.edu/~engelen/soaplicense.htmlSoftware distributed under the License is distributed on an "AS IS" basis,WITHOUT WARRANTY OF ANY KIND, either express or implied. See the Licensefor 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-2002 Robert A. van Engelen. All Rights Reserved.Note:Win32 build needs winsock.dll (Visual C++ "wsock32.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"wsock32.lib" to the "Object/library modules" entry*/#include "stdsoap2.h"#ifdef __cplusplusextern "C" {#endif/* EOF=-1 */#define LT (-2) /* XML character '<' */#define TT (-3) /* XML character '</' */#define GT (-4) /* XML character '>' */#define QT (-5) /* XML character ''' */#define AP (-6) /* XML character '"' */#define blank(c) ((c)>=0 && (c)<=32)#define notblank(c) ((c)>32)#define hash_ptr(p) (((long)(p)>>3)&(SOAP_PTRHASH-1))#define soap_get1(soap) ((soap->bufidx>=soap->buflen && soap_recv(soap)) ? EOF : (unsigned char)soap->buf[soap->bufidx++])#define soap_unget(soap, c) (soap->ahead1 = c)#define soap_unget2(soap, c) (soap->ahead2 = c)static struct soap_ilist *lookup(struct soap*, const char*);static struct soap_ilist *enter(struct soap*, const char*);static void soap_update_ptrs(struct soap*, char*, char*, long);static void soap_resolve_ptr(struct soap_ilist*);static void soap_resolve_copy(struct soap*, struct soap_ilist*);static int soap_putdimefield(struct soap*, const char*, int);static char *soap_getdimefield(struct soap*, int);static int soap_position(struct soap*);static int soap_mustUnderstand(struct soap*);static int soap_puthttphdr(struct soap*, size_t);static int http_post(struct soap*, const char*, const char*, const char*, const char*, size_t);static int http_response(struct soap*, int, size_t);static int http_parse(struct soap*);static int tcp_connect(struct soap*, const char*, const char*, int);static int tcp_disconnect(struct soap*);static int fsend(struct soap*, const char*, size_t);static size_t frecv(struct soap*, char*, size_t);static int fignore(struct soap*, const char*);#ifdef _MATH_Hstruct soap_double_nan soap_double_nan = {0xFFFFFFFF, 0xFFFFFFFF};#endifstruct code_map{ int code; const char *string;};static struct code_map h_errno_codes[] = {#ifdef HOST_NOT_FOUND { HOST_NOT_FOUND, "Host not found" },#endif#ifdef TRY_AGAIN { TRY_AGAIN, "Try Again" },#endif#ifdef NO_RECOVERY { NO_RECOVERY, "No Recovery" },#endif#ifdef NO_DATA { NO_DATA, "No Data" },#endif#ifdef NO_ADDRESS { NO_ADDRESS, "No Address" },#endif {0, NULL}};#ifdef WITH_OPENSSLstatic SSL_CTX *soap_ssl_ctx = NULL;static const char *soap_ssl_pw = NULL;#endif#ifdef WIN32static int tcp_done = 0;#endif/******************************************************************************/static intSOAP_FMAC2fsend(struct soap *soap, const char *s, size_t n){ int nwritten; while (n > 0) {#ifdef WITH_OPENSSL if (soap->ssl) nwritten = SSL_write(soap->ssl, s, n); else#endif if (soap->socket >= 0) { if (soap->send_timeout) { struct timeval timeout; fd_set fd; if (soap->send_timeout > 0) { timeout.tv_sec = soap->send_timeout; timeout.tv_usec = 0; } else { timeout.tv_sec = -soap->send_timeout/1000000; timeout.tv_usec = -soap->send_timeout%1000000; } FD_ZERO(&fd); FD_SET(soap->socket, &fd); for (;;) { if (select(soap->socket + 1, NULL, &fd, NULL, &timeout) > 0) break; if (soap_errno != SOAP_EINTR) return SOAP_EOF; } } nwritten = send(soap->socket, s, n, 0); } else#ifdef WITH_FASTCGI { nwritten = fwrite(s, 1, n, stdout); fflush(stdout); }#else#ifdef UNDER_CE nwritten = fwrite(s, 1, n, soap->sendfd);#else nwritten = write(soap->sendfd, s, n);#endif#endif if (nwritten <= 0) {#ifdef WITH_OPENSSL if (SSL_get_error(soap->ssl, nwritten) != SSL_ERROR_NONE) return SOAP_EOF; else#endif if (soap_errno == SOAP_EINTR || soap_errno == SOAP_EWOULDBLOCK || soap_errno == SOAP_EAGAIN) nwritten = 0; /* and call write() again */ else return SOAP_EOF; } n -= nwritten; s += nwritten; } return SOAP_OK;}/******************************************************************************/SOAP_FMAC1intSOAP_FMAC2soap_flush(struct soap *soap){ if (soap->bufidx == 0) return SOAP_OK; if (soap->chunked) { char tmp[12]; sprintf(tmp, "%X\r\n", (unsigned int)soap->bufidx); if ((soap->error = soap->fsend(soap, tmp, strlen(tmp)))) return soap->error; } if ((soap->error = soap->fsend(soap, soap->buf, soap->bufidx))) return soap->error; if (soap->chunked) if ((soap->error = soap->fsend(soap, "\r\n", 2))) return soap->error; soap->bufidx = 0; return SOAP_OK;}/******************************************************************************/SOAP_FMAC1intSOAP_FMAC2soap_send_raw(struct soap *soap, const char *s, size_t n){ register size_t i; if (soap->counting) { soap->count += n; return SOAP_OK; } DBGLOG(SENT, for (i = 0; i < n; i++) fputc(s[i], fdebug)); if (soap->buffering) /* send by packets of size SOAP_BUFLEN */ { char *b; while (n) { i = soap->bufidx; if (n >= SOAP_BUFLEN-i) { n -= SOAP_BUFLEN-i; for (b = soap->buf+i; i < SOAP_BUFLEN; i++) *b++ = *s++; soap->bufidx = SOAP_BUFLEN; if (soap_flush(soap)) return soap->error; } else { soap->bufidx += n; for (b = soap->buf+i; n; n--) *b++ = *s++; break; } } return SOAP_OK; } return soap->error = soap->fsend(soap, s, n);}/******************************************************************************/SOAP_FMAC1intSOAP_FMAC2soap_send(struct soap *soap, const char *s){ return soap_send_raw(soap, s, strlen(s));}/******************************************************************************/static size_tfrecv(struct soap *soap, char *s, size_t n){ int r;#ifdef WITH_OPENSSL if (soap->ssl) { r = SSL_read(soap->ssl, s, n); if (SSL_get_error(soap->ssl, r) == SSL_ERROR_NONE) return r; return 0; }#endif if (soap->socket >= 0) { if (soap->recv_timeout) { struct timeval timeout; fd_set fd; if (soap->recv_timeout > 0) { timeout.tv_sec = soap->recv_timeout; timeout.tv_usec = 0; } else { timeout.tv_sec = -soap->recv_timeout/1000000; timeout.tv_usec = -soap->recv_timeout%1000000; } FD_ZERO(&fd); FD_SET(soap->socket, &fd); for (;;) { if (select(soap->socket + 1, &fd, NULL, NULL, &timeout) > 0) break; if (soap_errno != SOAP_EINTR) return 0; } } r = recv(soap->socket, s, n, 0); if (r < 0) return 0; return r; }#ifdef WITH_FASTCGI return fread(s, 1, n, stdin);#else#ifdef UNDER_CE return fread(s, 1, n, soap->recvfd);#else return read(soap->recvfd, s, n);#endif#endif}/******************************************************************************/static intsoap_recv_raw(struct soap *soap){ size_t ret;#ifdef SOAP_DEBUG int i;#endif if (soap->chunked) /* read HTTP chunked transfer */ { if (soap->chunksize > 0) { if (soap->chunksize > SOAP_BUFLEN) soap->buflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN); else soap->buflen = ret = soap->frecv(soap, soap->buf, soap->chunksize); DBGLOG(TEST, SOAP_MESSAGE(fdebug,"\nGetting chunk: read %d bytes", ret)); soap->bufidx = 0; soap->chunksize -= ret; } else { char tmp[8], *t; t = tmp; if (!soap->chunkbuflen) { soap->chunkbuflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN); DBGLOG(TEST, SOAP_MESSAGE(fdebug,"\nRead %d bytes", ret)); soap->bufidx = 0; if (!ret) return EOF; } soap->buflen = soap->chunkbuflen; DBGLOG(TEST, SOAP_MESSAGE(fdebug,"\nGetting chunk size from buffered HTTP")); while (soap->bufidx < soap->buflen && !isxdigit((int)soap->buf[soap->bufidx])) soap->bufidx++; while (soap->bufidx < soap->buflen && t-tmp < 7 && isxdigit((int)soap->buf[soap->bufidx])) *t++ = soap->buf[soap->bufidx++]; while (soap->bufidx < soap->buflen && soap->buf[soap->bufidx] != '\n') soap->bufidx++; if (soap->bufidx >= soap->buflen || soap->buf[soap->bufidx] != '\n') { soap->buflen = soap->chunkbuflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN); DBGLOG(TEST, SOAP_MESSAGE(fdebug,"\nRead %d bytes", ret)); soap->bufidx = 0; if (!ret) return EOF; while (soap->bufidx < soap->buflen && t-tmp < 7 && isxdigit((int)soap->buf[soap->bufidx])) *t++ = soap->buf[soap->bufidx++]; while (soap->bufidx < soap->buflen && soap->buf[soap->bufidx] != '\n') soap->bufidx++; } *t = '\0'; soap->bufidx++; soap->chunksize = strtol(tmp, &t, 16); if (soap->chunksize <= 0) { soap->bufidx = 0; soap->buflen = 0; soap->chunkbuflen = 0; return EOF; } else soap->buflen = soap->bufidx + soap->chunksize; DBGLOG(TEST, SOAP_MESSAGE(fdebug,"\nMoving buf len to %d", soap->buflen)); if (soap->buflen > soap->chunkbuflen) { soap->buflen = soap->chunkbuflen; soap->chunksize -= soap->buflen - soap->bufidx; soap->chunkbuflen = 0; DBGLOG(TEST, SOAP_MESSAGE(fdebug,"\nPassed end of buffer for chunked HTTP")); } ret = soap->buflen - soap->bufidx; } } else { soap->buflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN); DBGLOG(TEST, SOAP_MESSAGE(fdebug,"\nRead %d bytes", ret)); soap->bufidx = 0; } DBGLOG(RECV, for (i = soap->bufidx; i < soap->buflen; i++) fputc(soap->buf[i], fdebug)); soap->count += ret; return !ret;}/******************************************************************************/intSOAP_FMAC2soap_recv(struct soap *soap){ if (soap->dime) { if (soap->dime_buflen) { char *s; int i; unsigned char tmp[12]; DBGLOG(TEST, SOAP_MESSAGE(fdebug,"\nDIME hdr for chunked DIME is in buffer")); soap->count += soap->dime_buflen - soap->buflen; soap->buflen = soap->dime_buflen; DBGLOG(TEST, SOAP_MESSAGE(fdebug,"\nSkip padding (%u bytes)", -(int)soap->dime_size&3)); for (i = -(int)soap->dime_size&3; i > 0; i--) { soap->bufidx++; if (soap->bufidx >= soap->buflen) if (soap_recv_raw(soap)) return EOF; } DBGLOG(TEST, SOAP_MESSAGE(fdebug,"\nGet DIME hdr for next chunk")); s = (char*)tmp; for (i = 12; i > 0; i--) { *s++ = soap->buf[soap->bufidx++]; if (soap->bufidx >= soap->buflen) if (soap_recv_raw(soap)) return EOF; } soap->dime_flags = tmp[0]&0x7; soap->dime_size = tmp[8]<<24 | tmp[9]<<16 | tmp[10]<<8 | tmp[11]; DBGLOG(TEST, SOAP_MESSAGE(fdebug,"\nGet DIME chunk (%u bytes)", soap->dime_size)); if (soap->dime_flags&SOAP_DIME_CF) { DBGLOG(TEST, SOAP_MESSAGE(fdebug,"\nMore chunking")); soap->dime_chunksize = soap->dime_size; if (soap->buflen - soap->bufidx >= soap->dime_size) { soap->dime_buflen = soap->buflen; soap->buflen = soap->bufidx + soap->dime_chunksize; } else soap->dime_chunksize -= soap->buflen - soap->bufidx; } else { DBGLOG(TEST, SOAP_MESSAGE(fdebug,"\nLast chunk")); soap->dime_buflen = 0; soap->dime_chunksize = 0; } soap->count = soap->buflen - soap->bufidx; DBGLOG(TEST, SOAP_MESSAGE(fdebug,"\n%d bytes remaining", soap->count)); return SOAP_OK; } else if (soap->dime_chunksize) { DBGLOG(TEST, SOAP_MESSAGE(fdebug,"\nGet next DIME hdr for chunked DIME (%u bytes chunk)", soap->dime_chunksize)); if (soap_recv_raw(soap)) return EOF; if (soap->buflen - soap->bufidx >= soap->dime_chunksize) { soap->dime_buflen = soap->buflen; soap->count -= soap->buflen - soap->bufidx - soap->dime_chunksize; soap->buflen = soap->bufidx + soap->dime_chunksize; } else soap->dime_chunksize -= soap->buflen - soap->bufidx; DBGLOG(TEST, SOAP_MESSAGE(fdebug,"\n%d bytes remaining, count=%d", soap->buflen-soap->bufidx, soap->count)); return SOAP_OK; } } return soap_recv_raw(soap);}/******************************************************************************/SOAP_FMAC1wcharSOAP_FMAC2soap_get2(struct soap *soap){ register wchar c; if (soap->ahead1) { c = soap->ahead1; soap->ahead1 = 0; return c; } if (soap->ahead2) { c = soap->ahead2; soap->ahead2 = 0; return c; } return soap_get1(soap);}/******************************************************************************/SOAP_FMAC1intSOAP_FMAC2soap_tag_cmp(const char *s, const char *t){ for (; *s; s++, t++) if (tolower(*s) != tolower(*t))
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -