[libsoup/new-io] Make SoupRequest a class rahter than an interface, add SoupRequestHTTP



commit c139fe37796247222d6da980df0924a8768d1bd5
Author: Dan Winship <danw gnome org>
Date:   Sun Dec 20 17:15:57 2009 +0100

    Make SoupRequest a class rahter than an interface, add SoupRequestHTTP

 libsoup/Makefile.am         |    4 +-
 libsoup/soup-message.c      |  112 +----------------------
 libsoup/soup-request-base.c |  177 -----------------------------------
 libsoup/soup-request-base.h |   39 --------
 libsoup/soup-request-data.c |   41 +++-----
 libsoup/soup-request-data.h |    6 +-
 libsoup/soup-request-file.c |   39 +++-----
 libsoup/soup-request-file.h |    6 +-
 libsoup/soup-request-ftp.c  |   57 +++++-------
 libsoup/soup-request-ftp.h  |   20 ++--
 libsoup/soup-request-http.c |  156 +++++++++++++++++++++++++++++++
 libsoup/soup-request-http.h |   33 +++++++
 libsoup/soup-request.c      |  217 ++++++++++++++++++++++++++++++++++---------
 libsoup/soup-request.h      |   29 +++++--
 libsoup/soup-session.c      |   15 ++--
 15 files changed, 462 insertions(+), 489 deletions(-)
---
diff --git a/libsoup/Makefile.am b/libsoup/Makefile.am
index 567fb84..9f4bb13 100644
--- a/libsoup/Makefile.am
+++ b/libsoup/Makefile.am
@@ -76,7 +76,6 @@ soup_headers =			\
 	soup-proxy-resolver.h	\
 	soup-proxy-uri-resolver.h \
 	soup-request.h		\
-	soup-request-base.h	\
 	soup-server.h		\
 	soup-session.h		\
 	soup-session-async.h	\
@@ -168,13 +167,14 @@ libsoup_2_4_la_SOURCES =		\
 	soup-proxy-resolver-static.c	\
 	soup-proxy-uri-resolver.c	\
 	soup-request.c			\
-	soup-request-base.c		\
 	soup-request-data.h		\
 	soup-request-data.c		\
 	soup-request-file.h		\
 	soup-request-file.c		\
 	soup-request-ftp.h		\
 	soup-request-ftp.c		\
+	soup-request-http.h		\
+	soup-request-http.c		\
 	soup-server.c			\
 	soup-session.c			\
 	soup-session-async.c		\
diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c
index 16a27ce..5ab50f3 100644
--- a/libsoup/soup-message.c
+++ b/libsoup/soup-message.c
@@ -89,11 +89,7 @@
  * @request_body as appropriate, passing %FALSE.
  **/
 
