Skip to content

Commit fe5dd09

Browse files
committed
Merge branch 'master' into curl-client-13
2 parents 47cb8d9 + 10d2a02 commit fe5dd09

File tree

8 files changed

+369
-6
lines changed

8 files changed

+369
-6
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,3 @@ build/
33
vendor/
44
composer.lock
55
phpunit.xml
6-
puli.json

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@
77
- #13: Remove HeaderParser.
88

99

10+
## 1.2 - 2016-03-09
11+
12+
### Added
13+
14+
- #16: Make sure discovery can find the curl client
15+
16+
### Fixed
17+
18+
- #15: "Out of memory" sending large files.
19+
20+
1021
## 1.1.0 - 2016-01-29
1122

1223
### Changed

composer.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
}
1212
],
1313
"prefer-stable": true,
14-
"minimum-stability": "dev",
14+
"minimum-stability": "beta",
1515
"require": {
1616
"php": ">=5.5",
1717
"ext-curl": "*",
@@ -21,8 +21,10 @@
2121
"require-dev": {
2222
"guzzlehttp/psr7": "^1.0",
2323
"php-http/adapter-integration-tests": "dev-master#836cdff8294174cceeae54601ab4079c309227b7",
24-
"php-http/message": "dev-master",
24+
"php-http/message": "^1.0.2",
25+
"php-http/discovery": "~0.8.0",
2526
"phpunit/phpunit": "^4.8",
27+
"puli/composer-plugin": "1.0.0-beta9",
2628
"zendframework/zend-diactoros": "^1.0"
2729
},
2830
"autoload": {

puli.json

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
{
2+
"version": "1.0",
3+
"name": "php-http/curl-client",
4+
"bindings": {
5+
"98239b8b-103b-4f47-94c7-4cba49a05a1f": {
6+
"_class": "Puli\\Discovery\\Binding\\ClassBinding",
7+
"class": "Http\\Client\\Curl\\Client",
8+
"type": "Http\\Client\\HttpAsyncClient"
9+
},
10+
"a6a79968-2aa5-427c-bbe1-a581d9a48321": {
11+
"_class": "Puli\\Discovery\\Binding\\ClassBinding",
12+
"class": "Http\\Client\\Curl\\Client",
13+
"type": "Http\\Client\\HttpClient"
14+
}
15+
},
16+
"config": {
17+
"bootstrap-file": "vendor/autoload.php"
18+
},
19+
"packages": {
20+
"clue/stream-filter": {
21+
"install-path": "vendor/clue/stream-filter",
22+
"installer": "composer",
23+
"env": "dev"
24+
},
25+
"doctrine/instantiator": {
26+
"install-path": "vendor/doctrine/instantiator",
27+
"installer": "composer",
28+
"env": "dev"
29+
},
30+
"guzzlehttp/psr7": {
31+
"install-path": "vendor/guzzlehttp/psr7",
32+
"installer": "composer",
33+
"env": "dev"
34+
},
35+
"justinrainbow/json-schema": {
36+
"install-path": "vendor/justinrainbow/json-schema",
37+
"installer": "composer",
38+
"env": "dev"
39+
},
40+
"php-http/adapter-integration-tests": {
41+
"install-path": "vendor/php-http/adapter-integration-tests",
42+
"installer": "composer",
43+
"env": "dev"
44+
},
45+
"php-http/discovery": {
46+
"install-path": "vendor/php-http/discovery",
47+
"installer": "composer",
48+
"env": "dev"
49+
},
50+
"php-http/httplug": {
51+
"install-path": "vendor/php-http/httplug",
52+
"installer": "composer"
53+
},
54+
"php-http/message": {
55+
"install-path": "vendor/php-http/message",
56+
"installer": "composer",
57+
"env": "dev"
58+
},
59+
"php-http/message-factory": {
60+
"install-path": "vendor/php-http/message-factory",
61+
"installer": "composer"
62+
},
63+
"php-http/promise": {
64+
"install-path": "vendor/php-http/promise",
65+
"installer": "composer"
66+
},
67+
"phpdocumentor/reflection-docblock": {
68+
"install-path": "vendor/phpdocumentor/reflection-docblock",
69+
"installer": "composer",
70+
"env": "dev"
71+
},
72+
"phpspec/prophecy": {
73+
"install-path": "vendor/phpspec/prophecy",
74+
"installer": "composer",
75+
"env": "dev"
76+
},
77+
"phpunit/php-code-coverage": {
78+
"install-path": "vendor/phpunit/php-code-coverage",
79+
"installer": "composer",
80+
"env": "dev"
81+
},
82+
"phpunit/php-file-iterator": {
83+
"install-path": "vendor/phpunit/php-file-iterator",
84+
"installer": "composer",
85+
"env": "dev"
86+
},
87+
"phpunit/php-text-template": {
88+
"install-path": "vendor/phpunit/php-text-template",
89+
"installer": "composer",
90+
"env": "dev"
91+
},
92+
"phpunit/php-timer": {
93+
"install-path": "vendor/phpunit/php-timer",
94+
"installer": "composer",
95+
"env": "dev"
96+
},
97+
"phpunit/php-token-stream": {
98+
"install-path": "vendor/phpunit/php-token-stream",
99+
"installer": "composer",
100+
"env": "dev"
101+
},
102+
"phpunit/phpunit": {
103+
"install-path": "vendor/phpunit/phpunit",
104+
"installer": "composer",
105+
"env": "dev"
106+
},
107+
"phpunit/phpunit-mock-objects": {
108+
"install-path": "vendor/phpunit/phpunit-mock-objects",
109+
"installer": "composer",
110+
"env": "dev"
111+
},
112+
"psr/http-message": {
113+
"install-path": "vendor/psr/http-message",
114+
"installer": "composer"
115+
},
116+
"psr/log": {
117+
"install-path": "vendor/psr/log",
118+
"installer": "composer",
119+
"env": "dev"
120+
},
121+
"puli/composer-plugin": {
122+
"install-path": "vendor/puli/composer-plugin",
123+
"installer": "composer",
124+
"env": "dev"
125+
},
126+
"puli/discovery": {
127+
"install-path": "vendor/puli/discovery",
128+
"installer": "composer",
129+
"env": "dev"
130+
},
131+
"puli/repository": {
132+
"install-path": "vendor/puli/repository",
133+
"installer": "composer",
134+
"env": "dev"
135+
},
136+
"puli/url-generator": {
137+
"install-path": "vendor/puli/url-generator",
138+
"installer": "composer",
139+
"env": "dev"
140+
},
141+
"ramsey/uuid": {
142+
"install-path": "vendor/ramsey/uuid",
143+
"installer": "composer",
144+
"env": "dev"
145+
},
146+
"sebastian/comparator": {
147+
"install-path": "vendor/sebastian/comparator",
148+
"installer": "composer",
149+
"env": "dev"
150+
},
151+
"sebastian/diff": {
152+
"install-path": "vendor/sebastian/diff",
153+
"installer": "composer",
154+
"env": "dev"
155+
},
156+
"sebastian/environment": {
157+
"install-path": "vendor/sebastian/environment",
158+
"installer": "composer",
159+
"env": "dev"
160+
},
161+
"sebastian/exporter": {
162+
"install-path": "vendor/sebastian/exporter",
163+
"installer": "composer",
164+
"env": "dev"
165+
},
166+
"sebastian/global-state": {
167+
"install-path": "vendor/sebastian/global-state",
168+
"installer": "composer",
169+
"env": "dev"
170+
},
171+
"sebastian/recursion-context": {
172+
"install-path": "vendor/sebastian/recursion-context",
173+
"installer": "composer",
174+
"env": "dev"
175+
},
176+
"sebastian/version": {
177+
"install-path": "vendor/sebastian/version",
178+
"installer": "composer",
179+
"env": "dev"
180+
},
181+
"seld/jsonlint": {
182+
"install-path": "vendor/seld/jsonlint",
183+
"installer": "composer",
184+
"env": "dev"
185+
},
186+
"symfony/process": {
187+
"install-path": "vendor/symfony/process",
188+
"installer": "composer",
189+
"env": "dev"
190+
},
191+
"symfony/yaml": {
192+
"install-path": "vendor/symfony/yaml",
193+
"installer": "composer",
194+
"env": "dev"
195+
},
196+
"th3n3rd/cartesian-product": {
197+
"install-path": "vendor/th3n3rd/cartesian-product",
198+
"installer": "composer",
199+
"env": "dev"
200+
},
201+
"webmozart/assert": {
202+
"install-path": "vendor/webmozart/assert",
203+
"installer": "composer",
204+
"env": "dev"
205+
},
206+
"webmozart/expression": {
207+
"install-path": "vendor/webmozart/expression",
208+
"installer": "composer",
209+
"env": "dev"
210+
},
211+
"webmozart/glob": {
212+
"install-path": "vendor/webmozart/glob",
213+
"installer": "composer",
214+
"env": "dev"
215+
},
216+
"webmozart/json": {
217+
"install-path": "vendor/webmozart/json",
218+
"installer": "composer",
219+
"env": "dev"
220+
},
221+
"webmozart/path-util": {
222+
"install-path": "vendor/webmozart/path-util",
223+
"installer": "composer",
224+
"env": "dev"
225+
},
226+
"zendframework/zend-diactoros": {
227+
"install-path": "vendor/zendframework/zend-diactoros",
228+
"installer": "composer",
229+
"env": "dev"
230+
}
231+
}
232+
}

src/Client.php

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ public function sendRequest(RequestInterface $request)
123123
} catch (\Exception $e) {
124124
throw new RequestException($e->getMessage(), $request, $e);
125125
}
126+
126127
return $response;
127128
}
128129

