GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — docs/requests.md at 0.4 · hypervel/docs

Expand file tree

/

requests.md

Copy path
More file actions
More file actions

Latest commit

 

History

History
History
1066 lines (739 loc) · 40.4 KB
/

requests.md

Copy path

File metadata and controls

1066 lines (739 loc) · 40.4 KB
Raw
Copy raw file
Download raw file
Outline
Edit and raw actions

HTTP Requests

  • Introduction
  • Interacting With The Request
    • Accessing the Request
    • Request Start Time and Server Metadata
    • Request Path, Host, and Method
    • Request Headers
    • Request IP Address
    • Content Negotiation
    • PSR-7 Requests
  • Input
    • Retrieving Input
    • Input Presence
    • Merging Additional Input
    • Old Input
    • Cookies
    • Input Trimming and Normalization
  • Files
    • Retrieving Uploaded Files
    • Storing Uploaded Files
  • Configuring Trusted Proxies
  • Configuring Trusted Hosts
  • Credits

Introduction

Hypervel's Hypervel\Http\Request class provides an object-oriented way to interact with the current HTTP request being handled by your application as well as retrieve the input, cookies, and files that were submitted with the request.

Interacting With The Request

Accessing the Request

To obtain an instance of the current HTTP request via dependency injection, you should type-hint the Hypervel\Http\Request class on your route closure or controller method. The incoming request instance will automatically be injected by the Hypervel service container:

<?php

namespace App\Http\Controllers;

use Hypervel\Http\RedirectResponse;
use Hypervel\Http\Request;

class UserController extends Controller
{
    /**
     * Store a new user.
     */
    public function store(Request $request): RedirectResponse
    {
        $name = $request->input('name');

        // Store the user...

        return redirect('/users');
    }
}

As mentioned, you may also type-hint the Hypervel\Http\Request class on a route closure. The service container will automatically inject the incoming request into the closure when it is executed:

use Hypervel\Http\Request;

Route::get('/', function (Request $request) {
    // ...
});

Hypervel's Swoole server bridge creates the current request. Access it through dependency injection or the request() helper rather than capturing PHP globals.

Dependency Injection and Route Parameters

If your controller method is also expecting input from a route parameter you should list your route parameters after your other dependencies. For example, if your route is defined like so:

use App\Http\Controllers\UserController;

Route::put('/user/{id}', [UserController::class, 'update']);

You may still type-hint the Hypervel\Http\Request and access your id route parameter by defining your controller method as follows:

<?php

namespace App\Http\Controllers;

use Hypervel\Http\RedirectResponse;
use Hypervel\Http\Request;

class UserController extends Controller
{
    /**
     * Update the specified user.
     */
    public function update(Request $request, string $id): RedirectResponse
    {
        // Update the user...

        return redirect('/users');
    }
}

Request Start Time and Server Metadata

The startedAt method returns a Hypervel\Support\CarbonImmutable instance representing when Swoole began processing the current request on the worker, before Hypervel's server bridge and HTTP kernel handled it:

$startedAt = $request->startedAt();

You may retrieve an individual server value using the server method, or call the method without an argument to retrieve all server metadata. Values received from Swoole use uppercase PHP / Symfony names:

$requestTime = $request->server('REQUEST_TIME_FLOAT');

$server = $request->server();

The request start time remains available for the lifetime of the request object, including after the HTTP kernel has terminated the request. The kernel's request lifecycle timer is a separate, later timing boundary used by lifecycle duration handlers.

When handling a WebSocket connection, the request start time describes the initial HTTP handshake, not subsequent WebSocket messages.

Request Path, Host, and Method

The Hypervel\Http\Request instance provides a variety of methods for examining the incoming HTTP request and extends the Symfony\Component\HttpFoundation\Request class. We will discuss a few of the most important methods below.

Retrieving the Request Path

The path method returns the request's path information. So, if the incoming request is targeted at http://example.com/foo/bar, the path method will return foo/bar:

$uri = $request->path();

Inspecting the Request Path / Route

The is method allows you to verify that the incoming request path matches a given pattern. You may use the * character as a wildcard when utilizing this method:

if ($request->is('admin/*')) {
    // ...
}

Using the routeIs method, you may determine if the incoming request has matched a named route:

if ($request->routeIs('admin.*')) {
    // ...
}

Retrieving the Request URL

To retrieve the full URL for the incoming request you may use the url or fullUrl methods. The url method will return the URL without the query string, while the fullUrl method includes the query string:

$url = $request->url();

$urlWithQueryString = $request->fullUrl();

If you would like to append query string data to the current URL, you may call the fullUrlWithQuery method. This method merges the given array of query string variables with the current query string:

$request->fullUrlWithQuery(['type' => 'phone']);

If you would like to get the current URL without a given query string parameter, you may utilize the fullUrlWithoutQuery method:

$request->fullUrlWithoutQuery(['type']);

Retrieving the Request Host

You may retrieve the "host" of the incoming request via the host, httpHost, and schemeAndHttpHost methods:

// http://localhost:8000
$request->host(); // localhost
$request->httpHost(); // localhost:8000
$request->schemeAndHttpHost(); // http://localhost:8000

Retrieving the Request Method

The method method will return the HTTP verb for the request. You may use the isMethod method to verify that the HTTP verb matches a given string:

$method = $request->method();

if ($request->isMethod('post')) {
    // ...
}

Request Headers

You may retrieve a request header from the Hypervel\Http\Request instance using the header method. If the header is not present on the request, null will be returned. However, the header method accepts an optional second argument that will be returned if the header is not present on the request:

$value = $request->header('X-Header-Name');

$value = $request->header('X-Header-Name', 'default');

The hasHeader method may be used to determine if the request contains a given header:

if ($request->hasHeader('X-Header-Name')) {
    // ...
}

For convenience, the bearerToken method may be used to retrieve a bearer token from the Authorization header. If no such header is present, null will be returned:

$token = $request->bearerToken();

Request IP Address

The ip method may be used to retrieve the IP address of the client that made the request to your application:

$ipAddress = $request->ip();

If you would like to retrieve an array of IP addresses, including all of the client IP addresses that were forwarded by proxies, you may use the ips method. The "original" client IP address will be at the end of the array:

$ipAddresses = $request->ips();

In general, IP addresses should be considered untrusted, user-controlled input and be used for informational purposes only.

Content Negotiation

Hypervel provides several methods for inspecting the incoming request's requested content types via the Accept header. First, the getAcceptableContentTypes method will return an array containing all of the content types accepted by the request:

$contentTypes = $request->getAcceptableContentTypes();

The accepts method accepts an array of content types and returns true if any of the content types are accepted by the request. Otherwise, false will be returned:

if ($request->accepts(['text/html', 'application/json'])) {
    // ...
}

You may use the prefers method to determine which content type out of a given array of content types is most preferred by the request. If none of the provided content types are accepted by the request, null will be returned:

$preferred = $request->prefers(['text/html', 'application/json']);

Since many applications only serve HTML or JSON, you may use the expectsJson method to quickly determine if the incoming request expects a JSON response:

if ($request->expectsJson()) {
    // ...
}

If you need to determine whether the request specifically prefers Markdown or will accept Markdown among other content types, such as when serving AI agents or other clients that consume Markdown responses, you may use the wantsMarkdown and acceptsMarkdown methods:

if ($request->wantsMarkdown()) {
    // The client's most preferred content type is text/markdown...
}

if ($request->acceptsMarkdown()) {
    // The client accepts Markdown responses...
}

PSR-7 Requests

The PSR-7 standard specifies interfaces for HTTP messages, including requests and responses. If you would like to obtain an instance of a PSR-7 request instead of a Hypervel\Http\Request, Hypervel can resolve it directly. Hypervel includes the required bridge packages by default. If you have removed them, you may reinstall them via Composer:

composer require symfony/psr-http-message-bridge nyholm/psr7

You may obtain a PSR-7 request by type-hinting the request interface on your route closure or controller method:

use Psr\Http\Message\ServerRequestInterface;

Route::get('/', function (ServerRequestInterface $request) {
    // ...
});

Note

If you return a PSR-7 response instance from a route or controller, it will automatically be converted back to a Hypervel response instance and be displayed by the framework.

Input

Retrieving Input

Retrieving All Input Data

You may retrieve all of the incoming request's input data as an array using the all method. This method may be used regardless of whether the incoming request is from an HTML form or is an XHR request:

$input = $request->all();

Pass a key or an array of keys to all to select specific fields. Passing an empty array returns an empty array; omit the argument or pass null to retrieve all input.

Using the collect method, you may retrieve all of the incoming request's input data as a collection:

$input = $request->collect();

The collect method also allows you to retrieve a subset of the incoming request's input as a collection:

$request->collect('users')->each(function (string $user) {
    // ...
});

Retrieving an Input Value

Using a few simple methods, you may access all of the user input from your Hypervel\Http\Request instance without worrying about which HTTP verb was used for the request. Regardless of the HTTP verb, the input method may be used to retrieve user input:

$name = $request->input('name');

You may pass a default value as the second argument to the input method. This value will be returned if the requested input value is not present on the request:

$name = $request->input('name', 'Sally');

When working with forms that contain array inputs, use "dot" notation to access the arrays:

$name = $request->input('products.0.name');

$names = $request->input('products.*.name');

You may call the input method without any arguments in order to retrieve all of the input values as an associative array:

$input = $request->input();

Retrieving Input From the Query String

While the input method retrieves values from the entire request payload (including the query string), the query method will only retrieve values from the query string:

$name = $request->query('name');

If the requested query string value data is not present, the second argument to this method will be returned:

$name = $request->query('name', 'Helen');

You may call the query method without any arguments in order to retrieve all of the query string values as an associative array:

$query = $request->query();

Retrieving JSON Input Values

When sending JSON requests to your application, you may access the JSON data via the input method as long as the Content-Type header of the request is properly set to application/json. You may even use "dot" syntax to retrieve values that are nested within JSON arrays / objects:

$name = $request->input('user.name');

Retrieving Stringable Input Values

Instead of retrieving the request's input data as a primitive string, you may use the string method to retrieve the request data as an instance of Hypervel\Support\Stringable:

$name = $request->string('name')->trim();

If the input is not a string, number, or Stringable instance, such as an array, you may pass strict: true to receive the default value instead:

$name = $request->string('name', 'Guest', strict: true);

Retrieving Integer Input Values

To retrieve input values as integers, you may use the integer method. This method will attempt to cast the input value to an integer. If the input is not present, it will return the default value you specify, or 0 if you don't specify one. This is particularly useful for pagination or other numeric inputs:

$perPage = $request->integer('per_page');

By default, the integer method casts whatever it receives, so a value like "12abc" becomes 12. To reject values that are not valid integers, pass strict: true. Invalid values will then return the default value, which may be null. The default may also be a closure, which is only called when the default is needed:

$perPage = $request->integer('per_page', default: null, strict: true);

Retrieving Float Input Values

Similarly, the float method retrieves an input value as a float. If the input is not present, it will return the default value you specify, or 0.0 if you don't specify one:

$price = $request->float('price');

The float method also accepts strict: true, which returns the default value for anything that is not a valid number, such as "1.5abc" or "1,000":

$price = $request->float('price', default: null, strict: true);

Retrieving Clamped Input Values

To retrieve a numeric input value constrained between a minimum and maximum value, you may use the clamp method. If the input is not present or is not numeric, the default value you specify will be clamped instead:

$perPage = $request->clamp('per_page', min: 1, max: 100, default: 15);

Retrieving Boolean Input Values

When dealing with HTML elements like checkboxes, your application may receive "truthy" values that are actually strings. For example, "true" or "on". For convenience, you may use the boolean method to retrieve these values as booleans. The boolean method returns true for 1, "1", true, "true", "on", and "yes", ignoring case and surrounding whitespace. All other values will return false:

$archived = $request->boolean('archived');

If you need to tell a false value apart from an invalid one, pass strict: true. Values such as 0, "0", false, "false", "off", and "no" will still return false, but unrecognized or empty input will return the default value instead:

$archived = $request->boolean('archived', default: null, strict: true);

Retrieving Array Input Values

Input values containing arrays may be retrieved using the array method. This method will always cast the input value to an array. If the request does not contain an input value with the given name, an empty array will be returned:

$versions = $request->array('versions');

Retrieving Fluent Input Values

The fluent method retrieves input as a Hypervel\Support\Fluent instance, allowing you to access its values as properties:

$user = $request->fluent('user');

$name = $user->name;

If the input is missing or null, an empty instance is returned. You may pass an array of default values as the second argument:

$user = $request->fluent('user', ['name' => 'Guest']);

You may also pass an array of keys to build the instance from only those input values:

$user = $request->fluent(['name', 'role']);

Fluent instances also provide the input retrieval methods described on this page, such as integer, boolean, date, and enum.

Retrieving Date Input Values

For convenience, input values containing dates / times may be retrieved as CarbonInterface instances using the date method. Request dates use Hypervel's configured date factory and are exact Hypervel\Support\CarbonImmutable instances by default. If the request does not contain an input value with the given name, null will be returned:

$birthday = $request->date('birthday');

The second and third arguments accepted by the date method may be used to specify the date's format and timezone, respectively:

$elapsed = $request->date('elapsed', '!H:i', 'Europe/Madrid');

If the input value is present but has an invalid format, a Carbon\Exceptions\InvalidFormatException will be thrown; therefore, it is recommended that you validate the input before invoking the date method.

Retrieving Interval Input Values

Input values containing durations may be retrieved as CarbonInterval instances using the interval method. If the request does not contain an input value with the given name, null will be returned:

$duration = $request->interval('duration');

If the input value is numeric, you may provide a unit as the second argument. The unit may be a string such as second, minute, or day, or a Carbon\Unit enum instance:

use Carbon\Unit;

$timeout = $request->interval('timeout', 'second');

$delay = $request->interval('delay', Unit::Minute);

If the input value is present but has an invalid format, an InvalidArgumentException will be thrown; therefore, it is recommended that you validate the input before invoking the interval method.

Retrieving Enum Input Values

Input values that correspond to PHP enums may also be retrieved from the request. If the request does not contain an input value with the given name or the enum does not have a backing value that matches the input value, null will be returned. The enum method accepts the name of the input value and the enum class as its first and second arguments:

use App\Enums\Status;

$status = $request->enum('status', Status::class);

You may also provide a default value that will be returned if the value is missing or invalid:

$status = $request->enum('status', Status::class, Status::Pending);

If the input value is an array of values that correspond to a PHP enum, you may use the enums method to retrieve the array of values as enum instances:

use App\Enums\Product;

$products = $request->enums('products', Product::class);

Retrieving Input via Dynamic Properties

You may also access user input using dynamic properties on the Hypervel\Http\Request instance. For example, if one of your application's forms contains a name field, you may access the value of the field like so:

$name = $request->name;

When using dynamic properties, Hypervel will first look for the parameter's value in the request payload. If it is not present, Hypervel will search for the field in the matched route's parameters.

Retrieving a Portion of the Input Data

If you need to retrieve a subset of the input data, you may use the only and except methods. Both of these methods accept a single array or a dynamic list of arguments:

$input = $request->only(['username', 'password']);

$input = $request->only('username', 'password');

$input = $request->except(['credit_card']);

$input = $request->except('credit_card');

Warning

The only method returns all of the key / value pairs that you request; however, it will not return key / value pairs that are not present on the request.

Input Presence

You may use the has method to determine if a value is present on the request. The has method returns true if the value is present on the request:

if ($request->has('name')) {
    // ...
}

When given an array, the has method will determine if all of the specified values are present:

if ($request->has(['name', 'email'])) {
    // ...
}

The hasAny method returns true if any of the specified values are present:

if ($request->hasAny(['name', 'email'])) {
    // ...
}

The whenHas method will execute the given closure if a value is present on the request:

$request->whenHas('name', function (string $input) {
    // ...
});

A second closure may be passed to the whenHas method that will be executed if the specified value is not present on the request:

$request->whenHas('name', function (string $input) {
    // The "name" value is present...
}, function () {
    // The "name" value is not present...
});

If you would like to determine if a value is present on the request and is not an empty string, you may use the filled method:

if ($request->filled('name')) {
    // ...
}

If you would like to determine if a value is missing from the request or is an empty string, you may use the isNotFilled method:

if ($request->isNotFilled('name')) {
    // ...
}

When given an array, the isNotFilled method will determine if all of the specified values are missing or empty:

if ($request->isNotFilled(['name', 'email'])) {
    // ...
}

The anyFilled method returns true if any of the specified values is not an empty string:

if ($request->anyFilled(['name', 'email'])) {
    // ...
}

The whenFilled method will execute the given closure if a value is present on the request and is not an empty string:

$request->whenFilled('name', function (string $input) {
    // ...
});

A second closure may be passed to the whenFilled method that will be executed if the specified value is not "filled":

$request->whenFilled('name', function (string $input) {
    // The "name" value is filled...
}, function () {
    // The "name" value is not filled...
});

The whenEnum method will execute the given closure if a value is present on the request and corresponds to a valid backed enum case:

use App\Enums\Status;

$request->whenEnum('status', Status::class, function (Status $status) {
    // ...
});

A second closure may be passed to the whenEnum method that will be executed if the specified value is missing, empty, or invalid:

$request->whenEnum('status', Status::class, function (Status $status) {
    // The "status" value is a valid enum case...
}, function () {
    // The "status" value is missing, empty, or invalid...
});

To determine if a given key is absent from the request, you may use the missing and whenMissing methods:

if ($request->missing('name')) {
    // ...
}

$request->whenMissing('name', function () {
    // The "name" value is missing...
}, function () {
    // The "name" value is present...
});

Merging Additional Input

Sometimes you may need to manually merge additional input into the request's existing input data. To accomplish this, you may use the merge method. If a given input key already exists on the request, it will be overwritten by the data provided to the merge method:

$request->merge(['votes' => 0]);

The mergeIfMissing method may be used to merge input into the request if the corresponding keys do not already exist within the request's input data:

$request->mergeIfMissing(['votes' => 0]);

Old Input

Hypervel allows you to keep input from one request during the next request. This feature is particularly useful for re-populating forms after detecting validation errors. However, if you are using Hypervel's included validation features, it is possible that you will not need to manually use these session input flashing methods directly, as some of Hypervel's built-in validation facilities will call them automatically.

Flashing Input to the Session

The flash method on the Hypervel\Http\Request class will flash the current input to the session so that it is available during the user's next request to the application:

$request->flash();

You may also use the flashOnly and flashExcept methods to flash a subset of the request data to the session. These methods are useful for keeping sensitive information such as passwords out of the session:

$request->flashOnly(['username', 'email']);

$request->flashExcept('password');

Flashing Input Then Redirecting

Since you often will want to flash input to the session and then redirect to the previous page, you may easily chain input flashing onto a redirect using the withInput method:

return redirect('/form')->withInput();

return redirect()->route('user.create')->withInput();

return redirect('/form')->withInput(
    $request->except('password')
);

Retrieving Old Input

To retrieve flashed input from the previous request, invoke the old method on an instance of Hypervel\Http\Request. The old method will pull the previously flashed input data from the session:

$username = $request->old('username');

Hypervel also provides a global old helper. If you are displaying old input within a Blade template, it is more convenient to use the old helper to repopulate the form. If no old input exists for the given field, null will be returned:

<input type="text" name="username" value="{{ old('username') }}">

Cookies

Retrieving Cookies From Requests

Cookies created by the Hypervel framework on routes that use the web middleware group are encrypted and signed with an authentication code, meaning they will be considered invalid if they have been changed by the client. To retrieve a cookie value from the request, use the cookie method on a Hypervel\Http\Request instance:

$value = $request->cookie('name');

Input Trimming and Normalization

By default, Hypervel includes the Hypervel\Foundation\Http\Middleware\TrimStrings and Hypervel\Foundation\Http\Middleware\ConvertEmptyStringsToNull middleware in your application's global middleware stack. These middleware will automatically trim all incoming string fields on the request, as well as convert any empty string fields to null. This allows you to not have to worry about these normalization concerns in your routes and controllers.

To prevent oversized nested field names from consuming excessive resources, these middleware reject requests with an HTTP 413 response when the combined size of the processed field paths exceeds 20 MiB. This limit counts full nested paths across the query string and request body.

Disabling Input Normalization

If you would like to disable this behavior for all requests, you may remove the two middleware from your application's middleware stack by invoking the $middleware->remove method in your application's bootstrap/app.php file:

use Hypervel\Foundation\Configuration\Middleware;
use Hypervel\Foundation\Http\Middleware\ConvertEmptyStringsToNull;
use Hypervel\Foundation\Http\Middleware\TrimStrings;

