コード例 #1
0
ファイル: hsts.c プロジェクト: vlampreia/vimb
/**
 * Change scheme and port of soup messages uri if the host is a known and
 * valid hsts host.
 *
 * This logic should be implemented in request_queued function but the changes
 * that are done there to the uri do not appear in webkit_web_view_get_uri().
 * If a valid hsts host is requested via http and the url is changed to https
 * vimb would still show the http uri in url bar. This seems to be a
 * missbehaviour in webkit, but for now we provide this function to put in the
 * logic in the scope of the navigation-policy-decision-requested event of the
 * webview.
 *
 * Returns newly allocated string with new URI if the URI was change to
 * fullfill HSTS, else NULL.
 */
char *hsts_get_changed_uri(SoupSession* session, SoupMessage *msg)
{
    SoupSessionFeature *feature;
    HSTSProvider *provider;
    SoupURI *uri;

    if (!msg) {
        return NULL;
    }

    feature = soup_session_get_feature_for_message(session, HSTS_TYPE_PROVIDER, msg);
    uri     = soup_message_get_uri(msg);
    if (!feature || !uri) {
        return NULL;
    }

    provider = HSTS_PROVIDER(feature);
    /* if URI uses still https we don't nee to rewrite it */
    if (uri->scheme != SOUP_URI_SCHEME_HTTPS
        && should_secure_host(provider, uri->host)
    ) {
        /* the ports is set by soup uri if scheme is changed */
        soup_uri_set_scheme(uri, SOUP_URI_SCHEME_HTTPS);
        return soup_uri_to_string(uri, false);
    }
    return NULL;
}
コード例 #2
0
static void
run_queue (SoupSessionAsync *sa)
{
	SoupSession *session = SOUP_SESSION (sa);
	SoupMessageQueue *queue = soup_session_get_queue (session);
	SoupMessageQueueItem *item;
	SoupProxyURIResolver *proxy_resolver;
	SoupMessage *msg;
	SoupConnection *conn;
	gboolean try_pruning = TRUE, should_prune = FALSE;

	soup_session_cleanup_connections (session, FALSE);

 try_again:
	for (item = soup_message_queue_first (queue);
	     item && !should_prune;
	     item = soup_message_queue_next (queue, item)) {
		msg = item->msg;

		/* CONNECT messages are handled specially */
		if (msg->method == SOUP_METHOD_CONNECT)
			continue;

		if (soup_message_io_in_progress (msg))
			continue;

		if (!item->resolved_proxy_addr) {
			proxy_resolver = (SoupProxyURIResolver *)soup_session_get_feature_for_message (session, SOUP_TYPE_PROXY_URI_RESOLVER, msg);
			if (proxy_resolver) {
				resolve_proxy_addr (item, proxy_resolver);
				continue;
			} else
				item->resolved_proxy_addr = TRUE;
		}

		conn = soup_session_get_connection (session, item,
						    &should_prune);
		if (!conn)
			continue;

		if (soup_connection_get_state (conn) == SOUP_CONNECTION_NEW) {
			soup_connection_connect_async (conn, got_connection,
						       session);
		} else
			soup_session_send_queue_item (session, item, conn);
	}
	if (item)
		soup_message_queue_item_unref (item);

	if (try_pruning && should_prune) {
		/* There is at least one message in the queue that
		 * could be sent if we pruned an idle connection from
		 * some other server.
		 */
		if (soup_session_cleanup_connections (session, TRUE)) {
			try_pruning = should_prune = FALSE;
			goto try_again;
		}
	}
}
コード例 #3
0
static void
conditional_get_ready_cb (SoupSession *session, SoupMessage *msg, gpointer user_data)
{
	ConditionalHelper *helper = (ConditionalHelper *)user_data;
	GSimpleAsyncResult *simple;
	SoupHTTPInputStream *httpstream;

	simple = g_simple_async_result_new (G_OBJECT (helper->req),
					    helper->callback, helper->user_data,
					    conditional_get_ready_cb);

	if (msg->status_code == SOUP_STATUS_NOT_MODIFIED) {
		SoupCache *cache = (SoupCache *)soup_session_get_feature (session, SOUP_TYPE_CACHE);

		httpstream = (SoupHTTPInputStream *)soup_cache_send_response (cache, msg);
		if (httpstream) {
			g_simple_async_result_set_op_res_gpointer (simple, httpstream, g_object_unref);

			soup_message_got_headers (helper->original);

			if (soup_session_get_feature_for_message (session, SOUP_TYPE_CONTENT_SNIFFER, helper->original)) {
			 	const char *content_type = soup_message_headers_get_content_type (msg->response_headers, NULL);
			 	soup_message_content_sniffed (helper->original, content_type, NULL);
			}

			g_simple_async_result_complete (simple);

			soup_message_finished (helper->original);

			g_object_unref (simple);
		} else {
			/* Ask again for the resource, somehow the cache cannot locate it */
			httpstream = soup_http_input_stream_new (session, helper->original);
			soup_http_input_stream_send_async (httpstream, G_PRIORITY_DEFAULT,
							   helper->cancellable, sent_async, simple);
		}
	} else {
		/* It is in the cache but it was modified remotely */
		httpstream = soup_http_input_stream_new (session, helper->original);
		soup_http_input_stream_send_async (httpstream, G_PRIORITY_DEFAULT,
						   helper->cancellable, sent_async, simple);
	}

	g_object_unref (helper->req);
	g_object_unref (helper->original);
	g_slice_free (ConditionalHelper, helper);
}
コード例 #4
0
ファイル: hsts.c プロジェクト: hirkmt/vimb
/**
 * Change scheme and port of soup messages uri if the host is a known and
 * valid hsts host.
 * This logic should be implemented in request_queued function but the changes
 * that are done there to the uri do not appear in webkit_web_view_get_uri().
 * If a valid hsts host is requested via http and the url is changed to https
 * vimb would still show the http uri in url bar. This seems to be a
 * missbehaviour in webkit, but for now we provide this function to put in the
 * logic in the scope of the resource-request-starting event of the webview.
 */
