Ankündigung

Einklappen
Keine Ankündigung bisher.

[Tutorial | PHP Sockets] Ein OOP HTTP-Proxy Server

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [Tutorial | PHP Sockets] Ein OOP HTTP-Proxy Server

    nachdem ich mich jetzt mal ein bisschen mit PHP und Sockets beschäftigt habe, will ich meine erkenntnisse doch mal "unters volk bringen".

    nachfolgendes script stellt einen proxy server da. dieser server hört auf anfragen auf einer ihm genannten adresse und port.
    wie gesagt, es ist ein HTTP-Server, das heißt er wertet anfragen eines clients (ein programm das ihn über die adresse und port kontaktiert) als HTTP-Header und versucht eine anfrage an die spezifizierte seite durchzuführen. damit das funktioniert, muss im browser als proxy folgendes eingetragen werden (dies sind die standard einstellungen des scripts):

    Adresse: 127.0.0.1
    Port: 3124
    (proxy einrichten für versch. browser bzw. proxy einrichten für verschiedene browser2

    anschließend muss der server aufgerufen werden. am besten tut ihr dies über die kommandozeile, hier ein kleines batchscript für windows:

    Code:
    start c:\pfad\zu\php.exe c:\pfad\zum\serverscript.php
    dazu legt ihr eine leere textdatei an, kopiert das darein, passt die pfade an, und benennt das ganze in "proxy.bat" um. doppelklick drauf und fertig. nun wartet der server auf anfragen des browser. erfolgt eine anfrage, gibt er die anfrage header aus und gibt die internetseite (wenn vorhanden) zurück.

    so aber nun zum script (warnung beachten!)

    WICHTIG: der server läuft in einer ENDLOSSCHLEIFE (er hört nie auf)! also muss er von hand beendet werden!

    PHP-Code:
    <?php

    error_reporting
    (E_ALL|E_STRICT);
    set_time_limit(0);
    ob_implicit_flush();

    $socket=new socket('127.0.0.1',3124);

    try
    {
        
    $socket->persistent();
    }
    catch(
    Exception $e)
    {
        echo 
    $e->getMessage();
    }

    class 
    socket
    {
        public 
    $address;
        public 
    $port;

        private 
    $socket;
        private 
    $socket_bind;
        private 
    $socket_listen;

        private 
    $socket_connection;

        private 
    $url='www.google.de';
        private 
    $request_headers;

        public function 
    __construct($adress,$port)
        {
            
    $this->address=$adress;
            
    $this->port=$port;
        }

        public function 
    create_bind_listen()
        {
            
    $this->socket=socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
            if(
    $this->socket===FALSE)
            {
                throw new 
    Exception('socket_create '.socket_strerror(socket_last_error()),socket_last_error());
                return 
    FALSE;
            }
                
            
    socket_set_option($this->socket,SOL_SOCKET,SO_REUSEADDR,1);

            
    $this->socket_bind=socket_bind($this->socket,$this->address,$this->port);
            if(
    $this->socket_bind===FALSE)
            {
                throw new 
    Exception('socket_bind '.socket_strerror(socket_last_error()),socket_last_error());
                return 
    FALSE;
            }

            
    $this->socket_listen=socket_listen($this->socket,5);
            if(
    $this->socket_listen===FALSE)
            {
                throw new 
    Exception('socket_listen '.socket_strerror(socket_last_error()),socket_last_error());
                return 
    FALSE;
            }
        }

        public function 
    persistent()
        {
            
    $this->create_bind_listen();

            echo 
    'Erwarte Verbindung'."\n";

            do
            {
                
    $this->socket_connection=socket_accept($this->socket);
                if(
    $this->socket_connection===FALSE)
                {
                    throw new 
    Exception('socket_accept '.socket_strerror(socket_last_error()),socket_last_error());
                    break;
                }

                
    socket_set_option($this->socket,SOL_SOCKET,SO_KEEPALIVE,1);

                if(
    FALSE===($this->request_headers=socket_read($this->socket_connection,10000,PHP_BINARY_READ)))
                {
                    throw new 
    Exception('socket_read '.socket_strerror(socket_last_error()),socket_last_error());
                    break 
    2;
                }

                echo 
    $this->request_headers;

                
    $this->parse_headers($this->request_headers);

                
    $this->make_request($this->url);

                
    socket_close($this->socket_connection);
            }
            while(
    TRUE);
        }

        public function 
    parse_headers($headers)
        {
            
    $headers=explode("\n",$headers);
            
    $this->url=array_shift($headers);
            
    $this->url=explode(' ',$this->url);
            
    $this->url=$this->url[1];
        }

        public function 
    make_request($url)
        {
            
    $url=trim($url);
            
    $page='';
            if(
    substr($url,0,7)!=='http://'$url='http://'.$url;

            
    $internet_connection=fopen($url,'r'); //fsockopen($url,80,$errno,$errstr,30);

            
    if($internet_connection===FALSE$page='HTTP Status Code: HTTP/1.1 404 Not found';
            else
            {
                
    stream_set_blocking($internet_connection,0);
                
    fwrite($internet_connection,$this->request_headers);
                
    usleep(1000);
                while(!
    feof($internet_connection))
                {
                    
    $page.=fgets($internet_connection,8192);
                }
                
    fclose($internet_connection);
            }

            
    socket_write($this->socket_connection,$page,strlen($page));
        }

        public function 
    __destruct()
        {
            @
    socket_close($this->socket_connection);
            @
    socket_close($this->socket);
        }    
    }

    ?>
    da das ganze als tutorial geplant ist, werd ich morgen noch eine dokumentation posten....

    gruß
    AC/DC Fanpage www.ifyouwantblood.de
    Nein zur Zensur im Internet und anderswo - Anonymous

  • #2
    AW: [Tutorial | PHP Sockets] Ein OOP HTTP-Proxy Server

    also fangen wir mal an....

    socket::__construct()

    der constructor. weist nur adresse und port zu, auf denen gehört wird.

    socket::create_bind_listen()

    PHP-Code:
            $this->socket=socket_create(AF_INET,SOCK_STREAM,SOL_TCP); 
    create_bind_listen() versucht zunächst einen unbestimmten socket zu der protokollfamilie AF_INET zu erstellen erstellen. die grundlage der protokollfamilie AF_INET sind IPv4 internetadressen. anschließend wird der sockettyp bestimmt, wir legen ihn auf SOCK_STREAM fest, da dies der übliche weg für TCP verbindungen sind. zum schluss bestimmen wir noch den protokolltyp mit SOL_TCP und legen uns somit auf das im Internet benutzte protokoll TCP fest.

    PHP-Code:
    $this->socket_bind=socket_bind($this->socket,$this->address,$this->port); 
    nun binden wir das script an die adresse und den port. binden bedeutet, dass das betriebssystem jede anfrage an diese adresse über diesen port an unser script weiterleitet. bindungen sind einzigartig, das heißt sie können das script zwar 2 mal starten, dennoch wird jede anfrage nur an das script, welches zuerst gestartet wurde, weitergeleitet.

    PHP-Code:
     $this->socket_listen=socket_listen($this->socket,5); 
    zum schluss sagen wir php noch, dass es verbindungen an diesen port annehmen soll (hier mit der limitierung von maximal 5 gleichzeitigen verbindungen)


    so morgen gehts weiter, bin jetzt zu müde....


    Edit (autom. Beitragszusammenführung):

    soooo...

    socket :: persistent()

    ist die funktion die unendlich lange läuft und anfragen beantwortet.

    zunächst rufen wir socket::create_bind_listen() auf, die uns eine Verbindung bereitsstellt.

    PHP-Code:
    $this->create_bind_listen(); 
    anschließend fängt die do-while schleife an.

    das erste was wir tun, ist der variablen $this->socket_connection() eine verbindung mittels der funktion socket_accept() zuzuweisen. diese funktion ist besonders. sie hält das script hier solange an, bis eine verbindung zustande gekommen ist.

    PHP-Code:
    $this->socket_connection=socket_accept($this->socket); 
    nachdem wir erfolgreich eine verbindung aufgebaut haben, stellen wir diese verbindung auf KEEPALIVE ein um ein abbrechen der verbindung sofort zu bemerken (also z.b. wenn der nutzer auf abbrechen drückt).

    PHP-Code:
    socket_set_option($this->socket,SOL_SOCKET,SO_KEEPALIVE,1); 
    anschließend lesen wir ~10kb der verbindung aus mittels socket_read() aus. was uns der browser hier sendet sind HTTP-REQUEST-HEADER.

    PHP-Code:
    if(FALSE===($this->request_headers=socket_read($this->socket_connection,10000,PHP_BINARY_READ))) 

                    throw new 
    Exception('socket_read '.socket_strerror(socket_last_error()),socket_last_error()); 
                    break 
    2

    anschließend geben wir, rein für uns, diese header aus

    PHP-Code:
    echo $this->request_headers
    aus diesen request_headern lesen wir jetzt mittels $this->parse_headers() die angeforderte url aus.

    PHP-Code:
    $this->parse_headers($this->request_headers); 
    ist dies erfolt, machen wir mittels $this->make_request() einen HTTP request an die angeforderte seite.

    PHP-Code:
    $this->make_request($this->url); 
    und noch die verbindung schließen.

    PHP-Code:
    socket_close($this->socket_connection); 
    socket :: parse_headers($header)

    diese funktion liest aus der ersten zeile von $header die angeforderte url aus und speichert diese in $this->url

    socket :: make_request($url)

    diese funktion führt einen HTTP-REQUEST an $this->url aus.

    zunächst bauen wir eine verbindung auf:

    PHP-Code:
    $internet_connection=fopen($url,'r'); 
    ist diese geglückt, senden wir mittels fwrite() $this->request_headers und lesen die antwort des servers in $page.

    PHP-Code:
    if($internet_connection===FALSE$page='HTTP Status Code: HTTP/1.1 404 Not found'
    else 

           
    stream_set_blocking($internet_connection,0); 
           
    fwrite($internet_connection,$this->request_headers); 
           
    usleep(1000); 
           while(!
    feof($internet_connection)) 
           { 
                 
    $page.=fgets($internet_connection,8192); 
           } 
           
    fclose($internet_connection); 

    jetzt senden wir $page an den browser....

    PHP-Code:
    socket_write($this->socket_connection,$page,strlen($page)); 
    socket :: __destruct()

    schließt noch offene sockets.
    Zuletzt geändert von Brian; 22.10.2007, 07:17. Grund: Antwort auf eigenen Beitrag innerhalb von 24 Stunden!
    AC/DC Fanpage www.ifyouwantblood.de
    Nein zur Zensur im Internet und anderswo - Anonymous

    Kommentar


    • #3
      AW: [Tutorial | PHP Sockets] Ein OOP HTTP-Proxy Server

      Code:
      ([  string $host = ini_get("mysqli.default_host")  [,  string $username = ini_get("mysqli.default_user")  [,  string $passwd = ini_get("mysqli.default_pw")  [,  string $dbname = ""  [,  int $port = ini_get("mysqli.default_port")  [,  string $socket = ini_get("mysqli.default_socket")  ]]]]]] )
      Kann entweder ein Hostname oder eine IP-Adresse. Vorbei an der NULL-Wert oder der String "localhost" auf diesem Parameter wird der lokale Host angenommen. Wenn möglich, werden Rohre verwendet statt des TCP / IP-Protokoll.

      Kommentar


      • #4
        AW: [Tutorial | PHP Sockets] Ein OOP HTTP-Proxy Server

        Wie sieht es mit mehreren gleichzeitigen Aufrufen aus?
        ... Meine Meinung

        Kommentar

        homepage-forum.de - Hilfe für Webmaster! Statistiken

        Einklappen

        Themen: 56.842   Beiträge: 430.466   Mitglieder: 28.593   Aktive Mitglieder: 49
        Willkommen an unser neuestes Mitglied, digital-mc.

        Online-Benutzer

        Einklappen

        285 Benutzer sind jetzt online. Registrierte Benutzer: 5, Gäste: 280.

        Mit 3.502 Benutzern waren am 23.01.2020 um 17:20 die meisten Benutzer gleichzeitig online.

        Die neuesten Themen

        Einklappen

        Die neuesten Beiträge

        Einklappen

        Lädt...
        X