Passed
Branch master (fc5382)
by Fabian
03:13
created

Connector::request()   B

Complexity

Conditions 6
Paths 2

Size

Total Lines 51
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 35
dl 0
loc 51
ccs 0
cts 32
cp 0
rs 8.7377
c 2
b 0
f 0
cc 6
nc 2
nop 3
crap 42

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace LE_ACME2\Connector;
4
5
use LE_ACME2\Request;
6
use LE_ACME2\Response;
7
8
use LE_ACME2\SingletonTrait;
9
use LE_ACME2\Cache;
10
use LE_ACME2\Utilities;
11
use LE_ACME2\Exception;
12
13
class Connector {
14
15
    use SingletonTrait;
16
    
17
    const METHOD_GET = 'GET';
18
    const METHOD_HEAD = 'HEAD';
19
    const METHOD_POST = 'POST';
20
21
    private function __construct() {}
22
23
    protected $_baseURL = 		 'https://acme-v02.api.letsencrypt.org';
24
    protected $_stagingBaseURL = 'https://acme-staging-v02.api.letsencrypt.org';
25
26
    protected $_useStagingServer = true;
27
28
    public function useStagingServer(bool $useStagingServer) {
29
        $this->_useStagingServer = $useStagingServer;
30
    }
31
32
    public function isUsingStagingServer() : bool {
33
        return $this->_useStagingServer;
34
    }
35
36
    public function getBaseURL() : string {
37
        return $this->_useStagingServer ? $this->_stagingBaseURL : $this->_baseURL;
38
    }
39
40
    /**
41
     * Makes a Curl request.
42
     *
43
     * @param string	$method	The HTTP method to use. Accepting GET, POST and HEAD requests.
44
     * @param string 	$url 	The URL to make the request to.
45
     * @param string 	$data  	The body to attach to a POST request. Expected as a JSON encoded string.
46
     *
47
     * @return RawResponse
48
     * @throws Exception\InvalidResponse
49
     * @throws Exception\RateLimitReached
50
     */
51
    public function request(string $method, string $url, string $data = null) : RawResponse {
52
53
        Utilities\Event::getInstance()->trigger(Utilities\Event::EVENT_CONNECTOR_WILL_REQUEST, [
0 ignored issues
show
Bug introduced by
It seems like trigger() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

53
        Utilities\Event::getInstance()->/** @scrutinizer ignore-call */ trigger(Utilities\Event::EVENT_CONNECTOR_WILL_REQUEST, [
Loading history...
54
            'method' => $method,
55
            'url' => $url,
56
            'data' => $data,
57
        ]);
58
        Utilities\Logger::getInstance()->add(Utilities\Logger::LEVEL_INFO, 'will request from ' . $url, ['data' => $data]);
0 ignored issues
show
Bug introduced by
It seems like add() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

58
        Utilities\Logger::getInstance()->/** @scrutinizer ignore-call */ add(Utilities\Logger::LEVEL_INFO, 'will request from ' . $url, ['data' => $data]);
Loading history...
59
60
        $handle = curl_init();
61
62
        $headers = array(
63
            'Accept: application/json',
64
            'Content-Type: ' . ($method == self::METHOD_POST ? 'application/jose+json' : 'application/json') //  ACME draft-10, section 6.2
65
        );
66
67
        curl_setopt($handle, CURLOPT_URL, $url);
68
        curl_setopt($handle, CURLOPT_HTTPHEADER, $headers);
69
        curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
70
        curl_setopt($handle, CURLOPT_HEADER, true);
71
72
        switch ($method) {
73
            case self::METHOD_GET:
74
                break;
75
            case self::METHOD_POST:
76
                curl_setopt($handle, CURLOPT_POST, true);
77
                curl_setopt($handle, CURLOPT_POSTFIELDS, $data);
78
                break;
79
            case self::METHOD_HEAD:
80
                curl_setopt($handle, CURLOPT_CUSTOMREQUEST, 'HEAD');
81
                curl_setopt($handle, CURLOPT_NOBODY, true);
82
                break;
83
            default:
84
                throw new \RuntimeException('HTTP request ' . $method . ' not supported.');
85
                break;
86
        }
87
        $response = curl_exec($handle);
88
89
        if(curl_errno($handle)) {
90
            throw new \RuntimeException('Curl: ' . curl_error($handle));
91
        }
92
93
        $header_size = curl_getinfo($handle, CURLINFO_HEADER_SIZE);
94
95
        $rawResponse = RawResponse::createFrom($method, $url, $response, $header_size);
0 ignored issues
show
Bug introduced by
It seems like $response can also be of type true; however, parameter $response of LE_ACME2\Connector\RawResponse::createFrom() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

95
        $rawResponse = RawResponse::createFrom($method, $url, /** @scrutinizer ignore-type */ $response, $header_size);
Loading history...
96
97
        Utilities\Logger::getInstance()->add(Utilities\Logger::LEVEL_INFO, self::class . ': response received', [get_class($rawResponse) => $rawResponse]);
98
99
        $this->_saveNewNonceFrom($rawResponse, $method);
100
101
        return $rawResponse;
102
    }
103
104
    /**
105
     * @param RawResponse $rawResponse
106
     * @param string $method
107
     * @throws Exception\InvalidResponse
108
     * @throws Exception\RateLimitReached
109
     */
110
    private function _saveNewNonceFrom(RawResponse $rawResponse, string $method) : void {
111
112
        try {
113
            $getNewNonceResponse = new Response\GetNewNonce($rawResponse);
114
            Cache\NewNonceResponse::getInstance()->set($getNewNonceResponse);
0 ignored issues
show
Bug introduced by
It seems like set() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

114
            Cache\NewNonceResponse::getInstance()->/** @scrutinizer ignore-call */ set($getNewNonceResponse);
Loading history...
115
116
        } catch(Exception\InvalidResponse $e) {
117
118
            if($method == self::METHOD_POST) {
119
                $request = new Request\GetNewNonce();
120
                $getNewNonceResponse = $request->getResponse();
121
                Cache\NewNonceResponse::getInstance()->set($getNewNonceResponse);
122
            }
123
        }
124
    }
125
}