After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 621791 - Connection terminated unexpectedly, during login. Connection should have been restarted instead
Connection terminated unexpectedly, during login. Connection should have been...
Status: RESOLVED DUPLICATE of bug 634425
Product: libsoup
Classification: Core
Component: HTTP Transport
2.31.x
Other Windows
: Normal normal
: ---
Assigned To: libsoup-maint@gnome.bugs
libsoup-maint@gnome.bugs
Depends on:
Blocks:
 
 
Reported: 2010-06-16 14:39 UTC by Egon Andersen
Modified: 2010-11-09 17:37 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Egon Andersen 2010-06-16 14:39:49 UTC
When using libsoup on windows to login from a client to a server, I get:
Status code 7, Connection terminated unexpectedly.
(The client is using asyncronous I/O)

On Linux and Mac OS.
Looking at the exact same scenario using libsoup on Linux or Mac OS, I can see from the log, that libsoup on both those platforms first tries to send the message containing the login info.
Immediately hereafter, it sends the message again and the log tells that the connection is restarted.

The server responds with a status code 302, Found and is redirected to the new location.

I'll try to explain the scenario in more detail.

1)
From client to server:
GET https://host/path1?query1

2)
From server to client:
HTTP/1.1 200 OK
Body contains request for userid and password

3)
User types password
(this will normally take a few seconds)

4)
From client to server:
POST https://host/path2
Content-Type: application/x-www-form-urlencoded
Body containing userid and password

5a)
On Windows I experience:
Status code 7, Connection terminated unexpectedly.

5b)
On Linux and MacOS I experience:
SoupSessionAsync, restarted
From client to server:
Message from 4) is now sent to the server.

6)
From server to client:
HTTP/1.1 302 Found
Location: /path3

7)
From client to server:
GET https://host/path3

8)
From server to client:
HTTP/1.1 200 OK

etc.


It seems that libsoup on both Linus and Mac OS restart the connection in step 5, where as it is not restarted when using libsoup on Windows.

If I programmatically inserts the userid and password, so that there are nearly no delay between step 2 and 4, the request in step 4 is succesfull on Windows too.

It seems that the server closes the connection after a very short time-out and this is causing problems on Windows, where libsoup apparently do not restart the connection like it does on Linux and Mac OS.
Comment 1 Dan Winship 2010-06-16 14:55:06 UTC
Yeah, a year ago it would have failed on Linux and Mac too, but I put in a hack that fixes it for "unix" but not Windows (http://git.gnome.org/browse/libsoup/commit/?id=ef7fc0585990b9c2e056596d1850bdb3f6f6dae9)

This will hopefully be fixed in 2.32/3.0.

If you need a fix now, try this: add a method soup_socket_get_iochannel() to return the socket's iochannel, and in soup_connection_get_state(), on windows create the GPollFD using g_io_channel_win32_make_pollfd() on the iochannel. (And then pass it into g_poll just like in the unix case.) If that works then I can add something like that to the 2.30 branch.
Comment 2 Egon Andersen 2010-06-21 14:01:30 UTC
I've tried to add the proposed fix.
Unfortunately it seems to crash the application the second time g_io_channel_win32_make_pollfd() is called.
Comment 3 Dan Winship 2010-06-21 14:28:27 UTC
hm... can you attach your patch?
Comment 4 Egon Andersen 2010-06-21 15:00:49 UTC
Here it comes

In soup-socket.h:
GIOChannel *   soup_socket_get_iochannel      (SoupSocket         *sock);


In soup-socket.c:

GIOChannel *
soup_socket_get_iochannel (SoupSocket *sock)
{
        GIOChannel * iochannel = NULL;
	g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);

	if(SOUP_SOCKET_GET_PRIVATE (sock)->sockfd != -1)
		{
		iochannel = SOUP_SOCKET_GET_PRIVATE (sock)->iochannel;
		}
	return iochannel;
}

In soup-connection.c:
In function soup_connection_gt_state(), just after the G_OS_UNIX stuff

#ifdef G_OS_WIN32
	if (priv->state == SOUP_CONNECTION_IDLE) {
	        GIOChannel * iochannel;
	        GPollFD pfd;
		iochannel = soup_socket_get_iochannel (priv->socket);
		if(iochannel != NULL)
			{
			g_io_channel_win32_make_pollfd(iochannel, G_IO_IN, &pfd);
			if (g_poll (&pfd, 1, 0) == 1)
				soup_connection_set_state (conn, SOUP_CONNECTION_REMOTE_DISCONNECTED);
			}
		}
#endif
Comment 5 Dan Winship 2010-06-21 15:47:10 UTC
hm... g_io_channel_win32_make_pollfd is kinda weird. it's possible you can only call it once per iochannel. So I guess instead of soup_socket_get_iochannel(), you'd want soup_socket_get_pollfd(), where the first time you call it it would call g_io_channel_win32_make_pollfd() on its iochannel, and it would store that result in socket->priv, and return the same pollfd later when it was called again...

(this is all part of why I didn't bother trying to fix it on windows before :)
Comment 6 Egon Andersen 2010-06-21 19:33:48 UTC
I have now tried this too.
Unfortunately with same bad result the second time g_io_channel_win32_make_pollfd() is called.

Looking into g_io_channel_win32_make_pollfd() shows that WSACreateEvent() is called.
WSACreateEvent() do not take any parameters. So it doesn't seems to have any clue about iochannel.
From the WSACreateEvent() description on MSDN, I don't really get any clue about how it is supposed to be used and why it crashes.


Added in soup-socket.c:
(Both priv->iochannel and priv->pfd are initialized to NULL in soup_socket_init() )

GPollFD *
soup_socket_get_pollfd (SoupSocket *sock)
{
	SoupSocketPrivate *priv;
	g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
	priv = SOUP_SOCKET_GET_PRIVATE (sock);
	g_return_val_if_fail (priv->sockfd != -1, NULL);
	g_return_val_if_fail (priv->iochannel != NULL, NULL);
	if(priv->pfd == NULL)
		{
		priv->pfd = g_new0 (GPollFD, 1);
		g_io_channel_win32_make_pollfd(priv->iochannel, G_IO_IN, priv->pfd);
		}
	return priv->pfd;
}
Comment 7 Dan Winship 2010-11-09 17:37:20 UTC
this will be fixed by the port to using GSocketConnection. I'm marking this as a dup of the "use gio tls" bug, since that's the thing that's blocking the move to GSocketConnection

*** This bug has been marked as a duplicate of bug 634425 ***