pollux/tests/gemini_test_client.py
Jeena 0459cb6220 feat: Implement virtual hosting for multi-domain Gemini server
- Add hostname-based request routing for multiple capsules per server
- Parse virtual host configs from TOML sections ([hostname])
- Implement per-host certificate and content isolation
- Add comprehensive virtual host testing and validation
- Update docs and examples for multi-host deployments

This enables Pollux to serve multiple Gemini domains from one instance,
providing the foundation for multi-tenant Gemini hosting.
2026-01-22 02:38:09 +00:00

86 lines
No EOL
2.7 KiB
Python
Executable file

#!/usr/bin/env python3
"""
Simple Gemini Test Client
Makes a single Gemini request and prints the status line.
Used by integration tests for rate limiting validation.
Usage: python3 tests/gemini_test_client.py gemini://host:port/path
"""
import os
import sys
import socket
import ssl
def main():
if len(sys.argv) != 2:
print("Usage: python3 gemini_test_client.py <gemini-url>", file=sys.stderr)
sys.exit(1)
url = sys.argv[1]
# Parse URL (basic parsing) - allow any protocol for testing
if url.startswith('gemini://'):
url_parts = url[9:].split('/', 1) # Remove gemini://
host = url_parts[0]
path = '/' + url_parts[1] if len(url_parts) > 1 else '/'
else:
# For non-gemini URLs, try to extract host anyway for testing
if '://' in url:
protocol, rest = url.split('://', 1)
url_parts = rest.split('/', 1)
host = url_parts[0]
path = '/' + url_parts[1] if len(url_parts) > 1 else '/'
else:
# No protocol, assume it's host/path
url_parts = url.split('/', 1)
host = url_parts[0]
path = '/' + url_parts[1] if len(url_parts) > 1 else '/'
# Get port from environment or use default
port = int(os.environ.get('GEMINI_PORT', '1965'))
# Allow overriding the connection host (useful for testing with localhost)
connect_host = os.environ.get('GEMINI_CONNECT_HOST', host)
try:
# Create SSL connection with permissive settings for self-signed certs
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
# Load default certificates to avoid some SSL issues
context.load_default_certs()
sock = socket.create_connection((connect_host, port), timeout=5.0)
ssl_sock = context.wrap_socket(sock, server_hostname=host)
# Send request (full URL for Gemini protocol over TLS)
request = f"{url}\r\n"
ssl_sock.send(request.encode('utf-8'))
# Read full response (header + body)
response = b''
while len(response) < 1024: # Read up to 1KB for test responses
try:
data = ssl_sock.recv(1024)
if not data:
break
response += data
except:
break
ssl_sock.close()
if response:
# Decode and return the full response
full_response = response.decode('utf-8', errors='ignore')
print(full_response.strip())
else:
print("Error: No response")
except Exception as e:
print(f"Error: {e}")
if __name__ == '__main__':
main()