13
13
*/
14
14
namespace Cake \Network \Http \Adapter ;
15
15
16
+ use Cake \Error ;
16
17
use Cake \Network \Http \Request ;
17
18
use Cake \Network \Http \Response ;
18
19
use Cake \Network \Http \FormData ;
@@ -46,6 +47,13 @@ class Stream {
46
47
*/
47
48
protected $ _stream ;
48
49
50
+ /**
51
+ * Connection error list.
52
+ *
53
+ * @var array
54
+ */
55
+ protected $ _connectionErrors = [];
56
+
49
57
/**
50
58
* Send a request and get a response back.
51
59
*
@@ -54,10 +62,12 @@ class Stream {
54
62
* @return Cake\Network\Http\Response
55
63
*/
56
64
public function send (Request $ request , $ options ) {
57
- $ this ->_context = array ();
65
+ $ this ->_stream = null ;
66
+ $ this ->_context = [];
67
+ $ this ->_connectionErrors = [];
58
68
59
69
$ this ->_buildContext ($ request , $ options );
60
- return $ this ->_send ();
70
+ return $ this ->_send ($ request );
61
71
}
62
72
63
73
/**
@@ -132,7 +142,9 @@ protected function _buildContent(Request $request, $options) {
132
142
$ type = 'multipart/form-data; boundary=" ' . $ formData ->boundary () . '" ' ;
133
143
$ request ->header ('Content-Type ' , $ type );
134
144
$ this ->_contextOptions ['content ' ] = (string )$ formData ;
145
+ return ;
135
146
}
147
+ $ this ->_contextOptions ['content ' ] = $ content ;
136
148
}
137
149
138
150
/**
@@ -187,7 +199,59 @@ protected function _buildSslContext(Request $request, $options) {
187
199
}
188
200
}
189
201
190
- protected function _send () {
202
+ /**
203
+ * Open the stream and send the request.
204
+ *
205
+ * @return void
206
+ * @throws Cake\Error\Exception
207
+ */
208
+ protected function _send ($ request ) {
209
+ $ url = $ request ->url ();
210
+ $ this ->_open ($ url );
211
+ $ content = '' ;
212
+ while (!feof ($ this ->_stream )) {
213
+ $ content .= fread ($ this ->_stream , 8192 );
214
+ }
215
+ $ meta = stream_get_meta_data ($ this ->_stream );
216
+ fclose ($ this ->_stream );
217
+
218
+ if ($ meta ['timed_out ' ]) {
219
+ throw Error \Exception ('Connection timed out ' . $ url );
220
+ }
221
+ $ headers = $ meta ['wrapper_data ' ];
222
+ if (isset ($ meta ['wrapper_type ' ]) && $ meta ['wrapper_type ' ] === 'curl ' ) {
223
+ $ headers = $ meta ['wrapper_data ' ]['headers ' ];
224
+ }
225
+ return new Response ($ headers , $ content );
226
+ }
227
+
228
+ /**
229
+ * Open the socket and handle any connection errors.
230
+ *
231
+ * @param string $url The url to connect to.
232
+ * @return void
233
+ * @throws Cake\Error\Exception
234
+ */
235
+ protected function _open ($ url ) {
236
+ set_error_handler ([$ this , '_connectionErrorHandler ' ]);
237
+ $ this ->_stream = fopen ($ url , 'rb ' , false , $ this ->_context );
238
+ restore_error_handler ();
239
+
240
+ if (!$ this ->_stream || !empty ($ this ->_connectionErrors )) {
241
+ throw new Error \Exception (implode ("\n" , $ this ->_connectionErrors ));
242
+ }
243
+ }
244
+
245
+ /**
246
+ * Local error handler to capture errors triggered during
247
+ * stream connection.
248
+ *
249
+ * @param int $code
250
+ * @param string $message
251
+ * @return void
252
+ */
253
+ protected function _connectionErrorHandler ($ code , $ message ) {
254
+ $ this ->_connectionErrors [] = $ message ;
191
255
}
192
256
193
257
/**
0 commit comments