public function onRequest() { $http = self::$serverInstance; $kernel = $this->kernel; $http->onMessage = function ($connection, $data) use($kernel) { // $http->on('request', function ($request, $response) use($kernel) { // if ($request->server['request_uri'] !== '/favicon.ico') { $l_request = new Symfony\Component\HttpFoundation\Request($data['get'], $data['post'], [], $data['cookie'], $data['files'], $data['server']); if (0 === strpos($l_request->headers->get('CONTENT_TYPE'), 'application/x-www-form-urlencoded') && in_array(strtoupper($l_request->server->get('REQUEST_METHOD', 'GET')), array('PUT', 'DELETE', 'PATCH'))) { parse_str($l_request->getContent(), $data); $l_request->request = new Symfony\Component\HttpFoundation\ParameterBag($data); } Illuminate\Http\Request::enableHttpMethodParameterOverride(); $l_request = Illuminate\Http\Request::createFromBase($l_request); $l_response = $kernel->handle($l_request); $result = $l_response->getContent(); foreach ($l_response->headers->allPreserveCase() as $name => $values) { Http::header($name . ':' . implode(';', $values)); } // $l_response->send(); foreach ($l_response->headers->getCookies() as $cookie) { Http::setcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly()); } $kernel->terminate($l_request, $l_response); $connection->send($result); // } }; }
public static function sendFile($connection, $file_path) { // Check 304. $info = stat($file_path); $modified_time = $info ? date('D, d M Y H:i:s', $info['mtime']) . ' GMT' : ''; if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $info) { // Http 304. if ($modified_time === $_SERVER['HTTP_IF_MODIFIED_SINCE']) { // 304 Http::header('HTTP/1.1 304 Not Modified'); // Send nothing but http headers.. $connection->close(''); return; } } // Http header. if ($modified_time) { $modified_time = "Last-Modified: {$modified_time}\r\n"; } $file_size = filesize($file_path); $file_info = pathinfo($file_path); $extension = isset($file_info['extension']) ? $file_info['extension'] : ''; $file_name = isset($file_info['filename']) ? $file_info['filename'] : ''; $header = "HTTP/1.1 200 OK\r\n"; if (isset(self::$mimeTypeMap[$extension])) { $header .= "Content-Type: " . self::$mimeTypeMap[$extension] . "\r\n"; } else { $header .= "Content-Type: application/octet-stream\r\n"; $header .= "Content-Disposition: attachment; filename=\"{$file_name}\"\r\n"; } $header .= "Connection: keep-alive\r\n"; $header .= $modified_time; $header .= "Content-Length: {$file_size}\r\n\r\n"; $trunk_limit_size = 1024 * 1024; if ($file_size < $trunk_limit_size) { return $connection->send($header . file_get_contents($file_path), true); } $connection->send($header, true); // Read file content from disk piece by piece and send to client. $connection->fileHandler = fopen($file_path, 'r'); $do_write = function () use($connection) { // Send buffer not full. while (empty($connection->bufferFull)) { // Read from disk. $buffer = fread($connection->fileHandler, 8192); // Read eof. if ($buffer === '' || $buffer === false) { return; } $connection->send($buffer, true); } }; // Send buffer full. $connection->onBufferFull = function ($connection) { $connection->bufferFull = true; }; // Send buffer drain. $connection->onBufferDrain = function ($connection) use($do_write) { $connection->bufferFull = false; $do_write(); }; $do_write(); }
/** * 退出 * @param string $str */ function _exit($str = '') { if (defined('WORKERMAN_ROOT_DIR')) { return Http::end($str); } return exit($str); }
/** * 退出 * @param string $str */ function _exit($str = '') { if (class_exists('\\Workerman\\Worker')) { return Http::end($str); } return exit($str); }
/** * 当接收到完整的http请求后的处理逻辑 * 1、如果请求的是以php为后缀的文件,则尝试加载 * 2、如果请求的url没有后缀,则尝试加载对应目录的index.php * 3、如果请求的是非php为后缀的文件,尝试读取原始数据并发送 * 4、如果请求的文件不存在,则返回404 * @param TcpConnection $connection * @param mixed $data * @return void */ public function onMessage($connection, $data) { // 请求的文件 $url_info = parse_url($_SERVER['REQUEST_URI']); if (!$url_info) { Http::header('HTTP/1.1 400 Bad Request'); return $connection->close('<h1>400 Bad Request</h1>'); } $path = $url_info['path']; $path_info = pathinfo($path); $extension = isset($path_info['extension']) ? $path_info['extension'] : ''; if ($extension === '') { $path = ($len = strlen($path)) && $path[$len - 1] === '/' ? $path . 'index.php' : $path . '/index.php'; $extension = 'php'; } $root_dir = isset($this->serverRoot[$_SERVER['HTTP_HOST']]) ? $this->serverRoot[$_SERVER['HTTP_HOST']] : current($this->serverRoot); $file = "{$root_dir}/{$path}"; // 对应的php文件不存在则直接使用根目录的index.php if ($extension === 'php' && !is_file($file)) { $file = "{$root_dir}/index.php"; if (!is_file($file)) { $file = "{$root_dir}/index.html"; $extension = 'html'; } } // 请求的文件存在 if (is_file($file)) { // 判断是否是站点目录里的文件 if (!($request_realpath = realpath($file)) || !($root_dir_realpath = realpath($root_dir)) || 0 !== strpos($request_realpath, $root_dir_realpath)) { Http::header('HTTP/1.1 400 Bad Request'); return $connection->close('<h1>400 Bad Request</h1>'); } $file = realpath($file); // 如果请求的是php文件 if ($extension === 'php') { $cwd = getcwd(); chdir($root_dir); ini_set('display_errors', 'off'); // 缓冲输出 ob_start(); // 载入php文件 try { // $_SERVER变量 $_SERVER['REMOTE_ADDR'] = $connection->getRemoteIp(); $_SERVER['REMOTE_PORT'] = $connection->getRemotePort(); include $file; } catch (\Exception $e) { // 如果不是exit if ($e->getMessage() != 'jump_exit') { echo $e; } } $content = ob_get_clean(); ini_set('display_errors', 'on'); $connection->close($content); chdir($cwd); return; } // 请求的是静态资源文件 if (isset(self::$mimeTypeMap[$extension])) { Http::header('Content-Type: ' . self::$mimeTypeMap[$extension]); } else { Http::header('Content-Type: ' . self::$defaultMimeType); } // 获取文件信息 $info = stat($file); $modified_time = $info ? date('D, d M Y H:i:s', $info['mtime']) . ' GMT' : ''; // 如果有$_SERVER['HTTP_IF_MODIFIED_SINCE'] if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $info) { // 文件没有更改则直接304 if ($modified_time === $_SERVER['HTTP_IF_MODIFIED_SINCE']) { // 304 Http::header('HTTP/1.1 304 Not Modified'); // 发送给客户端 return $connection->close(''); } } if ($modified_time) { Http::header("Last-Modified: {$modified_time}"); } // 发送给客户端 return $connection->close(file_get_contents($file)); } else { // 404 Http::header("HTTP/1.1 404 Not Found"); return $connection->close('<html><head><title>404 页面不存在</title></head><body><center><h3>404 Not Found</h3></center></body></html>'); } }
/** * Emit when http message coming. * @param TcpConnection $connection * @param mixed $data * @return void */ public function onMessage($connection, $data) { // REQUEST_URI. $url_info = parse_url($_SERVER['REQUEST_URI']); if (!$url_info) { Http::header('HTTP/1.1 400 Bad Request'); return $connection->close('<h1>400 Bad Request</h1>'); } $path = $url_info['path']; $path_info = pathinfo($path); $extension = isset($path_info['extension']) ? $path_info['extension'] : ''; if ($extension === '') { $path = ($len = strlen($path)) && $path[$len - 1] === '/' ? $path . 'index.php' : $path . '/index.php'; $extension = 'php'; } $root_dir = isset($this->serverRoot[$_SERVER['HTTP_HOST']]) ? $this->serverRoot[$_SERVER['HTTP_HOST']] : current($this->serverRoot); $file = "{$root_dir}/{$path}"; if ($extension === 'php' && !is_file($file)) { $file = "{$root_dir}/index.php"; if (!is_file($file)) { $file = "{$root_dir}/index.html"; $extension = 'html'; } } // File exsits. if (is_file($file)) { // Security check. if (!($request_realpath = realpath($file)) || !($root_dir_realpath = realpath($root_dir)) || 0 !== strpos($request_realpath, $root_dir_realpath)) { Http::header('HTTP/1.1 400 Bad Request'); return $connection->close('<h1>400 Bad Request</h1>'); } $file = realpath($file); // Request php file. if ($extension === 'php') { $cwd = getcwd(); chdir($root_dir); ini_set('display_errors', 'off'); ob_start(); // Try to include php file. try { // $_SERVER. $_SERVER['REMOTE_ADDR'] = $connection->getRemoteIp(); $_SERVER['REMOTE_PORT'] = $connection->getRemotePort(); include $file; } catch (\Exception $e) { // Jump_exit? if ($e->getMessage() != 'jump_exit') { echo $e; } } $content = ob_get_clean(); ini_set('display_errors', 'on'); $connection->close($content); chdir($cwd); return; } // Static resource file request. if (isset(self::$mimeTypeMap[$extension])) { Http::header('Content-Type: ' . self::$mimeTypeMap[$extension]); } else { Http::header('Content-Type: ' . self::$defaultMimeType); } // Get file stat. $info = stat($file); $modified_time = $info ? date('D, d M Y H:i:s', $info['mtime']) . ' GMT' : ''; if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $info) { // Http 304. if ($modified_time === $_SERVER['HTTP_IF_MODIFIED_SINCE']) { // 304 Http::header('HTTP/1.1 304 Not Modified'); // Send nothing but http headers.. return $connection->close(''); } } if ($modified_time) { Http::header("Last-Modified: {$modified_time}"); } // Send to client. return $connection->close(file_get_contents($file)); } else { // 404 Http::header("HTTP/1.1 404 Not Found"); return $connection->close('<html><head><title>404 File not found</title></head><body><center><h3>404 Not Found</h3></center></body></html>'); } }