-static void soup_message_request_interface_init (SoupRequestInterface *request_interface);
-
-G_DEFINE_TYPE_WITH_CODE (SoupMessage, soup_message, G_TYPE_OBJECT,
-			 G_IMPLEMENT_INTERFACE (SOUP_TYPE_REQUEST,
-						soup_message_request_interface_init))
+G_DEFINE_TYPE (SoupMessage, soup_message, G_TYPE_OBJECT)
 
 enum {
 	WROTE_INFORMATIONAL,
@@ -126,7 +122,6 @@ enum {
 	PROP_SERVER_SIDE,
 	PROP_STATUS_CODE,
 	PROP_REASON_PHRASE,
-	PROP_SESSION,
 
 	LAST_PROP
 };
@@ -140,17 +135,6 @@ static void set_property (GObject *object, guint prop_id,
 static void get_property (GObject *object, guint prop_id,
 			  GValue *value, GParamSpec *pspec);
 
-static GInputStream *soup_message_send        (SoupRequest          *request,
-					       GCancellable         *cancellable,
-					       GError              **error);
-static void          soup_message_send_async  (SoupRequest          *request,
-					       GCancellable         *cancellable,
-					       GAsyncReadyCallback   callback,
-					       gpointer              user_data);
-static GInputStream *soup_message_send_finish (SoupRequest          *request,
-					       GAsyncResult         *result,
-					       GError              **error);
-
 static void
 soup_message_init (SoupMessage *msg)
 {
@@ -595,22 +579,6 @@ soup_message_class_init (SoupMessageClass *message_class)
 				     "The HTTP response reason phrase",
 				     NULL,
 				     G_PARAM_READWRITE));
-
-	g_object_class_install_property (
-		object_class, PROP_SESSION,
-		g_param_spec_object ("session",
-				     "Session",
-				     "The message's session",
-				     SOUP_TYPE_SESSION,
-				     G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-}
-
-static void
-soup_message_request_interface_init (SoupRequestInterface *request_interface)
-{
-	request_interface->send = soup_message_send;
-	request_interface->send_async = soup_message_send_async;
-	request_interface->send_finish = soup_message_send_finish;
 }
 
 static void
@@ -647,11 +615,6 @@ set_property (GObject *object, guint prop_id,
 		soup_message_set_status_full (msg, msg->status_code,
 					      g_value_get_string (value));
 		break;
-	case PROP_SESSION:
-		if (priv->session)
-			g_object_unref (priv->session);
-		priv->session = g_value_dup_object (value);
-		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -687,9 +650,6 @@ get_property (GObject *object, guint prop_id,
 	case PROP_REASON_PHRASE:
 		g_value_set_string (value, msg->reason_phrase);
 		break;
-	case PROP_SESSION:
-		g_value_set_object (value, priv->session);
-		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -1707,73 +1667,3 @@ soup_message_disables_feature (SoupMessage *msg, gpointer feature)
 	}
 	return FALSE;
 }
-
-/* SoupRequest interface implementation */
-
-static GInputStream *
-soup_message_send (SoupRequest   *request,
-		   GCancellable  *cancellable,
-		   GError       **error)
-{
-	SoupMessage *msg = SOUP_MESSAGE (request);
-	SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
-	SoupHTTPInputStream *httpstream;
-
-	httpstream = soup_http_input_stream_new (priv->session, msg);
-	if (!soup_http_input_stream_send (httpstream, cancellable, error)) {
-		g_object_unref (httpstream);
-		return NULL;
-	}
-	return (GInputStream *)httpstream;
-}
-
-static void
-sent_async (GObject *source, GAsyncResult *result, gpointer user_data)
-{
-	SoupHTTPInputStream *httpstream = SOUP_HTTP_INPUT_STREAM (source);
-	GSimpleAsyncResult *simple = user_data;
-	GError *error = NULL;
-
-	if (soup_http_input_stream_send_finish (httpstream, result, &error)) {
-		g_simple_async_result_set_op_res_gpointer (simple, httpstream, g_object_unref);
-	} else {
-		g_simple_async_result_set_from_error (simple, error);
-		g_error_free (error);
-		g_object_unref (httpstream);
-	}
-	g_simple_async_result_complete (simple);
-	g_object_unref (simple);
-}
-
-static void
-soup_message_send_async (SoupRequest          *request,
-			 GCancellable         *cancellable,
-			 GAsyncReadyCallback   callback,
-			 gpointer              user_data)
-{
-	SoupMessage *msg = SOUP_MESSAGE (request);
-	SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
-	SoupHTTPInputStream *httpstream;
-	GSimpleAsyncResult *simple;
-
-	simple = g_simple_async_result_new (G_OBJECT (msg), callback, user_data,
-					    soup_message_send_async);
-	httpstream = soup_http_input_stream_new (priv->session, msg);
-	soup_http_input_stream_send_async (httpstream, G_PRIORITY_DEFAULT,
-					   cancellable, sent_async, simple);
-}
-
-static GInputStream *
-soup_message_send_finish (SoupRequest   *request,
-			  GAsyncResult  *result,
-			  GError       **error)
-{
-	GSimpleAsyncResult *simple;
-
-	g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (request), soup_message_send_async), NULL);
-
-	simple = G_SIMPLE_ASYNC_RESULT (result);
-	if (g_simple_async_result_propagate_error (simple, error))
-		return NULL;
-	return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
-}
diff --git a/libsoup/soup-request-data.c b/libsoup/soup-request-data.c
index 48c604e..eb3dd25 100644
--- a/libsoup/soup-request-data.c
+++ b/libsoup/soup-request-data.c
@@ -12,19 +12,13 @@
 #include <glib/gi18n.h>
 
 #include "soup-request-data.h"
-#include "soup-session-feature.h"
-#include "soup-session.h"
 #include "soup-uri.h"
 
-static void soup_request_data_request_interface_init (SoupRequestInterface *request_interface);
+G_DEFINE_TYPE (SoupRequestData, soup_request_data, SOUP_TYPE_REQUEST)
 
-G_DEFINE_TYPE_WITH_CODE (SoupRequestData, soup_request_data, SOUP_TYPE_REQUEST_BASE,
-			 G_IMPLEMENT_INTERFACE (SOUP_TYPE_REQUEST,
-						soup_request_data_request_interface_init))
-
-static gboolean soup_request_data_validate_uri (SoupRequestBase  *req_base,
-						SoupURI          *uri,
-						GError          **error);
+static gboolean soup_request_data_check_uri (SoupRequest  *request,
+					     SoupURI      *uri,
+					     GError      **error);
 
 static GInputStream *soup_request_data_send (SoupRequest   *request,
 					     GCancellable  *cancellable,
@@ -33,16 +27,11 @@ static GInputStream *soup_request_data_send (SoupRequest   *request,
 static void
 soup_request_data_class_init (SoupRequestDataClass *request_data_class)
 {
-	SoupRequestBaseClass *request_base_class =
-		SOUP_REQUEST_BASE_CLASS (request_data_class);
-
-	request_base_class->validate_uri = soup_request_data_validate_uri;
-}
+	SoupRequestClass *request_class =
+		SOUP_REQUEST_CLASS (request_data_class);
 
-static void
-soup_request_data_request_interface_init (SoupRequestInterface *request_interface)
-{
-	request_interface->send = soup_request_data_send;
+	request_class->check_uri = soup_request_data_check_uri;
+	request_class->send = soup_request_data_send;
 }
 
 static void
@@ -51,9 +40,9 @@ soup_request_data_init (SoupRequestData *data)
 }
 
 static gboolean
-soup_request_data_validate_uri (SoupRequestBase  *req_base,
-				SoupURI          *uri,
-				GError          **error)
+soup_request_data_check_uri (SoupRequest  *request,
+			     SoupURI      *uri,
+			     GError      **error)
 {
 	return uri->host == NULL;
 }
@@ -136,11 +125,11 @@ fail:
 }
 
 static GInputStream *
-soup_request_data_send (SoupRequest          *request,
-			GCancellable         *cancellable,
-			GError              **error)
+soup_request_data_send (SoupRequest   *request,
+			GCancellable  *cancellable,
+			GError       **error)
 {
-	SoupURI *uri = soup_request_base_get_uri (SOUP_REQUEST_BASE (request));
+	SoupURI *uri = soup_request_get_uri (request);
 
 	return data_uri_decode (uri->path, NULL);
 }
