~tcuthbert/wordpress/openstack-objectstorage

« back to all changes in this revision

Viewing changes to vendor/guzzlehttp/guzzle/tests/Adapter/StreamAdapterTest.php

  • Committer: Jacek Nykis
  • Date: 2015-02-11 15:35:31 UTC
  • Revision ID: jacek.nykis@canonical.com-20150211153531-hmy6zi0ov2qfkl0b
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
namespace GuzzleHttp\Tests\Adapter;
 
3
 
 
4
use GuzzleHttp\Adapter\StreamAdapter;
 
5
use GuzzleHttp\Client;
 
6
use GuzzleHttp\Event\ErrorEvent;
 
7
use GuzzleHttp\Message\MessageFactory;
 
8
use GuzzleHttp\Message\Response;
 
9
use GuzzleHttp\Stream\Stream;
 
10
use GuzzleHttp\Tests\Server;
 
11
 
 
12
/**
 
13
 * @covers GuzzleHttp\Adapter\StreamAdapter
 
14
 */
 
15
class StreamAdapterTest extends \PHPUnit_Framework_TestCase
 
16
{
 
17
    public function testReturnsResponseForSuccessfulRequest()
 
18
    {
 
19
        Server::flush();
 
20
        Server::enqueue(
 
21
            "HTTP/1.1 200 OK\r\nFoo: Bar\r\nContent-Length: 2\r\n\r\nhi"
 
22
        );
 
23
        $client = new Client([
 
24
            'base_url' => Server::$url,
 
25
            'adapter' => new StreamAdapter(new MessageFactory())
 
26
        ]);
 
27
        $response = $client->get('/', ['headers' => ['Foo' => 'Bar']]);
 
28
        $this->assertEquals(200, $response->getStatusCode());
 
29
        $this->assertEquals('OK', $response->getReasonPhrase());
 
30
        $this->assertEquals('Bar', $response->getHeader('Foo'));
 
31
        $this->assertEquals('2', $response->getHeader('Content-Length'));
 
32
        $this->assertEquals('hi', $response->getBody());
 
33
        $sent = Server::received(true)[0];
 
34
        $this->assertEquals('GET', $sent->getMethod());
 
35
        $this->assertEquals('/', $sent->getResource());
 
36
        $this->assertEquals('127.0.0.1:8125', $sent->getHeader('host'));
 
37
        $this->assertEquals('Bar', $sent->getHeader('foo'));
 
38
        $this->assertTrue($sent->hasHeader('user-agent'));
 
39
    }
 
40
 
 
41
    /**
 
42
     * @expectedException \GuzzleHttp\Exception\RequestException
 
43
     * @expectedExceptionMessage Error creating resource. [url] http://localhost:123 [proxy] tcp://localhost:1234
 
44
     */
 
45
    public function testThrowsExceptionsCaughtDuringTransfer()
 
46
    {
 
47
        Server::flush();
 
48
        $client = new Client([
 
49
            'adapter' => new StreamAdapter(new MessageFactory()),
 
50
        ]);
 
51
        $client->get('http://localhost:123', [
 
52
            'timeout' => 0.01,
 
53
            'proxy'   => 'tcp://localhost:1234'
 
54
        ]);
 
55
    }
 
56
 
 
57
    /**
 
58
     * @expectedException \GuzzleHttp\Exception\RequestException
 
59
     * @expectedExceptionMessage URL is invalid: ftp://localhost:123
 
60
     */
 
61
    public function testEnsuresTheHttpProtocol()
 
62
    {
 
63
        Server::flush();
 
64
        $client = new Client([
 
65
            'adapter' => new StreamAdapter(new MessageFactory()),
 
66
        ]);
 
67
        $client->get('ftp://localhost:123');
 
68
    }
 
69
 
 
70
    public function testCanHandleExceptionsUsingEvents()
 
71
    {
 
72
        Server::flush();
 
73
        $client = new Client([
 
74
            'adapter' => new StreamAdapter(new MessageFactory())
 
75
        ]);
 
76
        $request = $client->createRequest('GET', Server::$url);
 
77
        $mockResponse = new Response(200);
 
78
        $request->getEmitter()->on(
 
79
            'error',
 
80
            function (ErrorEvent $e) use ($mockResponse) {
 
81
                $e->intercept($mockResponse);
 
82
            }
 
83
        );
 
84
        $this->assertSame($mockResponse, $client->send($request));
 
85
    }
 
86
 
 
87
    public function testEmitsAfterSendEvent()
 
88
    {
 
89
        $ee = null;
 
90
        Server::flush();
 
91
        Server::enqueue(
 
92
            "HTTP/1.1 200 OK\r\nFoo: Bar\r\nContent-Length: 8\r\n\r\nhi there"
 
93
        );
 
94
        $client = new Client(['adapter' => new StreamAdapter(new MessageFactory())]);
 
95
        $request = $client->createRequest('GET', Server::$url);
 
96
        $request->getEmitter()->on('complete', function ($e) use (&$ee) {
 
97
            $ee = $e;
 
98
        });
 
99
        $client->send($request);
 
100
        $this->assertInstanceOf('GuzzleHttp\Event\CompleteEvent', $ee);
 
101
        $this->assertSame($request, $ee->getRequest());
 
102
        $this->assertEquals(200, $ee->getResponse()->getStatusCode());
 
103
    }
 
104
 
 
105
    public function testStreamAttributeKeepsStreamOpen()
 
106
    {
 
107
        Server::flush();
 
108
        Server::enqueue(
 
109
            "HTTP/1.1 200 OK\r\nFoo: Bar\r\nContent-Length: 8\r\n\r\nhi there"
 
110
        );
 
111
        $client = new Client([
 
112
            'base_url' => Server::$url,
 
113
            'adapter' => new StreamAdapter(new MessageFactory())
 
114
        ]);
 
115
        $response = $client->put('/foo', [
 
116
            'headers' => ['Foo' => 'Bar'],
 
117
            'body' => 'test',
 
118
            'stream' => true
 
119
        ]);
 
120
        $this->assertEquals(200, $response->getStatusCode());
 
121
        $this->assertEquals('OK', $response->getReasonPhrase());
 
122
        $this->assertEquals('8', $response->getHeader('Content-Length'));
 
123
        $body = $response->getBody();
 
124
        if (defined('HHVM_VERSION')) {
 
125
            $this->markTestIncomplete('HHVM has not implemented this?');
 
126
        }
 
127
        $this->assertEquals('http', $body->getMetadata()['wrapper_type']);
 
128
        $this->assertEquals(Server::$url . 'foo', $body->getMetadata()['uri']);
 
129
        $this->assertEquals('hi', $body->read(2));
 
130
        $body->close();
 
131
 
 
132
        $sent = Server::received(true)[0];
 
133
        $this->assertEquals('PUT', $sent->getMethod());
 
134
        $this->assertEquals('/foo', $sent->getResource());
 
135
        $this->assertEquals('127.0.0.1:8125', $sent->getHeader('host'));
 
136
        $this->assertEquals('Bar', $sent->getHeader('foo'));
 
137
        $this->assertTrue($sent->hasHeader('user-agent'));
 
138
    }
 
139
 
 
140
    public function testDrainsResponseIntoTempStream()
 
141
    {
 
142
        Server::flush();
 
143
        Server::enqueue("HTTP/1.1 200 OK\r\nFoo: Bar\r\nContent-Length: 8\r\n\r\nhi there");
 
144
        $client = new Client([
 
145
            'base_url' => Server::$url,
 
146
            'adapter' => new StreamAdapter(new MessageFactory())
 
147
        ]);
 
148
        $response = $client->get('/');
 
149
        $body = $response->getBody();
 
150
        $this->assertEquals('php://temp', $body->getMetadata()['uri']);
 
151
        $this->assertEquals('hi', $body->read(2));
 
152
        $body->close();
 
153
    }
 
154
 
 
155
    public function testDrainsResponseIntoSaveToBody()
 
156
    {
 
157
        $r = fopen('php://temp', 'r+');
 
158
        Server::flush();
 
159
        Server::enqueue("HTTP/1.1 200 OK\r\nFoo: Bar\r\nContent-Length: 8\r\n\r\nhi there");
 
160
        $client = new Client([
 
161
            'base_url' => Server::$url,
 
162
            'adapter' => new StreamAdapter(new MessageFactory())
 
163
        ]);
 
164
        $response = $client->get('/', ['save_to' => $r]);
 
165
        $body = $response->getBody();
 
166
        $this->assertEquals('php://temp', $body->getMetadata()['uri']);
 
167
        $this->assertEquals('hi', $body->read(2));
 
168
        $this->assertEquals(' there', stream_get_contents($r));
 
169
        $body->close();
 
170
    }
 
171
 
 
172
    public function testDrainsResponseIntoSaveToBodyAtPath()
 
173
    {
 
174
        $tmpfname = tempnam('/tmp', 'save_to_path');
 
175
        Server::flush();
 
176
        Server::enqueue("HTTP/1.1 200 OK\r\nFoo: Bar\r\nContent-Length: 8\r\n\r\nhi there");
 
177
        $client = new Client([
 
178
            'base_url' => Server::$url,
 
179
            'adapter' => new StreamAdapter(new MessageFactory())
 
180
        ]);
 
181
        $response = $client->get('/', ['save_to' => $tmpfname]);
 
182
        $body = $response->getBody();
 
183
        $this->assertEquals($tmpfname, $body->getMetadata()['uri']);
 
184
        $this->assertEquals('hi', $body->read(2));
 
185
        $body->close();
 
186
        unlink($tmpfname);
 
187
    }
 
188
 
 
189
    public function testAutomaticallyDecompressGzip()
 
190
    {
 
191
        Server::flush();
 
192
        $content = gzencode('test');
 
193
        $message = "HTTP/1.1 200 OK\r\n"
 
194
            . "Foo: Bar\r\n"
 
195
            . "Content-Encoding: gzip\r\n"
 
196
            . "Content-Length: " . strlen($content) . "\r\n\r\n"
 
197
            . $content;
 
198
        Server::enqueue($message);
 
199
        $client = new Client([
 
200
            'base_url' => Server::$url,
 
201
            'adapter' => new StreamAdapter(new MessageFactory())
 
202
        ]);
 
203
        $response = $client->get('/', ['stream' => true]);
 
204
        $body = $response->getBody();
 
205
        $this->assertEquals('guzzle://stream', $body->getMetadata()['uri']);
 
206
        $this->assertEquals('test', (string) $body);
 
207
    }
 
208
 
 
209
    public function testDoesNotForceDecode()
 
210
    {
 
211
        Server::flush();
 
212
        $content = gzencode('test');
 
213
        $message = "HTTP/1.1 200 OK\r\n"
 
214
            . "Foo: Bar\r\n"
 
215
            . "Content-Encoding: gzip\r\n"
 
216
            . "Content-Length: " . strlen($content) . "\r\n\r\n"
 
217
            . $content;
 
218
        Server::enqueue($message);
 
219
        $client = new Client([
 
220
            'base_url' => Server::$url,
 
221
            'adapter' => new StreamAdapter(new MessageFactory())
 
222
        ]);
 
223
        $response = $client->get('/', [
 
224
            'decode_content' => false,
 
225
            'stream'         => true
 
226
        ]);
 
227
        $body = $response->getBody();
 
228
        $this->assertSame($content, (string) $body);
 
229
    }
 
230
 
 
231
    protected function getStreamFromBody(Stream $body)
 
232
    {
 
233
        $r = new \ReflectionProperty($body, 'stream');
 
234
        $r->setAccessible(true);
 
235
 
 
236
        return $r->getValue($body);
 
237
    }
 
238
 
 
239
    protected function getSendResult(array $opts)
 
240
    {
 
241
        Server::enqueue("HTTP/1.1 200 OK\r\nFoo: Bar\r\nContent-Length: 8\r\n\r\nhi there");
 
242
        $client = new Client(['adapter' => new StreamAdapter(new MessageFactory())]);
 
243
 
 
244
        return $client->get(Server::$url, $opts);
 
245
    }
 
246
 
 
247
    public function testAddsProxy()
 
248
    {
 
249
        $body = $this->getSendResult(['stream' => true, 'proxy' => '127.0.0.1:8125'])->getBody();
 
250
        $opts = stream_context_get_options($this->getStreamFromBody($body));
 
251
        $this->assertEquals('127.0.0.1:8125', $opts['http']['proxy']);
 
252
    }
 
253
 
 
254
    public function testAddsTimeout()
 
255
    {
 
256
        $body = $this->getSendResult(['stream' => true, 'timeout' => 200])->getBody();
 
257
        $opts = stream_context_get_options($this->getStreamFromBody($body));
 
258
        $this->assertEquals(200, $opts['http']['timeout']);
 
259
    }
 
260
 
 
261
    /**
 
262
     * @expectedException \RuntimeException
 
263
     * @expectedExceptionMessage SSL certificate authority file not found: /does/not/exist
 
264
     */
 
265
    public function testVerifiesVerifyIsValidIfPath()
 
266
    {
 
267
        (new Client([
 
268
            'adapter' => new StreamAdapter(new MessageFactory()),
 
269
            'base_url' => Server::$url,
 
270
            'defaults' => ['verify' => '/does/not/exist']
 
271
        ]))->get('/');
 
272
    }
 
273
 
 
274
    public function testVerifyCanBeDisabled()
 
275
    {
 
276
        Server::enqueue("HTTP/1.1 200\r\nContent-Length: 0\r\n\r\n");
 
277
        (new Client([
 
278
            'adapter' => new StreamAdapter(new MessageFactory()),
 
279
            'base_url' => Server::$url,
 
280
            'defaults' => ['verify' => false]
 
281
        ]))->get('/');
 
282
    }
 
283
 
 
284
    public function testVerifyCanBeSetToPath()
 
285
    {
 
286
        $path = __DIR__ . '/../../src/cacert.pem';
 
287
        $this->assertFileExists($path);
 
288
        $body = $this->getSendResult(['stream' => true, 'verify' => $path])->getBody();
 
289
        $opts = stream_context_get_options($this->getStreamFromBody($body));
 
290
        $this->assertEquals(true, $opts['http']['verify_peer']);
 
291
        $this->assertEquals($path, $opts['http']['cafile']);
 
292
        $this->assertTrue(file_exists($opts['http']['cafile']));
 
293
    }
 
294
 
 
295
    /**
 
296
     * @expectedException \RuntimeException
 
297
     * @expectedExceptionMessage SSL certificate not found: /does/not/exist
 
298
     */
 
299
    public function testVerifiesCertIfValidPath()
 
300
    {
 
301
        (new Client([
 
302
            'adapter' => new StreamAdapter(new MessageFactory()),
 
303
            'base_url' => Server::$url,
 
304
            'defaults' => ['cert' => '/does/not/exist']
 
305
        ]))->get('/');
 
306
    }
 
307
 
 
308
    public function testCanSetPasswordWhenSettingCert()
 
309
    {
 
310
        $path = __DIR__ . '/../../src/cacert.pem';
 
311
        $body = $this->getSendResult(['stream' => true, 'cert' => [$path, 'foo']])->getBody();
 
312
        $opts = stream_context_get_options($this->getStreamFromBody($body));
 
313
        $this->assertEquals($path, $opts['http']['local_cert']);
 
314
        $this->assertEquals('foo', $opts['http']['passphrase']);
 
315
    }
 
316
 
 
317
    public function testDebugAttributeWritesStreamInfoToTempBufferByDefault()
 
318
    {
 
319
        if (defined('HHVM_VERSION')) {
 
320
            $this->markTestSkipped('HHVM has not implemented this?');
 
321
            return;
 
322
        }
 
323
 
 
324
        Server::flush();
 
325
        Server::enqueue("HTTP/1.1 200 OK\r\nFoo: Bar\r\nContent-Length: 8\r\n\r\nhi there");
 
326
        $client = new Client([
 
327
            'base_url' => Server::$url,
 
328
            'adapter' => new StreamAdapter(new MessageFactory())
 
329
        ]);
 
330
        $fp = fopen('php://temp', 'w');
 
331
        $client->get('/', ['debug' => $fp]);
 
332
        fseek($fp, 0);
 
333
        $contents = stream_get_contents($fp);
 
334
        $this->assertContains('<http://127.0.0.1:8125/> [CONNECT]', $contents);
 
335
        $this->assertContains('<http://127.0.0.1:8125/> [FILE_SIZE_IS]', $contents);
 
336
        $this->assertContains('<http://127.0.0.1:8125/> [PROGRESS]', $contents);
 
337
    }
 
338
 
 
339
    public function testDebugAttributeWritesStreamInfoToBuffer()
 
340
    {
 
341
        if (defined('HHVM_VERSION')) {
 
342
            $this->markTestSkipped('HHVM has not implemented this?');
 
343
            return;
 
344
        }
 
345
 
 
346
        $buffer = fopen('php://temp', 'r+');
 
347
        Server::flush();
 
348
        Server::enqueue("HTTP/1.1 200 OK\r\nContent-Length: 8\r\nContent-Type: text/plain\r\n\r\nhi there");
 
349
        $client = new Client([
 
350
            'base_url' => Server::$url,
 
351
            'adapter' => new StreamAdapter(new MessageFactory())
 
352
        ]);
 
353
        $client->get('/', ['debug' => $buffer]);
 
354
        fseek($buffer, 0);
 
355
        $contents = stream_get_contents($buffer);
 
356
        $this->assertContains('<http://127.0.0.1:8125/> [CONNECT]', $contents);
 
357
        $this->assertContains('<http://127.0.0.1:8125/> [FILE_SIZE_IS] message: "Content-Length: 8"', $contents);
 
358
        $this->assertContains('<http://127.0.0.1:8125/> [PROGRESS] bytes_max: "8"', $contents);
 
359
        $this->assertContains('<http://127.0.0.1:8125/> [MIME_TYPE_IS] message: "text/plain"', $contents);
 
360
    }
 
361
 
 
362
    public function testAddsProxyByProtocol()
 
363
    {
 
364
        $url = str_replace('http', 'tcp', Server::$url);
 
365
        $body = $this->getSendResult(['stream' => true, 'proxy' => ['http' => $url]])->getBody();
 
366
        $opts = stream_context_get_options($this->getStreamFromBody($body));
 
367
        $this->assertEquals($url, $opts['http']['proxy']);
 
368
    }
 
369
 
 
370
    public function testPerformsShallowMergeOfCustomContextOptions()
 
371
    {
 
372
        $body = $this->getSendResult([
 
373
            'stream' => true,
 
374
            'config' => [
 
375
                'stream_context' => [
 
376
                    'http' => [
 
377
                        'request_fulluri' => true,
 
378
                        'method' => 'HEAD'
 
379
                    ],
 
380
                    'socket' => [
 
381
                        'bindto' => '127.0.0.1:0'
 
382
                    ],
 
383
                    'ssl' => [
 
384
                        'verify_peer' => false
 
385
                    ]
 
386
                ]
 
387
            ]
 
388
        ])->getBody();
 
389
 
 
390
        $opts = stream_context_get_options($this->getStreamFromBody($body));
 
391
        $this->assertEquals('HEAD', $opts['http']['method']);
 
392
        $this->assertTrue($opts['http']['request_fulluri']);
 
393
        $this->assertFalse($opts['ssl']['verify_peer']);
 
394
        $this->assertEquals('127.0.0.1:0', $opts['socket']['bindto']);
 
395
    }
 
396
 
 
397
    /**
 
398
     * @expectedException \GuzzleHttp\Exception\RequestException
 
399
     * @expectedExceptionMessage stream_context must be an array
 
400
     */
 
401
    public function testEnsuresThatStreamContextIsAnArray()
 
402
    {
 
403
        $this->getSendResult([
 
404
            'stream' => true,
 
405
            'config' => ['stream_context' => 'foo']
 
406
        ]);
 
407
    }
 
408
 
 
409
    /**
 
410
     * @ticket https://github.com/guzzle/guzzle/issues/725
 
411
     */
 
412
    public function testHandlesMultipleHeadersOfSameName()
 
413
    {
 
414
        $a = new StreamAdapter(new MessageFactory());
 
415
        $ref = new \ReflectionMethod($a, 'headersFromLines');
 
416
        $ref->setAccessible(true);
 
417
        $this->assertEquals([
 
418
            'foo' => ['bar', 'bam'],
 
419
            'abc' => ['123']
 
420
        ], $ref->invoke($a, [
 
421
            'foo: bar',
 
422
            'foo: bam',
 
423
            'abc: 123'
 
424
        ]));
 
425
    }
 
426
 
 
427
    public function testDoesNotAddContentTypeByDefault()
 
428
    {
 
429
        Server::flush();
 
430
        Server::enqueue("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n");
 
431
        $client = new Client([
 
432
            'base_url' => Server::$url,
 
433
            'adapter' => new StreamAdapter(new MessageFactory())
 
434
        ]);
 
435
        $client->put('/', ['body' => 'foo']);
 
436
        $requests = Server::received(true);
 
437
        $this->assertEquals('', $requests[0]->getHeader('Content-Type'));
 
438
        $this->assertEquals(3, $requests[0]->getHeader('Content-Length'));
 
439
    }
 
440
}