If a session already exists, and Session::start() isn’t called until
after a large enough block of content is output, then headers_sent()
will be false. The previous code prevented the session from being
started in this case. That might makes sense for the creation of a new
session, but it prevent legitimate access to an existing session.
This mostly manifested when running debugging tools such as showqueries,
which may output content before the session is started.
If no body is defined, the email is rendered according to a template. Clearing requirements prevent unnecessary styles/scripts to be included in the html (and that needs to be processed/stripped down the line).
Fixes regression from 3.x, where sessions where lazy started as required:
Either because an existing session identifier was sent through with the request,
or because new session data needed to be persisted as part of the request execution.
Without this lazy starting, *every* request will get a session,
which makes all those responses uncacheable by HTTP layers.
Note that 4.x also changed the $data vs. $changedData payloads:
In 3.x, they both contained key/value pairs.
In 4.x, $data contains key/value, while $changedData contains key/boolean to declare isChanged.
While this reduces duplication in the class, it also surfaced a bug which was latent in 3.x:
When an existing session is lazily resumed via start(), $data is set back to an empty array.
In 3.x, any changed data before this point was *also* retained in $changedData,
ensuring it gets merged into existing $_SESSION data.
In 4.x, this clears out data - hence the need for a more complex merge logic.
Since isset($this->data) is no longer an accurate indicator of a started session,
we introduce a separate $this->started flag.
Note that I've chosen not to make lazy an opt-in (e.g. via start($request, $lazy=false)).
We already have a distinction between lazy starting via init(), and force starting via start().
At current certain interfaces exist that assume only local assets will be loaded (e.g. `SilverStripe\Forms\HTMLEditor\TinyMCEConfig::getConfig()`), where as someone may wish to load an off site resource via the use of an absolute URL (e.g. for fontawesome css provided via a CDN). Because asset path parsing is filtered through a `SilverStripe\Core\Manifest\ResourceURLGenerator`, one must either know in advance if they want an internal or external resource (loading different generators), or the API must allow for this (i.e. an inclusion function for each type of asset). So we can either double the API on the implementing class, or simply make an exception for an absolute URL as high as possible; inside the filter - for which the `vendor/module : path/to/file.asset` shorthand syntax was specifically designed not to conflict with.
It's currently broken (doesn't rewrite subsequent links),
and is of questionable use. It was introduced during a time
when PHP didn't have a built-in webserver (I think).
Virtually ever webserver will have rewriting capabilities these days (even IIS!),
and if you struggle with the setup as a new user, you can just fall back to PHP's built-in webserver.
This doesn't affect installation capabilities, since these are triggered via install.php.
NEW: URL generation now handled by pluggable ResourceURLGenerator service.
NEW: Requirements::javascript() and Requirements::css() now support “vendor/package:resource” syntax.
These changes will make it easier to us to fully abstract:
- file access from module location
- file location from URL generation
API: ModulePath template global now takes any composer package name.
NEW: URL generation now handled by pluggable ResourceURLGenerator service.
NEW: Requirements::javascript() and Requirements::css() now support “vendor/package:resource” syntax.
These changes will make it easier to us to fully abstract:
- file access from module location
- file location from URL generation
BUG Fix up test regressions
FIX director references to request object
API Move all middlewares to common namespace
API Implement RequestHandlerMiddlewareAdapter
ENHANCEMENT Improve IP address parsing
Fix up PHPDoc / psr2 linting
BUG Fix property parsing in TrustedProxyMiddleware
BUG Fix Director::is_https()
NEW: Add HTMLMiddlewareAware trait to HTTPApplication, Director, and RequestHandler
NEW: Allow service specs to be passed to Director rules.
This refactor of the controller middlewares takes a service definition
approach rather than a static-method-and-config approach that Director
historically had.
The use of a trait for middleware means that the Middlewares array
property can be defined on RequestHandler, Director, and HTTPApplication
objects in the same way.
NEW: Pass HTTPRequest to session
NEW: Pass HTTPReuqest optionally to Director statics
The session handler now expects to operate on a specific
HTTPRequest object.
API: SS_TRUSTED_PROXY_HOST_HEADER replace with middleware config
API: SS_TRUSTED_PROXY_PROTOCOL_HEADER replace with middleware config
API: SS_TRUSTED_PROXY_IP_HEADER replace with middleware config
API: Front-End-Https = “on” header no longer supported
This middleware replaces the TRUSTED_PROXY setting and shifts its
configuration out of the env vars and bootstrap and into the Director
flow.
NEW: Add HTTPRequest::setIP()
API: Rely on HTTPRequestBuilder to set scheme and IP
These changes tidy up HTTPRequest making it a container for information
and removing special logic from it.
This makes it less feature-rich: it doesn’t contain trusted-proxy logic.
This will be able to provided by a middleware.
The new getScheme() method is designed to be closish to PSR-7’s
getUri()->getScheme() equivalent.
There are no more direct $_SERVER references in HTTPRequest.
HTTPRequest is provided as a service so that global references for
session, hostname, etc can be facilitated. It’s a bit of a hack and
should be avoided but we’re unlikely to scrub it completely from the
Silverstripe 4 code.