12
12
use Http \Promise \Promise ;
13
13
use Psr \Http \Message \RequestInterface ;
14
14
use Psr \Http \Message \ResponseInterface ;
15
+ use Symfony \Component \OptionsResolver \OptionsResolver ;
15
16
16
17
/**
17
18
* PSR-7 compatible cURL based HTTP client.
@@ -62,8 +63,6 @@ class Client implements HttpClient, HttpAsyncClient
62
63
private $ multiRunner = null ;
63
64
64
65
/**
65
- * Create new client.
66
- *
67
66
* @param MessageFactory|null $messageFactory HTTP Message factory
68
67
* @param StreamFactory|null $streamFactory HTTP Stream factory
69
68
* @param array $options cURL options {@link http://php.net/curl_setopt}
@@ -79,7 +78,20 @@ public function __construct(
79
78
) {
80
79
$ this ->messageFactory = $ messageFactory ?: MessageFactoryDiscovery::find ();
81
80
$ this ->streamFactory = $ streamFactory ?: StreamFactoryDiscovery::find ();
82
- $ this ->options = $ options ;
81
+ $ resolver = new OptionsResolver ();
82
+ $ resolver ->setDefaults ([
83
+ CURLOPT_HEADER => false ,
84
+ CURLOPT_RETURNTRANSFER => false ,
85
+ CURLOPT_FOLLOWLOCATION => false ,
86
+ ]);
87
+ $ resolver ->setAllowedValues (CURLOPT_HEADER , [false ]); // our parsing will fail if this is set to true
88
+ $ resolver ->setAllowedValues (CURLOPT_RETURNTRANSFER , [false ]); // our parsing will fail if this is set to true
89
+
90
+ // We do not know what everything curl supports and might support in the future.
91
+ // Make sure that we accept everything that is in the options.
92
+ $ resolver ->setDefined (array_keys ($ options ));
93
+
94
+ $ this ->options = $ resolver ->resolve ($ options );
83
95
}
84
96
85
97
/**
@@ -111,15 +123,15 @@ public function __destruct()
111
123
public function sendRequest (RequestInterface $ request ): ResponseInterface
112
124
{
113
125
$ responseBuilder = $ this ->createResponseBuilder ();
114
- $ options = $ this ->createCurlOptions ($ request , $ responseBuilder );
126
+ $ requestOptions = $ this ->prepareRequestOptions ($ request , $ responseBuilder );
115
127
116
128
if (is_resource ($ this ->handle )) {
117
129
curl_reset ($ this ->handle );
118
130
} else {
119
131
$ this ->handle = curl_init ();
120
132
}
121
133
122
- curl_setopt_array ($ this ->handle , $ options );
134
+ curl_setopt_array ($ this ->handle , $ requestOptions );
123
135
curl_exec ($ this ->handle );
124
136
125
137
$ errno = curl_errno ($ this ->handle );
@@ -165,8 +177,8 @@ public function sendAsyncRequest(RequestInterface $request)
165
177
166
178
$ handle = curl_init ();
167
179
$ responseBuilder = $ this ->createResponseBuilder ();
168
- $ options = $ this ->createCurlOptions ($ request , $ responseBuilder );
169
- curl_setopt_array ($ handle , $ options );
180
+ $ requestOptions = $ this ->prepareRequestOptions ($ request , $ responseBuilder );
181
+ curl_setopt_array ($ handle , $ requestOptions );
170
182
171
183
$ core = new PromiseCore ($ request , $ handle , $ responseBuilder );
172
184
$ promise = new CurlPromise ($ core , $ this ->multiRunner );
@@ -176,7 +188,7 @@ public function sendAsyncRequest(RequestInterface $request)
176
188
}
177
189
178
190
/**
179
- * Generates cURL options.
191
+ * Update cURL options for this request and hook in the response builder .
180
192
*
181
193
* @param RequestInterface $request
182
194
* @param ResponseBuilder $responseBuilder
@@ -187,14 +199,10 @@ public function sendAsyncRequest(RequestInterface $request)
187
199
*
188
200
* @return array
189
201
*/
190
- private function createCurlOptions (RequestInterface $ request , ResponseBuilder $ responseBuilder )
202
+ private function prepareRequestOptions (RequestInterface $ request , ResponseBuilder $ responseBuilder )
191
203
{
192
204
$ options = $ this ->options ;
193
205
194
- $ options [CURLOPT_HEADER ] = false ;
195
- $ options [CURLOPT_RETURNTRANSFER ] = false ;
196
- $ options [CURLOPT_FOLLOWLOCATION ] = false ;
197
-
198
206
try {
199
207
$ options [CURLOPT_HTTP_VERSION ]
200
208
= $ this ->getProtocolVersion ($ request ->getProtocolVersion ());
0 commit comments