src/HTTP/Request2/MultipartBody.php
public function read($length)
    {
        $ret         = '';
        $boundary    = $this->getBoundary();
        $paramCount  = count($this->_params);
        $uploadCount = count($this->_uploads);
        while ($length > 0 && $this->_pos[0] <= $paramCount + $uploadCount) {
            $oldLength = $length;
            if ($this->_pos[0] < $paramCount) {
                $param = sprintf(
                    $this->_headerParam, $boundary, $this->_params[$this->_pos[0]][0]
                ) . $this->_params[$this->_pos[0]][1] . "\r\n";
                $ret    .= substr($param, $this->_pos[1], $length);
                $length -= min(strlen($param) - $this->_pos[1], $length);

            } elseif ($this->_pos[0] < $paramCount + $uploadCount) {
                $pos    = $this->_pos[0] - $paramCount;
                $header = sprintf(
                    $this->_headerUpload, $boundary, $this->_uploads[$pos]['name'],
                    $this->_uploads[$pos]['filename'], $this->_uploads[$pos]['type']
                );
                if ($this->_pos[1] < strlen($header)) {
                    $ret    .= substr($header, $this->_pos[1], $length);
                    $length -= min(strlen($header) - $this->_pos[1], $length);
                }
                $filePos  = max(0, $this->_pos[1] - strlen($header));
                if ($filePos < $this->_uploads[$pos]['size']) {
                    while ($length > 0 && !feof($this->_uploads[$pos]['fp'])) {
                        if (false === ($chunk = fread($this->_uploads[$pos]['fp'], $length))) {
                            throw new HTTP_Request2_LogicException(
                                'Failed reading file upload', HTTP_Request2_Exception::READ_ERROR
                            );
                        }
                        $ret    .= $chunk;
                        $length -= strlen($chunk);
                    }
                }
                if ($length > 0) {
                    $start   = $this->_pos[1] + ($oldLength - $length) -
                               strlen($header) - $this->_uploads[$pos]['size'];
                    $ret    .= substr("\r\n", $start, $length);
                    $length -= min(2 - $start, $length);
                }

            } else {
                $closing  = '--' . $boundary . "--\r\n";
                $ret     .= substr($closing, $this->_pos[1], $length);
                $length  -= min(strlen($closing) - $this->_pos[1], $length);
            }
            if ($length > 0) {
                $this->_pos     = array($this->_pos[0] + 1, 0);
            } else {
                $this->_pos[1] += $oldLength;
            }
        }
        return $ret;
    }
public function read($length)
    {
        $ret         = '';
        $boundary    = $this->getBoundary();
        $paramCount  = count($this->_params);
        $uploadCount = count($this->_uploads);
        while ($length > 0 && $this->_pos[0] <= $paramCount + $uploadCount) {
            $oldLength = $length;
            if ($this->_pos[0] < $paramCount) {
                $param = sprintf(
                    $this->_headerParam, $boundary, $this->_params[$this->_pos[0]][0]
                ) . $this->_params[$this->_pos[0]][1] . "\r\n";
                $ret    .= substr($param, $this->_pos[1], $length);
                $length -= min(strlen($param) - $this->_pos[1], $length);

            } elseif ($this->_pos[0] < $paramCount + $uploadCount) {
                $pos    = $this->_pos[0] - $paramCount;
                $header = sprintf(
                    $this->_headerUpload, $boundary, $this->_uploads[$pos]['name'],
                    $this->_uploads[$pos]['filename'], $this->_uploads[$pos]['type']
                );
                if ($this->_pos[1] < strlen($header)) {
                    $ret    .= substr($header, $this->_pos[1], $length);
                    $length -= min(strlen($header) - $this->_pos[1], $length);
                }
                $filePos  = max(0, $this->_pos[1] - strlen($header));
                if ($filePos < $this->_uploads[$pos]['size']) {
                    while ($length > 0 && !feof($this->_uploads[$pos]['fp'])) {
                        if (false === ($chunk = fread($this->_uploads[$pos]['fp'], $length))) {
                            throw new HTTP_Request2_LogicException(
                                'Failed reading file upload', HTTP_Request2_Exception::READ_ERROR
                            );
                        }
                        $ret    .= $chunk;
                        $length -= strlen($chunk);
                    }
                }
                if ($length > 0) {
                    $start   = $this->_pos[1] + ($oldLength - $length) -
                               strlen($header) - $this->_uploads[$pos]['size'];
                    $ret    .= substr("\r\n", $start, $length);
                    $length -= min(2 - $start, $length);
                }

            } else {
                $closing  = '--' . $boundary . "--\r\n";
                $ret     .= substr($closing, $this->_pos[1], $length);
                $length  -= min(strlen($closing) - $this->_pos[1], $length);
            }
            if ($length > 0) {
                $this->_pos     = array($this->_pos[0] + 1, 0);
            } else {
                $this->_pos[1] += $oldLength;
            }
        }
        return $ret;
    }
Returns next chunk of request body

@param integer $length Number of bytes to read

@return   string  Up to $length bytes of data, empty string if at end
@throws   HTTP_Request2_LogicException