Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- # Filename: localhost.py
- # Version: 1.0.2
- # Author: Jeoi Reqi
- """
- This script implements a simple HTTP server that serves files from the current directory and provides a directory listing API.
- It also includes functionality to terminate any process using a specified port, in this case, port 8080.
- Functions:
- - Serv(BaseHTTPRequestHandler):
- Defines a custom handler for handling HTTP requests.
- - list_files(self):
- Lists all files in the current directory.
- - do_GET(self):
- Handles GET requests, serving files or providing a directory listing based on the requested path.
- - line():
- Prints a line of underscores for formatting.
- - get_pid_on_port(port):
- Retrieves the process ID (PID) of any process using a specified port.
- - kill_process(pid):
- Terminates a process with a specified PID.
- - run_server():
- Starts the HTTP server.
- - shutdown_server(server_thread):
- Shuts down the HTTP server.
- Requirements:
- - Python 3.x
- - colorama library (for colored output)
- Usage:
- - Run the script. It will start an HTTP server listening on port 8080.
- - Access http://localhost:8080/ in a web browser to view the directory listing.
- - Access http://localhost:8080/api/directory to retrieve a JSON response containing the directory listing.
- - Press Ctrl+C to interrupt the script and stop the server.
- - After interrupting the script, it will attempt to terminate any process using port 8080.
- Additional Notes:
- - This script is intended for educational purposes and may require modifications for production use.
- - Ensure that no other process is using port 8080 before running the script.
- - Colorama library is used to print colored output for better visualization.
- """
- # Get Essential Imports
- from http.server import HTTPServer, BaseHTTPRequestHandler
- import os
- import subprocess
- import json
- import re
- import sys
- import threading
- from colorama import Fore, Style # For Colored Terminal Output
- # Print Header
- print("""
- █████╗ ██████╗ █████╗ ██████╗
- ██╔══██╗██╔═████╗██╔══██╗██╔═████╗
- ╚█████╔╝██║██╔██║╚█████╔╝██║██╔██║
- ██╔══██╗████╔╝██║██╔══██╗████╔╝██║
- ╚█████╔╝╚██████╔╝╚█████╔╝╚██████╔╝
- ╚════╝ ╚═════╝ ╚════╝ ╚═════╝
- """)
- # Class for custom HTTP request handler
- class Serv(BaseHTTPRequestHandler):
- """
- Custom HTTP request handler.
- """
- def list_files(self):
- """
- Lists all files in the current directory.
- Returns:
- list: A list of dictionaries containing file information.
- """
- files = os.listdir(".")
- file_list = []
- for file in files:
- file_info = {}
- if os.path.isfile(file):
- file_info["name"] = file
- file_info["path"] = file
- elif os.path.isdir(file):
- file_info["name"] = file + "/"
- file_info["path"] = file + "/"
- file_list.append(file_info)
- return file_list
- def do_GET(self):
- """
- Handles GET requests.
- If the path is '/', it serves an HTML page with a directory listing.
- If the path is '/api/directory', it provides a JSON response with the directory listing.
- Otherwise, it attempts to serve the requested file.
- """
- print("Request received for:", self.path)
- if self.path == "/":
- index_html = """
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Directory Listing</title>
- </head>
- <body>
- <h1>Directory Listing</h1>
- <ul id="fileList">
- <!-- File and directory list will be generated here -->
- </ul>
- <script>
- // Fetch directory listing
- fetch('/api/directory')
- .then(response => response.json())
- .then(data => {
- const fileList = document.getElementById('fileList');
- data.forEach(item => {
- const listItem = document.createElement('li');
- const link = document.createElement('a');
- link.textContent = item.name;
- link.href = item.path;
- listItem.appendChild(link);
- fileList.appendChild(listItem);
- });
- })
- .catch(error => {
- console.error('Error fetching directory listing:', error);
- });
- </script>
- </body>
- </html>
- """
- self.send_response(200)
- self.send_header("Content-type", "text/html")
- self.end_headers()
- self.wfile.write(index_html.encode())
- elif self.path == "/api/directory":
- file_list = self.list_files()
- self.send_response(200)
- self.send_header("Content-type", "application/json")
- self.end_headers()
- self.wfile.write(json.dumps(file_list).encode())
- else:
- try:
- file_to_open = open(self.path[1:], "rb").read()
- self.send_response(200)
- self.end_headers()
- self.wfile.write(file_to_open)
- except FileNotFoundError:
- file_to_open = b"File not found"
- self.send_response(404)
- self.end_headers()
- self.wfile.write(file_to_open)
- # Function to draw divider lines
- def line():
- print("_" * 70 + "\n")
- # Function to get port PIDs
- def get_pid_on_port(port):
- result = subprocess.run(["netstat", "-ano"], capture_output=True, text=True)
- lines = result.stdout.splitlines()
- port_re = re.compile(rf"TCP\s+\S+:{port}\s+\S+\s+LISTENING\s+(\d+)")
- for line in lines:
- match = port_re.search(line)
- if match:
- return match.group(1)
- return None
- # Function to kill all proceses on given port (8080)
- def kill_process(pid):
- subprocess.run(["taskkill", "/F", "/PID", pid])
- # Run the localhost:8080 server
- def run_server():
- httpd = HTTPServer(("localhost", 8080), Serv)
- print("Server started on http://localhost:8080/\n")
- httpd.serve_forever()
- httpd.server_close()
- # Shut down the localhost:8080 server
- def shutdown_server(server_thread):
- print("\n\t Shutting down server... Server shutdown complete!")
- server_thread.join()
- sys.stdout.flush()
- if __name__ == "__main__":
- server_thread = threading.Thread(target=run_server)
- server_thread.start()
- try:
- while server_thread.is_alive():
- server_thread.join(1)
- sys.stdout.flush()
- except KeyboardInterrupt:
- line()
- print("\t\t Keyboard interrupt received!")
- sys.stdout.flush()
- shutdown_server(server_thread)
- # Ensure any process using port 8080 is terminated
- pid = get_pid_on_port(8080)
- if pid:
- print(
- f"\n\t - {Fore.RED}Terminating process {pid} using port 8080{Style.RESET_ALL} -\n\n\tVerify cleanup completed with the terminal command:\n\n\t\t {Fore.GREEN}!netstat -ano | findstr :8080{Style.RESET_ALL}"
- )
- line()
- sys.stdout.flush()
- kill_process(pid)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement