static JsonNode * postal_http_parse_body (SoupMessage *message, GError **error) { JsonParser *p; JsonNode *ret; g_assert(SOUP_IS_MESSAGE(message)); p = json_parser_new(); if (!json_parser_load_from_data(p, message->request_body->data, message->request_body->length, error)) { g_object_unref(p); return NULL; } if ((ret = json_parser_get_root(p))) { ret = json_node_copy(ret); } g_object_unref(p); if (!ret) { g_set_error(error, postal_json_error_quark(), 0, "Missing JSON payload."); } return ret; }
static void postal_http_set_user_badge_cb (GObject *object, GAsyncResult *result, gpointer user_data) { PostalService *service = (PostalService *)object; SoupMessage *message = user_data; PostalHttp *http; GError *error = NULL; ENTRY; g_assert(POSTAL_IS_SERVICE(service)); g_assert(SOUP_IS_MESSAGE(message)); http = g_object_get_data(G_OBJECT(message), "http"); if (!postal_service_set_user_badge_finish(service, result, &error)) { postal_http_reply_error(http, message, error); g_object_unref(message); EXIT; } soup_message_set_status(message, SOUP_STATUS_OK); soup_server_unpause_message(http->priv->server, message); g_object_unref(message); EXIT; }
static void postal_http_find_device_cb (GObject *object, GAsyncResult *result, gpointer user_data) { PostalService *service = (PostalService *)object; PostalDevice *device; SoupMessage *message = user_data; PostalHttp *http; GError *error = NULL; ENTRY; g_assert(POSTAL_IS_SERVICE(service)); g_assert(SOUP_IS_MESSAGE(message)); http = g_object_get_data(user_data, "http"); g_assert(POSTAL_IS_HTTP(http)); if (!(device = postal_service_find_device_finish(service, result, &error))) { postal_http_reply_error(http, message, error); g_error_free(error); GOTO(failure); } postal_http_reply_device(http, message, SOUP_STATUS_OK, device); g_object_unref(device); failure: g_object_unref(message); EXIT; }
static void postal_http_router (SoupServer *server, SoupMessage *message, const gchar *path, GHashTable *query, SoupClientContext *client, gpointer user_data) { PostalHttpPrivate *priv; PostalHttp *http = user_data; ENTRY; g_assert(SOUP_IS_SERVER(server)); g_assert(SOUP_IS_MESSAGE(message)); g_assert(path); g_assert(client); g_assert(POSTAL_IS_HTTP(http)); priv = http->priv; g_object_set_data_full(G_OBJECT(message), "http", g_object_ref(http), g_object_unref); if (!url_router_route(priv->router, server, message, path, query, client)) { soup_message_set_status(message, SOUP_STATUS_NOT_FOUND); } EXIT; }
/** * soup_input_stream_new: * @session: the #SoupSession to use * @msg: the #SoupMessage whose response will be streamed * * Prepares to send @msg over @session, and returns a #GInputStream * that can be used to read the response. * * @msg may not be sent until the first read call; if you need to look * at the status code or response headers before reading the body, you * can use soup_input_stream_send() or soup_input_stream_send_async() * to force the message to be sent and the response headers read. * * If @msg gets a non-2xx result, the first read (or send) will return * an error with type %SOUP_INPUT_STREAM_HTTP_ERROR. * * Internally, #SoupInputStream is implemented using asynchronous I/O, * so if you are using the synchronous API (eg, * g_input_stream_read()), you should create a new #GMainContext and * set it as the %SOUP_SESSION_ASYNC_CONTEXT property on @session. (If * you don't, then synchronous #GInputStream calls will cause the main * loop to be run recursively.) The async #GInputStream API works fine * with %SOUP_SESSION_ASYNC_CONTEXT either set or unset. * * Returns: a new #GInputStream. **/ GInputStream * soup_input_stream_new (SoupSession *session, SoupMessage *msg) { SoupInputStream *stream; SoupInputStreamPrivate *priv; g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL); stream = g_object_new (SOUP_TYPE_INPUT_STREAM, NULL); priv = SOUP_INPUT_STREAM_GET_PRIVATE (stream); priv->session = g_object_ref (session); priv->async_context = soup_session_get_async_context (session); priv->msg = g_object_ref (msg); g_signal_connect (msg, "got_headers", G_CALLBACK (soup_input_stream_got_headers), stream); g_signal_connect (msg, "got_chunk", G_CALLBACK (soup_input_stream_got_chunk), stream); g_signal_connect (msg, "finished", G_CALLBACK (soup_input_stream_finished), stream); soup_input_stream_queue_message (stream); return G_INPUT_STREAM (stream); }
static void soup_logger_request_started (SoupSessionFeature *feature, SoupSession *session, SoupMessage *msg, SoupSocket *socket) { SoupLogger *logger = SOUP_LOGGER (feature); gboolean restarted; guint msg_id; g_return_if_fail (SOUP_IS_SESSION (session)); g_return_if_fail (SOUP_IS_MESSAGE (msg)); g_return_if_fail (SOUP_IS_SOCKET (socket)); msg_id = soup_logger_get_id (logger, msg); if (msg_id) restarted = TRUE; else { soup_logger_set_id (logger, msg); restarted = FALSE; } if (!soup_logger_get_id (logger, session)) soup_logger_set_id (logger, session); if (!soup_logger_get_id (logger, socket)) soup_logger_set_id (logger, socket); print_request (logger, msg, session, socket, restarted); soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, ' ', ""); }
/** * soup_auth_update: * @auth: a #SoupAuth * @msg: the #SoupMessage @auth is being updated for * @auth_header: the WWW-Authenticate/Proxy-Authenticate header * * Updates @auth with the information from @msg and @auth_header, * possibly un-authenticating it. As with soup_auth_new(), this is * normally only used by #SoupSession. * * Return value: %TRUE if @auth is still a valid (but potentially * unauthenticated) #SoupAuth. %FALSE if something about @auth_params * could not be parsed or incorporated into @auth at all. **/ gboolean soup_auth_update (SoupAuth *auth, SoupMessage *msg, const char *auth_header) { GHashTable *params; const char *scheme, *realm; gboolean was_authenticated, success; g_return_val_if_fail (SOUP_IS_AUTH (auth), FALSE); g_return_val_if_fail (SOUP_IS_MESSAGE (msg), FALSE); g_return_val_if_fail (auth_header != NULL, FALSE); scheme = soup_auth_get_scheme_name (auth); if (g_ascii_strncasecmp (auth_header, scheme, strlen (scheme)) != 0) return FALSE; params = soup_header_parse_param_list (auth_header + strlen (scheme)); if (!params) params = g_hash_table_new (NULL, NULL); realm = g_hash_table_lookup (params, "realm"); if (realm && auth->realm && strcmp (realm, auth->realm) != 0) { soup_header_free_param_list (params); return FALSE; } was_authenticated = soup_auth_is_authenticated (auth); success = SOUP_AUTH_GET_CLASS (auth)->update (auth, msg, params); if (was_authenticated != soup_auth_is_authenticated (auth)) g_object_notify (G_OBJECT (auth), SOUP_AUTH_IS_AUTHENTICATED); soup_header_free_param_list (params); return success; }
static void postal_http_notify_cb (GObject *object, GAsyncResult *result, gpointer user_data) { PostalService *service = (PostalService *)object; SoupMessage *message = user_data; PostalHttp *http; GError *error = NULL; ENTRY; g_assert(POSTAL_IS_SERVICE(service)); g_assert(SOUP_IS_MESSAGE(message)); http = g_object_get_data(user_data, "http"); g_assert(POSTAL_IS_HTTP(http)); if (!postal_service_notify_finish(service, result, &error)) { postal_http_reply_error(http, message, error); g_error_free(error); g_object_unref(message); EXIT; } soup_message_set_status(message, SOUP_STATUS_OK); soup_server_unpause_message(http->priv->server, message); soup_message_headers_append(message->response_headers, "Content-Type", "application/json"); g_object_unref(message); EXIT; }
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); } }
/** * soup_session_requeue_message: * @session: a #SoupSession * @msg: the message to requeue * * This causes @msg to be placed back on the queue to be attempted * again. **/ void soup_session_requeue_message (SoupSession *session, SoupMessage *msg) { g_return_if_fail (SOUP_IS_SESSION (session)); g_return_if_fail (SOUP_IS_MESSAGE (msg)); SOUP_SESSION_GET_CLASS (session)->requeue_message (session, msg); }
SoupSoapMessage * soup_soap_message_new_response (SoupMessage *msg) { g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL); return soup_soap_message_new (msg->response_headers, msg->response_body); }
/** * soup_session_send_message: * @session: a #SoupSession * @msg: the message to send * * Synchronously send @msg. This call will not return until the * transfer is finished successfully or there is an unrecoverable * error. * * @msg is not freed upon return. * * Return value: the HTTP status code of the response */ guint soup_session_send_message (SoupSession *session, SoupMessage *msg) { g_return_val_if_fail (SOUP_IS_SESSION (session), SOUP_STATUS_MALFORMED); g_return_val_if_fail (SOUP_IS_MESSAGE (msg), SOUP_STATUS_MALFORMED); return SOUP_SESSION_GET_CLASS (session)->send_message (session, msg); }
/** * soup_server_unpause_message: * @server: a #SoupServer * @msg: a #SoupMessage associated with @server. * * Resumes I/O on @msg. Use this to resume after calling * soup_server_pause_message(), or after adding a new chunk to a * chunked response. * * I/O won't actually resume until you return to the main loop. **/ void soup_server_unpause_message (SoupServer *server, SoupMessage *msg) { g_return_if_fail (SOUP_IS_SERVER (server)); g_return_if_fail (SOUP_IS_MESSAGE (msg)); soup_message_io_unpause (msg); }
/** * soup_session_unpause_message: * @session: a #SoupSession * @msg: a #SoupMessage currently running on @session * * Resumes HTTP I/O on @msg. Use this to resume after calling * soup_sessino_pause_message(). * * If @msg is being sent via blocking I/O, this will resume reading or * writing immediately. If @msg is using non-blocking I/O, then * reading or writing won't resume until you return to the main loop. **/ void soup_session_unpause_message (SoupSession *session, SoupMessage *msg) { g_return_if_fail (SOUP_IS_SESSION (session)); g_return_if_fail (SOUP_IS_MESSAGE (msg)); soup_message_io_unpause (msg); }
/** * soup_session_queue_message: * @session: a #SoupSession * @msg: the message to queue * @callback: a #SoupSessionCallback which will be called after the * message completes or when an unrecoverable error occurs. * @user_data: a pointer passed to @callback. * * Queues the message @msg for sending. All messages are processed * while the glib main loop runs. If @msg has been processed before, * any resources related to the time it was last sent are freed. * * Upon message completion, the callback specified in @callback will * be invoked (in the thread associated with @session's async * context). If after returning from this callback the message has not * been requeued, @msg will be unreffed. */ void soup_session_queue_message (SoupSession *session, SoupMessage *msg, SoupSessionCallback callback, gpointer user_data) { g_return_if_fail (SOUP_IS_SESSION (session)); g_return_if_fail (SOUP_IS_MESSAGE (msg)); SOUP_SESSION_GET_CLASS (session)->queue_message (session, msg, callback, user_data); }
void HTTPClientReceiver::start(bool dump) { if (!_world->parser()) _world->load_module("serialisation"); SoupMessage* msg = soup_message_new("GET", (_url + "/stream").c_str()); assert(SOUP_IS_MESSAGE(msg)); soup_session_queue_message(client_session, msg, message_callback, this); }
static void soup_logger_request_unqueued (SoupSessionFeature *logger, SoupSession *session, SoupMessage *msg) { g_return_if_fail (SOUP_IS_MESSAGE (msg)); g_signal_handlers_disconnect_by_func (msg, got_informational, logger); g_signal_handlers_disconnect_by_func (msg, got_body, logger); }
char * soup_content_sniffer_sniff (SoupContentSniffer *sniffer, SoupMessage *msg, SoupBuffer *buffer, GHashTable **params) { g_return_val_if_fail (SOUP_IS_CONTENT_SNIFFER (sniffer), NULL); g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL); g_return_val_if_fail (buffer != NULL, NULL); return SOUP_CONTENT_SNIFFER_GET_CLASS (sniffer)->sniff (sniffer, msg, buffer, params); }
void HTTPClientReceiver::send(SoupMessage* msg) { if (!client_session) { LOG(debug) << "Starting session" << endl; client_session = soup_session_sync_new(); } assert(SOUP_IS_MESSAGE(msg)); soup_session_queue_message(client_session, msg, message_callback, client_receiver); }
/** * soup_auth_is_ready: * @auth: a #SoupAuth * @msg: a #SoupMessage * * Tests if @auth is ready to make a request for @msg with. For most * auths, this is equivalent to soup_auth_is_authenticated(), but for * some auth types (eg, NTLM), the auth may be sendable (eg, as an * authentication request) even before it is authenticated. * * Return value: %TRUE if @auth is ready to make a request with. * * Since: 2.42 **/ gboolean soup_auth_is_ready (SoupAuth *auth, SoupMessage *msg) { g_return_val_if_fail (SOUP_IS_AUTH (auth), TRUE); g_return_val_if_fail (SOUP_IS_MESSAGE (msg), TRUE); if (SOUP_AUTH_GET_CLASS (auth)->is_ready) return SOUP_AUTH_GET_CLASS (auth)->is_ready (auth, msg); else return SOUP_AUTH_GET_CLASS (auth)->is_authenticated (auth); }
/** * soup_session_cancel_message: * @session: a #SoupSession * @msg: the message to cancel * @status_code: status code to set on @msg (generally * %SOUP_STATUS_CANCELLED) * * Causes @session to immediately finish processing @msg (regardless * of its current state) with a final status_code of @status_code. You * may call this at any time after handing @msg off to @session; if * @session has started sending the request but has not yet received * the complete response, then it will close the request's connection. * Note that with non-idempotent requests (eg, %POST, %PUT, %DELETE) * it is possible that you might cancel the request after the server * acts on it, but before it returns a response, leaving the remote * resource in an unknown state. * * If the message is cancelled while its response body is being read, * then the response body in @msg will be left partially-filled-in. * The response headers, on the other hand, will always be either * empty or complete. * * For messages queued with soup_session_queue_message() (and * cancelled from the same thread), the callback will be invoked * before soup_session_cancel_message() returns. **/ void soup_session_cancel_message (SoupSession *session, SoupMessage *msg, guint status_code) { g_return_if_fail (SOUP_IS_SESSION (session)); g_return_if_fail (SOUP_IS_MESSAGE (msg)); /* If the message is already ending, don't do anything */ if (soup_message_get_io_status (msg) == SOUP_MESSAGE_IO_STATUS_FINISHED) return; SOUP_SESSION_GET_CLASS (session)->cancel_message (session, msg, status_code); }
static void soup_logger_request_queued (SoupSessionFeature *logger, SoupSession *session, SoupMessage *msg) { g_return_if_fail (SOUP_IS_MESSAGE (msg)); g_signal_connect (msg, "got-informational", G_CALLBACK (got_informational), logger); g_signal_connect (msg, "got-body", G_CALLBACK (got_body), logger); }
/** * soup_connection_send_request: * @conn: a #SoupConnection * @req: a #SoupMessage * * Sends @req on @conn. This is a low-level function, intended for use * by #SoupSession. **/ void soup_connection_send_request (SoupConnection *conn, SoupMessage *req) { SoupConnectionPrivate *priv; g_return_if_fail (SOUP_IS_CONNECTION (conn)); g_return_if_fail (SOUP_IS_MESSAGE (req)); priv = SOUP_CONNECTION_GET_PRIVATE (conn); g_return_if_fail (priv->state != SOUP_CONNECTION_NEW && priv->state != SOUP_CONNECTION_DISCONNECTED); if (req != priv->cur_req) set_current_request (conn, req); soup_message_send_request (req, priv->socket, conn, priv->proxy_uri != NULL); }
static void postal_http_reply_devices (PostalHttp *http, SoupMessage *message, guint status, GPtrArray *devices) { JsonGenerator *g; PostalDevice *device; JsonArray *ar; JsonNode *node; JsonNode *child; gchar *json_buf; gsize length; guint i; g_assert(SOUP_IS_MESSAGE(message)); g_assert(devices); ar = json_array_new(); node = json_node_new(JSON_NODE_ARRAY); for (i = 0; i < devices->len; i++) { device = g_ptr_array_index(devices, i); if ((child = postal_device_save_to_json(device, NULL))) { json_array_add_element(ar, child); } } json_node_set_array(node, ar); json_array_unref(ar); g = json_generator_new(); json_generator_set_root(g, node); json_node_free(node); json_generator_set_indent(g, 2); json_generator_set_pretty(g, TRUE); json_buf = json_generator_to_data(g, &length); g_object_unref(g); soup_message_set_response(message, "application/json", SOUP_MEMORY_TAKE, json_buf, length); soup_message_set_status(message, status ?: SOUP_STATUS_OK); soup_server_unpause_message(http->priv->server, message); }
static void postal_http_add_device_cb (GObject *object, GAsyncResult *result, gpointer user_data) { PostalService *service = (PostalService *)object; PostalDevice *device; SoupMessage *message = user_data; PostalHttp *http; gboolean updated_existing = FALSE; GError *error = NULL; gchar *str; ENTRY; g_assert(POSTAL_IS_SERVICE(service)); g_assert(SOUP_IS_MESSAGE(message)); http = g_object_get_data(user_data, "http"); g_assert(POSTAL_IS_HTTP(http)); if (!postal_service_add_device_finish(service, result, &updated_existing, &error)) { postal_http_reply_error(http, message, error); g_error_free(error); GOTO(failure); } if ((device = POSTAL_DEVICE(g_object_get_data(G_OBJECT(message), "device")))) { str = g_strdup_printf("/v1/users/%s/devices/%s", postal_device_get_user(device), postal_device_get_device_token(device)); soup_message_headers_append(message->response_headers, "Location", str); g_free(str); postal_http_reply_device(http, message, updated_existing ? SOUP_STATUS_OK : SOUP_STATUS_CREATED, device); } else { g_assert_not_reached(); } failure: g_object_unref(message); EXIT; }
static void postal_http_reply_device (PostalHttp *http, SoupMessage *message, guint status, PostalDevice *device) { PostalHttpPrivate *priv; JsonGenerator *g; JsonNode *node; GError *error = NULL; gchar *json_buf; gsize length; ENTRY; g_assert(SOUP_IS_MESSAGE(message)); g_assert(POSTAL_IS_DEVICE(device)); g_assert(POSTAL_IS_HTTP(http)); priv = http->priv; if (!(node = postal_device_save_to_json(device, &error))) { postal_http_reply_error(http, message, error); soup_server_unpause_message(priv->server, message); g_error_free(error); EXIT; } g = json_generator_new(); json_generator_set_indent(g, 2); json_generator_set_pretty(g, TRUE); json_generator_set_root(g, node); json_node_free(node); if ((json_buf = json_generator_to_data(g, &length))) { soup_message_set_response(message, "application/json", SOUP_MEMORY_TAKE, json_buf, length); } soup_message_set_status(message, status); soup_server_unpause_message(priv->server, message); g_object_unref(g); EXIT; }
/** * soup_output_stream_new: * @session: the #SoupSession to use * @msg: the #SoupMessage whose request will be streamed * @size: the total size of the request body, or -1 if not known * * Prepares to send @msg over @session, and returns a #GOutputStream * that can be used to write the response. The server's response will * be available in @msg after calling soup_output_stream_close() * (which will return a %SOUP_OUTPUT_STREAM_HTTP_ERROR #GError if the * status is not 2xx). * * If you know the total number of bytes that will be written, pass * that in @size. Otherwise, pass -1. (If you pass a size, you MUST * write that many bytes to the stream; Trying to write more than * that, or closing the stream without having written enough, will * result in an error. * * In some situations, the request will not actually be sent until you * call g_output_stream_close(). (In fact, currently this is *always* * true.) * * Internally, #SoupOutputStream is implemented using asynchronous * I/O, so if you are using the synchronous API (eg, * g_output_stream_write()), you should create a new #GMainContext and * set it as the %SOUP_SESSION_ASYNC_CONTEXT property on @session. (If * you don't, then synchronous #GOutputStream calls will cause the * main loop to be run recursively.) The async #GOutputStream API * works fine with %SOUP_SESSION_ASYNC_CONTEXT either set or unset. * * Returns: a new #GOutputStream. **/ GOutputStream * soup_output_stream_new (SoupSession *session, SoupMessage *msg, goffset size) { SoupOutputStream *stream; SoupOutputStreamPrivate *priv; g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL); stream = g_object_new (SOUP_TYPE_OUTPUT_STREAM, NULL); priv = SOUP_OUTPUT_STREAM_GET_PRIVATE (stream); priv->session = g_object_ref (session); priv->async_context = soup_session_get_async_context (session); priv->msg = g_object_ref (msg); priv->size = size; return G_OUTPUT_STREAM (stream); }
/** * soup_auth_new: * @type: the type of auth to create (a subtype of #SoupAuth) * @msg: the #SoupMessage the auth is being created for * @auth_header: the WWW-Authenticate/Proxy-Authenticate header * * Creates a new #SoupAuth of type @type with the information from * @msg and @auth_header. * * This is called by #SoupSession; you will normally not create auths * yourself. * * Return value: the new #SoupAuth, or %NULL if it could not be * created **/ SoupAuth * soup_auth_new (GType type, SoupMessage *msg, const char *auth_header) { SoupAuth *auth; GHashTable *params; const char *scheme, *realm; g_return_val_if_fail (g_type_is_a (type, SOUP_TYPE_AUTH), NULL); g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL); g_return_val_if_fail (auth_header != NULL, NULL); auth = g_object_new (type, SOUP_AUTH_IS_FOR_PROXY, (msg->status_code == SOUP_STATUS_PROXY_UNAUTHORIZED), SOUP_AUTH_HOST, soup_message_get_uri (msg)->host, NULL); scheme = soup_auth_get_scheme_name (auth); if (g_ascii_strncasecmp (auth_header, scheme, strlen (scheme)) != 0) { g_object_unref (auth); return NULL; } params = soup_header_parse_param_list (auth_header + strlen (scheme)); if (!params) { g_object_unref (auth); return NULL; } realm = g_hash_table_lookup (params, "realm"); if (!realm) { soup_header_free_param_list (params); g_object_unref (auth); return NULL; } auth->realm = g_strdup (realm); if (!SOUP_AUTH_GET_CLASS (auth)->update (auth, msg, params)) { g_object_unref (auth); auth = NULL; } soup_header_free_param_list (params); return auth; }
static void postal_http_handle_v1_users_user_devices (UrlRouter *router, SoupServer *server, SoupMessage *message, const gchar *path, GHashTable *params, GHashTable *query, SoupClientContext *client, gpointer user_data) { const gchar *user; PostalHttp *http = user_data; ENTRY; g_assert(router); g_assert(SOUP_IS_SERVER(server)); g_assert(SOUP_IS_MESSAGE(message)); g_assert(path); g_assert(params); g_assert(g_hash_table_contains(params, "user")); g_assert(client); g_assert(POSTAL_IS_HTTP(http)); user = g_hash_table_lookup(params, "user"); soup_server_pause_message(server, message); if (message->method == SOUP_METHOD_GET) { postal_service_find_devices(http->priv->service, user, get_int_param(query, "offset"), get_int_param(query, "limit"), NULL, /* TODO */ devices_get_cb, g_object_ref(message)); EXIT; } soup_message_set_status(message, SOUP_STATUS_METHOD_NOT_ALLOWED); soup_server_unpause_message(server, message); EXIT; }
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); } } }