+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),
* 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)
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);
* @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,
* @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
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);
* 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");
*
* 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);
/* 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;
}
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*/