Giter Club home page Giter Club logo

fetch's People

Contributors

dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar g105b avatar j4m3s avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

fetch's Issues

Synchronous text, json, arraybuffer, blob functions

Following off of #88 , this thought needs its own issue...

More often than not, I reach for PhpGt/Fetch only because it's my own library, and not because it's the best tool for the job. I hardly ever actually need to make an asynchronous HTTP call, but I still work with Fetch so that I'm eating my own dogfood.

But if I'm always using it for a simple HTTP request, and I always want the HTTP body without anything else, there should be helper functions on the Http class (and possibly exposed globally like with #88).

My idea would allow something like this:

$json = $http->fetchJson("https://api.example.com/getInfo");
echo "Hello, ", $json->getString("name");

Rather than the current approach:

$http->fetch("https://api.example.com/getInfo")
->then(function(Response $response) {
  return $response->json();
})->then(function(JsonObject $json) {
  echo "Hello, ", $json->getString("name");
});

Json->getStdClass()

Would be useful to get the actual StdClass object that the Json class is representing.

PSR-18

We have compatibility with PSR-7 and PHP-HTTP, and can probably implement PSR-18 without any fuss.

BodyResponse promise is not resolving

Here's a sample program:

<?php
require(__DIR__ . "/vendor/autoload.php");

use Gt\Fetch\Http;
use Gt\Fetch\BodyResponse;

$http = new Http();

$http->fetch("http://atlas.srv.brightflair.com/slow.php?i=1&num=2000")
->then(function(BodyResponse $response) {
        if($response->ok) {
                echo "Response 1 OK. Getting text..." . PHP_EOL;
                return $response->text();
        }
})
->then(function(string $text) {
        echo "Full response 1 is " . strlen($text) . " bytes!" . PHP_EOL;
});

$http->wait();

echo "The script has completed. Has the final callback been called?";

The RequestResolver class works a treat. The BodyResponse is resolved as soon as the headers come back from the Curl request, so when "Response 1 OK. Getting text..." is written, the body contents is still streaming in via the React loop.

The problem is that even though the BodyResponse is resolved (see snippet below), the outer Promise never resolves.

This runs: https://github.com/PhpGt/fetch/blob/97aaaae4f4b78dae921cca262534a885b92acbab/src/BodyResponse.php#L58-L68 , but the final ->then does not run.

FormData to send data using x-www-form-urlencoded

Pass the request body as a FormData object to automatically set the correct content type.

Currently trying to decide whether the FormData object should be the responsibility of this repository, or PHP.Gt/Http instead.

Json response object improvement

Needs a toString function to return the encoded text. Sub-objects should also be Json type, allowing for toString of only certain properties.

Json object should expose getString, getInt, ... functions that are throughout php.gt projects.

Json object should be iterable over keys and values.

Subresource integrity

Currently not implemented but should probably be a feature of PHP.Gt/Curl or PHP.Gt/Http.

AbortSignal init parameter

The AbortSignal callback should be passed in to cancel any ongoing requests from code external to the async loop.

Internal errors parsing response are not triggering "catch" functions

There's a purposefully broken JSON file in the repository that can be used to reproduce this issue.

Take the first example script at example/01-basic-fetch.php, but change the URL to the broken JSON (https://github.com/PhpGt/Fetch/blob/59a3d1c447fd44d94ea389404c3a2595d98629ce/broken.json), and the JSONDecodeException will be thrown to the main thread, rather than caught and passed to the catch function.

Full code example to reproduce:

<?php
require(implode(DIRECTORY_SEPARATOR, ["..", "vendor", "autoload.php"]));

use Gt\Fetch\Http;
use Gt\Fetch\Response\Blob;
use Gt\Fetch\Response\BodyResponse;
use Gt\Json\JsonKvpObject;
use Gt\Json\JsonPrimitive\JsonArrayPrimitive;

$http = new Http();

$http->fetch("https://raw.githubusercontent.com/PhpGt/Fetch/master/broken.json")
	->then(function(BodyResponse $response) {
		if(!$response->ok) {
			throw new RuntimeException("Can't retrieve Github's API on $response->uri");
		}

		return $response->json();
	})
	->then(function(JsonArrayPrimitive $json) {
		echo "SUCCESS: Json promise resolved!", PHP_EOL;
		echo "PHP.Gt has the following repositories: ";
		$repoList = [];
		/** @var JsonKvpObject $item */
		foreach($json->getPrimitiveValue() as $item) {
			array_push($repoList, $item->getString("name"));
		}

		echo wordwrap(implode(", ", $repoList)) . ".";
		echo PHP_EOL, PHP_EOL;
	})
	->catch(function(Throwable $reason) {
// THIS FUNCTION SHOULD TRIGGER, BUT DOESN'T!
		echo "ERROR: ", PHP_EOL, $reason->getMessage(), PHP_EOL, PHP_EOL;
	});

$http->wait();

I've tried to isolate this issue within the Promise implementation, but I can't, so I think there must be something I'm doing wrong in the way a new promise is created within the json() function, but as far as I can see, the exception is being thrown from calling $builder->fromJsonString($resolvedValue), but it isn't getting caught for some reason.

Use Http/Promise interface

The reason this is classed as a bug is because currently, using React's Promise library breaks PSR-5 as it doesn't implement the interface.

Stress test and concurrency limit

If many requests are sent in parallel, this will likely max out the CPU and cause issues. There could be a locking mechanism used to only allow a certain number of incoming handles' bytes at any one point.

FormData type

This is probably something to implement in PHP.Gt/Http. The BodyResponse::formData() function should return an actual FormData object, and the fetch() function should be able to set a FormData as its body as per #44.

Difference between blob/text ?

In PHP, binary data is represented in strings, so the BodyResponse::blob() resolved data is exactly the same as BodyResponse::text(). This might be OK, but is there some functionality missing in the text function? Maybe the output should be forced into a particular charset, for example?

Example code.

<?php

$http = new \phpgt\fetch\Http();

$http->get("http://example.com/photograph.jpg")
->then(function($response) {
    return $response->blob();
})
->then(function($blob) {
    file_put_contents(OUTPUT_FILE, $blob);
});

$http->get("http://example.com/page.html")
->then(function($response) {
    return $response->body();
})
->then(function($body) {
    echo "Got HTML: $body";
});

// Wait for promises to resolve:

// ... using another promise ...
$http->all()->then(function() {
    completed_everything();
});

// ... or wait until they are resolved before continuing ...
$http->wait();
completed_everything();

Curl and CurlMulti interfaces.

Defining an interface for containing Curl methods promotes tidy code, but most importantly allows testing of remote calls through DI.

Body stream is empty!

Pretty major bug here... since refactoring the Response into the new BodyResponse (so we can isolate the fetch-specific functions), the body stream always comes back empty. Needs investigating.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.