@@ -161,6 +162,7 @@ public function sendAsyncRequest(RequestInterface $request)
161162
* @param RequestInterface $request
162163
*
163164
* @throws \UnexpectedValueException if unsupported HTTP version requested
165+
* @throws \RuntimeException if can not read body
164166
*
165167
* @return array
166168
*/
@@ -177,9 +179,23 @@ private function createCurlOptions(RequestInterface $request)
177179

178180
if (in_array($request->getMethod(), ['OPTIONS', 'POST', 'PUT'], true)) {
179181
// cURL allows request body only for these methods.
180-
$body = (string) $request->getBody();
181-
if ('' !== $body) {
182-
$options[CURLOPT_POSTFIELDS] = $body;
182+
$body = $request->getBody();
183+
$bodySize = $body->getSize();
184+
if ($bodySize !== 0) {
185+
// Message has non empty body.
186+
if (null === $bodySize || $bodySize > 1024 * 1024) {
187+
// Avoid full loading large or unknown size body into memory
188+
$options[CURLOPT_UPLOAD] = true;
189+
if (null !== $bodySize) {
190+
$options[CURLOPT_INFILESIZE] = $bodySize;
191+
}
192+
$options[CURLOPT_READFUNCTION] = function ($ch, $fd, $length) use ($body) {
193+
return $body->read($length);
194+
};
195+
} else {
196+
// Small body can be loaded into memory
197+
$options[CURLOPT_POSTFIELDS] = (string) $body;
198+
}
183199
}
184200
}
185201

@@ -221,6 +237,7 @@ private function getProtocolVersion($requestVersion)
221237
}
222238
throw new \UnexpectedValueException('libcurl 7.33 needed for HTTP 2.0 support');
223239
}
240+
224241
return CURL_HTTP_VERSION_NONE;
225242
}
226243

