コード例 #1
0
static void
timeout_test_request_started (SoupSession *session, SoupMessage *msg,
			      SoupSocket *socket, gpointer user_data)
{
	SoupSocket **sockets = user_data;
	int i;

	debug_printf (2, "      msg %p => socket %p\n", msg, socket);
	for (i = 0; i < 4; i++) {
		if (!sockets[i]) {
			/* We ref the socket to make sure that even if
			 * it gets disconnected, it doesn't get freed,
			 * since our checks would get messed up if the
			 * slice allocator reused the same address for
			 * two consecutive sockets.
			 */
			sockets[i] = g_object_ref (socket);
			return;
		}
	}

	debug_printf (1, "      socket queue overflowed!\n");
	errors++;
	soup_session_cancel_message (session, msg, SOUP_STATUS_CANCELLED);
}
コード例 #2
0
ファイル: aws-s3-client.c プロジェクト: chergert/aws-glib
static void
aws_s3_client_read_got_chunk (SoupMessage *message,
                              SoupBuffer  *buffer,
                              GTask       *task)
{
  AwsS3Client *client;
  ReadState *state;

  g_assert (SOUP_IS_MESSAGE (message));
  g_assert (buffer != NULL);
  g_assert (G_IS_TASK (task));

  client = g_task_get_source_object (task);
  g_assert (AWS_IS_S3_CLIENT (client));

  state = g_task_get_task_data (task);
  g_assert (state != NULL);
  g_assert (state->handler != NULL);

  if (!state->handler (client, message, buffer, state->handler_data))
    {
      g_task_return_new_error (task,
                               G_IO_ERROR,
                               G_IO_ERROR_CANCELLED,
                               "The request was cancelled");
      soup_session_cancel_message (SOUP_SESSION (client), message, SOUP_STATUS_CANCELLED);
   }
}
コード例 #3
0
ファイル: soup-session.c プロジェクト: gcorvala/gsoc-2009
/**
 * soup_session_abort:
 * @session: the session
 *
 * Cancels all pending requests in @session.
 **/
