Blame libsoup/soup-message-client-io.c

rpm-build 4f3c61
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
rpm-build 4f3c61
/*
rpm-build 4f3c61
 * soup-message-client-io.c: client-side request/response
rpm-build 4f3c61
 *
rpm-build 4f3c61
 * Copyright (C) 2000-2003, Ximian, Inc.
rpm-build 4f3c61
 */
rpm-build 4f3c61
rpm-build 4f3c61
#ifdef HAVE_CONFIG_H
rpm-build 4f3c61
#include "config.h"
rpm-build 4f3c61
#endif
rpm-build 4f3c61
rpm-build 4f3c61
#include <string.h>
rpm-build 4f3c61
rpm-build 4f3c61
#include <glib/gi18n-lib.h>
rpm-build 4f3c61
rpm-build 4f3c61
#include "soup.h"
rpm-build 4f3c61
#include "soup-connection.h"
rpm-build 4f3c61
#include "soup-message-private.h"
rpm-build 4f3c61
#include "soup-message-queue.h"
rpm-build 4f3c61
#include "soup-socket-private.h"
rpm-build 4f3c61
rpm-build 4f3c61
static guint
rpm-build 4f3c61
parse_response_headers (SoupMessage *msg,
rpm-build 4f3c61
			char *headers, guint headers_len,
rpm-build 4f3c61
			SoupEncoding *encoding,
rpm-build 4f3c61
			gpointer user_data,
rpm-build 4f3c61
			GError **error)
rpm-build 4f3c61
{
rpm-build 4f3c61
	SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
rpm-build 4f3c61
	SoupHTTPVersion version;
rpm-build 4f3c61
rpm-build 4f3c61
	g_free(msg->reason_phrase);
rpm-build 4f3c61
	msg->reason_phrase = NULL;
rpm-build 4f3c61
	if (!soup_headers_parse_response (headers, headers_len,
rpm-build 4f3c61
					  msg->response_headers,
rpm-build 4f3c61
					  &version,
rpm-build 4f3c61
					  &msg->status_code,
rpm-build 4f3c61
					  &msg->reason_phrase)) {
rpm-build 4f3c61
		g_set_error_literal (error, SOUP_REQUEST_ERROR,
rpm-build 4f3c61
				     SOUP_REQUEST_ERROR_PARSING,
rpm-build 4f3c61
				     _("Could not parse HTTP response"));
rpm-build 4f3c61
		return SOUP_STATUS_MALFORMED;
rpm-build 4f3c61
	}
rpm-build 4f3c61
rpm-build 4f3c61
	g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_STATUS_CODE);
rpm-build 4f3c61
	g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_REASON_PHRASE);
rpm-build 4f3c61
rpm-build 4f3c61
	if (version < priv->http_version) {
rpm-build 4f3c61
		priv->http_version = version;
rpm-build 4f3c61
		g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_HTTP_VERSION);
rpm-build 4f3c61
	}
rpm-build 4f3c61
rpm-build 4f3c61
	if ((msg->method == SOUP_METHOD_HEAD ||
rpm-build 4f3c61
	     msg->status_code  == SOUP_STATUS_NO_CONTENT ||
rpm-build 4f3c61
	     msg->status_code  == SOUP_STATUS_NOT_MODIFIED ||
rpm-build 4f3c61
	     SOUP_STATUS_IS_INFORMATIONAL (msg->status_code)) ||
rpm-build 4f3c61
	    (msg->method == SOUP_METHOD_CONNECT &&
rpm-build 4f3c61
	     SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)))
rpm-build 4f3c61
		*encoding = SOUP_ENCODING_NONE;
rpm-build 4f3c61
	else
rpm-build 4f3c61
		*encoding = soup_message_headers_get_encoding (msg->response_headers);
rpm-build 4f3c61
rpm-build 4f3c61
	if (*encoding == SOUP_ENCODING_UNRECOGNIZED) {
rpm-build 4f3c61
		g_set_error_literal (error, SOUP_REQUEST_ERROR,
rpm-build 4f3c61
				     SOUP_REQUEST_ERROR_ENCODING,
rpm-build 4f3c61
				     _("Unrecognized HTTP response encoding"));
rpm-build 4f3c61
		return SOUP_STATUS_MALFORMED;
rpm-build 4f3c61
	}
rpm-build 4f3c61
rpm-build 4f3c61
	return SOUP_STATUS_OK;
rpm-build 4f3c61
}
rpm-build 4f3c61
rpm-build 4f3c61
static void
rpm-build 4f3c61
get_request_headers (SoupMessage *msg, GString *header,
rpm-build 4f3c61
		     SoupEncoding *encoding, gpointer user_data)
