/** * soup_message_headers_set_encoding: * @hdrs: a #SoupMessageHeaders * @encoding: a #SoupEncoding * * Sets the message body encoding that @hdrs will declare. In particular, * you should use this if you are going to send a request or response in * chunked encoding. **/ void soup_message_headers_set_encoding (SoupMessageHeaders *hdrs, SoupEncoding encoding) { if (encoding == hdrs->encoding) return; switch (encoding) { case SOUP_ENCODING_NONE: case SOUP_ENCODING_EOF: soup_message_headers_remove (hdrs, "Transfer-Encoding"); soup_message_headers_remove (hdrs, "Content-Length"); break; case SOUP_ENCODING_CONTENT_LENGTH: soup_message_headers_remove (hdrs, "Transfer-Encoding"); break; case SOUP_ENCODING_CHUNKED: soup_message_headers_remove (hdrs, "Content-Length"); soup_message_headers_replace (hdrs, "Transfer-Encoding", "chunked"); break; default: g_return_if_reached (); } hdrs->encoding = encoding; }
/** * soup_message_headers_replace: * @hdrs: a #SoupMessageHeaders * @name: the header name to replace * @value: the new value of @name * * Replaces the value of the header @name in @hdrs with @value. (See * also soup_message_headers_append().) * * The caller is expected to make sure that @name and @value are * syntactically correct. **/ void soup_message_headers_replace (SoupMessageHeaders *hdrs, const char *name, const char *value) { soup_message_headers_remove (hdrs, name); soup_message_headers_append (hdrs, name, value); }
/** * Callback for web pages send-request signal. */ static gboolean on_web_page_send_request(WebKitWebPage *webpage, WebKitURIRequest *request, WebKitURIResponse *response, gpointer extension) { char *name, *value; SoupMessageHeaders *headers; GHashTableIter iter; if (!ext.headers) { return FALSE; } /* Change request headers according to the users preferences. */ headers = webkit_uri_request_get_http_headers(request); if (!headers) { return FALSE; } g_hash_table_iter_init(&iter, ext.headers); while (g_hash_table_iter_next(&iter, (gpointer*)&name, (gpointer*)&value)) { /* Null value is used to indicate that the header should be * removed completely. */ if (value == NULL) { soup_message_headers_remove(headers, name); } else { soup_message_headers_replace(headers, name, value); } } return FALSE; }
static gboolean soup_input_stream_seek (GSeekable *seekable, goffset offset, GSeekType type, GCancellable *cancellable, GError **error) { GInputStream *stream = G_INPUT_STREAM (seekable); SoupInputStreamPrivate *priv = SOUP_INPUT_STREAM_GET_PRIVATE (seekable); char *range; if (type == G_SEEK_END) { /* FIXME: we could send "bytes=-offset", but unless we know the * Content-Length, we wouldn't be able to answer a tell() properly. * We could find the Content-Length by doing a HEAD... */ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "G_SEEK_END not currently supported"); return FALSE; } if (!g_input_stream_set_pending (stream, error)) return FALSE; soup_session_cancel_message (priv->session, priv->msg, SOUP_STATUS_CANCELLED); soup_message_io_cleanup (priv->msg); switch (type) { case G_SEEK_CUR: offset += priv->offset; /* fall through */ case G_SEEK_SET: range = g_strdup_printf ("bytes=%"G_GUINT64_FORMAT"-", (guint64)offset); priv->offset = offset; break; case G_SEEK_END: range = NULL; /* keep compilers happy */ g_return_val_if_reached (FALSE); break; default: g_return_val_if_reached (FALSE); } soup_message_headers_remove (priv->msg->request_headers, "Range"); soup_message_headers_append (priv->msg->request_headers, "Range", range); g_free (range); soup_input_stream_queue_message (SOUP_INPUT_STREAM (stream)); g_input_stream_clear_pending (stream); return TRUE; }
static void disappear_request_read (SoupServer *server, SoupMessage *msg, SoupClientContext *context, gpointer user_data) { /* Remove the WWW-Authenticate header if this was a failed attempt */ if (soup_message_headers_get_one (msg->request_headers, "Authorization") && msg->status_code == SOUP_STATUS_UNAUTHORIZED) soup_message_headers_remove (msg->response_headers, "WWW-Authenticate"); }
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); }
/** * soup_message_headers_set_content_length: * @hdrs: a #SoupMessageHeaders * @content_length: the message body length * * Sets the message body length that @hdrs will declare, and sets * @hdrs's encoding to %SOUP_ENCODING_CONTENT_LENGTH. * * You do not normally need to call this; if @hdrs is set to use * Content-Length encoding, libsoup will automatically set its * Content-Length header for you immediately before sending the * headers. One situation in which this method is useful is when * generating the response to a HEAD request; Calling * soup_message_headers_set_content_length() allows you to put the * correct content length into the response without needing to waste * memory by filling in a response body which won't actually be sent. **/ void soup_message_headers_set_content_length (SoupMessageHeaders *hdrs, goffset content_length) { char length[128]; snprintf (length, sizeof (length), "%" G_GUINT64_FORMAT, content_length); soup_message_headers_remove (hdrs, "Transfer-Encoding"); soup_message_headers_replace (hdrs, "Content-Length", length); }
/** * soup_message_headers_set_expectations: * @hdrs: a #SoupMessageHeaders * @expectations: the expectations to set * * Sets @hdrs's "Expect" header according to @expectations. * * Currently %SOUP_EXPECTATION_CONTINUE is the only known expectation * value. You should set this value on a request if you are sending a * large message body (eg, via POST or PUT), and want to give the * server a chance to reject the request after seeing just the headers * (eg, because it will require authentication before allowing you to * post, or because you're POSTing to a URL that doesn't exist). This * saves you from having to transmit the large request body when the * server is just going to ignore it anyway. **/ void soup_message_headers_set_expectations (SoupMessageHeaders *hdrs, SoupExpectation expectations) { g_return_if_fail ((expectations & ~SOUP_EXPECTATION_CONTINUE) == 0); if (expectations & SOUP_EXPECTATION_CONTINUE) soup_message_headers_replace (hdrs, "Expect", "100-continue"); else soup_message_headers_remove (hdrs, "Expect"); }
void newrequest(SoupSession *s, SoupMessage *msg, gpointer v) { SoupMessageHeaders *h = msg->request_headers; SoupURI *uri; const char *c; soup_message_headers_remove(h, "Cookie"); uri = soup_message_get_uri(msg); if((c = getcookies(uri))) soup_message_headers_append(h, "Cookie", c); g_signal_connect_after(G_OBJECT(msg), "got-headers", G_CALLBACK(gotheaders), NULL); }
static void send_headers (SoupMessage *from, SoupMessage *to) { g_print ("[%p] HTTP/1.%d %d %s\n", to, soup_message_get_http_version (from), from->status_code, from->reason_phrase); soup_message_set_status_full (to, from->status_code, from->reason_phrase); soup_message_headers_foreach (from->response_headers, copy_header, to->response_headers); soup_message_headers_remove (to->response_headers, "Content-Length"); soup_server_unpause_message (server, to); }
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); }
/** * soup_message_headers_clean_connection_headers: * @hdrs: a #SoupMessageHeaders * * Removes all the headers listed in the Connection header. * * Since: 2.36 */ void soup_message_headers_clean_connection_headers (SoupMessageHeaders *hdrs) { /* RFC 2616 14.10 */ const char *connection; GSList *tokens, *t; connection = soup_message_headers_get_list (hdrs, "Connection"); if (!connection) return; tokens = soup_header_parse_list (connection); for (t = tokens; t; t = t->next) soup_message_headers_remove (hdrs, t->data); soup_header_free_list (tokens); }
static gboolean gst_soup_http_src_add_range_header (GstSoupHTTPSrc * src, guint64 offset) { gchar buf[64]; gint rc; soup_message_headers_remove (src->msg->request_headers, "Range"); if (offset) { rc = g_snprintf (buf, sizeof (buf), "bytes=%" G_GUINT64_FORMAT "-", offset); if (rc > sizeof (buf) || rc < 0) return FALSE; soup_message_headers_append (src->msg->request_headers, "Range", buf); } src->read_position = offset; return TRUE; }
static void recv_headers(SoupMessage *from, gpointer data) { SoupMessage *to = ((struct destination_info *) data)->msg; SoupServer *server = ((struct destination_info *) data)->server; g_print("[%p] HTTP/1.%d %d %s\n", to, soup_message_get_http_version(from), from->status_code, from->reason_phrase); soup_message_set_status_full(to, from->status_code, from->reason_phrase); soup_message_headers_foreach(from->response_headers, copy_header, to->response_headers); /* we remove it, because libsoup appending at the end */ soup_message_headers_remove(to->response_headers, "Content-Length"); soup_server_unpause_message(server, to); }
// Called each time the message is going to be sent again except the first time. // It's used mostly to let webkit know about redirects. static void restartedCallback(SoupMessage* msg, gpointer data) { ResourceHandle* handle = static_cast<ResourceHandle*>(data); if (!handle) return; ResourceHandleInternal* d = handle->getInternal(); if (d->m_cancelled) return; char* uri = soup_uri_to_string(soup_message_get_uri(msg), false); String location = String(uri); g_free(uri); KURL newURL = KURL(handle->request().url(), location); ResourceRequest request = handle->request(); ResourceResponse response; request.setURL(newURL); request.setHTTPMethod(msg->method); fillResponseFromMessage(msg, &response); // Should not set Referer after a redirect from a secure resource to non-secure one. if (!request.url().protocolIs("https") && protocolIs(request.httpReferrer(), "https")) { request.clearHTTPReferrer(); soup_message_headers_remove(msg->request_headers, "Referer"); } if (d->client()) d->client()->willSendRequest(handle, request, response); if (d->m_cancelled) return; #ifdef HAVE_LIBSOUP_2_29_90 // Update the first party in case the base URL changed with the redirect String firstPartyString = request.firstPartyForCookies().string(); if (!firstPartyString.isEmpty()) { GOwnPtr<SoupURI> firstParty(soup_uri_new(firstPartyString.utf8().data())); soup_message_set_first_party(d->m_msg, firstParty.get()); } #endif }
static void request_started(SoupSessionFeature *feature, SoupSession *session, SoupMessage *msg, SoupSocket *socket) { (void) session; (void) socket; SoupCookieJar *sj = SOUP_COOKIE_JAR(feature); SoupURI *uri = soup_message_get_uri(msg); lua_State *L = globalconf.L; /* give user a chance to add cookies from other instances into the jar */ gchar *str = soup_uri_to_string(uri, FALSE); lua_pushstring(L, str); g_free(str); signal_object_emit(L, soupconf.signals, "request-started", 1, 0); /* generate cookie header */ gchar *header = soup_cookie_jar_get_cookies(sj, uri, TRUE); if (header) { soup_message_headers_replace(msg->request_headers, "Cookie", header); g_free(header); } else soup_message_headers_remove(msg->request_headers, "Cookie"); }
static void forget_close (SoupMessage *msg, gpointer user_data) { soup_message_headers_remove (msg->response_headers, "Connection"); }