void hsts_prepare_message(SoupSession* session, SoupMessage *msg)
{
    SoupSessionFeature *feature;
    HSTSProvider *provider;
    SoupURI *uri;

    feature = soup_session_get_feature_for_message(session, HSTS_TYPE_PROVIDER, msg);
    uri     = soup_message_get_uri(msg);
    if (!feature || !uri) {
        return;
    }

    provider = HSTS_PROVIDER(feature);
    if (should_secure_host(provider, uri->host)) {
        /* the ports is set by soup uri if scheme is changed */
        soup_uri_set_scheme(uri, SOUP_URI_SCHEME_HTTPS);
    }
}
コード例 #5
0
ファイル: soup-session-async.c プロジェクト: BabaNina/libsoup
static void
auth_required (SoupSession *session, SoupMessage *msg,
	       SoupAuth *auth, gboolean retrying)
{
	SoupSessionFeature *password_manager;

	password_manager = soup_session_get_feature_for_message (
		session, SOUP_TYPE_PASSWORD_MANAGER, msg);
	if (password_manager) {
		soup_session_pause_message (session, msg);
		g_object_ref (auth);
		soup_password_manager_get_passwords_async (
			SOUP_PASSWORD_MANAGER (password_manager),
			msg, auth, retrying,
			soup_session_get_async_context (session),
			NULL, /* FIXME cancellable */
			got_passwords, session);
	} else {
		SOUP_SESSION_CLASS (soup_session_async_parent_class)->
			auth_required (session, msg, auth, retrying);
	}
}
コード例 #6
0
static gboolean
send_async_cb (gpointer data)
{
	GSimpleAsyncResult *simple;
	SoupSession *session;
	SendAsyncHelper *helper = (SendAsyncHelper *)data;

	session = soup_request_get_session (SOUP_REQUEST (helper->http));
	simple = g_simple_async_result_new (G_OBJECT (helper->http),
					    helper->callback, helper->user_data,
					    soup_request_http_send_async);

	g_simple_async_result_set_op_res_gpointer (simple, helper->httpstream, g_object_unref);

	/* Update message status */
	soup_message_set_status (helper->http->priv->msg, SOUP_STATUS_OK);

	/* Issue signals  */
	soup_message_got_headers (helper->http->priv->msg);

	if (soup_session_get_feature_for_message (session, SOUP_TYPE_CONTENT_SNIFFER, helper->http->priv->msg)) {
		const char *content_type = soup_message_headers_get_content_type (helper->http->priv->msg->response_headers, NULL);
		soup_message_content_sniffed (helper->http->priv->msg, content_type, NULL);
	}

	g_simple_async_result_complete (simple);

	soup_message_finished (helper->http->priv->msg);

	g_object_unref (simple);

	g_object_unref (helper->http);
	g_slice_free (SendAsyncHelper, helper);

	return FALSE;
}
コード例 #7
0
ファイル: soup-session-async.c プロジェクト: BabaNina/libsoup
static void
process_queue_item (SoupMessageQueueItem *item,
		    gboolean             *should_prune,
		    gboolean              loop)
{
	SoupSession *session = item->session;
	SoupProxyURIResolver *proxy_resolver;

	do {
		switch (item->state) {
		case SOUP_MESSAGE_STARTING:
			proxy_resolver = (SoupProxyURIResolver *)soup_session_get_feature_for_message (session, SOUP_TYPE_PROXY_URI_RESOLVER, item->msg);
			if (!proxy_resolver) {
				item->state = SOUP_MESSAGE_AWAITING_CONNECTION;
				break;
			}
			resolve_proxy_addr (item, proxy_resolver);
			return;

		case SOUP_MESSAGE_AWAITING_CONNECTION:
			if (!soup_session_get_connection (session, item, should_prune))
				return;

			if (soup_connection_get_state (item->conn) != SOUP_CONNECTION_NEW) {
				item->state = SOUP_MESSAGE_READY;
				break;
			}

			item->state = SOUP_MESSAGE_CONNECTING;
			soup_message_queue_item_ref (item);
			g_object_ref (session);
			soup_connection_connect_async (item->conn, item->cancellable,
						       got_connection, item);
			return;

		case SOUP_MESSAGE_READY:
			item->state = SOUP_MESSAGE_RUNNING;
			soup_session_send_queue_item (session, item, message_completed);
			break;

		case SOUP_MESSAGE_RESTARTING:
			item->state = SOUP_MESSAGE_STARTING;
			soup_message_restarted (item->msg);
			break;

		case SOUP_MESSAGE_FINISHING:
			item->state = SOUP_MESSAGE_FINISHED;
			soup_message_finished (item->msg);
			if (item->state != SOUP_MESSAGE_FINISHED)
				break;

			g_object_ref (session);
			soup_session_unqueue_item (session, item);
			if (item->callback)
				item->callback (session, item->msg, item->callback_data);
			g_object_unref (item->msg);
			do_idle_run_queue (session);
			g_object_unref (session);
			return;

		default:
			/* Nothing to do with this message in any
			 * other state.
			 */
			return;
		}
	} while (loop && item->state != SOUP_MESSAGE_FINISHED);
}