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

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条)

报告相同问题?

悬赏问题

  • ¥30 DeepLung肺结节检测生成最大froc值对应的epoch报错
  • ¥50 滴滴出行模拟系统,模拟叫车、出行过程等过程
  • ¥15 信号发生器如何将频率调大,步尽值改成10
  • ¥15 keil 5 编程智能家具,风扇台灯开关,人体感应等
  • ¥100 找一名渗透方面的专家
  • ¥20 使用Matlab gui设计一个插补小程序
  • ¥15 evo评估时曲线出现问题
  • ¥15 eNSP拓扑图配置实验
  • ¥20 有没有兄弟会替换fmod studio的.bank文件内的音效?
  • ¥20 如何解决访问网址被屏蔽的情况