/** * @uses \Crunch\FastCGI\Protocol\Record * @uses \Crunch\FastCGI\Protocol\RecordType * @uses \Crunch\FastCGI\Protocol\Header * @covers ::encode */ public function testEncodeEmptyParameters() { $parameters = new RequestParameters([]); $records = $parameters->encode(123); self::assertCount(1, $records); self::assertEquals(123, $records[0]->getRequestId()); self::assertSame(RecordType::params(), $records[0]->getType()); self::assertEquals('', $records[0]->getContent()); }
/** * Encodes request into an traversable of records. * * @return Traversable|Record[] */ public function toRecords() { $result = []; while ($chunk = $this->error->read(65535)) { $result[] = new Record(new Header(RecordType::stderr(), $this->requestId, strlen($chunk)), $chunk); } while ($chunk = $this->content->read(65535)) { $result[] = new Record(new Header(RecordType::stdout(), $this->requestId, strlen($chunk)), $chunk); } $result[] = new Record(new Header(RecordType::stdout(), $this->requestId, 0, 8), ''); $result[] = new Record(new Header(RecordType::endRequest(), $this->requestId, 0, 8), ''); return new ArrayIterator($result); }
/** * @param int $requestId * * @return Record[]|Traversable */ public function encode($requestId) { $packet = ''; foreach ($this->parameters as $name => $value) { // TODO "pack(C)" when < 128 // 0x80000000 => 4byte, highest bit 1, rest 0 (0x1000...0000) $new = \pack('NN', \strlen($name) + 0x80000000, \strlen($value) + 0x80000000) . $name . $value; // Although the specs states, that it isn't important it looks like // at least php-fpm expects parameters not to be spread over several // records. That doesn't make much sense for really long values though ... if (strlen($new) + strlen($packet) > 65535) { $result[] = new Record(new Header(RecordType::params(), $requestId, strlen($packet)), $packet); $packet = ''; } $packet .= $new; } if ($packet) { $result[] = new Record(new Header(RecordType::params(), $requestId, strlen($packet)), $packet); } // Some servers miss to drop the padding on the empty PARAMS-record // I look at you php-fpm ;) $result[] = new Record(new Header(RecordType::params(), $requestId, 0, 0), ''); return new ArrayIterator($result); }
/** * @dataProvider payloadLengthMismatchExamples * @uses \Crunch\FastCGI\Protocol\Header * @uses \Crunch\FastCGI\Protocol\RecordType * @param integer $length * @param string $payload */ public function testPayloadLengthMismatch($length, $payload) { $this->setExpectedException('\\LengthException'); $header = new Header(RecordType::beginRequest(), 1, $length); new Record($header, $payload); }
/** * @param string $header * * @throws InvalidArgumentException thrown when $header is not a string * @throws LengthException thrown when $header is not exactly 8 bytes * @return Header */ public static function decode($header) { if (!is_string($header)) { throw new InvalidArgumentException(sprintf('Header must be a (binary) string, %s given', gettype($header))); } if (strlen($header) != 8) { throw new LengthException(sprintf('Header must be exactly 8 bytes, %d bytes given', strlen($header))); } $header = \unpack('Cversion/Ctype/nrequestId/nlength/CpaddingLength/Creserved', $header); return new self(RecordType::instance($header['type']), $header['requestId'], $header['length'], $header['paddingLength']); }
/** * @covers ::maxtype */ public function testDirectInstancationMethodOfMaxtype() { $expectedRecordType = RecordType::instance(RecordType::MAXTYPE); $recordType = RecordType::maxtype(); self::assertSame($expectedRecordType, $recordType); }
/** * Encodes request into an traversable of records. * * @return Traversable|Record[] */ public function toRecords() { $result = [new Record(new Header(RecordType::beginRequest(), $this->getRequestId(), 8), \pack('xCCxxxxx', $this->role->value(), 0xff & ($this->keepConnection ? 1 : 0)))]; foreach ($this->getParameters()->encode($this->getRequestId()) as $value) { $result[] = $value; } while ($chunk = $this->stdin->read(65535)) { $result[] = new Record(new Header(RecordType::stdin(), $this->getRequestId(), strlen($chunk)), $chunk); } $result[] = new Record(new Header(RecordType::stdin(), $this->getRequestId(), 0, 0), ''); return new ArrayIterator($result); }