Workerman3.4.2在3.4.0版本上改动了HTTP协议,导致POST请求收不到内容

moubai

之前业务是建立在3.4.0版本上,客户端采用POST发送JSON数据,接收正常,现更换为3.4.2版本后,业务代码不变,但打印data数据段,发现content-type为application/json时,post节点一直为空,为application/x-www-form-urlencoded时才会有数据。

对比两个版本中的Http.php,发现3.4.2改动了一处。
原3.4.0版本:

// Parse $_POST.
if ($_SERVER === 'POST') {
    if (isset($_SERVER) && $_SERVER === 'multipart/form-data') {
        self::parseUploadFiles($http_body, $http_post_boundary);
    } else {
        **parse_str($http_body, $_POST);**
        // $GLOBALS
        $GLOBALS = $GLOBALS = $http_body;
    }
}

现3.4.2版本:

// Parse $_POST.
if ($_SERVER === 'POST') {
    if (isset($_SERVER)) {
        switch ($_SERVER) {
            case 'multipart/form-data':
                self::parseUploadFiles($http_body, $http_post_boundary);
                break;
            case 'application/x-www-form-urlencoded':
                parse_str($http_body, $_POST);
                break;
            default:
                // $GLOBALS
                $GLOBALS = $GLOBALS = $http_body;
        }
    } else {
        // $GLOBALS
        $GLOBALS = $GLOBALS = $http_body;
    }
}

尝试在default段加入:parse_str($http_body, $_POST); 业务正常。

3071 2 0
2个回答

walkor

打印下 $GLOBALS ,我这边看看是什么数据

  • moubai 2017-06-15

    打印出的是JSON数据体:string(33) "{"type":"ad_list","sessionid":""}"

walkor

https://github.com/walkor/Workerman/pull/154
这里有个关于这个的issue
如果不是application/x-www-form-urlencoded的,不应该用parse_str。
content-type为application/json 时,应该是传递的json数据,不是urlencoded的数据

  • moubai 2017-06-15

    业务这边修改下接收数据的方式就可以了,现在3.4.2跟Apache上处理方式一样了。也贴下原先3.4.0的接收方式,现在这种更好:
    // 收到客户端发来的消息
    //$data_json = json_decode(array_keys($data['post'], 0)[0], true);
    $data_json = json_decode($GLOBALS['HTTP_RAW_REQUEST_DATA'], true);

  • walkor 2017-06-16

    好的

年代过于久远,无法发表回答
🔝