Skip to content

Commit 8bbdda4

Browse files
committed
refactor: extract much of server.php into a Server class
- Move all functions into a new `Server` class. - Simplify various server.php code by adding the code into a new method in the `Server` class, and use it in the server.php. Eg. `uriFromRequestUri`, `siteNameFromHttpHost`, `domainFromSiteName`, etc. - Change all method names to camelCase, and rename these specific methods to be more precise names: `show_valet_404` -> `show404` `get_valet_site_path` -> `sitePath` `valet_default_site_path` -> `defaultSitePath` `valet_support_wildcard_dns` -> `supportWildcardDnsDomains - Change the `showDirectoryListing` method to output the contents of the file instead of using the HTML for the directory listing, which would output an empty document with the title.
1 parent 4d80e51 commit 8bbdda4

File tree

2 files changed

+300
-167
lines changed

2 files changed

+300
-167
lines changed

cli/Valet/Server.php

Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
<?php
2+
3+
namespace Valet;
4+
5+
class Server {
6+
/**
7+
* @var array
8+
*/
9+
public $config;
10+
11+
public function __construct($config) {
12+
$this->config = $config;
13+
}
14+
15+
/**
16+
* Extract $uri from $SERVER['REQUEST_URI'] variable.
17+
*
18+
* @param string $requestUri The request URI.
19+
*
20+
* @return string The extracted URI.
21+
*/
22+
public function uriFromRequestUri($requestUri) {
23+
return rawurldecode(
24+
explode('?', $requestUri)[0]
25+
);
26+
}
27+
28+
/**
29+
* Extract site name from HTTP host, stripping www. and supporting wildcard DNS.
30+
*
31+
* @param string $httpHost The HTTP host.
32+
*
33+
* @return string The extracted site name.
34+
*/
35+
public function siteNameFromHttpHost($httpHost) {
36+
$siteName = basename(
37+
// Filter host to support wildcard dns feature
38+
$this->supportWildcardDnsDomains($httpHost),
39+
'.'.$this->config['tld']
40+
);
41+
42+
if (strpos($siteName, 'www.') === 0) {
43+
$siteName = substr($siteName, 4);
44+
}
45+
46+
return $siteName;
47+
}
48+
49+
/**
50+
* You may use wildcard DNS providers xip.io or nip.io as a tool for testing your site via
51+
* an IP address.
52+
* It's simple to use: First determine the IP address of your local computer
53+
* (like 192.168.0.10).
54+
* Then simply use http://project.your-ip.xip.io - ie: http://laravel.192.168.0.10.xip.io.
55+
*
56+
* @param string $domain The domain to check.
57+
*
58+
* @return string The domain
59+
*/
60+
public function supportWildcardDnsDomains($domain) {
61+
$services = [
62+
'.*.*.*.*.xip.io',
63+
'.*.*.*.*.nip.io',
64+
'-*-*-*-*.nip.io'
65+
];
66+
67+
if (isset($this->config['tunnel_services'])) {
68+
$services = array_merge($services, (array) $this->config['tunnel_services']);
69+
}
70+
71+
$patterns = [];
72+
foreach ($services as $service) {
73+
$pattern = preg_quote($service, '#');
74+
$pattern = str_replace('\*', '.*', $pattern);
75+
$patterns[] = '(.*)' . $pattern;
76+
}
77+
78+
$pattern = implode('|', $patterns);
79+
80+
if (preg_match('#(?:' . $pattern . ')\z#u', $domain, $matches)) {
81+
$domain = array_pop($matches);
82+
}
83+
84+
if (strpos($domain, ':') !== false) {
85+
$domain = explode(':', $domain)[0];
86+
}
87+
88+
return $domain;
89+
}
90+
91+
/**
92+
* Determine the fully qualified path to the site.
93+
* Inspects registered path directories, case-sensitive.
94+
*
95+
* @param string $siteName The site name.
96+
*
97+
* @return string|null The fully qualified path to the site, or null if not found.
98+
*/
99+
public function sitePath($siteName) {
100+
$valetSitePath = null;
101+
$domain = $this->domainFromSiteName($siteName);
102+
103+
foreach ($this->config['paths'] as $path) {
104+
if (!is_dir($path)) {
105+
continue;
106+
}
107+
108+
$handle = opendir($path);
109+
110+
if ($handle === false) {
111+
continue;
112+
}
113+
114+
$dirs = [];
115+
116+
while (($file = readdir($handle)) !== false) {
117+
if (is_dir("$path/$file") && !in_array($file, ['.', '..'])) {
118+
$dirs[] = $file;
119+
}
120+
}
121+
122+
closedir($handle);
123+
124+
foreach ($dirs as $dir) {
125+
// Note: strtolower used below because Nginx only tells us lowercase names
126+
if (strtolower($dir) === $siteName) {
127+
// Early return when exact match for linked subdomain
128+
return "$path/$dir";
129+
}
130+
131+
if (strtolower($dir) === $domain) {
132+
// No early return here because the foreach may still have some subdomains to
133+
// process with higher priority
134+
$valetSitePath = "$path/$dir";
135+
}
136+
}
137+
138+
if ($valetSitePath) {
139+
return $valetSitePath;
140+
}
141+
}
142+
143+
return null;
144+
}
145+
146+
/**
147+
* Extract the domain from the site name.
148+
*
149+
* @param string $siteName The site name.
150+
*
151+
* @return string The extracted domain.
152+
*/
153+
public function domainFromSiteName($siteName) {
154+
return array_slice(explode('.', $siteName), -1)[0];
155+
}
156+
157+
/**
158+
* Get the default site path for uncaught URLs, if it's set.
159+
*
160+
* @return string|null If set, default site path for uncaught urls
161+
*/
162+
public function defaultSitePath() {
163+
if (isset($this->config['default']) && is_string($this->config['default']) && is_dir($this->config['default'])) {
164+
return $this->config['default'];
165+
}
166+
167+
return null;
168+
}
169+
170+
/**
171+
* Set the ngrok server forwarded host if it's not already set.
172+
* (ngrok uses the X-Original-Host to store the forwarded hostname.)
173+
*/
174+
public function setNgrokServerForwardedHost() {
175+
if (isset($_SERVER['HTTP_X_ORIGINAL_HOST']) && !isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
176+
$_SERVER['HTTP_X_FORWARDED_HOST'] = $_SERVER['HTTP_X_ORIGINAL_HOST'];
177+
}
178+
}
179+
180+
/**
181+
* Is the incoming request for a static file?
182+
*
183+
* @param string $uri The URI of the request.
184+
* @param string $valetSitePath The path to the Valet site.
185+
* @param string $siteName The name of the site.
186+
* @param object $valetDriver The Valet driver instance.
187+
*
188+
* @return string|false The path to the static file or false if not found.
189+
*/
190+
public function isRequestStaticFile($uri, $valetSitePath, $siteName, $valetDriver) {
191+
192+
$isPhpFile = pathinfo($uri, PATHINFO_EXTENSION) === 'php';
193+
194+
if ($uri !== '/' && !$isPhpFile && $staticFilePath = $valetDriver->isStaticFile($valetSitePath, $siteName, $uri)) {
195+
return $staticFilePath;
196+
}
197+
return false;
198+
}
199+
200+
/**
201+
* Show the Valet 404 "Not Found" page.
202+
*/
203+
public function show404() {
204+
http_response_code(404);
205+
require __DIR__ . '/../templates/404.html';
206+
exit;
207+
}
208+
209+
/**
210+
* Show directory listing or 404 if directory doesn't exist.
211+
*
212+
* @param string $valetSitePath The path to the Valet site.
213+
* @param string $uri The URI of the request.
214+
*/
215+
public function showDirectoryListing($valetSitePath, $uri) {
216+
$is_root = ($uri == '/');
217+
$directory = $is_root ? $valetSitePath : $valetSitePath . $uri;
218+
219+
if (!file_exists($directory)) {
220+
$this->show404();
221+
}
222+
223+
// Sort directories at the top
224+
$paths = glob("$directory/*");
225+
usort($paths, function ($a, $b) {
226+
return (is_dir($a) == is_dir($b)) ? strnatcasecmp($a, $b) : (is_dir($a) ? -1 : 1);
227+
});
228+
229+
// If the directory is a file, output its contents and exit.
230+
if (is_file($directory)) {
231+
echo "<pre>";
232+
echo file_get_contents($directory);
233+
echo "</pre>";
234+
235+
exit;
236+
}
237+
238+
// Output the HTML for the directory listing
239+
echo "<h1>Index of $uri</h1>";
240+
echo '<hr>';
241+
echo implode("<br>\n", array_map(function ($path) use ($uri, $is_root) {
242+
$file = basename($path);
243+
244+
return ($is_root) ? "<a href='/$file'>/$file</a>" : "<a href='$uri/$file'>$uri/$file/</a>";
245+
}, $paths));
246+
247+
exit;
248+
}
249+
250+
/**
251+
* Show directory listing if it's enabled or 404.
252+
*
253+
* @param string $valetSitePath The path to the Valet site.
254+
* @param string $uri The URI of the request.
255+
*/
256+
public function showDirectoryListingOr404($valetSitePath, $uri) {
257+
if (isset($this->config['directory-listing']) && $this->config['directory-listing'] == 'on') {
258+
$this->showDirectoryListing($valetSitePath, $uri);
259+
}
260+
261+
$this->show404();
262+
}
263+
264+
/**
265+
* Change into front controller path when executing
266+
*
267+
* @param string $frontControllerPath The path to the front controller.
268+
*/
269+
public function changeDir($frontControllerPath) {
270+
chdir(dirname($frontControllerPath));
271+
}
272+
}

0 commit comments

Comments
 (0)