This project is a peer-to-peer (P2P) download accelerator that allows users to download files from each other, falling back to a direct download if no peers are available. It uses a combination of Python libraries including tkinter for the GUI, flask for peer communication, requests and aria2c for downloading, and sqlite3 for local file metadata storage.
- Peer-to-peer downloading: Downloads files from other peers if they have the requested file, reducing server load and potentially increasing download speeds.
- Direct download fallback: If no peers have the file, it downloads directly from the source URL using
aria2cfor optimized downloading. - GUI: A simple Tkinter GUI allows users to input download URLs and monitor the download process.
- Local caching: Downloaded files are cached locally, so subsequent requests for the same file can be served directly from the cache.
- Automatic peer discovery: Uses UDP broadcasting to discover other peers on the local network.
- Security: Basic security measures are in place, including shared secret validation for peer connections and path traversal prevention.
- Hash verification: Ensures the integrity of downloaded files by verifying SHA256 hashes.
- Python 3.7+
aria2cinstalled and available in your system's PATH.
-
Clone the repository:
git clone https://github.com/aeldi/p2p-download-accelerator.git cd p2p-download-accelerator -
Install the required Python packages:
pip install -r requirements.txt
-
Make sure
aria2cis installed.
APP_SECRET(Environment Variable): A shared secret used to authenticate peer connections. Set this to a strong, unique value. If not set, it defaults todefault-secret-123. It's highly recommended to set this environment variable.CACHE_DIR: The directory where downloaded files are stored (defaults to./cache).DB_PATH: The path to the SQLite database file (defaults tocache.db).BROADCAST_PORT: The UDP port used for peer discovery (defaults to 37020).HTTP_PORT: The port the Flask server listens on (defaults to 5000).- Other configurable parameters are available in
config.py.
- Run the
main.pyscript:python main.py
- The GUI will open. Enter the URL of the file you want to download and click "Start Download".
- The application will attempt to download the file from peers. If no peers are found, it will download directly from the URL.
- The downloaded file will be saved in the
CACHE_DIR.
main.py: The main entry point of the application. Starts the Flask server, initializes the database, and launches the GUI.gui.py: Contains the Tkinter GUI code.filemgr.py: Handles file downloading, including peer-to-peer and direct downloads, hash verification, and local caching.network.py: Manages peer discovery and communication.config.py: Stores configuration settings.database.py: Handles database interactions for storing file metadata.security.py: Provides security-related functions, such as peer validation and path traversal prevention.requirements.txt: Lists the required Python packages.
-
Peer Discovery:
- The
NetworkManagerclass uses UDP broadcasting to discover other peers on the local network. - Each instance sends periodic "HELLO" messages containing a shared secret.
- Peers listen for these messages and add valid senders to their peer list.
- A peer timeout mechanism removes inactive peers.
- The
-
Download Process:
- When a user initiates a download, the
download_filefunction infilemgr.pyis called. - First, it checks if the file is already available in the local cache (
get_local_file). - If not found locally, it queries known peers using the
/haveendpoint to see if they have the file. - If a peer responds positively, it attempts to download the file from that peer (
download_from_peer). This involves a request to the peer's/download/<guid>endpoint. The peer serves the file, and the downloader verifies the hash. - If no peers have the file, or if the peer download fails, it falls back to downloading directly from the original URL using
aria2c(download_from_internet). - After a successful download (from either a peer or the internet), the file's hash is calculated and verified. The file is then moved to its final location in the cache, and its metadata is stored in the database (
handle_download).
- When a user initiates a download, the
-
Flask Server:
- The Flask server (
main.py) handles two main endpoints:/have: Checks if the requested file is available locally and returns metadata (hash, GUID) if it is./download/<guid>: Serves a file from the cache based on a unique identifier (GUID). This endpoint includes security checks to prevent unauthorized access.
- The Flask server (
-
GUI:
- The
DownloadAppclass ingui.pyprovides a simple interface for users to enter URLs and start downloads. - It uses a background thread to perform the download, preventing the GUI from freezing.
- A queue is used to communicate between the download thread and the GUI thread, allowing for updates to the progress bar and status messages.
- The
-
Database:
- The
database.pyfile uses sqlite3 to store metadata about downloaded files. - This metadata includes the URL, filename, size, hash, and local path.
- The database is used to check if a file is already cached and to manage the cache.
- The