2017-03-15 106 views
1

我向一个API提交CURL Post请求,一旦成功返回标题LOCATION部分资源URL的状态“201 Created”。我想要的是自动检索新创建的资源,但到目前为止还没有这样做。我试过设置curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);但无济于事。值得注意的是该资源确实需要GET请求。PHP Curl - 跟随“201 Created”响应标题的位置

我不知道,如果它的状态代码是一个201,或者如果请求方法需要改变从POSTGET,但由于某种原因它不遵循LOCATION头。提取curl_getinfo($ch,CURLINFO_EFFECTIVE_URL);似乎证实了这一点,因为结果与原始URL相同,而不是新的LOCATION

作为最后的手段,我已经考虑简单地解析头文件并创建一个新的CURL请求,但这不会是最佳的,而且我猜测我只是缺少一些简单的东西来使这项工作按需要。

如何获得CURL自动跟踪并向LOCATION提交GET请求,并返回201响应?

回答

3

你不能。

With curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl请按照响应LOCATION仅限于3xx状态码。

AFAIK并声明作为文件没有办法迫使卷曲跟随201位回应的位置。

您必须解析标头,获取LOCATION,然后发出第二个卷曲请求。

以下位置的状态不同于3xx将是一个异常。此外,从curl命令行工具和C库documentation-L, --location -- (HTTP) If the server reports that the requested page has moved to a different location (indicated with a Location: header and a 3XX response code), this option will make curl redo the request on the new place


给人一种快看卷曲源代码,你会发现在/lib/http.c功能Curl_http_readwrite_headers

位置遵循的是里面有这个条件处理:

else if((k->httpcode >= 300 && k->httpcode < 400) && 
     checkprefix("Location:", k->p) && 
     !data->req.location) { 
    /* this is the URL that the server advises us to use instead */ 
    char *location = Curl_copy_header_value(k->p); 
    if(!location) 
    return CURLE_OUT_OF_MEMORY; 
    if(!*location) 
    /* ignore empty data */ 
    free(location); 
    else { 
    data->req.location = location; 

    if(data->set.http_follow_location) { 
     DEBUGASSERT(!data->req.newurl); 
     data->req.newurl = strdup(data->req.location); /* clone */ 
     if(!data->req.newurl) 
     return CURLE_OUT_OF_MEMORY; 

     /* some cases of POST and PUT etc needs to rewind the data 
     stream at this point */ 
     result = http_perhapsrewind(conn); 
     if(result) 
     return result; 
    } 
    } 
} 

位置之后与300399

+0

谢谢,我开始怀疑这一点。你能添加一个链接到描述这个的文档吗?我认为这会改善答案,我很乐意接受它。 – billynoah

+0

http://php.net/manual/en/function.curl-setopt.php – Paolo

+1

我删除了评论,还发布了一部分源代码,它提供了对文档的解释是正确的线索(状态没有重定向超出范围3xx) – Paolo

0

我明白这并没有回答你的问题在纯粹意义之间的状态码它 - 我的解决方案甚至没有在PHP中,但这里有一种方法(使用jq)遵循201 cURL:

shrinkImageFunction() { 
echo 
echo Compressing $1 . . . 

curl --user api: https://tinypng.com/developers \ 
     --data-binary @$1 \ 
     -o .$1-json \ 
     -s \ 
     https://api.tinify.com/shrink 

cat .$1-json | jq -r '.output.url' > .$1-url 

url=$(cat .$1-url) 

if [ -z "$url" ]; then 
     echo Something went wrong 
     return 
fi 

echo Downloading $url . . . 

echo 
curl -o compressed-$1 $url 
echo 

rm .$1-json 
rm .$1-url 
} 

# alias for using tinypng 
alias shrinkImage=shrinkImageFunction 

我今天在做类似的研究的时候把它扔在了一起,并且认为我会分享遇到这个问题的同时寻找选择。

它可以很容易地被调整来解析http 201标题响应使用sed或类似的而不是jq我在解析http提供的身体json响应tinypng(仅供参考 - 我不隶属于他们)。