diff --git a/libsoup/soup-request-data.h b/libsoup/soup-request-data.h
index db5cb00..238d5b2 100644
--- a/libsoup/soup-request-data.h
+++ b/libsoup/soup-request-data.h
@@ -6,7 +6,7 @@
 #ifndef SOUP_REQUEST_DATA_H
 #define SOUP_REQUEST_DATA_H 1
 
-#include "soup-request-base.h"
+#include "soup-request.h"
 
 #define SOUP_TYPE_REQUEST_DATA            (soup_request_data_get_type ())
 #define SOUP_REQUEST_DATA(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), SOUP_TYPE_REQUEST_DATA, SoupRequestData))
@@ -16,12 +16,12 @@
 #define SOUP_REQUEST_DATA_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SOUP_TYPE_REQUEST_DATA, SoupRequestDataClass))
 
 typedef struct {
-	SoupRequestBase parent;
+	SoupRequest parent;
 
 } SoupRequestData;
 
 typedef struct {
-	SoupRequestBaseClass parent;
+	SoupRequestClass parent;
 
 } SoupRequestDataClass;
 
diff --git a/libsoup/soup-request-file.c b/libsoup/soup-request-file.c
index 351be14..6a735dd 100644
--- a/libsoup/soup-request-file.c
+++ b/libsoup/soup-request-file.c
@@ -12,15 +12,9 @@
 #include <glib/gi18n.h>
 
 #include "soup-request-file.h"
-#include "soup-session-feature.h"
-#include "soup-session.h"
 #include "soup-uri.h"
 
