dsjklb0205 2017-03-15 18:08
浏览 348
已采纳

PHP Curl - 跟随“201 Created”响应头的位置

I am submitting a CURL Post request to an API which, upon success, returns status "201 Created" with the URL of the resource in the LOCATION part of the header. What I'd like is to automatically retrieve the newly created resource but so far haven't been able to do so. I've tried setting curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); but to no avail. it's worth noting that the resource does require a GET request.

I'm not sure if it's the status code being a 201, or if the request method needs to change from POST to GET, but for some reason it's not following the LOCATION header. Fetching curl_getinfo($ch,CURLINFO_EFFECTIVE_URL); seems to confirm this as the result is the same as the original URL, not the new LOCATION.

As a last resort I have considered simply parsing the headers and creating a new CURL request, but this would not be optimal and I'm guessing that I'm just missing something simple to make this work as desired.

How can I get CURL to automatically follow and submit a GET request to the LOCATION returned with a 201 response?

  • 写回答

2条回答 默认 最新

  • douqiao4450 2017-03-15 18:19
    关注

    You can't.

    With curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl follow the response LOCATION only for 3xx status codes.

    AFAIK and stating as the documentation there is no way to force curl to follow-location with a 201 response.

    You have to parse the header, fetch the LOCATION and then issue a second curl request.

    Following a location with a status different than 3xx would be an anomaly. Also from the curl command line tool and C library 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


    Giving a quick look at the curl source code you find on /lib/http.c the function Curl_http_readwrite_headers.

    Location follow is handled inside with this conditional:

    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;
        }
      }
    }
    

    The location is followed with a status code between 300 and 399

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3