• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

sirn-se / websocket-php / 4771910143

pending completion
4771910143

push

github

Sören Jensen
Connect, handshake, HTTP, etc

212 of 212 new or added lines in 5 files covered. (100.0%)

591 of 670 relevant lines covered (88.21%)

14.85 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

19.57
/lib/Http/Request.php
1
<?php
2

3
/**
4
 * File for Phrity\WebSocket\Http\Request class
5
 * @package Phrity > WebSocket > Http
6
 */
7

8
namespace WebSocket\Http;
9

10
use Phrity\Net\Uri;
11
use Psr\Http\Message\RequestInterface;
12
use Psr\Http\Message\UriInterface;
13
use RuntimeException;
14

15
/**
16
 * Phrity\WebSocket\Http\Request class.
17
 */
18
class Request extends Message implements RequestInterface
19
{
20
    private $target;
21
    private $method;
22
    private $uri;
23

24
    public function __construct(string $method = '', $uri = null)
25
    {
26
        $this->uri = $uri instanceof Uri ? $uri : new Uri((string)$uri);
31✔
27
        $this->method = $method;
31✔
28
        if ($this->uri->getHost()) {
31✔
29
            $this->headers = ['host' => ['host' => [$this->uri->getHost()]]];
×
30
        }
31
    }
32

33
    /**
34
     * Retrieves the message's request target.
35
     * @return string
36
     */
37
    public function getRequestTarget(): string
38
    {
39
        if ($this->target) {
31✔
40
            return $this->target;
×
41
        }
42
        $uri = (new Uri())->withPath($this->uri->getPath())->withQuery($this->uri->getQuery());
31✔
43
        return $uri->toString(Uri::ABSOLUTE_PATH);
31✔
44
    }
45

46
    /**
47
     * Return an instance with the specific request-target.
48
     * @param mixed $requestTarget
49
     * @return static
50
     */
51
    public function withRequestTarget($requestTarget): self
52
    {
53
        $new = clone $this;
×
54
        $new->target = $requestTarget;
×
55
        return $new;
×
56
    }
57

58
    /**
59
     * Retrieves the HTTP method of the request.
60
     * @return string Returns the request method.
61
     */
62
    public function getMethod(): string
63
    {
64
        return $this->method;
×
65
    }
66

67
    /**
68
     * Return an instance with the provided HTTP method.
69
     * @param string $method Case-sensitive method.
70
     * @return static
71
     * @throws \InvalidArgumentException for invalid HTTP methods.
72
     */
73
    public function withMethod($method): self
74
    {
75
        $new = clone $this;
×
76
        $new->method = $method;
×
77
        return $new;
×
78
    }
79

80
    /**
81
     * Retrieves the URI instance.
82
     * This method MUST return a UriInterface instance.
83
     * @return UriInterface Returns a UriInterface instance representing the URI of the request.
84
     */
85
    public function getUri(): UriInterface
86
    {
87
        return $this->uri;
×
88
    }
89

90
    /**
91
     * Returns an instance with the provided URI.
92
     * @param UriInterface $uri New request URI to use.
93
     * @param bool $preserveHost Preserve the original state of the Host header.
94
     * @return static
95
     */
96
    public function withUri(UriInterface $uri, $preserveHost = false): self
97
    {
98
        $new = clone $this;
×
99
        $new->uri = $uri instanceof Uri ? $uri : new Uri((string)$uri);
×
100
        if (!$preserveHost || !$new->hasHeader('host')) {
×
101
            if (isset($new->headers['host'])) {
×
102
                unset($new->headers['host']);
×
103
            }
104
            if ($host = $uri->getHost()) {
×
105
                $new->headers = array_merge(['host' => ['host' => [$host]]], $new->headers);
×
106
            }
107
        }
108
        return $new;
×
109
    }
110

111
    public function parse(string $data): self
112
    {
113
        list ($head, $body) = explode("\r\n\r\n", $data);
×
114
        $headers = array_filter(explode("\r\n", $head));
×
115
        $status = array_shift($headers);
×
116

117
        preg_match('!^(?P<method>[A-Z]+) (?P<path>[^ ]*) HTTP/(?P<protocol>[0-9/.]+)!', $status, $matches);
×
118
        if (empty($matches)) {
×
119
            // @todo: handle error
120
            throw new RuntimeException('Invalid http request');
×
121
        }
122

123

124
        $path = $matches['path'];
×
125

126
        $request = $this
×
127
            ->withProtocolVersion($matches['protocol'])
×
128
            ->withMethod($matches['method']);
×
129

130
        foreach ($headers as $header) {
×
131
            $parts = explode(':', $header, 2);
×
132
            $request = $request->withHeader($parts[0], $parts[1]);
×
133
        }
134
        $host = new Uri("//{$request->getHeaderLine('host')}{$path}");
×
135
        $uri = $request->getUri()
×
136
            ->withHost($host->getHost())
×
137
            ->withPath($host->getPath())
×
138
            ->withQuery($host->getQuery());
×
139
        return $request->withUri($uri);
×
140
    }
141

142
    public function render(): string
143
    {
144
        $data = "GET {$this->getRequestTarget()} HTTP/{$this->getProtocolVersion()}\r\n";
31✔
145
        $data .= parent::render();
31✔
146
        return $data;
31✔
147
    }
148
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc