Skip to content

Commit 081d8de

Browse files
committed
Merge pull request #112 from AlexeyDsov/curlHttpClientUpdate
CurlHttpClient: allowing upload files and send post/get arrays with any deep lvl
2 parents 0d3b9e5 + 9e36e33 commit 081d8de

File tree

10 files changed

+476
-17
lines changed

10 files changed

+476
-17
lines changed

doc/ChangeLog

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
2012-09-12 Alexey S. Denisov
2+
3+
* main/Flow/HttpRequest.class.php
4+
main/Net/Http/CurlHttpClient.class.php
5+
main/Utils/UrlParamsUtils.class.php:
6+
allowing curlHttpClient upload files and send post/get arrays with any deep lvl
7+
18
2012-09-06 Igor V. Gulyaev
29

310
* main/Base/Hstore.class.php

doc/Migration1.0-1.1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
https://github.com/onPHP/onphp-framework/wiki/Ru%3A1.0to1.1

global.inc.php.tpl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@
7676
ONPHP_ROOT_PATH.'meta'.DIRECTORY_SEPARATOR
7777
);
7878

79+
/**
80+
* @deprecated
81+
*/
82+
if (!defined('ONPHP_CURL_CLIENT_OLD_TO_STRING'))
83+
define('ONPHP_CURL_CLIENT_OLD_TO_STRING', false);
84+
7985
define('ONPHP_META_CLASSES', ONPHP_META_PATH.'classes'.DIRECTORY_SEPARATOR);
8086

8187
define(

main/Flow/HttpRequest.class.php

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,27 @@ final class HttpRequest
2929
// reference, not copy
3030
private $session = array();
3131

32-
// uploads
32+
// uploads and downloads (CurlHttpClient)
3333
private $files = array();
3434

3535
// all other sh1t
3636
private $attached = array();
3737

3838
private $headers = array();
3939

40+
/**
41+
* @var HttpMethod
42+
*/
4043
private $method = null;
4144

45+
/**
46+
* @var HttpUrl
47+
*/
4248
private $url = null;
4349

50+
//for CurlHttpClient if you need to send raw CURLOPT_POSTFIELDS
51+
private $body = null;
52+
4453
/**
4554
* @return HttpRequest
4655
**/
@@ -341,5 +350,25 @@ public function getUrl()
341350
{
342351
return $this->url;
343352
}
353+
354+
public function hasBody()
355+
{
356+
return $this->body !== null;
357+
}
358+
359+
public function getBody()
360+
{
361+
return $this->body;
362+
}
363+
364+
/**
365+
* @param string $body
366+
* @return HttpRequest
367+
*/
368+
public function setBody($body)
369+
{
370+
$this->body = $body;
371+
return $this;
372+
}
344373
}
345374
?>

main/Net/Http/CurlHttpClient.class.php

Lines changed: 89 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
* License, or (at your option) any later version. *
99
* *
1010
***************************************************************************/
11-
/* $Id: CurlHttpClient.class.php 45 2009-05-08 07:41:33Z lom $ */
1211

1312
/**
1413
* @ingroup Http
@@ -23,6 +22,10 @@ final class CurlHttpClient implements HttpClient
2322
private $multiRequests = array();
2423
private $multiResponses = array();
2524
private $multiThreadOptions = array();
25+
/**
26+
* @deprecated in the furure will work like this value is false;
27+
*/
28+
private $oldUrlConstructor = ONPHP_CURL_CLIENT_OLD_TO_STRING;
2629

2730
/**
2831
* @return CurlHttpClient
@@ -148,6 +151,26 @@ public function getMaxFileSize()
148151
return $this->maxFileSize;
149152
}
150153

154+
/**
155+
* @deprecated in the future value always false and method will be removed
156+
* @param bool $oldUrlConstructor
157+
* @return CurlHttpClient
158+
*/
159+
public function setOldUrlConstructor($oldUrlConstructor = false)
160+
{
161+
$this->oldUrlConstructor = ($oldUrlConstructor == true);
162+
return $this;
163+
}
164+
165+
/**
166+
* @deprecated in the future value always false and method will be removed
167+
* @return bool
168+
*/
169+
public function isOldUrlConstructor()
170+
{
171+
return $this->oldUrlConstructor;
172+
}
173+
151174
/**
152175
* @return CurlHttpClient
153176
**/
@@ -280,9 +303,14 @@ protected function makeHandle(HttpRequest $request, CurlHttpResponse $response)
280303
break;
281304

282305
case HttpMethod::POST:
306+
if ($request->getGet())
307+
$options[CURLOPT_URL] .=
308+
($request->getUrl()->getQuery() ? '&' : '?')
309+
.$this->argumentsToString($request->getGet());
310+
283311
$options[CURLOPT_POST] = true;
284-
$options[CURLOPT_POSTFIELDS] =
285-
$this->argumentsToString($request->getPost());
312+
$options[CURLOPT_POSTFIELDS] = $this->getPostFields($request);
313+
286314
break;
287315

288316
default:
@@ -337,23 +365,68 @@ protected function makeResponse($handle, CurlHttpResponse $response)
337365
return $this;
338366
}
339367