void
soup_session_abort (SoupSession *session)
{
	SoupSessionPrivate *priv;
	SoupMessageQueueItem *item;
	GSList *conns, *c;

	g_return_if_fail (SOUP_IS_SESSION (session));
	priv = SOUP_SESSION_GET_PRIVATE (session);

	for (item = soup_message_queue_first (priv->queue);
	     item;
	     item = soup_message_queue_next (priv->queue, item)) {
		soup_session_cancel_message (session, item->msg,
					     SOUP_STATUS_CANCELLED);
	}

	/* Close all connections */
	g_mutex_lock (priv->host_lock);
	conns = NULL;
	g_hash_table_foreach (priv->conns, gather_conns, &conns);

	g_mutex_unlock (priv->host_lock);
	for (c = conns; c; c = c->next) {
		soup_connection_disconnect (c->data);
		g_object_unref (c->data);
	}

	g_slist_free (conns);
}
コード例 #4
0
static void
cancellable_cancelled_cb (GCancellable *cancellable,
                          gpointer user_data)
{
        GUPnPServiceInfo *info;
        GetSCPDURLData *data;
        SoupSession *session;
        GError *error;

        data = user_data;
        info = data->info;

        session = gupnp_context_get_session (info->priv->context);
        soup_session_cancel_message (session,
                                     data->message,
                                     SOUP_STATUS_CANCELLED);

        info->priv->pending_gets =
                g_list_remove (info->priv->pending_gets, data);

        error = g_error_new (G_IO_ERROR,
                             G_IO_ERROR_CANCELLED,
                             "The call was canceled");

        data->callback (data->info,
                        NULL,
                        error,
                        data->user_data);

        get_scpd_url_data_free (data);
}
コード例 #5
0
ファイル: soup-input-stream.c プロジェクト: Andais/gvfs
static gboolean
soup_input_stream_seek (GSeekable     *seekable,
			goffset        offset,
			GSeekType      type,
			GCancellable  *cancellable,
			GError       **error)
{
  GInputStream *stream = G_INPUT_STREAM (seekable);
  SoupInputStreamPrivate *priv = SOUP_INPUT_STREAM_GET_PRIVATE (seekable);
  char *range;

  if (type == G_SEEK_END)
    {
      /* FIXME: we could send "bytes=-offset", but unless we know the
       * Content-Length, we wouldn't be able to answer a tell() properly.
       * We could find the Content-Length by doing a HEAD...
       */

      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
	                   "G_SEEK_END not currently supported");
      return FALSE;
    }

  if (!g_input_stream_set_pending (stream, error))
      return FALSE;

  soup_session_cancel_message (priv->session, priv->msg, SOUP_STATUS_CANCELLED);
  soup_message_io_cleanup (priv->msg);

  switch (type)
    {
    case G_SEEK_CUR:
      offset += priv->offset;
      /* fall through */

    case G_SEEK_SET:
      range = g_strdup_printf ("bytes=%"G_GUINT64_FORMAT"-", (guint64)offset);
      priv->offset = offset;
      break;

    case G_SEEK_END:
      range = NULL; /* keep compilers happy */
      g_return_val_if_reached (FALSE);
      break;

    default:
      g_return_val_if_reached (FALSE);
    }

  soup_message_headers_remove (priv->msg->request_headers, "Range");
  soup_message_headers_append (priv->msg->request_headers, "Range", range);
  g_free (range);

  soup_input_stream_queue_message (SOUP_INPUT_STREAM (stream));

  g_input_stream_clear_pending (stream);
  return TRUE;
}
コード例 #6
0
ファイル: connection-test.c プロジェクト: NEVERMOR/libsoup
static void
do_max_conns_test_for_session (SoupSession *session)
{
	SoupMessage *msgs[TEST_CONNS];
	int i;

	max_conns_loop = g_main_loop_new (NULL, TRUE);

	g_mutex_lock (&server_mutex);

	g_signal_connect (session, "request-started",
			  G_CALLBACK (max_conns_request_started), NULL);
	msgs_done = 0;
	for (i = 0; i < TEST_CONNS; i++) {
		msgs[i] = soup_message_new_from_uri ("GET", base_uri);
		g_object_ref (msgs[i]);
		soup_session_queue_message (session, msgs[i],
					    max_conns_message_complete, NULL);
	}

	g_main_loop_run (max_conns_loop);
	if (msgs_done != MAX_CONNS) {
		debug_printf (1, "  Queued %d connections out of max %d?",
			      msgs_done, MAX_CONNS);
		errors++;
	}
	g_signal_handlers_disconnect_by_func (session, max_conns_request_started, NULL);

	msgs_done = 0;
	g_idle_add (idle_start_server, NULL);
	quit_loop_timeout = g_timeout_add (1000, quit_loop, NULL);
	g_main_loop_run (max_conns_loop);

	for (i = 0; i < TEST_CONNS; i++) {
		if (!SOUP_STATUS_IS_SUCCESSFUL (msgs[i]->status_code)) {
			debug_printf (1, "    Message %d failed? %d %s\n",
				      i, msgs[i]->status_code,
				      msgs[i]->reason_phrase ? msgs[i]->reason_phrase : "-");
			errors++;
		}
	}

	if (msgs_done != TEST_CONNS) {
		/* Clean up so we don't get a spurious "Leaked
		 * session" error.
		 */
		for (i = 0; i < TEST_CONNS; i++)
			soup_session_cancel_message (session, msgs[i], SOUP_STATUS_CANCELLED);
		g_main_loop_run (max_conns_loop);
	}

	g_main_loop_unref (max_conns_loop);
	if (quit_loop_timeout)
		g_source_remove (quit_loop_timeout);

	for (i = 0; i < TEST_CONNS; i++)
		g_object_unref (msgs[i]);
}
コード例 #7
0
static gboolean
t5_cancel_cb (gpointer data)
{
  SoupMessage *msg = (SoupMessage *) data;
  GST_DEBUG ("Cancel Message.");
  soup_session_cancel_message (session, msg, SOUP_STATUS_CANCELLED);

  return FALSE;
}
コード例 #8
0
ファイル: aws-s3-client.c プロジェクト: chergert/aws-glib
static void
aws_s3_client_read_got_headers (SoupMessage *message,
                                GTask       *task)
{
  AwsS3Client *client;

  g_assert (SOUP_IS_MESSAGE(message));
  g_assert (G_IS_TASK (task));

  client = g_task_get_source_object (task);
  g_assert (AWS_IS_S3_CLIENT (client));

  if (!SOUP_STATUS_IS_SUCCESSFUL (message->status_code))
    {
      /*
       * Extract the given error type.
       */
      if (message->status_code == SOUP_STATUS_NOT_FOUND)
        {
          g_task_return_new_error (task,
                                   AWS_S3_CLIENT_ERROR,
                                   AWS_S3_CLIENT_ERROR_NOT_FOUND,
                                   "The requested object was not found.");
         soup_session_cancel_message (SOUP_SESSION (client), message, message->status_code);
        }
      else if (SOUP_STATUS_IS_CLIENT_ERROR (message->status_code))
        {
          g_task_return_new_error (task,
                                   AWS_S3_CLIENT_ERROR,
                                   AWS_S3_CLIENT_ERROR_BAD_REQUEST,
                                   "The request was invalid.");
          soup_session_cancel_message (SOUP_SESSION (client), message, message->status_code);
        }
      else
        {
          g_task_return_new_error (task,
                                   AWS_S3_CLIENT_ERROR,
                                   AWS_S3_CLIENT_ERROR_UNKNOWN,
                                   "An unknown error occurred.");
          soup_session_cancel_message (SOUP_SESSION (client), message, SOUP_STATUS_CANCELLED);
        }
    }
}
コード例 #9
0
ファイル: misc-test.c プロジェクト: Kharif/libsoup
static gboolean
cancel_message_timeout (gpointer msg)
{
	SoupSession *session = g_object_get_data (G_OBJECT (msg), "session");

	soup_session_cancel_message (session, msg, SOUP_STATUS_CANCELLED);
	g_object_unref (msg);
	g_object_unref (session);
	return FALSE;
}
コード例 #10
0
static void
gst_soup_http_src_cancel_message (GstSoupHTTPSrc * src)
{
  if (src->msg != NULL) {
    src->session_io_status = GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_CANCELLED;
    soup_session_cancel_message (src->session, src->msg, SOUP_STATUS_CANCELLED);
  }
  src->session_io_status = GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_IDLE;
  src->msg = NULL;
}
コード例 #11
0
void
mex_download_queue_cancel (MexDownloadQueue *queue,
                           gpointer          id)
{
  MexDownloadQueuePrivate *priv;
  DQTask *task = id;
  GList *l;

  g_return_if_fail (MEX_IS_DOWNLOAD_QUEUE (queue));
  g_return_if_fail (id);

  priv = queue->priv;

  MEX_NOTE (DOWNLOAD_QUEUE, "cancelling download: %s", task->any.uri);

  l = g_queue_find (priv->queue, task);
  if (l)
    {
      /* Make sure our last-local link stays valid */
      if (priv->last_local == l)
        priv->last_local = l->prev;

      mex_download_queue_free (task);
      g_queue_delete_link (priv->queue, l);

      g_object_notify (G_OBJECT (queue), "queue-length");

      return;
    }

  switch (task->type)
    {
    case MEX_DQ_TYPE_SOUP:
      soup_session_cancel_message (priv->session,
                                   task->soup.message,
                                   SOUP_STATUS_CANCELLED);
      break;

    case MEX_DQ_TYPE_GIO:
      g_cancellable_cancel (task->gio.cancellable);
      break;

    case MEX_DQ_TYPE_CACHED:
      if (task->cached.source_id)
        g_source_remove (task->cached.source_id);
      task->cached.source_id = 0;

      mex_download_queue_free (task);
      break;

    default:
      g_warning ("Unknown download type cancelled! %d", task->type);
      break;
    }
}
コード例 #12
0
ファイル: misc-test.c プロジェクト: Kharif/libsoup
static gpointer
cancel_message_thread (gpointer msg)
{
	SoupSession *session = g_object_get_data (G_OBJECT (msg), "session");

	g_usleep (100000); /* .1s */
	soup_session_cancel_message (session, msg, SOUP_STATUS_CANCELLED);
	g_object_unref (msg);
	g_object_unref (session);
	return NULL;
}
コード例 #13
0
ファイル: aur-client.c プロジェクト: kevinjen1031/aurena
static gboolean
conn_idle_timeout (AurClient * client)
{
  client->idle_timeout = 0;

  if (client->msg) {
    g_print ("Connection timed out\n");
    soup_session_cancel_message (client->soup, client->msg, 200);
  }

  return FALSE;
}
コード例 #14
0
ファイル: soup-input-stream.c プロジェクト: Andais/gvfs
static gboolean
soup_input_stream_close (GInputStream *stream,
			 GCancellable *cancellable,
			 GError      **error)
{
  SoupInputStreamPrivate *priv = SOUP_INPUT_STREAM_GET_PRIVATE (stream);

  if (!priv->finished)
    soup_session_cancel_message (priv->session, priv->msg, SOUP_STATUS_CANCELLED);

  return TRUE;
}
コード例 #15
0
static void
mex_download_queue_free (DQTask *task)
{
  MexDownloadQueue *self = task->any.queue;
  MexDownloadQueuePrivate *priv = self->priv;

  switch (task->any.type)
    {
    case MEX_DQ_TYPE_GIO:
      if (task->gio.cancellable)
        {
          g_cancellable_cancel (task->gio.cancellable);

          /* Return, cancelling the task will run the file load callback,
            * which will unref the cancellable and call this free function
            * again.
            */
          return;
        }

      if (task->gio.file)
        g_object_unref (task->gio.file);

      break;

    case MEX_DQ_TYPE_SOUP:
      if (task->soup.message)
        {
          soup_session_cancel_message (priv->session,
                                       task->soup.message,
                                       SOUP_STATUS_CANCELLED);

          /* Return, the callback will call this function again
            * after setting the message to NULL.
            */
          return;
        }

      break;

    default:
      break;
    }

  if (task->any.type != MEX_DQ_TYPE_NONE)
    {
      priv->in_progress--;
      process_queue (self);
      g_object_notify (G_OBJECT (self), "queue-length");
    }

  g_slice_free (DQTask, task);
}
コード例 #16
0
void ResourceHandle::cancel()
{
    d->m_cancelled = true;
    if (d->m_msg) {
        soup_session_cancel_message(session, d->m_msg, SOUP_STATUS_CANCELLED);
        // For re-entrancy troubles we call didFinishLoading when the message hasn't been handled yet.
        d->client()->didFinishLoading(this);
    } else if (d->m_cancellable) {
        g_cancellable_cancel(d->m_cancellable);
        d->client()->didFinishLoading(this);
    }
}
コード例 #17
0
ファイル: web-service.c プロジェクト: KapTmaN/gthumb
static void
web_service_cancelled (GthTask *base)
{
	WebService *self = WEB_SERVICE (base);

	if ((self->priv->session == NULL) || (self->priv->msg == NULL))
		return;

	soup_session_cancel_message (self->priv->session,
				     self->priv->msg,
				     SOUP_STATUS_CANCELLED);
}
コード例 #18
0
static void
cal_backend_http_cancelled (GCancellable *cancellable,
                            gpointer user_data)
{
	struct {
		SoupSession *soup_session;
		SoupMessage *soup_message;
	} *cancel_data = user_data;

	soup_session_cancel_message (
		cancel_data->soup_session,
		cancel_data->soup_message,
		SOUP_STATUS_CANCELLED);
}
コード例 #19
0
static void
gupnp_service_info_dispose (GObject *object)
{
        GUPnPServiceInfo *info;
        GUPnPServiceInfoPrivate *priv;

        info = GUPNP_SERVICE_INFO (object);
        priv = gupnp_service_info_get_instance_private (info);

        /* Cancel any pending SCPD GETs */
        if (priv->context) {
                SoupSession *session;

                session = gupnp_context_get_session (priv->context);

                while (priv->pending_gets) {
                        GetSCPDURLData *data;

                        data = priv->pending_gets->data;

                        if (data->cancellable)
                                g_cancellable_disconnect (data->cancellable,
                                                          data->cancelled_id);

                        soup_session_cancel_message (session,
                                                     data->message,
                                                     SOUP_STATUS_CANCELLED);

                        get_scpd_url_data_free (data);

                        priv->pending_gets =
                                g_list_delete_link (priv->pending_gets,
                                                    priv->pending_gets);
                }

                /* Unref context */
                g_object_unref (priv->context);
                priv->context = NULL;
        }

        if (priv->doc) {
                g_object_unref (priv->doc);
                priv->doc = NULL;
        }

        G_OBJECT_CLASS (gupnp_service_info_parent_class)->dispose (object);
}
コード例 #20
0
static gboolean
item_failed (SoupMessageQueueItem *item, guint status)
{
	if (item->removed) {
		soup_message_queue_item_unref (item);
		return TRUE;
	}

	if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
		if (status != SOUP_STATUS_CANCELLED)
			soup_session_cancel_message (item->session, item->msg, status);
		soup_message_queue_item_unref (item);
		return TRUE;
	}

	return FALSE;
}
コード例 #21
0
ファイル: hsts.c プロジェクト: vlampreia/vimb
static void request_started(SoupSessionFeature *feature,
    SoupSession *session, SoupMessage *msg, SoupSocket *socket)
{
    HSTSProvider *provider = HSTS_PROVIDER(feature);
    SoupURI *uri           = soup_message_get_uri(msg);
    GTlsCertificate *certificate;
    GTlsCertificateFlags errors;

    if (should_secure_host(provider, uri->host)) {
        if (uri->scheme != SOUP_URI_SCHEME_HTTPS
            || (soup_message_get_https_status(msg, &certificate, &errors) && errors)
        ) {
            soup_session_cancel_message(session, msg, SOUP_STATUS_SSL_FAILED);
            g_warning("cancel invalid hsts request to %s://%s", uri->scheme, uri->host);
        }
    }
}
コード例 #22
0
ファイル: gupnp-control-point.c プロジェクト: Ham22/gupnp
static void
gupnp_control_point_dispose (GObject *object)
{
        GUPnPControlPoint *control_point;
        GSSDPResourceBrowser *browser;
        GObjectClass *object_class;

        control_point = GUPNP_CONTROL_POINT (object);
        browser = GSSDP_RESOURCE_BROWSER (control_point);

        gssdp_resource_browser_set_active (browser, FALSE);

        if (control_point->priv->factory) {
                g_object_unref (control_point->priv->factory);
                control_point->priv->factory = NULL;
        }

        /* Cancel any pending description file GETs */
        while (control_point->priv->pending_gets) {
                GetDescriptionURLData *data;
                GUPnPContext *context;
                SoupSession *session;

                data = control_point->priv->pending_gets->data;

                context = gupnp_control_point_get_context (control_point);
                session = gupnp_context_get_session (context);

                soup_session_cancel_message (session,
                                             data->message,
                                             SOUP_STATUS_CANCELLED);

                get_description_url_data_free (data);
        }

        /* Release weak references on remaining cached documents */
        g_hash_table_foreach (control_point->priv->doc_cache,
                              weak_unref_doc,
                              control_point);

        /* Call super */
        object_class = G_OBJECT_CLASS (gupnp_control_point_parent_class);
        object_class->dispose (object);
}
コード例 #23
0
static void
gs_screenshot_image_destroy (GtkWidget *widget)
{
	GsScreenshotImage *ssimg = GS_SCREENSHOT_IMAGE (widget);

	if (ssimg->message != NULL) {
		soup_session_cancel_message (ssimg->session,
		                             ssimg->message,
		                             SOUP_STATUS_CANCELLED);
		g_clear_object (&ssimg->message);
	}
	g_clear_object (&ssimg->screenshot);
	g_clear_object (&ssimg->session);
	g_clear_object (&ssimg->settings);

	g_clear_pointer (&ssimg->filename, g_free);

	GTK_WIDGET_CLASS (gs_screenshot_image_parent_class)->destroy (widget);
}
コード例 #24
0
ファイル: icons.c プロジェクト: prajoshpremdas/gupnp-tools
void
deinit_icons (void)
{
        int i;

        while (pending_gets) {
                GetIconURLData *data;

                data = pending_gets->data;

                soup_session_cancel_message (download_session,
                                             data->message,
                                             SOUP_STATUS_CANCELLED);
        }

        g_object_unref (download_session);

        for (i = 0; i < ICON_LAST; i++) {
                g_object_unref (icons[i]);
        }
}
コード例 #25
0
/**
 * gs_screenshot_image_destroy:
 **/
