static void sanity_check_date (RestProxyCall *call) { GHashTable *headers; SoupDate *call_date; const char *s; time_t call_time, diff; headers = rest_proxy_call_get_response_headers (call); s = g_hash_table_lookup (headers, "Date"); if (s) { call_date = soup_date_new_from_string (s); if (call_date) { call_time = soup_date_to_time_t (call_date); diff = labs (time (NULL) - call_time); /* More than five minutes difference between local time and the response time? */ if (diff > (60 * 5)) { g_warning ("%ld seconds difference between HTTP time and system time!", diff); } } soup_date_free (call_date); } g_hash_table_unref (headers); }
/** * Reads the entries save in given file and store them in the whitelist. */ static void load_entries(HSTSProvider *provider, const char *file) { char **lines, **parts, *host, *line; int i, len, partlen; gboolean include_sub_domains; SoupDate *date; HSTSEntry *entry; lines = util_get_lines(file); if (!(len = g_strv_length(lines))) { return; } for (i = len - 1; i >= 0; i--) { line = lines[i]; /* skip empty or commented lines */ if (!*line || *line == '#') { continue; } parts = g_strsplit(line, "\t", 3); partlen = g_strv_length(parts); if (partlen == 3) { host = parts[0]; if (g_hostname_is_ip_address(host)) { continue; } date = soup_date_new_from_string(parts[1]); if (!date) { continue; } include_sub_domains = (*parts[2] == 'y') ? true : false; /* built the new entry to add */ entry = g_slice_new(HSTSEntry); entry->expires_at = soup_date_new_from_string(parts[1]); entry->include_sub_domains = include_sub_domains; add_host_entry(provider, host, entry); } else { g_warning("could not parse hsts line '%s'", line); } g_strfreev(parts); } g_strfreev(lines); }
/* local_db_needs_update function returns TRUE on success and FALSE on failure. * It sets the parameter needs_update to TRUE if the local database needs * to be updated. */ static gboolean local_db_needs_update (SoupSession *session, const char *db_uri, GFile *db_local, gboolean *needs_update, GError **error) { GFileInfo *db_local_info; SoupMessage *msg; SoupDate *date; const gchar *db_time_str; guint64 db_time; guint64 db_local_time; guint status_code; if (g_file_query_exists (db_local, NULL) == FALSE) { *needs_update = TRUE; return TRUE; } msg = soup_message_new ("HEAD", db_uri); status_code = soup_session_send_message (session, msg); if (status_code != SOUP_STATUS_OK) { g_set_error_literal (error, SOUP_HTTP_ERROR, status_code, msg->reason_phrase); return FALSE; } db_time_str = soup_message_headers_get_one (msg->response_headers, "Last-Modified"); date = soup_date_new_from_string (db_time_str); db_time = (guint64) soup_date_to_time_t (date); soup_date_free (date); g_object_unref (msg); db_local_info = g_file_query_info (db_local, "time::modified", G_FILE_QUERY_INFO_NONE, NULL, error); if (!db_local_info) return FALSE; db_local_time = g_file_info_get_attribute_uint64 (db_local_info, "time::modified"); if (db_time <= db_local_time) *needs_update = FALSE; else *needs_update = TRUE; g_object_unref (db_local_info); return TRUE; }
static gint64 utils_http_full_date_to_timestamp(const char* string) { gint64 ret; SoupDate* tmp; tmp = soup_date_new_from_string(string); ret = soup_date_to_time_t(tmp); soup_date_free(tmp); return ret; }
gint64 utils_http_full_date_to_timestamp(const char* string) { gint64 ret = G_MAXINT64; g_autoptr(SoupDate) date = NULL; date = soup_date_new_from_string(string); RETURN_VAL_IF_FAIL(date != NULL, ret); ret = soup_date_to_time_t(date); return ret; }
static SoupDate * make_date (const char *strdate) { char *dup; SoupDate *date; /* We do it this way so that if soup_date_new_from_string() * reads off the end of the string, it will trigger an error * when valgrinding, rather than just reading the start of the * next const string. */ dup = g_strdup (strdate); date = soup_date_new_from_string (dup); g_free (dup); return date; }
time_t twitter_http_date_to_time_t (const gchar *date) { SoupDate *soup_date; time_t retval; g_return_val_if_fail (date != NULL, (time_t) -1); soup_date = soup_date_new_from_string (date); if (!soup_date) return (time_t) -1; retval = soup_date_to_time_t (soup_date); soup_date_free (soup_date); return retval; }
static void rygel_mediathek_rss_container_on_feed_got (RygelMediathekRssContainer* self, SoupSession* session, SoupMessage* msg) { #line 129 "rygel-mediathek-rss-container.c" guint _tmp0_; #line 31 "rygel-mediathek-rss-container.vala" g_return_if_fail (self != NULL); #line 31 "rygel-mediathek-rss-container.vala" g_return_if_fail (session != NULL); #line 31 "rygel-mediathek-rss-container.vala" g_return_if_fail (msg != NULL); #line 32 "rygel-mediathek-rss-container.vala" switch ((g_object_get (msg, "status-code", &_tmp0_, NULL), _tmp0_)) { #line 139 "rygel-mediathek-rss-container.c" case 304: { #line 34 "rygel-mediathek-rss-container.vala" g_message ("rygel-mediathek-rss-container.vala:34: %s", _ ("Feed has not changed, nothing to do")); #line 35 "rygel-mediathek-rss-container.vala" break; #line 146 "rygel-mediathek-rss-container.c" } case 200: { #line 37 "rygel-mediathek-rss-container.vala" if (rygel_mediathek_rss_container_parse_response (self, (const char*) msg->response_body->data, (gsize) msg->response_body->length)) { #line 152 "rygel-mediathek-rss-container.c" SoupDate* _tmp1_; #line 39 "rygel-mediathek-rss-container.vala" self->priv->last_modified = (_tmp1_ = soup_date_new_from_string (soup_message_headers_get (msg->response_headers, "Date")), _soup_date_free0 (self->priv->last_modified), _tmp1_); #line 156 "rygel-mediathek-rss-container.c" } #line 42 "rygel-mediathek-rss-container.vala" break; #line 160 "rygel-mediathek-rss-container.c" } default: { guint _tmp2_; guint _tmp3_; #line 45 "rygel-mediathek-rss-container.vala" g_warning (_ ("Got unexpected response %u (%s)"), (g_object_get (msg, "status-code", &_tmp2_, NULL), _tmp2_), soup_status_get_phrase ((g_object_get (msg, "status-code", &_tmp3_, NULL), _tmp3_))); #line 48 "rygel-mediathek-rss-container.vala" break; #line 170 "rygel-mediathek-rss-container.c" } } }
static void network_process_callback (SoupSession *session, SoupMessage *msg, gpointer user_data) { updateJobPtr job = (updateJobPtr)user_data; SoupDate *last_modified; const gchar *tmp = NULL; job->result->source = soup_uri_to_string (soup_message_get_uri(msg), FALSE); if (SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code)) { job->result->returncode = msg->status_code; job->result->httpstatus = 0; } else { job->result->httpstatus = msg->status_code; job->result->returncode = 0; } debug1 (DEBUG_NET, "download status code: %d", msg->status_code); debug1 (DEBUG_NET, "source after download: >>>%s<<<", job->result->source); job->result->data = g_memdup (msg->response_body->data, msg->response_body->length+1); job->result->size = (size_t)msg->response_body->length; debug1 (DEBUG_NET, "%d bytes downloaded", job->result->size); job->result->contentType = g_strdup (soup_message_headers_get_content_type (msg->response_headers, NULL)); /* Update last-modified date */ tmp = soup_message_headers_get_one (msg->response_headers, "Last-Modified"); if (tmp) { /* The string may be badly formatted, which will make * soup_date_new_from_string() return NULL */ last_modified = soup_date_new_from_string (tmp); if (last_modified) { job->result->updateState->lastModified = soup_date_to_time_t (last_modified); soup_date_free (last_modified); } } /* Update ETag value */ tmp = soup_message_headers_get_one (msg->response_headers, "ETag"); if (tmp) { job->result->updateState->etag = g_strdup(tmp); } update_process_finished_job (job); }
gboolean twitter_date_to_time_val (const gchar *date, GTimeVal *time_) { time_t res; SoupDate *soup_date; g_return_val_if_fail (date != NULL, FALSE); g_return_val_if_fail (time_ != NULL, FALSE); soup_date = soup_date_new_from_string (date); if (soup_date) { res = soup_date_to_time_t (soup_date); soup_date_free (soup_date); time_->tv_sec = res; time_->tv_usec = 0; return TRUE; } #ifdef HAVE_STRPTIME { struct tm tmp; /* OMFG, what are they? insane? */ strptime (date, "%a %b %d %T %z %Y", &tmp); res = mktime (&tmp); if (res != 0) { time_->tv_sec = res; time_->tv_usec = 0; return TRUE; } } #endif /* HAVE_STRPTIME */ return FALSE; }
gint64 feed_get_element_date (FeedParser* fparser) { time_t date; gchar* content; date = 0; content = feed_get_element_string (fparser); if (content) { SoupDate* sdate; sdate = soup_date_new_from_string (content); date = soup_date_to_time_t (sdate); soup_date_free (sdate); g_free (content); } return ((gint64)date); }
static void resource_available (GSSDPResourceBrowser *resource_browser, SoupMessageHeaders *headers) { GSSDPResourceBrowserPrivate *priv; const char *usn; const char *header; Resource *resource; gboolean was_cached; guint timeout; GList *locations; gboolean destroyLocations; GList *it1, *it2; char *canonical_usn; priv = gssdp_resource_browser_get_instance_private (resource_browser); usn = soup_message_headers_get_one (headers, "USN"); if (!usn) return; /* No USN specified */ /* Build list of locations */ locations = NULL; destroyLocations = TRUE; header = soup_message_headers_get_one (headers, "Location"); if (header) locations = g_list_append (locations, g_strdup (header)); header = soup_message_headers_get_one (headers, "AL"); if (header) { /* Parse AL header. The format is: * <uri1><uri2>... */ const char *start, *end; char *uri; start = header; while ((start = strchr (start, '<'))) { start += 1; if (!start || !*start) break; end = strchr (start, '>'); if (!end || !*end) break; uri = g_strndup (start, end - start); locations = g_list_append (locations, uri); start = end; } } if (!locations) return; /* No location specified */ if (priv->version > 0) { char *version; version = g_strrstr (usn, ":"); canonical_usn = g_strndup (usn, version - usn); } else { canonical_usn = g_strdup (usn); } /* Get from cache, if possible */ resource = g_hash_table_lookup (priv->resources, canonical_usn); /* Put usn into fresh resources, so this resource will not be * removed on cache refreshing. */ if (priv->fresh_resources != NULL) { g_hash_table_add (priv->fresh_resources, g_strdup (canonical_usn)); } /* If location does not match, expect that we missed bye bye packet */ if (resource) { for (it1 = locations, it2 = resource->locations; it1 && it2; it1 = it1->next, it2 = it2->next) { if (strcmp ((const char *) it1->data, (const char *) it2->data) != 0) { resource_unavailable (resource_browser, headers); /* Will be destroyed by resource_unavailable */ resource = NULL; break; } } } if (resource) { /* Remove old timeout */ g_source_destroy (resource->timeout_src); was_cached = TRUE; } else { /* Create new Resource data structure */ resource = g_slice_new (Resource); resource->resource_browser = resource_browser; resource->usn = g_strdup (usn); resource->locations = locations; destroyLocations = FALSE; /* Ownership passed to resource */ g_hash_table_insert (priv->resources, canonical_usn, resource); was_cached = FALSE; /* hash-table takes ownership of this */ canonical_usn = NULL; } g_free (canonical_usn); /* Calculate new timeout */ header = soup_message_headers_get_one (headers, "Cache-Control"); if (header) { GSList *list; int res; res = 0; for (list = soup_header_parse_list (header); list; list = list->next) { res = sscanf (list->data, "max-age = %d", &timeout); if (res == 1) break; } if (res != 1) { g_warning ("Invalid 'Cache-Control' header. Assuming " "default max-age of %d.\n" "Header was:\n%s", SSDP_DEFAULT_MAX_AGE, header); timeout = SSDP_DEFAULT_MAX_AGE; } soup_header_free_list (list); } else { const char *expires; expires = soup_message_headers_get_one (headers, "Expires"); if (expires) { SoupDate *soup_exp_time; time_t exp_time, cur_time; soup_exp_time = soup_date_new_from_string (expires); exp_time = soup_date_to_time_t (soup_exp_time); soup_date_free (soup_exp_time); cur_time = time (NULL); if (exp_time > cur_time) timeout = exp_time - cur_time; else { g_warning ("Invalid 'Expires' header. Assuming " "default max-age of %d.\n" "Header was:\n%s", SSDP_DEFAULT_MAX_AGE, expires); timeout = SSDP_DEFAULT_MAX_AGE; } } else { g_warning ("No 'Cache-Control' nor any 'Expires' " "header was specified. Assuming default " "max-age of %d.", SSDP_DEFAULT_MAX_AGE); timeout = SSDP_DEFAULT_MAX_AGE; } } resource->timeout_src = g_timeout_source_new_seconds (timeout); g_source_set_callback (resource->timeout_src, resource_expire, resource, NULL); g_source_attach (resource->timeout_src, g_main_context_get_thread_default ()); g_source_unref (resource->timeout_src); /* Only continue with signal emission if this resource was not * cached already */ if (!was_cached) { /* Emit signal */ g_signal_emit (resource_browser, signals[RESOURCE_AVAILABLE], 0, usn, locations); } /* Cleanup */ if (destroyLocations) g_list_free_full (locations, g_free); }
static void file_info_from_message (SoupMessage *msg, GFileInfo *info, GFileAttributeMatcher *matcher) { const char *text; GHashTable *params; char *basename; char *ed_name; basename = ed_name = NULL; /* prefer the filename from the Content-Disposition (rfc2183) header if one if present. See bug 551298. */ if (soup_message_headers_get_content_disposition (msg->response_headers, NULL, ¶ms)) { const char *name = g_hash_table_lookup (params, "filename"); if (name) basename = g_strdup (name); g_hash_table_destroy (params); } if (basename == NULL) { const SoupURI *uri; uri = soup_message_get_uri (msg); basename = http_uri_get_basename (uri->path); } g_debug ("basename:%s\n", basename); /* read http/1.1 rfc, until then we copy the local files * behaviour */ if (basename != NULL && (g_file_attribute_matcher_matches (matcher, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME) || g_file_attribute_matcher_matches (matcher, G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME))) ed_name = gvfs_file_info_populate_names_as_local (info, basename); g_free (basename); g_free (ed_name); if (soup_message_headers_get_encoding (msg->response_headers) == SOUP_ENCODING_CONTENT_LENGTH) { goffset start, end, length; gboolean ret; ret = soup_message_headers_get_content_range (msg->response_headers, &start, &end, &length); if (ret && length != -1) { g_file_info_set_size (info, length); } else if (!ret) { length = soup_message_headers_get_content_length (msg->response_headers); g_file_info_set_size (info, length); } } g_file_info_set_file_type (info, G_FILE_TYPE_REGULAR); text = soup_message_headers_get_content_type (msg->response_headers, NULL); if (text) { GIcon *icon; g_file_info_set_content_type (info, text); g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE, text); icon = g_content_type_get_icon (text); g_file_info_set_icon (info, icon); g_object_unref (icon); icon = g_content_type_get_symbolic_icon (text); g_file_info_set_symbolic_icon (info, icon); g_object_unref (icon); } text = soup_message_headers_get_one (msg->response_headers, "Last-Modified"); if (text) { SoupDate *sd; GTimeVal tv; sd = soup_date_new_from_string(text); if (sd) { soup_date_to_timeval (sd, &tv); g_file_info_set_modification_time (info, &tv); soup_date_free (sd); } } text = soup_message_headers_get_one (msg->response_headers, "ETag"); if (text) { g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_ETAG_VALUE, text); } }
/** * twitter_date_to_time_val: * @date: a timestamp coming from Twitter * @time_: return location for a #GTimeVal * * Converts a Twitter date into a #GTimeVal. The timestamp is relative * to UTC. * * Return value: %TRUE if the conversion was successful */ gboolean twitter_date_to_time_val (const gchar *date, GTimeVal *time_) { time_t res; SoupDate *soup_date; g_return_val_if_fail (date != NULL, FALSE); g_return_val_if_fail (time_ != NULL, FALSE); /* XXX - this code is here in case there's a sudden onset of sanity * at Twitter and they switch to using any format supported by libsoup */ soup_date = soup_date_new_from_string (date); if (soup_date) { res = soup_date_to_time_t (soup_date); soup_date_free (soup_date); time_->tv_sec = res; time_->tv_usec = 0; return TRUE; } #ifdef HAVE_STRPTIME { struct tm tmp; /* OMFG, ctime()? really? what are they? insane? I swear, this is * what happens when you let ruby developers write public APIs * * what happened to ISO8601 and web datestamps? you work on the web, * people! */ strptime (date, "%a %b %d %T %z %Y", &tmp); #ifdef HAVE_TIMEGM time_->tv_sec = timegm (&tmp); time_->tv_usec = 0; return TRUE; #else { res = 0; if (tmp.tm_mon < 0 || tmp.tm_mon > 11) { time_->tv_sec = res; time_->tv_usec = 0; return FALSE; } res += (tmp.tm_year - 70) * 365; res += (tmp.tm_year - 68) / 4; res += days_before[tmp.tm_mon] + tmp.tm_mday - 1; if (tmp.tm_year % 4 == 0 && tmp.tm_mon < 2) res -= 1; res = ((((res * 24) + tmp.tm_hour) * 60) + tmp.tm_min) * 60 + tmp.tm_sec; time_->tv_sec = res; time_->tv_usec = 0; return TRUE; } #endif /* HAVE_TIMEGM */ } #endif /* HAVE_STRPTIME */ return FALSE; }
static void server_callback (SoupServer *server, SoupMessage *msg, const char *path, GHashTable *query, SoupClientContext *context, gpointer data) { const char *last_modified, *etag; const char *header; guint status = SOUP_STATUS_OK; if (msg->method != SOUP_METHOD_GET && msg->method != SOUP_METHOD_POST) { soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); return; } header = soup_message_headers_get_one (msg->request_headers, "Test-Set-Expires"); if (header) { soup_message_headers_append (msg->response_headers, "Expires", header); } header = soup_message_headers_get_one (msg->request_headers, "Test-Set-Cache-Control"); if (header) { soup_message_headers_append (msg->response_headers, "Cache-Control", header); } last_modified = soup_message_headers_get_one (msg->request_headers, "Test-Set-Last-Modified"); if (last_modified) { soup_message_headers_append (msg->response_headers, "Last-Modified", last_modified); } etag = soup_message_headers_get_one (msg->request_headers, "Test-Set-ETag"); if (etag) { soup_message_headers_append (msg->response_headers, "ETag", etag); } header = soup_message_headers_get_one (msg->request_headers, "If-Modified-Since"); if (header && last_modified) { SoupDate *date; time_t lastmod, check; date = soup_date_new_from_string (last_modified); lastmod = soup_date_to_time_t (date); soup_date_free (date); date = soup_date_new_from_string (header); check = soup_date_to_time_t (date); soup_date_free (date); if (lastmod <= check) status = SOUP_STATUS_NOT_MODIFIED; } header = soup_message_headers_get_one (msg->request_headers, "If-None-Match"); if (header && etag) { if (!strcmp (header, etag)) status = SOUP_STATUS_NOT_MODIFIED; } if (status == SOUP_STATUS_OK) { GChecksum *sum; const char *body; sum = g_checksum_new (G_CHECKSUM_SHA256); g_checksum_update (sum, (guchar *)path, strlen (path)); if (last_modified) g_checksum_update (sum, (guchar *)last_modified, strlen (last_modified)); if (etag) g_checksum_update (sum, (guchar *)etag, strlen (etag)); body = g_checksum_get_string (sum); soup_message_set_response (msg, "text/plain", SOUP_MEMORY_COPY, body, strlen (body) + 1); g_checksum_free (sum); } soup_message_set_status (msg, status); }