Http.class.php

gehe zur Dokumentation dieser Datei
00001 <?php
00002 
00011 class Http
00012 {
00013      var $url    = array();
00014      var $header = array();
00015      var $responseHeader = array();
00016      var $requestParameter = array();
00017      var $urlParameter = array();
00018 
00026      var $method = 'GET';
00027      var $error  = '';
00028      var $status = '';
00029      var $body   = '';
00030 
00031 
00032 
00039      function Http( $url = '' )
00040      {
00041           $this->setURL( $url );
00042           $this->header[] = 'User-Agent: Mozilla/5.0 (OpenRat CMS)';
00043           $this->header[] = 'Connection: close';
00044      }
00045 
00046 
00047 
00053      function setURL( $url )
00054      {
00055 //        Html::debug($url,"neue url");
00056           $this->url = parse_url($url);
00057 //        Html::debug($this->url,"direkt nach parse_url");
00058 
00059           if   ( empty($this->url['host']) && !empty($this->url['path']) )
00060           {
00061                $this->url['host'] = basename($this->url['path']);
00062                $this->url['path'] = '/';
00063           }
00064 
00065           if   ( empty($this->url['path']) )
00066                $this->url['path'] = '/';
00067 
00068           if   ( !isset($this->url['port']) )
00069                if   ( !isset($this->url['scheme']) )
00070                {
00071                     $this->url['scheme'] = 'http'; // Standard-Port.
00072                     $this->url['port']   = 80; // Standard-Port.
00073                }
00074                elseif    ( $this->url['scheme'] == 'https' )
00075                     $this->url['port'] = 443; // SSL-Port.
00076                else
00077                     $this->url['port'] = 80; // Standard-Port.
00078           
00079           if   ( !empty($this->url['query']) )
00080                parse_str( $this->url['query'],$this->urlParameter );
00081 
00082      }
00083 
00084 
00085 
00092      function setBasicAuthentication( $user, $password )
00093      {
00094           $this->header[] = 'Authorization: Basic '.base64_encode($user.':'.$password);
00095      }
00096 
00097      
00098 
00104      function getParameterString( $withPraefixQuestionMark=false )
00105      {
00106           $parameterString = '';
00107           $parameter = $this->urlParameter + $this->requestParameter;
00108           
00109           if   ( ! empty($parameter) )
00110           {
00111                foreach( $this->requestParameter as $paramName => $paramValue )
00112                {
00113                     if   ( strlen($parameterString) > 0)
00114                          $parameterString .= '&';
00115                     elseif    ( $withPraefixQuestionMark )
00116                          $parameterString .= '?';
00117                          
00118                     $parameterString .= urlencode($paramName) . '=' .urlencode($paramValue);
00119                }
00120           }
00121           
00122           return $parameterString;
00123      }
00124 
00125      
00130      function getUrl()
00131      {
00132           $location = $this->url['scheme'];
00133           $location .= '://'; 
00134           $location .= $this->url['host'];
00135           if   ( $this->url['scheme'] == 'http'  && $this->url['port'] != 80  ||
00136                  $this->url['scheme'] == 'https' && $this->url['port'] != 443    )
00137                $location .= ':'.$this->url['port'];
00138           $location .= $this->url['path'];
00139                
00140           $location .= $this->getParameterString(true);
00141 
00142           if   ( isset($this->url['fragment']) )
00143                $location .= '#'.$this->url['fragment'];
00144           
00145           return $location;
00146      }
00147 
00148 
00152      function sendRedirect()
00153      {
00154           $location = $this->getUrl();
00155           
00156           header('Location: '.$location);
00157           exit;
00158      }
00159 
00160 
00166      function request()
00167      {
00168           $this->error  = '';
00169           $this->status = '';
00170 
00171           $errno  = 0;
00172           $errstr = '';
00173 
00174           if   ( empty($this->url['host']) )
00175           {
00176                $this->error = "No hostname specified";
00177                return false;
00178           }
00179           
00180           // RFC 1945 (Section 9.3) says:
00181           // A user agent should never automatically redirect a request
00182           // more than 5 times, since such redirections usually indicate an infinite loop.
00183           for( $r=1; $r<=5; $r++ )
00184           {
00185                // Die Funktion fsockopen() erwartet eine Protokollangabe (bei TCP optional, bei SSL notwendig).
00186                if   ( $this->url['scheme'] == 'https' || $this->url['port'] == '443' )
00187                     $prx_proto = 'ssl://'; // SSL
00188                else
00189                     $prx_proto = 'tcp://'; // Default
00190                     
00191                $fp = @fsockopen ($prx_proto.$this->url['host'],$this->url['port'], $errno, $errstr, 30);
00192      
00193                if   ( !$fp || !is_resource($fp) )
00194                {
00195                     // Keine Verbindung zum Host moeglich.
00196                     $this->error = "Connection refused: '".$prx_proto.$this->url['host'].':'.$this->url['port']." - $errstr ($errno)";
00197                     return false;
00198                }
00199                else
00200                {
00201                     $lb = "\r\n";
00202                     $http_get = $this->url['path'];
00203 
00204                     $parameterString = $this->getParameterString();
00205 
00206                     if   ( $this->method == 'GET')
00207                          if   ( !empty($parameterString) )
00208                               $http_get .= '?'.$parameterString;
00209 
00210                     if   ( $this->method == 'POST' )
00211                     {
00212                          $this->header[] = 'Content-Type: application/x-www-form-urlencoded';
00213                          $this->header[] = 'Content-Length: '.strlen($parameterString);
00214                     }
00215                               
00216                     $this->header[] = 'Host: '.$this->url['host'];
00217                     $this->header[] = 'Accept: */*';
00218                     $request_header = array( $this->method.' '.$http_get.' HTTP/1.0') + $this->header;
00219                     $http_request = implode($lb,$request_header).$lb.$lb;
00220                     
00221                     if   ( $this->method == 'POST' )
00222                          $http_request .= $parameterString;
00223 
00224                     if (!is_resource($fp)) {
00225                          $this->error = 'Connection lost after connect: '.$prx_proto.$this->url['host'].':'.$this->url['port'];
00226                          return false;
00227                     }
00228                     fputs($fp, $http_request); // Die HTTP-Anfrage zum Server senden.
00229 
00230                     // Jetzt erfolgt das Auslesen der HTTP-Antwort.
00231                     $isHeader = true;
00232 
00233                     // RFC 1945 (Section 6.1) schreibt als Statuszeile folgendes Format vor
00234                     // "HTTP/" 1*DIGIT "." 1*DIGIT SP 3DIGIT SP
00235                     if (!is_resource($fp)) {
00236                          $this->error = 'Connection lost during transfer: '.$this->url['host'].':'.$this->url['port'];
00237                          return false;
00238                     }
00239                     elseif (!feof($fp)) {
00240                          $line = fgets($fp,1028);
00241                          $this->status = substr($line,9,3);
00242                     }
00243                     else
00244                     {
00245                          $this->error = 'Unexpected EOF while reading HTTP-Response';
00246                          return false;
00247                     }
00248                     
00249                     while (!feof($fp)) {
00250                          $line = fgets($fp,1028);
00251                          if   ( $isHeader && trim($line)=='' ) // Leerzeile nach Header.
00252                          {
00253                               $isHeader = false;
00254                          }
00255                          elseif( $isHeader )
00256                          {
00257                               list($headerName,$headerValue) = explode(': ',$line) + array(1=>'');
00258                               $this->responseHeader[$headerName] = trim($headerValue);
00259                          }
00260                          else
00261                          {
00262                               $this->body .= $line;
00263                          }
00264                     }
00265 //                  Html::debug($this->url,"URL");
00266 //                  Html::debug($http_request,"REQUEST komplett");
00267 //                  Html::debug($this->responseHeader);
00268 //                  Html::debug($this->body,'BODY');
00269 //                  echo "<pre>";
00270 //                  echo "REQUEST=".nl2br($http_request);
00271 //                  echo "HEADER=".nl2br(htmlentities(implode("\n",$this->responseHeader)));
00272 //                  echo "BODY=".nl2br(htmlentities($this->body));
00273 //                  echo "</pre>";
00274                     fclose($fp); // Verbindung brav schließen.
00275 
00276 
00277                     // RFC 1945 (Section 6.1.1) schreibt
00278                     // "[...] However, applications must understand the class of any status code, as
00279                     // indicated by the first digit"
00280                     // Daher interessiert uns nur die erste Stelle des 3-stelligen HTTP-Status.
00281 
00282                     // 301 Moved Permanently
00283                     // 302 Moved Temporarily
00284                     if   ( $this->status == '301' ||
00285                            $this->status == '302'   )
00286                     {
00287                          $location = @$this->responseHeader['Location'];
00288                          if   ( empty($location) )
00289                          {
00290                               $this->error = '301/302 Response without Location-header';
00291                               return false;
00292                          }
00293                          
00294 //                       Html::debug($this->url,"alte URL");
00295 //                       Html::debug($location,"NEUES REDIRECT AUF");
00296                          $this->setURL($location);
00297 //                       Html::debug($this->url,"NEUE URL NACH REDIRECT");
00298                          continue; // Nächster Versuch mit umgeleiteter Adresse.
00299                     }
00300                     // RFC 1945 (Section 6.1.1) schreibt
00301                     // "2xx: Success - The action was successfully received, understood, and accepted."
00302                     elseif    ( substr($this->status,0,1) == '2' )
00303                     {
00304                          return true;
00305                     }
00306                     elseif    ( substr($this->status,0,1) == '4' )
00307                     {
00308                          $this->error = 'Client Error: '.$this->status;
00309                          return false;
00310                     }
00311                     elseif    ( substr($this->status,0,1) == '5' )
00312                     {
00313                          $this->error = 'Server Error: '.$this->status;
00314                          return false;
00315                     }
00316                     else
00317                     {
00318                          $this->error = 'Unexpected HTTP-Status: '.$this->status. '; this is mostly a client error, sorry.';
00319                          return false;
00320                     }
00321                }
00322 
00323                $this->error = 'Too much redirects, infinite loop assumed. Exiting. Last URL: '.$http_get;
00324                return false;
00325 
00326           }
00327 
00328      }
00329 
00330 
00341      function getLanguages()
00342      {
00343           global $HTTP_SERVER_VARS;
00344 
00345           $languages = array();
00346           $http_languages = @$HTTP_SERVER_VARS['HTTP_ACCEPT_LANGUAGE'];
00347           foreach( explode(',',$http_languages) as $l )
00348           {
00349                list($part) = explode(';',$l); // Prioritäten ignorieren.
00350                $languages[] = trim($part);
00351 
00352                // Aus "de_DE" das "de" extrahieren.
00353                $languages[] = current(explode('_',str_replace('-','_',trim($part))));
00354           }
00355 
00356           return array_unique( $languages );
00357      }
00358      
00359      
00366      function getServer()
00367      {
00368           $https = getenv('HTTPS');
00369           
00370           if   ( $https )
00371                $server = 'https://';
00372           else
00373                $server = 'http://';
00374                
00375           $server .= getenv('SERVER_NAME').dirname(getenv('REQUEST_URI'));
00376           
00377           return $server;
00378      }
00379      
00380 
00381      
00387      function serverError($message)
00388      {
00389 
00390           Http::sendStatus(501,'Internal Server Error',$message);
00391      }
00392      
00393      
00394      
00400      function notAuthorized($message)
00401      {
00402 
00403           Http::sendStatus(403,'Not Authorized',$message);
00404      }
00405      
00406      
00407      
00415      function sendStatus( $status=501,$text='Internal Server Error',$message='' )
00416      {
00417           if   ( headers_sent() )
00418           {
00419                echo "$status $text\n$message";
00420                exit;
00421           }
00422           
00423           header('HTTP/1.0 '.intval($status).' '.$text);
00424           
00425           
00426           $types = Http::getAccept();
00427           
00428           if   ( sizeof($types)==1 && in_array('application/json',$types) )
00429           {
00430                header('Content-Type: application/json');
00431                require_once( OR_SERVICECLASSES_DIR."JSON.class.".PHP_EXT );
00432                $json = new JSON();
00433                echo $json->encode( array('status'=>$status,'error'=>$text,'description'=>$message) );
00434           }
00435           elseif    ( sizeof($types)==1 && in_array('application/xml',$types) )
00436           {
00437                header('Content-Type: application/xml');
00438                require_once( OR_SERVICECLASSES_DIR."XML.class.".PHP_EXT );
00439                $xml = new XML();
00440                $xml->root='error';
00441                echo $xml->encode( array('status'=>$status,'error'=>$text,'description'=>$message) );
00442           }
00443           else
00444           {
00445                header('Content-Type: text/html');
00446                $signature = OR_TITLE.' '.OR_VERSION.' '.getenv('SERVER_SOFTWARE');
00447                echo <<<HTML
00448 <html>
00449 <head><title>$status $text - OpenRat</title></head>
00450 <body>
00451 <h1>$text</h1>
00452 <p>$message</p>
00453 <hr>
00454 <address>$signature</adddress>
00455 </body>
00456 </html>
00457 HTML;
00458           }
00459           exit;
00460      }
00461      
00462      
00467      function getAccept()
00468      {
00469           $httpAccept = getenv('HTTP_ACCEPT');
00470           return $types = explode(',',$httpAccept);
00471      }
00472 }
00473 
00474 ?>

Erzeugt am Thu May 14 00:55:49 2009 für OpenRat von  doxygen 1.5.8