PHPDaemon\Clients\HTTP\Connection::onRead PHP Method

onRead() public method

Called when new data received
public onRead ( )
    public function onRead()
    {
        if ($this->state === self::STATE_BODY) {
            goto body;
        }
        if ($this->reqType === null) {
            if ($this->requests->isEmpty()) {
                $this->finish();
                return;
            }
            $this->reqType = $this->requests->shift();
        }
        while (($line = $this->readLine()) !== null) {
            if ($line !== '') {
                if ($this->rawHeaders !== null) {
                    $this->rawHeaders[] = $line;
                }
            } else {
                if (isset($this->headers['HTTP_CONTENT_LENGTH'])) {
                    $this->contentLength = (int) $this->headers['HTTP_CONTENT_LENGTH'];
                } else {
                    $this->contentLength = -1;
                }
                if (isset($this->headers['HTTP_TRANSFER_ENCODING'])) {
                    $e = explode(', ', strtolower($this->headers['HTTP_TRANSFER_ENCODING']));
                    $this->chunked = in_array('chunked', $e, true);
                } else {
                    $this->chunked = false;
                }
                if (isset($this->headers['HTTP_CONNECTION'])) {
                    $e = explode(', ', strtolower($this->headers['HTTP_CONNECTION']));
                    $this->keepalive = in_array('keep-alive', $e, true);
                }
                if (isset($this->headers['HTTP_CONTENT_TYPE'])) {
                    parse_str('type=' . strtr($this->headers['HTTP_CONTENT_TYPE'], [';' => '&', ' ' => '']), $p);
                    $this->contentType = $p['type'];
                    if (isset($p['charset'])) {
                        $this->charset = strtolower($p['charset']);
                    }
                }
                if ($this->contentLength === -1 && !$this->chunked && !$this->keepalive) {
                    $this->eofTerminated = true;
                }
                if ($this->reqType === 'HEAD') {
                    $this->requestFinished();
                } else {
                    $this->state = self::STATE_BODY;
                }
                break;
            }
            if ($this->state === self::STATE_ROOT) {
                $this->headers['STATUS'] = $line;
                $e = explode(' ', $this->headers['STATUS']);
                $this->responseCode = isset($e[1]) ? (int) $e[1] : 0;
                $this->state = self::STATE_HEADERS;
            } elseif ($this->state === self::STATE_HEADERS) {
                $e = explode(': ', $line);
                if (isset($e[1])) {
                    $k = 'HTTP_' . strtoupper(strtr($e[0], Generic::$htr));
                    if ($k === 'HTTP_SET_COOKIE') {
                        parse_str(strtr($e[1], [';' => '&', ' ' => '']), $p);
                        if (sizeof($p)) {
                            $this->cookie[$k = key($p)] =& $p;
                            $p['value'] = $p[$k];
                            unset($p[$k], $p);
                        }
                    }
                    if (isset($this->headers[$k])) {
                        if (is_array($this->headers[$k])) {
                            $this->headers[$k][] = $e[1];
                        } else {
                            $this->headers[$k] = [$this->headers[$k], $e[1]];
                        }
                    } else {
                        $this->headers[$k] = $e[1];
                    }
                }
            }
        }
        if ($this->state !== self::STATE_BODY) {
            return;
            // not enough data yet
        }
        body:
        if ($this->eofTerminated) {
            $body = $this->readUnlimited();
            if ($this->chunkcb) {
                $func = $this->chunkcb;
                $func($body);
            }
            $this->body .= $body;
            return;
        }
        if ($this->chunked) {
            chunk:
            if ($this->curChunkSize === null) {
                // outside of chunk
                $l = $this->readLine();
                if ($l === '') {
                    // skip empty line
                    goto chunk;
                }
                if ($l === null) {
                    return;
                    // not enough data yet
                }
                if (!ctype_xdigit($l)) {
                    $this->protocolError = __LINE__;
                    $this->finish();
                    // protocol error
                    return;
                }
                $this->curChunkSize = hexdec($l);
            }
            if ($this->curChunkSize !== null) {
                if ($this->curChunkSize === 0) {
                    if ($this->readLine() === '') {
                        $this->requestFinished();
                        return;
                    } else {
                        // protocol error
                        $this->protocolError = __LINE__;
                        $this->finish();
                        return;
                    }
                }
                $n = $this->curChunkSize - mb_orig_strlen($this->curChunk);
                $this->curChunk .= $this->read($n);
                if ($this->curChunkSize <= mb_orig_strlen($this->curChunk)) {
                    if ($this->chunkcb) {
                        $func = $this->chunkcb;
                        $func($this->curChunk);
                    }
                    $this->body .= $this->curChunk;
                    $this->curChunkSize = null;
                    $this->curChunk = '';
                    goto chunk;
                }
            }
        } else {
            $body = $this->read($this->contentLength - mb_orig_strlen($this->body));
            if ($this->chunkcb) {
                $func = $this->chunkcb;
                $func($body);
            }
            $this->body .= $body;
            if ($this->contentLength !== -1 && mb_orig_strlen($this->body) >= $this->contentLength) {
                $this->requestFinished();
            }
        }
    }