->withMiddleware(function (Middleware $middleware): void {
    $middleware->remove([
        ConvertEmptyStringsToNull::class,
        TrimStrings::class,
    ]);
})

If you would like to disable string trimming and empty string conversion for a subset of requests to your application, you may use the trimStrings and convertEmptyStringsToNull middleware methods within your application's bootstrap/app.php file. Both methods accept an array of closures, which should return true or false to indicate whether input normalization should be skipped:

use Hypervel\Foundation\Configuration\Middleware;
use Hypervel\Http\Request;

->withMiddleware(function (Middleware $middleware): void {
    $middleware->convertEmptyStringsToNull(except: [
        fn (Request $request) => $request->is('admin/*'),
    ]);

    $middleware->trimStrings(except: [
        fn (Request $request) => $request->is('admin/*'),
    ]);
})

You may also exclude individual attributes from trimming by passing their names to the trimStrings method. Use * to match nested attributes:

->withMiddleware(function (Middleware $middleware): void {
    $middleware->trimStrings(except: [
        'title',
        'users.*.name',
    ]);
})

Files

Retrieving Uploaded Files

You may retrieve uploaded files from a Hypervel\Http\Request instance using the file method or using dynamic properties. The file method returns an instance of the Hypervel\Http\UploadedFile class, which extends the PHP SplFileInfo class and provides a variety of methods for interacting with the file:

$file = $request->file('photo');

$file = $request->photo;

When a text field and an uploaded file share a name, all() and dynamic properties return the text value. Use file() to retrieve the upload. This also applies when validating data from all(); give upload metadata a different field name or explicitly validate the value returned by file().

You may determine if a file is present on the request using the hasFile method:

if ($request->hasFile('photo')) {
    // ...
}

If the uploaded file is an image that you need to manipulate before storing, you may use the image method to retrieve a Hypervel\Image\Image instance, or null if the file is not present:

$image = $request->image('photo');

For more information on manipulating images, please consult the complete image manipulation documentation.

Validating Successful Uploads

In addition to checking if the file is present, you may verify that there were no problems uploading the file via the isValid method:

if ($request->file('photo')->isValid()) {
    // ...
}

File Paths and Extensions

The UploadedFile class also contains methods for accessing the file's fully-qualified path and its extension. The extension method will attempt to guess the file's extension based on its contents. This extension may be different from the extension that was supplied by the client:

$path = $request->photo->path();

$extension = $request->photo->extension();

Other File Methods

There are a variety of other methods available on UploadedFile instances. Check out the API documentation for the class for more information regarding these methods.

Storing Uploaded Files

To store an uploaded file, you will typically use one of your configured filesystems. The UploadedFile class has a store method that will move an uploaded file to one of your disks, which may be a location on your local filesystem or a cloud storage location like Amazon S3.

The store method accepts the path where the file should be stored relative to the filesystem's configured root directory. This path should not contain a filename, since a unique ID will automatically be generated to serve as the filename.

The store method also accepts an optional second argument for the name of the disk that should be used to store the file. The method will return the path of the file relative to the disk's root:

$path = $request->photo->store('images');

$path = $request->photo->store('images', 's3');

If you do not want a filename to be automatically generated, you may use the storeAs method, which accepts the path, filename, and disk name as its arguments:

$path = $request->photo->storeAs('images', 'filename.jpg');

$path = $request->photo->storeAs('images', 'filename.jpg', 's3');

Note

For more information about file storage in Hypervel, check out the complete file storage documentation.

Configuring Trusted Proxies

When running your applications behind a load balancer that terminates TLS / SSL certificates, you may notice your application sometimes does not generate HTTPS links when using the url helper. Typically this is because your application is being forwarded traffic from your load balancer on port 80 and does not know it should generate secure links.

To solve this, you may enable the Hypervel\Http\Middleware\TrustProxies middleware that is included in your Hypervel application, which allows you to quickly customize the load balancers or proxies that should be trusted by your application. Your trusted proxies should be specified using the trustProxies middleware method in your application's bootstrap/app.php file:

use Hypervel\Foundation\Configuration\Middleware;

->withMiddleware(function (Middleware $middleware): void {
    $middleware->trustProxies(at: [
        '192.168.1.1',
        '10.0.0.0/8',
    ]);
})

