#include <gio/gio.h>
#include "soup-http-input-stream.h"
+#include "soup-headers.h"
+#include "soup-content-sniffer.h"
#include "soup-session.h"
G_DEFINE_TYPE (SoupHTTPInputStream, soup_http_input_stream, G_TYPE_INPUT_STREAM)
gsize caller_bufsize, caller_nread;
GAsyncReadyCallback outstanding_callback;
GSimpleAsyncResult *result;
+
+ char *sniffed_content_type;
} SoupHTTPInputStreamPrivate;
#define SOUP_HTTP_INPUT_STREAM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_HTTP_INPUT_STREAM, SoupHTTPInputStreamPrivate))
GError **error);
static void soup_http_input_stream_got_headers (SoupMessage *msg, gpointer stream);
+static void soup_http_input_stream_content_sniffed (SoupMessage *msg, const char *content_type, GHashTable *params, gpointer stream);
static void soup_http_input_stream_got_chunk (SoupMessage *msg, SoupBuffer *chunk, gpointer stream);
static void soup_http_input_stream_restarted (SoupMessage *msg, gpointer stream);
static void soup_http_input_stream_finished (SoupMessage *msg, gpointer stream);
g_object_unref (priv->session);
g_signal_handlers_disconnect_by_func (priv->msg, G_CALLBACK (soup_http_input_stream_got_headers), stream);
+ g_signal_handlers_disconnect_by_func (priv->msg, G_CALLBACK (soup_http_input_stream_content_sniffed), stream);
g_signal_handlers_disconnect_by_func (priv->msg, G_CALLBACK (soup_http_input_stream_got_chunk), stream);
g_signal_handlers_disconnect_by_func (priv->msg, G_CALLBACK (soup_http_input_stream_restarted), stream);
g_signal_handlers_disconnect_by_func (priv->msg, G_CALLBACK (soup_http_input_stream_finished), stream);
g_queue_foreach (priv->leftover_queue, (GFunc) soup_buffer_free, NULL);
g_queue_free (priv->leftover_queue);
+ g_free (priv->sniffed_content_type);
+
if (G_OBJECT_CLASS (soup_http_input_stream_parent_class)->finalize)
(*G_OBJECT_CLASS (soup_http_input_stream_parent_class)->finalize)(object);
}
priv->got_headers = priv->finished = FALSE;
+ if (soup_session_get_feature_for_message (priv->session, SOUP_TYPE_CONTENT_SNIFFER, priv->msg)) {
+ g_signal_connect (priv->msg, "content_sniffed",
+ G_CALLBACK (soup_http_input_stream_content_sniffed), stream);
+ } else {
+ g_signal_connect (priv->msg, "got_headers",
+ G_CALLBACK (soup_http_input_stream_got_headers), stream);
+ }
+ g_signal_connect (priv->msg, "got_chunk",
+ G_CALLBACK (soup_http_input_stream_got_chunk), stream);
+ g_signal_connect (priv->msg, "restarted",
+ G_CALLBACK (soup_http_input_stream_restarted), stream);
+ g_signal_connect (priv->msg, "finished",
+ G_CALLBACK (soup_http_input_stream_finished), stream);
+
/* Add an extra ref since soup_session_queue_message steals one */
g_object_ref (priv->msg);
soup_session_queue_message (priv->session, priv->msg, NULL, NULL);
priv->async_context = soup_session_get_async_context (session);
priv->msg = g_object_ref (msg);
- g_signal_connect (msg, "got_headers",
- G_CALLBACK (soup_http_input_stream_got_headers), stream);
- g_signal_connect (msg, "got_chunk",
- G_CALLBACK (soup_http_input_stream_got_chunk), stream);
- g_signal_connect (msg, "restarted",
- G_CALLBACK (soup_http_input_stream_restarted), stream);
- g_signal_connect (msg, "finished",
- G_CALLBACK (soup_http_input_stream_finished), stream);
-
- soup_http_input_stream_queue_message (stream);
return (GInputStream *)stream;
}
}
static void
+soup_http_input_stream_content_sniffed (SoupMessage *msg, const char *content_type,
+ GHashTable *params, gpointer stream)
+{
+ SoupHTTPInputStreamPrivate *priv = SOUP_HTTP_INPUT_STREAM_GET_PRIVATE (stream);
+ GString *sniffed_type;
+
+ sniffed_type = g_string_new (content_type);
+ if (params) {
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_hash_table_iter_init (&iter, params);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ g_string_append (sniffed_type, "; ");
+ soup_header_g_string_append_param (sniffed_type, key, value);
+ }
+ }
+ g_free (priv->sniffed_content_type);
+ priv->sniffed_content_type = g_string_free (sniffed_type, FALSE);
+
+ soup_http_input_stream_got_headers (msg, stream);
+}
+
+static void
soup_http_input_stream_got_chunk (SoupMessage *msg, SoupBuffer *chunk_buffer,
gpointer stream)
{
g_return_val_if_fail (SOUP_IS_HTTP_INPUT_STREAM (httpstream), FALSE);
+ soup_http_input_stream_queue_message (httpstream);
+
if (!g_input_stream_set_pending (istream, error))
return FALSE;
g_return_if_fail (SOUP_IS_HTTP_INPUT_STREAM (httpstream));
+ soup_http_input_stream_queue_message (httpstream);
+
if (!g_input_stream_set_pending (istream, &error)) {
g_simple_async_report_take_gerror_in_idle (G_OBJECT (httpstream),
callback,
SoupHTTPInputStreamPrivate *priv = SOUP_HTTP_INPUT_STREAM_GET_PRIVATE (httpstream);
return priv->msg ? g_object_ref (priv->msg) : NULL;
}
+
+const char *
+soup_http_input_stream_get_content_type (SoupHTTPInputStream *httpstream)
+{
+ SoupHTTPInputStreamPrivate *priv = SOUP_HTTP_INPUT_STREAM_GET_PRIVATE (httpstream);
+
+ if (priv->sniffed_content_type)
+ return priv->sniffed_content_type;
+ else
+ return soup_message_headers_get_content_type (priv->msg->response_headers, NULL);
+
+}
#include "soup-request-http.h"
#include "soup-cache.h"
#include "soup-cache-private.h"
-#include "soup-content-sniffer.h"
#include "soup-http-input-stream.h"
#include "soup-message.h"
#include "soup-session.h"
struct _SoupRequestHTTPPrivate {
SoupMessage *msg;
+ char *content_type;
};
static void
g_object_unref (httpstream);
return NULL;
}
+ http->priv->content_type = g_strdup (soup_http_input_stream_get_content_type (SOUP_HTTP_INPUT_STREAM (httpstream)));
return httpstream;
}
GError *error = NULL;
if (soup_http_input_stream_send_finish (httpstream, result, &error)) {
+ sadata->http->priv->content_type = g_strdup (soup_http_input_stream_get_content_type (httpstream));
g_simple_async_result_set_op_res_gpointer (sadata->simple, httpstream, g_object_unref);
} else {
g_simple_async_result_take_error (sadata->simple, error);
soup_message_got_headers (sadata->original);
- if (soup_session_get_feature_for_message (session, SOUP_TYPE_CONTENT_SNIFFER, sadata->original)) {
- const char *content_type =
- soup_message_headers_get_content_type (sadata->original->response_headers, NULL);
- soup_message_content_sniffed (sadata->original, content_type, NULL);
- }
+ /* FIXME: this is wrong; the cache won't have
+ * the sniffed type.
+ */
+ sadata->http->priv->content_type = g_strdup (soup_message_headers_get_content_type (sadata->original->response_headers, NULL));
g_simple_async_result_complete (sadata->simple);
idle_return_from_cache_cb (gpointer data)
{
SendAsyncData *sadata = data;
- SoupSession *session;
-
- session = soup_request_get_session (SOUP_REQUEST (sadata->http));
g_simple_async_result_set_op_res_gpointer (sadata->simple,
g_object_ref (sadata->stream), g_object_unref);
/* Issue signals */
soup_message_got_headers (sadata->http->priv->msg);
- if (soup_session_get_feature_for_message (session, SOUP_TYPE_CONTENT_SNIFFER, sadata->http->priv->msg)) {
- const char *content_type = soup_message_headers_get_content_type (sadata->http->priv->msg->response_headers, NULL);
- soup_message_content_sniffed (sadata->http->priv->msg, content_type, NULL);
- }
+ sadata->http->priv->content_type = g_strdup (soup_message_headers_get_content_type (sadata->http->priv->msg->response_headers, NULL));
g_simple_async_result_complete (sadata->simple);
{
SoupRequestHTTP *http = SOUP_REQUEST_HTTP (request);
- return soup_message_headers_get_content_type (http->priv->msg->response_headers, NULL);
+ return http->priv->content_type;
}
static const char *http_schemes[] = { "http", "https", NULL };