/ Zope / Apsis / Pound Mailing List / Archive / 2005 / 2005-08 / Pound and Gsoap

[ << ] [ >> ]

[ Pound Virtual Host / IP address question / ... ] [ Re: [Pound Mailing List] Pound and Gsoap / Robert ... ]

Pound and Gsoap
Gaetan OFFREDO <gaetan.offredo(at)alcatel.fr>
2005-08-25 18:15:44 [ FULL ]
Hello everybody

I am developping web services and client test applications.
One of my client test is running on Windows with gsoap.

I tested my web services with this gsoap client in different configurations.
One of these configurations is to access the web services thru a reverse proxy 
....which is pound !

A. SYMPTOMS

The client can not access the web services in this configuration.
In the log file :
"Aug 19 11:06:17 (none) pound[17826]: error read from 172.26.172.37: 
Input/output error"
or
"Aug 19 11:06:17 (none) pound[17826]: error flush headers to 172.26.172.37: 
Connection reset by peer"

B. ANALYZE
I tried to understand more precisely what happened

If the client is configured to use an HTTP persistent socket, OK
BUT, If the client is configured to not use an HTTP persistent socket, NOK

I used tcpdump to compare the difference between the 2 modes 
(persistent/non-persistent).
In the case of the non persistent socket, the client sends:
   HTTP : POST <the content>
   TCP : bit FIN is set

In the case of the persistent socket, the client does not send the TCP FIN 
packet (normal, it is persistent !)

Let's go deeper !
I used strace on pound with the non persistent socket
The following strace traces describes the 2nd case ("Connection reset by 
peer")

And the result is (I suppressed some system calls ...)

poll([{fd=9, events=POLLIN|POLLPRI, revents=POLLIN}], 1, 10000) = 1
read(9, "POST /services/mgtsrv HTTP/1.1\r\n"..., 4096) = 925
...
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 10
...
connect(10, {sin_family=AF_INET, sin_port=htons(56000), 
...
poll([{fd=9, events=POLLOUT, revents=POLLOUT|POLLHUP}], 1, 10000) = 1

shutdown(10, 2 /* send and receive */)  = 0
close(10)                               = 0

In this case, pound tries to send back the back-end reponse to the client
The last call to the poll system call is to flush the headers to the client 
(call to function BIO_flush in the http.c file)
The poll function returns POLLOUT|POLLHUP, meaning: "writing now will not 
block" and "Hung up" (see man poll(2))
The POLLHUP is due to the fact that the linux kernel received the TCP FIN bit.
In these condition, the BIO_flush returns != 1 => pound fails to send the 
response to the client

C. WHO IS THE GUILTY ?

The GSOAP behaviour seems to be normal. The fact to send a FIN is appeared in 
version GSOAP 2.6
When looking at the generated stubs, we have:
<code>
if (soap_valid_socket(soap->socket) && !soap->keep_alive)
      shutdown((SOAP_SOCKET)soap->socket, 1); /* Send TCP FIN */
</code>

According to the TCP RFC, the bit FIN indicates that half on the connection is 
closed (from sender to receiver)


I tried the same GSOAP client with the following configuration :

Client ----> Apache ----> Pound ---->Back-end

and it works !

I am not (at all) a specialist of the openssl library (which defines the 
BIO_xxx functions), but it seems that this function is not correctly called 
in Pound (maybe a BIO_xxx function with a finest behaviour has to be called)

D. CONCLUSION

The pound web site mentions that the tested clients are browsers .... but not 
soap client
But is this limitation not too restrictive (due to the development of the WS) 
on the WEB ?

Has anyone already encountered this problem and corrected it ?

Thanks


Gaëtan
[...]

MailBoxer