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, 08: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.170   Beiträge: 432.150   Mitglieder: 29.549   Aktive Mitglieder: 45
        Willkommen an unser neuestes Mitglied, [email protected].

        Online-Benutzer

        Einklappen

        273 Benutzer sind jetzt online. Registrierte Benutzer: 2, Gäste: 271.

        Mit 4.707 Benutzern waren am 12.01.2023 um 04:07 die meisten Benutzer gleichzeitig online.

        Die neuesten Themen

        Einklappen

        Die neuesten Beiträge

        Einklappen

        • daniel5959
          Antwort auf Otmar
          Hallo,

          habe das Programm HomepageFIX 2020 nicht, aber wie bei allen Programmen zum Erstellungen von Webseiten müssen die FTP-Angaben stimmen, damit das Programm die Dateien auch auf den Webspace hochladen kann.

          Dafür müsste man wissen beim welchem Provider der Webspace ist,...
          Heute, 16:35
        • Otmar.spiss@gmail.com
          Otmar
          Ich kann HomepageFIX 2020, nicht veröffentlichen. Von seiten des Providers ist angeblich alles in Ordnung. Wer hat Erfahrung mit diesem Problem?
          Heute, 11:24
        • bdt600
          Antwort auf Otmar
          Ich würde mir an deiner Stelle nicht allzu große Hoffnungen machen, dass du hier Hilfe zu HomepageFIX 2020 bekommen wirst. Solche WYSIWYG-Editoren sind bei Leuten mit Ahnung meist verpönt, weil der HTML-Code, der am Ende raus kommt, (vorsichtig gesagt) nicht so dolle ist.
          Heute, 14:22
        • admin
          Antwort auf Mail-Authentifizierung
          Hallo Localfu,

          voll krass, zum Glück haben wir noch uralte Verträge... Aber da wird es in Zukunft für eine Firma ja richtig teuer, wenn Sie alle Mitarbeiter mit E-Mail-Adressen versorgen will.

          Wir arbeiten uns aktuell an die Lösung heran, ein User hier aus dem Forum hat...
          Heute, 12:17
        • admin
          Mail-Authentifizierung
          Hallo,

          wir haben heute das erste Mal das Erlebnis gehabt, dass eine Firmenmail nicht zu einer Kundenadresse durchgekommen ist.

          Die Empfänger-Adresse ist eine [email protected] Adresse, und Googlemail blockt wohl seit November 2022 nicht authentifizierte Domains.

          Hier...
          02.02.2023, 13:04
        • Localfu
          Antwort auf Mail-Authentifizierung
          Hi admin,
          bei IONOS gibt es Seit Ende 2022 Einschränkungen bei der Vergabe von E-Mails. Neue Standardverträge lassen nur eine E-Mailadresse zu(Jede weitere Adresse kostet mehr). Das ist bei den alten Verträgen noch vermeidbar.

          Das ander Problem ist die Nutzung von E-Mailadressen...
          Heute, 01:09
        • arnego2
          Antwort auf Lebensmittelpreise - die x-te Version
          Tja da seit ihr gut dran, bei uns kommen 200Gr Butter auf ungefähr 6$. Da wir Butter nicht so häufig nutzen so 2 pro Jahr macht den Kohl nicht fetter....
          Gestern, 21:38
        • bodan
          KeePass - Password-Manager :: welche Addons /Plugins verwendet ihr!?
          Hallo u. guten Abend liebe Community

          welche Keepass-Addons /Plugins verwendet ihr!?

          Es gibt ja sehr viele Plugnis / Addons die die Funktionalitäten erweitern: welche verwendet ihr denn!?

          Plugins für KeePass (hier eine Übersicht: https://keepass.info/plugins.h...
          24.01.2023, 23:58
        • eloms
          Antwort auf KeePass - Password-Manager :: welche Addons /Plugins verwendet ihr!?
          Hallo

          Doch, kann man.
          Ich verwende einen anderen PWM und der kennt nur einen Teil des PW und somit kann damit keiner etwas anfangen.
          Und für wichtige Seite wie Banking oder Paypal verwende ich eine Authenticator App. Und die kann man nicht auslesen weil sie auf einem anderen...
          Gestern, 20:00
        • daniel5959
          Antwort auf Lebensmittelpreise - die x-te Version
          Hallo,

          auch sonst ist vieles immer noch günstig bzw. wir wieder günstiger.

          A) Einige Artikel (Eigenmarken) - Auszug aus meinem letzten Netto-Kassenzettel:

          Scheuermilch (Reinigungsmittel) 750 ml für 0,89 Euro
          Handcreme (Öko-Test "Sehr Gut") 125...
          03.02.2023, 21:52
        Lädt...
        X