Beispiel #1
0
/**
 * ephy_download_get_content_type:
 * @download: an #EphyDownload
 *
 * Gets content-type information for @download. If the file is already
 * present on the filesystem and readable, uses GIO to get the
 * content-type. Otherwise it uses WebKit and Soup.
 *
 * Returns: content-type for @download, must be freed with g_free()
 **/
char *
ephy_download_get_content_type (EphyDownload *download)
{
#ifdef HAVE_WEBKIT2
  WebKitURIResponse *response;
#else
  WebKitNetworkResponse *response;
  SoupMessage *message;
#endif
  char *content_type = NULL;
  GError *error = NULL;

  if (download->priv->destination) {
    GFile *destination;
    GFileInfo *info;

    destination = g_file_new_for_uri (download->priv->destination);
    info = g_file_query_info (destination, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
                              G_FILE_QUERY_INFO_NONE, NULL, &error);
    if (info) {
      content_type = g_strdup (g_file_info_get_content_type (info));
      LOG ("ephy_download_get_content_type: GIO: %s", content_type);
      g_object_unref (info);
    } else {
      LOG ("ephy_download_get_content_type: error getting file "
           "content-type: %s", error->message);
      g_error_free (error);
    }

    g_object_unref (destination);
  }

  if (content_type)
    return content_type;

  /* Fallback to Soup */
#ifdef HAVE_WEBKIT2
  response = webkit_download_get_response (download->priv->download);
  if (response)
    content_type = g_strdup (webkit_uri_response_get_mime_type (response));
#else
  response = webkit_download_get_network_response (download->priv->download);
  message = webkit_network_response_get_message (response);

  if (message != NULL)
    content_type = g_strdup (soup_message_headers_get_content_type (message->response_headers, NULL));
#endif

  LOG ("ephy_download_get_content_type: Soup: %s", content_type);

  LOG ("ephy_download_get_content_type: %s", content_type);

  return content_type;
}
Beispiel #2
0
gboolean
download_cb(WebKitWebView *web_view, WebKitDownload *download, gpointer user_data) {
    (void) web_view; (void) user_data;

    /* get the URI being downloaded */
    const gchar *uri = webkit_download_get_uri(download);

    /* get the destination path, if specified.
     * this is only intended to be set when this function is trigger by an
     * explicit download using uzbl's 'download' action. */
    const gchar *destination = user_data;

    if (uzbl.state.verbose)
        printf("Download requested -> %s\n", uri);

    if (!uzbl.behave.download_handler) {
        webkit_download_cancel(download);
        return FALSE; /* reject downloads when there's no download handler */
    }

    /* get a reasonable suggestion for a filename */
    const gchar *suggested_filename;
#ifdef USE_WEBKIT2
    WebKitURIResponse *response;
    g_object_get(download, "network-response", &response, NULL);
#if WEBKIT_CHECK_VERSION (1, 9, 90)
    g_object_get(response, "suggested-filename", &suggested_filename, NULL);
#else
    suggested_filename = webkit_uri_response_get_suggested_filename(respose);
#endif
#elif WEBKIT_CHECK_VERSION (1, 9, 6)
    WebKitNetworkResponse *response;
    g_object_get(download, "network-response", &response, NULL);
    g_object_get(response, "suggested-filename", &suggested_filename, NULL);
#else
    g_object_get(download, "suggested-filename", &suggested_filename, NULL);
#endif

    /* get the mimetype of the download */
    const gchar *content_type = NULL;
    WebKitNetworkResponse *r  = webkit_download_get_network_response(download);
    /* downloads can be initiated from the context menu, in that case there is
       no network response yet and trying to get one would crash. */
    if(WEBKIT_IS_NETWORK_RESPONSE(r)) {
        SoupMessage        *m = webkit_network_response_get_message(r);
        SoupMessageHeaders *h = NULL;
        g_object_get(m, "response-headers", &h, NULL);
        if(h) /* some versions of libsoup don't have "response-headers" here */
            content_type = soup_message_headers_get_one(h, "Content-Type");
    }

    if(!content_type)
        content_type = "application/octet-stream";

    /* get the filesize of the download, as given by the server.
       (this may be inaccurate, there's nothing we can do about that.)  */
    unsigned int total_size = webkit_download_get_total_size(download);

    GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*));
    const CommandInfo *c = parse_command_parts(uzbl.behave.download_handler, a);
    if(!c) {
        webkit_download_cancel(download);
        g_array_free(a, TRUE);
        return FALSE;
    }

    g_array_append_val(a, uri);
    g_array_append_val(a, suggested_filename);
    g_array_append_val(a, content_type);
    gchar *total_size_s = g_strdup_printf("%d", total_size);
    g_array_append_val(a, total_size_s);

    if(destination)
        g_array_append_val(a, destination);

    GString *result = g_string_new ("");
    run_parsed_command(c, a, result);

    g_free(total_size_s);
    g_array_free(a, TRUE);

    /* no response, cancel the download */
    if(result->len == 0) {
        webkit_download_cancel(download);
        return FALSE;
    }

    /* we got a response, it's the path we should download the file to */
    gchar *destination_path = result->str;
    g_string_free(result, FALSE);

    /* presumably people don't need newlines in their filenames. */
    char *p = strchr(destination_path, '\n');
    if ( p != NULL ) *p = '\0';

    /* set up progress callbacks */
    g_signal_connect(download, "notify::status",   G_CALLBACK(download_status_cb),   NULL);
    g_signal_connect(download, "notify::progress", G_CALLBACK(download_progress_cb), NULL);

    /* convert relative path to absolute path */
    if(destination_path[0] != '/') {
        gchar *rel_path = destination_path;
        gchar *cwd = g_get_current_dir();
        destination_path = g_strconcat(cwd, "/", destination_path, NULL);
        g_free(cwd);
        g_free(rel_path);
    }

    send_event(DOWNLOAD_STARTED, NULL, TYPE_STR, destination_path, NULL);

    /* convert absolute path to file:// URI */
    gchar *destination_uri = g_strconcat("file://", destination_path, NULL);
    g_free(destination_path);

    webkit_download_set_destination_uri(download, destination_uri);
    g_free(destination_uri);

    return TRUE;
}