-static void soup_request_file_request_interface_init (SoupRequestInterface *request_interface);
-
-G_DEFINE_TYPE_WITH_CODE (SoupRequestFile, soup_request_file, SOUP_TYPE_REQUEST_BASE,
-			 G_IMPLEMENT_INTERFACE (SOUP_TYPE_REQUEST,
-						soup_request_file_request_interface_init))
+G_DEFINE_TYPE (SoupRequestFile, soup_request_file, SOUP_TYPE_REQUEST)
 
 struct _SoupRequestFilePrivate {
 	GFile *gfile;
@@ -28,9 +22,9 @@ struct _SoupRequestFilePrivate {
 
 static void soup_request_file_finalize (GObject *object);
 
-static gboolean soup_request_file_validate_uri (SoupRequestBase  *req_base,
-						SoupURI          *uri,
-						GError          **error);
+static gboolean soup_request_file_check_uri (SoupRequest  *request,
+					     SoupURI      *uri,
+					     GError      **error);
 
 static GInputStream *soup_request_file_send        (SoupRequest          *request,
 						    GCancellable         *cancellable,
@@ -47,22 +41,17 @@ static void
 soup_request_file_class_init (SoupRequestFileClass *request_file_class)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (request_file_class);
-	SoupRequestBaseClass *request_base_class =
-		SOUP_REQUEST_BASE_CLASS (request_file_class);
+	SoupRequestClass *request_class =
+		SOUP_REQUEST_CLASS (request_file_class);
 
 	g_type_class_add_private (request_file_class, sizeof (SoupRequestFilePrivate));
 
 	object_class->finalize = soup_request_file_finalize;
 
-	request_base_class->validate_uri = soup_request_file_validate_uri;
-}
-
-static void
-soup_request_file_request_interface_init (SoupRequestInterface *request_interface)
-{
-	request_interface->send = soup_request_file_send;
-	request_interface->send_async = soup_request_file_send_async;
-	request_interface->send_finish = soup_request_file_send_finish;
+	request_class->check_uri = soup_request_file_check_uri;
+	request_class->send = soup_request_file_send;
+	request_class->send_async = soup_request_file_send_async;
+	request_class->send_finish = soup_request_file_send_finish;
 }
 
 static void
@@ -83,11 +72,11 @@ soup_request_file_finalize (GObject *object)
 }
 
 static gboolean
-soup_request_file_validate_uri (SoupRequestBase  *req_base,
-				SoupURI          *uri,
-				GError          **error)
+soup_request_file_check_uri (SoupRequest  *request,
+			     SoupURI      *uri,
+			     GError      **error)
 {
-	SoupRequestFile *file = SOUP_REQUEST_FILE (req_base);
+	SoupRequestFile *file = SOUP_REQUEST_FILE (request);
 	char *path_decoded;
 
 	/* "file:/foo" is not valid */
diff --git a/libsoup/soup-request-file.h b/libsoup/soup-request-file.h
index 7745436..9e6f39d 100644
--- a/libsoup/soup-request-file.h
+++ b/libsoup/soup-request-file.h
@@ -6,7 +6,7 @@
 #ifndef SOUP_REQUEST_FILE_H
 #define SOUP_REQUEST_FILE_H 1
 
-#include "soup-request-base.h"
+#include "soup-request.h"
 
 #define SOUP_TYPE_REQUEST_FILE            (soup_request_file_get_type ())
 #define SOUP_REQUEST_FILE(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), SOUP_TYPE_REQUEST_FILE, SoupRequestFile))
@@ -18,13 +18,13 @@
 typedef struct _SoupRequestFilePrivate SoupRequestFilePrivate;
 
 typedef struct {
-	SoupRequestBase parent;
+	SoupRequest parent;
 
 	SoupRequestFilePrivate *priv;
 } SoupRequestFile;
 
 typedef struct {
-	SoupRequestBaseClass parent;
+	SoupRequestClass parent;
 
 } SoupRequestFileClass;
 
diff --git a/libsoup/soup-request-ftp.c b/libsoup/soup-request-ftp.c
index a81872d..c14ce9a 100644
--- a/libsoup/soup-request-ftp.c
+++ b/libsoup/soup-request-ftp.c
@@ -13,25 +13,19 @@
 
 #include "soup-request-ftp.h"
 #include "soup-ftp-connection.h"
-#include "soup-session-feature.h"
-#include "soup-session.h"
 #include "soup-uri.h"
 
-static void soup_request_ftp_request_interface_init (SoupRequestInterface *request_interface);
+G_DEFINE_TYPE (SoupRequestFTP, soup_request_ftp, SOUP_TYPE_REQUEST)
 
-G_DEFINE_TYPE_WITH_CODE (SoupRequestFtp, soup_request_ftp, SOUP_TYPE_REQUEST_BASE,
-			 G_IMPLEMENT_INTERFACE (SOUP_TYPE_REQUEST,
-						soup_request_ftp_request_interface_init))
-
-struct _SoupRequestFtpPrivate {
+struct _SoupRequestFTPPrivate {
 	SoupFTPConnection *conn;
 };
 
 static void soup_request_ftp_finalize (GObject *object);
 
-static gboolean soup_request_ftp_validate_uri (SoupRequestBase  *req_base,
-					       SoupURI          *uri,
-					       GError          **error);
+static gboolean soup_request_ftp_check_uri (SoupRequest  *request,
+					    SoupURI      *uri,
+					    GError      **error);
 
 static GInputStream *soup_request_ftp_send        (SoupRequest          *request,
 						   GCancellable         *cancellable,
@@ -45,38 +39,33 @@ static GInputStream *soup_request_ftp_send_finish (SoupRequest          *request
 						   GError              **error);
 
 static void
-soup_request_ftp_class_init (SoupRequestFtpClass *request_ftp_class)
+soup_request_ftp_class_init (SoupRequestFTPClass *request_ftp_class)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (request_ftp_class);
-	SoupRequestBaseClass *request_base_class =
-		SOUP_REQUEST_BASE_CLASS (request_ftp_class);
+	SoupRequestClass *request_class =
+		SOUP_REQUEST_CLASS (request_ftp_class);
 
-	g_type_class_add_private (request_ftp_class, sizeof (SoupRequestFtpPrivate));
+	g_type_class_add_private (request_ftp_class, sizeof (SoupRequestFTPPrivate));
 
 	object_class->finalize = soup_request_ftp_finalize;
 
-	request_base_class->validate_uri = soup_request_ftp_validate_uri;
-}
-
-static void
-soup_request_ftp_request_interface_init (SoupRequestInterface *request_interface)
-{
-	request_interface->send = soup_request_ftp_send;
-	request_interface->send_async = soup_request_ftp_send_async;
-	request_interface->send_finish = soup_request_ftp_send_finish;
+	request_class->check_uri = soup_request_ftp_check_uri;
+	request_class->send = soup_request_ftp_send;
+	request_class->send_async = soup_request_ftp_send_async;
+	request_class->send_finish = soup_request_ftp_send_finish;
 }
 
 static void
-soup_request_ftp_init (SoupRequestFtp *ftp)
+soup_request_ftp_init (SoupRequestFTP *ftp)
 {
-	ftp->priv = G_TYPE_INSTANCE_GET_PRIVATE (ftp, SOUP_TYPE_REQUEST_FTP, SoupRequestFtpPrivate);
+	ftp->priv = G_TYPE_INSTANCE_GET_PRIVATE (ftp, SOUP_TYPE_REQUEST_FTP, SoupRequestFTPPrivate);
 	ftp->priv->conn = soup_ftp_connection_new ();
 }
 
 static gboolean
-soup_request_ftp_validate_uri (SoupRequestBase  *req_base,
-			       SoupURI          *uri,
-			       GError          **error)
+soup_request_ftp_check_uri (SoupRequest  *request,
+			    SoupURI      *uri,
+			    GError      **error)
 {
 	return uri->host != NULL;
 }
@@ -84,7 +73,7 @@ soup_request_ftp_validate_uri (SoupRequestBase  *req_base,
 static void
 soup_request_ftp_finalize (GObject *object)
 {
-	SoupRequestFtp *ftp = SOUP_REQUEST_FTP (object);
+	SoupRequestFTP *ftp = SOUP_REQUEST_FTP (object);
 
 	if (ftp->priv->conn)
 		g_object_unref (ftp->priv->conn);
@@ -99,10 +88,10 @@ soup_request_ftp_send (SoupRequest          *request,
 		       GCancellable         *cancellable,
 		       GError              **error)
 {
-	SoupRequestFtp *ftp = SOUP_REQUEST_FTP (request);
+	SoupRequestFTP *ftp = SOUP_REQUEST_FTP (request);
 
 	return soup_ftp_connection_load_uri (ftp->priv->conn,
-					     soup_request_base_get_uri (SOUP_REQUEST_BASE (request)),
+					     soup_request_get_uri (request),
 					     cancellable,
 					     error);
 }
@@ -132,14 +121,14 @@ soup_request_ftp_send_async (SoupRequest          *request,
 			     GAsyncReadyCallback   callback,
 			     gpointer              user_data)
 {
-	SoupRequestFtp *ftp = SOUP_REQUEST_FTP (request);
+	SoupRequestFTP *ftp = SOUP_REQUEST_FTP (request);
 	GSimpleAsyncResult *simple;
 
 	simple = g_simple_async_result_new (G_OBJECT (request),
 					    callback, user_data,
 					    soup_request_ftp_send_async);
 	soup_ftp_connection_load_uri_async (ftp->priv->conn,
-					    soup_request_base_get_uri (SOUP_REQUEST_BASE (request)),
+					    soup_request_get_uri (request),
 					    cancellable,
 					    sent_async, simple);
 }
diff --git a/libsoup/soup-request-ftp.h b/libsoup/soup-request-ftp.h
index 5d2a8aa..935bdd5 100644
--- a/libsoup/soup-request-ftp.h
+++ b/libsoup/soup-request-ftp.h
@@ -6,27 +6,27 @@
 #ifndef SOUP_REQUEST_FTP_H
 #define SOUP_REQUEST_FTP_H 1
 
-#include "soup-request-base.h"
+#include "soup-request.h"
 
 #define SOUP_TYPE_REQUEST_FTP            (soup_request_ftp_get_type ())
-#define SOUP_REQUEST_FTP(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), SOUP_TYPE_REQUEST_FTP, SoupRequestFtp))
-#define SOUP_REQUEST_FTP_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), SOUP_TYPE_REQUEST_FTP, SoupRequestFtpClass))
+#define SOUP_REQUEST_FTP(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), SOUP_TYPE_REQUEST_FTP, SoupRequestFTP))
+#define SOUP_REQUEST_FTP_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), SOUP_TYPE_REQUEST_FTP, SoupRequestFTPClass))
 #define SOUP_IS_REQUEST_FTP(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), SOUP_TYPE_REQUEST_FTP))
 #define SOUP_IS_REQUEST_FTP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SOUP_TYPE_REQUEST_FTP))
-#define SOUP_REQUEST_FTP_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SOUP_TYPE_REQUEST_FTP, SoupRequestFtpClass))
+#define SOUP_REQUEST_FTP_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SOUP_TYPE_REQUEST_FTP, SoupRequestFTPClass))
 
-typedef struct _SoupRequestFtpPrivate SoupRequestFtpPrivate;
+typedef struct _SoupRequestFTPPrivate SoupRequestFTPPrivate;
 
 typedef struct {
-	SoupRequestBase parent;
+	SoupRequest parent;
 
-	SoupRequestFtpPrivate *priv;
-} SoupRequestFtp;
+	SoupRequestFTPPrivate *priv;
+} SoupRequestFTP;
 
 typedef struct {
-	SoupRequestBaseClass parent;
+	SoupRequestClass parent;
 
-} SoupRequestFtpClass;
+} SoupRequestFTPClass;
 
 GType soup_request_ftp_get_type (void);
 
diff --git a/libsoup/soup-request-http.c b/libsoup/soup-request-http.c
new file mode 100644
index 0000000..fc34b13
--- /dev/null
+++ b/libsoup/soup-request-http.c
@@ -0,0 +1,156 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * soup-request-http.c: http: URI request object
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n.h>
+
+#include "soup-request-http.h"
+#include "soup-http-input-stream.h"
+#include "soup-message.h"
+#include "soup-uri.h"
+
+G_DEFINE_TYPE (SoupRequestHTTP, soup_request_http, SOUP_TYPE_REQUEST)
+
+struct _SoupRequestHTTPPrivate {
+	SoupMessage *msg;
+};
+
+static void soup_request_http_finalize (GObject *object);
+
+static gboolean soup_request_http_check_uri (SoupRequest  *request,
+					     SoupURI      *uri,
+					     GError      **error);
+
+static GInputStream *soup_request_http_send        (SoupRequest          *request,
+						    GCancellable         *cancellable,
+						    GError              **error);
+static void          soup_request_http_send_async  (SoupRequest          *request,
+						    GCancellable         *cancellable,
+						    GAsyncReadyCallback   callback,
+						    gpointer              user_data);
+static GInputStream *soup_request_http_send_finish (SoupRequest          *request,
+						    GAsyncResult         *result,
+						    GError              **error);
+
+static void
+soup_request_http_class_init (SoupRequestHTTPClass *request_http_class)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (request_http_class);
+	SoupRequestClass *request_class =
+		SOUP_REQUEST_CLASS (request_http_class);
+
+	g_type_class_add_private (request_http_class, sizeof (SoupRequestHTTPPrivate));
+
+	object_class->finalize = soup_request_http_finalize;
+
+	request_class->check_uri = soup_request_http_check_uri;
+	request_class->send = soup_request_http_send;
+	request_class->send_async = soup_request_http_send_async;
+	request_class->send_finish = soup_request_http_send_finish;
+}
+
+static void
+soup_request_http_init (SoupRequestHTTP *http)
+{
+	http->priv = G_TYPE_INSTANCE_GET_PRIVATE (http, SOUP_TYPE_REQUEST_HTTP, SoupRequestHTTPPrivate);
+}
+
+static gboolean
+soup_request_http_check_uri (SoupRequest  *request,
+			     SoupURI      *uri,
+			     GError      **error)
+{
+	SoupRequestHTTP *http = SOUP_REQUEST_HTTP (request);
+
+	if (!SOUP_URI_VALID_FOR_HTTP (uri))
+		return FALSE;
+
+	http->priv->msg = soup_message_new_from_uri (SOUP_METHOD_GET, uri);
+	return TRUE;
+}
+
+static void
+soup_request_http_finalize (GObject *object)
+{
+	SoupRequestHTTP *http = SOUP_REQUEST_HTTP (object);
+
+	if (http->priv->msg)
+		g_object_unref (http->priv->msg);
+
+	G_OBJECT_CLASS (soup_request_http_parent_class)->finalize (object);
+}
+
+static GInputStream *
+soup_request_http_send (SoupRequest          *request,
+			GCancellable         *cancellable,
+			GError              **error)
+{
+	SoupRequestHTTP *http = SOUP_REQUEST_HTTP (request);
+	SoupHTTPInputStream *httpstream;
+
+	httpstream = soup_http_input_stream_new (soup_request_get_session (request), http->priv->msg);
+	if (!soup_http_input_stream_send (httpstream, cancellable, error)) {
+		g_object_unref (httpstream);
+		return NULL;
+	}
+	return (GInputStream *)httpstream;
+}
+
+static void
+sent_async (GObject *source, GAsyncResult *result, gpointer user_data)
+{
+	SoupHTTPInputStream *httpstream = SOUP_HTTP_INPUT_STREAM (source);
+	GSimpleAsyncResult *simple = user_data;
+	GError *error = NULL;
+
+	if (soup_http_input_stream_send_finish (httpstream, result, &error)) {
+		g_simple_async_result_set_op_res_gpointer (simple, httpstream, g_object_unref);
+	} else {
+		g_simple_async_result_set_from_error (simple, error);
+		g_error_free (error);
+		g_object_unref (httpstream);
+	}
+	g_simple_async_result_complete (simple);
+	g_object_unref (simple);
+}
+
+static void
+soup_request_http_send_async (SoupRequest          *request,
+			      GCancellable         *cancellable,
+			      GAsyncReadyCallback   callback,
+			      gpointer              user_data)
+{
+	SoupRequestHTTP *http = SOUP_REQUEST_HTTP (request);
+	SoupHTTPInputStream *httpstream;
+	GSimpleAsyncResult *simple;
+
+	simple = g_simple_async_result_new (G_OBJECT (http),
+					    callback, user_data,
+					    soup_request_http_send_async);
+	httpstream = soup_http_input_stream_new (soup_request_get_session (request),
+						 http->priv->msg);
+	soup_http_input_stream_send_async (httpstream, G_PRIORITY_DEFAULT,
+					   cancellable, sent_async, simple);
+}
+
+static GInputStream *
+soup_request_http_send_finish (SoupRequest          *request,
+			      GAsyncResult         *result,
+			      GError              **error)
+{
+	GSimpleAsyncResult *simple;
+
+	g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (request), soup_request_http_send_async), NULL);
+
+	simple = G_SIMPLE_ASYNC_RESULT (result);
+	if (g_simple_async_result_propagate_error (simple, error))
+		return NULL;
+	return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
+}
diff --git a/libsoup/soup-request-http.h b/libsoup/soup-request-http.h
new file mode 100644
index 0000000..249d9c1
--- /dev/null
+++ b/libsoup/soup-request-http.h
@@ -0,0 +1,33 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2009 Red Hat, Inc.
+ */
+
+#ifndef SOUP_REQUEST_HTTP_H
+#define SOUP_REQUEST_HTTP_H 1
+
+#include "soup-request.h"
+
+#define SOUP_TYPE_REQUEST_HTTP            (soup_request_http_get_type ())
+#define SOUP_REQUEST_HTTP(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), SOUP_TYPE_REQUEST_HTTP, SoupRequestHTTP))
+#define SOUP_REQUEST_HTTP_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), SOUP_TYPE_REQUEST_HTTP, SoupRequestHTTPClass))
+#define SOUP_IS_REQUEST_HTTP(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), SOUP_TYPE_REQUEST_HTTP))
+#define SOUP_IS_REQUEST_HTTP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SOUP_TYPE_REQUEST_HTTP))
+#define SOUP_REQUEST_HTTP_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SOUP_TYPE_REQUEST_HTTP, SoupRequestHTTPClass))
+
+typedef struct _SoupRequestHTTPPrivate SoupRequestHTTPPrivate;
+
+typedef struct {
+	SoupRequest parent;
+
+	SoupRequestHTTPPrivate *priv;
+} SoupRequestHTTP;
+
+typedef struct {
+	SoupRequestClass parent;
+
+} SoupRequestHTTPClass;
+
+GType soup_request_http_get_type (void);
+
+#endif /* SOUP_REQUEST_HTTP_H */
diff --git a/libsoup/soup-request.c b/libsoup/soup-request.c
index 3623cb8..66b0f97 100644
--- a/libsoup/soup-request.c
+++ b/libsoup/soup-request.c
@@ -9,6 +9,8 @@
 #include <config.h>
 #endif
 
