Skip to content
This repository

Added new client: Samson\Protocol\Protocol\HTTP #64

Closed
wants to merge 5 commits into from

4 participants

Bart van den Burg Christophe Coevoet Kris Wallsmith Markus Bachmann
Bart van den Burg

This PR adds an optional dependency: samson/protocol.

The problem with Curl is that it isn't available on all installations and file_get_contents refuses to actually fetch contents if the return status is any other dan 2xx, meaning you can't get the actual error message for, for example, a 404 or 500 response.

This adds a third client, named Protocol. This one tries to do an HTTP request using bare sockets. The socket classes appear to be more common in PHP installations than CURL, so it should almost always work.

I ran the tests using the server.php script and they work as expected.

composer.json
@@ -16,7 +16,8 @@
16 16
         "php": ">=5.3.0"
17 17
     },
18 18
     "suggest": {
19  
-        "ext-curl": "*"
  19
+        "ext-curl": "*",
  20
+        "samson/protocol": "dev-master"
1
Christophe Coevoet
stof added a note

I don't think you should suggest dev-master explicitly as this version will change. You should either use a constraint targeting releases (if there is any) or * IMO

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
test/Buzz/Test/Client/FunctionalTest.php
((9 lines not shown))
143 143
         );
  144
+
  145
+        if (class_exists('Samson\Protocol\Protocol\HTTP', true)) {
1
Christophe Coevoet
stof added a note

you should remove the second argument as it is its default value

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Buzz/Client/Protocol.php
... ...
@@ -0,0 +1,22 @@
  1
+<?php
  2
+
  3
+namespace Buzz\Client;
  4
+
  5
+use Buzz\Message;
  6
+use Samson\Protocol\Protocol\HTTP;
  7
+class Protocol extends AbstractClient implements ClientInterface
1
Christophe Coevoet
stof added a note

missing empty line between the use statement and the class definition

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Buzz/Client/Protocol.php
((3 lines not shown))
  3
+namespace Buzz\Client;
  4
+
  5
+use Buzz\Message;
  6
+use Samson\Protocol\Protocol\HTTP;
  7
+class Protocol extends AbstractClient implements ClientInterface
  8
+{
  9
+    private $http;
  10
+
  11
+    public function __construct()
  12
+    {
  13
+        $this->http = new HTTP();
  14
+        $this->http->setTimeout($this->getTimeout());
  15
+    }
  16
+
  17
+    public function send(Message\Request $request, Message\Response $response)
  18
+    {
1
Christophe Coevoet
stof added a note

you should set the timeout according to the value configured in the client (inherited from AbstractClient)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Buzz/Client/Protocol.php
... ...
@@ -0,0 +1,22 @@
  1
+<?php
  2
+
  3
+namespace Buzz\Client;
  4
+
  5
+use Buzz\Message;
  6
+use Samson\Protocol\Protocol\HTTP;
  7
+class Protocol extends AbstractClient implements ClientInterface
  8
+{
  9
+    private $http;
  10
+
  11
+    public function __construct()
  12
+    {
  13
+        $this->http = new HTTP();
  14
+        $this->http->setTimeout($this->getTimeout());
1
Christophe Coevoet
stof added a note

this is wrong. The timeout is set by a setter, so after the constructor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Christophe Coevoet
stof commented

I don't like the way your library handles errors: it does not handle them and break the whole app in such case. die when the response is invalid is a no-go IMO

Bart van den Burg

@stof: you're right. I'll create an issue right away and fix it soon. Actually I wrote the script over a year ago and ported it into the library you see now, but I haven't had time to really polish it up yet. Hopefully I will be able to do it this evening

Bart van den Burg

the die is now replaced by a proper exception

Christophe Coevoet
stof commented

@Burgov you should implement the ignore_error in the adapter then.

And btw, does your library follow redirections ? If no, the adapter need to handle it

Kris Wallsmith
Owner

Please break this into smaller PRs.

Kris Wallsmith kriswallsmith closed this
Christophe Coevoet
stof commented

@kriswallsmith smaller PRs ? This only adds one new client implementation, and its tests

Kris Wallsmith
Owner

The change to how PHPUnit sets up autoloading should be a separate PR.

Kris Wallsmith
Owner

I should also say I'm hesitant to merge the new client. I would rather introduce a stream client than integrate with a vendor for that.

Markus Bachmann
Baachi commented

I agree with @kriswallsmith.
I would also prefer a stream or socket client without a vendor.

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.
3  composer.json
@@ -16,7 +16,8 @@
16 16
         "php": ">=5.3.0"
17 17
     },
18 18
     "suggest": {
19  
-        "ext-curl": "*"
  19
+        "ext-curl": "*",
  20
+        "samson/protocol": "*"
20 21
     },
21 22
     "autoload": {
22 23
         "psr-0": {
27  lib/Buzz/Client/Protocol.php
... ...
@@ -0,0 +1,27 @@
  1
+<?php
  2
+
  3
+namespace Buzz\Client;
  4
+
  5
+use Buzz\Message;
  6
+use Samson\Protocol\Protocol\HTTP;
  7
+
  8
+class Protocol extends AbstractClient implements ClientInterface
  9
+{
  10
+    private $http;
  11
+
  12
+    public function __construct()
  13
+    {
  14
+        $this->http = new HTTP();
  15
+    }
  16
+
  17
+    public function send(Message\Request $request, Message\Response $response)
  18
+    {
  19
+        $this->http->setTimeout($this->getTimeout());
  20
+        $this->http->setMaxRedirects($this->getMaxRedirects());
  21
+
  22
+        $raw = $this->http->request($request->getUrl(), $request->getMethod(), $request->getHeader
  23
+        list($headersRaw, $content) = explode("\r\n\r\n", $raw, 2);
  24
+        $response->setContent($content);
  25
+        $response->setHeaders(explode("\r\n", $headersRaw));
  26
+    }
  27
+}
2  phpunit.xml.dist
... ...
@@ -1,6 +1,6 @@
1 1
 <?xml version="1.0" encoding="UTF-8"?>
2 2
 
3  
-<phpunit bootstrap="./test/bootstrap.php" colors="true">
  3
+<phpunit bootstrap="./vendor/.composer/autoload.php" colors="true">
4 4
     <testsuites>
5 5
         <testsuite name="Buzz Test Suite">
6 6
             <directory suffix="Test.php">./test/Buzz/</directory>
38  test/Buzz/Test/Client/FunctionalTest.php
@@ -121,6 +121,34 @@ public function testConsecutiveRequests($client)
121 121
     /**
122 122
      * @dataProvider provideClient
123 123
      */
  124
+    public function testRedirection($client)
  125
+    {
  126
+        $request = new Request(Request::METHOD_GET);
  127
+        $request->fromUrl($_SERVER['TEST_SERVER'].'?redirect=3');
  128
+
  129
+        $response = new Response();
  130
+        $client->send($request, $response);
  131
+        $data = json_decode($response->getContent(), true);
  132
+
  133
+        $this->assertEquals('0', $data['GET']['redirect']);
  134
+    }
  135
+
  136
+    /**
  137
+     * @dataProvider provideClient
  138
+     * @expectedException RuntimeException
  139
+     */
  140
+    public function testTooMuchRedirection($client)
  141
+    {
  142
+        $request = new Request(Request::METHOD_GET);
  143
+        $request->fromUrl($_SERVER['TEST_SERVER'].'?redirect=8');
  144
+
  145
+        $response = new Response();
  146
+        $client->send($request, $response);
  147
+    }
  148
+
  149
+    /**
  150
+     * @dataProvider provideClient
  151
+     */
124 152
     public function testPlus($client)
125 153
     {
126 154
         $request = new FormRequest();
@@ -137,10 +165,16 @@ public function testPlus($client)
137 165
 
138 166
     public function provideClient()
139 167
     {
140  
-        return array(
  168
+        $return = array(
141 169
             array(new Curl()),
142  
-            array(new FileGetContents()),
  170
+            array(new FileGetContents())
143 171
         );
  172
+
  173
+        if (class_exists('Samson\Protocol\Protocol\HTTP')) {
  174
+            $return[] = array(new \Buzz\Client\Protocol());
  175
+        }
  176
+
  177
+        return $return;
144 178
     }
145 179
 
146 180
     public function provideClientAndMethod()
12  test/bootstrap.php
... ...
@@ -1,12 +0,0 @@
1  
-<?php
2  
-
3  
-spl_autoload_register(function($class)
4  
-{
5  
-    if (0 === strpos($class, 'Buzz\\')) {
6  
-        $file = __DIR__ . '/../lib/' . str_replace('\\', '/', $class) . '.php';
7  
-        if (file_exists($file)) {
8  
-            require_once $file;
9  
-            return true;
10  
-        }
11  
-    }
12  
-});
5  test/server.php
... ...
@@ -1,5 +1,10 @@
1 1
 <?php
2 2
 
  3
+if (isset($_GET['redirect']) && $_GET['redirect']) {
  4
+    header('Location: server.php?redirect='.($_GET['redirect']-1));
  5
+    exit;
  6
+}
  7
+
3 8
 echo json_encode(array(
4 9
     'SERVER' => $_SERVER,
5 10
     'GET'    => $_GET,
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.