Skip to content
This repository

Throw an exception before invalid response is parsed by getResponse() #1022

Closed
wants to merge 6 commits into from

4 participants

Piotr Sam Moffatt Louis Landry elinw
Piotr

to test: JHttpFactory::getHttp()->head('http://blah')

Parsing invalid response (false, "") throws PHP errors as getResponse() assumes $content is consists headers and content.

Piotr

In case of JHttpTransportStream,
PHP shows a Warning:
Warning: fopen($invaliduri) failed to open stream: HTTP request failed! in ~libraries\joomla\http\transport\stream.php on line 125

But I'm not sure if it's the right thing to supress the errors

Edit:
As I'm thinking about it, fopen should supress any PHP warnings.
Typical scenario may be when the response (after processing) is going to be output as JSON. Any PHP warnings are then appended to the response body, deforming the JSON output.

The check for no HTTP response that I added is supposed to handle it anyway

see: http://php.net/manual/en/function.fopen.php
If the open fails, an error of level E_WARNING is generated. You may use @ to suppress this warning.

Piotr

There is 1 error in Unit test (http://developer.joomla.org/pulls/pulls/1022.html) but seems like it's triggered by something strange outside this PR

Does this PR have any chance to be merged? There are few other issues in JHttp package but I decided to wait so this one can be still merged

Piotr

JHttpTransportCurl fixed by #1438

Sam Moffatt

You'll need to update to master because of the curl changes and would you mind putting in some code to check $php_errormsg for the stream handler so that we can get some insight at least there why it failed?

elinw elinw commented on the diff August 14, 2012
libraries/joomla/http/transport/socket.php
@@ -137,6 +137,12 @@ public function request($method, JUri $uri, $data = null, array $headers = null,
137 137
 			$content .= fgets($connection, 4096);
138 138
 		}
139 139
 
  140
+		// Received empty response (invalid uri, connection reached timeout);
  141
+		if ($content === "")
  142
+		{
  143
+			throw new RuntimeException('HTTP request failed');
  144
+		}
  145
+
140 146
 		return $this->getResponse($content);
141 147
 	}
142 148
 
2
elinw
elinw added a note August 14, 2012

What you are doing here is different than what I did in my pull request which relate to the warning from fsockopen() at line 256 similar to what you did with fopen() in stream.

Piotr
piotr-cz added a note August 15, 2012

I've tested all transports against invalid url and var_dump'ed the result:

  • for socket it was: ""
  • for curl and stream: false

So I've checked for empty response in the request method to be able to throw an exception in about the same place as in other transports.

Probably emphasizing an convention may not be optimal here as every transport is different.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Louis Landry

@piotr-cz would you mind rebasing this so we can potentially getting it merged? I'm gonna want to give it a test drive for sure, but I'd love to have consistency here. Can you think of a way we might be able to test it?

Note: I'm closing this until it is mergeable again, not because I'm rejecting the work. Please re-open the request when you get it ready to go.

Louis Landry LouisLandry closed this October 08, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
7  libraries/joomla/http/transport/curl.php
@@ -55,6 +55,7 @@ public function __construct(JRegistry $options)
55 55
 	 * @return  JHttpResponse
56 56
 	 *
57 57
 	 * @since   11.3
  58
+	 * @throws  RuntimeException
58 59
 	 */
59 60
 	public function request($method, JUri $uri, $data = null, array $headers = null, $timeout = null, $userAgent = null)
60 61
 	{
@@ -134,6 +135,12 @@ public function request($method, JUri $uri, $data = null, array $headers = null,
134 135
 		$content = curl_exec($ch);
135 136
 		curl_close($ch);
136 137
 
  138
+		// Received empty response (invalid uri, connection reached timeout);
  139
+		if ($content === false)
  140
+		{
  141
+			throw new RuntimeException('HTTP request failed');
  142
+		}
  143
+
137 144
 		return $this->getResponse($content);
138 145
 	}
139 146
 
6  libraries/joomla/http/transport/socket.php
@@ -137,6 +137,12 @@ public function request($method, JUri $uri, $data = null, array $headers = null,
137 137
 			$content .= fgets($connection, 4096);
138 138
 		}
139 139
 
  140
+		// Received empty response (invalid uri, connection reached timeout);
  141
+		if ($content === "")
  142
+		{
  143
+			throw new RuntimeException('HTTP request failed');
  144
+		}
  145
+
140 146
 		return $this->getResponse($content);
141 147
 	}
142 148
 
9  libraries/joomla/http/transport/stream.php
@@ -62,6 +62,7 @@ public function __construct(JRegistry $options)
62 62
 	 * @return  JHttpResponse
63 63
 	 *
64 64
 	 * @since   11.3
  65
+	 * @throws  RuntimeException
65 66
 	 */
66 67
 	public function request($method, JUri $uri, $data = null, array $headers = null, $timeout = null, $userAgent = null)
67 68
 	{
@@ -122,7 +123,13 @@ public function request($method, JUri $uri, $data = null, array $headers = null,
122 123
 		$context = stream_context_create(array('http' => $options));
123 124
 
124 125
 		// Open the stream for reading.
125  
-		$stream = fopen((string) $uri, 'r', false, $context);
  126
+		$stream = @fopen((string) $uri, 'r', false, $context);
  127
+
  128
+		// When fopen($uri) returns false (invalid uri, connection reached timeout)
  129
+		if ($stream === false)
  130
+		{
  131
+			throw new RuntimeException('HTTP request failed');
  132
+		}
126 133
 
127 134
 		// Get the metadata for the stream, including response headers.
128 135
 		$metadata = stream_get_meta_data($stream);
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.