1 | <?php |
||
33 | class RequestFactory |
||
34 | { |
||
35 | /** |
||
36 | * |
||
37 | * @param RequestInterface $request |
||
38 | * @param array $options |
||
39 | * @param $resolver Resolver |
||
40 | * @param HttpClient $httpClient |
||
41 | * @param LoopInterface $loop |
||
42 | * @return \React\Promise\Promise |
||
43 | */ |
||
44 | 1 | public function create( |
|
45 | RequestInterface $request, |
||
46 | array $options, |
||
47 | Resolver $resolver, |
||
|
|||
48 | HttpClient $httpClient, |
||
49 | LoopInterface $loop |
||
50 | ) { |
||
51 | 1 | $options = $this->convertOptions($options); |
|
52 | |||
53 | 1 | if (isset($options['delay'])) { |
|
54 | $promise = \WyriHaximus\React\timedPromise($loop, $options['delay']); |
||
55 | } |
||
56 | 1 | if (!isset($promise)) { |
|
57 | 1 | $promise = \WyriHaximus\React\futurePromise($loop); |
|
58 | 1 | } |
|
59 | |||
60 | return $promise->then(function () use ( |
||
61 | 1 | $request, |
|
62 | 1 | $options, |
|
63 | 1 | $httpClient, |
|
64 | 1 | $loop |
|
65 | ) { |
||
66 | 1 | $sender = $this->createSender($options, $httpClient, $loop); |
|
67 | 1 | return (new Browser($loop, $sender)) |
|
68 | 1 | ->withOptions($options) |
|
69 | ->send($request)->then(function ($response) use ($loop, $options) { |
||
70 | if (!isset($options['sink'])) { |
||
71 | return \React\Promise\resolve($response); |
||
72 | } |
||
73 | |||
74 | return \React\Promise\resolve($this->sink($loop, $response, $options['sink'])); |
||
75 | 1 | }); |
|
76 | 1 | }); |
|
77 | } |
||
78 | |||
79 | protected function sink($loop, $response, $target) |
||
80 | { |
||
81 | $deferred = new Deferred(); |
||
82 | $writeStream = fopen($target, 'w'); |
||
83 | $saveToStream = new WritableResourceStream($writeStream, $loop); |
||
84 | |||
85 | $saveToStream->on( |
||
86 | 'end', |
||
87 | function () use ($deferred, $response) { |
||
88 | $deferred->resolve($response); |
||
89 | } |
||
90 | ); |
||
91 | |||
92 | $body = $response->getBody(); |
||
93 | if ($body instanceof ReadableStreamInterface) { |
||
94 | $body->pipe($saveToStream); |
||
95 | } else { |
||
96 | $saveToStream->end($body->getContents()); |
||
97 | } |
||
98 | |||
99 | return $deferred->promise(); |
||
100 | } |
||
101 | |||
102 | /** |
||
103 | * @param array $options |
||
104 | * @param HttpClient $httpClient |
||
105 | * @param LoopInterface $loop |
||
106 | * @return Sender |
||
107 | */ |
||
108 | 1 | protected function createSender(array $options, HttpClient $httpClient, LoopInterface $loop) |
|
109 | { |
||
110 | 1 | $connector = $this->getProperty($httpClient, 'connector'); |
|
111 | |||
112 | 1 | if (isset($options['proxy'])) { |
|
113 | switch (parse_url($options['proxy'], PHP_URL_SCHEME)) { |
||
114 | case 'http': |
||
115 | $connector = new Connector( |
||
116 | $loop, |
||
117 | [ |
||
118 | 'tcp' => new HttpProxyClient( |
||
119 | $options['proxy'], |
||
120 | $connector |
||
121 | ), |
||
122 | ] |
||
123 | ); |
||
124 | break; |
||
125 | case 'socks': |
||
126 | case 'socks4': |
||
127 | case 'socks4a': |
||
128 | case 'socks5': |
||
129 | $connector = new Connector( |
||
130 | $loop, |
||
131 | [ |
||
132 | 'tcp' => new SocksProxyClient( |
||
133 | $options['proxy'], |
||
134 | $connector |
||
135 | ), |
||
136 | ] |
||
137 | ); |
||
138 | break; |
||
139 | } |
||
140 | } |
||
141 | |||
142 | 1 | if (isset($options['connect_timeout'])) { |
|
143 | $connector = new TimeoutConnector($connector, $options['connect_timeout'], $loop); |
||
144 | } |
||
145 | |||
146 | 1 | return $connector; |
|
147 | } |
||
148 | |||
149 | /** |
||
150 | * @param array $options |
||
151 | * @return array |
||
152 | */ |
||
153 | 1 | protected function convertOptions(array $options) |
|
154 | { |
||
155 | // provides backwards compatibility for Guzzle 3-5. |
||
156 | 1 | if (isset($options['client'])) { |
|
157 | $options = array_merge($options, $options['client']); |
||
158 | unset($options['client']); |
||
159 | } |
||
160 | |||
161 | // provides for backwards compatibility for Guzzle 3-5 |
||
162 | 1 | if (isset($options['save_to'])) { |
|
163 | $options['sink'] = $options['save_to']; |
||
164 | unset($options['save_to']); |
||
165 | } |
||
166 | |||
167 | 1 | if (isset($options['delay'])) { |
|
168 | $options['delay'] = $options['delay']/1000; |
||
169 | } |
||
170 | |||
171 | 1 | if (isset($options['allow_redirects'])) { |
|
172 | $this->convertRedirectOption($options); |
||
173 | } |
||
174 | |||
175 | 1 | return $options; |
|
176 | } |
||
177 | |||
178 | protected function convertRedirectOption(&$options) |
||
179 | { |
||
180 | $option = $options['allow_redirects']; |
||
181 | unset($options['allow_redirects']); |
||
182 | |||
183 | if (is_bool($option)) { |
||
184 | $options['followRedirects'] = $option; |
||
185 | return; |
||
186 | } |
||
187 | |||
188 | if (is_array($option)) { |
||
189 | if (isset($option['max'])) { |
||
190 | $options['maxRedirects'] = $option['max']; |
||
191 | } |
||
192 | $options['followRedirects'] = true; |
||
193 | return; |
||
194 | } |
||
195 | } |
||
196 | |||
197 | /** |
||
198 | * @param object $object |
||
199 | * @param string $desiredProperty |
||
200 | * @return mixed |
||
201 | */ |
||
202 | 1 | protected function getProperty($object, $desiredProperty) |
|
209 | } |
||
210 |
This check looks from parameters that have been defined for a function or method, but which are not used in the method body.