static void
gs_screenshot_image_destroy (GtkWidget *widget)
{
	GsScreenshotImage *ssimg = GS_SCREENSHOT_IMAGE (widget);
	GsScreenshotImagePrivate *priv;

	priv = gs_screenshot_image_get_instance_private (ssimg);

	if (priv->message != NULL) {
		soup_session_cancel_message (priv->session,
		                             priv->message,
		                             SOUP_STATUS_CANCELLED);
		g_clear_object (&priv->message);
	}
	g_clear_object (&priv->screenshot);
	g_clear_object (&priv->session);

	g_clear_pointer (&priv->cachedir, g_free);
	g_clear_pointer (&priv->filename, g_free);

	GTK_WIDGET_CLASS (gs_screenshot_image_parent_class)->destroy (widget);
}
コード例 #26
0
ファイル: icons.c プロジェクト: GNOME/gupnp-tools
void
unschedule_icon_update (GUPnPDeviceInfo *info)
{
        GList *gets;

        for (gets = pending_gets; gets; gets = gets->next) {
                GetIconURLData *data;
                const char *udn1;
                const char *udn2;

                data = gets->data;
                udn1 = gupnp_device_info_get_udn (info);
                udn2 = gupnp_device_info_get_udn (data->info);

                if (udn1 && udn2 && strcmp (udn1, udn2) == 0) {
                        soup_session_cancel_message (download_session,
                                                     data->message,
                                                     SOUP_STATUS_CANCELLED);
                        break;
                }
        }
}
コード例 #27
0
ファイル: soup-session.c プロジェクト: gcorvala/gsoc-2009
void
soup_session_connection_failed (SoupSession *session,
				SoupConnection *conn, guint status)
{
	SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session);
	SoupSessionHost *host;
	SoupMessageQueueItem *item;
	SoupMessage *msg;

	g_mutex_lock (priv->host_lock);
	host = g_hash_table_lookup (priv->conns, conn);
	g_mutex_unlock (priv->host_lock);
	if (!host)
		return;

	connection_disconnected (conn, session);

	if (host->connections) {
		/* Something went wrong this time, but we have at
		 * least one open connection to this host. So just
		 * leave the message in the queue so it can use that
		 * connection once it's free.
		 */
		return;
	}

	/* Assume that there's something wrong with the host, and
	 * cancel any other messages waiting for a connection to it,
	 * since they're out of luck.
	 */
	g_object_ref (session);
	for (item = soup_message_queue_first (priv->queue); item; item = soup_message_queue_next (priv->queue, item)) {
		msg = item->msg;
		if (get_host_for_message (session, msg) == host)
			soup_session_cancel_message (session, msg, status);
	}
	g_object_unref (session);
}
コード例 #28
0
ファイル: simple-proxy.c プロジェクト: NEVERMOR/libsoup
static void
client_msg_failed (SoupMessage *msg, gpointer msg2)
{
	soup_session_cancel_message (session, msg2, SOUP_STATUS_IO_ERROR);
}
コード例 #29
0
/**
 * gs_screenshot_image_load_async:
 **/
