public function read( $curlOptions = array() )
	{
		$curl		= new Net_CURL( $this->url );

		$curl->setOption( CURLOPT_SSL_VERIFYHOST, $this->verifyHost );
		$curl->setOption( CURLOPT_SSL_VERIFYPEER, $this->verifyPeer );
		$curl->setOption( CURLOPT_FOLLOWLOCATION, !ini_get( 'safe_mode' ) && !ini_get( 'open_basedir' ) );
		$curl->setOption( CURLOPT_HEADER, TRUE );
		if( self::$userAgent )
			$curl->setOption( CURLOPT_USERAGENT, self::$userAgent );
		if( $this->username )
			$curl->setOption( CURLOPT_USERPWD, $this->username.":".$this->password );
		if( $this->proxyAddress ){
			$curl->setOption( CURLOPT_HTTPPROXYTUNNEL, TRUE);
			$curl->setOption( CURLOPT_PROXY, $this->proxyAddress );
			$curl->setOption( CURLOPT_PROXYTYPE, $this->proxyType );
			if( $this->proxyAuth )
				$curl->setOption( CURLOPT_PROXYUSERPWD, $this->proxyAuth );
		}

		foreach( $curlOptions as $key => $value )
		{
			if( is_string( $key ) )
			{
				if( !( preg_match( "@^CURLOPT_@", $key ) && defined( $key ) ) )
					throw new InvalidArgumentException( 'Invalid option constant key "'.$key.'"' );
				$key	= constant( $key );
			}
			if( !is_int( $key ) )
				throw new InvalidArgumentException( 'Option must be given as integer or string' );
			$curl->setOption( $key, $value );
		}
		$result			= $curl->exec( TRUE, FALSE );
		$response		= Net_HTTP_Response_Parser::fromString( $result );

		$this->body		= $response->getBody();
		$this->headers	= $response->getHeaders();
		$this->info		= $curl->getInfo();
		$code			= $curl->getInfo( Net_CURL::INFO_HTTP_CODE );
		$error			= $curl->getInfo( Net_CURL::INFO_ERROR );
		$errno			= $curl->getInfo( Net_CURL::INFO_ERRNO );
		if( $errno )
			throw new Exception_IO( 'HTTP request failed: '.$error, $errno, $this->url );
		if( !in_array( $code, array( '200', '301', '303', '304', '307' ) ) )
			throw new Exception_IO( 'HTTP request failed', $code, $this->url );
		return $this->body;
	}