Aerys\BodyParser::initIncremental PHP Method

initIncremental() private method

this should be inside an immediate (not direct resolve) to give user a chance to install watch() handlers
private initIncremental ( )
    private function initIncremental()
    {
        $buf = "";
        if ($this->boundary) {
            // RFC 7578, RFC 2046 Section 5.1.1
            $sep = "--{$this->boundary}";
            while (\strlen($buf) < \strlen($sep) + 4) {
                if (!(yield $this->body->valid())) {
                    return $this->fail(new ClientException());
                }
                $buf .= $this->body->consume();
            }
            $off = \strlen($sep);
            if (strncmp($buf, $sep, $off)) {
                return $this->fail(new ClientException());
            }
            $sep = "\r\n{$sep}";
            while (substr_compare($buf, "--\r\n", $off)) {
                $off += 2;
                while (($end = strpos($buf, "\r\n\r\n", $off)) === false) {
                    if (!(yield $this->body->valid())) {
                        return $this->fail(new ClientException());
                    }
                    $off = \strlen($buf);
                    $buf .= $this->body->consume();
                }
                $headers = [];
                foreach (explode("\r\n", substr($buf, $off, $end - $off)) as $header) {
                    $split = explode(":", $header, 2);
                    if (!isset($split[1])) {
                        return $this->fail(new ClientException());
                    }
                    $headers[strtolower($split[0])] = trim($split[1]);
                }
                if (!preg_match('#^\\s*form-data(?:\\s*;\\s*(?:name\\s*=\\s*"([^"]+)"|filename\\s*=\\s*"([^"]+)"))+\\s*$#', $headers["content-disposition"] ?? "", $m) || !isset($m[1])) {
                    return $this->fail(new ClientException());
                }
                $field = $m[1];
                // Ignore Content-Transfer-Encoding as deprecated and hence we won't support it
                if (isset($m[2])) {
                    $metadata = ["filename" => $m[2], "mime" => $headers["content-type"] ?? "application/octet-stream"];
                } elseif (isset($headers["content-type"])) {
                    $metadata = ["mime" => $headers["content-type"]];
                } else {
                    $metadata = [];
                }
                $dataPromisor = $this->initField($field, $metadata);
                $buf = substr($buf, $end + 4);
                $off = 0;
                while (($end = strpos($buf, $sep, $off)) === false) {
                    if (!(yield $this->body->valid())) {
                        $e = new ClientException();
                        $dataPromisor->fail($e);
                        return $this->fail($e);
                    }
                    $buf .= $this->body->consume();
                    if (\strlen($buf) > \strlen($sep)) {
                        $off = \strlen($buf) - \strlen($sep);
                        $data = substr($buf, 0, $off);
                        if ($this->updateFieldSize($field, $data)) {
                            $dataPromisor->fail(new ClientSizeException());
                            return;
                        }
                        $dataPromisor->update($data);
                        $buf = substr($buf, $off);
                    }
                }
                $data = substr($buf, 0, $end);
                if ($this->updateFieldSize($field, $data)) {
                    $dataPromisor->fail(new ClientSizeException());
                    return;
                }
                $dataPromisor->update($data);
                $dataPromisor->succeed();
                $off = $end + \strlen($sep);
                while (\strlen($buf) < 4) {
                    if (!(yield $this->body->valid())) {
                        return $this->fail(new ClientException());
                    }
                    $buf .= $this->body->consume();
                }
            }
        } else {
            $field = null;
            while ((yield $this->body->valid())) {
                $new = $this->body->consume();
                if ($new[0] === "&") {
                    if ($field !== null) {
                        if ($noData || $buf != "") {
                            $data = urldecode($buf);
                            if ($this->updateFieldSize($field, $data)) {
                                $dataPromisor->fail(new ClientSizeException());
                                return;
                            }
                            $dataPromisor->update($data);
                            $buf = "";
                        }
                        $field = null;
                        $dataPromisor->succeed();
                    } elseif ($buf != "") {
                        if (!($dataPromisor = $this->initField(urldecode($buf)))) {
                            return;
                        }
                        $dataPromisor->update("");
                        $dataPromisor->succeed();
                        $buf = "";
                    }
                }
                $buf .= strtok($new, "&");
                if ($field !== null && ($new = strtok("&")) !== false) {
                    $data = urldecode($buf);
                    if ($this->updateFieldSize($field, $data)) {
                        $dataPromisor->fail(new ClientSizeException());
                        return;
                    }
                    $dataPromisor->update($data);
                    $dataPromisor->succeed();
                    $buf = $new;
                    $field = null;
                }
                while (($next = strtok("&")) !== false) {
                    $pair = explode("=", $buf, 2);
                    $key = urldecode($pair[0]);
                    if (!($dataPromisor = $this->initField($key))) {
                        return;
                    }
                    $data = urldecode($pair[1] ?? "");
                    if ($this->updateFieldSize($key, $data)) {
                        $dataPromisor->fail(new ClientSizeException());
                        return;
                    }
                    $dataPromisor->update($data);
                    $dataPromisor->succeed();
                    $buf = $next;
                }
                if ($field === null) {
                    if (($new = strstr($buf, "=", true)) !== false) {
                        $field = urldecode($new);
                        if (!($dataPromisor = $this->initField($field))) {
                            return;
                        }
                        $buf = substr($buf, \strlen($new) + 1);
                        $noData = true;
                    } elseif (\strlen($buf) > $this->maxFieldLen) {
                        return $this->fail();
                    }
                }
                if ($field !== null && $buf != "" && (\strlen($buf > 2) || $buf[0] !== "%")) {
                    if (\strlen($buf) > 1 ? false !== ($percent = strrpos($buf, "%", -2)) : !($percent = $buf[0] !== "%")) {
                        if ($percent) {
                            if ($this->updateFieldSize($field, $data)) {
                                return;
                            }
                            $dataPromisor->update(urldecode(substr($buf, 0, $percent)));
                            $buf = substr($buf, $percent);
                        }
                    } else {
                        $data = urldecode($buf);
                        if ($this->updateFieldSize($field, $data)) {
                            $dataPromisor->fail(new ClientSizeException());
                            return;
                        }
                        $dataPromisor->update($data);
                        $buf = "";
                    }
                    $noData = false;
                }
            }
            if ($field !== null) {
                if ($noData || $buf) {
                    $data = urldecode($buf);
                    if ($this->updateFieldSize($field, $data)) {
                        return;
                    }
                    $dataPromisor->update($data);
                }
                $dataPromisor->succeed();
                $field = null;
            } elseif ($buf) {
                $field = urldecode($buf);
                if (!($dataPromisor = $this->initField($field))) {
                    return;
                }
                $dataPromisor->update("");
                $dataPromisor->succeed();
            }
        }
        foreach ($this->bodyPromisors as $fieldArray) {
            foreach ($fieldArray as list($promisor, $metadata)) {
                $promisor->succeed();
                $metadata->succeed([]);
            }
        }
    }