📄 stdsoap2.cpp
字号:
#endif#ifdef WIN32static int tcp_done = 0;#endif/******************************************************************************/#ifndef WITH_NOIO#ifndef PALM_1static intfsend(struct soap *soap, const char *s, size_t n){ register int nwritten, err;#if defined(__cplusplus) && !defined(WITH_LEAN) if (soap->os) { soap->os->write(s, (std::streamsize)n); if (soap->os->good()) return SOAP_OK; soap->errnum = 0; return SOAP_EOF; }#endif while (n) { if (soap_valid_socket(soap->socket)) { #ifndef WITH_LEAN if (soap->send_timeout) {#ifndef WIN32 if ((int)soap->socket >= (int)FD_SETSIZE) return SOAP_FD_EXCEEDED; /* Hint: MUST increase FD_SETSIZE */#endif for (;;) { struct timeval timeout; fd_set fd; register int r; 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);#ifdef WITH_OPENSSL if (soap->ssl) r = select((int)soap->socket + 1, &fd, &fd, &fd, &timeout); else#endif r = select((int)soap->socket + 1, NULL, &fd, &fd, &timeout); if (r > 0) break; if (!r) { soap->errnum = 0; return SOAP_EOF; } err = soap_socket_errno(soap->socket); if (err != SOAP_EINTR && err != SOAP_EAGAIN) { soap->errnum = err; return SOAP_EOF; } } }#endif#ifdef WITH_OPENSSL if (soap->ssl) nwritten = SSL_write(soap->ssl, s, (int)n); else if (soap->bio) nwritten = BIO_write(soap->bio, s, (int)n); else#endif#ifdef WITH_UDP if ((soap->omode & SOAP_IO_UDP)) { if (soap->peerlen) nwritten = sendto(soap->socket, s, n, soap->socket_flags, (struct sockaddr*)&soap->peer, soap->peerlen); else nwritten = send(soap->socket, s, 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) { struct timeval timeout; fd_set fd; int udp_repeat; int udp_delay;#ifndef WIN32 if ((int)soap->socket >= (int)FD_SETSIZE) return SOAP_FD_EXCEEDED; /* Hint: MUST increase FD_SETSIZE */#endif if ((soap->connect_flags & SO_BROADCAST)) udp_repeat = 3; /* SOAP-over-UDP MULTICAST_UDP_REPEAT - 1 */ else udp_repeat = 1; /* SOAP-over-UDP UNICAST_UDP_REPEAT - 1 */ udp_delay = (soap_random % 201) + 50; /* UDP_MIN_DELAY .. UDP_MAX_DELAY */ do { timeout.tv_sec = 0; timeout.tv_usec = 1000 * udp_delay; /* ms */ FD_ZERO(&fd); FD_SET(soap->socket, &fd); select((int)soap->socket + 1, NULL, NULL, &fd, &timeout); if (soap->peerlen) nwritten = sendto(soap->socket, s, n, soap->socket_flags, (struct sockaddr*)&soap->peer, soap->peerlen); else nwritten = send(soap->socket, s, n, soap->socket_flags); udp_delay <<= 1; if (udp_delay > 500) /* UDP_UPPER_DELAY */ udp_delay = 500; } while (nwritten < 0 && --udp_repeat > 0); } } else#endif#if !defined(PALM) && !defined(AS400) nwritten = send(soap->socket, s, (int)n, soap->socket_flags);#else nwritten = send(soap->socket, (void*)s, n, soap->socket_flags);#endif if (nwritten <= 0) { register int r = 0; err = soap_socket_errno(soap->socket);#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; return SOAP_EOF; }#endif if (err == SOAP_EWOULDBLOCK || err == SOAP_EAGAIN) {#ifndef WITH_LEAN struct timeval timeout; fd_set fd;#ifndef WIN32 if ((int)soap->socket >= (int)FD_SETSIZE) return SOAP_FD_EXCEEDED; /* Hint: MUST increase FD_SETSIZE */#endif if (soap->send_timeout > 0) { timeout.tv_sec = soap->send_timeout; timeout.tv_usec = 0; } else if (soap->send_timeout < 0) { timeout.tv_sec = -soap->send_timeout/1000000; timeout.tv_usec = -soap->send_timeout%1000000; } else { timeout.tv_sec = 0; timeout.tv_usec = 10000; } FD_ZERO(&fd); FD_SET(soap->socket, &fd);#ifdef WITH_OPENSSL if (soap->ssl && r == SSL_ERROR_WANT_READ) r = select((int)soap->socket + 1, &fd, NULL, &fd, &timeout); else r = select((int)soap->socket + 1, NULL, &fd, &fd, &timeout);#else r = select((int)soap->socket + 1, NULL, &fd, &fd, &timeout);#endif if (r < 0 && (r = soap_socket_errno(soap->socket)) != SOAP_EINTR) { soap->errnum = r; return SOAP_EOF; }#endif } else if (err && err != SOAP_EINTR) { soap->errnum = err; return SOAP_EOF; } nwritten = 0; /* and call write() again */ } } else {#ifdef WITH_FASTCGI nwritten = fwrite((void*)s, 1, n, stdout); fflush(stdout);#else#ifdef UNDER_CE nwritten = fwrite(s, 1, n, soap->sendfd);#else#ifdef VXWORKS#ifdef WMW_RPM_IO if (soap->rpmreqid) nwritten = (httpBlockPut(soap->rpmreqid, s, n) == 0) ? n : -1; else#endif nwritten = fwrite(s, sizeof(char), n, fdopen(soap->sendfd, "w"));#else nwritten = write(soap->sendfd, s, (unsigned int)n);#endif#endif#endif if (nwritten <= 0) { err = soap_errno; if (err && err != SOAP_EINTR && err != SOAP_EWOULDBLOCK && err != SOAP_EAGAIN) { soap->errnum = err; return SOAP_EOF; } nwritten = 0; /* and call write() again */ } } n -= nwritten; s += nwritten; } return SOAP_OK;}#endif#endif/******************************************************************************/#ifndef PALM_1SOAP_FMAC1intSOAP_FMAC2soap_send_raw(struct soap *soap, const char *s, size_t n){ if (!n) return SOAP_OK; if (soap->mode & SOAP_IO_LENGTH) { soap->count += n;#ifndef WITH_LEANER if (soap->fpreparesend && (soap->mode & SOAP_IO) != SOAP_IO_STORE) return soap->error = soap->fpreparesend(soap, s, n);#endif return SOAP_OK; } if (soap->mode & SOAP_IO) { register size_t i = SOAP_BUFLEN - soap->bufidx; while (n >= i) { memcpy(soap->buf + soap->bufidx, s, i); soap->bufidx = SOAP_BUFLEN; if (soap_flush(soap)) return soap->error; s += i; n -= i; i = SOAP_BUFLEN; } memcpy(soap->buf + soap->bufidx, s, n); soap->bufidx += n; return SOAP_OK; } return soap_flush_raw(soap, s, n);}#endif/******************************************************************************/#ifndef PALM_1SOAP_FMAC1intSOAP_FMAC2soap_flush(struct soap *soap){ register size_t n = soap->bufidx; if (n) { soap->bufidx = 0;#ifdef WITH_ZLIB if (soap->mode & SOAP_ENC_ZLIB) { soap->d_stream.next_in = (Byte*)soap->buf; soap->d_stream.avail_in = (unsigned int)n;#ifdef WITH_GZIP soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)n);#endif 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:"")); return soap->error = SOAP_ZLIB_ERROR; } if (!soap->d_stream.avail_out) { if (soap_flush_raw(soap, soap->z_buf, SOAP_BUFLEN)) return soap->error; soap->d_stream.next_out = (Byte*)soap->z_buf; soap->d_stream.avail_out = SOAP_BUFLEN; } } while (soap->d_stream.avail_in); } else#endif return soap_flush_raw(soap, soap->buf, n); } return SOAP_OK;}#endif/******************************************************************************/#ifndef PALM_1SOAP_FMAC1intSOAP_FMAC2soap_flush_raw(struct soap *soap, const char *s, size_t n){ if ((soap->mode & SOAP_IO) == SOAP_IO_STORE) { register char *t; if (!(t = (char*)soap_push_block(soap, n))) return soap->error = SOAP_EOM; memcpy(t, s, n);#ifndef WITH_LEANER if (soap->fpreparesend) return soap->error = soap->fpreparesend(soap, s, n);#endif return SOAP_OK; }#ifndef WITH_LEANER if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) { char t[16]; sprintf(t, "\r\n%lX\r\n" + (soap->chunksize ? 0 : 2), (unsigned long)n); DBGMSG(SENT, t, strlen(t)); if ((soap->error = soap->fsend(soap, t, strlen(t)))) return soap->error; soap->chunksize += n; } DBGMSG(SENT, s, n);#endif return soap->error = soap->fsend(soap, s, n);}#endif/******************************************************************************/#ifndef PALM_1SOAP_FMAC1intSOAP_FMAC2soap_send(struct soap *soap, const char *s){ if (s) return soap_send_raw(soap, s, strlen(s)); return SOAP_OK;}#endif/******************************************************************************/#ifndef WITH_LEANER#ifndef PALM_1SOAP_FMAC1intSOAP_FMAC2soap_send2(struct soap *soap, const char *s1, const char *s2){ if (soap_send(soap, s1)) return soap->error; return soap_send(soap, s2);}#endif#endif/******************************************************************************/#ifndef WITH_LEANER#ifndef PALM_1SOAP_FMAC1intSOAP_FMAC2soap_send3(struct soap *soap, const char *s1, const char *s2, const char *s3){ if (soap_send(soap, s1) || soap_send(soap, s2)) return soap->error; return soap_send(soap, s3);}#endif#endif/******************************************************************************/#ifndef WITH_NOIO#ifndef PALM_1static size_tfrecv(struct soap *soap, char *s, size_t n){ register int r;#ifdef PALM register int timeouts = 6000; /* Palm: 1 min timeout for SSL */#endif soap->errnum = 0;#if defined(__cplusplus) && !defined(WITH_LEAN) if (soap->is) { if (soap->is->good()) return soap->is->read(s, (std::streamsize)n).gcount(); return 0; }#endif if (soap_valid_socket(soap->socket)) { for (;;) { #ifdef WITH_OPENSSL register int err = 0;#endif#ifndef WITH_LEAN#ifdef WITH_OPENSSL if (soap->recv_timeout && !soap->ssl) /* SSL: sockets are nonblocking */#else if (soap->recv_timeout)#endif {#ifndef WIN32 if ((int)soap->socket >= (int)FD_SETSIZE) { soap->error = SOAP_FD_EXCEEDED; return 0; /* Hint: MUST increase FD_SETSIZE */ }#endif for (;;) { 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); r = select((int)soap->socket + 1, &fd, NULL, &fd, &timeout); if (r > 0) break; if (!r) { soap->errnum = 0; return 0; } r = soap_socket_errno(soap->socket); if (r != SOAP_EINTR && r != SOAP_EAGAIN) { soap->errnum = r; return 0; } } }#endif#ifdef WITH_OPENSSL if (soap->ssl) { r = SSL_read(soap->ssl, s, (int)n); if (r > 0) return (size_t)r; err = SSL_get_error(soap->ssl, r); if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) return 0; } else if (soap->bio) { r = BIO_read(soap->bio, s, (int)n); if (r > 0) return (size_t)r; return 0; } else#endif { #ifdef WITH_UDP 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, 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);#endif } else#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -