Simple handler system used to power clients and servers in PHP (this project is no longer used in Guzzle 6+)

Related tags

HTTP RingPHP
Overview

RingPHP

Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function. RingPHP be used to power HTTP clients and servers through a PHP function that accepts a request hash and returns a response hash that is fulfilled using a promise, allowing RingPHP to support both synchronous and asynchronous workflows.

By abstracting the implementation details of different HTTP clients and servers, RingPHP allows you to utilize pluggable HTTP clients and servers without tying your application to a specific implementation.

<?php
require 'vendor/autoload.php';

use GuzzleHttp\Ring\Client\CurlHandler;

$handler = new CurlHandler();
$response = $handler([
    'http_method' => 'GET',
    'uri'         => '/',
    'headers'     => [
        'host'  => ['www.google.com'],
        'x-foo' => ['baz']
    ]
]);

$response->then(function (array $response) {
    echo $response['status'];
});

$response->wait();

RingPHP is inspired by Clojure's Ring, which, in turn, was inspired by Python's WSGI and Ruby's Rack. RingPHP is utilized as the handler layer in Guzzle 5.0+ to send HTTP requests.

Documentation

See http://ringphp.readthedocs.org/ for the full online documentation.

Comments
  • Error descriptions provided also in absence of curl_strerror() function ...

    Error descriptions provided also in absence of curl_strerror() function ...

    ...(PHP version < 5.5)

    This little addition allows clear text error descriptions also for PHP 5.4 and earlier. I don't check for the existence of curl_error as it exists along curl_errno since PHP v4.0.3.

    opened by silverdr 5
  • WIP: Invalid content-length response header with decode_content option

    WIP: Invalid content-length response header with decode_content option

    When the decode_contentoption is enabled and the server return an encoded response, the returned content-length and content-encoding headers must be fixed.

    This problem was already reported and fixed in Guzzle 6+. See https://github.com/guzzle/guzzle/issues/1075

    opened by ajgarlag 3
  • [Stream] Fix stream ssl verify

    [Stream] Fix stream ssl verify

    Hey!

    I'm currently implementing SSL verification in egeloen/ivory-http-adapter#62 which test all adapters of guzzle http in order to be sure everything is working fine. When doing it, I discover an inconsitence between Curl (Single/Multi) and the Stream one. Basically, in my test suite I have generated a self signed certificate which allow me to test the feature. For Curl and MultiCurl, if I enable ssl verification, I got an exception because it does not allow self signed cetificate whereas the stream one does not use the same strategy and allow it. This PR rationalizes this behavior.

    Feedback welcome!

    opened by egeloen 3
  • Calling then() on FutureArray or FutureValue returns a new FutureArray or FutureValue, not just a PromiseInterface

    Calling then() on FutureArray or FutureValue returns a new FutureArray or FutureValue, not just a PromiseInterface

    When calling then() on a FutureArray or FutureValue, an instance of FutureInterface is returned. It would be nice if an instance of FutureArray or FutureValue would be returned instead.

    Typical use case

    I have a service that communicates with ElasticSearch via their PHP library (that for async calls returns a FutureArray) and the service somehow processes the result (the ES response contains lots of stuff I don't need) - that's where the then() method comes to play.

    I want to use the service output in both a cli command (for one-time testing/debug/...) and a worker that runs completely asynchronously in an event loop. That means in the first case, I would get the result by calling wait() and in the second one, I would simply chain another then() call to the service output.

    Problem

    Calling then() on the FutureArray returns a PromiseInterface (the result of calling then() on the wrapped promise) and I am unable to block until a result is available using the wait() method because it simply does not exist in React promises.

    Solution

    The then() method can return a new FutureArray that simply wraps the result originally returned.

    Considering the FutureArray already implements PromiseInterface, this should be no BC break.

    Instead of new self(...) the method could use late static binding and call new static(...) but the only difference would be if someone subclassed FutureArray. And in such case, it is quite possible that they created their own constructor with a different signature.

    The same applies to FutureValue.

    I have included two unit tests that test that the then() method returns the apprioriate class instance and that the returned value was processed by the callback.

    opened by Andrewsville 2
  • debug=false validation added

    debug=false validation added

    If you call Guzzle client using debug=false (having curl disabled) you get printed debug information, since actually right now its just validating that the key exists but your are not checking the value.

    opened by mustela 2
  • Fix reverse ordering of same name headers

    Fix reverse ordering of same name headers

    When received multiple Set-Cookie headers in same response, after parseHeaderOutput the cookies order is reversed. Can break in situations where order of cookies is important because later in guzzlehttp/guzzle setCookie is changing the content of the same-name cookie. Therefore instead of eventually ending in cookieJar with the newest cookie value, we are left with the oldest. This for example has the effect of breaking secure logins in many servers.

    opened by lygav 2
  • The result of CurlFactory::retryFailedRewind should return an array

    The result of CurlFactory::retryFailedRewind should return an array

    When curl has the error status "65" "rewind failed". Which can happen when putting a big file via a resource. Which gets a redirect as response. Then this flow will happen:

    We have a curl error https://github.com/PBWebMedia/RingPHP/blob/master/src/Client/CurlFactory.php#L90

    return !empty($response['curl']['errno']) || !isset($response['status'])
                ? self::createErrorResponse($handler, $request, $response)
                : $response;
    

    We have error number 65 https://github.com/PBWebMedia/RingPHP/blob/master/src/Client/CurlFactory.php#L112

    // Retry when nothing is present or when curl failed to rewind.
            if (!isset($response['err_message'])
                && (empty($response['curl']['errno'])
                    || $response['curl']['errno'] == 65)
            ) {
                return self::retryFailedRewind($handler, $request, $response);
            }
    

    Nothing of the above happens so we run the handle (gues he follows the redirect) https://github.com/PBWebMedia/RingPHP/blob/master/src/Client/CurlFactory.php#L544

    return $handler($request);
    

    But the problem here is that the handle does not return an array but an CompletedFutureArray

    Here is the handle set: https://github.com/guzzle/RingPHP/blob/master/src/Client/CurlHandler.php#L78

    return new CompletedFutureArray(
                CurlFactory::createResponse($this, $request, $response, $hd, $bd)
            );
    

    As we can see in the row above that will return a CompletedFutureArray

    Which it will put in CompletedFutureArray::__construct() But the constructor accepts an array and not a CompletedFutureArray.

    I thought it would be weird to modify CompletedFutureArray so it can also accept itself. It seemed more clean to make sure that CurlFactory::createResponse always return an array instead having 1 case that returns an object.

    opened by JordyMoos 1
  • Allow listeners to send requests asynchronously

    Allow listeners to send requests asynchronously

    Currently, the adapter may process any new requests added by listeners one curl_multi_select cycle late. For example, a complete listener sends a new request (on the line $this->processMessages();), which results in curl_multi_add_handle being called, but after that the execute loop will call curl_multi_select waiting for a previous request to be completed before adding the new request to the multi pool via curl_multi_exec.

    Hope I managed to described the problem well. I know it's only a copy-paste of previous few lines, but I don't have a better idea at the moment. Here at ManageWP we use our own fork of the CurlMultiAdapter for Guzzle 4, but it seems it's much easier for Guzzle 5 to implement this functionality.

    opened by Briareos 1
  • headres from lines function bug fix

    headres from lines function bug fix

    when headers coming from curl are like this Set-cookie: a=b Set-Cookie: c=d then there is a bug, because of associative array of headers keys of array of headers are case-sensitive

    opened by sullyj 1
  • Add resilience to the integration tests' NodeJS server

    Add resilience to the integration tests' NodeJS server

    Make the test server aware that its http-auth module is not available, when responding to an authentified request. Now, in this situation (authentified query AND http-auth not here) the server will not crash, but will reply with an HTTP 501.

    opened by outtersg 1
  • Extract response protocol version

    Extract response protocol version

    Hey!

    This PR extracts the response protocol version in order to propagate it in the response. Without this extraction/parsing, the response always get an 1.1 protocol version (default value) even when the response is an 1.0 one.

    opened by egeloen 0
Releases(1.1.1)
  • 1.1.1(Jul 31, 2018)

  • 1.0.6(Feb 26, 2015)

    • Bug fix: futures now extend from React's PromiseInterface to ensure that they are properly forwarded down the promise chain.
    • The multi handle of the CurlMultiHandler is now created lazily.
    Source code(tar.gz)
    Source code(zip)
  • 1.0.5(Dec 11, 2014)

  • 1.0.4(Dec 2, 2014)

    • Added support for older versions of cURL that do not have CURLOPT_TIMEOUT_MS.
    • Setting debug to false does not enable debug output.
    • Added a fix to the StreamHandler to return a FutureArrayInterface when an error occurs.
    Source code(tar.gz)
    Source code(zip)
  • 1.0.3(Nov 4, 2014)

    • Setting the header stream option as a string to be compatible with GAE.
    • Header parsing now ensures that header order is maintained in the parsed message.
    Source code(tar.gz)
    Source code(zip)
  • 1.0.2(Oct 29, 2014)

  • 1.0.1(Oct 26, 2014)

    • Fixed a header parsing issue with the CurlHandler and CurlMultiHandler that caused cURL requests with multiple responses to merge repsonses together (e.g., requests with digest authentication).
    Source code(tar.gz)
    Source code(zip)
Owner
Guzzle
An extensible PHP HTTP client
Guzzle
A HTTP Cache for Guzzle 6. It's a simple Middleware to be added in the HandlerStack.

A HTTP Cache for Guzzle 6. It's a simple Middleware to be added in the HandlerStack.

Kevin Robatel 371 Dec 17, 2022
Guzzle, an extensible PHP HTTP client

Guzzle, PHP HTTP client Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and trivial to integrate with web services. Simple interf

Guzzle 22.3k Jan 2, 2023
Supercharge your app or SDK with a testing library specifically for Guzzle

Full Documentation at guzzler.dev Supercharge your app or SDK with a testing library specifically for Guzzle. Guzzler covers the process of setting up

null 275 Oct 30, 2022
Server emulator for the Hasbro Em@il Games clients

HasbroPBEMProxy Greg Kennedy, 2021 Server emulator for the Hasbro Em@il Games clients About In 1999 Hasbro launched a series of games under the "Em@il

Greg Kennedy 4 Dec 20, 2022
librestful is a virion for PocketMine servers that make easier, readable code and for async http requests.

librestful is a virion for PocketMine servers that make easier, readable code for async rest requests.

RedMC Network 17 Oct 31, 2022
Just HTTP Status Codes is a great way to empower your project with clean practice 💫

The Simplest & Cleanest HTTP Status Codes for PHP. All PHP HTTP Status Codes are stored into beautiful constant names ?? Ideal when you develop an API that involves various HTTP codes ??

♚ PH⑦ de Soria™♛ 10 Dec 18, 2022
A simple PHP Toolkit to parallel generate combinations, save and use the generated terms to brute force attack via the http protocol.

Brutal A simple PHP Toolkit to parallel generate combinations, save and use the generated terms to apply brute force attack via the http protocol. Bru

Jean Carlo de Souza 4 Jul 28, 2021
A functional and simple rate limit control to prevent request attacks ready-to-use for PHP.

RateLimitControl A functional and simple rate limit control to prevent request attacks ready-to-use for PHP. Features: Prepared statements (using PDO)

b(i*2)tez 5 Sep 16, 2022
A simple yet powerful HTTP metadata and assets provider for NFT collections using Symfony

Safe NFT Metadata Provider A simple yet powerful HTTP metadata and assets provider for NFT collections using Symfony.

HashLips Lab 66 Oct 7, 2022
Simple PHP curl wrapper class

php-curl The smallest possible OOP wrapper for PHP's curl capabilities. Note that this is not meant as a high-level abstraction. You should still know

Andreas Lutro 243 Dec 5, 2022
Zenscrape package is a simple PHP HTTP client-provider that makes it easy to parsing site-pages

Zenscrape package is a simple PHP HTTP client-provider that makes it easy to parsing site-pages

Andrei 3 Jan 17, 2022
Simple HTTP cURL client for PHP 7.1+ based on PSR-18

Simple HTTP cURL client for PHP 7.1+ based on PSR-18 Installation composer require sunrise/http-client-curl QuickStart composer require sunrise/http-f

Sunrise // PHP 15 Sep 5, 2022
A simple OOP wrapper to work with HTTP headers in PHP

Headers This package is to allow you to create HTTP Headers in PHP, in a simple and reliable way. Installation composer require http-php/headers Usage

null 5 Aug 9, 2022
A simple script i made that generate a valid http(s) proxy in json format with its geo-location info

Gev Proxy Generator GPG is a simple PHP script that generate a proxy using free services on the web, the proxy is HTTP(s) and it generate it in json f

gev 1 Nov 15, 2021
Satis Control Panel (SCP) is a simple web UI for managing your Satis Repository for Composer Packages.

Satis Control Panel Satis Control Panel (SCP) is a simple web UI for managing your Satis Repository for Composer Packages. SCP backend is written in L

Lukáš Homza 152 Nov 18, 2022
Requests for PHP is a humble HTTP request library. It simplifies how you interact with other sites and takes away all your worries.

Requests for PHP Requests is a HTTP library written in PHP, for human beings. It is roughly based on the API from the excellent Requests Python librar

null 3.5k Dec 31, 2022
Requests for PHP is a humble HTTP request library. It simplifies how you interact with other sites and takes away all your worries.

Requests for PHP Requests is a HTTP library written in PHP, for human beings. It is roughly based on the API from the excellent Requests Python librar

null 3.5k Dec 31, 2022
PHP Curl Class makes it easy to send HTTP requests and integrate with web APIs

PHP Curl Class: HTTP requests made easy PHP Curl Class makes it easy to send HTTP requests and integrate with web APIs. Installation Requirements Quic

null 3.1k Jan 5, 2023