static void get_user_info_ready_cb (SoupSession *session, SoupMessage *msg, gpointer user_data) { FacebookService *self = user_data; GSimpleAsyncResult *result; SoupBuffer *body; DomDocument *doc = NULL; GError *error = NULL; result = facebook_connection_get_result (self->priv->conn); if (msg->status_code != 200) { g_simple_async_result_set_error (result, SOUP_HTTP_ERROR, msg->status_code, "%s", soup_status_get_phrase (msg->status_code)); g_simple_async_result_complete_in_idle (result); return; } body = soup_message_body_flatten (msg->response_body); if (facebook_utils_parse_response (body, &doc, &error)) { DomElement *node; FacebookUser *user = NULL; for (node = DOM_ELEMENT (doc)->first_child; node; node = node->next_sibling) { if (g_strcmp0 (node->tag_name, "users_getInfo_response") == 0) { DomElement *child; for (child = node->first_child; child; child = child->next_sibling) { if (g_strcmp0 (child->tag_name, "user") == 0) { user = facebook_user_new (); dom_domizable_load_from_element (DOM_DOMIZABLE (user), child); g_simple_async_result_set_op_res_gpointer (result, user, (GDestroyNotify) g_object_unref); } } } } if (user == NULL) { error = g_error_new_literal (FACEBOOK_CONNECTION_ERROR, 0, _("Unknown error")); g_simple_async_result_set_from_error (result, error); } g_object_unref (doc); } else g_simple_async_result_set_from_error (result, error); g_simple_async_result_complete_in_idle (result); soup_buffer_free (body); }
static void _process_check_resp(SoupSession *ss, SoupMessage *msg, gpointer user_data) { GWQSession *wqs; const guint8* data; gsize size; SoupBuffer *sBuf; int i; wqs = (GWQSession*)user_data; sBuf = soup_message_body_flatten(msg->response_body); GWQ_DBG("check responsed, retcode=%d, reason:%s\n", msg->status_code, msg->reason_phrase); if (sBuf) { soup_buffer_get_data(sBuf, &data, &size); GWQ_DBG("bodySize=%d\nbody:%s\n", size, data); if (size>0) { const gchar *tmpCStr, *vc, *end; tmpCStr = (const gchar*)data; end = (gchar*)(data+size-1); if (tmpCStr && (tmpCStr = g_strstr_len(tmpCStr, size, ",")) && tmpCStr < end && *(++tmpCStr) && (tmpCStr = g_strstr_len(tmpCStr, size, "'")) && tmpCStr < end && *(vc = ++tmpCStr) && (tmpCStr = g_strstr_len(tmpCStr, size, "'")) && tmpCStr < end) { g_string_assign(wqs->verifyCode, ""); g_string_append_len(wqs->verifyCode, vc, tmpCStr-vc); GWQ_DBG("vc.verifyCode: %s\n", wqs->verifyCode->str); } if (tmpCStr && (tmpCStr = g_strstr_len(tmpCStr, size, ",")) && tmpCStr < end && *(++tmpCStr) && (tmpCStr = g_strstr_len(tmpCStr, size, "'")) && tmpCStr < end && *(vc = ++tmpCStr) && (tmpCStr = g_strstr_len(tmpCStr, size, "'")) && tmpCStr < end) { g_string_assign(wqs->vcUin, ""); g_string_append_len(wqs->vcUin, vc, tmpCStr-vc); GWQ_DBG("vc.uin:%s\n", wqs->vcUin->str); wqs->vcUinAryLen = (wqs->vcUin->len)>>2; if (wqs->vcUinAryLen < sizeof(wqs->vcUinAry)) { for (i=0; i<wqs->vcUinAryLen; i++) { wqs->vcUinAry[i] = DigestCharToChar(wqs->vcUin->str[(i<<2)+2], wqs->vcUin->str[(i<<2)+3]); GWQ_DBG("%x\n", wqs->vcUinAry[i]); } } } } soup_buffer_free(sBuf); }
int main (int argc, char **argv) { SoupSession *session; const char *base_uri; test_init (argc, argv, NULL); apache_init (); base_uri = "http://127.0.0.1:47524/"; get_correct_response (base_uri); debug_printf (1, "\nFully async, fast requests\n"); session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL); g_signal_connect (session, "authenticate", G_CALLBACK (authenticate), NULL); do_fully_async_test (session, base_uri, "/", TRUE, SOUP_STATUS_OK); do_fully_async_test (session, base_uri, "/Basic/realm1/", TRUE, SOUP_STATUS_UNAUTHORIZED); do_fully_async_test (session, base_uri, "/Basic/realm2/", TRUE, SOUP_STATUS_OK); soup_test_session_abort_unref (session); debug_printf (1, "\nFully async, slow requests\n"); session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL); g_signal_connect (session, "authenticate", G_CALLBACK (authenticate), NULL); do_fully_async_test (session, base_uri, "/", FALSE, SOUP_STATUS_OK); do_fully_async_test (session, base_uri, "/Basic/realm1/", FALSE, SOUP_STATUS_UNAUTHORIZED); do_fully_async_test (session, base_uri, "/Basic/realm2/", FALSE, SOUP_STATUS_OK); soup_test_session_abort_unref (session); debug_printf (1, "\nSynchronously async\n"); session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL); g_signal_connect (session, "authenticate", G_CALLBACK (authenticate), NULL); do_synchronously_async_test (session, base_uri, "/", SOUP_STATUS_OK); do_synchronously_async_test (session, base_uri, "/Basic/realm1/", SOUP_STATUS_UNAUTHORIZED); do_synchronously_async_test (session, base_uri, "/Basic/realm2/", SOUP_STATUS_OK); soup_test_session_abort_unref (session); soup_buffer_free (correct_response); test_cleanup (); return errors != 0; }
void trex_callback(SoupServer *server, SoupMessage *msg, const char *path, GHashTable *query, const char *dest) { SoupMessage *new_msg; SoupSession *session; char *uri_str; struct destination_info *to = malloc(sizeof(struct destination_info)); to->server = server; to->msg = msg; session = soup_session_async_new(); uri_str = soup_uri_to_string(soup_message_get_uri(msg), true); /* * TODO Memory Leak :-) */ uri_str = g_strjoin(NULL, dest, uri_str, NULL); g_print("[%p] %s %s HTTP/1.%d\n", msg, msg->method, uri_str, soup_message_get_http_version(msg)); /* build new request */ new_msg = soup_message_new(msg->method, uri_str); soup_message_headers_foreach(msg->request_headers, copy_header, new_msg->request_headers); soup_message_headers_remove(new_msg->request_headers, "Host"); if (msg->request_body->length) { SoupBuffer *request = soup_message_body_flatten(msg->request_body); soup_message_body_append_buffer(new_msg->request_body, request); soup_buffer_free(request); } soup_message_headers_set_encoding(msg->response_headers, SOUP_ENCODING_CHUNKED); soup_server_pause_message(server, msg); g_signal_connect(new_msg, "got_headers", G_CALLBACK(recv_headers), to); g_signal_connect(new_msg, "got_chunk", G_CALLBACK(recv_chunk), to); soup_session_queue_message(session, new_msg, finish_msg, to); g_object_ref(msg); g_object_unref(session); }
/* * If there is a mismatch or an error, then gda_connection_add_event_string() is used * * - if all OK, extracs the <challenge> value and replace cdata->next_challenge with it (or simply * reset cdata->next_challenge to NULL) * * Returns: a new #xmlDocPtr, or %NULL on error */ xmlDocPtr _gda_web_decode_response (GdaConnection *cnc, WebConnectionData *cdata, SoupMessageBody *body, gchar *out_status_chr, guint *out_counter_id) { SoupBuffer *sbuffer; xmlDocPtr doc; sbuffer = soup_message_body_flatten (body); #ifdef DEBUG_WEB_PROV g_print ("=== START of response ===\n%s\n=== END of response ===\n", (gchar*) sbuffer->data); #endif doc = decode_buffer_response (cnc, cdata, sbuffer, out_status_chr, out_counter_id); soup_buffer_free (sbuffer); return doc; }
static gssize webkit_soup_directory_input_stream_read (GInputStream *input, void *buffer, gsize count, GCancellable *cancellable, GError **error) { WebKitSoupDirectoryInputStream *stream = WEBKIT_SOUP_DIRECTORY_INPUT_STREAM (input); gsize total, size; for (total = 0; total < count; total += size) { if (stream->buffer == NULL) { stream->buffer = webkit_soup_directory_input_stream_read_next_file (stream, cancellable, error); if (stream->buffer == NULL) { /* FIXME: Is this correct or should we forward the error? */ if (total) g_clear_error (error); return total; } } size = MIN (stream->buffer->length, count - total); memcpy ((char *)buffer + total, stream->buffer->data, size); if (size == stream->buffer->length) { soup_buffer_free (stream->buffer); stream->buffer = NULL; } else { SoupBuffer *sub = soup_buffer_new_subbuffer (stream->buffer, size, stream->buffer->length - size); soup_buffer_free (stream->buffer); stream->buffer = sub; } } return total; }
static void soup_soap_message_constructed (GObject *object) { SoupSoapMessage *msg = SOUP_SOAP_MESSAGE (object); SoupSoapMessagePrivate *priv = msg->priv; soup_buffer_free (soup_message_body_flatten (priv->message_body)); xmlNodePtr current_node, op_node; xmlDocPtr doc = xmlParseDoc (BAD_CAST priv->message_body->data); if (doc) { current_node = xmlDocGetRootElement (doc); if (current_node && current_node->name && xmlStrEqual (current_node->name, BAD_CAST "Envelope")) { for (current_node = current_node->children; current_node != NULL; current_node = current_node->next) { if (current_node->type == XML_ELEMENT_NODE) { if (xmlStrEqual (current_node->name, BAD_CAST "Header")) parse_param (priv->header, current_node); else if (xmlStrEqual (current_node->name, BAD_CAST "Body")) { op_node = current_node->children; if (op_node) { soup_soap_param_set_name (SOUP_SOAP_PARAM (priv->body), (gchar *) op_node->name); parse_param (priv->body, op_node); } } } } } } xmlFreeDoc (doc); G_OBJECT_CLASS (soup_soap_message_parent_class)->constructed (object); }
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); }
static void get_logged_in_user_ready_cb (SoupSession *session, SoupMessage *msg, gpointer user_data) { FacebookService *self = user_data; GSimpleAsyncResult *result; SoupBuffer *body; DomDocument *doc = NULL; GError *error = NULL; result = facebook_connection_get_result (self->priv->conn); if (msg->status_code != 200) { g_simple_async_result_set_error (result, SOUP_HTTP_ERROR, msg->status_code, "%s", soup_status_get_phrase (msg->status_code)); g_simple_async_result_complete_in_idle (result); return; } body = soup_message_body_flatten (msg->response_body); if (facebook_utils_parse_response (body, &doc, &error)) { DomElement *root; char *uid = NULL; root = DOM_ELEMENT (doc)->first_child; if (g_strcmp0 (root->tag_name, "users_getLoggedInUser_response") == 0) uid = g_strdup (dom_element_get_inner_text (root)); if (uid == NULL) { error = g_error_new_literal (FACEBOOK_CONNECTION_ERROR, 0, _("Unknown error")); g_simple_async_result_set_from_error (result, error); } else g_simple_async_result_set_op_res_gpointer (result, uid, g_free); g_object_unref (doc); } else g_simple_async_result_set_from_error (result, error); g_simple_async_result_complete_in_idle (result); soup_buffer_free (body); }
static gboolean picasa_web_utils_parse_json_response (SoupMessage *msg, JsonNode **node, GError **error) { JsonParser *parser; SoupBuffer *body; g_return_val_if_fail (msg != NULL, FALSE); g_return_val_if_fail (node != NULL, FALSE); *node = NULL; if ((msg->status_code != 200) && (msg->status_code != 400)) { *error = g_error_new (SOUP_HTTP_ERROR, msg->status_code, "%s", soup_status_get_phrase (msg->status_code)); return FALSE; } body = soup_message_body_flatten (msg->response_body); parser = json_parser_new (); if (json_parser_load_from_data (parser, body->data, body->length, error)) { JsonObject *obj; *node = json_node_copy (json_parser_get_root (parser)); obj = json_node_get_object (*node); if (json_object_has_member (obj, "error")) { JsonObject *error_obj; error_obj = json_object_get_object_member (obj, "error"); *error = g_error_new (WEB_SERVICE_ERROR, json_object_get_int_member (error_obj, "code"), "%s", json_object_get_string_member (error_obj, "message")); json_node_free (*node); *node = NULL; } } g_object_unref (parser); soup_buffer_free (body); return *node != NULL; }
/* Attempts to write @len bytes from @data. See the note at * read_metadata() for an explanation of the return value. */ static gboolean write_data (SoupMessage *msg, const char *data, guint len, gboolean body) { SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg); SoupMessageIOData *io = priv->io_data; SoupSocketIOStatus status; gsize nwrote; GError *error = NULL; SoupBuffer *chunk; const char *start; while (len > io->written) { status = soup_socket_write (io->sock, data + io->written, len - io->written, &nwrote, NULL, &error); switch (status) { case SOUP_SOCKET_EOF: case SOUP_SOCKET_ERROR: io_error (io->sock, msg, error); return FALSE; case SOUP_SOCKET_WOULD_BLOCK: return FALSE; case SOUP_SOCKET_OK: start = data + io->written; io->written += nwrote; if (body) { if (io->write_length) io->write_length -= nwrote; chunk = soup_buffer_new (SOUP_MEMORY_TEMPORARY, start, nwrote); SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK; soup_message_wrote_body_data (msg, chunk); soup_buffer_free (chunk); SOUP_MESSAGE_IO_RETURN_VAL_IF_CANCELLED_OR_PAUSED (FALSE); } break; } } io->written = 0; return TRUE; }
static void _oauth_service_get_request_token_ready_cb (SoupSession *session, SoupMessage *msg, gpointer user_data) { OAuthService *self = user_data; GSimpleAsyncResult *result; SoupBuffer *body; GHashTable *values; char *token; char *token_secret; result = _web_service_get_result (WEB_SERVICE (self)); if (msg->status_code != 200) { g_simple_async_result_set_error (result, SOUP_HTTP_ERROR, msg->status_code, "%s", soup_status_get_phrase (msg->status_code)); g_simple_async_result_complete_in_idle (result); return; } body = soup_message_body_flatten (msg->response_body); values = soup_form_decode (body->data); token = g_hash_table_lookup (values, "oauth_token"); token_secret = g_hash_table_lookup (values, "oauth_token_secret"); if ((token != NULL) && (token_secret != NULL)) { oauth_service_set_token (self, token); oauth_service_set_token_secret (self, token_secret); g_simple_async_result_set_op_res_gboolean (result, TRUE); } else { GError *error; error = g_error_new_literal (WEB_SERVICE_ERROR, WEB_SERVICE_ERROR_GENERIC, _("Unknown error")); g_simple_async_result_set_from_error (result, error); } g_simple_async_result_complete_in_idle (result); g_hash_table_destroy (values); soup_buffer_free (body); }
/* This is not a supported part of the API. Use SOUP_MESSAGE_CAN_REBUILD * instead. */ static void write_next_chunk_streaming_hack (SoupMessage *msg, gpointer user_data) { PutTestData *ptd = user_data; SoupBuffer *chunk; debug_printf (2, " freeing chunk at %d\n", ptd->nfreed); chunk = soup_message_body_get_chunk (msg->request_body, ptd->nfreed); if (chunk) { ptd->nfreed += chunk->length; soup_message_body_wrote_chunk (msg->request_body, chunk); soup_buffer_free (chunk); } else { debug_printf (1, " error: written chunk does not exist!\n"); errors++; } write_next_chunk (msg, user_data); }
static void append_buffer (SoupMessageBody *body, SoupBuffer *buffer) { SoupMessageBodyPrivate *priv = (SoupMessageBodyPrivate *)body; if (priv->last) { priv->last = g_slist_append (priv->last, buffer); priv->last = priv->last->next; } else priv->chunks = priv->last = g_slist_append (NULL, buffer); if (priv->flattened) { soup_buffer_free (priv->flattened); priv->flattened = NULL; body->data = NULL; } body->length += buffer->length; }
static gssize read_and_sniff (GInputStream *stream, gboolean blocking, GCancellable *cancellable, GError **error) { SoupContentSnifferStreamPrivate *priv = SOUP_CONTENT_SNIFFER_STREAM (stream)->priv; gssize nread; GError *my_error = NULL; SoupBuffer *buf; do { nread = g_pollable_stream_read (G_FILTER_INPUT_STREAM (stream)->base_stream, priv->buffer + priv->buffer_nread, priv->buffer_size - priv->buffer_nread, blocking, cancellable, &my_error); if (nread <= 0) break; priv->buffer_nread += nread; } while (priv->buffer_nread < priv->buffer_size); /* If we got EAGAIN or cancellation before filling the buffer, * just return that right away. Likewise if we got any other * error without ever reading any data. Otherwise, save the * error to return after we're done sniffing. */ if (my_error) { if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK) || g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_CANCELLED) || priv->buffer_nread == 0) { g_propagate_error (error, my_error); return -1; } else priv->error = my_error; } /* Sniff, then return the data */ buf = soup_buffer_new (SOUP_MEMORY_TEMPORARY, priv->buffer, priv->buffer_nread); priv->sniffed_type = soup_content_sniffer_sniff (priv->sniffer, priv->msg, buf, &priv->sniffed_params); soup_buffer_free (buf); priv->sniffing = FALSE; return priv->buffer_nread; }
static void server_callback (SoupServer *server, SoupMessage *msg, const char *path, GHashTable *query, SoupClientContext *context, gpointer data) { SoupMessage *msg2; char *uristr; uristr = soup_uri_to_string (soup_message_get_uri (msg), FALSE); printf ("[%p] %s %s HTTP/1.%d\n", msg, msg->method, uristr, soup_message_get_http_version (msg)); if (msg->method == SOUP_METHOD_CONNECT) { soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); return; } msg2 = soup_message_new (msg->method, uristr); msg2 = soup_message_new (msg->method, uristr); soup_message_headers_foreach (msg->request_headers, copy_header, msg2->request_headers); soup_message_headers_remove (msg2->request_headers, "Host"); soup_message_headers_remove (msg2->request_headers, "Connection"); if (msg->request_body->length) { SoupBuffer *request = soup_message_body_flatten (msg->request_body); soup_message_body_append_buffer (msg2->request_body, request); soup_buffer_free (request); } soup_message_headers_set_encoding (msg->response_headers, SOUP_ENCODING_CHUNKED); g_signal_connect (msg2, "got_headers", G_CALLBACK (send_headers), msg); g_signal_connect (msg2, "got_chunk", G_CALLBACK (send_chunk), msg); g_signal_connect (msg, "finished", G_CALLBACK (client_msg_failed), msg2); soup_session_queue_message (session, msg2, finish_msg, msg); g_object_ref (msg); soup_server_pause_message (server, msg); }
void e_gw_message_write_footer (SoupSoapMessage *msg) { soup_soap_message_end_element (msg); soup_soap_message_end_body (msg); soup_soap_message_end_envelope (msg); soup_soap_message_persist (msg); if (g_getenv ("GROUPWISE_DEBUG") && (atoi (g_getenv ("GROUPWISE_DEBUG")) == 1)) { const gchar *header = soup_message_headers_get (SOUP_MESSAGE (msg)->request_headers, "SOAPAction"); soup_buffer_free (soup_message_body_flatten (SOUP_MESSAGE (msg)->request_body)); if (header && g_str_equal (header, "loginRequest")) { gchar *body; gchar *begin = NULL; gchar *end = NULL; body = g_strdup (SOUP_MESSAGE (msg)->request_body->data); begin = g_strrstr (body, "<types:password>"); if (begin) begin = begin + strlen ("<types:password>"); end = g_strrstr (body , "</types:password>"); if (begin && end) { gchar *tmp; for (tmp = begin; tmp < end; tmp++) *tmp='X'; } fputc ('\n', stdout); fputs (body, stdout); fputc ('\n', stdout); g_free (body); } else { /* print request's body */ fputc ('\n', stdout); fputs (SOUP_MESSAGE (msg)->request_body->data, stdout); fputc ('\n', stdout); } } }
/** * soup_message_body_wrote_chunk: * @body: a #SoupMessageBody * @chunk: a #SoupBuffer returned from soup_message_body_get_chunk() * * Handles the #SoupMessageBody part of writing a chunk of data to the * network. Normally this is a no-op, but if you have set @body's * accumulate flag to %FALSE, then this will cause @chunk to be * discarded to free up memory. * * This is a low-level method which you should not need to use, and * there are further restrictions on its proper use which are not * documented here. * * Since: 2.4.1 **/ void soup_message_body_wrote_chunk (SoupMessageBody *body, SoupBuffer *chunk) { SoupMessageBodyPrivate *priv = (SoupMessageBodyPrivate *)body; SoupBuffer *chunk2; if (priv->accumulate) return; chunk2 = priv->chunks->data; g_return_if_fail (chunk->length == chunk2->length); g_return_if_fail (chunk == chunk2 || ((SoupBufferPrivate *)chunk2)->use == SOUP_MEMORY_TEMPORARY); priv->chunks = g_slist_remove (priv->chunks, chunk2); if (!priv->chunks) priv->last = NULL; priv->base_offset += chunk2->length; soup_buffer_free (chunk2); }
static void create_album_ready_cb (SoupSession *session, SoupMessage *msg, gpointer user_data) { PicasaWebService *self = user_data; GSimpleAsyncResult *result; SoupBuffer *body; DomDocument *doc; GError *error = NULL; result = _web_service_get_result (WEB_SERVICE (self)); if (msg->status_code != 201) { g_simple_async_result_set_error (result, SOUP_HTTP_ERROR, msg->status_code, "%s", soup_status_get_phrase (msg->status_code)); g_simple_async_result_complete_in_idle (result); return; } body = soup_message_body_flatten (msg->response_body); doc = dom_document_new (); if (dom_document_load (doc, body->data, body->length, &error)) { PicasaWebAlbum *album; album = picasa_web_album_new (); dom_domizable_load_from_element (DOM_DOMIZABLE (album), DOM_ELEMENT (doc)->first_child); g_simple_async_result_set_op_res_gpointer (result, album, (GDestroyNotify) g_object_unref); } else { g_simple_async_result_set_from_error (result, error); g_error_free (error); } g_simple_async_result_complete_in_idle (result); g_object_unref (doc); soup_buffer_free (body); }
static void write_next_chunk (SoupMessage *msg, gpointer user_data) { PutTestData *ptd = user_data; debug_printf (2, " writing chunk %d\n", ptd->next); if (ptd->streaming && ptd->next > 0 && ptd->chunks[ptd->next - 1]) { debug_printf (1, " error: next chunk requested before last one freed!\n"); errors++; } if (ptd->next < G_N_ELEMENTS (ptd->chunks)) { soup_message_body_append_buffer (msg->request_body, ptd->chunks[ptd->next]); soup_buffer_free (ptd->chunks[ptd->next]); ptd->next++; } else soup_message_body_complete (msg->request_body); soup_session_unpause_message (ptd->session, msg); }
static void temp_test_wrote_chunk (SoupMessage *msg, gpointer session) { SoupBuffer *chunk; chunk = soup_message_body_get_chunk (msg->request_body, 5); /* When the bug is present, the second chunk will also be * discarded after the first is written, which will cause * the I/O to stall since soup-message-io will think it's * done, but it hasn't written Content-Length bytes yet. */ if (!chunk) { debug_printf (1, " Lost second chunk!\n"); errors++; soup_session_abort (session); } else soup_buffer_free (chunk); g_signal_handlers_disconnect_by_func (msg, temp_test_wrote_chunk, session); }
static void do_md5_test_libsoup (const char *uri, const char *contents, gsize length, const char *md5) { SoupMultipart *multipart; SoupBuffer *buffer; SoupMessage *msg; SoupSession *session; debug_printf (1, " via libsoup: "); multipart = soup_multipart_new (SOUP_FORM_MIME_TYPE_MULTIPART); buffer = soup_buffer_new (SOUP_MEMORY_COPY, contents, length); soup_multipart_append_form_file (multipart, "file", MD5_TEST_FILE_BASENAME, MD5_TEST_FILE_MIME_TYPE, buffer); soup_buffer_free (buffer); soup_multipart_append_form_string (multipart, "fmt", "text"); msg = soup_form_request_new_from_multipart (uri, multipart); soup_multipart_free (multipart); session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL); soup_session_send_message (session, msg); if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) { debug_printf (1, "ERROR: Unexpected status %d %s\n", msg->status_code, msg->reason_phrase); errors++; } else if (strcmp (msg->response_body->data, md5) != 0) { debug_printf (1, "ERROR: Incorrect response: expected '%s' got '%s'\n", md5, msg->response_body->data); errors++; } else debug_printf (1, "OK!\n"); g_object_unref (msg); soup_test_session_abort_unref (session); }
static gboolean download_file (const gchar *source, const gchar *dest) { g_return_val_if_fail (source && dest, FALSE); // g_debug ("download_file %s to %s\n", source, dest); SoupSession *session; SoupBuffer *buf; gchar *cafile; gboolean sync; FILE *fp; buf = NULL; sync = TRUE; cafile = NULL; /*TODO: should we have the static session? */ session = open_app_soup_session_new (sync, cafile); gint retry; for (retry = 0; retry <3; retry ++) { buf = open_app_get_data_by_request (session, source); if (buf) break; g_debug ("retry %d\n", retry); } g_object_unref (session); if (!buf) return FALSE; fp = fopen (dest, "w"); if (fp) { fwrite (buf->data, 1, buf->length, fp); fclose (fp); } soup_buffer_free (buf); return TRUE; }
static void gss_program_finalize (GObject * object) { GssProgram *program = GSS_PROGRAM (object); gss_program_stop (program); g_list_free_full (program->streams, g_object_unref); if (program->hls.variant_buffer) { soup_buffer_free (program->hls.variant_buffer); } gss_metrics_free (program->metrics); g_free (program->follow_uri); g_free (program->follow_host); g_free (program->description); g_free (program->safe_description); g_free (program->uuid); parent_class->finalize (object); }
void soup_message_io_cleanup (SoupMessage *msg) { SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg); SoupMessageIOData *io; soup_message_io_stop (msg); io = priv->io_data; if (!io) return; priv->io_data = NULL; if (io->iostream) g_object_unref (io->iostream); if (io->body_istream) g_object_unref (io->body_istream); if (io->body_ostream) g_object_unref (io->body_ostream); if (io->async_context) g_main_context_unref (io->async_context); if (io->item) soup_message_queue_item_unref (io->item); g_byte_array_free (io->read_header_buf, TRUE); g_string_free (io->write_buf, TRUE); if (io->write_chunk) soup_buffer_free (io->write_chunk); if (io->async_close_wait) { g_cancellable_cancel (io->async_close_wait); g_clear_object (&io->async_close_wait); } g_clear_error (&io->async_close_error); g_slice_free (SoupMessageIOData, io); }
static void server_callback (SoupServer *server, SoupMessage *msg, const char *path, GHashTable *query, SoupClientContext *context, gpointer data) { SoupMessageBody *md5_body; char *md5; if (g_str_has_prefix (path, "/redirect")) { soup_message_set_status (msg, SOUP_STATUS_FOUND); soup_message_headers_replace (msg->response_headers, "Location", "/"); return; } if (msg->method == SOUP_METHOD_GET) { soup_message_set_response (msg, "text/plain", SOUP_MEMORY_STATIC, "three\r\ntwo\r\none\r\n", strlen ("three\r\ntwo\r\none\r\n")); soup_buffer_free (soup_message_body_flatten (msg->response_body)); md5_body = msg->response_body; soup_message_set_status (msg, SOUP_STATUS_OK); } else if (msg->method == SOUP_METHOD_PUT) { soup_message_set_status (msg, SOUP_STATUS_CREATED); md5_body = msg->request_body; } else { soup_message_set_status (msg, SOUP_STATUS_METHOD_NOT_ALLOWED); return; } md5 = g_compute_checksum_for_data (G_CHECKSUM_MD5, (guchar *)md5_body->data, md5_body->length); soup_message_headers_append (msg->response_headers, "Content-MD5", md5); g_free (md5); }
GHashTable * gss_config_get_post_hash (GssTransaction * t) { GHashTable *hash; const char *content_type; content_type = soup_message_headers_get_one (t->msg->request_headers, "Content-Type"); hash = NULL; if (g_str_equal (content_type, "application/x-www-form-urlencoded")) { hash = soup_form_decode (t->msg->request_body->data); } else if (g_str_has_prefix (content_type, "multipart/form-data")) { SoupBuffer *buffer; hash = soup_form_decode_multipart (t->msg, "none", NULL, NULL, &buffer); if (buffer && buffer->length > 0) { soup_buffer_free (buffer); } } return hash; }
static gboolean webkit_soup_directory_input_stream_close (GInputStream *input, GCancellable *cancellable, GError **error) { WebKitSoupDirectoryInputStream *stream = WEBKIT_SOUP_DIRECTORY_INPUT_STREAM (input); gboolean result; if (stream->buffer) { soup_buffer_free (stream->buffer); stream->buffer = NULL; } result = g_file_enumerator_close (stream->enumerator, cancellable, error); g_object_unref (stream->enumerator); stream->enumerator = NULL; g_free (stream->uri); stream->uri = NULL; return result; }
/* Attempts to push forward the reading side of @msg's I/O. Returns * %TRUE if it manages to make some progress, and it is likely that * further progress can be made. Returns %FALSE if it has reached a * stopping point of some sort (need input from the application, * socket not readable, read is complete, etc). */ static gboolean io_read (SoupMessage *msg, gboolean blocking, GCancellable *cancellable, GError **error) { SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg); SoupMessageIOData *io = priv->io_data; guchar *stack_buf = NULL; gssize nread; SoupBuffer *buffer; guint status; switch (io->read_state) { case SOUP_MESSAGE_IO_STATE_HEADERS: if (!read_headers (msg, blocking, cancellable, error)) return FALSE; status = io->parse_headers_cb (msg, (char *)io->read_header_buf->data, io->read_header_buf->len, &io->read_encoding, io->header_data, error); g_byte_array_set_size (io->read_header_buf, 0); if (status != SOUP_STATUS_OK) { /* Either we couldn't parse the headers, or they * indicated something that would mean we wouldn't * be able to parse the body. (Eg, unknown * Transfer-Encoding.). Skip the rest of the * reading, and make sure the connection gets * closed when we're done. */ soup_message_set_status (msg, status); soup_message_headers_append (msg->request_headers, "Connection", "close"); io->read_state = SOUP_MESSAGE_IO_STATE_FINISHING; break; } if (io->mode == SOUP_MESSAGE_IO_CLIENT && SOUP_STATUS_IS_INFORMATIONAL (msg->status_code)) { if (msg->status_code == SOUP_STATUS_CONTINUE && io->write_state == SOUP_MESSAGE_IO_STATE_BLOCKING) { /* Pause the reader, unpause the writer */ io->read_state = SOUP_MESSAGE_IO_STATE_BLOCKING; io->write_state = SOUP_MESSAGE_IO_STATE_BODY_START; } else { /* Just stay in HEADERS */ io->read_state = SOUP_MESSAGE_IO_STATE_HEADERS; } /* Informational responses have no bodies, so * bail out here rather than parsing encoding, etc */ soup_message_got_informational (msg); /* If this was "101 Switching Protocols", then * the session may have stolen the connection... */ if (io != priv->io_data) return FALSE; soup_message_cleanup_response (msg); break; } else if (io->mode == SOUP_MESSAGE_IO_SERVER && soup_message_headers_get_expectations (msg->request_headers) & SOUP_EXPECTATION_CONTINUE) { /* We must return a status code and response * headers to the client; either an error to * be set by a got-headers handler below, or * else %SOUP_STATUS_CONTINUE otherwise. */ io->write_state = SOUP_MESSAGE_IO_STATE_HEADERS; io->read_state = SOUP_MESSAGE_IO_STATE_BLOCKING; } else { io->read_state = SOUP_MESSAGE_IO_STATE_BODY_START; /* If the client was waiting for a Continue * but got something else, then it's done * writing. */ if (io->mode == SOUP_MESSAGE_IO_CLIENT && io->write_state == SOUP_MESSAGE_IO_STATE_BLOCKING) io->write_state = SOUP_MESSAGE_IO_STATE_FINISHING; } if (io->read_encoding == SOUP_ENCODING_CONTENT_LENGTH) { SoupMessageHeaders *hdrs = (io->mode == SOUP_MESSAGE_IO_CLIENT) ? msg->response_headers : msg->request_headers; io->read_length = soup_message_headers_get_content_length (hdrs); if (io->mode == SOUP_MESSAGE_IO_CLIENT && !soup_message_is_keepalive (msg)) { /* Some servers suck and send * incorrect Content-Length values, so * allow EOF termination in this case * (iff the message is too short) too. */ io->read_encoding = SOUP_ENCODING_EOF; } } else io->read_length = -1; soup_message_got_headers (msg); break; case SOUP_MESSAGE_IO_STATE_BODY_START: if (!io->body_istream) { GInputStream *body_istream = soup_body_input_stream_new (G_INPUT_STREAM (io->istream), io->read_encoding, io->read_length); /* TODO: server-side messages do not have a io->item. This means * that we cannot use content processors for them right now. */ if (io->mode == SOUP_MESSAGE_IO_CLIENT) { io->body_istream = soup_message_setup_body_istream (body_istream, msg, io->item->session, SOUP_STAGE_MESSAGE_BODY); g_object_unref (body_istream); } else { io->body_istream = body_istream; } } if (priv->sniffer) { SoupContentSnifferStream *sniffer_stream = SOUP_CONTENT_SNIFFER_STREAM (io->body_istream); const char *content_type; GHashTable *params; if (!soup_content_sniffer_stream_is_ready (sniffer_stream, blocking, cancellable, error)) return FALSE; content_type = soup_content_sniffer_stream_sniff (sniffer_stream, ¶ms); soup_message_content_sniffed (msg, content_type, params); } io->read_state = SOUP_MESSAGE_IO_STATE_BODY; break; case SOUP_MESSAGE_IO_STATE_BODY: if (priv->chunk_allocator) { buffer = priv->chunk_allocator (msg, io->read_length, priv->chunk_allocator_data); if (!buffer) { g_return_val_if_fail (!io->item || !io->item->new_api, FALSE); soup_message_io_pause (msg); return FALSE; } } else { if (!stack_buf) stack_buf = alloca (RESPONSE_BLOCK_SIZE); buffer = soup_buffer_new (SOUP_MEMORY_TEMPORARY, stack_buf, RESPONSE_BLOCK_SIZE); } nread = g_pollable_stream_read (io->body_istream, (guchar *)buffer->data, buffer->length, blocking, cancellable, error); if (nread > 0) { buffer->length = nread; soup_message_body_got_chunk (io->read_body, buffer); soup_message_got_chunk (msg, buffer); soup_buffer_free (buffer); break; } soup_buffer_free (buffer); if (nread == -1) return FALSE; /* else nread == 0 */ io->read_state = SOUP_MESSAGE_IO_STATE_BODY_DONE; break; case SOUP_MESSAGE_IO_STATE_BODY_DONE: io->read_state = SOUP_MESSAGE_IO_STATE_FINISHING; soup_message_got_body (msg); break; case SOUP_MESSAGE_IO_STATE_FINISHING: io->read_state = SOUP_MESSAGE_IO_STATE_DONE; if (io->mode == SOUP_MESSAGE_IO_SERVER) io->write_state = SOUP_MESSAGE_IO_STATE_HEADERS; break; default: g_return_val_if_reached (FALSE); } return TRUE; }
/* Attempts to push forward the writing side of @msg's I/O. Returns * %TRUE if it manages to make some progress, and it is likely that * further progress can be made. Returns %FALSE if it has reached a * stopping point of some sort (need input from the application, * socket not writable, write is complete, etc). */ static gboolean io_write (SoupMessage *msg, gboolean blocking, GCancellable *cancellable, GError **error) { SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg); SoupMessageIOData *io = priv->io_data; SoupBuffer *chunk; gssize nwrote; if (io->async_close_error) { g_propagate_error (error, io->async_close_error); io->async_close_error = NULL; return FALSE; } else if (io->async_close_wait) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK, _("Operation would block")); return FALSE; } switch (io->write_state) { case SOUP_MESSAGE_IO_STATE_HEADERS: if (io->mode == SOUP_MESSAGE_IO_SERVER && io->read_state == SOUP_MESSAGE_IO_STATE_BLOCKING && msg->status_code == 0) { /* Client requested "Expect: 100-continue", and * server did not set an error. */ soup_message_set_status (msg, SOUP_STATUS_CONTINUE); } if (!io->write_buf->len) { io->get_headers_cb (msg, io->write_buf, &io->write_encoding, io->header_data); } while (io->written < io->write_buf->len) { nwrote = g_pollable_stream_write (io->ostream, io->write_buf->str + io->written, io->write_buf->len - io->written, blocking, cancellable, error); if (nwrote == -1) return FALSE; io->written += nwrote; } io->written = 0; g_string_truncate (io->write_buf, 0); if (io->mode == SOUP_MESSAGE_IO_SERVER && SOUP_STATUS_IS_INFORMATIONAL (msg->status_code)) { if (msg->status_code == SOUP_STATUS_CONTINUE) { /* Stop and wait for the body now */ io->write_state = SOUP_MESSAGE_IO_STATE_BLOCKING; io->read_state = SOUP_MESSAGE_IO_STATE_BODY_START; } else { /* We just wrote a 1xx response * header, so stay in STATE_HEADERS. * (The caller will pause us from the * wrote_informational callback if he * is not ready to send the final * response.) */ } soup_message_wrote_informational (msg); /* If this was "101 Switching Protocols", then * the server probably stole the connection... */ if (io != priv->io_data) return FALSE; soup_message_cleanup_response (msg); break; } if (io->write_encoding == SOUP_ENCODING_CONTENT_LENGTH) { SoupMessageHeaders *hdrs = (io->mode == SOUP_MESSAGE_IO_CLIENT) ? msg->request_headers : msg->response_headers; io->write_length = soup_message_headers_get_content_length (hdrs); } if (io->mode == SOUP_MESSAGE_IO_CLIENT && soup_message_headers_get_expectations (msg->request_headers) & SOUP_EXPECTATION_CONTINUE) { /* Need to wait for the Continue response */ io->write_state = SOUP_MESSAGE_IO_STATE_BLOCKING; io->read_state = SOUP_MESSAGE_IO_STATE_HEADERS; } else { io->write_state = SOUP_MESSAGE_IO_STATE_BODY_START; /* If the client was waiting for a Continue * but we sent something else, then they're * now done writing. */ if (io->mode == SOUP_MESSAGE_IO_SERVER && io->read_state == SOUP_MESSAGE_IO_STATE_BLOCKING) io->read_state = SOUP_MESSAGE_IO_STATE_DONE; } soup_message_wrote_headers (msg); break; case SOUP_MESSAGE_IO_STATE_BODY_START: io->body_ostream = soup_body_output_stream_new (io->ostream, io->write_encoding, io->write_length); io->write_state = SOUP_MESSAGE_IO_STATE_BODY; break; case SOUP_MESSAGE_IO_STATE_BODY: if (!io->write_length && io->write_encoding != SOUP_ENCODING_EOF && io->write_encoding != SOUP_ENCODING_CHUNKED) { io->write_state = SOUP_MESSAGE_IO_STATE_BODY_FLUSH; break; } if (!io->write_chunk) { io->write_chunk = soup_message_body_get_chunk (io->write_body, io->write_body_offset); if (!io->write_chunk) { g_return_val_if_fail (!io->item || !io->item->new_api, FALSE); soup_message_io_pause (msg); return FALSE; } if (!io->write_chunk->length) { io->write_state = SOUP_MESSAGE_IO_STATE_BODY_FLUSH; break; } } nwrote = g_pollable_stream_write (io->body_ostream, io->write_chunk->data + io->written, io->write_chunk->length - io->written, blocking, cancellable, error); if (nwrote == -1) return FALSE; chunk = soup_buffer_new_subbuffer (io->write_chunk, io->written, nwrote); io->written += nwrote; if (io->write_length) io->write_length -= nwrote; if (io->written == io->write_chunk->length) io->write_state = SOUP_MESSAGE_IO_STATE_BODY_DATA; soup_message_wrote_body_data (msg, chunk); soup_buffer_free (chunk); break; case SOUP_MESSAGE_IO_STATE_BODY_DATA: io->written = 0; if (io->write_chunk->length == 0) { io->write_state = SOUP_MESSAGE_IO_STATE_BODY_FLUSH; break; } if (io->mode == SOUP_MESSAGE_IO_SERVER || priv->msg_flags & SOUP_MESSAGE_CAN_REBUILD) soup_message_body_wrote_chunk (io->write_body, io->write_chunk); io->write_body_offset += io->write_chunk->length; soup_buffer_free (io->write_chunk); io->write_chunk = NULL; io->write_state = SOUP_MESSAGE_IO_STATE_BODY; soup_message_wrote_chunk (msg); break; case SOUP_MESSAGE_IO_STATE_BODY_FLUSH: if (io->body_ostream) { if (blocking || io->write_encoding != SOUP_ENCODING_CHUNKED) { if (!g_output_stream_close (io->body_ostream, cancellable, error)) return FALSE; g_clear_object (&io->body_ostream); } else { io->async_close_wait = g_cancellable_new (); if (io->async_context) g_main_context_push_thread_default (io->async_context); g_output_stream_close_async (io->body_ostream, G_PRIORITY_DEFAULT, cancellable, closed_async, g_object_ref (msg)); if (io->async_context) g_main_context_pop_thread_default (io->async_context); } } io->write_state = SOUP_MESSAGE_IO_STATE_BODY_DONE; break; case SOUP_MESSAGE_IO_STATE_BODY_DONE: io->write_state = SOUP_MESSAGE_IO_STATE_FINISHING; soup_message_wrote_body (msg); break; case SOUP_MESSAGE_IO_STATE_FINISHING: io->write_state = SOUP_MESSAGE_IO_STATE_DONE; if (io->mode == SOUP_MESSAGE_IO_CLIENT) io->read_state = SOUP_MESSAGE_IO_STATE_HEADERS; break; default: g_return_val_if_reached (FALSE); } return TRUE; }