r - 带有 URL 重定向的未记录的 RCurl "progressfunction"

标签 r .htaccess redirect curl rcurl

考虑这个简单的 RCurl 函数来报告下载进度:

library(RCurl)
curlDown=function(url, follow=TRUE){
    x=getURL(url, followlocation=follow, noprogress = FALSE,
        progressfunction=function(down,up) cat(down, '\n'))    
}

请注意,使用 followlocation=TRUE(默认)我们接受跟随服务器作为 HTTP header 的一部分发送的可能的重定向位置。

我们得到:

curlDown("http://www.example.com")
# 0 0 
# 1270 1079 
# 1270 1127 
# 1270 1270 
# 1270 1270 
# 1270 1270 

如您所见,RCurl 传递给回调的 down 变量是一个数值向量,其中第一个元素是以字节为单位的总下载量,第二个是运行下载大小。限于篇幅,这里就不展示了,单独查看发现前者相当于响应头中的Content-Length字段。

并非每个服务器都在响应 header 中提供 Content-Length 字段:

curlDown("http://www.google.it")
# 0 0  
# 0 603
# ... blah blah
# 0 44848 
# 0 44848 

在这种情况下,RCurl 将缺失的总值设置为零(NA 会更好吗?)。

Google 主域“.com”重定向到特定国家/地区的域,例如“.it”,如果您从与该域关联的国家/地区(意大利)进行查询。如果您实际位于“.it”域中,您将获得:

curlDown("http://www.google.com")
# 0 0 
# 274 274 
# 274 274 
# 274 274 
# 274 0 
# 274 0 
# 274 603
# ... blah blah
# 274 44896 
# 274 44896 

这些结果很奇怪。如果将正在运行的下载值与之前的 curlDown("http://www.google.it") 进行比较,您就会明白,在重定向之后,这些值与您预期的一样;但总数小于正在运行的下载量!

要了解我们不遵循重定向位置的问题:

curlDown("http://www.google.com", follow=FALSE)
# 0 0 
# 274 274 
# 274 274 
# 274 274 

主域服务器 .com 发送 Content-Length,274 字节,而重定向服务器则不发送(参见 curlDown("http ://www.google.it").

问题是,在重定向之后,RCurl 不会更新总下载大小的值(对于未知大小的情况为零),它仍然堆叠为 274 字节的错误值.

这是 BUG 还是我遗漏了什么?

最佳答案

我认为 Rcurl 忠实地转发来自 curl 的值,例如,如在 CURLOPT_PROGRESSFUNCTION 下的 curl_set_easyopt 上记录的那样,缺失值返回为 0。如果有错误,那么它就是 curl。这是一个简单的程序(请参阅 here 开始)

#include <stdio.h>
#include <curl/curl.h>

curl_progress_callback progress(void *clientp, double dltotal, double dlnow,
                                double ultotal, double ulnow)
{
    fprintf(stderr, "PROGRESS: %.0f %.0f %.0f %.0f\n",
            dltotal, dlnow, ultotal, ulnow);
    return 0;
}

int main(int argc, char **argv)
{
    CURL *curl;
    CURLcode res;

    curl = curl_easy_init();
    curl_easy_setopt(curl, CURLOPT_URL, argv[1]);
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
    curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress);
    res = curl_easy_perform(curl);
    curl_easy_cleanup(curl);

    return 0;
}

它的评价

$ clang curl.c -lcurl && ./a.out http://google.com > /dev/null
PROGRESS: 0 0 0 0
PROGRESS: 0 0 0 0
PROGRESS: 219 219 0 0
PROGRESS: 219 219 0 0
PROGRESS: 219 219 0 0
PROGRESS: 219 219 0 0
PROGRESS: 219 0 0 0
PROGRESS: 219 2097 0 0
PROGRESS: 219 6441 0 0
PROGRESS: 219 12233 0 0
PROGRESS: 219 20921 0 0
PROGRESS: 219 32505 0 0
PROGRESS: 219 45360 0 0
PROGRESS: 219 45360 0 0
PROGRESS: 219 45360 0 0

关于r - 带有 URL 重定向的未记录的 RCurl "progressfunction",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21969948/

相关文章:

linux - 在所有 .htaccess 文件中递归地查找一个字符串

grails - 在Grails中多次重定向响应

r - 如何计算R中的月差

r - 如何使用非线性函数拟合数据并绘制数据并使用 ggplot() 拟合

r - 使用 geom_smooth 将 glm 拟合到分数

R 动态重命名列并忽略缺失

apache - 如何从 https 子域 URL 中删除 www

apache - Mod_Rewrite 将子域和目录设置为 GET 变量

redirect - 交响乐 2 : Redirect a user to a page if he has a specific role

redirect - Webfaction 将 no-WWW 重定向到 WWW(静态应用程序、htaccess 文件)