douquan2023 2016-11-26 09:14
浏览 187
已采纳

cURL FTP自定义命令:运行w / o返回dir索引?

Writing a wrapper class for cURL/FTP in PHP. When I get or put files etc. standard ops with specific cURL options, cURL doesn't return the FTP directory index as the default response.

However: When I run custom FTP commands with CURLOPT_CUSTOMREQUEST, CURLOPT_QUOTE or CURLOPT_POSTQUOTE, for example to DELE or RNFR|RNTO, the FTP server returns the directory index as the default response in addition to running the commands. (If the commands are successful.)

This'd be expected behavior since CURLOPT_URL is also passed in, and without upload/download the index is what you get. (And I can't connect to the server w/o using CURLOPT_URL, or can I?) But I really don't care to waste bandwidth/RAM for receiving the index for every command I run. Would be problematic with large directories or large amounts of individual commands.

Of course I could minimize the waste by bundling up all the ops into a single curl_exec() call. I can minimize the response by adding in a CURLOPT_FTPLISTONLY, but that's still a load of unnecessary data being returned. Or I could append a failing command, very hackish and gives me just a fail result although the cmds are done. Or I could finally CWD into a directory that I know is blank huh? {^_^}

Then: Is there a way to tell cURL not to bother returning the directory index? Implementing a request pooler for cURL FTP calls coming in from various times/locations in other code using the class would also prevent me from returning individual success/fail responses in real time.

  • 写回答

1条回答 默认 最新

  • duanfu3634 2016-11-26 12:51
    关注

    So. There is an option for this after all. To exclude the response body from your cURL request:

    curl_setopt($this->curl, CURLOPT_NOBODY, true);
    

    ...does the trick. The command then returns an empty string or bool false if the command failed. Information on the last failed request is available with curl_error($this->curl).

    Now, some cURL responses to FTP commands are on the obscure side, displaying e.g. QUOT command failed with 550 (for failed rename attempt), while the actual FTP transaction was:

    > RNFR /foox/test.txt
    < 550 file/directory not found
    * QUOT command failed with 550
    

    Which is a lot more informative as far as what went wrong. Then set the CURLOPT_VERBOSE option. If you don't want to log either to a file or to stdout (= on-screen), here's a handy way to capture the response into a temporary stream. (N.B. we're working within a wrapper class/object here.)

    curl_setopt(CURLOPT_VERBOSE, true);
    $this->stream_log = fopen('php://temp', 'r+b');
    curl_setopt(CURLOPT_STDERR, $this->stream_log);
    

    ...and something like the following in your log fetcher method:

    rewind($this->stream_log);
    return stream_get_contents($this->stream_log);
    

    Makes cURL transaction debugging a lot easier. Further, if you want to get just the relevant segment of the log, here's a quick regex that helps ($cmd being the command you sent, starting the match):

    preg_match("#(> {$cmd}(.*?))\\v\*#s", $log, $m);
    return $m ? $m[1] : '';
    

    When my FTP cURL wrapper for PHP is done and dusted, will make available. Happy cURLing y'all.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥100 需要跳转番茄畅听app的adb命令
  • ¥50 寻找一位有逆向游戏盾sdk 应用程序经验的技术
  • ¥15 请问有用MZmine处理 “Waters SYNAPT G2-Si QTOF质谱仪在MSE模式下采集的非靶向数据” 的分析教程吗
  • ¥50 opencv4nodejs 如何安装
  • ¥15 adb push异常 adb: error: 1409-byte write failed: Invalid argument
  • ¥15 nginx反向代理获取ip,java获取真实ip
  • ¥15 eda:门禁系统设计
  • ¥50 如何使用js去调用vscode-js-debugger的方法去调试网页
  • ¥15 376.1电表主站通信协议下发指令全被否认问题
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证