1212use Http \Promise \Promise ;
1313use Psr \Http \Message \RequestInterface ;
1414use Psr \Http \Message \ResponseInterface ;
15+ use Symfony \Component \OptionsResolver \OptionsResolver ;
1516
1617/**
1718 * PSR-7 compatible cURL based HTTP client.
@@ -62,8 +63,6 @@ class Client implements HttpClient, HttpAsyncClient
6263 private $ multiRunner = null ;
6364
6465 /**
65- * Create new client.
66- *
6766 * @param MessageFactory|null $messageFactory HTTP Message factory
6867 * @param StreamFactory|null $streamFactory HTTP Stream factory
6968 * @param array $options cURL options {@link http://php.net/curl_setopt}
@@ -79,7 +78,20 @@ public function __construct(
7978 ) {
8079 $ this ->messageFactory = $ messageFactory ?: MessageFactoryDiscovery::find ();
8180 $ 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 );
8395 }
8496
8597 /**
@@ -111,15 +123,15 @@ public function __destruct()
111123 public function sendRequest (RequestInterface $ request ): ResponseInterface
112124 {
113125 $ responseBuilder = $ this ->createResponseBuilder ();
114- $ options = $ this ->createCurlOptions ($ request , $ responseBuilder );
126+ $ requestOptions = $ this ->prepareRequestOptions ($ request , $ responseBuilder );
115127
116128 if (is_resource ($ this ->handle )) {
117129 curl_reset ($ this ->handle );
118130 } else {
119131 $ this ->handle = curl_init ();
120132 }
121133
122- curl_setopt_array ($ this ->handle , $ options );
134+ curl_setopt_array ($ this ->handle , $ requestOptions );
123135 curl_exec ($ this ->handle );
124136
125137 $ errno = curl_errno ($ this ->handle );
@@ -165,8 +177,8 @@ public function sendAsyncRequest(RequestInterface $request)
165177
166178 $ handle = curl_init ();
167179 $ 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 );
170182
171183 $ core = new PromiseCore ($ request , $ handle , $ responseBuilder );
172184 $ promise = new CurlPromise ($ core , $ this ->multiRunner );
@@ -176,7 +188,7 @@ public function sendAsyncRequest(RequestInterface $request)
176188 }
177189
178190 /**
179- * Generates cURL options.
191+ * Update cURL options for this request and hook in the response builder .
180192 *
181193 * @param RequestInterface $request
182194 * @param ResponseBuilder $responseBuilder
@@ -187,14 +199,10 @@ public function sendAsyncRequest(RequestInterface $request)
187199 *
188200 * @return array
189201 */
190- private function createCurlOptions (RequestInterface $ request , ResponseBuilder $ responseBuilder )
202+ private function prepareRequestOptions (RequestInterface $ request , ResponseBuilder $ responseBuilder )
191203 {
192204 $ options = $ this ->options ;
193205
194- $ options [CURLOPT_HEADER ] = false ;
195- $ options [CURLOPT_RETURNTRANSFER ] = false ;
196- $ options [CURLOPT_FOLLOWLOCATION ] = false ;
197-
198206 try {
199207 $ options [CURLOPT_HTTP_VERSION ]
200208 = $ this ->getProtocolVersion ($ request ->getProtocolVersion ());
0 commit comments