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

报告相同问题?

悬赏问题

  • ¥15 网络科学导论,网络控制
  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd
  • ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
  • ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)