Completed
Push — master ( 34eae3...467c27 )
by Marcel
03:10
created

MessageSerializer::fixTarget()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 14
rs 9.4285
cc 2
eloc 7
nc 2
nop 1
1
<?php
2
3
namespace UMA\Psr\Http\Message\Serializer;
4
5
use Psr\Http\Message\MessageInterface;
6
use Psr\Http\Message\RequestInterface;
7
use Psr\Http\Message\ResponseInterface;
8
9
final class MessageSerializer
10
{
11
    const SP = ' ';
12
    const CRLF = "\r\n";
13
14
    /**
15
     * Returns the string representation of an HTTP message.
16
     *
17
     * @param MessageInterface $message Message to convert to a string.
18
     *
19
     * @return string
20
     *
21
     * @throws \InvalidArgumentException When $message is neither an implementation
22
     *                                   of RequestInterface nor ResponseInterface.
23
     */
24
    public static function serialize(MessageInterface $message)
25
    {
26
        return self::startLine($message).self::headers($message).self::CRLF.$message->getBody();
27
    }
28
29
    private static function startLine(MessageInterface $message)
30
    {
31
        if ($message instanceof RequestInterface) {
32
            return self::requestLine($message);
33
        } elseif ($message instanceof ResponseInterface) {
34
            return self::statusLine($message);
35
        } else {
36
            throw new \InvalidArgumentException('Unknown message type');
37
        }
38
    }
39
40
    private static function headers(MessageInterface $message)
41
    {
42
        $headers = array_change_key_case($message->getHeaders(), CASE_LOWER);
43
44
        unset($headers['host']);
45
46
        ksort($headers);
47
48
        $msg = '';
49
        foreach ($headers as $name => $values) {
50
            $values = is_array($values) ?
51
                $values : [$values];
52
53
            $msg .= mb_strtolower($name).':'.self::SP.implode(',', $values).self::CRLF;
54
        }
55
56
        return $msg;
57
    }
58
59
    private static function requestLine(RequestInterface $request)
60
    {
61
        $method = $request->getMethod();
62
        $target = self::fixTarget(trim($request->getRequestTarget()));
63
        $protocol = 'HTTP/'.$request->getProtocolVersion();
64
        $host = $request->getUri()->getHost();
65
66
        return $method.self::SP.$target.self::SP.$protocol.self::CRLF."host: $host".self::CRLF;
67
    }
68
69
    private static function statusLine(ResponseInterface $response)
70
    {
71
        $protocol = 'HTTP/'.$response->getProtocolVersion();
72
        $statusCode = $response->getStatusCode();
73
        $reasonPhrase = $response->getReasonPhrase();
74
75
        return $protocol.self::SP.$statusCode.self::SP.$reasonPhrase.self::CRLF;
76
    }
77
78
    private static function fixTarget($target)
79
    {
80
        $parsedTarget = parse_url($target);
81
82
        if (!array_key_exists('query', $parsedTarget)) {
83
            return $target;
84
        }
85
86
        parse_str($parsedTarget['query'], $query);
87
88
        ksort($query);
89
90
        return $parsedTarget['path'].'?'.http_build_query($query);
91
    }
92
}
93