Skip to content

Instantly share code, notes, and snippets.

@thewheat
Last active July 13, 2024 14:53
Show Gist options
  • Save thewheat/f0d0a528aa36f6a3682b5c9bc76f0eca to your computer and use it in GitHub Desktop.
Save thewheat/f0d0a528aa36f6a3682b5c9bc76f0eca to your computer and use it in GitHub Desktop.
Simple HTTP server examples catered for accessing/sharing files via a web browser

Simple HTTP servers for file transfers

  • Examples of how to set up simple HTTP servers with different languages / libaries
  • Main use case is for
    • HTML pages
    • file transfers
  • Access via a browser with a format like http://your.ip.address.or.hostname.here:8080 (e.g. http://127.0.0.1:8080 / http://localhost:8080 / http://192.168.0.1:8080)
    • Local access IP: 127.0.0.1 / localhost
    • Remote access IP:
      • Some servers will show the IP address in the output
      • If not shown use OS specific commands/features to find appropriate IPs (ifconfig / ipconfig)
      • For remote access, the server must be started on an accessible address (i.e. not 127.0.0.1 / localhost)
  • Some may allow local development of the language but check for docs if it is possiible

Python

How to use

python3 -m http.server [--bind ADDRESS] [--directory DIRECTORY] [port]
python3 -m http.server --help

Example Usage

python3 -m http.server
python3 -m http.server --directory /var/www 8080

Example Output

  • Serves on all IP addresses
Serving HTTP on :: port 8000 (http://[::]:8000/) ...

Node

Installation

Installation optional when using npx (see exampel below)

npm install --global http-server

How to use

npx http-server [path] [options] # No install method

http-server [path] [options]
http-server --help

Example Usage

http-server
http-server /var/www -p 8080 -d true

Example output

Starting up http-server, serving ./

http-server version: 14.0.0

http-server settings: 
CORS: disabled
Cache: 3600 seconds
Connection Timeout: 120 seconds
Directory Listings: visible
AutoIndex: visible
Serve GZIP Files: false
Serve Brotli Files: false
Default File Extension: none

Available on:
  http://127.0.0.1:8080
  http://192.168.1.1:8080
  http://10.1.2.3:8080
Hit CTRL-C to stop the server

PHP

How to use

php [options] -S <addr>:<port> [-t docroot] [router]
php -S

Example Usage

php -S 0.0.0.0:8080    # this serves on all IP addresses
php -S localhost:8080  # only serve on localhost 
php -S localhost:8080 -t /var/www
php -S localhost:8080 -t /var/www router.php

Example Output

[Sun Dec 12 08:54:23 2021] PHP 8.0.12 Development Server (http://localhost:8080) started
<?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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment