new macro to check if a URI is a valid http or https URI.
authorDan Winship <danw@src.gnome.org>
Mon, 25 Aug 2008 13:53:41 +0000 (13:53 +0000)
committerDan Winship <danw@src.gnome.org>
Mon, 25 Aug 2008 13:53:41 +0000 (13:53 +0000)
* libsoup/soup-uri.h (SOUP_URI_VALID_FOR_HTTP): new macro to check
if a URI is a valid http or https URI.

* libsoup/soup-uri.c (soup_uri_new_with_base): Update http/https
check to use SOUP_URI_VALID_FOR_HTTP().

* libsoup/soup-session.c (redirect_handler): Check
SOUP_URI_VALID_FOR_HTTP() and call it an error if the check fails.

* libsoup/soup-message.c (soup_message_new): Remove the uri->host
check from here. Update docs to clarify that @uri must be an
http/https URI.
(soup_message_new_from_uri): Check SOUP_URI_VALID_FOR_HTTP().
Update docs.
(soup_message_set_uri): Check SOUP_URI_VALID_FOR_HTTP(). Update
docs.

Should prevent the crash in #528882, but there's still something
going wrong there at a higher level.

svn path=/trunk/; revision=1155

ChangeLog
libsoup/soup-message.c
libsoup/soup-session.c
libsoup/soup-uri.c
libsoup/soup-uri.h

index 696f2be..e06258b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2008-08-25  Dan Winship  <danw@gnome.org>
+
+       * libsoup/soup-uri.h (SOUP_URI_VALID_FOR_HTTP): new macro to check
+       if a URI is a valid http or https URI.
+
+       * libsoup/soup-uri.c (soup_uri_new_with_base): Update http/https
+       check to use SOUP_URI_VALID_FOR_HTTP().
+
+       * libsoup/soup-session.c (redirect_handler): Check
+       SOUP_URI_VALID_FOR_HTTP() and call it an error if the check fails.
+
+       * libsoup/soup-message.c (soup_message_new): Remove the uri->host
+       check from here. Update docs to clarify that @uri must be an
+       http/https URI.
+       (soup_message_new_from_uri): Check SOUP_URI_VALID_FOR_HTTP().
+       Update docs.
+       (soup_message_set_uri): Check SOUP_URI_VALID_FOR_HTTP(). Update
+       docs.
+
+       Should prevent the crash in #528882, but there's still something
+       going wrong there at a higher level.
+
 2008-08-22  Bastien Nocera  <hadess@hadess.net>
 
        * libsoup/soup-date.c (soup_date_to_time_t),
index c5890ce..4c6aebb 100644 (file)
@@ -554,7 +554,7 @@ get_property (GObject *object, guint prop_id,
  * Creates a new empty #SoupMessage, which will connect to @uri
  *
  * Return value: the new #SoupMessage (or %NULL if @uri could not
- * be parsed).
+ * be parsed or is not a valid HTTP/HTTPS URI).
  */
 SoupMessage *
 soup_message_new (const char *method, const char *uri_string)
@@ -568,10 +568,6 @@ soup_message_new (const char *method, const char *uri_string)
        uri = soup_uri_new (uri_string);
        if (!uri)
                return NULL;
-       if (!uri->host) {
-               soup_uri_free (uri);
-               return NULL;
-       }
 
        msg = soup_message_new_from_uri (method, uri);
        soup_uri_free (uri);
