/** * Check If accept mime type? * * @param array|string $type * @return array|null|string */ public function accept($type = null) { if (!isset($this->injectors['accept'])) { if (!empty($this->injectors['server']['HTTP_ACCEPT'])) { $this->injectors['accept'] = self::parseAcceptsMap($this->injectors['server']['HTTP_ACCEPT']); } else { $this->injectors['accept'] = array(); } } // if no parameter was passed, just return parsed data if (!$type) { return $this->injectors['accept']; } // Support get best match if ($type === true) { reset($this->injectors['accept']); return key($this->injectors['accept']); } // If type is 'txt', 'xml' and so on, use smarty stracy if (is_string($type) && !strpos($type, '/')) { $type = Config::export('mimes')->{$type}; if (!$type) { return null; } } // Force to array $type = (array) $type; // let’s check our supported types: foreach ($this->injectors['accept'] as $mime => $q) { if ($q && in_array($mime, $type)) { return $mime; } } // All match if (isset($this->injectors['accept']['*/*'])) { return $type[0]; } return null; }
/** * Set content type * * @param string $mime_type * @throws \InvalidArgumentException * @return string|Output */ public function type($mime_type = null) { if ($mime_type) { if (!strpos($mime_type, '/')) { if (!($type = Config::export('mimes')->{$mime_type}[0])) { throw new \InvalidArgumentException("Unknown mime type '{$mime_type}'"); } $mime_type = $type; } $this->injectors['content_type'] = $mime_type; return $this; } return $this->injectors['content_type']; }
public function run($req, $res) { $port = $this->params['port'] ? $this->params['port'] : '5000'; $command_app = $this->app; $default_headers = array('X-Powered-By' => 'Pagon/0.8'); /** * Mock Application and init */ $app = (include $command_app->command['app_dir'] . '/bootstrap.php'); $server_app = function ($request, $response) use($port, $app, $command_app, $default_headers) { /** * Static file check and render */ $static_file = $command_app->command['public_dir'] . '/' . $request->getPath(); if (is_file($static_file)) { echo Console::text("<green>200</green>" . ' <cyan>' . str_pad($request->getMethod(), 6, ' ', STR_PAD_RIGHT) . '</cyan>' . ' ' . $request->getPath(), true); $_arr = explode('.', $static_file); $ext = end($_arr); $mimes = Config::export('mimes'); $response->writeHead(200, $default_headers + array('Content-Type' => isset($mimes[$ext]) ? $mimes[$ext][0] : mime_content_type($static_file))); $response->end(file_get_contents($static_file)); return; } $raw = ''; $app->input = $mock_req = new \Pagon\Http\Input(array('app' => $app)); $app->output = $mock_res = new \Pagon\Http\Output(array('app' => $app)); $app->buffer = true; $app->cli = false; // Init request data $mock_req->server = $mock_req->query = $mock_req->data = $mock_req->files = $mock_req->_cookies = array(); $headers = $request->getHeaders(); $mock_req->query = $request->getQuery(); if ($headers['Cookie']) { $mock_req->_cookies = decode_cookie($headers['Cookie']); } $request->on('data', function ($data) use(&$raw, $request, $headers, $app, $command_app) { $raw .= $data; if (strlen($raw) < $headers['Content-Length']) { return; } // Start parse $parsed = parse_raw_http_request($raw, $headers['Content-Type']); // Inject data and files $app->input->data = $parsed['data']; $app->input->files = $parsed['files']; include $command_app->command['public_dir'] . '/index.php'; }); /** * Web header initial */ foreach ($headers as $k => $v) { $mock_req->server['HTTP_' . strtoupper(str_replace('-', '_', $k))] = $v; } /** * Web environment set */ $mock_req->server['REQUEST_URI'] = $request->getPath() . ($mock_req->query ? '?' . http_build_query($mock_req->query) : ''); $mock_req->server['REQUEST_METHOD'] = $request->getMethod(); $mock_req->server['REMOTE_ADDR'] = '127.0.0.1'; $mock_req->server['SERVER_NAME'] = '127.0.0.1'; $mock_req->server['SERVER_PORT'] = $port; $mock_req->server['SCRIPT_NAME'] = '/'; /** * Pagon header inject */ $mock_res->on('header', function () use($response, $request, $mock_res, $mock_req, $default_headers) { echo Console::text(($mock_res->status < 400 ? "<green>{$mock_res->status}</green>" : "<red>{$mock_res->status}</red>") . ' <cyan>' . str_pad($request->getMethod(), 6, ' ', STR_PAD_RIGHT) . '</cyan>' . ' ' . $mock_req->url, true); $headers = $mock_res->headers; if ($cookies = $mock_res->buildCookie()) { $headers['Set-Cookie'] = encode_cookie($cookies); } try { $response->writeHead($mock_res->status, $default_headers + $headers); $response->end($mock_res->body); } catch (\Exception $e) { echo Console::text($e->getMessage(), 'red', true); } $mock_res->body(''); }); }; $loop = \React\EventLoop\Factory::create(); $socket = new \React\Socket\Server($loop); $http = new \React\Http\Server($socket, $loop); $http->on('request', $server_app); $socket->listen($port, $this->params['ip']); echo "Pagon serve at " . Console::text("http://{$this->params['ip']}:{$port}", array("underline", "bold")) . "\n"; $loop->run(); }