scratch – Blame information for rev 87

Subversion Repositories:
Rev:
Rev Author Line No. Line
87 office 1 <?php
2  
3 namespace GuzzleHttp\Tests;
4  
5 use GuzzleHttp\Client;
6 use GuzzleHttp\Message\MessageFactory;
7 use GuzzleHttp\Message\ResponseInterface;
8  
9 /**
10 * The Server class is used to control a scripted webserver using node.js that
11 * will respond to HTTP requests with queued responses.
12 *
13 * Queued responses will be served to requests using a FIFO order. All requests
14 * received by the server are stored on the node.js server and can be retrieved
15 * by calling {@see Server::received()}.
16 *
17 * Mock responses that don't require data to be transmitted over HTTP a great
18 * for testing. Mock response, however, cannot test the actual sending of an
19 * HTTP request using cURL. This test server allows the simulation of any
20 * number of HTTP request response transactions to test the actual sending of
21 * requests over the wire without having to leave an internal network.
22 */
23 class Server
24 {
25 const REQUEST_DELIMITER = "\n----[request]\n";
26  
27 /** @var Client */
28 private static $client;
29  
30 public static $started;
31 public static $url = 'http://127.0.0.1:8125/';
32 public static $port = 8125;
33  
34 /**
35 * Flush the received requests from the server
36 * @throws \RuntimeException
37 */
38 public static function flush()
39 {
40 self::start();
41  
42 return self::$client->delete('guzzle-server/requests');
43 }
44  
45 /**
46 * Queue an array of responses or a single response on the server.
47 *
48 * Any currently queued responses will be overwritten. Subsequent requests
49 * on the server will return queued responses in FIFO order.
50 *
51 * @param array|ResponseInterface $responses A single or array of Responses
52 * to queue.
53 * @throws \Exception
54 */
55 public static function enqueue($responses)
56 {
57 static $factory;
58 if (!$factory) {
59 $factory = new MessageFactory();
60 }
61  
62 self::start();
63  
64 $data = [];
65 foreach ((array) $responses as $response) {
66  
67 // Create the response object from a string
68 if (is_string($response)) {
69 $response = $factory->fromMessage($response);
70 } elseif (!($response instanceof ResponseInterface)) {
71 throw new \Exception('Responses must be strings or Responses');
72 }
73  
74 $headers = array_map(function ($h) {
75 return implode(' ,', $h);
76 }, $response->getHeaders());
77  
78 $data[] = [
79 'statusCode' => $response->getStatusCode(),
80 'reasonPhrase' => $response->getReasonPhrase(),
81 'headers' => $headers,
82 'body' => base64_encode((string) $response->getBody())
83 ];
84 }
85  
86 self::getClient()->put('guzzle-server/responses', [
87 'body' => json_encode($data)
88 ]);
89 }
90  
91 /**
92 * Get all of the received requests
93 *
94 * @param bool $hydrate Set to TRUE to turn the messages into
95 * actual {@see RequestInterface} objects. If $hydrate is FALSE,
96 * requests will be returned as strings.
97 *
98 * @return array
99 * @throws \RuntimeException
100 */
101 public static function received($hydrate = false)
102 {
103 if (!self::$started) {
104 return [];
105 }
106  
107 $response = self::getClient()->get('guzzle-server/requests');
108 $data = array_filter(explode(self::REQUEST_DELIMITER, (string) $response->getBody()));
109 if ($hydrate) {
110 $factory = new MessageFactory();
111 $data = array_map(function ($message) use ($factory) {
112 return $factory->fromMessage($message);
113 }, $data);
114 }
115  
116 return $data;
117 }
118  
119 /**
120 * Stop running the node.js server
121 */
122 public static function stop()
123 {
124 if (self::$started) {
125 self::getClient()->delete('guzzle-server');
126 }
127  
128 self::$started = false;
129 }
130  
131 public static function wait($maxTries = 5)
132 {
133 $tries = 0;
134 while (!self::isListening() && ++$tries < $maxTries) {
135 usleep(100000);
136 }
137  
138 if (!self::isListening()) {
139 throw new \RuntimeException('Unable to contact node.js server');
140 }
141 }
142  
143 private static function start()
144 {
145 if (self::$started) {
146 return;
147 }
148  
149 if (!self::isListening()) {
150 exec('node ' . __DIR__ . \DIRECTORY_SEPARATOR . 'server.js '
151 . self::$port . ' >> /tmp/server.log 2>&1 &');
152 self::wait();
153 }
154  
155 self::$started = true;
156 }
157  
158 private static function isListening()
159 {
160 try {
161 self::getClient()->get('guzzle-server/perf', [
162 'connect_timeout' => 5,
163 'timeout' => 5
164 ]);
165 return true;
166 } catch (\Exception $e) {
167 return false;
168 }
169 }
170  
171 private static function getClient()
172 {
173 if (!self::$client) {
174 self::$client = new Client(['base_url' => self::$url]);
175 }
176  
177 return self::$client;
178 }
179 }