Пример #1
0
static void
resolved_proxy_uri (SoupProxyURIResolver *proxy_resolver,
		    guint status, SoupURI *proxy_uri, gpointer user_data)
{
	SoupMessageQueueItem *item = user_data;
	SoupSession *session = item->session;

	if (item_failed (item, status))
		return;

	if (proxy_uri) {
		SoupAddress *proxy_addr;

		item->state = SOUP_MESSAGE_RESOLVING_PROXY_ADDRESS;

		item->proxy_uri = soup_uri_copy (proxy_uri);
		proxy_addr = soup_address_new (proxy_uri->host,
					       proxy_uri->port);
		soup_address_resolve_async (proxy_addr,
					    soup_session_get_async_context (session),
					    item->cancellable,
					    resolved_proxy_addr, item);
		g_object_unref (proxy_addr);
		return;
	}

	item->state = SOUP_MESSAGE_AWAITING_CONNECTION;
	soup_message_queue_item_unref (item);

	/* If we got here we know session still exists */
	run_queue ((SoupSessionAsync *)session);
}
Пример #2
0
static SoupURI *
suburi_new (SoupURI   *base,
            const char *first,
            ...)
{
  va_list args;
  GPtrArray *arg_array;
  const char *arg;
  char *subpath;
  SoupURI *ret;

  arg_array = g_ptr_array_new ();
  g_ptr_array_add (arg_array, (char*)soup_uri_get_path (base));
  g_ptr_array_add (arg_array, (char*)first);

  va_start (args, first);
  
  while ((arg = va_arg (args, const char *)) != NULL)
    g_ptr_array_add (arg_array, (char*)arg);
  g_ptr_array_add (arg_array, NULL);

  subpath = g_build_filenamev ((char**)arg_array->pdata);
  g_ptr_array_unref (arg_array);
  
  ret = soup_uri_copy (base);
  soup_uri_set_path (ret, subpath);
  g_free (subpath);
  
  va_end (args);
  
  return ret;
}
Пример #3
0
/* Server handlers for "*" work but are separate from handlers for
 * all other URIs. #590751
 */
static void
do_star_test (void)
{
	SoupSession *session;
	SoupMessage *msg;
	SoupURI *star_uri;
	const char *handled_by;

	debug_printf (1, "\nOPTIONS *\n");

	session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC, NULL);
	star_uri = soup_uri_copy (base_uri);
	soup_uri_set_path (star_uri, "*");

	debug_printf (1, "  Testing with no handler\n");
	msg = soup_message_new_from_uri ("OPTIONS", star_uri);
	soup_session_send_message (session, msg);

	if (msg->status_code != SOUP_STATUS_NOT_FOUND) {
		debug_printf (1, "    Unexpected response: %d %s\n",
			      msg->status_code, msg->reason_phrase);
		errors++;
	}
	handled_by = soup_message_headers_get_one (msg->response_headers,
						   "X-Handled-By");
	if (handled_by) {
		/* Should have been rejected by SoupServer directly */
		debug_printf (1, "    Message reached handler '%s'\n",
			      handled_by);
		errors++;
	}
	g_object_unref (msg);

	soup_server_add_handler (server, "*", server_star_callback, NULL, NULL);

	debug_printf (1, "  Testing with handler\n");
	msg = soup_message_new_from_uri ("OPTIONS", star_uri);
	soup_session_send_message (session, msg);

	if (msg->status_code != SOUP_STATUS_OK) {
		debug_printf (1, "    Unexpected response: %d %s\n",
			      msg->status_code, msg->reason_phrase);
		errors++;
	}
	handled_by = soup_message_headers_get_one (msg->response_headers,
						   "X-Handled-By");
	if (!handled_by) {
		debug_printf (1, "    Message did not reach handler!\n");
		errors++;
	} else if (strcmp (handled_by, "star_callback") != 0) {
		debug_printf (1, "    Message reached incorrect handler '%s'\n",
			      handled_by);
		errors++;
	}
	g_object_unref (msg);

	soup_test_session_abort_unref (session);
	soup_uri_free (star_uri);
}
Пример #4
0
static unsigned soupProxyResolverWkGetProxyURISync(SoupProxyURIResolver* proxyResolver, SoupURI* uri, GCancellable*, SoupURI** proxyURI)
{
    SoupProxyResolverWkPrivate* priv = SOUP_PROXY_RESOLVER_WK_GET_PRIVATE(proxyResolver);

    if (!shouldBypassProxy(priv, uri))
        *proxyURI = soup_uri_copy(priv->proxyURI);

    return SOUP_STATUS_OK;
}
Пример #5
0
static void soupProxyResolverWkGetProxyURIAsync(SoupProxyURIResolver* proxyResolver, SoupURI* uri, GMainContext* asyncContext, GCancellable*, SoupProxyURIResolverCallback callback, void* userData)
{
    SoupWkAsyncData* ssad;

    ssad = g_slice_new0(SoupWkAsyncData);
    ssad->proxyResolver = SOUP_PROXY_URI_RESOLVER(g_object_ref(proxyResolver));
    ssad->uri = soup_uri_copy(uri);
    ssad->callback = callback;
    ssad->userData = userData;
    soup_add_completion(asyncContext, idle_return_proxy_uri, ssad);
}
Пример #6
0
static SoupURI *
get_uri_to_sig (SoupURI *uri)
{
  g_autofree gchar *sig_path = NULL;
  SoupURI *sig_uri = soup_uri_copy (uri);

  sig_path = g_strconcat (soup_uri_get_path (uri), ".sig", NULL);
  soup_uri_set_path (sig_uri, sig_path);

  return sig_uri;
}
Пример #7
0
static void
md5_post_callback (SoupServer *server, SoupMessage *msg,
                   const char *path, GHashTable *query,
                   SoupClientContext *context, gpointer data)
{
    const char *content_type;
    GHashTable *params;
    const char *fmt;
    char *filename, *md5sum, *redirect_uri;
    SoupBuffer *file;
    SoupURI *uri;

    content_type = soup_message_headers_get_content_type (msg->request_headers, NULL);
    if (!content_type || strcmp (content_type, "multipart/form-data") != 0) {
        soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST);
        return;
    }

    params = soup_form_decode_multipart (msg, "file",
                                         &filename, NULL, &file);
    if (!params) {
        soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST);
        return;
    }
    fmt = g_hash_table_lookup (params, "fmt");

    md5sum = g_compute_checksum_for_data (G_CHECKSUM_MD5,
                                          (gpointer)file->data,
                                          file->length);
    soup_buffer_free (file);

    uri = soup_uri_copy (soup_message_get_uri (msg));
    soup_uri_set_query_from_fields (uri,
                                    "file", filename ? filename : "",
                                    "md5sum", md5sum,
                                    "fmt", fmt ? fmt : "html",
                                    NULL);
    redirect_uri = soup_uri_to_string (uri, FALSE);

    soup_message_set_status (msg, SOUP_STATUS_SEE_OTHER);
    soup_message_headers_replace (msg->response_headers, "Location",
                                  redirect_uri);

    g_free (redirect_uri);
    soup_uri_free (uri);
    g_free (md5sum);
    g_free (filename);
    g_hash_table_destroy (params);
}
Пример #8
0
static void
gupnp_device_info_set_property (GObject      *object,
                                guint         property_id,
                                const GValue *value,
                                GParamSpec   *pspec)
{
        GUPnPDeviceInfo *info;

        info = GUPNP_DEVICE_INFO (object);

        switch (property_id) {
        case PROP_RESOURCE_FACTORY:
                info->priv->factory = 
			GUPNP_RESOURCE_FACTORY (g_value_dup_object (value));
                break;
        case PROP_CONTEXT:
                info->priv->context = g_object_ref (g_value_get_object (value));
                break;
        case PROP_LOCATION:
                info->priv->location = g_value_dup_string (value);
                break;
        case PROP_UDN:
                info->priv->udn = g_value_dup_string (value);
                break;
        case PROP_DEVICE_TYPE:
                info->priv->device_type = g_value_dup_string (value);
                break;
        case PROP_URL_BASE:
                info->priv->url_base = g_value_get_pointer (value);
                if (info->priv->url_base)
                        info->priv->url_base =
                                soup_uri_copy (info->priv->url_base);

                break;
        case PROP_DOCUMENT:
                info->priv->doc = g_value_dup_object (value);
                break;
        case PROP_ELEMENT:
                info->priv->element = g_value_get_pointer (value);
                break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
                break;
        }
}
static void
get_proxy_uri_async (SoupProxyURIResolver  *proxy_uri_resolver,
		     SoupURI               *uri,
		     GMainContext          *async_context,
		     GCancellable          *cancellable,
		     SoupProxyURIResolverCallback callback,
		     gpointer               user_data)
{
	SoupGNOMEAsyncData *sgad;

	sgad = g_slice_new0 (SoupGNOMEAsyncData);
	sgad->proxy_uri_resolver = g_object_ref (proxy_uri_resolver);
	sgad->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
	sgad->callback = callback;
	sgad->user_data = user_data;

	G_LOCK (resolver_gnome);
	switch (proxy_mode) {
	case SOUP_PROXY_RESOLVER_GNOME_MODE_NONE:
		sgad->proxy_uri = NULL;
		sgad->status = SOUP_STATUS_OK;
		break;

	case SOUP_PROXY_RESOLVER_GNOME_MODE_MANUAL:
		/* We know libproxy won't do PAC or WPAD in this case,
		 * so we can make a "blocking" call to it.
		 */
		sgad->status = get_proxy_for_uri (uri, &sgad->proxy_uri);
		break;

	case SOUP_PROXY_RESOLVER_GNOME_MODE_AUTO:
		/* FIXME: cancellable */
		sgad->uri = soup_uri_copy (uri);
		sgad->async_context = async_context ? g_main_context_ref (async_context) : NULL;
		g_thread_pool_push (libproxy_threadpool, sgad, NULL);
		G_UNLOCK (resolver_gnome);
		return;
	}
	G_UNLOCK (resolver_gnome);

	soup_add_completion (async_context, resolved_proxy, sgad);
}
Пример #10
0
static void soupProxyResolverWkSetProperty(GObject* object, unsigned propID, const GValue* value, GParamSpec* pspec)
{
    SoupProxyResolverWkPrivate* priv = SOUP_PROXY_RESOLVER_WK_GET_PRIVATE(object);

    switch (propID) {
    case PROP_PROXY_URI: {
        SoupURI* uri = static_cast<SoupURI*>(g_value_get_boxed(value));
        if (priv->proxyURI)
            soup_uri_free(priv->proxyURI);

        priv->proxyURI = uri ? soup_uri_copy(uri) : 0;
        break;
    }
    case PROP_NO_PROXY:
        priv->noProxy = g_value_get_string(value);
        priv->proxyExceptions.clear();
        String::fromUTF8(priv->noProxy.data()).replaceWithLiteral(' ', "").split(',', priv->proxyExceptions);
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, pspec);
        break;
    }
}
Пример #11
0
gboolean
ostree_repo_pull (OstreeRepo               *self,
                  const char               *remote_name,
                  char                    **refs_to_fetch,
                  OstreeRepoPullFlags       flags,
                  OstreeAsyncProgress      *progress,
                  GCancellable             *cancellable,
                  GError                  **error)
{
  gboolean ret = FALSE;
  GHashTableIter hash_iter;
  gpointer key, value;
  gboolean tls_permissive = FALSE;
  OstreeFetcherConfigFlags fetcher_flags = 0;
  gs_free char *remote_key = NULL;
  gs_free char *path = NULL;
  gs_free char *baseurl = NULL;
  gs_free char *summary_data = NULL;
  gs_unref_hashtable GHashTable *requested_refs_to_fetch = NULL;
  gs_unref_hashtable GHashTable *updated_refs = NULL;
  gs_unref_hashtable GHashTable *commits_to_fetch = NULL;
  gs_free char *remote_mode_str = NULL;
  GSource *queue_src = NULL;
  OtPullData pull_data_real = { 0, };
  OtPullData *pull_data = &pull_data_real;
  SoupURI *summary_uri = NULL;
  GKeyFile *config = NULL;
  GKeyFile *remote_config = NULL;
  char **configured_branches = NULL;
  guint64 bytes_transferred;
  guint64 start_time;
  guint64 end_time;

  pull_data->async_error = error;
  pull_data->main_context = g_main_context_ref_thread_default ();
  pull_data->loop = g_main_loop_new (pull_data->main_context, FALSE);
  pull_data->flags = flags;

  pull_data->repo = self;
  pull_data->progress = progress;

  pull_data->scanned_metadata = g_hash_table_new_full (ostree_hash_object_name, g_variant_equal,
                                                       (GDestroyNotify)g_variant_unref, NULL);
  pull_data->requested_content = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                        (GDestroyNotify)g_free, NULL);
  pull_data->requested_metadata = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                         (GDestroyNotify)g_free, NULL);

  start_time = g_get_monotonic_time ();

  pull_data->remote_name = g_strdup (remote_name);
  config = ostree_repo_get_config (self);

  remote_key = g_strdup_printf ("remote \"%s\"", pull_data->remote_name);
  if (!repo_get_string_key_inherit (self, remote_key, "url", &baseurl, error))
    goto out;
  pull_data->base_uri = soup_uri_new (baseurl);

#ifdef HAVE_GPGME
  if (!ot_keyfile_get_boolean_with_default (config, remote_key, "gpg-verify",
                                            TRUE, &pull_data->gpg_verify, error))
    goto out;
#else
  pull_data->gpg_verify = FALSE;
#endif

  if (!ot_keyfile_get_boolean_with_default (config, remote_key, "tls-permissive",
                                            FALSE, &tls_permissive, error))
    goto out;
  if (tls_permissive)
    fetcher_flags |= OSTREE_FETCHER_FLAGS_TLS_PERMISSIVE;

  pull_data->fetcher = ostree_fetcher_new (pull_data->repo->tmp_dir,
                                           fetcher_flags);

  if (!pull_data->base_uri)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Failed to parse url '%s'", baseurl);
      goto out;
    }

  if (!load_remote_repo_config (pull_data, &remote_config, cancellable, error))
    goto out;

  if (!ot_keyfile_get_value_with_default (remote_config, "core", "mode", "bare",
                                          &remote_mode_str, error))
    goto out;

  if (!ostree_repo_mode_from_string (remote_mode_str, &pull_data->remote_mode, error))
    goto out;

  if (pull_data->remote_mode != OSTREE_REPO_MODE_ARCHIVE_Z2)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Can't pull from archives with mode \"%s\"",
                   remote_mode_str);
      goto out;
    }

  requested_refs_to_fetch = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
  updated_refs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
  commits_to_fetch = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);

  if (refs_to_fetch != NULL)
    {
      char **strviter;
      for (strviter = refs_to_fetch; *strviter; strviter++)
        {
          const char *branch = *strviter;
          char *contents;

          if (ostree_validate_checksum_string (branch, NULL))
            {
              char *key = g_strdup (branch);
              g_hash_table_insert (commits_to_fetch, key, key);
            }
          else
            {
              if (!fetch_ref_contents (pull_data, branch, &contents, cancellable, error))
                goto out;
      
              /* Transfer ownership of contents */
              g_hash_table_insert (requested_refs_to_fetch, g_strdup (branch), contents);
            }
        }
    }
  else
    {
      GError *temp_error = NULL;
      gboolean fetch_all_refs;

      configured_branches = g_key_file_get_string_list (config, remote_key, "branches", NULL, &temp_error);
      if (configured_branches == NULL && temp_error != NULL)
        {
          if (g_error_matches (temp_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND))
            {
              g_clear_error (&temp_error);
              fetch_all_refs = TRUE;
            }
          else
            {
              g_propagate_error (error, temp_error);
              goto out;
            }
        }
      else
        fetch_all_refs = FALSE;

      if (fetch_all_refs)
        {
          summary_uri = soup_uri_copy (pull_data->base_uri);
          path = g_build_filename (soup_uri_get_path (summary_uri), "refs", "summary", NULL);
          soup_uri_set_path (summary_uri, path);
          
          if (!fetch_uri_contents_utf8_sync (pull_data, summary_uri, &summary_data, cancellable, error))
            goto out;
          
          if (!parse_ref_summary (summary_data, &requested_refs_to_fetch, error))
            goto out;
        }
      else
        {
          char **branches_iter = configured_branches;

          if (!(branches_iter && *branches_iter))
            g_print ("No configured branches for remote %s\n", pull_data->remote_name);
          for (;branches_iter && *branches_iter; branches_iter++)
            {
              const char *branch = *branches_iter;
              char *contents;
              
              if (!fetch_ref_contents (pull_data, branch, &contents, cancellable, error))
                goto out;
              
              /* Transfer ownership of contents */
              g_hash_table_insert (requested_refs_to_fetch, g_strdup (branch), contents);
            }
        }
    }

  if (!ostree_repo_prepare_transaction (pull_data->repo, &pull_data->transaction_resuming,
                                        cancellable, error))
    goto out;

  pull_data->metadata_objects_to_fetch = ot_waitable_queue_new ();
  pull_data->metadata_objects_to_scan = ot_waitable_queue_new ();
  pull_data->metadata_thread = g_thread_new ("metadatascan", metadata_thread_main, pull_data);

  g_hash_table_iter_init (&hash_iter, commits_to_fetch);
  while (g_hash_table_iter_next (&hash_iter, &key, &value))
    {
      const char *commit = value;

      ot_waitable_queue_push (pull_data->metadata_objects_to_scan,
                              pull_worker_message_new (PULL_MSG_SCAN,
                                                       ostree_object_name_serialize (commit, OSTREE_OBJECT_TYPE_COMMIT)));
    }

  g_hash_table_iter_init (&hash_iter, requested_refs_to_fetch);
  while (g_hash_table_iter_next (&hash_iter, &key, &value))
    {
      const char *ref = key;
      const char *sha256 = value;

      ot_waitable_queue_push (pull_data->metadata_objects_to_scan,
                              pull_worker_message_new (PULL_MSG_SCAN,
                                                       ostree_object_name_serialize (sha256, OSTREE_OBJECT_TYPE_COMMIT)));
      g_hash_table_insert (updated_refs, g_strdup (ref), g_strdup (sha256));
    }
  
  {
    queue_src = ot_waitable_queue_create_source (pull_data->metadata_objects_to_fetch);
    g_source_set_callback (queue_src, (GSourceFunc)on_metadata_objects_to_fetch_ready, pull_data, NULL);
    g_source_attach (queue_src, pull_data->main_context);
    g_source_unref (queue_src);
  }

  /* Prime the message queue */
  pull_data->idle_serial++;
  ot_waitable_queue_push (pull_data->metadata_objects_to_scan,
                          pull_worker_message_new (PULL_MSG_MAIN_IDLE, GUINT_TO_POINTER (pull_data->idle_serial)));
  
  /* Now await work completion */
  if (!run_mainloop_monitor_fetcher (pull_data))
    goto out;
  

  g_hash_table_iter_init (&hash_iter, updated_refs);
  while (g_hash_table_iter_next (&hash_iter, &key, &value))
    {
      const char *ref = key;
      const char *checksum = value;
      gs_free char *remote_ref = NULL;
      gs_free char *original_rev = NULL;
          
      remote_ref = g_strdup_printf ("%s/%s", pull_data->remote_name, ref);

      if (!ostree_repo_resolve_rev (pull_data->repo, remote_ref, TRUE, &original_rev, error))
        goto out;
          
      if (original_rev && strcmp (checksum, original_rev) == 0)
        {
          g_print ("remote %s is unchanged from %s\n", remote_ref, original_rev);
        }
      else
        {
          ostree_repo_transaction_set_ref (pull_data->repo, pull_data->remote_name, ref, checksum);

          g_print ("remote %s is now %s\n", remote_ref, checksum);
        }
    }

  if (!ostree_repo_commit_transaction (pull_data->repo, NULL, cancellable, error))
    goto out;

  end_time = g_get_monotonic_time ();

  bytes_transferred = ostree_fetcher_bytes_transferred (pull_data->fetcher);
  if (bytes_transferred > 0)
    {
      guint shift; 
      if (bytes_transferred < 1024)
        shift = 1;
      else
        shift = 1024;
      g_print ("%u metadata, %u content objects fetched; %" G_GUINT64_FORMAT " %s transferred in %u seconds\n", 
               pull_data->n_fetched_metadata, pull_data->n_fetched_content,
               (guint64)(bytes_transferred / shift),
               shift == 1 ? "B" : "KiB",
               (guint) ((end_time - start_time) / G_USEC_PER_SEC));
    }

  ret = TRUE;
 out:
  if (pull_data->main_context)
    g_main_context_unref (pull_data->main_context);
  if (pull_data->loop)
    g_main_loop_unref (pull_data->loop);
  g_strfreev (configured_branches);
  g_clear_object (&pull_data->fetcher);
  g_free (pull_data->remote_name);
  if (pull_data->base_uri)
    soup_uri_free (pull_data->base_uri);
  if (queue_src)
    g_source_destroy (queue_src);
  if (pull_data->metadata_thread)
    {
      ot_waitable_queue_push (pull_data->metadata_objects_to_scan,
                              pull_worker_message_new (PULL_MSG_QUIT, NULL));
      g_thread_join (pull_data->metadata_thread);
    }
  g_clear_pointer (&pull_data->metadata_objects_to_scan, (GDestroyNotify) ot_waitable_queue_unref);
  g_clear_pointer (&pull_data->metadata_objects_to_fetch, (GDestroyNotify) ot_waitable_queue_unref);
  g_clear_pointer (&pull_data->scanned_metadata, (GDestroyNotify) g_hash_table_unref);
  g_clear_pointer (&pull_data->requested_content, (GDestroyNotify) g_hash_table_unref);
  g_clear_pointer (&pull_data->requested_metadata, (GDestroyNotify) g_hash_table_unref);
  g_clear_pointer (&remote_config, (GDestroyNotify) g_key_file_unref);
  if (summary_uri)
    soup_uri_free (summary_uri);
  return ret;
}
static void
do_request_test (SoupSession *session, SoupURI *base_uri, RequestTestFlags flags)
{
	SoupURI *uri = base_uri;
	PutTestData ptd;
	SoupMessage *msg;
	const char *client_md5, *server_md5;
	GChecksum *check;
	int i, length;

	debug_printf (1, "PUT");
	if (flags & HACKY_STREAMING)
		debug_printf (1, " w/ hacky streaming");
	else if (flags & PROPER_STREAMING)
		debug_printf (1, " w/ proper streaming");
	if (flags & RESTART) {
		debug_printf (1, " and restart");
		uri = soup_uri_copy (base_uri);
		soup_uri_set_path (uri, "/redirect");
	}
	debug_printf (1, "\n");

	ptd.session = session;
	setup_request_body (&ptd);
	ptd.streaming = flags & (HACKY_STREAMING | PROPER_STREAMING);

	check = g_checksum_new (G_CHECKSUM_MD5);
	length = 0;
	for (i = 0; i < 3; i++) {
		g_checksum_update (check, (guchar *)ptd.chunks[i]->data,
				   ptd.chunks[i]->length);
		length += ptd.chunks[i]->length;
	}
	client_md5 = g_checksum_get_string (check);

	msg = soup_message_new_from_uri ("PUT", uri);
	soup_message_headers_set_encoding (msg->request_headers, SOUP_ENCODING_CHUNKED);
	soup_message_body_set_accumulate (msg->request_body, FALSE);
	soup_message_set_chunk_allocator (msg, error_chunk_allocator, NULL, NULL);
	if (flags & HACKY_STREAMING) {
		g_signal_connect (msg, "wrote_chunk",
				  G_CALLBACK (write_next_chunk_streaming_hack), &ptd);
		if (flags & RESTART) {
			g_signal_connect (msg, "restarted",
					  G_CALLBACK (restarted_streaming_hack), &ptd);
		}
	} else {
		g_signal_connect (msg, "wrote_chunk",
				  G_CALLBACK (write_next_chunk), &ptd);
	}

	if (flags & PROPER_STREAMING) {
		soup_message_set_flags (msg, SOUP_MESSAGE_CAN_REBUILD);
		if (flags & RESTART) {
			g_signal_connect (msg, "restarted",
					  G_CALLBACK (restarted_streaming), &ptd);
		}
	}

	g_signal_connect (msg, "wrote_headers",
			  G_CALLBACK (write_next_chunk), &ptd);
	g_signal_connect (msg, "wrote_body_data",
			  G_CALLBACK (wrote_body_data), &ptd);
	soup_session_send_message (session, msg);

	if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
		debug_printf (1, "  message failed: %d %s\n",
			      msg->status_code, msg->reason_phrase);
		errors++;
	}

	if (msg->request_body->data) {
		debug_printf (1, "  msg->request_body set!\n");
		errors++;
	}
	if (msg->request_body->length != length || length != ptd.nwrote) {
		debug_printf (1, "  sent length mismatch: %d vs %d vs %d\n",
			      (int)msg->request_body->length, length, ptd.nwrote);
		errors++;
	}

	server_md5 = soup_message_headers_get_one (msg->response_headers,
						   "Content-MD5");
	if (!server_md5 || strcmp (client_md5, server_md5) != 0) {
		debug_printf (1, "  client/server data mismatch: %s vs %s\n",
			      client_md5, server_md5 ? server_md5 : "(null)");
		errors++;
	}

	g_object_unref (msg);
	g_checksum_free (check);

	if (uri != base_uri)
		soup_uri_free (uri);
}
Пример #13
0
static void
server_callback (SoupServer *server, SoupMessage *msg,
		 const char *path, GHashTable *query,
		 SoupClientContext *context, gpointer data)
{
	SoupURI *uri = soup_message_get_uri (msg);
	const char *server_protocol = data;

	soup_message_headers_append (msg->response_headers,
				     "X-Handled-By", "server_callback");

	if (!strcmp (path, "*")) {
		debug_printf (1, "    default server_callback got request for '*'!\n");
		errors++;
		soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);
		return;
	}

	if (msg->method != SOUP_METHOD_GET && msg->method != SOUP_METHOD_POST) {
		soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
		return;
	}

	if (!strcmp (path, "/redirect")) {
		soup_message_set_redirect (msg, SOUP_STATUS_FOUND, "/");
		return;
	}

	if (!strcmp (path, "/alias-redirect")) {
		SoupURI *redirect_uri;
		char *redirect_string;
		const char *redirect_protocol;

		redirect_protocol = soup_message_headers_get_one (msg->request_headers, "X-Redirect-Protocol");

		redirect_uri = soup_uri_copy (uri);
		soup_uri_set_scheme (redirect_uri, "foo");
		if (!g_strcmp0 (redirect_protocol, "https"))
			soup_uri_set_port (redirect_uri, ssl_base_uri->port);
		else
			soup_uri_set_port (redirect_uri, base_uri->port);
		soup_uri_set_path (redirect_uri, "/alias-redirected");
		redirect_string = soup_uri_to_string (redirect_uri, FALSE);

		soup_message_set_redirect (msg, SOUP_STATUS_FOUND, redirect_string);
		g_free (redirect_string);
		soup_uri_free (redirect_uri);
		return;
	} else if (!strcmp (path, "/alias-redirected")) {
		soup_message_set_status (msg, SOUP_STATUS_OK);
		soup_message_headers_append (msg->response_headers,
					     "X-Redirected-Protocol",
					     server_protocol);
		return;
	}

	if (!strcmp (path, "/slow")) {
		soup_server_pause_message (server, msg);
		g_object_set_data (G_OBJECT (msg), "server", server);
		soup_add_timeout (soup_server_get_async_context (server),
				  1000, timeout_finish_message, msg);
	}

	soup_message_set_status (msg, SOUP_STATUS_OK);
	if (!strcmp (uri->host, "foo")) {
		soup_message_set_response (msg, "text/plain",
					   SOUP_MEMORY_STATIC, "foo-index", 9);
		return;
	} else {
		soup_message_set_response (msg, "text/plain",
					   SOUP_MEMORY_STATIC, "index", 5);
		return;
	}
}
Пример #14
0
static void
do_request_test (SoupSession *session, SoupURI *base_uri, int test)
{
	SoupURI *uri = base_uri;
	PutTestData ptd;
	SoupMessage *msg;
	const char *client_md5, *server_md5;
	GChecksum *check;
	int i, length;
	gboolean streaming = FALSE;

	switch (test) {
	case 0:
		debug_printf (1, "PUT\n");
		break;

	case 1:
		debug_printf (1, "PUT w/ streaming\n");
		streaming = TRUE;
		break;

	case 2:
		debug_printf (1, "PUT w/ streaming and restart\n");
		streaming = TRUE;
		uri = soup_uri_copy (base_uri);
		soup_uri_set_path (uri, "/redirect");
		break;
	}

	ptd.session = session;
	make_put_chunk (&ptd.chunks[0], "one\r\n");
	make_put_chunk (&ptd.chunks[1], "two\r\n");
	make_put_chunk (&ptd.chunks[2], "three\r\n");
	ptd.next = ptd.nwrote = ptd.nfreed = 0;
	ptd.streaming = streaming;

	check = g_checksum_new (G_CHECKSUM_MD5);
	length = 0;
	for (i = 0; i < 3; i++) {
		g_checksum_update (check, (guchar *)ptd.chunks[i]->data,
				   ptd.chunks[i]->length);
		length += ptd.chunks[i]->length;
	}
	client_md5 = g_checksum_get_string (check);

	msg = soup_message_new_from_uri ("PUT", uri);
	soup_message_headers_set_encoding (msg->request_headers, SOUP_ENCODING_CHUNKED);
	soup_message_body_set_accumulate (msg->request_body, FALSE);
	soup_message_set_chunk_allocator (msg, error_chunk_allocator, NULL, NULL);
	if (streaming) {
		g_signal_connect (msg, "wrote_chunk",
				  G_CALLBACK (write_next_chunk_streaming_hack), &ptd);
		g_signal_connect (msg, "restarted",
				  G_CALLBACK (restarted_streaming_hack), &ptd);
	} else {
		g_signal_connect (msg, "wrote_chunk",
				  G_CALLBACK (write_next_chunk), &ptd);
	}
	g_signal_connect (msg, "wrote_headers",
			  G_CALLBACK (write_next_chunk), &ptd);
	g_signal_connect (msg, "wrote_body_data",
			  G_CALLBACK (wrote_body_data), &ptd);
	soup_session_send_message (session, msg);

	if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
		debug_printf (1, "  message failed: %d %s\n",
			      msg->status_code, msg->reason_phrase);
		errors++;
	}

	if (msg->request_body->data) {
		debug_printf (1, "  msg->request_body set!\n");
		errors++;
	}
	if (msg->request_body->length != length || length != ptd.nwrote) {
		debug_printf (1, "  sent length mismatch: %d vs %d vs %d\n",
			      (int)msg->request_body->length, length, ptd.nwrote);
		errors++;
	}

	server_md5 = soup_message_headers_get_one (msg->response_headers,
						   "Content-MD5");
	if (!server_md5 || strcmp (client_md5, server_md5) != 0) {
		debug_printf (1, "  client/server data mismatch: %s vs %s\n",
			      client_md5, server_md5 ? server_md5 : "(null)");
		errors++;
	}

	g_object_unref (msg);
	g_checksum_free (check);

	if (uri != base_uri)
		soup_uri_free (uri);
}