Example #1
0
SoupURI* ResourceRequest::soupURI() const
{
    // WebKit does not support fragment identifiers in data URLs, but soup does.
    // Before passing the URL to soup, we should make sure to urlencode any '#'
    // characters, so that soup does not interpret them as fragment identifiers.
    // See http://wkbug.com/68089
    if (m_url.protocolIsData()) {
        String urlString = m_url.string();
        urlString.replace("#", "%23");
        return soup_uri_new(urlString.utf8().data());
    }

    KURL url = m_url;
    url.removeFragmentIdentifier();
    SoupURI* uri = soup_uri_new(url.string().utf8().data());

    // Versions of libsoup prior to 2.42 have a soup_uri_new that will convert empty passwords that are not
    // prefixed by a colon into null. Some parts of soup like the SoupAuthenticationManager will only be active
    // when both the username and password are non-null. When we have credentials, empty usernames and passwords
    // should be empty strings instead of null.
    if (!url.user().isEmpty() || !url.pass().isEmpty()) {
        soup_uri_set_user(uri, url.user().utf8().data());
        soup_uri_set_password(uri, url.pass().utf8().data());
    }
    return uri;
}
Example #2
0
static void 
seahorse_hkp_operation_init (SeahorseHKPOperation *hop)
{
    SoupURI *uri;
    gchar *host;
#if DEBUG_HKP_ENABLE
    SoupLogger *logger;
#endif
    
    if (seahorse_gconf_get_boolean (GCONF_USE_HTTP_PROXY)) {
        
        host = seahorse_gconf_get_string (GCONF_HTTP_PROXY_HOST);
        if (host) {
            uri = soup_uri_new (NULL);
            
            if (!uri) {
                g_warning ("creation of SoupURI from '%s' failed", host);
                
            } else {

                soup_uri_set_scheme (uri, SOUP_URI_SCHEME_HTTP);
                soup_uri_set_host (uri, host);
                g_free (host);
                soup_uri_set_port (uri, seahorse_gconf_get_integer (GCONF_PROXY_PORT));
                
                if (seahorse_gconf_get_boolean (GCONF_USE_AUTH)) {
                    char *user, *pass;

                    user = seahorse_gconf_get_string (GCONF_AUTH_USER);
                    soup_uri_set_user (uri, user);
                    g_free (user);
                    pass = seahorse_gconf_get_string (GCONF_AUTH_PASS);
                    soup_uri_set_password (uri, pass);
                    g_free (pass);
                }
                
                hop->session = soup_session_async_new_with_options (SOUP_SESSION_PROXY_URI, uri, NULL);
                soup_uri_free (uri);
            }
        }
    }
    
    /* Without a proxy */
    if (!hop->session)
        hop->session = soup_session_async_new ();

#if DEBUG_HKP_ENABLE
    logger = soup_logger_new (SOUP_LOGGER_LOG_BODY, -1);
    soup_logger_attach (logger, hop->session);
    g_object_unref (logger);
#endif
}
Example #3
0
static SoupURI *
network_get_proxy_uri (void)
{
	SoupURI *uri = NULL;
	
	if (!proxyname)
		return uri;
		
	uri = soup_uri_new (NULL);
	soup_uri_set_scheme (uri, SOUP_URI_SCHEME_HTTP);
	soup_uri_set_host (uri, proxyname);
	soup_uri_set_port (uri, proxyport);
	soup_uri_set_user (uri, proxyusername);
	soup_uri_set_password (uri, proxypassword);

	return uri;
}
Example #4
0
static void
liferea_webkit_set_proxy (const gchar *host, guint port, const gchar *user, const gchar *pwd)
{
	SoupURI *proxy = NULL;

	if (host) {
		proxy = soup_uri_new (NULL);
		soup_uri_set_scheme (proxy, SOUP_URI_SCHEME_HTTP);
		soup_uri_set_host (proxy, host);
		soup_uri_set_port (proxy, port);
		soup_uri_set_user (proxy, user);
		soup_uri_set_password (proxy, pwd);
	}

	g_object_set (webkit_get_default_session (),
		      SOUP_SESSION_PROXY_URI, proxy,
		      NULL);
}
static guint
get_proxy_for_uri (SoupURI *uri, SoupURI **proxy_uri)
{
	char *uristr, **proxies;
	gboolean got_proxy;
	int i;

	*proxy_uri = NULL;

	/* resolver_gnome is locked */

	uristr = soup_uri_to_string (uri, FALSE);
	proxies = px_proxy_factory_get_proxies (libproxy_factory, uristr);
	g_free (uristr);

	if (!proxies)
		return SOUP_STATUS_OK;

	got_proxy = FALSE;
	for (i = 0; proxies[i]; i++) {
		if (!strcmp (proxies[i], "direct://")) {
			got_proxy = TRUE;
			break;
		}
		if (strncmp (proxies[i], "http://", 7) == 0) {
			*proxy_uri = soup_uri_new (proxies[i]);
			got_proxy = TRUE;
			break;
		}
	}
	for (i = 0; proxies[i]; i++)
		free (proxies[i]);
	free (proxies);

	if (got_proxy) {
		if (*proxy_uri && proxy_user) {
			soup_uri_set_user (*proxy_uri, proxy_user);
			soup_uri_set_password (*proxy_uri, proxy_password);
		}

		return SOUP_STATUS_OK;
	} else
		return SOUP_STATUS_CANT_RESOLVE_PROXY;
}
Example #6
0
static void
do_message_do_not_use_auth_cache_test (void)
{
	SoupSession *session;
	SoupAuthManager *manager;
	SoupURI *soup_uri;
	char *uri;
	char *uri_with_credentials;

	SOUP_TEST_SKIP_IF_NO_APACHE;

	session = soup_test_session_new (SOUP_TYPE_SESSION, NULL);

	uri = g_strconcat (base_uri, "Digest/realm1/", NULL);

	/* First check that cached credentials are not used */
	do_digest_nonce_test (session, "First", uri, TRUE, TRUE, TRUE);
	do_digest_nonce_test (session, "Second", uri, TRUE, FALSE, FALSE);
	do_digest_nonce_test (session, "Third", uri, FALSE, TRUE, TRUE);

	/* Passing credentials in the URI should always authenticate
	 * no matter whether the cache is used or not
	 */
	soup_uri = soup_uri_new (uri);
	soup_uri_set_user (soup_uri, "user1");
	soup_uri_set_password (soup_uri, "realm1");
	uri_with_credentials = soup_uri_to_string (soup_uri, FALSE);
	soup_uri_free (soup_uri);
	do_digest_nonce_test (session, "Fourth", uri_with_credentials, FALSE, TRUE, FALSE);
	g_free (uri_with_credentials);

	manager = SOUP_AUTH_MANAGER (soup_session_get_feature (session, SOUP_TYPE_AUTH_MANAGER));
	soup_auth_manager_clear_cached_credentials (manager);

	/* Now check that credentials are not stored */
	do_digest_nonce_test (session, "First", uri, FALSE, TRUE, TRUE);
	do_digest_nonce_test (session, "Second", uri, TRUE, TRUE, TRUE);
	do_digest_nonce_test (session, "Third", uri, TRUE, FALSE, FALSE);
	g_free (uri);

	soup_test_session_abort_unref (session);
}
static void
authenticate_auth (SoupAuthManager *manager, SoupAuth *auth,
		   SoupMessage *msg, gboolean prior_auth_failed,
		   gboolean proxy, gboolean can_interact)
{
	SoupAuthManagerPrivate *priv = manager->priv;
	SoupURI *uri;

	if (proxy) {
		SoupMessageQueue *queue;
		SoupMessageQueueItem *item;

		queue = soup_session_get_queue (priv->session);
		item = soup_message_queue_lookup (queue, msg);
		if (item) {
			uri = soup_connection_get_proxy_uri (item->conn);
			soup_message_queue_item_unref (item);
		} else
			uri = NULL;

		if (!uri)
			return;
	} else
		uri = soup_message_get_uri (msg);

	/* If a password is specified explicitly in the URI, use it
	 * even if the auth had previously already been authenticated.
	 */
	if (uri->password && uri->user) {
		soup_auth_authenticate (auth, uri->user, uri->password);
		soup_uri_set_password (uri, NULL);
		soup_uri_set_user (uri, NULL);
	} else if (!soup_auth_is_authenticated (auth) && can_interact) {
		g_signal_emit (manager, signals[AUTHENTICATE], 0,
			       msg, auth, prior_auth_failed);
	}
}
Example #8
0
static void
network_set_soup_session_proxy (SoupSession *session, ProxyDetectMode mode, const gchar *host, guint port, const gchar *user, const gchar *password)
{
	SoupURI *uri = NULL;

	switch (mode) {
		case PROXY_DETECT_MODE_AUTO:
			/* Sets proxy-resolver to the default resolver, this unsets proxy-uri. */
			g_object_set (G_OBJECT (session),
				SOUP_SESSION_PROXY_RESOLVER, g_proxy_resolver_get_default (),
				NULL);
			break;
		case PROXY_DETECT_MODE_NONE:
			/* Sets proxy-resolver to NULL, this unsets proxy-uri. */
			g_object_set (G_OBJECT (session),
				SOUP_SESSION_PROXY_RESOLVER, NULL,
				NULL);
			break;
		case PROXY_DETECT_MODE_MANUAL:
			uri = soup_uri_new (NULL);
			soup_uri_set_scheme (uri, SOUP_URI_SCHEME_HTTP);
			soup_uri_set_host (uri, host);
			soup_uri_set_port (uri, port);
			soup_uri_set_user (uri, user);
			soup_uri_set_password (uri, password);
			soup_uri_set_path (uri, "/");

			if (SOUP_URI_IS_VALID (uri)) {
				/* Sets proxy-uri, this unsets proxy-resolver. */
				g_object_set (G_OBJECT (session),
					SOUP_SESSION_PROXY_URI, uri,
					NULL);
			}
			soup_uri_free (uri);
			break;
	}
}
Example #9
0
static void
do_batch_tests (const gchar *base_uri_str, gint ntests)
{
	SoupSession *session;
	SoupMessage *msg;
	char *expected;
	SoupURI *base_uri;
	int i;

	session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
	g_signal_connect (session, "authenticate",
			  G_CALLBACK (authenticate), &i);

	base_uri = soup_uri_new (base_uri_str);

	for (i = 0; i < ntests; i++) {
		SoupURI *soup_uri = soup_uri_new_with_base (base_uri, current_tests[i].url);

		debug_printf (1, "Test %d: %s\n", i + 1, current_tests[i].explanation);

		if (current_tests[i].url_auth) {
			gchar *username = g_strdup_printf ("user%c", current_tests[i].provided[0]);
			gchar *password = g_strdup_printf ("realm%c", current_tests[i].provided[0]);
			soup_uri_set_user (soup_uri, username);
			soup_uri_set_password (soup_uri, password);
			g_free (username);
			g_free (password);
		}

		msg = soup_message_new_from_uri (SOUP_METHOD_GET, soup_uri);
		soup_uri_free (soup_uri);
		if (!msg) {
			fprintf (stderr, "auth-test: Could not parse URI\n");
			exit (1);
		}

		debug_printf (1, "  GET %s\n", soup_uri_to_string (soup_message_get_uri (msg), FALSE));

		expected = g_strdup (current_tests[i].expected);
		soup_message_add_status_code_handler (
			msg, "got_headers", SOUP_STATUS_UNAUTHORIZED,
			G_CALLBACK (handler), expected);
		soup_message_add_status_code_handler (
			msg, "got_headers", SOUP_STATUS_OK,
			G_CALLBACK (handler), expected);
		soup_session_send_message (session, msg);
		if (msg->status_code != SOUP_STATUS_UNAUTHORIZED &&
		    msg->status_code != SOUP_STATUS_OK) {
			debug_printf (1, "  %d %s !\n", msg->status_code,
				      msg->reason_phrase);
			errors++;
		}
		if (*expected) {
			debug_printf (1, "  expected %d more round(s)\n",
				      (int)strlen (expected));
			errors++;
		}
		g_free (expected);

		if (msg->status_code != current_tests[i].final_status) {
			debug_printf (1, "  expected %d\n",
				      current_tests[i].final_status);
		}

		debug_printf (1, "\n");

		g_object_unref (msg);
	}
	soup_uri_free (base_uri);

	soup_test_session_abort_unref (session);
}
Example #10
0
static void
do_batch_tests (gconstpointer data)
{
	const SoupAuthTest *current_tests = data;
	SoupSession *session;
	SoupMessage *msg;
	char *expected, *uristr;
	SoupURI *base;
	guint signal;
	int i;

	SOUP_TEST_SKIP_IF_NO_APACHE;

	session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
	base = soup_uri_new (base_uri);

	for (i = 0; current_tests[i].url; i++) {
		SoupURI *soup_uri = soup_uri_new_with_base (base, current_tests[i].url);

		debug_printf (1, "Test %d: %s\n", i + 1, current_tests[i].explanation);

		if (current_tests[i].url_auth) {
			gchar *username = g_strdup_printf ("user%c", current_tests[i].provided[0]);
			gchar *password = g_strdup_printf ("realm%c", current_tests[i].provided[0]);
			soup_uri_set_user (soup_uri, username);
			soup_uri_set_password (soup_uri, password);
			g_free (username);
			g_free (password);
		}

		msg = soup_message_new_from_uri (SOUP_METHOD_GET, soup_uri);
		soup_uri_free (soup_uri);
		if (!msg) {
			g_printerr ("auth-test: Could not parse URI\n");
			exit (1);
		}

		uristr = soup_uri_to_string (soup_message_get_uri (msg), FALSE);
		debug_printf (1, "  GET %s\n", uristr);
		g_free (uristr);

		expected = g_strdup (current_tests[i].expected);
		soup_message_add_status_code_handler (
			msg, "got_headers", SOUP_STATUS_UNAUTHORIZED,
			G_CALLBACK (handler), expected);
		soup_message_add_status_code_handler (
			msg, "got_headers", SOUP_STATUS_OK,
			G_CALLBACK (handler), expected);

		signal = g_signal_connect (session, "authenticate",
					   G_CALLBACK (authenticate),
					   (gpointer)&current_tests[i]);
		soup_session_send_message (session, msg);
		g_signal_handler_disconnect (session, signal);

		soup_test_assert_message_status (msg, current_tests[i].final_status);
		soup_test_assert (!*expected,
				  "expected %d more round(s)\n",
				  (int)strlen (expected));

		g_free (expected);
		debug_printf (1, "\n");

		g_object_unref (msg);
	}
	soup_uri_free (base);

	soup_test_session_abort_unref (session);
}
Example #11
0
static SoupURI *
fwupd_remote_build_uri (FwupdRemote *self, const gchar *url, GError **error)
{
	FwupdRemotePrivate *priv = GET_PRIVATE (self);
	SoupURI *uri;

	g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
	g_return_val_if_fail (url != NULL, NULL);
	g_return_val_if_fail (error == NULL || *error == NULL, NULL);

	/* create URI, substituting if required */
	if (priv->firmware_base_uri != NULL) {
		g_autoptr(SoupURI) uri_tmp = NULL;
		g_autofree gchar *basename = NULL;
		g_autofree gchar *url2 = NULL;
		uri_tmp = soup_uri_new (url);
		if (uri_tmp == NULL) {
			g_set_error (error,
				     FWUPD_ERROR,
				     FWUPD_ERROR_INVALID_FILE,
				     "Failed to parse URI '%s'", url);
			return NULL;
		}
		basename = g_path_get_basename (soup_uri_get_path (uri_tmp));
		url2 = g_build_filename (priv->firmware_base_uri, basename, NULL);
		uri = soup_uri_new (url2);
		if (uri == NULL) {
			g_set_error (error,
				     FWUPD_ERROR,
				     FWUPD_ERROR_INVALID_FILE,
				     "Failed to parse URI '%s'", url2);
			return NULL;
		}

	/* use the base URI of the metadata to build the full path */
	} else if (g_strstr_len (url, -1, "/") == NULL) {
		g_autofree gchar *basename = NULL;
		g_autofree gchar *path = NULL;
		uri = soup_uri_new (priv->metadata_uri);
		if (uri == NULL) {
			g_set_error (error,
				     FWUPD_ERROR,
				     FWUPD_ERROR_INVALID_FILE,
				     "Failed to parse metadata URI '%s'", url);
			return NULL;
		}
		basename = g_path_get_dirname (soup_uri_get_path (uri));
		path = g_build_filename (basename, url, NULL);
		soup_uri_set_path (uri, path);

	/* a normal URI */
	} else {
		uri = soup_uri_new (url);
		if (uri == NULL) {
			g_set_error (error,
				     FWUPD_ERROR,
				     FWUPD_ERROR_INVALID_FILE,
				     "Failed to parse URI '%s'", url);
			return NULL;
		}
	}

	/* set the username and password */
	if (priv->username != NULL)
		soup_uri_set_user (uri, priv->username);
	if (priv->password != NULL)
		soup_uri_set_password (uri, priv->password);
	return uri;
}
Example #12
0
/* Downloads a feed specified in the request structure, returns 
   the downloaded data or NULL in the request structure.
   If the webserver reports a permanent redirection, the
   feed url will be modified and the old URL 'll be freed. The
   request structure will also contain the HTTP status and the
   last modified string.
 */