+#include <glib/gi18n.h>
+
 #include "soup-request.h"
 #include "soup-session.h"
 #include "soup-uri.h"
@@ -28,72 +30,148 @@
  * Since: 2.30
  **/
 
-/**
- * SoupRequestInterface:
- * @parent: The parent interface.
- * @send: Synchronously send a request
- * @send_async: Asynchronously begin sending a request
- * @send_finish: Get the result of asynchronously sending a request
- *
- * The interface implemented by #SoupRequest<!-- -->s.
- *
- * Since: 2.30
- **/
+static void soup_request_initable_interface_init (GInitableIface *initable_interface);
+
+G_DEFINE_TYPE_WITH_CODE (SoupRequest, soup_request, G_TYPE_OBJECT,
+			 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+						soup_request_initable_interface_init))
+
+enum {
+	PROP_0,
+	PROP_URI,
+	PROP_SESSION
+};
 
-static void          send_async_default  (SoupRequest          *request,
-					  GCancellable         *cancellable,
-					  GAsyncReadyCallback   callback,
-					  gpointer              user_data);
-static GInputStream *send_finish_default (SoupRequest          *request,
-					  GAsyncResult         *result,
-					  GError              **error);
+struct _SoupRequestPrivate {
+	SoupURI *uri;
+	SoupSession *session;
 
-G_DEFINE_INTERFACE (SoupRequest, soup_request, G_TYPE_OBJECT)
+};
 
 static void
