Project updates from Template
This commit contains the latest updates from the generic Website template, which rework the compression and localization: - Reworked the compression and localization in the Infrastructure package. (3c568e4) - Adopted the reworked compression and localization in the Website service. (08cf3e3) The template commit that only touched the root README (53676ed) was left out, as this project no longer carries that file. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
import Foundation
|
||||
import HTTPTypes
|
||||
import Hummingbird
|
||||
import Localization
|
||||
|
||||
public extension Negotiate {
|
||||
|
||||
// MARK: Methods
|
||||
|
||||
/// The language to serve a request in.
|
||||
///
|
||||
/// The `lang` query parameter wins as a deliberate override; failing that, a leading path segment naming a supported language pins it, so an
|
||||
/// unrouted path under a language's prefix answers in that language. Anything naming no supported language is ignored, leaving the
|
||||
/// `Accept-Language` header and its fallback to the default.
|
||||
///
|
||||
/// Called where the answer is used rather than stamped onto every request on the way past: page routes that pin their language by URL never ask.
|
||||
/// - Parameter request: the request to negotiate for.
|
||||
/// - Returns: the identifier of the supported language to serve.
|
||||
func callAsFunction(
|
||||
for request: Request
|
||||
) -> String {
|
||||
let requested = request.uri.queryParameters[.Parameter.language].map(String.init)
|
||||
?? request.uri.path.split(separator: "/").first.map(String.init)
|
||||
|
||||
return callAsFunction(
|
||||
requested: requested,
|
||||
acceptLanguage: request.headers[.acceptLanguage]
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Constants
|
||||
|
||||
private extension Substring {
|
||||
/// A namespace for the query parameters the negotiation reads.
|
||||
enum Parameter {
|
||||
/// The query parameter carrying an explicit language choice; the site's language switcher appends it to the current path.
|
||||
static let language: Substring = "lang"
|
||||
}
|
||||
}
|
||||
@@ -7,9 +7,11 @@ extension String {
|
||||
/// The default `Content-Security-Policy`.
|
||||
///
|
||||
/// Restricts every resource to the site's own origin (`default-src 'self'`), blocks plugins (`object-src 'none'`), pins the document
|
||||
/// base URL (`base-uri 'self'`), and forbids framing (`frame-ancestors 'none'`). No inline-style exception is included, so pages must
|
||||
/// link external stylesheets.
|
||||
public static let contentSecurityPolicy = "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'"
|
||||
/// base URL (`base-uri 'self'`), holds form submissions to the origin (`form-action 'self'`), and forbids framing
|
||||
/// (`frame-ancestors 'none'`). No inline-style exception is included, so pages must link external stylesheets.
|
||||
///
|
||||
/// `form-action` is named outright because it inherits from nothing: `default-src` does not cover it, however tight.
|
||||
public static let contentSecurityPolicy = "default-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'"
|
||||
/// The default `X-Content-Type-Options` (disables MIME sniffing).
|
||||
public static let contentTypeOptions = "nosniff"
|
||||
/// The default `X-Frame-Options` (forbids framing the page).
|
||||
|
||||
Reference in New Issue
Block a user