Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add factory methods for common HTML/JSON/plaintext/XML response types #439

Merged
merged 2 commits into from
Feb 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
321 changes: 220 additions & 101 deletions README.md

Large diffs are not rendered by default.

13 changes: 3 additions & 10 deletions examples/51-server-hello-world.php
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
<?php

use Psr\Http\Message\ServerRequestInterface;
use React\Http\Message\Response;

require __DIR__ . '/../vendor/autoload.php';

$http = new React\Http\HttpServer(function (ServerRequestInterface $request) {
return new Response(
Response::STATUS_OK,
array(
'Content-Type' => 'text/plain'
),
"Hello world\n"
$http = new React\Http\HttpServer(function (Psr\Http\Message\ServerRequestInterface $request) {
return React\Http\Message\Response::plaintext(
"Hello World!\n"
);
});

Expand Down
11 changes: 2 additions & 9 deletions examples/52-server-count-visitors.php
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
<?php

use Psr\Http\Message\ServerRequestInterface;
use React\Http\Message\Response;

require __DIR__ . '/../vendor/autoload.php';

$counter = 0;
$http = new React\Http\HttpServer(function (ServerRequestInterface $request) use (&$counter) {
return new Response(
Response::STATUS_OK,
array(
'Content-Type' => 'text/plain'
),
$http = new React\Http\HttpServer(function (Psr\Http\Message\ServerRequestInterface $request) use (&$counter) {
return React\Http\Message\Response::plaintext(
"Welcome number " . ++$counter . "!\n"
);
});
Expand Down
13 changes: 3 additions & 10 deletions examples/53-server-whatsmyip.php
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
<?php

use Psr\Http\Message\ServerRequestInterface;
use React\Http\Message\Response;

require __DIR__ . '/../vendor/autoload.php';

$http = new React\Http\HttpServer(function (ServerRequestInterface $request) {
$body = "Your IP is: " . $request->getServerParams()['REMOTE_ADDR'];
$http = new React\Http\HttpServer(function (Psr\Http\Message\ServerRequestInterface $request) {
$body = "Your IP is: " . $request->getServerParams()['REMOTE_ADDR'] . "\n";

return new Response(
Response::STATUS_OK,
array(
'Content-Type' => 'text/plain'
),
return React\Http\Message\Response::plaintext(
$body
);
});
Expand Down
11 changes: 2 additions & 9 deletions examples/54-server-query-parameter.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
<?php

use Psr\Http\Message\ServerRequestInterface;
use React\Http\Message\Response;

require __DIR__ . '/../vendor/autoload.php';

$http = new React\Http\HttpServer(function (ServerRequestInterface $request) {
$http = new React\Http\HttpServer(function (Psr\Http\Message\ServerRequestInterface $request) {
$queryParams = $request->getQueryParams();

$body = 'The query parameter "foo" is not set. Click the following link ';
Expand All @@ -15,11 +12,7 @@
$body = 'The value of "foo" is: ' . htmlspecialchars($queryParams['foo']);
}

return new Response(
Response::STATUS_OK,
array(
'Content-Type' => 'text/html'
),
return React\Http\Message\Response::html(
$body
);
});
Expand Down
24 changes: 6 additions & 18 deletions examples/55-server-cookie-handling.php
Original file line number Diff line number Diff line change
@@ -1,33 +1,21 @@
<?php

use Psr\Http\Message\ServerRequestInterface;
use React\Http\Message\Response;

require __DIR__ . '/../vendor/autoload.php';

$http = new React\Http\HttpServer(function (ServerRequestInterface $request) {
$http = new React\Http\HttpServer(function (Psr\Http\Message\ServerRequestInterface $request) {
$key = 'react\php';

if (isset($request->getCookieParams()[$key])) {
$body = "Your cookie value is: " . $request->getCookieParams()[$key];
$body = "Your cookie value is: " . $request->getCookieParams()[$key] . "\n";

return new Response(
Response::STATUS_OK,
array(
'Content-Type' => 'text/plain'
),
return React\Http\Message\Response::plaintext(
$body
);
}

return new Response(
Response::STATUS_OK,
array(
'Content-Type' => 'text/plain',
'Set-Cookie' => urlencode($key) . '=' . urlencode('test;more')
),
"Your cookie has been set."
);
return React\Http\Message\Response::plaintext(
"Your cookie has been set.\n"
)->withHeader('Set-Cookie', urlencode($key) . '=' . urlencode('test;more'));
});

$socket = new React\Socket\SocketServer(isset($argv[1]) ? $argv[1] : '0.0.0.0:0');
Expand Down
22 changes: 9 additions & 13 deletions examples/56-server-sleep.php
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
<?php

use Psr\Http\Message\ServerRequestInterface;
use React\EventLoop\Loop;
use React\Http\Message\Response;
use React\Promise\Promise;

require __DIR__ . '/../vendor/autoload.php';

$http = new React\Http\HttpServer(function (ServerRequestInterface $request) {
return new Promise(function ($resolve, $reject) {
$http = new React\Http\HttpServer(function (Psr\Http\Message\ServerRequestInterface $request) {
$promise = new React\Promise\Promise(function ($resolve, $reject) {
Loop::addTimer(1.5, function() use ($resolve) {
$response = new Response(
Response::STATUS_OK,
array(
'Content-Type' => 'text/plain'
),
"Hello world"
);
$resolve($response);
$resolve();
});
});

return $promise->then(function () {
return React\Http\Message\Response::plaintext(
"Hello world!\n"
);
});
});

$socket = new React\Socket\SocketServer(isset($argv[1]) ? $argv[1] : '0.0.0.0:0');
Expand Down
28 changes: 8 additions & 20 deletions examples/57-server-error-handling.php
Original file line number Diff line number Diff line change
@@ -1,30 +1,18 @@
<?php

use Psr\Http\Message\ServerRequestInterface;
use React\Http\Message\Response;
use React\Promise\Promise;

require __DIR__ . '/../vendor/autoload.php';

$count = 0;
$http = new React\Http\HttpServer(function (ServerRequestInterface $request) use (&$count) {
return new Promise(function ($resolve, $reject) use (&$count) {
$count++;

if ($count%2 === 0) {
throw new Exception('Second call');
}
$http = new React\Http\HttpServer(function (Psr\Http\Message\ServerRequestInterface $request) use (&$count) {
$count++;

$response = new Response(
Response::STATUS_OK,
array(
'Content-Type' => 'text/plain'
),
"Hello World!\n"
);
if ($count % 2 === 0) {
throw new Exception('Second call');
}

$resolve($response);
});
return React\Http\Message\Response::plaintext(
"Hello World!\n"
);
});

$socket = new React\Socket\SocketServer(isset($argv[1]) ? $argv[1] : '0.0.0.0:0');
Expand Down
3 changes: 1 addition & 2 deletions examples/58-server-stream-response.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
<?php

use Psr\Http\Message\ServerRequestInterface;
use React\EventLoop\Loop;
use React\Http\Message\Response;
use React\Stream\ThroughStream;

require __DIR__ . '/../vendor/autoload.php';

$http = new React\Http\HttpServer(function (ServerRequestInterface $request) {
$http = new React\Http\HttpServer(function (Psr\Http\Message\ServerRequestInterface $request) {
if ($request->getMethod() !== 'GET' || $request->getUri()->getPath() !== '/') {
return new Response(Response::STATUS_NOT_FOUND);
}
Expand Down
41 changes: 12 additions & 29 deletions examples/59-server-json-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,49 +6,32 @@
// $ php examples/59-server-json-api.php 8080
// $ curl -v http://localhost:8080/ -H 'Content-Type: application/json' -d '{"name":"Alice"}'

use Psr\Http\Message\ServerRequestInterface;
use React\Http\Message\Response;

require __DIR__ . '/../vendor/autoload.php';

$http = new React\Http\HttpServer(function (ServerRequestInterface $request) {
$http = new React\Http\HttpServer(function (Psr\Http\Message\ServerRequestInterface $request) {
if ($request->getHeaderLine('Content-Type') !== 'application/json') {
return new Response(
Response::STATUS_UNSUPPORTED_MEDIA_TYPE,
array(
'Content-Type' => 'application/json'
),
json_encode(array('error' => 'Only supports application/json')) . "\n"
);
return Response::json(
array('error' => 'Only supports application/json')
)->withStatus(Response::STATUS_UNSUPPORTED_MEDIA_TYPE);
}

$input = json_decode($request->getBody()->getContents());
if (json_last_error() !== JSON_ERROR_NONE) {
return new Response(
Response::STATUS_BAD_REQUEST,
array(
'Content-Type' => 'application/json'
),
json_encode(array('error' => 'Invalid JSON data given')) . "\n"
);
return Response::json(
array('error' => 'Invalid JSON data given')
)->withStatus(Response::STATUS_BAD_REQUEST);
}

if (!isset($input->name) || !is_string($input->name)) {
return new Response(
Response::STATUS_UNPROCESSABLE_ENTITY,
array(
'Content-Type' => 'application/json'
),
json_encode(array('error' => 'JSON data does not contain a string "name" property')) . "\n"
);
return Response::json(
array('error' => 'JSON data does not contain a string "name" property')
)->withStatus(Response::STATUS_UNPROCESSABLE_ENTITY);
}

return new Response(
Response::STATUS_OK,
array(
'Content-Type' => 'application/json'
),
json_encode(array('message' => 'Hello ' . $input->name)) . "\n"
return Response::json(
array('message' => 'Hello ' . $input->name)
);
});

Expand Down
13 changes: 3 additions & 10 deletions examples/61-server-hello-world-https.php
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
<?php

use Psr\Http\Message\ServerRequestInterface;
use React\Http\Message\Response;

require __DIR__ . '/../vendor/autoload.php';

$http = new React\Http\HttpServer(function (ServerRequestInterface $request) {
return new Response(
Response::STATUS_OK,
array(
'Content-Type' => 'text/plain'
),
"Hello world!\n"
$http = new React\Http\HttpServer(function (Psr\Http\Message\ServerRequestInterface $request) {
return React\Http\Message\Response::plaintext(
"Hello World!\n"
);
});

Expand Down
6 changes: 1 addition & 5 deletions examples/62-server-form-upload.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,7 @@

HTML;

return new Response(
Response::STATUS_OK,
array(
'Content-Type' => 'text/html; charset=UTF-8'
),
return Response::html(
$html
);
};
Expand Down
14 changes: 3 additions & 11 deletions examples/63-server-streaming-request.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,16 @@ function (Psr\Http\Message\ServerRequestInterface $request) {
});

$body->on('end', function () use ($resolve, &$bytes){
$resolve(new React\Http\Message\Response(
React\Http\Message\Response::STATUS_OK,
array(
'Content-Type' => 'text/plain'
),
$resolve(React\Http\Message\Response::plaintext(
"Received $bytes bytes\n"
));
});

// an error occures e.g. on invalid chunked encoded data or an unexpected 'end' event
$body->on('error', function (Exception $e) use ($resolve, &$bytes) {
$resolve(new React\Http\Message\Response(
React\Http\Message\Response::STATUS_BAD_REQUEST,
array(
'Content-Type' => 'text/plain'
),
$resolve(React\Http\Message\Response::plaintext(
"Encountered error after $bytes bytes: {$e->getMessage()}\n"
));
)->withStatus(React\Http\Message\Response::STATUS_BAD_REQUEST));
});
});
}
Expand Down
24 changes: 6 additions & 18 deletions examples/71-server-http-proxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,17 @@
// $ php examples/71-server-http-proxy.php 8080
// $ curl -v --proxy http://localhost:8080 http://reactphp.org/

use Psr\Http\Message\RequestInterface;
use React\Http\Message\Response;
use RingCentral\Psr7;

require __DIR__ . '/../vendor/autoload.php';

// Note how this example uses the `HttpServer` without the `StreamingRequestMiddleware`.
// This means that this proxy buffers the whole request before "processing" it.
// As such, this is store-and-forward proxy. This could also use the advanced
// `StreamingRequestMiddleware` to forward the incoming request as it comes in.
$http = new React\Http\HttpServer(function (RequestInterface $request) {
$http = new React\Http\HttpServer(function (Psr\Http\Message\ServerRequestInterface $request) {
if (strpos($request->getRequestTarget(), '://') === false) {
return new Response(
Response::STATUS_BAD_REQUEST,
array(
'Content-Type' => 'text/plain'
),
'This is a plain HTTP proxy'
);
return React\Http\Message\Response::plaintext(
"This is a plain HTTP proxy\n"
)->withStatus(React\Http\Message\Response::STATUS_BAD_REQUEST);
}

// prepare outgoing client request by updating request-target and Host header
Expand All @@ -35,12 +27,8 @@
// pseudo code only: simply dump the outgoing request as a string
// left up as an exercise: use an HTTP client to send the outgoing request
// and forward the incoming response to the original client request
return new Response(
Response::STATUS_OK,
array(
'Content-Type' => 'text/plain'
),
Psr7\str($outgoing)
return React\Http\Message\Response::plaintext(
RingCentral\Psr7\str($outgoing)
);
});

Expand Down
6 changes: 1 addition & 5 deletions examples/99-server-benchmark-download.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,7 @@ public function getSize()
$http = new React\Http\HttpServer(function (ServerRequestInterface $request) {
switch ($request->getUri()->getPath()) {
case '/':
return new Response(
Response::STATUS_OK,
array(
'Content-Type' => 'text/html'
),
return Response::html(
'<html><a href="1g.bin">1g.bin</a><br/><a href="10g.bin">10g.bin</a></html>'
);
case '/1g.bin':
Expand Down
Loading