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?

        Kommentar

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

        Einklappen

        Themen: 57.089   Beiträge: 432.164   Mitglieder: 29.279   Aktive Mitglieder: 38
        Willkommen an unser neuestes Mitglied, Grufty.

        Online-Benutzer

        Einklappen

        220 Benutzer sind jetzt online. Registrierte Benutzer: 3, Gäste: 217.

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

        Die neuesten Themen

        Einklappen

        • daniel5959
          Gaspreise - gut wer Energie auf Vorrat lagern kann
          Hallo,

          jetzt sind alle Leute gut dran, die ihre Heizenergie im eigenen Haus lagern können und schon im Frühjahr Heizöl bestellt haben, sie müssen sich keine Sorgen um die Gaspreissteigerungen der kommenden Monate machen.

          Bisher waren die Gaskunden gut dran, sie haben sich...
          24.06.2022, 01:37
        • Grufty
          Handydarstellung
          In der Handydarstellung meiner Homepage fehlt neuerdings das Menue. War bisher ok. Sonst alles ok.

          Problem durch sehr prompte Hilfe durch IN MEDIA gelöst!
          Es lag am COUNTER CODE.
          22.06.2022, 09:04
        • Sprueche
          LustigX.de - Lustige Bilder & witzige Memes
          Hallo liebe Leute,

          ich will Euch ein neues Projekt von mir vorstellen. Es handelt sich um "LustigX.de". Auf der Webseite werden von Mitgliedern "Lustiges/Witziges" gepostet. Du kannst gerne ein Teil der Community werden und selber "Lustiges/Witziges" posten....
          21.06.2022, 02:08
        • daniel5959
          Energiewende mit günstigem Ökostrom und Wärmepumpe
          Hallo,

          meine Berechnung für eine persönliche Energiewende.

          A) Grob geschätzt für mein kleines Häuschen rund 850 Liter Heizöl im langjährigen Mittel, das wären (Heizöl - Heizwert ca. 9,8 kWh pro Liter) 8.330 kWh und wenn ich diese Wärme mit einer Wärmepumpe und einer Jahresarbeitszahl
          ...
          18.06.2022, 02:45
        • rene_j
          Euere Meinung und Feedback zu meinem Projekt - van-reise.eu
          Um welches Thema geht es?
          Es geht primär um die Themen Reisen, Wandern, Geocaching, Trekking, Urban Exploration (Lost Places) und Übernachtungen im Freien (Wälder, Berge etc.) sowie Fahrzeug Anschaffung und Ausbau.

          Das Projekt steckt noch in Kinderschuhen.
          Die Social-Media-Kanäle...
          14.06.2022, 13:41

        Die neuesten Beiträge

        Einklappen

        • Sprueche
          Antwort auf SpruecheX.de - Sprüche, Zitate und Weisheiten
          Wegen Social-Media und SEO.

          Update: Neues Design ist online!...
          26.06.2022, 22:51
        • eloms
          Antwort auf Feedback zur Überarbeitung meiner Homepage
          Hallo

          So, ich habe diverse Ändeungen vorgenommen und ein Zufallsbild auf der Startseite eingefügt. Klickt man auf den Link, wird das ausgewählte Bild grün angezeigt.
          War für mich gar nicht so einfach da so umzusetzen.
          Langsam wird die Seite fertig.

          mfg
          ...
          26.06.2022, 05:47
        • daniel5959
          Gaspreise - gut wer Energie auf Vorrat lagern kann
          Hallo,

          jetzt sind alle Leute gut dran, die ihre Heizenergie im eigenen Haus lagern können und schon im Frühjahr Heizöl bestellt haben, sie müssen sich keine Sorgen um die Gaspreissteigerungen der kommenden Monate machen.

          Bisher waren die Gaskunden gut dran, sie haben sich...
          24.06.2022, 01:37
        • ST747
          Antwort auf Gaspreise - gut wer Energie auf Vorrat lagern kann
          hi,

          beim gas ist die lieferung derzeit gedrosselt, weil ein pumpe kaputt ist.

          deshalb werden auch die gasspeicher nicht so gefüllt, wie geplant.

          nach meinen informationen muss die pumpe von einer deutschen firma gewartet oder repariert werden. das geht aber nicht,...
          25.06.2022, 13:48
        • daniel5959
          Antwort auf Gaspreise - gut wer Energie auf Vorrat lagern kann
          Nachtrag 2:

          Frage: Wie weit würde man mit maximal 256 TWh (= max. 256 Mrd. kWh) Gas kommen?



          In den letzten 3 Monaten des Jahres - Oktober, November und Dezember - werden im Mittel 277 TWh an Gas verbraucht, d.h. die maximal gefüllten Gasspeicher wären am Jahresende...
          25.06.2022, 05:53
        • daniel5959
          Antwort auf Gaspreise - gut wer Energie auf Vorrat lagern kann
          Nachtrag:

          Deutschland hat genau genommen keinen Gasvorrat, sondern nur einen Gaspuffer, um die Spitzen im Winter abzupuffern.



          Also wenn die Erdgasspeicher ganz voll wären, dann würde es für 2 bis 3 Monate reichen, aber nur wenn in dieser Zeit weiterhin Gas...
          25.06.2022, 00:15
        • Grufty
          Handydarstellung
          In der Handydarstellung meiner Homepage fehlt neuerdings das Menue. War bisher ok. Sonst alles ok.

          Problem durch sehr prompte Hilfe durch IN MEDIA gelöst!
          Es lag am COUNTER CODE.
          22.06.2022, 09:04
        • Localfu
          Antwort auf Handydarstellung
          Hier eine Lösung von mir
          Code:
          var linkTitle = ['Startseite', 'Über mich', 'Aktuelles', 'Kontakt', 'Impressum'];
          var linkURL = ['home.html', 'about.html', 'news.html', 'contact.html', 'impressum.html'];
          var topnav;
          document.addEventListener('DOMContentLoaded', ()=> {
          ...
          24.06.2022, 16:16
        • Localfu
          Antwort auf Handydarstellung
          Hallo Grufty,
          leider ist dein JavaScript-Code fehlerhaft und weisst viele Fehler auf:
          Code:
          jQuery.noConflict()(function($){$("<form id='mobilemenu' class='right2'><select /></form>").appendTo("#topnav"),$("<option />",{selected:"selected",value:"",value:"",text:"F"
          ...
          24.06.2022, 15:22
        • daniel5959
          Antwort auf SpruecheX.de - Sprüche, Zitate und Weisheiten
          Hallo,

          mich ärgern immer noch die aufs Foto geklatschten Texte.

          Warum wird nicht einfach nur ein unifarbener Hintergrund verwendet, wenn das Foto eh nicht so wichtig ist?

          Den Text könnte man besser ins Foto einbauen, siehe Beispiel



          ...
          23.06.2022, 22:58
        Lädt...
        X