Last active
December 9, 2022 02:51
-
-
Save xcaptain/d3184e2d5c75bea3c420c61872c37a69 to your computer and use it in GitHub Desktop.
server lumen app using amphp-server
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Amp\Http\Server\RequestHandler\CallableRequestHandler; | |
use Amp\Http\Server\Server; | |
use Amp\Http\Server\Request; | |
use Amp\Http\Server\Response; | |
use Amp\Http\Status; | |
use Amp\Socket; | |
use Symfony\Component\HttpFoundation\Request as SymfonyRequest; | |
use Symfony\Component\HttpFoundation\File\UploadedFile; | |
use Monolog\Logger; | |
use Monolog\Handler\StreamHandler; | |
/* | |
|-------------------------------------------------------------------------- | |
| Create The Application | |
|-------------------------------------------------------------------------- | |
| | |
| First we need to get an application instance. This creates an instance | |
| of the application / container and bootstraps the application so it | |
| is ready to receive HTTP / Console requests from the environment. | |
| | |
*/ | |
$app = require __DIR__.'/../bootstrap/app.php'; | |
/* | |
|-------------------------------------------------------------------------- | |
| Run The Application | |
|-------------------------------------------------------------------------- | |
| | |
| Once we have the application, we can handle the incoming request | |
| through the kernel, and send the associated response back to | |
| the client's browser allowing them to enjoy the creative | |
| and wonderful application we have prepared for them. | |
| | |
*/ | |
Amp\Loop::run(function () use ($app) { | |
$sockets = [ | |
Socket\listen("0.0.0.0:8000"), | |
Socket\listen("[::]:8000"), | |
]; | |
$logger = app('log'); | |
$server = new Server($sockets, new CallableRequestHandler(function (Request $request) use ($app) { | |
$content = yield $request->getBody()->buffer(); | |
$method = $request->getMethod(); | |
switch (strtoupper($method)) { | |
case 'POST': | |
case 'PUT': | |
case 'DELETE': | |
case 'PATCH': | |
parse_str($content, $params); | |
break; | |
default: | |
parse_str($request->getUri()->getQuery(), $params); | |
break; | |
} | |
$server = []; | |
$headers = $request->getHeaders(); | |
foreach ($headers as $name => $header) { | |
$server['HTTP_' . str_replace('-', '_', strtoupper($name))] = $header[0]; | |
} | |
$server['CONTENT_TYPE'] = $headers['content-type']; | |
$server['CONTENT_LENGTH'] = $headers['content-length']; | |
// process $_FILES | |
$form = yield Amp\Http\Server\FormParser\parseForm($request); | |
$files = []; | |
foreach ($form->getNames() as $name) { | |
foreach ($form->getFieldArray($name) as $field) { | |
$attribute = $field->getAttributes(); | |
if (!$attribute->isFile()) { | |
continue; | |
} | |
$file_location = tempnam(ini_get("upload_tmp_dir"), "uploaded_file"); | |
file_put_contents($file_location, $field->getValue()); | |
$target["name"] = $attribute->getFilename(); | |
$target["type"] = $attribute->getMimeType(); | |
$target["size"] = strlen($field->getValue()); | |
$target["tmp_name"] = $file_location; | |
$file = new UploadedFile($target['tmp_name'], $target['name'], $target['type'], 0); | |
$files[$name] = $file; | |
} | |
} | |
$sfmRequest = SymfonyRequest::create((string)$request->getUri(), $request->getMethod(), $params, $request->getCookies(), $files, $server, $content); | |
$response = $app->runAmp($sfmRequest); | |
return new Response($response->getStatusCode(), $response->headers->all(), $response->getContent()); | |
}), $logger); | |
yield $server->start(); | |
// Stop the server gracefully when SIGINT is received. | |
// This is technically optional, but it is best to call Server::stop(). | |
Amp\Loop::onSignal(SIGINT, function (string $watcherId) use ($server) { | |
Amp\Loop::cancel($watcherId); | |
yield $server->stop(); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// replace the app part, so we can get the response object rather that just a output string | |
$app = new class(realpath(__DIR__.'/../')) extends Laravel\Lumen\Application { | |
public function runAmp($request) | |
{ | |
$response = $this->dispatch($request); | |
return $response; | |
} | |
}; |
Instead of using ->read()
on the request body, you should use ->buffer()
. read()
only reads a single chunk.
Thanks, changed from ->read()
to ->buffer()
Retrive $_FILES
from $request
using https://github.com/amphp/http-server-form-parser can make symfony UploadFile like objects but are not really uploaded.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
install the corresponding dependencies and then run
php public/index.php
invoke from http://localhost:8000