@@ -583,13 +579,20 @@ soup_message_new (const char *method, const char *uri_string)
  * @method: the HTTP method for the created request
  * @uri: the destination endpoint (as a #SoupURI)
  * 
- * Creates a new empty #SoupMessage, which will connect to @uri
+ * Creates a new empty #SoupMessage, which will connect to @uri.
  *
- * Return value: the new #SoupMessage
+ * Return value: the new #SoupMessage (or %NULL if @uri is not a
+ * valid HTTP/HTTPS URI)
  */
 SoupMessage *
 soup_message_new_from_uri (const char *method, SoupURI *uri)
 {
+       g_return_val_if_fail (method != NULL, NULL);
+       g_return_val_if_fail (uri != NULL, NULL);
+
+       if (!SOUP_URI_VALID_FOR_HTTP (uri))
+               return NULL;
+
        return g_object_new (SOUP_TYPE_MESSAGE,
                             SOUP_MESSAGE_METHOD, method,
                             SOUP_MESSAGE_URI, uri,
@@ -1266,8 +1269,9 @@ soup_message_is_keepalive (SoupMessage *msg)
  * @msg: a #SoupMessage
  * @uri: the new #SoupURI
  *
- * Sets @msg's URI to @uri. If @msg has already been sent and you want
- * to re-send it with the new URI, you need to call
+ * Sets @msg's URI to @uri, which must be a valid HTTP/HTTPS URI (per
+ * SOUP_URI_VALID_FOR_HTTP()). If @msg has already been sent and you
+ * want to re-send it with the new URI, you need to call
  * soup_session_requeue_message().
  **/
 void
@@ -1276,8 +1280,9 @@ soup_message_set_uri (SoupMessage *msg, SoupURI *uri)
        SoupMessagePrivate *priv;
 
        g_return_if_fail (SOUP_IS_MESSAGE (msg));
-       priv = SOUP_MESSAGE_GET_PRIVATE (msg);
+       g_return_if_fail (SOUP_URI_VALID_FOR_HTTP (uri));
 
+       priv = SOUP_MESSAGE_GET_PRIVATE (msg);
        if (priv->uri)
                soup_uri_free (priv->uri);
        priv->uri = soup_uri_copy (uri);
index dfedb78..1d69646 100644 (file)
@@ -815,7 +815,9 @@ redirect_handler (SoupMessage *msg, gpointer user_data)
         * are lame, so we use soup_uri_new_with_base().
         */
        new_uri = soup_uri_new_with_base (soup_message_get_uri (msg), new_loc);
-       if (!new_uri) {
+       if (!SOUP_URI_VALID_FOR_HTTP (new_uri)) {
+               if (new_uri)
+                       soup_uri_free (new_uri);
                soup_message_set_status_full (msg,
                                              SOUP_STATUS_MALFORMED,
                                              "Invalid Redirect URL");
index 5091fe2..4ecf931 100644 (file)
@@ -38,7 +38,9 @@
  *
  * A #SoupURI represents a (parsed) URI. #SoupURI supports RFC 3986
  * (URI Generic Syntax), and can parse any valid URI. However, libsoup
- * only uses "http" and "https" URIs internally.
+ * only uses "http" and "https" URIs internally; You can use
+ * SOUP_URI_VALID_FOR_HTTP() to test if a #SoupURI is a valid HTTP
+ * URI.
  *
  * @scheme will always be set in any URI. It is an interned string and
  * is always all lowercase. (If you parse a URI with a non-lowercase
  * as well, but this would be more annoying than useful.)
  **/
 
+/**
+ * SOUP_URI_VALID_FOR_HTTP:
+ * @uri: a #SoupURI
+ *
+ * Tests if @uri is a valid #SoupURI for HTTP communication; that is, if
+ * it can be used to construct a #SoupMessage.
+ *
+ * Return value: %TRUE if @uri is a valid "http" or "https" URI.
+ **/
+
 static void append_uri_encoded (GString *str, const char *in, const char *extra_enc_chars);
 static char *uri_decoded_copy (const char *str, int length);
 static char *uri_normalized_copy (const char *str, int length, const char *unescape_extra);
@@ -337,7 +349,7 @@ soup_uri_new_with_base (SoupURI *base, const char *uri_string)
        /* HTTP-specific stuff */
        if (uri->scheme == SOUP_URI_SCHEME_HTTP ||
            uri->scheme == SOUP_URI_SCHEME_HTTPS) {
-               if (!uri->host) {
+               if (!SOUP_URI_VALID_FOR_HTTP (uri)) {
                        soup_uri_free (uri);
                        return NULL;
                }
index 551ad54..3a5c8dd 100644 (file)
@@ -78,6 +78,8 @@ void      soup_uri_set_query_from_fields (SoupURI    *uri,
 void      soup_uri_set_fragment          (SoupURI    *uri,
                                          const char *fragment);
 
+#define   SOUP_URI_VALID_FOR_HTTP(uri) ((uri) && ((uri)->scheme == SOUP_URI_SCHEME_HTTP || (uri)->scheme == SOUP_URI_SCHEME_HTTPS) && (uri)->host)
+
 G_END_DECLS
 
 #endif /*SOUP_URI_H*/