2007-10-28 Dan Winship <danw@gnome.org>
+ * libsoup/soup-server.c (start_request, request_finished): ref the
+ socket around the processing of the message, since otherwise it
+ might already be freed when request_finished runs. #459896.
+
+ * libsoup/soup-message-io.c (soup_message_io_pause)
+ (soup_message_io_unpause): Clarify the docs here; this is for
+ server-side use only. Inspired by #452280.
+
+ * docs/reference/server-howto.xml: You need to watch the
+ "finished" signal on the message if using soup_message_io_pause()
+ or chunked encoding, because the client might disconnect while
+ you're paused. Clarification inspired by #471385.
+
+ * tests/simple-proxy.c (client_msg_failed): Fix this to DTRT since
+ server-howto.xml points to it as an example of what to do.
+
+2007-10-28 Dan Winship <danw@gnome.org>
+
* libsoup/soup-session.c (finalize): free proxy-related stuff
* libsoup/soup-session-async.c (idle_run_queue): clean up the weak
- pointer
+ pointer. (From the dev repo, but identical to a patch from Rob
+ Bradford in #484988.)
* tests/*.c: fix leaks
on the message before returning from the callback. This will delay
sending a response until you call <link
linkend="soup-message-io-unpause"><function>soup_message_io_unpause</function></link>.
+(You must also connect to the <link
+linkend="SoupMessage-finished">finished</link> signal on the message
+in this case, so that you can break off processing if the client
+unexpectedly disconnects before you start sending the data.)
</para>
<para>
</para>
<para>
+When using chunked encoding, you must also connect to the <link
+linkend="SoupMessage-finished">finished</link> signal on the message,
+so that you will be notified if the client disconnects between two
+chunks; <type>SoupServer</type> will unref the message if that
+happens, so you must stop adding new chunks to the response at that
+point.
+</para>
+
+<para>
The <emphasis role="bold"><literal>simple-proxy</literal></emphasis>
example in the <literal>tests/</literal> directory gives an example of
using <literal>chunked</literal> encoding.
/**
* soup_message_io_pause:
- * @msg: a #SoupMessage
+ * @msg: a server-side #SoupMessage
*
- * Pauses I/O on @msg.
+ * Pauses I/O on @msg. This can be used in a #SoupServer handler when
+ * you don't have the data ready to return yet; call
+ * soup_message_io_unpause() to start sending the response once it is
+ * ready.
**/
void
soup_message_io_pause (SoupMessage *msg)
SoupMessageIOData *io = priv->io_data;
g_return_if_fail (io != NULL);
+ g_return_if_fail (io->mode == SOUP_MESSAGE_IO_SERVER);
if (io->write_tag) {
g_signal_handler_disconnect (io->sock, io->write_tag);
/**
* soup_message_io_unpause:
- * @msg: a #SoupMessage
+ * @msg: a server-side #SoupMessage
*
- * Resumes I/O on @msg.
+ * Resumes I/O on @msg. Use this to resume after calling
+ * soup_message_io_pause(), or after adding a new chunk to a chunked
+ * response.
**/
void
soup_message_io_unpause (SoupMessage *msg)
SoupMessageIOData *io = priv->io_data;
g_return_if_fail (io != NULL);
+ g_return_if_fail (io->mode == SOUP_MESSAGE_IO_SERVER);
if (io->write_tag || io->read_tag)
return;
} else
soup_socket_disconnect (sock);
g_object_unref (msg);
+ g_object_unref (sock);
}
static inline void
g_signal_connect (msg, "got_body", G_CALLBACK (call_handler), server_sock);
g_signal_connect (msg, "finished", G_CALLBACK (request_finished), server_sock);
+ g_object_ref (server_sock);
soup_message_read_request (msg, server_sock);
}
static void
client_msg_failed (SoupMessage *msg, gpointer msg2)
{
- /* FIXME
- soup_message_cancel (msg2);
- */
+ soup_message_set_status (msg2, SOUP_STATUS_IO_ERROR);
+ soup_session_cancel_message (session, msg2);
}
static void