-soup_request_default_init (SoupRequestInterface *interface)
+soup_request_init (SoupRequest *request)
 {
-	interface->send_async = send_async_default;
-	interface->send_finish = send_finish_default;
+	request->priv = G_TYPE_INSTANCE_GET_PRIVATE (request, SOUP_TYPE_REQUEST, SoupRequestPrivate);
+}
 
-	g_object_interface_install_property (
-		interface,
-		g_param_spec_boxed (SOUP_REQUEST_URI,
-				    "URI",
-				    "The request URI",
-				    SOUP_TYPE_URI,
-				    G_PARAM_READWRITE));
-	g_object_interface_install_property (
-		interface,
-		g_param_spec_object (SOUP_REQUEST_SESSION,
-				     "Session",
-				     "The request's session",
-				     SOUP_TYPE_SESSION,
-				     G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+static void
+soup_request_finalize (GObject *object)
+{
+	SoupRequest *request = SOUP_REQUEST (object);
+
+	if (request->priv->uri)
+		soup_uri_free (request->priv->uri);
+	if (request->priv->session)
+		g_object_unref (request->priv->session);
+
+	G_OBJECT_CLASS (soup_request_parent_class)->finalize (object);
+}
+
+static void
+soup_request_set_property (GObject      *object,
+			   guint         prop_id,
+			   const GValue *value,
+			   GParamSpec   *pspec)
+{
+	SoupRequest *request = SOUP_REQUEST (object);
+
+	switch (prop_id) {
+	case PROP_URI:
+		if (request->priv->uri)
+			soup_uri_free (request->priv->uri);
+		request->priv->uri = g_value_dup_boxed (value);
+		break;
+	case PROP_SESSION:
+		if (request->priv->session)
+			g_object_unref (request->priv->session);
+		request->priv->session = g_value_dup_object (value);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+soup_request_get_property (GObject    *object,
+			   guint       prop_id,
+			   GValue     *value,
+			   GParamSpec *pspec)
+{
+	SoupRequest *request = SOUP_REQUEST (object);
+
+	switch (prop_id) {
+	case PROP_URI:
+		g_value_set_boxed (value, request->priv->uri);
+		break;
+	case PROP_SESSION:
+		g_value_set_object (value, request->priv->session);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static gboolean
+soup_request_initable_init (GInitable     *initable,
+			    GCancellable  *cancellable,
+			    GError       **error)
+{
+	SoupRequest *request = SOUP_REQUEST (initable);
+	gboolean ok;
+
+	if (!request->priv->uri) {
+		g_set_error (error, SOUP_ERROR, SOUP_ERROR_BAD_URI,
+			     _("No URI provided"));
+		return FALSE;
+	}
+
+	ok = SOUP_REQUEST_GET_CLASS (initable)->
+		check_uri (request, request->priv->uri, error);
+
+	if (!ok && error) {
+		char *uri_string = soup_uri_to_string (request->priv->uri, FALSE);
+		g_set_error (error, SOUP_ERROR, SOUP_ERROR_BAD_URI,
+			     _("Invalid '%s' URI: %s"),
+			     request->priv->uri->scheme,
+			     uri_string);
+		g_free (uri_string);
+	}
+
+	return ok;
+}
+
+static gboolean
+soup_request_default_check_uri (SoupRequest  *request,
+				SoupURI      *uri,
+				GError      **error)
+{
+	return TRUE;
 }
 
 /* Default implementation: assume the sync implementation doesn't block */
 static void
-send_async_default  (SoupRequest          *request,
-		     GCancellable         *cancellable,
-		     GAsyncReadyCallback   callback,
-		     gpointer              user_data)
+soup_request_default_send_async  (SoupRequest          *request,
+				  GCancellable         *cancellable,
+				  GAsyncReadyCallback   callback,
+				  gpointer              user_data)
 {
 	GSimpleAsyncResult *simple;
 
 	simple = g_simple_async_result_new (G_OBJECT (request),
 					    callback, user_data,
-					    send_async_default);
+					    soup_request_default_send_async);
 	g_simple_async_result_complete_in_idle (simple);
 	g_object_unref (simple);
 }
 
 static GInputStream *
-send_finish_default (SoupRequest          *request,
-		     GAsyncResult         *result,
-		     GError              **error)
+soup_request_default_send_finish (SoupRequest          *request,
+				  GAsyncResult         *result,
+				  GError              **error)
 {
-	g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (request), send_async_default), NULL);
+	g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (request), soup_request_default_send_async), NULL);
 
 	return soup_request_send (request, NULL, error);	
 }
@@ -125,3 +203,52 @@ soup_request_send_finish (SoupRequest          *request,
 	return SOUP_REQUEST_GET_CLASS (request)->
 		send_finish (request, result, error);
 }
+
+static void
+soup_request_class_init (SoupRequestClass *request_class)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (request_class);
+
+	g_type_class_add_private (request_class, sizeof (SoupRequestPrivate));
+
+	request_class->check_uri = soup_request_default_check_uri;
+	request_class->send_async = soup_request_default_send_async;
+	request_class->send_finish = soup_request_default_send_finish;
+
+	object_class->finalize = soup_request_finalize;
+	object_class->set_property = soup_request_set_property;
+	object_class->get_property = soup_request_get_property;
+
+	g_object_class_install_property (
+		object_class, PROP_URI,
+		g_param_spec_boxed (SOUP_REQUEST_URI,
+				    "URI",
+				    "The request URI",
+				    SOUP_TYPE_URI,
+				    G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+	g_object_class_install_property (
+		object_class, PROP_SESSION,
+		g_param_spec_object (SOUP_REQUEST_SESSION,
+				     "Session",
+				     "The request's session",
+				     SOUP_TYPE_SESSION,
+				     G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+soup_request_initable_interface_init (GInitableIface *initable_interface)
+{
+	initable_interface->init = soup_request_initable_init;
+}
+
+SoupURI *
+soup_request_get_uri (SoupRequest *request)
+{
+	return request->priv->uri;
+}
+
+SoupSession *
+soup_request_get_session (SoupRequest *request)
+{
+	return request->priv->session;
+}
diff --git a/libsoup/soup-request.h b/libsoup/soup-request.h
index 7fda09d..512ac05 100644
--- a/libsoup/soup-request.h
+++ b/libsoup/soup-request.h
@@ -1,6 +1,6 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
- * Copyright (C) 2008 Red Hat, Inc.
+ * Copyright (C) 2009 Red Hat, Inc.
  */
 
 #ifndef SOUP_REQUEST_H
@@ -13,15 +13,27 @@ G_BEGIN_DECLS
 
 #define SOUP_TYPE_REQUEST            (soup_request_get_type ())
 #define SOUP_REQUEST(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SOUP_TYPE_REQUEST, SoupRequest))
-#define SOUP_REQUEST_CLASS(klass)    (G_TYPE_CHECK_INTERFACE_CAST ((klass), SOUP_TYPE_REQUEST, SoupRequestInterface))
+#define SOUP_REQUEST_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), SOUP_TYPE_REQUEST, SoupRequestClass))
 #define SOUP_IS_REQUEST(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SOUP_TYPE_REQUEST))
 #define SOUP_IS_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SOUP_TYPE_REQUEST))
-#define SOUP_REQUEST_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_INTERFACE ((obj), SOUP_TYPE_REQUEST, SoupRequestInterface))
+#define SOUP_REQUEST_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SOUP_TYPE_REQUEST, SoupRequestClass))
 
-typedef struct {
-	GTypeInterface parent;
+typedef struct _SoupRequestPrivate SoupRequestPrivate;
+typedef struct _SoupRequestClass   SoupRequestClass;
+
+struct _SoupRequest {
+	GObject parent;
+
+	SoupRequestPrivate *priv;
+};
+
+struct _SoupRequestClass {
+	GObjectClass parent;
+
+	gboolean       (*check_uri)   (SoupRequest          *req_base,
+				       SoupURI              *uri,
+				       GError              **error);
 
-	/* methods */
 	GInputStream * (*send)        (SoupRequest          *request,
 				       GCancellable         *cancellable,
 				       GError              **error);
@@ -32,7 +44,7 @@ typedef struct {
 	GInputStream * (*send_finish) (SoupRequest          *request,
 				       GAsyncResult         *result,
 				       GError              **error);
-} SoupRequestInterface;
+};
 
 GType soup_request_get_type (void);
 
@@ -50,6 +62,9 @@ GInputStream *soup_request_send_finish (SoupRequest          *request,
 					GAsyncResult         *result,
 					GError              **error);
 
+SoupURI      *soup_request_get_uri     (SoupRequest          *request);
+SoupSession  *soup_request_get_session (SoupRequest          *request);
+
 G_END_DECLS
 
 #endif /* SOUP_REQUEST_H */
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index 0cec47b..34c9bd5 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -30,6 +30,7 @@
 #include "soup-request-data.h"
 #include "soup-request-file.h"
 #include "soup-request-ftp.h"
+#include "soup-request-http.h"
 #include "soup-session.h"
 #include "soup-session-feature.h"
 #include "soup-session-private.h"
@@ -1996,15 +1997,15 @@ init_request_types (SoupSessionPrivate *priv)
 	priv->request_types = g_hash_table_new_full (soup_str_case_hash,
 						     soup_str_case_equal,
 						     g_free, NULL);
-	g_hash_table_insert (priv->request_types, "file",
+	g_hash_table_insert (priv->request_types, g_strdup ("file"),
 			     GSIZE_TO_POINTER (SOUP_TYPE_REQUEST_FILE));
-	g_hash_table_insert (priv->request_types, "data",
+	g_hash_table_insert (priv->request_types, g_strdup ("data"),
 			     GSIZE_TO_POINTER (SOUP_TYPE_REQUEST_DATA));
-	g_hash_table_insert (priv->request_types, "http",
-			     GSIZE_TO_POINTER (SOUP_TYPE_MESSAGE));
-	g_hash_table_insert (priv->request_types, "https",
-			     GSIZE_TO_POINTER (SOUP_TYPE_MESSAGE));
-	g_hash_table_insert (priv->request_types, "ftp",
+	g_hash_table_insert (priv->request_types, g_strdup ("http"),
+			     GSIZE_TO_POINTER (SOUP_TYPE_REQUEST_HTTP));
+	g_hash_table_insert (priv->request_types, g_strdup ("https"),
+			     GSIZE_TO_POINTER (SOUP_TYPE_REQUEST_HTTP));
+	g_hash_table_insert (priv->request_types, g_strdup ("ftp"),
 			     GSIZE_TO_POINTER (SOUP_TYPE_REQUEST_FTP));
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]