<?php
  class http_wrapper {
    public $referer;
    public $cookies;
    private $method;
    private $parameters;
    private $header_global;
    private $header_temp;
    
    /*
     * Klasse initialisieren
     * 
     * Initialisiert eine neue Klasse.
     * Wenn angegeben werden die Cookies aus $cookies übernommen.
     * 
     * @param array Ein Array mit Cookies z.B.: array("foo"=>"bar","cookie"=>"value") 
     */
    function __construct($cookies) {
      $this->method = "GET";
      $this->parameters = array();
      $this->header_global = array();
      $this->header_temp = array();
      $this->cookies = ($cookies ? $cookies : array());
    }
  
    /*
     * AddCookie($name, $value)
     * 
     * Für alle zukünftigen Requests mit dieser instanz $headerline
     * zum Header hinzufügen.
     * z.B.: $http_wrapper->AddHeader("Accept-Encoding: deflate");
     * 
     * @param string      Name des Cookies
     * @param string/int  Wert des Cookies
     */
    public function AddCookie($name, $value) {
      $this->cookies[$name] = $value;
      return true;
    }
  
    /*
     * AddHeader($headerline)
     * 
     * Für alle zukünftigen Requests mit dieser instanz $headerline
     * zum Header hinzufügen.
     * z.B.: $http_wrapper->AddHeader("Accept-Encoding: deflate");
     * 
     * @param string  Zusätzliche Zeile für den HTTP Request-Header
     */
    public function AddHeader($headerline) {
      $this->header_global[] = $headerline;
      return true;
    }
    
    /*
     * AddHeaderOnce($headerline)
     * 
     * Für den nächsten Request $headerline zum Header hinzufügen.
     * z.B.: $http_wrapper->AddHeader("Accept-Encoding: deflate");
     * 
     * @param string  Zusätzliche Zeile für den HTTP Request-Header
     */
    public function AddHeaderOnce($headerline) {
      $this->header_temp[] = $headerline;
      return true;
    }
    
    /*
     * AddParameter($parameter, $value)
     * 
     * Fügt einen Parameter hinzu der beim nächsten Request per
     * POST oder GET übergeben wird.
     * 
     * @param string      Name des Parameters
     * @param string/int  Wert des Parameters
     */
    public function AddParameter($parameter, $value) {
      $this->parameters[$parameter] = $value;
      return true;
    }
    
    /*
     * AddParameters($parameters)
     * 
     * Fügt einen Parameter hinzu der beim nächsten Request per
     * POST oder GET übergeben wird.
     * 
     * @param array  Ein Array mit Parametern z.B.: array("foo"=>"bar","param"=>"value") 
     */
    public function AddParameters($parameters) { 
      if (!$this->parameters) {
        $this->parameters = $parameters;
        return true;
      }
      if ($this->parameters = array_merge($parameters, $this->parameters))       
        return true;
      return false;
    }
    
    /*
     * ClearCookies()
     * 
     * Löscht alle in dieser Instanz der Klasse gesetzen Cookies. 
     */
    public function ClearCookies() { 
      $this->cookies = array();             
      return true;
    }
    
    /*
     * ClearParameters()
     * 
     * Löscht alle in dieser Instanz der Klasse gesetzen Parameter. 
     */
    public function ClearParameters() { 
      $this->parameters = array();             
      return true;
    }
    
    /*
     * ClearTempHeader()
     * 
     * Löscht alle in dieser Instanz der Klasse gesetzen temporären Header-Zeilen. 
     */
    public function ClearTempHeader() { 
      $this->header_temp = array();             
      return true;
    }
    
    /*
     * ClearHeader()
     * 
     * Löscht alle in dieser Instanz der Klasse gesetzen Header-Zeilen. 
     */
    public function ClearHeader() { 
      $this->header_global = array();             
      return true;
    }
    
    /*
     * ClearHeader()
     * 
     * Löscht alle in dieser Instanz der Klasse gesetzen Header-Zeilen. 
     * Sowohl temporäre als auch dauerhafte.
     */
    public function ClearAllHeader() { 
      $this->header_temp = array();   
      $this->header_global = array();             
      return true;
    }
    
    /*
     * SetMethod($method)
     * 
     * Festlegen ob Requests als GET oder POST abgeschickt werden
     * 
     * @param string  "GET" oder "POST"
     */
    public function SetMethod($method) {
      switch(strtoupper($method)) {
        Case "POST":
          $this->method = "POST";
          return true;
        Case "GET":
          $this->method = "GET";
          return true;
        Default:
          return false;
      }
    }
    
    /*
     * GetURL($url);
     * 
     * Schickt einen Request an $url und gibt das Ergebniss zurück.
     * 
     * @param string Die URL die aufgerufen werden soll 
     */
    public function GetURL($url) {
      // Header vorbereiten
      $opts = array(
        'http'=>array(
          'method'=>$this->method,
          'header'=>($this->header_global ? implode("\r\n",$this->header_global)."\r\n" : "").
                    ($this->header_temp ? implode("\r\n",$this->header_temp)."\r\n" : "").
                    $this->GetCookieHeader($cookies),
        )
      );      
      // Referer eintragen
      $opts['http']['header'] .= "Referer: ".$this->referer."\r\n";
      $this->referer = $url;
      // Parameter vorhanden?
      if (!empty($this->parameters)) {
        if ($this->method == "GET") {
          $params = array();
          foreach($this->parameters as $name=>$value) {
            $params[] = $name."=".$value;
          }
          // Bei GET einfach an die URL anhängen 
          if (strpos($url, "?") > -1)
            $url .= "&".implode("&", $params);  // Es sind bereits parameter vorhanden
          else
            $url .= "?".implode("&", $params);  // Blanke URL
        } else {
          $params = http_build_query($this->parameters);
          // Bei POST als application/x-www-form-urlencoded mit schicken
          $opts['http']['header'] .= "Content-Type: application/x-www-form-urlencoded;\r\n".
                                     "Content-Length: ".strlen($params)."\r\n";
          $opts['http']['content'] = $params;
        }
      }
      var_dump($opts);
      
      // Kontext für den HTTP Header erzeugen
      $context = stream_context_create($opts);
      // Request abschicken
      $result = file_get_contents($url, 0, $context);  
          
      // Temporäre Header-Zeilen löschen
      $this->header_temp = array();
      // Parameter löschen
      $this->parameters = array();
      
      if (strlen($result) > 0) {
        // Request lieferte eine Antwort
        foreach ($http_response_header as $httpline) {
           // HTTP Response-Header nach Cookies durchsuchen
           @list($header,$parameters) = explode(";",$httpline,2);
           @list($attr,$value) = explode(":",$header,2);
           if (strtolower(trim($attr)) == "set-cookie") {
              // Set-Cookie gefunden
              echo($httpline."<br>");
              $cookies_raw = explode("&", trim($value));
              foreach($cookies_raw as $cookie) {
                list($cookie_name, $cookie_value) = explode("=", $cookie);
                // Cookies für zukünftige Requests Speichern
                $this->cookies[$cookie_name] = $cookie_value;
              }
           }
        }
        // Antwort ausgeben
        return $result;
      }
      return false;
    }
    
    /*
     * GetCookieHeader()
     * 
     * Gibt die Cookie-Zeile für den Header zurück.
     */
    private function GetCookieHeader() {
      if (empty($this->cookies))
        return "";
      $header = array();
      foreach($this->cookies as $cookie=>$value) {
        $header[] = $cookie."=".$value;
      }
      return "Cookie: ".implode("; ", $header)."\r\n";
    }
  }
?>