Skip to content
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ repos:
pass_filenames: false
- id: phpunit
name: PHPUnit
entry: vendor/bin/phpunit
entry: env XDEBUG_MODE=coverage vendor/bin/phpunit
language: system
types: [php]
pass_filenames: false
224 changes: 224 additions & 0 deletions src/Adapter/Psr7/ServerRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
<?php

declare(strict_types=1);

namespace Deviantintegral\Har\Adapter\Psr7;

use Deviantintegral\Har\Cookie;
use Deviantintegral\Har\Params;
use Deviantintegral\Har\PostData;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface;

/**
* Adapts PSR-7 ServerRequests.
*
* Only features supported by HAR spec are implemented. Unsupported features
* will throw a \LogicException if they involve possible data loss.
*/
class ServerRequest extends Request implements ServerRequestInterface
{
public function getServerParams(): array
{
return [];
}

public function getCookieParams(): array
{
$request = $this->getHarRequest();
$cookieParams = [];
foreach ($request->getCookies() as $cookie) {
$cookieParams[$cookie->getName()] = $cookie->getValue();
}

return $cookieParams;
}

public function withCookieParams(array $cookies): ServerRequestInterface
{
$request = clone $this->getHarRequest();
$harCookies = [];
foreach ($cookies as $name => $value) {
$harCookies[] = (new Cookie())
->setName($name)
->setValue($value);
}
$request->setCookies($harCookies);

return new static($request);
}

public function getQueryParams(): array
{
$request = $this->getHarRequest();
$queryParams = [];
foreach ($request->getQueryString() as $param) {
$queryParams[$param->getName()] = $param->getValue();
}

return $queryParams;
}

public function withQueryParams(array $query): ServerRequestInterface
{
$request = clone $this->getHarRequest();
$harParams = [];
foreach ($query as $name => $value) {
$harParams[] = (new Params())
->setName($name)
->setValue((string) $value);
}
$request->setQueryString($harParams);

return new static($request);
}

public function getUploadedFiles(): array
{
return [];
}

public function withUploadedFiles(array $uploadedFiles): ServerRequestInterface
{
throw new \LogicException('Uploaded files are not supported.');
}

public function getParsedBody()
{
$request = $this->getHarRequest();

if (!$request->hasPostData()) {
return null;
}

$postData = $request->getPostData();
if ($postData->hasParams()) {
$parsedBody = [];
foreach ($postData->getParams() as $param) {
$parsedBody[$param->getName()] = $param->getValue();
}

return $parsedBody;
}

if ($postData->hasText()) {
// Try to parse as form data if content type suggests it
$contentType = $postData->getMimeType();
if ('application/x-www-form-urlencoded' === $contentType) {
$parsedBody = [];
parse_str($postData->getText(), $parsedBody);

return $parsedBody;
}
}

return null;
}

public function withParsedBody($data): ServerRequestInterface
{
if (!\is_array($data) && !\is_object($data) && null !== $data) {
throw new \InvalidArgumentException('Parsed body must be an array, object, or null.');
}

$request = clone $this->getHarRequest();

if (\is_array($data) || \is_object($data)) {
$postData = new PostData();
$harParams = [];
foreach ($data as $name => $value) {
$harParams[] = (new Params())
->setName($name)
->setValue((string) $value);
}
$postData->setParams($harParams);
$request->setPostData($postData);
} elseif (null === $data) {
// Clear post data
$request->setPostData(new PostData());
}

return new static($request);
}

public function getAttributes(): array
{
return [];
}

public function getAttribute($name, $default = null)
{
return $default;
}

public function withAttribute($name, $value): ServerRequestInterface
{
throw new \LogicException('Attributes are not supported.');
}

public function withoutAttribute($name): ServerRequestInterface
{
// Attributes are not part of HAR spec, return unchanged clone
return new static($this->getHarRequest());
}

/**
* Override parent methods to return ServerRequestInterface.
*/
public function withMethod($method): ServerRequestInterface
{
$parent = parent::withMethod($method);

return new static($parent->getHarRequest());
}

public function withUri(UriInterface $uri, $preserveHost = false): ServerRequestInterface
{
$parent = parent::withUri($uri, $preserveHost);

return new static($parent->getHarRequest());
}

public function withRequestTarget($requestTarget): ServerRequestInterface
{
$parent = parent::withRequestTarget($requestTarget);

return new static($parent->getHarRequest());
}

public function withBody(StreamInterface $body): ServerRequestInterface
{
$parent = parent::withBody($body);

return new static($parent->getHarRequest());
}

public function withHeader($name, $value): ServerRequestInterface
{
$parent = parent::withHeader($name, $value);

return new static($parent->getHarRequest());
}

public function withAddedHeader($name, $value): ServerRequestInterface
{
$parent = parent::withAddedHeader($name, $value);

return new static($parent->getHarRequest());
}

public function withoutHeader($name): ServerRequestInterface
{
$parent = parent::withoutHeader($name);

return new static($parent->getHarRequest());
}

public function withProtocolVersion($version): ServerRequestInterface
{
$parent = parent::withProtocolVersion($version);

return new static($parent->getHarRequest());
}
}
5 changes: 2 additions & 3 deletions src/PostData.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@
use Deviantintegral\Har\SharedFields\CommentTrait;
use Deviantintegral\Har\SharedFields\MimeTypeTrait;
use Deviantintegral\Har\SharedFields\TextTrait;
use GuzzleHttp\Psr7\Query;
use JMS\Serializer\Annotation as Serializer;