void
network_process_request (const updateJobPtr job)
{
	SoupMessage	*msg;
	SoupDate	*date;
	gboolean	do_not_track = FALSE;

	g_assert (NULL != job->request);
	debug1 (DEBUG_NET, "downloading %s", job->request->source);
	if (job->request->postdata && (debug_level & DEBUG_VERBOSE) && (debug_level & DEBUG_NET))
		debug1 (DEBUG_NET, "   postdata=>>>%s<<<", job->request->postdata);

	/* Prepare the SoupMessage */
	msg = soup_message_new (job->request->postdata ? SOUP_METHOD_POST : SOUP_METHOD_GET,
				job->request->source);

	if (!msg) {
		g_warning ("The request for %s could not be parsed!", job->request->source);
		return;
	}

	/* Set the postdata for the request */
	if (job->request->postdata) {
		soup_message_set_request (msg,
					  "application/x-www-form-urlencoded",
					  SOUP_MEMORY_STATIC, /* libsoup won't free the postdata */
					  job->request->postdata,
					  strlen (job->request->postdata));
	}

	/* Set the If-Modified-Since: header */
	if (job->request->updateState && update_state_get_lastmodified (job->request->updateState)) {
		gchar *datestr;

		date = soup_date_new_from_time_t (update_state_get_lastmodified (job->request->updateState));
		datestr = soup_date_to_string (date, SOUP_DATE_HTTP);
		soup_message_headers_append (msg->request_headers,
					     "If-Modified-Since",
					     datestr);
		g_free (datestr);
		soup_date_free (date);
	}

	/* Set the If-None-Match header */
	if (job->request->updateState && update_state_get_etag (job->request->updateState)) {
		soup_message_headers_append(msg->request_headers,
					    "If-None-Match",
					    update_state_get_etag (job->request->updateState));
	}

	/* Set the I-AM header */
	if (job->request->updateState &&
	    (update_state_get_lastmodified (job->request->updateState) ||
	     update_state_get_etag (job->request->updateState))) {
		soup_message_headers_append(msg->request_headers,
					    "A-IM",
					    "feed");
	}

	/* Support HTTP content negotiation */
	soup_message_headers_append(msg->request_headers, "Accept", "application/atom+xml,application/xml;q=0.9,text/xml;q=0.8,*/*;q=0.7");

	/* Set the authentication */
	if (!job->request->authValue &&
	    job->request->options &&
	    job->request->options->username &&
	    job->request->options->password) {
		SoupURI *uri = soup_message_get_uri (msg);
		
		soup_uri_set_user (uri, job->request->options->username);
		soup_uri_set_password (uri, job->request->options->password);
	}

	if (job->request->authValue) {
		soup_message_headers_append (msg->request_headers, "Authorization",
					     job->request->authValue);
	}

	/* Add requested cookies */
	if (job->request->updateState && job->request->updateState->cookies) {
		soup_message_headers_append (msg->request_headers, "Cookie",
		                             job->request->updateState->cookies);
		soup_message_disable_feature (msg, SOUP_TYPE_COOKIE_JAR);
	}

	/* TODO: Right now we send the msg, and if it requires authentication and
	 * we didn't provide one, the petition fails and when the job is processed
	 * it sees it needs authentication and displays a dialog, and if credentials
	 * are entered, it queues a new job with auth credentials. Instead of that,
	 * we should probably handle authentication directly here, connecting the
	 * msg to a callback in case of 401 (see soup_message_add_status_code_handler())
	 * displaying the dialog ourselves, and requeing the msg if we get credentials */

	/* Add Do Not Track header according to settings */
	conf_get_bool_value (DO_NOT_TRACK, &do_not_track);
	if (do_not_track)
		soup_message_headers_append (msg->request_headers, "DNT", "1");

	/* If the feed has "dont use a proxy" selected, use 'session2' which is non-proxy */
	if (job->request->options && job->request->options->dontUseProxy)
		soup_session_queue_message (session2, msg, network_process_callback, job);
	else
		soup_session_queue_message (session, msg, network_process_callback, job);
}
Example #13
0
/* Downloads a feed specified in the request structure, returns 
   the downloaded data or NULL in the request structure.
   If the the webserver reports a permanent redirection, the
   feed url will be modified and the old URL 'll be freed. The
   request structure will also contain the HTTP status and the
   last modified string.
 */
