<?php ############################### # Run with the following format ############################### # php -S HOST:PORT [-t DOC_ROOT] index.php # e.g. php -S localhost:8080 -t /var/www/ index.php # e.g. php -S localhost:8080 index.php # (uses current directory as DOC_ROOT) # Some other examples # https://stackoverflow.com/questions/14946964/php-built-in-server-any-way-to-configure-it-to-show-files-of-directory $BASE_DIR = $_SERVER['DOCUMENT_ROOT']; $request_url = explode("?",$_SERVER['REQUEST_URI'])[0]; $RELATIVE_PATH = getFilePath(urldecode($request_url)); $ABSOLUTE_PATH = realpath($BASE_DIR . $RELATIVE_PATH); $ERROR_PATH = ""; $DEBUG = false; // For Windows (disclaimer: haven't actaully tested) function getFilePath($dir){ return str_replace("/", DIRECTORY_SEPARATOR, urldecode($dir)); } function getParents($file){ if($file == DIRECTORY_SEPARATOR) return array(); $base = basename($file); $parent = dirname($file); return array_merge(getParents($parent), array($base)); } function urlencodePaths($paths){ $output = ""; foreach ($paths as $path) { $output .= urlencode($path) . "/"; } return $output; } if($DEBUG){ echo "<PRE>"; print_r($_SERVER); echo "RELATIVE_PATH: $RELATIVE_PATH<BR>"; echo "ABSOLUTE_PATH: $ABSOLUTE_PATH<BR>"; echo "REAL: " . realpath($ABSOLUTE_PATH) . "<BR>"; } # handle 404s and prevent escaping doc_root if(!file_exists($ABSOLUTE_PATH) || strpos($ABSOLUTE_PATH, $BASE_DIR) === FALSE){ $ERROR_PATH = $RELATIVE_PATH; $RELATIVE_PATH = DIRECTORY_SEPARATOR; $ABSOLUTE_PATH = $BASE_DIR . $RELATIVE_PATH; http_response_code(404); } if($DEBUG){ echo "RELATIVE_PATH: $RELATIVE_PATH<BR>"; echo "ABSOLUTE_PATH: $ABSOLUTE_PATH<BR>"; echo "REAL: " . realpath($ABSOLUTE_PATH) . "<BR>"; } if(!is_dir($ABSOLUTE_PATH)) { if(@$_GET['dl']) { header('Content-Disposition: attachment; filename="'. basename($ABSOLUTE_PATH) .'"'); $mime = "application/octet-stream"; } else { $mime = mime_content_type($ABSOLUTE_PATH); } header('Content-type: ' . $mime); readfile($ABSOLUTE_PATH); return true; } else if($RELATIVE_PATH != "" && $RELATIVE_PATH[strlen($RELATIVE_PATH)-1] != DIRECTORY_SEPARATOR){ $RELATIVE_PATH .= DIRECTORY_SEPARATOR; $ABSOLUTE_PATH = $BASE_DIR . $RELATIVE_PATH; } $FOLDER_PATH = $RELATIVE_PATH; if(is_dir($ABSOLUTE_PATH)) $PARENT_FOLDER_PATH = $FOLDER_PATH; else $PARENT_FOLDER_PATH = dirname($FOLDER_PATH); $PARENT_FOLDER_PATH_PARTS = getParents($FOLDER_PATH); if($DEBUG){ echo "PARENT_FOLDER_PATH: $PARENT_FOLDER_PATH<BR>"; echo "PARENT_FOLDER_PATH_PARTS: " . print_r($PARENT_FOLDER_PATH_PARTS, true) . "<BR>"; } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Simple PHP Server</title> </head> <body> <h2>Directory listing for <?php echo $FOLDER_PATH; ?></h2> <HR> <?php if($ERROR_PATH) : ?> <h3><?php echo $ERROR_PATH; ?> does not exist</h3> <?php endif ?> <ul> <?php // order alphabetically but folders first $folders = []; $files = []; foreach (scandir($ABSOLUTE_PATH) as $file) { if(is_dir($ABSOLUTE_PATH . DIRECTORY_SEPARATOR . $file)){ $folders[] = $file; } else { $files[] = $file; } } foreach (array_merge($folders,$files) as $file) { $file_path = $RELATIVE_PATH . $file; $absolute_file_path = realpath($BASE_DIR . $file_path); $display_name = htmlentities($file); if(is_dir($absolute_file_path)) { if($file == ".") continue; if($file == "..") $file_path = $PARENT_FOLDER_PATH; } $url = "/" . urlencodePaths($PARENT_FOLDER_PATH_PARTS) . urlencode($file); if(is_dir($absolute_file_path)){ echo "<li><a href='$url'>" . $display_name . "</a>"; } else { echo "<li>[<a href='$url?dl=1'>Download</a>] <a href='$url'>" . $display_name . "</a>"; } if($DEBUG){ echo " || file: $file <BR>"; echo " || display_name: $display_name <BR>"; echo " || RELATIVE_PATH: $RELATIVE_PATH <BR>"; echo " || file_path: $file_path <BR>"; echo " || url: $url<BR>"; echo " || urlencode(parents): " . urlencodePaths($PARENT_FOLDER_PATH_PARTS) . " <BR>"; echo " || urlencode(file): " . urlencode($file) . " <BR>"; echo " || parent: " . print_r($PARENT_FOLDER_PATH_PARTS, true). " </li>"; } } ?> </ul> <HR> </body> </html>