@@ -67,32 +67,31 @@ public function withOptions(array $options)
67
67
68
68
public function send (RequestInterface $ request )
69
69
{
70
- $ deferred = new Deferred (function () use (&$ deferred ) {
71
- if (isset ($ deferred ->pending )) {
72
- $ deferred ->pending ->cancel ();
73
- unset($ deferred ->pending );
70
+ $ state = new ClientRequestState ();
71
+ $ deferred = new Deferred (function () use ($ state ) {
72
+ if ($ state ->pending !== null ) {
73
+ $ state ->pending ->cancel ();
74
+ $ state ->pending = null ;
74
75
}
75
76
});
76
77
77
- $ deferred ->numRequests = 0 ;
78
-
79
78
// use timeout from options or default to PHP's default_socket_timeout (60)
80
79
$ timeout = (float )($ this ->timeout !== null ? $ this ->timeout : ini_get ("default_socket_timeout " ));
81
80
82
81
$ loop = $ this ->loop ;
83
- $ this ->next ($ request , $ deferred )->then (
84
- function (ResponseInterface $ response ) use ($ deferred , $ loop , &$ timeout ) {
85
- if (isset ( $ deferred ->timeout ) ) {
86
- $ loop ->cancelTimer ($ deferred ->timeout );
87
- unset( $ deferred ->timeout ) ;
82
+ $ this ->next ($ request , $ deferred, $ state )->then (
83
+ function (ResponseInterface $ response ) use ($ state , $ deferred , $ loop , &$ timeout ) {
84
+ if ($ state ->timeout !== null ) {
85
+ $ loop ->cancelTimer ($ state ->timeout );
86
+ $ state ->timeout = null ;
88
87
}
89
88
$ timeout = -1 ;
90
89
$ deferred ->resolve ($ response );
91
90
},
92
- function ($ e ) use ($ deferred , $ loop , &$ timeout ) {
93
- if (isset ( $ deferred ->timeout ) ) {
94
- $ loop ->cancelTimer ($ deferred ->timeout );
95
- unset( $ deferred ->timeout ) ;
91
+ function ($ e ) use ($ state , $ deferred , $ loop , &$ timeout ) {
92
+ if ($ state ->timeout !== null ) {
93
+ $ loop ->cancelTimer ($ state ->timeout );
94
+ $ state ->timeout = null ;
96
95
}
97
96
$ timeout = -1 ;
98
97
$ deferred ->reject ($ e );
@@ -106,67 +105,65 @@ function ($e) use ($deferred, $loop, &$timeout) {
106
105
$ body = $ request ->getBody ();
107
106
if ($ body instanceof ReadableStreamInterface && $ body ->isReadable ()) {
108
107
$ that = $ this ;
109
- $ body ->on ('close ' , function () use ($ that , $ deferred , &$ timeout ) {
108
+ $ body ->on ('close ' , function () use ($ that , $ deferred , $ state , &$ timeout ) {
110
109
if ($ timeout >= 0 ) {
111
- $ that ->applyTimeout ($ deferred , $ timeout );
110
+ $ that ->applyTimeout ($ deferred , $ state , $ timeout );
112
111
}
113
112
});
114
113
} else {
115
- $ this ->applyTimeout ($ deferred , $ timeout );
114
+ $ this ->applyTimeout ($ deferred , $ state , $ timeout );
116
115
}
117
116
118
117
return $ deferred ->promise ();
119
118
}
120
119
121
120
/**
122
121
* @internal
123
- * @param Deferred $deferred
124
- * @param number $timeout
122
+ * @param number $timeout
125
123
* @return void
126
124
*/
127
- public function applyTimeout (Deferred $ deferred , $ timeout )
125
+ public function applyTimeout (Deferred $ deferred , ClientRequestState $ state , $ timeout )
128
126
{
129
- $ deferred ->timeout = $ this ->loop ->addTimer ($ timeout , function () use ($ timeout , $ deferred ) {
127
+ $ state ->timeout = $ this ->loop ->addTimer ($ timeout , function () use ($ timeout , $ deferred, $ state ) {
130
128
$ deferred ->reject (new \RuntimeException (
131
129
'Request timed out after ' . $ timeout . ' seconds '
132
130
));
133
- if (isset ( $ deferred ->pending ) ) {
134
- $ deferred ->pending ->cancel ();
135
- unset( $ deferred ->pending ) ;
131
+ if ($ state ->pending !== null ) {
132
+ $ state ->pending ->cancel ();
133
+ $ state ->pending = null ;
136
134
}
137
135
});
138
136
}
139
137
140
- private function next (RequestInterface $ request , Deferred $ deferred )
138
+ private function next (RequestInterface $ request , Deferred $ deferred, ClientRequestState $ state )
141
139
{
142
140
$ this ->progress ('request ' , array ($ request ));
143
141
144
142
$ that = $ this ;
145
- ++$ deferred ->numRequests ;
143
+ ++$ state ->numRequests ;
146
144
147
145
$ promise = $ this ->sender ->send ($ request );
148
146
149
147
if (!$ this ->streaming ) {
150
- $ promise = $ promise ->then (function ($ response ) use ($ deferred , $ that ) {
151
- return $ that ->bufferResponse ($ response , $ deferred );
148
+ $ promise = $ promise ->then (function ($ response ) use ($ deferred , $ state , $ that ) {
149
+ return $ that ->bufferResponse ($ response , $ deferred, $ state );
152
150
});
153
151
}
154
152
155
- $ deferred ->pending = $ promise ;
153
+ $ state ->pending = $ promise ;
156
154
157
155
return $ promise ->then (
158
- function (ResponseInterface $ response ) use ($ request , $ that , $ deferred ) {
159
- return $ that ->onResponse ($ response , $ request , $ deferred );
156
+ function (ResponseInterface $ response ) use ($ request , $ that , $ deferred, $ state ) {
157
+ return $ that ->onResponse ($ response , $ request , $ deferred, $ state );
160
158
}
161
159
);
162
160
}
163
161
164
162
/**
165
163
* @internal
166
- * @param ResponseInterface $response
167
164
* @return PromiseInterface Promise<ResponseInterface, Exception>
168
165
*/
169
- public function bufferResponse (ResponseInterface $ response , $ deferred )
166
+ public function bufferResponse (ResponseInterface $ response , Deferred $ deferred, ClientRequestState $ state )
170
167
{
171
168
$ stream = $ response ->getBody ();
172
169
@@ -205,26 +202,24 @@ function ($e) use ($stream, $maximumSize) {
205
202
}
206
203
);
207
204
208
- $ deferred ->pending = $ promise ;
205
+ $ state ->pending = $ promise ;
209
206
210
207
return $ promise ;
211
208
}
212
209
213
210
/**
214
211
* @internal
215
- * @param ResponseInterface $response
216
- * @param RequestInterface $request
217
212
* @throws ResponseException
218
213
* @return ResponseInterface|PromiseInterface
219
214
*/
220
- public function onResponse (ResponseInterface $ response , RequestInterface $ request , $ deferred )
215
+ public function onResponse (ResponseInterface $ response , RequestInterface $ request , Deferred $ deferred, ClientRequestState $ state )
221
216
{
222
217
$ this ->progress ('response ' , array ($ response , $ request ));
223
218
224
219
// follow 3xx (Redirection) response status codes if Location header is present and not explicitly disabled
225
220
// @link https://tools.ietf.org/html/rfc7231#section-6.4
226
221
if ($ this ->followRedirects && ($ response ->getStatusCode () >= 300 && $ response ->getStatusCode () < 400 ) && $ response ->hasHeader ('Location ' )) {
227
- return $ this ->onResponseRedirect ($ response , $ request , $ deferred );
222
+ return $ this ->onResponseRedirect ($ response , $ request , $ deferred, $ state );
228
223
}
229
224
230
225
// only status codes 200-399 are considered to be valid, reject otherwise
@@ -242,19 +237,19 @@ public function onResponse(ResponseInterface $response, RequestInterface $reques
242
237
* @return PromiseInterface
243
238
* @throws \RuntimeException
244
239
*/
245
- private function onResponseRedirect (ResponseInterface $ response , RequestInterface $ request , Deferred $ deferred )
240
+ private function onResponseRedirect (ResponseInterface $ response , RequestInterface $ request , Deferred $ deferred, ClientRequestState $ state )
246
241
{
247
242
// resolve location relative to last request URI
248
243
$ location = Uri::resolve ($ request ->getUri (), $ response ->getHeaderLine ('Location ' ));
249
244
250
245
$ request = $ this ->makeRedirectRequest ($ request , $ location );
251
246
$ this ->progress ('redirect ' , array ($ request ));
252
247
253
- if ($ deferred ->numRequests >= $ this ->maxRedirects ) {
248
+ if ($ state ->numRequests >= $ this ->maxRedirects ) {
254
249
throw new \RuntimeException ('Maximum number of redirects ( ' . $ this ->maxRedirects . ') exceeded ' );
255
250
}
256
251
257
- return $ this ->next ($ request , $ deferred );
252
+ return $ this ->next ($ request , $ deferred, $ state );
258
253
}
259
254
260
255
/**
0 commit comments