|
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 |
}
|