예제 #1
0
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);
}
예제 #2
0
파일: hsts.c 프로젝트: vlampreia/vimb
/**
 * 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);
}
예제 #3
0
/* 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;
}
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #6
0
파일: date.c 프로젝트: Conservatory/quark
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;
}
예제 #7
0
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;
}
예제 #8
0
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"
		}
	}
}
예제 #9
0
파일: net.c 프로젝트: gcampax/liferea
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);
}
예제 #10
0
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;
}
예제 #11
0
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);
}
예제 #12
0
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);
}
예제 #13
0
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, &params))
    {
      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);
    }
}
예제 #14
0
/**
 * 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;
}
예제 #15
0
파일: cache-test.c 프로젝트: Kharif/libsoup
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);
}