Changeset 1204
- Timestamp:
- 01/04/08 14:56:57 (1 year ago)
- Files:
-
- trunk/src/main/php/net/stubbles/lang/exceptions/stubIllegalStateException.php (added)
- trunk/src/main/php/net/stubbles/util/net/http/stubHTTPRequest.php (modified) (2 diffs)
- trunk/src/main/php/net/stubbles/util/net/http/stubHTTPResponse.php (modified) (1 diff)
- trunk/src/main/php/net/stubbles/util/net/stubSocket.php (modified) (7 diffs)
- trunk/src/main/php/net/stubbles/util/net/stubSocketException.php (deleted)
- trunk/src/test/php/net/stubbles/util/net/stubSocketTestCase.php (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/src/main/php/net/stubbles/util/net/http/stubHTTPRequest.php
r1203 r1204 116 116 * @param string $version optional version of HTTP-protocol to use, standard: HTTP/1.0 117 117 * @return stubHTTPResponse response of given request 118 * @throws stubConnectionException119 118 */ 120 119 public function send($method, $version = null) … … 130 129 $socket = $this->createSocket(); 131 130 $socket->setTimeout($this->timeout); 132 try { 133 $socket->connect(); 134 $socket->write($method . ' ' . $this->http->getPath() . ' ' . $version . stubHTTPConnection::END_OF_LINE); 135 $socket->write('Host: ' . $this->http->getHost() . stubHTTPConnection::END_OF_LINE); 131 $socket->connect(); 132 $socket->write($method . ' ' . $this->http->getPath() . ' ' . $version . stubHTTPConnection::END_OF_LINE); 133 $socket->write('Host: ' . $this->http->getHost() . stubHTTPConnection::END_OF_LINE); 134 135 // prepare last headers and write all headers to socket 136 $this->headers->putDate(); 137 if ($this->headers->containsKey('User-Agent') == false) { 138 $this->headers->putUserAgent('stubbles HTTP Client'); 139 } 140 141 $this->headers->putPower(); 142 foreach ($this->headers as $key => $value) { 143 $socket->write($key . ': ' . $value . stubHTTPConnection::END_OF_LINE); 144 } 145 146 switch ($method) { 147 // on GET: write one further end of line 148 case self::METHOD_GET: 149 $socket->write(stubHTTPConnection::END_OF_LINE); 150 break; 136 151 137 // prepare last headers and write all headers to socket138 $this->headers->putDate();139 if ($this->headers->containsKey('User-Agent') == false) {140 $ this->headers->putUserAgent('stubbles HTTP Client');141 }152 // on POST we have to write the body 153 case self::METHOD_POST: 154 $socket->write(stubHTTPConnection::END_OF_LINE); 155 $socket->write($this->body); 156 break; 142 157 143 $this->headers->putPower(); 144 foreach ($this->headers as $key => $value) { 145 $socket->write($key . ': ' . $value . stubHTTPConnection::END_OF_LINE); 146 } 147 148 switch ($method) { 149 // on GET: write one further end of line 150 case self::METHOD_GET: 151 $socket->write(stubHTTPConnection::END_OF_LINE); 152 break; 153 154 // on POST we have to write the body 155 case self::METHOD_POST: 156 $socket->write(stubHTTPConnection::END_OF_LINE); 157 $socket->write($this->body); 158 break; 159 160 // on HEAD we write one additional header and close the connection 161 case self::METHOD_HEAD: 162 $socket->write('Connection: close' . stubHTTPConnection::END_OF_LINE . stubHTTPConnection::END_OF_LINE); 163 break; 164 } 165 } catch (stubSocketException $se) { 166 throw new stubConnectionException('Failed sending request to ' . $this->http->getHost(), $se); 158 // on HEAD we write one additional header and close the connection 159 case self::METHOD_HEAD: 160 $socket->write('Connection: close' . stubHTTPConnection::END_OF_LINE . stubHTTPConnection::END_OF_LINE); 161 break; 167 162 } 168 163 trunk/src/main/php/net/stubbles/util/net/http/stubHTTPResponse.php
r1203 r1204 108 108 /** 109 109 * read the response from socket and parse it 110 *111 * @throws stubConnectionException112 110 */ 113 111 public function read() 114 112 { 115 try { 116 $this->parseHead($this->socket->readLine()); 117 $header = ''; 118 $line = ''; 119 while ($this->socket->eof() === false && stubHTTPConnection::END_OF_LINE !== $line) { 120 $line = $this->socket->read(); 121 $header .= $line; 122 } 123 124 $this->headers = stubHeaderList::fromString($header); 125 if ($this->headers->containsKey('Content-Length') === true) { 126 $readLength = $this->headers->get('Content-Length'); 113 $this->parseHead($this->socket->readLine()); 114 $header = ''; 115 $line = ''; 116 while ($this->socket->eof() === false && stubHTTPConnection::END_OF_LINE !== $line) { 117 $line = $this->socket->read(); 118 $header .= $line; 119 } 120 121 $this->headers = stubHeaderList::fromString($header); 122 if ($this->headers->containsKey('Content-Length') === true) { 123 $readLength = $this->headers->get('Content-Length'); 124 } else { 125 $readLength = 4096; 126 } 127 128 if (self::STATUS_CLASS_SUCCESS == $this->getType(self::TYPE_STATUS_CLASS)) { 129 // if server sends chunked data 130 if ($this->headers->containsKey('Transfer-Encoding') === true && $this->headers->get('Transfer-Encoding') === 'chunked') { 131 // it gets a little bit more complicated because we can not read the data in a whole 132 // the following lines implement the pseudo code given in RFC 2616 section 19.4.6: Introduction of Transfer-Encoding 133 $readLength = 0; 134 $chunksize = null; 135 $extension = null; 136 // read chunk-size, chunk-extension (if any) and CRLF 137 sscanf($this->socket->read(1024), "%x%s\r\n", $chunksize, $extension); 138 139 while (0 < $chunksize) { 140 // read chunk-data and CRLF 141 $data = $this->socket->readBinary($chunksize + 2); 142 // append chunk-data to entity-body 143 $this->body .= rtrim($data); 144 $readLength = $readLength + $chunksize; 145 // read chunk-size and CRLF 146 sscanf($this->socket->read(1024), "%x\r\n", $chunksize); 147 } 148 149 #read entity-header 150 #while (entity-header not empty) { 151 # append entity-header to existing header fields 152 # read entity-header 153 #} 154 155 // set correct content length 156 $this->headers->put('Content-Length', $readLength); 157 // remove "chunked" from Transfer-Encoding 158 $this->headers->remove('Transfer-Encoding'); 127 159 } else { 128 $readLength = 4096; 129 } 130 131 if (self::STATUS_CLASS_SUCCESS == $this->getType(self::TYPE_STATUS_CLASS)) { 132 // if server sends chunked data 133 if ($this->headers->containsKey('Transfer-Encoding') === true && $this->headers->get('Transfer-Encoding') === 'chunked') { 134 // it gets a little bit more complicated because we can not read the data in a whole 135 // the following lines implement the pseudo code given in RFC 2616 section 19.4.6: Introduction of Transfer-Encoding 136 $readLength = 0; 137 $chunksize = null; 138 $extension = null; 139 // read chunk-size, chunk-extension (if any) and CRLF 140 sscanf($this->socket->read(1024), "%x%s\r\n", $chunksize, $extension); 141 142 while (0 < $chunksize) { 143 // read chunk-data and CRLF 144 $data = $this->socket->readBinary($chunksize + 2); 145 // append chunk-data to entity-body 146 $this->body .= rtrim($data); 147 $readLength = $readLength + $chunksize; 148 // read chunk-size and CRLF 149 sscanf($this->socket->read(1024), "%x\r\n", $chunksize); 150 } 151 152 #read entity-header 153 #while (entity-header not empty) { 154 # append entity-header to existing header fields 155 # read entity-header 156 #} 157 158 // set correct content length 159 $this->headers->put('Content-Length', $readLength); 160 // remove "chunked" from Transfer-Encoding 161 $this->headers->remove('Transfer-Encoding'); 162 } else { 163 // no chunked data, we just read all that we can get until we reach the end of data 164 while ($this->socket->eof() === false) { 165 $this->body .= $this->socket->read($readLength); 166 } 160 // no chunked data, we just read all that we can get until we reach the end of data 161 while ($this->socket->eof() === false) { 162 $this->body .= $this->socket->read($readLength); 167 163 } 168 164 } 169 } catch (stubSocketException $se) {170 throw new stubConnectionException('Failed getting response from ' . $this->socket->getHost(), $se);171 165 } 172 166 } trunk/src/main/php/net/stubbles/util/net/stubSocket.php
r1127 r1204 7 7 * @subpackage util_net 8 8 */ 9 stubClassLoader::load('net.stubbles.util.net.stubSocketException'); 9 stubClassLoader::load('net.stubbles.lang.exceptions.stubIllegalStateException', 10 'net.stubbles.util.net.stubConnectionException' 11 ); 10 12 /** 11 13 * Class for operations on sockets. … … 65 67 * 66 68 * @return bool TRUE if connect was successful 67 * @throws stub SocketException69 * @throws stubConnectionException 68 70 */ 69 71 public function connect() … … 82 84 if (false === $this->fp) { 83 85 $this->fp = null; 84 throw new stub SocketException('Connecting to ' . $this->host . ':' . $this->port . ' within ' . $this->timeout . ' seconds failed: ' . $errstr . ' (' . $errno . ').');86 throw new stubConnectionException('Connecting to ' . $this->host . ':' . $this->port . ' within ' . $this->timeout . ' seconds failed: ' . $errstr . ' (' . $errno . ').'); 85 87 } 86 88 … … 118 120 * @param int $length optional length of data to read 119 121 * @return string data read from socket 120 * @throws stubSocketException 122 * @throws stubConnectionException 123 * @throws stubIllegalStateException 121 124 */ 122 125 public function read($length = 4096) 123 126 { 124 127 if ($this->isConnected() == false) { 125 throw new stub SocketException('Can not read on unconnected socket.');128 throw new stubIllegalStateException('Can not read on unconnected socket.'); 126 129 } 127 130 128 131 $data = fgets($this->fp, $length); 129 132 if (false === $data) { 130 throw new stub SocketException('Reading of ' . $length . ' bytes failed.');133 throw new stubConnectionException('Reading of ' . $length . ' bytes failed.'); 131 134 } 132 135 … … 139 142 * @param int $length optional length of data to read 140 143 * @return string data read from socket 141 * @throws stubSocketException142 144 */ 143 145 public function readLine($length = 4096) … … 151 153 * @param int $length optional length of data to read 152 154 * @return string data read from socket 153 * @throws stubSocketException 155 * @throws stubConnectionException 156 * @throws stubIllegalStateException 154 157 */ 155 158 public function readBinary($length = 1024) 156 159 { 157 160 if ($this->isConnected() == false) { 158 throw new stub SocketException('Can not read on unconnected socket.');161 throw new stubIllegalStateException('Can not read on unconnected socket.'); 159 162 } 160 163 161 164 $data = fread($this->fp, $length); 162 165 if (false === $data) { 163 throw new stub SocketException('Reading of ' . $length . ' bytes failed.');166 throw new stubConnectionException('Reading of ' . $length . ' bytes failed.'); 164 167 } 165 168 … … 173 176 * @access public 174 177 * @return int amount of bytes written to socket 175 * @throws stubSocketException 178 * @throws stubConnectionException 179 * @throws stubIllegalStateException 176 180 */ 177 181 public function write($data) 178 182 { 179 183 if ($this->isConnected() == false) { 180 throw new stub SocketException('Can not write on unconnected socket.');184 throw new stubIllegalStateException('Can not write on unconnected socket.'); 181 185 } 182 186 183 187 $length = fputs($this->fp, $data, strlen($data)); 184 188 if (false === $length) { 185 throw new stub SocketException('"Writing of ' . strlen($data) . ' bytes failed.');189 throw new stubConnectionException('"Writing of ' . strlen($data) . ' bytes failed.'); 186 190 } 187 191 trunk/src/test/php/net/stubbles/util/net/stubSocketTestCase.php
r719 r1204 1 1 <?php 2 2 /** 3 * Test for net .stubbles.util.net.stubSocket.3 * Test for net::stubbles::util::net::stubSocket. 4 4 * 5 5 * @author Frank Kleine <mikey@stubbles.net> … … 10 10 Mock::generate('stubSession'); 11 11 /** 12 * Test for net .stubbles.util.net.stubSocket.12 * Test for net::stubbles::util::net::stubSocket. 13 13 * 14 14 * @package stubbles … … 42 42 43 43 /** 44 * assure that trying to read on an unconnected socket throws a SocketException44 * assure that trying to read on an unconnected socket throws an IllegalStateException 45 45 */ 46 46 public function testReadOnUnconnected() 47 47 { 48 48 $socket = new stubSocket('example.com'); 49 $this->expectException('stub SocketException');49 $this->expectException('stubIllegalStateException'); 50 50 $data = $socket->read(); 51 51 } 52 52 53 53 /** 54 * assure that trying to read on an unconnected socket throws a SocketException54 * assure that trying to read on an unconnected socket throws an IllegalStateException 55 55 */ 56 56 public function testReadLineOnUnconnected() 57 57 { 58 58 $socket = new stubSocket('example.com'); 59 $this->expectException('stub SocketException');59 $this->expectException('stubIllegalStateException'); 60 60 $data = $socket->readLine(); 61 61 } 62 62 63 63 /** 64 * assure that trying to write on an unconnected socket throws a SocketException64 * assure that trying to write on an unconnected socket throws an IllegalStateException 65 65 */ 66 66 public function testWriteOnUnconnected() 67 67 { 68 68 $socket = new stubSocket('example.com'); 69 $this->expectException('stub SocketException');69 $this->expectException('stubIllegalStateException'); 70 70 $data = $socket->write(); 71 71 }