void
network_process_request (const updateJobPtr const job)
{
	SoupMessage	*msg;
	SoupDate	*date;

	g_assert (NULL != job->request);
	debug1 (DEBUG_NET, "downloading %s", job->request->source);

	/* Prepare the SoupMessage */
	msg = soup_message_new (job->request->postdata ? SOUP_METHOD_POST : SOUP_METHOD_GET,
				job->request->source);

	if (!msg) {
		g_warning ("The request for %s could not be parsed!", job->request->source);
		return;
	}

	/* Set the postdata for the request */
	if (job->request->postdata) {
		soup_message_set_request (msg,
					  "application/x-www-form-urlencoded",
					  SOUP_MEMORY_STATIC, /* libsoup won't free the postdata */
					  job->request->postdata,
					  strlen (job->request->postdata));
	}

	/* Set the If-Modified-Since: header */
	if (job->request->updateState && job->request->updateState->lastModified) {
		gchar *datestr;

		date = soup_date_new_from_time_t (job->request->updateState->lastModified);
		datestr = soup_date_to_string (date, SOUP_DATE_HTTP);
		soup_message_headers_append (msg->request_headers,
					     "If-Modified-Since",
					     datestr);
		g_free (datestr);
		soup_date_free (date);
	}

	/* Set the authentication */
	if (!job->request->authValue &&
	    job->request->options &&
	    job->request->options->username &&
	    job->request->options->password) {
		SoupURI *uri = soup_message_get_uri (msg);
		
		soup_uri_set_user (uri, job->request->options->username);
		soup_uri_set_password (uri, job->request->options->password);
	}

	if (job->request->authValue) {
		soup_message_headers_append (msg->request_headers, "Authorization",
					     job->request->authValue);
	}

	/* Add requested cookies */
	if (job->request->updateState && job->request->updateState->cookies) {
		soup_message_headers_append (msg->request_headers, "Cookie",
		                             job->request->updateState->cookies);
		soup_message_disable_feature (msg, SOUP_TYPE_COOKIE_JAR);
	}

	/* TODO: Right now we send the msg, and if it requires authentication and
	 * we didn't provide one, the petition fails and when the job is processed
	 * it sees it needs authentication and displays a dialog, and if credentials
	 * are entered, it queues a new job with auth credentials. Instead of that,
	 * we should probably handle authentication directly here, connecting the
	 * msg to a callback in case of 401 (see soup_message_add_status_code_handler())
	 * displaying the dialog ourselves, and requeing the msg if we get credentials */

	/* If the feed has "dont use a proxy" selected, disable the proxy for the msg */
	if ((job->request->options && job->request->options->dontUseProxy) ||
	    (network_get_proxy_host () == NULL))
		soup_message_disable_feature (msg, SOUP_TYPE_PROXY_URI_RESOLVER);

	soup_session_queue_message (session, msg, network_process_callback, job);
}