public function curlStreaming($url, $callback, $params = array(), $proxy = '') {
        static $decode;
        if (!$decode) {
            if (version_compare(PHP_VERSION, '5.4.0') < 0) {
                $decode = function ($ch, $response) {
                    static $rm;
                    if (!$rm) {
                        $rm = new ReflectionMethod(__CLASS__, 'decode');
                        $rm->setAccessible(true);
                    }
                    return $rm->invoke(null, $ch, $response);
                };
            } else {
                $decode = array(__CLASS__, 'decode');
            }
        }
        $u        = self::url(self::validateString('$url', $url), false);
        $callback = self::validateCallback('$callback', $callback);
        $obj      = self::getParamObject(self::validateParams('$params', $params, $u[1]));
        $proxy    = self::validateString('$proxy', $proxy);
        $params   = array();
        foreach ($obj->paramData as $key => $value) {
            $params[$key] =
                $obj->paramIsFile[$key] ?
                base64_encode($value) :
                $value
            ;
        }
        $ch = self::curlInit($proxy);
        curl_setopt_array($ch, array(
            CURLOPT_HTTPHEADER     => $this->getAuthorization($u[0], 'POST', $params, 0),
            CURLOPT_URL            => $u[0],
            CURLOPT_POST           => true,
            CURLOPT_POSTFIELDS     => http_build_query($params, '', '&'),
            CURLOPT_TIMEOUT        => 0,
            CURLOPT_WRITEFUNCTION  => function ($ch, $str) use ($callback, $decode) {
                static $first = true;
                static $buffer = '';
                $buffer .= $str;
                // check error at first
                if ($first) {
                    $first = false;
                    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
                    if ($code !== 200) {
                        $decode($ch, $buffer);
                        // unknown error
                        throw new TwistException('Streaming stopped unexpectedly: ' . $buffer, $code);
                    }
                }
                // decode line
                if ($buffer[strlen($buffer) - 1] === "\n") {
                    // skip empty line
                    if (trim($buffer) !== '' && $callback($decode($ch, $buffer))) {
                        return 0;
                    }
                    $buffer = '';
                }
                return strlen($str);
            }
        ));
        return $ch;
    }