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.933   Beiträge: 431.211   Mitglieder: 28.702   Aktive Mitglieder: 44
        Willkommen an unser neuestes Mitglied, sukhdevscatering.

        Online-Benutzer

        Einklappen

        208 Benutzer sind jetzt online. Registrierte Benutzer: 4, Gäste: 204.

        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

        • Megabyte
          mySQL ORDER BY mit Umlauten
          Wenn man auf meiner Seite bei der Auswahl 'Suche' die Kategorie 'Land' auswählt und dort nach 'Deutschland' sucht erfolgt eine Auflistung der Filme die mindestens einen Drehort in Deutschland hatten. So weit do gut...

          Wenn man nun bis ans Ende scrollt erscheint dort der Film "Zweiohrküken"...
          Heute, 00:50
        • arnego2
          Antwort auf mySQL ORDER BY mit Umlauten
          Wenn das alles so klappt warum ist dir die Ordnung so wichtig?
          Heute, 17:18
        • Megabyte
          Antwort auf mySQL ORDER BY mit Umlauten
          Hallo Sempervivum

          Danke für deinen Beitrag. Das wäre sicherlich ein begehbarer Weg. Fühlt sich aber immer noch irgendwie an wie "durch den Rücken in die Brust geschossen". Aber scheinbar lässt sich diese Aufgabe nicht mit einer einzigen Direktive elegant lösen. Wenn es daher...
          Heute, 16:38
        • Sempervivum
          Antwort auf mySQL ORDER BY mit Umlauten
          Wenn es nicht gerade hunderttausende von Datensätzen sind würde ich auf eine Sortierung mit PHP und einem Callback setzen, also usort. Dann kannst Du in der Vergleichsfunktion die Strings in eine Form bringen, die für den Vergleich geeignet ist und brauchst diese nirgends zu speichern, also die Redundanz...
          Heute, 16:18
        • Megabyte
          Antwort auf mySQL ORDER BY mit Umlauten
          Hallo arnego2

          Danke für die Rückmeldung, aber hilft hier nicht :-)

          Ich habe keinerlei Probleme mit der Darstellung von Umlauten. Alle Umlaute werden sowohl in phpMyAdmin als auch im Frontend exakt dargestellt. Dafür wurde mittels diversen utf-8 Direktiven gesorgt. Keine...
          Heute, 15:53
        • arnego2
          Antwort auf mySQL ORDER BY mit Umlauten
          Bei mir hat die .my.cnf Methode funktioniert.

          https://stackoverflow.com/questions/...sql-phpmyadmin
          Heute, 14:41
        • Dekson
          Antwort auf Neuer Drucker?
          Morgen

          Hattest du dich denn entschieden zu einem Drucker?
          Ich muss ja sagen, dass es wirklich unterschiedliche Hersteller und Modelle gibt, man sollte einfach schauen, welchen man gebrauchen kann bzw. welcher die Voraussetzungen erfüllt.
          Ich zum Beispiel habe mich nach Zubehör...
          Heute, 05:58
        • Megabyte
          Antwort auf Bitcoin-Board.de - Deutschsprachiges Bitcoin & Altcoin Forum
          Ich mag Bitcoins ebenso wenig. Bitcoins öffnen dubiosen Machenschaften Tür und Tor. Außerdem sind wegen dem Schrott gute Grafikkarten exorbitant teuer geworden bzw. gar nicht mehr erhältlich :-)
          Gestern, 22:09
        • Megabyte
          Antwort auf HomeOffice
          Bin bei Localfu (auch aus Erfahrung)

          Die zu erwartende Arbeitsergebnisse sind vorab klar festzuhalten und mit einer realistischen Zeitschiene zu versehen. Wenn z.B. ein Konstrukteur zu Hause an einem CAD-System ein Bauteil entwickeln soll so erwartet man dann Ergebnisse in 14 Tage (Beispiel...
          Gestern, 22:00
        • Nightland Driver
          Mysql id anhand des nutzers auslesen und nächste/letzte erhalten?
          Hey, ich habe ein kleines Logik Problem und wollte mal fragen ob mir jemand dabei helfen kann.

          Ich mag aus meiner Datenbank eine Nachricht auslesen. Diese hat folgende werte [id, user_id, text].
          Nun rufe ich anhand der id [5] die nachricht von dem Benutzer [2] auf. Dieser Benutzer...
          23.09.2021, 17:00
        Lädt...
        X