douyouming9180 2013-07-26 04:21
浏览 120
已采纳

通过shell_exec将二进制数据发送到php-cgi

I have a script that sends a post request to /usr/bin/php-cgi. The script is working fine when dealing with plain text, but fails when the data is binary:

$data = file_get_contents('example.jpg');
$size = filesize('example.jpg') + 5; 
$post_data = 'file='.$data;
$response = shell_exec('echo "'.$post_data.'" | 
                        REDIRECT_STATUS=CGI
                        REQUEST_METHOD=POST
                        SCRIPT_FILENAME=/example/script.php 
                        SCRIPT_NAME=/script.php 
                        PATH_INFO=/ 
                        SERVER_NAME=localhost 
                        SERVER_PROTOCOL=HTTP/1.1 
                        REQUEST_URI=/example/index.html 
                        HTTP_HOST=example.com 
                        CONTENT_TYPE=application/x-www-form-urlencoded
                        CONTENT_LENGTH='.$size.' php-cgi');

I get the following error:

sh: -c: line 1: unexpected EOF while looking for matching `"'
sh: -c: line 5: syntax error: unexpected end of file

I guess this is because the data I'm trying to send is binary and must be encoded/escaped somehow.

Like I said the above code works if the data is plain text:

$post_data = "data=sample data to php-cgi";
$size = strlen($post_data);

I also tried to encode the data using base64_encode() but then I face another problem; the data must be decoded from within the receiving script. I was thinking that perhaps I could encode the data in base64 and then add some content or mime type header to force the php-cgi binary to make the conversation?

One other problem is that I like to send the data as an attachment and therefore I think we must set CONTENT_TYPE to multipart/form-data; boundary=<random_boundary> and CONTENT_DISPOSITION to form-data, but I'm not sure how to set these headers from the commandline.

  • 写回答

3条回答 默认 最新

  • dongnong3019 2013-08-05 19:31
    关注

    Finally I got this working, the solution was to send a base64 encoded request which also contained a constant named field like ORIGINAL_QUERY_URI to a sort of gateway file that in turn would decode the request and bounce it to it's original destination.

    Basically, the server does this:

    1. encode any received file data in base64
    2. add a form-data field named ORIGINAL_REQEUST_URI with the original url as value
    3. assemble a valid http request body encoded as multipart/form-data based on above
    4. send this data using shell_exec to a gateway file that will decode the content

    Here is the command I used to send everything to php-cgi:

    shell_exec('echo "' . $body . '" | 
                HOST=localhost 
                REDIRECT_STATUS=200 
                REQUEST_METHOD=POST 
                SCRIPT_FILENAME=/<path>/gate.php 
                SCRIPT_NAME=/gate.php 
                PATH_INFO=/ 
                SERVER_NAME=localhost 
                SERVER_PROTOCOL=HTTP/1.1 
                REQUEST_URI=/example.php 
                HTTP_HOST=localhost
                CONTENT_TYPE="multipart/form-data; boundary=' . $boundary . '"  
                CONTENT_LENGTH=' . $size . ' php-cgi');
    

    Then inside the gate.php file I decoded the data and included the file pointed to by theORIGINAL_REQUEST_URI field.

    // File: gate.php
    if (isset($_FILES)) {
      foreach ($_FILES as $key => $value) {
         // decode the `base64` encoded file data
         $content = file_get_contents($_FILES[$key]['tmp_name']);
         $content = base64_decode($content);
         file_put_contents($_FILES[$key]['tmp_name'], $content);
      }
    }
    // bounce to original destination
    include_once($_POST['ORIGINAL_REQUEST_URI']);  
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上
  • ¥15 c程序不知道为什么得不到结果
  • ¥40 复杂的限制性的商函数处理
  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来