void
gs_screenshot_image_load_async (GsScreenshotImage *ssimg,
				GCancellable *cancellable)
{
	AsImage *im = NULL;
	GsScreenshotImagePrivate *priv;
	SoupURI *base_uri = NULL;
	const gchar *url;
	gint rc;
	_cleanup_free_ gchar *basename = NULL;
	_cleanup_free_ gchar *cachedir2 = NULL;
	_cleanup_free_ gchar *cachedir = NULL;
	_cleanup_free_ gchar *sizedir = NULL;

	g_return_if_fail (GS_IS_SCREENSHOT_IMAGE (ssimg));

	priv = gs_screenshot_image_get_instance_private (ssimg);

	g_return_if_fail (AS_IS_SCREENSHOT (priv->screenshot));
	g_return_if_fail (priv->width != 0);
	g_return_if_fail (priv->height != 0);

	/* load an image according to the scale factor */
	priv->scale = gtk_widget_get_scale_factor (GTK_WIDGET (ssimg));
	im = as_screenshot_get_image (priv->screenshot,
				      priv->width * priv->scale,
				      priv->height * priv->scale);

	/* if we've failed to load a HiDPI image, fallback to LoDPI */
	if (im == NULL && priv->scale > 1) {
		priv->scale = 1;
		im = as_screenshot_get_image (priv->screenshot,
					      priv->width,
					      priv->height);
	}
	if (im == NULL) {
		/* TRANSLATORS: this is when we request a screenshot size that
		 * the generator did not create or the parser did not add */
		gs_screenshot_image_set_error (ssimg, _("Screenshot size not found"));
		return;
	}
	url = as_image_get_url (im);
	basename = g_path_get_basename (url);
	if (priv->width == G_MAXUINT || priv->height == G_MAXUINT) {
		sizedir = g_strdup ("unknown");
	} else {
		sizedir = g_strdup_printf ("%ux%u", priv->width * priv->scale, priv->height * priv->scale);
	}
	cachedir = g_build_filename (priv->cachedir,
				     "gnome-software",
				     "screenshots",
				     sizedir,
				     NULL);
	rc = g_mkdir_with_parents (cachedir, 0700);
	if (rc != 0) {
		/* TRANSLATORS: this is when we try create the cache directory
		 * but we were out of space or permission was denied */
		gs_screenshot_image_set_error (ssimg, _("Could not create cache"));
		return;
	}

	/* does local file already exist */
	priv->filename = g_build_filename (cachedir, basename, NULL);
	if (g_file_test (priv->filename, G_FILE_TEST_EXISTS)) {
		as_screenshot_show_image (ssimg);
		return;
	}

	/* can we load a blurred smaller version of this straight away */
	if (priv->width > AS_IMAGE_THUMBNAIL_WIDTH &&
	    priv->height > AS_IMAGE_THUMBNAIL_HEIGHT) {
		cachedir2 = g_build_filename (priv->cachedir,
					      "gnome-software",
					      "screenshots",
					      "112x63",
					      basename,
					      NULL);
		if (g_file_test (cachedir2, G_FILE_TEST_EXISTS))
			gs_screenshot_image_show_blurred (ssimg, cachedir2);
	}

	/* download file */
	g_debug ("downloading %s to %s", url, priv->filename);
	base_uri = soup_uri_new (url);
	if (base_uri == NULL || !SOUP_URI_VALID_FOR_HTTP (base_uri)) {
		/* TRANSLATORS: this is when we try to download a screenshot
		 * that was not a valid URL */
		gs_screenshot_image_set_error (ssimg, _("Screenshot not valid"));
		soup_uri_free (base_uri);
		return;
	}

	/* cancel any previous messages */
	if (priv->message != NULL) {
		soup_session_cancel_message (priv->session,
		                             priv->message,
		                             SOUP_STATUS_CANCELLED);
		g_clear_object (&priv->message);
	}

	priv->message = soup_message_new_from_uri (SOUP_METHOD_GET, base_uri);
	if (priv->message == NULL) {
		/* TRANSLATORS: this is when networking is not available */
		gs_screenshot_image_set_error (ssimg, _("Screenshot not available"));
		soup_uri_free (base_uri);
		return;
	}

	/* send async */
	soup_session_queue_message (priv->session,
				    g_object_ref (priv->message) /* transfer full */,
				    gs_screenshot_image_complete_cb,
				    g_object_ref (ssimg));
	soup_uri_free (base_uri);
}
コード例 #30
0
static void
ews_client_autodiscover_response_cb (SoupSession *session, SoupMessage *msg, gpointer user_data)
{
  GError *error;
  AutodiscoverData *data = user_data;
  gboolean op_res;
  guint status;
  gint idx;
  gsize size;
  xmlDoc *doc;
  xmlNode *node;

  error = NULL;
  op_res = FALSE;
  size = sizeof (data->msgs) / sizeof (data->msgs[0]);

  for (idx = 0; idx < size; idx++)
    {
      if (data->msgs[idx] == msg)
        break;
    }
  if (idx == size || data->pending == 0)
    return;

  data->msgs[idx] = NULL;
  status = msg->status_code;

  /* status == SOUP_STATUS_CANCELLED, if we are being aborted by the
   * GCancellable, an SSL error or another message that was
   * successful.
   */
  if (status == SOUP_STATUS_CANCELLED)
    goto out;
  else if (status != SOUP_STATUS_OK)
    {
      g_set_error (&error,
                   GOA_ERROR,
                   GOA_ERROR_FAILED, /* TODO: more specific */
                   _("Code: %u — Unexpected response from server"),
                   status);
      goto out;
    }

  soup_buffer_free (soup_message_body_flatten (SOUP_MESSAGE (msg)->response_body));
  g_debug ("The response headers");
  g_debug ("===================");
  g_debug ("%s", SOUP_MESSAGE (msg)->response_body->data);

  doc = xmlReadMemory (msg->response_body->data, msg->response_body->length, "autodiscover.xml", NULL, 0);
  if (doc == NULL)
    {
      g_set_error (&error,
                   GOA_ERROR,
                   GOA_ERROR_FAILED, /* TODO: more specific */
                   _("Failed to parse autodiscover response XML"));
      goto out;
    }

  node = xmlDocGetRootElement (doc);
  if (g_strcmp0 ((gchar *) node->name, "Autodiscover"))
    {
      g_set_error (&error,
                   GOA_ERROR,
                   GOA_ERROR_FAILED, /* TODO: more specific */
                   /* Translators: the parameter is an XML element name. */
                   _("Failed to find ‘%s’ element"), "Autodiscover");
      goto out;
    }

  for (node = node->children; node; node = node->next)
    {
      if (ews_client_check_node (node, "Response"))
        break;
    }
  if (node == NULL)
    {
      g_set_error (&error,
                   GOA_ERROR,
                   GOA_ERROR_FAILED, /* TODO: more specific */
                   /* Translators: the parameter is an XML element name. */
                   _("Failed to find ‘%s’ element"), "Response");
      goto out;
    }

  for (node = node->children; node; node = node->next)
    {
      if (ews_client_check_node (node, "Account"))
        break;
    }
  if (node == NULL)
    {
      g_set_error (&error,
                   GOA_ERROR,
                   GOA_ERROR_FAILED, /* TODO: more specific */
                   /* Translators: the parameter is an XML element name. */
                   _("Failed to find ‘%s’ element"), "Account");
      goto out;
    }

  for (node = node->children; node; node = node->next)
    {
      if (ews_client_check_node (node, "Protocol"))
        {
          op_res = ews_client_autodiscover_parse_protocol (node);
          /* Since the server may send back multiple <Protocol> nodes
           * don't break unless we found the one we want.
           */
          if (op_res)
            break;
        }
    }
  if (!op_res)
    {
      g_set_error (&error,
                   GOA_ERROR,
                   GOA_ERROR_FAILED, /* TODO: more specific*/
                   _("Failed to find ASUrl and OABUrl in autodiscover response"));
      goto out;
    }

  for (idx = 0; idx < size; idx++)
    {
      if (data->msgs[idx] != NULL)
        {
          /* The callback (ie. this function) will be invoked after we
           * have returned to the main loop.
           */
          soup_session_cancel_message (data->session, data->msgs[idx], SOUP_STATUS_CANCELLED);
        }
    }

 out:
  /* error == NULL, if we are being aborted by the GCancellable, an
   * SSL error or another message that was successful.
   */
  if (!op_res)
    {
      /* There's another request outstanding.
       * Hope that it has better luck.
       */
      if (data->pending > 1)
        g_clear_error (&error);

      if (error != NULL)
        g_simple_async_result_take_error (data->res, error);
    }

  data->pending--;
  if (data->pending == 0)
    {
      GMainContext *context;
      GSource *source;

      g_simple_async_result_set_op_res_gboolean (data->res, op_res);

      source = g_idle_source_new ();
      g_source_set_priority (source, G_PRIORITY_DEFAULT_IDLE);
      g_source_set_callback (source, ews_client_autodiscover_data_free, data, NULL);
      g_source_set_name (source, "[goa] ews_client_autodiscover_data_free");

      context = g_main_context_get_thread_default ();
      g_source_attach (source, context);
      g_source_unref (source);
    }
}