rpm-build 4f3c61
{
rpm-build 4f3c61
	SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
rpm-build 4f3c61
	SoupMessageQueueItem *item = user_data;
rpm-build 4f3c61
	SoupURI *uri = soup_message_get_uri (msg);
rpm-build 4f3c61
	char *uri_host;
rpm-build 4f3c61
	char *uri_string;
rpm-build 4f3c61
	SoupMessageHeadersIter iter;
rpm-build 4f3c61
	const char *name, *value;
rpm-build 4f3c61
rpm-build 4f3c61
	if (strchr (uri->host, ':'))
rpm-build 4f3c61
		uri_host = g_strdup_printf ("[%.*s]", (int) strcspn (uri->host, "%"), uri->host);
rpm-build 4f3c61
	else if (g_hostname_is_non_ascii (uri->host))
rpm-build 4f3c61
		uri_host = g_hostname_to_ascii (uri->host);
rpm-build 4f3c61
	else
rpm-build 4f3c61
		uri_host = uri->host;
rpm-build 4f3c61
rpm-build 4f3c61
	if (msg->method == SOUP_METHOD_CONNECT) {
rpm-build 4f3c61
		/* CONNECT URI is hostname:port for tunnel destination */
rpm-build 4f3c61
		uri_string = g_strdup_printf ("%s:%d", uri_host, uri->port);
rpm-build 4f3c61
	} else {
rpm-build 4f3c61
		gboolean proxy = soup_connection_is_via_proxy (item->conn);
rpm-build 4f3c61
rpm-build 4f3c61
		/* Proxy expects full URI to destination. Otherwise
rpm-build 4f3c61
		 * just the path.
rpm-build 4f3c61
		 */
rpm-build 4f3c61
		uri_string = soup_uri_to_string (uri, !proxy);
rpm-build 4f3c61
rpm-build 4f3c61
		if (proxy && uri->fragment) {
rpm-build 4f3c61
			/* Strip fragment */
rpm-build 4f3c61
			char *fragment = strchr (uri_string, '#');
rpm-build 4f3c61
			if (fragment)
rpm-build 4f3c61
				*fragment = '\0';
rpm-build 4f3c61
		}
rpm-build 4f3c61
	}
rpm-build 4f3c61
rpm-build 4f3c61
	g_string_append_printf (header, "%s %s HTTP/1.%d\r\n",
rpm-build 4f3c61
				msg->method, uri_string,
rpm-build 4f3c61
				(priv->http_version == SOUP_HTTP_1_0) ? 0 : 1);
rpm-build 4f3c61
rpm-build 4f3c61
	if (!soup_message_headers_get_one (msg->request_headers, "Host")) {
rpm-build 4f3c61
		if (soup_uri_uses_default_port (uri)) {
rpm-build 4f3c61
			g_string_append_printf (header, "Host: %s\r\n",
rpm-build 4f3c61
						uri_host);
rpm-build 4f3c61
		} else {
rpm-build 4f3c61
			g_string_append_printf (header, "Host: %s:%d\r\n",
rpm-build 4f3c61
						uri_host, uri->port);
rpm-build 4f3c61
		}
rpm-build 4f3c61
	}
rpm-build 4f3c61
	g_free (uri_string);
rpm-build 4f3c61
	if (uri_host != uri->host)
rpm-build 4f3c61
		g_free (uri_host);
rpm-build 4f3c61
rpm-build 4f3c61
	*encoding = soup_message_headers_get_encoding (msg->request_headers);
rpm-build 4f3c61
	if ((*encoding == SOUP_ENCODING_CONTENT_LENGTH ||
rpm-build 4f3c61
	     *encoding == SOUP_ENCODING_NONE) &&
rpm-build 4f3c61
	    (msg->request_body->length > 0 ||
rpm-build 4f3c61
	     soup_message_headers_get_one (msg->request_headers, "Content-Type")) &&
rpm-build 4f3c61
	    !soup_message_headers_get_content_length (msg->request_headers)) {
rpm-build 4f3c61
		*encoding = SOUP_ENCODING_CONTENT_LENGTH;
rpm-build 4f3c61
		soup_message_headers_set_content_length (msg->request_headers,
rpm-build 4f3c61
							 msg->request_body->length);
rpm-build 4f3c61
	}
rpm-build 4f3c61
rpm-build 4f3c61
	soup_message_headers_iter_init (&iter, msg->request_headers);
rpm-build 4f3c61
	while (soup_message_headers_iter_next (&iter, &name, &value))
rpm-build 4f3c61
		g_string_append_printf (header, "%s: %s\r\n", name, value);
rpm-build 4f3c61
	g_string_append (header, "\r\n");
rpm-build 4f3c61
}
rpm-build 4f3c61
rpm-build 4f3c61
void
rpm-build 4f3c61
soup_message_send_request (SoupMessageQueueItem      *item,
rpm-build 4f3c61
			   SoupMessageCompletionFn    completion_cb,
rpm-build 4f3c61
			   gpointer                   user_data)
rpm-build 4f3c61
{
rpm-build 4f3c61
	GMainContext *async_context;
rpm-build 4f3c61
	GIOStream *iostream;
rpm-build 4f3c61
rpm-build 4f3c61
	if (!SOUP_IS_SESSION_SYNC (item->session)) {
rpm-build 4f3c61
		async_context = soup_session_get_async_context (item->session);
rpm-build 4f3c61
		if (!async_context)
rpm-build 4f3c61
			async_context = g_main_context_default ();
rpm-build 4f3c61
	} else
rpm-build 4f3c61
		async_context = NULL;
rpm-build 4f3c61
	iostream = soup_socket_get_iostream (soup_connection_get_socket (item->conn));
rpm-build 4f3c61
rpm-build 4f3c61
	soup_message_io_client (item, iostream, async_context,
rpm-build 4f3c61
				get_request_headers,
rpm-build 4f3c61
				parse_response_headers,
rpm-build 4f3c61
				item,
rpm-build 4f3c61
				completion_cb, user_data);
rpm-build 4f3c61
}