import requests
import sys

# ==========================================
# CONFIGURATION
# ==========================================
TARGET_URL = "http://192.168.178.108:51051/upload" # <--- IP ANPASSEN
# ==========================================

def trigger_guaranteed_crash():
    """
    Scenario 1: RFC Compliant Upload (Short Boundary).
    
    We use a simple boundary like "myboundary".
    According to HTTP Standard (RFC), the body must start with "--myboundary".
    
    The B4A Server expects "------" (6 dashes).
    Since "--myboundary" only has 2 dashes, the server fails to find it.
    
    Result: CRASH (ArrayIndexOutOfBoundsException).
    """
    print(f"\n[!] 1. Sending VALID Upload with Short Boundary (Standard Compliant)...")
    print("    Boundary: 'myboundary'")
    print("    Body starts with: '--myboundary' (2 dashes)")
    print("    Expected Result: Server CRASH (because it expects 6 dashes).")
    
    boundary = "myboundary"
    
    # Manually build body to guarantee the exact format
    payload = (
        f"--{boundary}\r\n"
        f'Content-Disposition: form-data; name="file"; filename="crash.txt"\r\n'
        f"Content-Type: text/plain\r\n\r\n"
        f"This request is 100% valid HTTP standard, but it kills the server.\r\n"
        f"--{boundary}--\r\n"
    )
    
    headers = {"Content-Type": f"multipart/form-data; boundary={boundary}"}
    
    try:
        # Timeout set to 5s because server usually hangs/crashes immediately
        requests.post(TARGET_URL, data=payload, headers=headers, timeout=5)
        print("[-] Server replied (Unexpected - did it survive?)")
    except requests.exceptions.ReadTimeout:
        print("[+] SUCCESS: ReadTimeout. Server crashed or hung as expected.")
    except requests.exceptions.ConnectionError:
        print("[+] SUCCESS: ConnectionError. Server closed connection (Crash).")
    except Exception as e:
        print(f"[?] Error: {e}")

def upload_workaround():
    """
    Scenario 2: Workaround Upload (Long Boundary).
    
    We use a boundary that forces 6 dashes in the body.
    Boundary: "----WebKitFormBoundaryXYZ"
    Body starts with: "------WebKitFormBoundaryXYZ" (2 + 4 = 6 dashes)
    
    Result: SUCCESS.
    """
    print(f"\n[*] 2. Sending WORKAROUND Upload (Forced 6 dashes)...")
    print("    Boundary: '----WebKitFormBoundaryXYZ'")
    print("    Body starts with: '------WebKit...' (6 dashes)")
    print("    Expected Result: Success (200 OK).")
    
    boundary = "----WebKitFormBoundaryXYZ"
    
    payload = (
        f"--{boundary}\r\n"
        f'Content-Disposition: form-data; name="file"; filename="work.txt"\r\n'
        f"Content-Type: text/plain\r\n\r\n"
        f"This works because we trick the server with extra dashes.\r\n"
        f"--{boundary}--\r\n"
    )
    
    headers = {"Content-Type": f"multipart/form-data; boundary={boundary}"}
    
    try:
        r = requests.post(TARGET_URL, data=payload, headers=headers, timeout=10)
        print(f"[*] SUCCESS: Server responded with Code: {r.status_code}")
    except Exception as e:
        print(f"[!] FAILED: {e}")

def main():
    while True:
        print("\n" + "="*60)
        print(" B4A HttpServer Bug Reproducer (Deterministic)")
        print("="*60)
        print("1. CRASH the server (using valid HTTP standard)")
        print("2. SUCCESSFUL upload (using '------' workaround)")
        print("q. Quit")
        print("-" * 60)
        
        choice = input("Select option: ").strip().lower()
        
        if choice == '1':
            trigger_guaranteed_crash()
        elif choice == '2':
            upload_workaround()
        elif choice == 'q':
            sys.exit()
        else:
            print("Invalid selection.")
        
        input("\nPress Enter to continue...")

if __name__ == "__main__":
    main()