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

sirn-se / websocket-php / 5608975860

pending completion
5608975860

push

github

Sören Jensen
Middleware support

90 of 90 new or added lines in 8 files covered. (100.0%)

245 of 671 relevant lines covered (36.51%)

1.27 hits per line

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

9.38
/src/Http/HttpHandler.php
1
<?php
2

3
/**
4
 * Copyright (C) 2014-2023 Textalk and contributors.
5
 *
6
 * This file is part of Websocket PHP and is free software under the ISC License.
7
 * License text: https://raw.githubusercontent.com/sirn-se/websocket-php/master/COPYING.md
8
 */
9

10
namespace WebSocket\Http;
11

12
use Phrity\Net\{
13
    SocketStream,
14
    Uri
15
};
16
use Psr\Http\Message\{
17
    MessageInterface,
18
    RequestInterface,
19
    ResponseInterface,
20
    StreamInterface
21
};
22
use Psr\Log\{
23
    LoggerInterface,
24
    LoggerAwareInterface,
25
    NullLogger
26
};
27
use RuntimeException;
28

29
/**
30
 * WebSocket\Http\HttpHandler class.
31
 * Reads and writes HTTP message to/from stream.
32
 */
33
class HttpHandler implements LoggerAwareInterface
34
{
35
    private $stream;
36
    private $logger;
37

38
    public function __construct(SocketStream $stream)
39
    {
40
        $this->stream = $stream;
5✔
41
        $this->setLogger(new NullLogger());
5✔
42
    }
43

44
    public function setLogger(LoggerInterface $logger): void
45
    {
46
        $this->logger = $logger;
5✔
47
    }
48

49
    public function pull(): MessageInterface
50
    {
51
        $data = '';
×
52
        do {
53
            $buffer = $this->stream->readLine(1024);
×
54
            $data .= $buffer;
×
55
        } while (substr_count($data, "\r\n\r\n") == 0);
×
56

57
        list ($head, $body) = explode("\r\n\r\n", $data);
×
58
        $headers = array_filter(explode("\r\n", $head));
×
59
        $status = array_shift($headers);
×
60

61
        // Pulling server request
62
        preg_match('!^(?P<method>[A-Z]+) (?P<path>[^ ]*) HTTP/(?P<version>[0-9/.]+)!', $status, $matches);
×
63
        if (!empty($matches)) {
×
64
            $message = new ServerRequest($matches['method']);
×
65
            $path = $matches['path'];
×
66
            $version = $matches['version'];
×
67
        }
68

69
        // Pulling response
70
        preg_match('!^HTTP/(?P<version>[0-9/.]+) (?P<code>[0-9]*) (?P<reason>.*)!', $status, $matches);
×
71
        if (!empty($matches)) {
×
72
            $message = new Response($matches['code'], $matches['reason']);
×
73
            $version = $matches['version'];
×
74
        }
75

76
        if (empty($message)) {
×
77
            throw new RuntimeException('Invalid Http request.');
×
78
        }
79

80
        $message = $message->withProtocolVersion($version);
×
81
        foreach ($headers as $header) {
×
82
            $parts = explode(':', $header, 2);
×
83
            if (count($parts) == 2) {
×
84
                $message = $message->withHeader($parts[0], $parts[1]);
×
85
            }
86
        }
87
        if ($message instanceof Request) {
×
88
            $uri = new Uri("//{$message->getHeaderLine('host')}{$path}");
×
89
            $message = $message->withUri($uri);
×
90
        }
91

92
        return $message;
×
93
    }
94

95
    public function push(MessageInterface $message): int
96
    {
97
        $data = implode("\r\n", $message->getAsArray()) . "\r\n\r\n";
×
98
        return $this->stream->write($data);
×
99
    }
100
}
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