Changeset 1495

Show
Ignore:
Timestamp:
04/04/08 19:07:38 (3 months ago)
Author:
mikey
Message:

added unit test for net::stubbles::peer::http::stubHTTPResponse

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/main/php/net/stubbles/peer/http/stubHTTPResponse.php

    r1493 r1495  
    11<?php 
    22/** 
    3  * Class for recieving a HTTP response. 
     3 * Class for reading a HTTP response. 
    44 * 
    55 * @author      Frank Kleine <mikey@stubbles.net> 
     
    1212); 
    1313/** 
    14  * Class for recieving a HTTP response. 
     14 * Class for reading a HTTP response. 
    1515 * 
    1616 * @package     stubbles 
     
    2828     * list of response parts 
    2929     * 
    30      * @var  array 
     30     * @var  array<string,scalar> 
    3131     */ 
    3232    protected $response             = array(); 
     
    8989 
    9090    /** 
    91      * constructor for this class. 
     91     * constructor 
    9292     * 
    9393     * @param  stubSocket  $socket  socket where the response can be read from 
     
    9595    public function __construct(stubSocket $socket) 
    9696    { 
    97         $this->socket = $socket; 
    98     } 
    99  
    100     /** 
    101      * destructor for this class. 
     97        $this->socket = $socket; 
     98    } 
     99 
     100    /** 
     101     * destructor 
    102102     */ 
    103103    public function __destruct() 
     
    130130         
    131131        $this->headers = stubHeaderList::fromString($header); 
    132         if ($this->headers->containsKey('Content-Length') === true) { 
    133             $readLength = $this->headers->get('Content-Length'); 
     132        if ($this->headers->get('Transfer-Encoding') === 'chunked') { 
     133            $this->body = $this->readChunked(); 
    134134        } else { 
    135             $readLength = 4096; 
    136         } 
    137          
    138         if (self::STATUS_CLASS_SUCCESS == $this->getType(self::TYPE_STATUS_CLASS)) { 
    139             // if server sends chunked data 
    140             if ($this->headers->containsKey('Transfer-Encoding') === true && $this->headers->get('Transfer-Encoding') === 'chunked') { 
    141                 // it gets a little bit more complicated because we can not read the data in a whole 
    142                 // the following lines implement the pseudo code given in RFC 2616 section 19.4.6: Introduction of Transfer-Encoding 
    143                 $readLength = 0; 
    144                 $chunksize  = null; 
    145                 $extension  = null; 
    146                 // read chunk-size, chunk-extension (if any) and CRLF 
    147                 sscanf($this->socket->read(1024), "%x%s\r\n", $chunksize, $extension); 
    148                  
    149                 while (0 < $chunksize) { 
    150                     // read chunk-data and CRLF 
    151                     $data        = $this->socket->readBinary($chunksize + 2); 
    152                     // append chunk-data to entity-body 
    153                     $this->body .= rtrim($data); 
    154                     $readLength  = $readLength + $chunksize; 
    155                     // read chunk-size and CRLF 
    156                     sscanf($this->socket->read(1024), "%x\r\n", $chunksize); 
    157                 } 
    158                  
    159                 #read entity-header 
    160                 #while (entity-header not empty) { 
    161                 #    append entity-header to existing header fields 
    162                 #    read entity-header 
    163                 #} 
    164                  
    165                 // set correct content length 
    166                 $this->headers->put('Content-Length', $readLength); 
    167                 // remove "chunked" from Transfer-Encoding 
    168                 $this->headers->remove('Transfer-Encoding'); 
    169             } else { 
    170                 // no chunked data, we just read all that we can get until we reach the end of data 
    171                 while ($this->socket->eof() === false) { 
    172                     $this->body .= $this->socket->read($readLength); 
    173                 } 
    174             } 
    175         } 
     135            $this->body = $this->readDefault($this->headers->get('Content-Length', 4096)); 
     136        } 
     137    } 
     138 
     139    /** 
     140     * helper method to read chunked response body 
     141     * 
     142     * @return  string 
     143     */ 
     144    protected function readChunked() 
     145    { 
     146        // it gets a little bit more complicated because we can not read the data in a whole 
     147        // the following lines implement the pseudo code given in RFC 2616 section 19.4.6: Introduction of Transfer-Encoding 
     148        $readLength = 0; 
     149        $chunksize  = null; 
     150        $extension  = null; 
     151        $body       = ''; 
     152        // read chunk-size, chunk-extension (if any) and CRLF 
     153        sscanf($this->socket->read(1024), "%x%s\r\n", $chunksize, $extension); 
     154        while (0 < $chunksize) { 
     155            // read chunk-data and CRLF 
     156            $data        = $this->socket->readBinary($chunksize + 2); 
     157            // append chunk-data to entity-body 
     158            $body       .= rtrim($data); 
     159            $readLength += $chunksize; 
     160            // read chunk-size and CRLF 
     161            sscanf($this->socket->read(1024), "%x\r\n", $chunksize); 
     162        } 
     163         
     164        #read entity-header 
     165        #while (entity-header not empty) { 
     166        #    append entity-header to existing header fields 
     167        #    read entity-header 
     168        #} 
     169         
     170        // set correct content length 
     171        $this->headers->put('Content-Length', $readLength); 
     172        // remove "chunked" from Transfer-Encoding 
     173        $this->headers->remove('Transfer-Encoding'); 
     174        return $body; 
     175    } 
     176 
     177    /** 
     178     * helper method for default reading of response body 
     179     * 
     180     * @param   int     $readLength  expected length of response body 
     181     * @return  string 
     182     */ 
     183    protected function readDefault($readLength) 
     184    { 
     185        $body = ''; 
     186        while ($this->socket->eof() === false) { 
     187            $body .= $this->socket->read($readLength); 
     188        } 
     189         
     190        return $body; 
    176191    } 
    177192 
     
    217232     * @return  stubHeaderList 
    218233     */ 
    219     public function getHeaders() 
     234    public function getHeader() 
    220235    { 
    221236        return $this->headers; 
     
    247262     * @param  string  $head  first line of response 
    248263     */ 
    249     private function parseHead($head) 
     264    protected function parseHead($head) 
    250265    { 
    251266        $matches = array(); 
    252         if (preg_match('=^(HTTP/\d+\.\d+) (\d{3}) ([^' . stubHTTPConnection::END_OF_LINE . ']*)=', $head, $matches) !== false) { 
    253             $this->response[self::TYPE_STATUS_LINE]   = $matches[0]; 
    254             $this->response[self::TYPE_HTTP_VERSION]  = $matches[1]; 
    255             $this->response[self::TYPE_STATUS_CODE]   = $matches[2]; 
    256             $this->response[self::TYPE_REASON_PHRASE] = $matches[3]; 
    257             switch ($this->response[self::TYPE_STATUS_CODE][0]) { 
    258                 case 1: 
    259                     $this->response[self::TYPE_STATUS_CLASS] = self::STATUS_CLASS_INFO; 
    260                     break; 
    261                  
    262                 case 2: 
    263                     $this->response[self::TYPE_STATUS_CLASS] = self::STATUS_CLASS_SUCCESS; 
    264                     break; 
    265                  
    266                 case 3: 
    267                     $this->response[self::TYPE_STATUS_CLASS] = self::STATUS_CLASS_REDIRECT; 
    268                     break; 
    269                  
    270                 case 4: 
    271                     $this->response[self::TYPE_STATUS_CLASS] = self::STATUS_CLASS_ERROR_CLIENT; 
    272                     break; 
    273                  
    274                 case 5: 
    275                     $this->response[self::TYPE_STATUS_CLASS] = self::STATUS_CLASS_ERROR_SERVER; 
    276                     break; 
    277                  
    278                 default: 
    279                     $this->response[self::TYPE_STATUS_CLASS] = self::STATUS_CLASS_UNKNOWN; 
    280             } 
     267        if (preg_match('=^(HTTP/\d+\.\d+) (\d{3}) ([^' . stubHTTPConnection::END_OF_LINE . ']*)=', $head, $matches) == false) { 
     268            return; 
     269        } 
     270         
     271        $this->response[self::TYPE_STATUS_LINE]   = $matches[0]; 
     272        $this->response[self::TYPE_HTTP_VERSION]  = $matches[1]; 
     273        $this->response[self::TYPE_STATUS_CODE]   = $matches[2]; 
     274        $this->response[self::TYPE_REASON_PHRASE] = $matches[3]; 
     275        switch ($this->response[self::TYPE_STATUS_CODE][0]) { 
     276            case 1: 
     277                $this->response[self::TYPE_STATUS_CLASS] = self::STATUS_CLASS_INFO; 
     278                break; 
     279             
     280            case 2: 
     281                $this->response[self::TYPE_STATUS_CLASS] = self::STATUS_CLASS_SUCCESS; 
     282                break; 
     283             
     284            case 3: 
     285                $this->response[self::TYPE_STATUS_CLASS] = self::STATUS_CLASS_REDIRECT; 
     286                break; 
     287             
     288            case 4: 
     289                $this->response[self::TYPE_STATUS_CLASS] = self::STATUS_CLASS_ERROR_CLIENT; 
     290                break; 
     291             
     292            case 5: 
     293                $this->response[self::TYPE_STATUS_CLASS] = self::STATUS_CLASS_ERROR_SERVER; 
     294                break; 
     295             
     296            default: 
     297                $this->response[self::TYPE_STATUS_CLASS] = self::STATUS_CLASS_UNKNOWN; 
    281298        } 
    282299    } 
  • trunk/src/test/php/net/stubbles/peer/PeerTestSuite.php

    r1493 r1495  
    3333        $suite->addTestFile($dir . '/http/stubHTTPConnectionTestCase.php'); 
    3434        $suite->addTestFile($dir . '/http/stubHTTPRequestTestCase.php'); 
     35        $suite->addTestFile($dir . '/http/stubHTTPResponseTestCase.php'); 
    3536        $suite->addTestFile($dir . '/http/stubHTTPURLTestCase.php'); 
    3637