340-
private function argumentsToString($array)
368+
private function argumentsToString($array, $isFile = false)
341369
{
342-
Assert::isArray($array);
343-
$result = array();
344-
345-
foreach ($array as $key => $value) {
346-
if (is_array($value)) {
347-
foreach ($value as $valueKey => $simpleValue) {
348-
$result[] =
349-
$key.'['.$valueKey.']='.urlencode($simpleValue);
350-
}
370+
if ($this->oldUrlConstructor)
371+
return UrlParamsUtils::toStringOneDeepLvl($array);
372+
else
373+
return UrlParamsUtils::toString($array);
374+
}
375+
376+
private function getPostFields(HttpRequest $request)
377+
{
378+
if ($request->hasBody()) {
379+
return $request->getBody();
380+
} else {
381+
if ($this->oldUrlConstructor) {
382+
return UrlParamsUtils::toStringOneDeepLvl($request->getPost());
351383
} else {
352-
$result[] = $key.'='.urlencode($value);
384+
$fileList = array_map(
385+
array($this, 'fileFilter'),
386+
UrlParamsUtils::toParamsList($request->getFiles())
387+
);
388+
if (empty($fileList)) {
389+
return UrlParamsUtils::toString($request->getPost());
390+
} else {
391+
$postList = UrlParamsUtils::toParamsList($request->getPost());
392+
if (!is_null($atParam = $this->findAtParamInPost($postList)))
393+
throw new NetworkException(
394+
'Security excepion: not allowed send post param '.$atParam
395+
. ' which begins from @ in request which contains files'
396+
);
397+
398+
return array_merge($postList, $fileList);
399+
}
353400
}
354401
}
355-
356-
return implode('&', $result);
402+
}
403+
404+
/**
405+
* Return param name which start with symbol @ or null
406+
* @param array $postList
407+
* @return string|null
408+
*/
409+
private function findAtParamInPost($postList)
410+
{
411+
foreach ($postList as $param)
412+
if (mb_stripos($param, '@') === 0)
413+
return $param;
414+
415+
return null;
416+
}
417+
418+
/**
419+
* using in getPostFields - array_map func
420+
* @param string $value
421+
* @return string
422+
*/
423+
private function fileFilter($value)
424+
{
425+
Assert::isTrue(
426+
is_readable($value) && is_file($value),
427+
'couldn\'t access to file with path: '.$value
428+
);
429+
return '@'.$value;
357430
}
358431
}
359432
?>
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php
2+
/***************************************************************************
3+
* Copyright (C) 2012 by Alexey S. Denisov *
4+
* *
5+
* This program is free software; you can redistribute it and/or modify *
6+
* it under the terms of the GNU Lesser General Public License as *
7+
* published by the Free Software Foundation; either version 3 of the *
8+
* License, or (at your option) any later version. *
9+
* *
10+
***************************************************************************/
11+
12+
/**
13+
* @ingroup Utils
14+
**/
15+
final class UrlParamsUtils extends StaticFactory
16+
{
17+
/**
18+
* @deprecated to support old convert method in CurlHttpClient
19+
* @param array $array
20+
* @return string
21+
*/
22+
public static function toStringOneDeepLvl($array)
23+
{
24+
Assert::isArray($array);
25+
$result = array();
26+
27+
foreach ($array as $key => $value) {
28+
if (is_array($value)) {
29+
foreach ($value as $valueKey => $simpleValue) {
30+
$result[] =
31+
$key.'['.$valueKey.']='.urlencode($simpleValue);
32+
}
33+
} else {
34+
$result[] = $key.'='.urlencode($value);
35+
}
36+
}
37+
38+
return implode('&', $result);
39+
}
40+
41+
public static function toString($array)
42+
{
43+
$sum = function ($left, $right) {return $left.'='.urlencode($right);};
44+
$params = self::toParamsList($array, true);
45+
return implode('&',
46+
array_map($sum, array_keys($params), $params)
47+
);
48+
}
49+
50+
public static function toParamsList($array, $encodeKey = false)
51+
{
52+
$result = array();
53+
54+
self::argumentsToParams($array, $result, '', $encodeKey);
55+
56+
return $result;
57+
}
58+
59+
private static function argumentsToParams(
60+
$array,
61+
&$result,
62+
$keyPrefix,
63+
$encodeKey = false
64+
) {
65+
foreach ($array as $key => $value) {
66+
$filteredKey = $encodeKey ? urlencode($key) : $key;
67+
$fullKey = $keyPrefix
68+
? ($keyPrefix.'['.$filteredKey.']')
69+
: $filteredKey;
70+
71+
if (is_array($value)) {
72+
self::argumentsToParams($value, $result, $fullKey, $encodeKey);
73+
} else {
74+
$result[$fullKey] = $value;
75+
}
76+
}
77+
}
78+
}
79+
?>

test/config.inc.php.tpl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,5 @@
5454
VoodooDaoWorker::setDefaultHandler('CacheSegmentHandler');
5555

5656
define('__LOCAL_DEBUG__', true);
57+
define('ONPHP_CURL_TEST_URL', 'http://localhost/curlTest.php'); //set here url to test script test/main/data/curlTest/curlTest.php
5758
?>

0 commit comments

Comments
 (0)