static void redirect_handler (SoupMessage *msg, gpointer user_data) { if (SOUP_STATUS_IS_REDIRECTION (msg->status_code)) { CallbackInfo *info = user_data; SoupURI *new_uri; const gchar *new_loc; new_loc = soup_message_headers_get (msg->response_headers, "Location"); if (!new_loc) return; info->reset=1; new_uri = soup_uri_new_with_base (soup_message_get_uri (msg), new_loc); if (!new_uri) { soup_message_set_status_full (msg, SOUP_STATUS_MALFORMED, "Invalid Redirect URL"); return; } soup_message_set_uri (msg, new_uri); soup_session_requeue_message (info->ss, msg); soup_uri_free (new_uri); } }
static void gst_soup_http_src_response_cb (SoupSession * session, SoupMessage * msg, GstSoupHTTPSrc * src) { if (G_UNLIKELY (msg != src->msg)) { GST_DEBUG_OBJECT (src, "got response %d: %s, but not for current message", msg->status_code, msg->reason_phrase); return; } if (G_UNLIKELY (src->session_io_status != GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_RUNNING) && SOUP_STATUS_IS_REDIRECTION (msg->status_code)) { /* Ignore redirections. */ return; } GST_DEBUG_OBJECT (src, "got response %d: %s", msg->status_code, msg->reason_phrase); if (src->session_io_status == GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_RUNNING && src->read_position > 0) { /* The server disconnected while streaming. Reconnect and seeking to the * last location. */ src->retry = TRUE; } else gst_soup_http_src_parse_status (msg, src); /* The session's SoupMessage object expires after this callback returns. */ src->msg = NULL; g_main_loop_quit (src->loop); }
static void contentSniffedCallback(SoupMessage* msg, const char* sniffedType, GHashTable *params, gpointer data) { if (sniffedType) { const char* officialType = soup_message_headers_get_one(msg->response_headers, "Content-Type"); if (!officialType || strcmp(officialType, sniffedType)) soup_message_headers_set_content_type(msg->response_headers, sniffedType, params); } // The 304 status code (SOUP_STATUS_NOT_MODIFIED) needs to be fed // into WebCore, as opposed to other kinds of redirections, which // are handled by soup directly, so we special-case it here and in // gotChunk. if (SOUP_STATUS_IS_TRANSPORT_ERROR(msg->status_code) || (SOUP_STATUS_IS_REDIRECTION(msg->status_code) && (msg->status_code != SOUP_STATUS_NOT_MODIFIED)) || (msg->status_code == SOUP_STATUS_UNAUTHORIZED)) return; RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(data); if (!handle) return; ResourceHandleInternal* d = handle->getInternal(); if (d->m_cancelled) return; ResourceHandleClient* client = handle->client(); if (!client) return; fillResponseFromMessage(msg, &d->m_response); client->didReceiveResponse(handle.get(), d->m_response); }
static void queue_message_restarted (SoupMessage *msg, gpointer user_data) { SoupMessageQueueItem *item = user_data; if (item->proxy_addr) { g_object_unref (item->proxy_addr); item->proxy_addr = NULL; } if (item->proxy_uri) { soup_uri_free (item->proxy_uri); item->proxy_uri = NULL; } if (item->conn && (!soup_message_is_keepalive (msg) || SOUP_STATUS_IS_REDIRECTION (msg->status_code))) { if (soup_connection_get_state (item->conn) == SOUP_CONNECTION_IN_USE) soup_connection_set_state (item->conn, SOUP_CONNECTION_IDLE); g_object_unref (item->conn); item->conn = NULL; } g_cancellable_reset (item->cancellable); item->state = SOUP_MESSAGE_STARTING; }
static void do_get (SoupMessage * msg, const char *path) { char *uri; int buflen = 4096; SoupKnownStatusCode status = SOUP_STATUS_OK; uri = soup_uri_to_string (soup_message_get_uri (msg), FALSE); GST_DEBUG ("request: \"%s\"", uri); if (!strcmp (path, "/301")) status = SOUP_STATUS_MOVED_PERMANENTLY; else if (!strcmp (path, "/302")) status = SOUP_STATUS_MOVED_TEMPORARILY; else if (!strcmp (path, "/307")) status = SOUP_STATUS_TEMPORARY_REDIRECT; else if (!strcmp (path, "/403")) status = SOUP_STATUS_FORBIDDEN; else if (!strcmp (path, "/404")) status = SOUP_STATUS_NOT_FOUND; if (SOUP_STATUS_IS_REDIRECTION (status)) { char *redir_uri; redir_uri = g_strdup_printf ("%s-redirected", uri); soup_message_headers_append (msg->response_headers, "Location", redir_uri); g_free (redir_uri); } if (status != SOUP_STATUS_OK) goto leave; if (msg->method == SOUP_METHOD_GET) { char *buf; buf = g_malloc (buflen); memset (buf, 0, buflen); soup_message_body_append (msg->response_body, SOUP_MEMORY_TAKE, buf, buflen); } else { /* msg->method == SOUP_METHOD_HEAD */ char *length; /* We could just use the same code for both GET and * HEAD. But we'll optimize and avoid the extra * malloc. */ length = g_strdup_printf ("%lu", (gulong) buflen); soup_message_headers_append (msg->response_headers, "Content-Length", length); g_free (length); } leave: soup_message_set_status (msg, status); g_free (uri); }
// All other kinds of redirections, except for the *304* status code // (SOUP_STATUS_NOT_MODIFIED) which needs to be fed into WebCore, will be // handled by soup directly. static gboolean statusWillBeHandledBySoup(guint statusCode) { if (SOUP_STATUS_IS_TRANSPORT_ERROR(statusCode) || (SOUP_STATUS_IS_REDIRECTION(statusCode) && (statusCode != SOUP_STATUS_NOT_MODIFIED)) || (statusCode == SOUP_STATUS_UNAUTHORIZED)) return true; return false; }
static void soup_session_cb (SoupSession *session, SoupMessage *msg, gpointer user_data) { DQTask *task = user_data; if (SOUP_STATUS_IS_REDIRECTION (msg->status_code)) { const char *header = soup_message_headers_get_one (msg->response_headers, "Location"); if (header) { SoupURI *uri; uri = soup_uri_new_with_base (soup_message_get_uri (msg), header); soup_message_set_uri (msg, uri); soup_uri_free (uri); soup_session_requeue_message (session, msg); return; } } else if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) { void *cache; task->any.callback (task->any.queue, task->any.uri, msg->response_body->data, msg->response_body->length, NULL, task->any.userdata); /* add the contents to the cache */ cache = g_memdup (msg->response_body->data, msg->response_body->length); mex_download_queue_cache_insert (task->any.queue, task->any.uri, cache, msg->response_body->length); } else if (msg->status_code != SOUP_STATUS_CANCELLED) { /* FIXME: Also create an error on failure */ task->any.callback (task->any.queue, task->any.uri, NULL, 0, NULL, task->any.userdata); } /* The message is unref'd by the session */ task->soup.message = NULL; mex_download_queue_free (task); }
static void gst_soup_http_src_parse_status (SoupMessage * msg, GstSoupHTTPSrc * src) { if (SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code)) { switch (msg->status_code) { case SOUP_STATUS_CANT_RESOLVE: case SOUP_STATUS_CANT_RESOLVE_PROXY: SOUP_HTTP_SRC_ERROR (src, msg, RESOURCE, NOT_FOUND, _("Could not resolve server name.")); src->ret = GST_FLOW_ERROR; break; case SOUP_STATUS_CANT_CONNECT: case SOUP_STATUS_CANT_CONNECT_PROXY: SOUP_HTTP_SRC_ERROR (src, msg, RESOURCE, OPEN_READ, _("Could not establish connection to server.")); src->ret = GST_FLOW_ERROR; break; case SOUP_STATUS_SSL_FAILED: SOUP_HTTP_SRC_ERROR (src, msg, RESOURCE, OPEN_READ, _("Secure connection setup failed.")); src->ret = GST_FLOW_ERROR; break; case SOUP_STATUS_IO_ERROR: SOUP_HTTP_SRC_ERROR (src, msg, RESOURCE, READ, _("A network error occured, or the server closed the connection " "unexpectedly.")); src->ret = GST_FLOW_ERROR; break; case SOUP_STATUS_MALFORMED: SOUP_HTTP_SRC_ERROR (src, msg, RESOURCE, READ, _("Server sent bad data.")); src->ret = GST_FLOW_ERROR; break; case SOUP_STATUS_CANCELLED: /* No error message when interrupted by program. */ break; } } else if (SOUP_STATUS_IS_CLIENT_ERROR (msg->status_code) || SOUP_STATUS_IS_REDIRECTION (msg->status_code) || SOUP_STATUS_IS_SERVER_ERROR (msg->status_code)) { /* Report HTTP error. */ /* FIXME: reason_phrase is not translated and not suitable for user * error dialog according to libsoup documentation. * FIXME: error code (OPEN_READ vs. READ) should depend on http status? */ GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("%s", msg->reason_phrase), ("%s (%d), URL: %s", msg->reason_phrase, msg->status_code, src->location)); src->ret = GST_FLOW_ERROR; } }
const char * network_strerror (gint netstatus, gint httpstatus) { const gchar *tmp = NULL; int status = netstatus?netstatus:httpstatus; switch (status) { /* Some libsoup transport errors */ case SOUP_STATUS_NONE: tmp = _("The update request was cancelled"); break; case SOUP_STATUS_CANT_RESOLVE: tmp = _("Unable to resolve destination host name"); break; case SOUP_STATUS_CANT_RESOLVE_PROXY: tmp = _("Unable to resolve proxy host name"); break; case SOUP_STATUS_CANT_CONNECT: tmp = _("Unable to connect to remote host"); break; case SOUP_STATUS_CANT_CONNECT_PROXY: tmp = _("Unable to connect to proxy"); break; case SOUP_STATUS_SSL_FAILED: tmp = _("A network error occurred, or the other end closed the connection unexpectedly"); break; /* http 3xx redirection */ case SOUP_STATUS_MOVED_PERMANENTLY: tmp = _("The resource moved permanently to a new location"); break; /* http 4xx client error */ case SOUP_STATUS_UNAUTHORIZED: tmp = _("You are unauthorized to download this feed. Please update your username and " "password in the feed properties dialog box"); break; case SOUP_STATUS_PAYMENT_REQUIRED: tmp = _("Payment required"); break; case SOUP_STATUS_FORBIDDEN: tmp = _("You're not allowed to access this resource"); break; case SOUP_STATUS_NOT_FOUND: tmp = _("Resource Not Found"); break; case SOUP_STATUS_METHOD_NOT_ALLOWED: tmp = _("Method Not Allowed"); break; case SOUP_STATUS_NOT_ACCEPTABLE: tmp = _("Not Acceptable"); break; case SOUP_STATUS_PROXY_UNAUTHORIZED: tmp = _("Proxy authentication required"); break; case SOUP_STATUS_REQUEST_TIMEOUT: tmp = _("Request timed out"); break; case SOUP_STATUS_GONE: tmp = _("Gone. Resource doesn't exist. Please unsubscribe!"); break; } if (!tmp) { if (SOUP_STATUS_IS_TRANSPORT_ERROR (status)) { tmp = _("There was an internal error in the update process"); } else if (SOUP_STATUS_IS_REDIRECTION (status)) { tmp = _("Feed not available: Server requested unsupported redirection!"); } else if (SOUP_STATUS_IS_CLIENT_ERROR (status)) { tmp = _("Client Error"); } else if (SOUP_STATUS_IS_SERVER_ERROR (status)) { tmp = _("Server Error"); } else { tmp = _("An unknown networking error happened!"); } } g_assert (tmp); return tmp; }
static void gotChunkCallback(SoupMessage* msg, SoupBuffer* chunk, gpointer data) { if (SOUP_STATUS_IS_TRANSPORT_ERROR(msg->status_code) || (SOUP_STATUS_IS_REDIRECTION(msg->status_code) && (msg->status_code != SOUP_STATUS_NOT_MODIFIED)) || (msg->status_code == SOUP_STATUS_UNAUTHORIZED)) return; RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(data); if (!handle) return; ResourceHandleInternal* d = handle->getInternal(); if (d->m_cancelled) return; ResourceHandleClient* client = handle->client(); if (!client) return; client->didReceiveData(handle.get(), chunk->data, chunk->length, false); }
static void gst_soup_http_src_got_headers_cb (SoupMessage * msg, GstSoupHTTPSrc * src) { const char *value; GstTagList *tag_list; GstBaseSrc *basesrc; guint64 newsize; GHashTable *params = NULL; GST_DEBUG_OBJECT (src, "got headers:"); soup_message_headers_foreach (msg->response_headers, gst_soup_http_src_headers_foreach, src); if (msg->status_code == 407 && src->proxy_id && src->proxy_pw) return; if (src->automatic_redirect && SOUP_STATUS_IS_REDIRECTION (msg->status_code)) { GST_DEBUG_OBJECT (src, "%u redirect to \"%s\"", msg->status_code, soup_message_headers_get_one (msg->response_headers, "Location")); return; } if (msg->status_code == SOUP_STATUS_UNAUTHORIZED) return; src->session_io_status = GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_RUNNING; /* Parse Content-Length. */ if (soup_message_headers_get_encoding (msg->response_headers) == SOUP_ENCODING_CONTENT_LENGTH) { newsize = src->request_position + soup_message_headers_get_content_length (msg->response_headers); if (!src->have_size || (src->content_size != newsize)) { src->content_size = newsize; src->have_size = TRUE; src->seekable = TRUE; GST_DEBUG_OBJECT (src, "size = %" G_GUINT64_FORMAT, src->content_size); basesrc = GST_BASE_SRC_CAST (src); gst_segment_set_duration (&basesrc->segment, GST_FORMAT_BYTES, src->content_size); gst_element_post_message (GST_ELEMENT (src), gst_message_new_duration (GST_OBJECT (src), GST_FORMAT_BYTES, src->content_size)); } } /* Icecast stuff */ tag_list = gst_tag_list_new (); if ((value = soup_message_headers_get_one (msg->response_headers, "icy-metaint")) != NULL) { gint icy_metaint = atoi (value); GST_DEBUG_OBJECT (src, "icy-metaint: %s (parsed: %d)", value, icy_metaint); if (icy_metaint > 0) { if (src->src_caps) gst_caps_unref (src->src_caps); src->src_caps = gst_caps_new_simple ("application/x-icy", "metadata-interval", G_TYPE_INT, icy_metaint, NULL); } } if ((value = soup_message_headers_get_content_type (msg->response_headers, ¶ms)) != NULL) { GST_DEBUG_OBJECT (src, "Content-Type: %s", value); if (g_ascii_strcasecmp (value, "audio/L16") == 0) { gint channels = 2; gint rate = 44100; char *param; if (src->src_caps) gst_caps_unref (src->src_caps); param = g_hash_table_lookup (params, "channels"); if (param != NULL) channels = atol (param); param = g_hash_table_lookup (params, "rate"); if (param != NULL) rate = atol (param); src->src_caps = gst_caps_new_simple ("audio/x-raw-int", "channels", G_TYPE_INT, channels, "rate", G_TYPE_INT, rate, "width", G_TYPE_INT, 16, "depth", G_TYPE_INT, 16, "signed", G_TYPE_BOOLEAN, TRUE, "endianness", G_TYPE_INT, G_BIG_ENDIAN, NULL); } else { /* Set the Content-Type field on the caps */ if (src->src_caps) gst_caps_set_simple (src->src_caps, "content-type", G_TYPE_STRING, value, NULL); } } if (params != NULL) g_hash_table_destroy (params); if ((value = soup_message_headers_get_one (msg->response_headers, "icy-name")) != NULL) { g_free (src->iradio_name); src->iradio_name = gst_soup_http_src_unicodify (value); if (src->iradio_name) { g_object_notify (G_OBJECT (src), "iradio-name"); gst_tag_list_add (tag_list, GST_TAG_MERGE_REPLACE, GST_TAG_ORGANIZATION, src->iradio_name, NULL); } } if ((value = soup_message_headers_get_one (msg->response_headers, "icy-genre")) != NULL) { g_free (src->iradio_genre); src->iradio_genre = gst_soup_http_src_unicodify (value); if (src->iradio_genre) { g_object_notify (G_OBJECT (src), "iradio-genre"); gst_tag_list_add (tag_list, GST_TAG_MERGE_REPLACE, GST_TAG_GENRE, src->iradio_genre, NULL); } } if ((value = soup_message_headers_get_one (msg->response_headers, "icy-url")) != NULL) { g_free (src->iradio_url); src->iradio_url = gst_soup_http_src_unicodify (value); if (src->iradio_url) { g_object_notify (G_OBJECT (src), "iradio-url"); gst_tag_list_add (tag_list, GST_TAG_MERGE_REPLACE, GST_TAG_LOCATION, src->iradio_url, NULL); } } if (!gst_tag_list_is_empty (tag_list)) { GST_DEBUG_OBJECT (src, "calling gst_element_found_tags with %" GST_PTR_FORMAT, tag_list); gst_element_found_tags (GST_ELEMENT_CAST (src), tag_list); } else { gst_tag_list_free (tag_list); } /* Handle HTTP errors. */ gst_soup_http_src_parse_status (msg, src); /* Check if Range header was respected. */ if (src->ret == GST_FLOW_CUSTOM_ERROR && src->read_position && msg->status_code != SOUP_STATUS_PARTIAL_CONTENT) { src->seekable = FALSE; GST_ELEMENT_ERROR (src, RESOURCE, SEEK, (_("Server does not support seeking.")), ("Server does not accept Range HTTP header, URL: %s", src->location)); src->ret = GST_FLOW_ERROR; } }
static void get_url (const char *url) { const char *name; SoupMessage *msg; const char *header; FILE *output_file = NULL; msg = soup_message_new (head ? "HEAD" : "GET", url); soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT); if (loop) { g_object_ref (msg); soup_session_queue_message (session, msg, finished, loop); g_main_loop_run (loop); } else soup_session_send_message (session, msg); name = soup_message_get_uri (msg)->path; if (!debug) { if (msg->status_code == SOUP_STATUS_SSL_FAILED) { GTlsCertificateFlags flags; if (soup_message_get_https_status (msg, NULL, &flags)) g_print ("%s: %d %s (0x%x)\n", name, msg->status_code, msg->reason_phrase, flags); else g_print ("%s: %d %s (no handshake status)\n", name, msg->status_code, msg->reason_phrase); } else if (!quiet || SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code)) g_print ("%s: %d %s\n", name, msg->status_code, msg->reason_phrase); } if (SOUP_STATUS_IS_REDIRECTION (msg->status_code)) { header = soup_message_headers_get_one (msg->response_headers, "Location"); if (header) { SoupURI *uri; char *uri_string; if (!debug && !quiet) g_print (" -> %s\n", header); uri = soup_uri_new_with_base (soup_message_get_uri (msg), header); uri_string = soup_uri_to_string (uri, FALSE); get_url (uri_string); g_free (uri_string); soup_uri_free (uri); } } else if (!head && SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) { if (output_file_path) { output_file = fopen (output_file_path, "w"); if (!output_file) g_printerr ("Error trying to create file %s.\n", output_file_path); } else if (!quiet) output_file = stdout; if (output_file) { fwrite (msg->response_body->data, 1, msg->response_body->length, output_file); if (output_file_path) fclose (output_file); } } }
SoupBuffer * open_app_get_data_by_request (SoupSession *session, const gchar *request) { SoupMessage *msg; SoupBuffer *buf; const gchar *name; const gchar *header; const gchar *method; g_return_val_if_fail (request != NULL, NULL); // g_debug ("open_app_get_data_by_request: %s\n", request); buf = NULL; method = SOUP_METHOD_GET; msg = soup_message_new (method, request); soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT); soup_session_send_message (session, msg); name = soup_message_get_uri (msg)->path; if (SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code)) { g_debug ("%s: %d %s\n", name, msg->status_code, msg->reason_phrase); } else { #ifdef SERVER_DEBUG SoupMessageHeadersIter iter; const gchar *hname, *value; gchar *path = soup_uri_to_string (soup_message_get_uri (msg), TRUE); g_debug ("%s %s HTTP/1.%d\n", method, path, soup_message_get_http_version (msg)); g_free (path); soup_message_headers_iter_init (&iter, msg->request_headers); while (soup_message_headers_iter_next (&iter, &hname, &value)) g_debug ("%s: %s\r\n", hname, value); g_debug ("\n"); g_debug ("HTTP/1.%d %d %s\n", soup_message_get_http_version (msg), msg->status_code, msg->reason_phrase); soup_message_headers_iter_init (&iter, msg->response_headers); while (soup_message_headers_iter_next (&iter, &hname, &value)) g_debug ("%s: %s\r\n", hname, value); g_debug ("\n"); #endif } if (SOUP_STATUS_IS_REDIRECTION (msg->status_code)) { header = soup_message_headers_get_one (msg->response_headers, "Location"); if (header) { SoupURI *request; gchar *request_string; g_debug (" -> %s\n", header); request = soup_uri_new_with_base (soup_message_get_uri (msg), header); request_string = soup_uri_to_string (request, FALSE); buf = open_app_get_data_by_request (session, request_string); g_free (request_string); soup_uri_free (request); } } else if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) { buf = soup_message_body_flatten (msg->response_body); } g_object_unref (msg); return buf; }
static gboolean cal_backend_http_load (ECalBackendHttp *backend, const gchar *uri, gchar **out_certificate_pem, GTlsCertificateFlags *out_certificate_errors, GCancellable *cancellable, GError **error) { ECalBackendHttpPrivate *priv = backend->priv; ETimezoneCache *timezone_cache; SoupMessage *soup_message; SoupSession *soup_session; icalcomponent *icalcomp, *subcomp; icalcomponent_kind kind; const gchar *newuri; SoupURI *uri_parsed; GHashTable *old_cache; GSList *comps_in_cache; ESource *source; guint status_code; gulong cancel_id = 0; struct { SoupSession *soup_session; SoupMessage *soup_message; } cancel_data; timezone_cache = E_TIMEZONE_CACHE (backend); soup_session = backend->priv->soup_session; soup_message = cal_backend_http_new_message (backend, uri); if (soup_message == NULL) { g_set_error ( error, SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED, _("Malformed URI: %s"), uri); return FALSE; } if (G_IS_CANCELLABLE (cancellable)) { cancel_data.soup_session = soup_session; cancel_data.soup_message = soup_message; cancel_id = g_cancellable_connect ( cancellable, G_CALLBACK (cal_backend_http_cancelled), &cancel_data, (GDestroyNotify) NULL); } source = e_backend_get_source (E_BACKEND (backend)); e_soup_ssl_trust_connect (soup_message, source); e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTING); status_code = soup_session_send_message (soup_session, soup_message); if (G_IS_CANCELLABLE (cancellable)) g_cancellable_disconnect (cancellable, cancel_id); if (status_code == SOUP_STATUS_NOT_MODIFIED) { e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTED); /* attempts with ETag can result in 304 status code */ g_object_unref (soup_message); priv->opened = TRUE; return TRUE; } /* Handle redirection ourselves */ if (SOUP_STATUS_IS_REDIRECTION (status_code)) { gboolean success; newuri = soup_message_headers_get_list ( soup_message->response_headers, "Location"); d (g_message ("Redirected from %s to %s\n", async_context->uri, newuri)); if (newuri != NULL) { gchar *redirected_uri; if (newuri[0]=='/') { g_warning ("Hey! Relative URI returned! Working around...\n"); uri_parsed = soup_uri_new (uri); soup_uri_set_path (uri_parsed, newuri); soup_uri_set_query (uri_parsed, NULL); /* g_free (newuri); */ newuri = soup_uri_to_string (uri_parsed, FALSE); g_message ("Translated URI: %s\n", newuri); soup_uri_free (uri_parsed); } redirected_uri = webcal_to_http_method (newuri, FALSE); success = cal_backend_http_load ( backend, redirected_uri, out_certificate_pem, out_certificate_errors, cancellable, error); g_free (redirected_uri); } else { g_set_error ( error, SOUP_HTTP_ERROR, SOUP_STATUS_BAD_REQUEST, _("Redirected to Invalid URI")); success = FALSE; } if (success) { e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTED); } else { e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_DISCONNECTED); } g_object_unref (soup_message); return success; } /* check status code */ if (!SOUP_STATUS_IS_SUCCESSFUL (status_code)) { /* because evolution knows only G_IO_ERROR_CANCELLED */ if (status_code == SOUP_STATUS_CANCELLED) g_set_error ( error, G_IO_ERROR, G_IO_ERROR_CANCELLED, "%s", soup_message->reason_phrase); else g_set_error ( error, SOUP_HTTP_ERROR, status_code, "%s", soup_message->reason_phrase); if (status_code == SOUP_STATUS_SSL_FAILED) { e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_SSL_FAILED); cal_backend_http_extract_ssl_failed_data (soup_message, out_certificate_pem, out_certificate_errors); } else { e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_DISCONNECTED); } g_object_unref (soup_message); empty_cache (backend); return FALSE; } e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTED); if (priv->store) { const gchar *etag; etag = soup_message_headers_get_one ( soup_message->response_headers, "ETag"); if (etag != NULL && *etag == '\0') etag = NULL; e_cal_backend_store_put_key_value (priv->store, "ETag", etag); } /* get the calendar from the response */ icalcomp = icalparser_parse_string (soup_message->response_body->data); if (!icalcomp) { g_set_error ( error, SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED, _("Bad file format.")); g_object_unref (soup_message); empty_cache (backend); return FALSE; } if (icalcomponent_isa (icalcomp) != ICAL_VCALENDAR_COMPONENT) { g_set_error ( error, SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED, _("Not a calendar.")); icalcomponent_free (icalcomp); g_object_unref (soup_message); empty_cache (backend); return FALSE; } g_object_unref (soup_message); soup_message = NULL; /* Update cache */ old_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); comps_in_cache = e_cal_backend_store_get_components (priv->store); while (comps_in_cache != NULL) { const gchar *uid; ECalComponent *comp = comps_in_cache->data; e_cal_component_get_uid (comp, &uid); g_hash_table_insert (old_cache, g_strdup (uid), e_cal_component_get_as_string (comp)); comps_in_cache = g_slist_remove (comps_in_cache, comps_in_cache->data); g_object_unref (comp); } kind = e_cal_backend_get_kind (E_CAL_BACKEND (backend)); subcomp = icalcomponent_get_first_component (icalcomp, ICAL_ANY_COMPONENT); e_cal_backend_store_freeze_changes (priv->store); while (subcomp) { ECalComponent *comp; icalcomponent_kind subcomp_kind; icalproperty *prop = NULL; subcomp_kind = icalcomponent_isa (subcomp); prop = icalcomponent_get_first_property (subcomp, ICAL_UID_PROPERTY); if (!prop && subcomp_kind == kind) { gchar *new_uid = e_cal_component_gen_uid (); icalcomponent_set_uid (subcomp, new_uid); g_free (new_uid); } if (subcomp_kind == kind) { comp = e_cal_component_new (); if (e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (subcomp))) { const gchar *uid; gpointer orig_key, orig_value; e_cal_component_get_uid (comp, &uid); if (!put_component_to_store (backend, comp)) { g_hash_table_remove (old_cache, uid); } else if (g_hash_table_lookup_extended (old_cache, uid, &orig_key, &orig_value)) { ECalComponent *orig_comp = e_cal_component_new_from_string (orig_value); e_cal_backend_notify_component_modified (E_CAL_BACKEND (backend), orig_comp, comp); g_hash_table_remove (old_cache, uid); if (orig_comp) g_object_unref (orig_comp); } else { e_cal_backend_notify_component_created (E_CAL_BACKEND (backend), comp); } } g_object_unref (comp); } else if (subcomp_kind == ICAL_VTIMEZONE_COMPONENT) { icaltimezone *zone; zone = icaltimezone_new (); icaltimezone_set_component (zone, icalcomponent_new_clone (subcomp)); e_timezone_cache_add_timezone (timezone_cache, zone); icaltimezone_free (zone, 1); } subcomp = icalcomponent_get_next_component (icalcomp, ICAL_ANY_COMPONENT); } e_cal_backend_store_thaw_changes (priv->store); /* notify the removals */ g_hash_table_foreach_remove (old_cache, (GHRFunc) notify_and_remove_from_cache, backend); g_hash_table_destroy (old_cache); /* free memory */ icalcomponent_free (icalcomp); priv->opened = TRUE; return TRUE; }
static void server_callback (SoupServer *server, SoupMessage *msg, const char *path, GHashTable *query, SoupClientContext *context, gpointer data) { char *remainder; guint status_code; if (g_str_has_prefix (path, "/bad")) { if (!strcmp (path, "/bad")) { soup_message_set_status (msg, SOUP_STATUS_FOUND); soup_message_headers_replace (msg->response_headers, "Location", "/bad with spaces"); } else if (!strcmp (path, "/bad with spaces")) soup_message_set_status (msg, SOUP_STATUS_OK); else soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND); return; } if (!strcmp (path, "/")) { if (msg->method != SOUP_METHOD_GET && msg->method != SOUP_METHOD_HEAD) { soup_message_set_status (msg, SOUP_STATUS_METHOD_NOT_ALLOWED); return; } /* Make sure that redirecting a POST clears the body */ if (msg->request_body->length) { soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST); return; } /* Make sure that a HTTP/1.0 redirect doesn't cause an * HTTP/1.0 re-request. (#521848) */ if (soup_message_get_http_version (msg) == SOUP_HTTP_1_0) { soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST); return; } soup_message_set_status (msg, SOUP_STATUS_OK); /* FIXME: this is wrong, though it doesn't matter for * the purposes of this test, and to do the right * thing currently we'd have to set Content-Length by * hand. */ if (msg->method != SOUP_METHOD_HEAD) { soup_message_set_response (msg, "text/plain", SOUP_MEMORY_STATIC, "OK\r\n", 4); } return; } status_code = strtoul (path + 1, &remainder, 10); if (!SOUP_STATUS_IS_REDIRECTION (status_code) || (*remainder && *remainder != '/')) { soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND); return; } /* See above comment re bug 521848. */ soup_message_set_http_version (msg, SOUP_HTTP_1_0); soup_message_set_status (msg, status_code); if (*remainder) { soup_message_headers_replace (msg->response_headers, "Location", remainder); } else { soup_message_headers_replace (msg->response_headers, "Location", "/"); } }