@@ -249,6 +266,7 @@ private function createHeaders(RequestInterface $request, array $options)
249266
$curlHeaders[] = $name . ': ' . $value;
250267
}
251268
}
269+
252270
return $curlHeaders;
253271
}
254272
}

tests/HttpClientDiactorosTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
use Http\Client\HttpClient;
66
use Http\Message\MessageFactory\DiactorosMessageFactory;
77
use Http\Message\StreamFactory\DiactorosStreamFactory;
8+
use Psr\Http\Message\StreamInterface;
89
use Zend\Diactoros\Request;
910
use Zend\Diactoros\Response;
11+
use Zend\Diactoros\Stream;
1012

1113
/**
1214
* Tests for Http\Client\Curl\Client
@@ -20,4 +22,16 @@ protected function createHttpAdapter()
2022
{
2123
return new Client(new DiactorosMessageFactory(), new DiactorosStreamFactory());
2224
}
25+
26+
/**
27+
* Create stream from file
28+
*
29+
* @param string $filename
30+
*
31+
* @return StreamInterface
32+
*/
33+
protected function createFileStream($filename)
34+
{
35+
return new Stream($filename);
36+
}
2337
}

tests/HttpClientGuzzleTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
<?php
22
namespace Http\Client\Curl\Tests;
33

4+
use GuzzleHttp\Psr7\Stream;
45
use Http\Client\Curl\Client;
56
use Http\Client\HttpClient;
67
use Http\Message\MessageFactory\GuzzleMessageFactory;
78
use Http\Message\StreamFactory\GuzzleStreamFactory;
9+
use Psr\Http\Message\StreamInterface;
810

911
/**
1012
* Tests for Http\Client\Curl\Client
@@ -18,4 +20,16 @@ protected function createHttpAdapter()
1820
{
1921
return new Client(new GuzzleMessageFactory(), new GuzzleStreamFactory());
2022
}
23+
24+
/**
25+
* Create stream from file
26+
*
27+
* @param string $filename
28+
*
29+
* @return StreamInterface
30+
*/
31+
protected function createFileStream($filename)
32+
{
33+
return new Stream(fopen($filename, 'r'));
34+
}
2135
}

0 commit comments

Comments
 (0)