use function GuzzleHttp\Psr7\build_query;

/**
* @see http://www.softwareishard.com/blog/har-12-spec/#postData
*/
Expand Down Expand Up @@ -77,7 +76,7 @@ public function getBodySize(): int
foreach ($this->params as $param) {
$query[$param->getName()] = $param->getValue();
}
$string = build_query($query);
$string = Query::build($query);

return \strlen($string);
}
Expand Down
38 changes: 37 additions & 1 deletion src/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Deviantintegral\Har\SharedFields\HttpVersionTrait;
use JMS\Serializer\Annotation as Serializer;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ServerRequestInterface;

/**
* @see http://www.softwareishard.com/blog/har-12-spec/#request
Expand Down Expand Up @@ -75,6 +76,41 @@ public static function fromPsr7Request(RequestInterface $source): self
return $request->getHarRequest();
}

/**
* Construct a new Request from a PSR-7 ServerRequest.
*/
public static function fromPsr7ServerRequest(ServerRequestInterface $source): self
{
// Start with the basic request conversion (ServerRequest extends Request)
$harRequest = static::fromPsr7Request($source);

// Extract and set cookies from ServerRequest
$cookies = [];
foreach ($source->getCookieParams() as $name => $value) {
$cookie = (new Cookie())
->setName($name)
->setValue($value);
$cookies[] = $cookie;
}
if (!empty($cookies)) {
$harRequest->setCookies($cookies);
}

// Extract and set query parameters from ServerRequest
$queryParams = [];
foreach ($source->getQueryParams() as $name => $value) {
$param = (new Params())
->setName($name)
->setValue((string) $value);
$queryParams[] = $param;
}
if (!empty($queryParams)) {
$harRequest->setQueryString($queryParams);
}

return $harRequest;
}

public function getMethod(): string
{
return $this->method;
Expand Down Expand Up @@ -104,7 +140,7 @@ public function setUrl(\Psr\Http\Message\UriInterface $url): self
*/
public function getQueryString(): array
{
return $this->queryString;
return $this->queryString ?? [];
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/SharedFields/CookiesTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ trait CookiesTrait
*/
public function getCookies(): array
{
return $this->cookies;
return $this->cookies ?? [];
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/SharedFields/MimeTypeTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ trait MimeTypeTrait

public function getMimeType(): string
{
return $this->mimeType;
return $this->mimeType ?? '';
}

public function setMimeType(string $mimeType): self
Expand Down
Loading
Loading