Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.5.0
current_version = 0.6.0
commit = True
tag = True

Expand Down
4 changes: 1 addition & 3 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
__pycache__/
*/__pycache__/

config/*.txt
config/*.json
logs/*.log

certs/*.key
certs/*.pem
!certs/ca/*

tests/
config.ini.example
config.yaml.example

.github
.bumpversion.cfg
Expand Down
4 changes: 0 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,6 @@ cython_debug/
# PyPI configuration file
.pypirc

# Config file
config/*
!config/*.example*

# Certs folder
certs/*.key
certs/*.pem
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ The proxy will be available at: `0.0.0.0:8080`.
The access log will be available at `./logs/access.log`.

## 📚 **Documentation**
If you encounter any problems, or if you want to use the program in a particular way, I advise you to read the [documentation](https://github.com/pyproxytools/pyproxy/wiki).
If you encounter any problems, or if you want to use the program in a particular way, I advise you to read the [documentation](https://pyproxytools.github.io/pyproxy-docs/).

## 🔧 **To do**

Expand Down
44 changes: 0 additions & 44 deletions config.ini.example

This file was deleted.

58 changes: 58 additions & 0 deletions config.yaml.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
server:
host: 0.0.0.0
port: 8080

logging:
debug: false
access_log: ./logs/access.log
block_log: ./logs/block.log
no_logging_access: false
no_logging_block: false
console_format: date=%(asctime)s level=%(levelname)s file=%(filename)s function=%(funcName)s message=%(message)s
access_log_format: date=%(asctime)s ip_src=%(ip_src)s url=%(url)s method=%(method)s domain=%(domain)s port=%(port)s protocol=%(protocol)s bytes_sent=%(bytes_sent)s bytes_received=%(bytes_received)s tls_version=%(tls_version)s
block_log_format: date=%(asctime)s ip_src=%(ip_src)s url=%(url)s method=%(method)s domain=%(domain)s port=%(port)s protocol=%(protocol)s
datefmt: '%Y-%m-%d %H:%M:%S'

files:
html_403: assets/403.html

filtering:
no_filter: false
filter_mode: local
blocked_sites:
- example.com
blocked_url:
- example2.com/about

options:
shortcuts:
f: https://facebook.com
gh: https://github.com
yt: https://youtube.com
custom_header:
"https://example.com":
X-Custom-Header: HeaderValue
X-Another-Header: AnotherValue
"https://example2.com":
X-Different-Header: DifferentValue
authorized_ips:
- 0.0.0.0/0
- 127.0.0.1/8
- 10.0.0.1/32

security:
ssl_inspect: false
inspect_ca_cert: certs/ca/cert.pem
inspect_ca_key: certs/ca/key.pem
inspect_certs_folder: certs/
cancel_inspect:
- mybank.com

monitoring:
flask_port: 5000
flask_pass: password

proxy:
proxy_enable: false
proxy_host: 127.0.0.1
proxy_port: 8081
3 changes: 0 additions & 3 deletions config/authorized_ips.example.txt

This file was deleted.

1 change: 0 additions & 1 deletion config/blocked_sites.example.txt

This file was deleted.

1 change: 0 additions & 1 deletion config/blocked_url.example.txt

This file was deleted.

1 change: 0 additions & 1 deletion config/cancel_inspect.example.txt

This file was deleted.

9 changes: 0 additions & 9 deletions config/custom_header.example.json

This file was deleted.

3 changes: 0 additions & 3 deletions config/shortcuts.example.txt

This file was deleted.

3 changes: 1 addition & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ services:
#volumes:
#- ./assets:/app/assets
#- ./certs/ca:/app/certs/ca
#- ./config:/app/config
#- ./logs:/app/logs
#- ./config.ini:/app/config.ini
#- ./config.yaml:/app/config.yaml
environment:
PYPROXY_HOST: 0.0.0.0
PYPROXY_PORT: 8080
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ classifiers = [
dynamic = ["version", "dependencies"]

[project.urls]
Documentation = "https://github.com/pyproxytools/pyproxy/wiki"
Documentation = "https://pyproxytools.github.io/pyproxy-docs/"
"Issue tracker" = "https://github.com/pyproxytools/pyproxy/issues"

[tool.setuptools.packages]
Expand Down
2 changes: 1 addition & 1 deletion pyproxy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import os

__version__ = "0.5.0"
__version__ = "0.6.0"

if os.path.isdir("pyproxy/monitoring"):
__slim__ = False
Expand Down
7 changes: 3 additions & 4 deletions pyproxy/handlers/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"""

import socket
import os
import threading
from urllib.parse import urlparse

Expand Down Expand Up @@ -77,7 +76,7 @@ def _apply_shortcut(self, url: str) -> str | None:
"""
Checks if a shortcut is defined for the given domain.
"""
if self.config_shortcuts and os.path.isfile(self.config_shortcuts):
if self.config_shortcuts:
parsed_url = urlparse(url)
domain = parsed_url.hostname
self.shortcuts_queue.put(domain)
Expand Down Expand Up @@ -142,7 +141,7 @@ def handle_http_request(self, client_socket, request):
first_line = request.decode(errors="ignore").split("\n")[0]
url = first_line.split(" ")[1]

if self.config_shortcuts and os.path.isfile(self.config_shortcuts):
if self.config_shortcuts:
shortcut_url = self._apply_shortcut(url)
if shortcut_url:
response = (
Expand All @@ -158,7 +157,7 @@ def handle_http_request(self, client_socket, request):
self._send_403(client_socket, url, first_line)
return

if self.config_custom_header and os.path.isfile(self.config_custom_header):
if self.config_custom_header:
request_text = request.decode(errors="ignore")
request_lines = request_text.split("\r\n")
headers = self._get_modified_headers(url, request_text)
Expand Down
11 changes: 8 additions & 3 deletions pyproxy/handlers/https.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
relay raw data when SSL inspection is disabled.
"""

import socket
import select
import os
import select
import socket
import ssl
import threading

Expand Down Expand Up @@ -377,7 +377,12 @@ def transfer_data_between_sockets(self, client_socket, server_socket):
and "target_ip" not in self.active_connections[thread_id]
):
try:
target_ip, target_port = server_socket.getpeername()
peer = server_socket.getpeername()
if len(peer) == 2:
target_ip, target_port = server_socket.getpeername()
else:
target_ip, target_port, *_ = server_socket.getpeername()

self.active_connections[thread_id]["target_ip"] = target_ip
self.active_connections[thread_id]["target_port"] = target_port
except OSError as e:
Expand Down
38 changes: 6 additions & 32 deletions pyproxy/modules/cancel_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,15 @@
pyproxy.modules.cancel_inspect.py

This module contains functions and a process to load and monitor cancel inspection entries.
It reads a file containing cancel inspection data and checks whether specific entries exist
in that file. The file is monitored in a background thread for live updates.
It uses cancel inspection data from the configuration and checks whether specific entries exist
in that list.

Functions:
- load_cancel_inspect: Loads the cancel inspection list from a file into a list.
- cancel_inspect_process: Process that listens for URL-like entries and checks
if they exist in the cancel inspection list.
"""

import multiprocessing
import time
import sys
import threading


def load_cancel_inspect(cancel_inspect_path: str) -> dict:
Expand All @@ -39,42 +35,20 @@ def load_cancel_inspect(cancel_inspect_path: str) -> dict:
def cancel_inspect_process(
queue: multiprocessing.Queue,
result_queue: multiprocessing.Queue,
cancel_inspect_path: str,
cancel_inspect: list[str],
) -> None:
"""
Process that monitors the cancel inspection file and checks if received entries exist in it.
Process that checks if received entries exist in the cancel inspection list.

Args:
queue (multiprocessing.Queue): A queue to receive entries to check.
result_queue (multiprocessing.Queue): A queue to send back True/False depending on match.
cancel_inspect_path (str): Path to the file containing cancel inspection entries.
cancel_inspect (list[str]): The list of cancel inspection entries.
"""
manager = multiprocessing.Manager()
cancel_inspect_data = manager.list(load_cancel_inspect(cancel_inspect_path))

error_event = threading.Event()

def file_monitor() -> None:
try:
while True:
new_cancel_inspect = load_cancel_inspect(cancel_inspect_path)
cancel_inspect_data[:] = new_cancel_inspect
time.sleep(5)
except (IOError, ValueError) as e:
print(f"File monitor error: {e}")
error_event.set()

monitor_thread = threading.Thread(target=file_monitor, daemon=True)
monitor_thread.start()

while True:
if error_event.is_set():
print("Error detected in file monitor thread, terminating process.")
sys.exit(1)

try:
url = queue.get()
if url in cancel_inspect_data:
if url in cancel_inspect:
result_queue.put(True)
else:
result_queue.put(False)
Expand Down
Loading
Loading