In addition to configuring the trusted proxies, you may also configure the proxy headers that should be trusted:

use Hypervel\Foundation\Configuration\Middleware;
use Hypervel\Http\Request;

->withMiddleware(function (Middleware $middleware): void {
    $middleware->trustProxies(headers: Request::HEADER_X_FORWARDED_FOR |
        Request::HEADER_X_FORWARDED_HOST |
        Request::HEADER_X_FORWARDED_PORT |
        Request::HEADER_X_FORWARDED_PROTO |
        Request::HEADER_X_FORWARDED_AWS_ELB
    );
})

Note

If you are using AWS Elastic Load Balancing, the headers value should be Request::HEADER_X_FORWARDED_AWS_ELB. If your load balancer uses the standard Forwarded header from RFC 7239, the headers value should be Request::HEADER_FORWARDED. For more information on the constants that may be used in the headers value, check out Symfony's documentation on trusting proxies.

Trusting All Proxies

If you are using Amazon AWS or another "cloud" load balancer provider, you may not know the IP addresses of your actual balancers. In this case, you may use * to trust all proxies:

use Hypervel\Foundation\Configuration\Middleware;

->withMiddleware(function (Middleware $middleware): void {
    $middleware->trustProxies(at: '*');
})

Configuring Trusted Hosts

By default, Hypervel will respond to all requests it receives regardless of the content of the HTTP request's Host header. In addition, the Host header's value will be used when generating absolute URLs to your application during a web request.

Typically, you should configure your web server, such as Nginx or Apache, to only send requests to your application that match a given hostname. However, if you do not have the ability to customize your web server directly and need to instruct Hypervel to only respond to certain hostnames, you may do so by enabling the Hypervel\Http\Middleware\TrustHosts middleware for your application.

To enable the TrustHosts middleware, you should invoke the trustHosts middleware method in your application's bootstrap/app.php file. Using the at argument of this method, you may specify the hostnames that your application should respond to. The hostname string is treated as a regular expression. Incoming requests with other Host headers will be rejected:

use Hypervel\Foundation\Configuration\Middleware;

->withMiddleware(function (Middleware $middleware): void {
    $middleware->trustHosts(at: ['^hypervel\.test$']);
})

By default, requests coming from subdomains of the application's URL are also automatically trusted. If you would like to disable this behavior, you may use the subdomains argument:

use Hypervel\Foundation\Configuration\Middleware;

->withMiddleware(function (Middleware $middleware): void {
    $middleware->trustHosts(at: ['^hypervel\.test$'], subdomains: false);
})

If you need to access your application's configuration files or database to determine your trusted hosts, you may provide a closure to the at argument:

use Hypervel\Foundation\Configuration\Middleware;

->withMiddleware(function (Middleware $middleware): void {
    $middleware->trustHosts(at: fn () => config()->array('app.trusted_hosts'));
})

If trusted hosts depend on the current request, such as applications that resolve verified custom domains from request data, register a resolver during boot:

use App\Models\VerifiedDomain;
use Hypervel\Http\Middleware\TrustHosts;
use Hypervel\Http\Request;

public function boot(): void
{
    TrustHosts::resolveHostsUsing(function (Request $request): array {
        $domain = VerifiedDomain::query()
            ->where('host', $request->headers->get('HOST'))
            ->first();

        return $domain ? ['^' . preg_quote($domain->host, '/') . '$'] : [];
    });
}

The resolver returns every host pattern that should be trusted for the current request. When a resolver is registered, it fully replaces the static at list and the application's configured URL fallback, so include any first-party, admin, or custom domain patterns that should be accepted. Returning an empty array rejects the request.

The resolver runs during trusted host resolution for each request. In production, resolve against cached verified-host data, such as an application cache or Redis, instead of querying the database on every request.

Do not build trusted host patterns directly from the incoming Host header unless that host has first been verified against trusted application data.

When TrustHosts is enabled, Hypervel rejects requests if no trusted host patterns can be resolved. Configure a valid application URL, at list, or resolver so legitimate hosts are trusted.

Credits

Hypervel HTTP began as a port of Laravel HTTP and has been adapted for Hypervel's framework architecture and coroutine runtime.

You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.