Full Code of vapor/vapor for AI

main ff88583e10f0 cached
325 files
1.7 MB
428.1k tokens
21 symbols
1 requests
Download .txt
Showing preview only (1,816K chars total). Download the full file or copy to clipboard to get everything.
Repository: vapor/vapor
Branch: main
Commit: ff88583e10f0
Files: 325
Total size: 1.7 MB

Directory structure:
gitextract_n1aicf92/

├── .github/
│   ├── CODEOWNERS
│   ├── contributing.md
│   ├── dependabot.yml
│   ├── maintainers.md
│   └── workflows/
│       ├── api-docs.yml
│       ├── sponsors.yml
│       └── test.yml
├── .gitignore
├── .spi.yml
├── AGENTS.md
├── LICENSE
├── NOTICES.txt
├── Package.swift
├── README.md
├── Sources/
│   ├── CVaporBcrypt/
│   │   ├── bcrypt.c
│   │   ├── bcrypt.h
│   │   ├── blf.c
│   │   ├── blf.h
│   │   └── include/
│   │       └── module.modulemap
│   ├── Development/
│   │   ├── Resources/
│   │   │   └── fileio.txt
│   │   ├── configure.swift
│   │   ├── entrypoint.swift
│   │   └── routes.swift
│   ├── Vapor/
│   │   ├── Application.swift
│   │   ├── Authentication/
│   │   │   ├── AuthenticationCache.swift
│   │   │   ├── Authenticator.swift
│   │   │   ├── BasicAuthorization.swift
│   │   │   ├── BearerAuthorization.swift
│   │   │   ├── GuardMiddleware.swift
│   │   │   ├── RedirectMiddleware.swift
│   │   │   └── SessionAuthenticatable.swift
│   │   ├── Bcrypt/
│   │   │   └── Bcrypt.swift
│   │   ├── Cache/
│   │   │   ├── Application+Cache.swift
│   │   │   ├── Cache.swift
│   │   │   ├── CacheExpirationTime.swift
│   │   │   ├── MemoryCache.swift
│   │   │   └── Request+Cache.swift
│   │   ├── Client/
│   │   │   ├── Application+Clients.swift
│   │   │   ├── Client.swift
│   │   │   ├── ClientRequest.swift
│   │   │   ├── ClientResponse.swift
│   │   │   └── Request+Client.swift
│   │   ├── Commands/
│   │   │   ├── BootCommand.swift
│   │   │   ├── CommandContext+Application.swift
│   │   │   ├── RoutesCommand.swift
│   │   │   └── ServeCommand.swift
│   │   ├── Concurrency/
│   │   │   ├── AnyResponse+Concurrency.swift
│   │   │   ├── AsyncBasicResponder.swift
│   │   │   ├── AsyncMiddleware.swift
│   │   │   ├── AsyncPasswordHasher+Concurrency.swift
│   │   │   ├── AsyncSessionDriver.swift
│   │   │   ├── Authentication+Concurrency.swift
│   │   │   ├── Cache+Concurrency.swift
│   │   │   ├── Client+Concurrency.swift
│   │   │   ├── RequestBody+Concurrency.swift
│   │   │   ├── Responder+Concurrency.swift
│   │   │   ├── ResponseCodable+Concurrency.swift
│   │   │   ├── RoutesBuilder+Concurrency.swift
│   │   │   ├── ViewRenderer+Concurrency.swift
│   │   │   └── WebSocket+Concurrency.swift
│   │   ├── Content/
│   │   │   ├── ContainerGetPathExecutor.swift
│   │   │   ├── Content.swift
│   │   │   ├── ContentCoders.swift
│   │   │   ├── ContentConfiguration.swift
│   │   │   ├── ContentContainer.swift
│   │   │   ├── JSONCoder+Custom.swift
│   │   │   ├── JSONCoders+Content.swift
│   │   │   ├── PlaintextDecoder.swift
│   │   │   ├── PlaintextEncoder.swift
│   │   │   ├── URLQueryCoders.swift
│   │   │   └── URLQueryContainer.swift
│   │   ├── Core/
│   │   │   ├── Core.swift
│   │   │   └── Running.swift
│   │   ├── Deprecations/
│   │   │   ├── CORSMiddleware+AllowOriginSetting.swift
│   │   │   ├── CORSMiddleware+Configuration+exposedHeaders.swift
│   │   │   ├── DotEnvFile+load.swift
│   │   │   ├── Routes+caseInsenstive.swift
│   │   │   └── Validatable+validate.swift
│   │   ├── Docs.docc/
│   │   │   └── index.md
│   │   ├── Environment/
│   │   │   ├── Environment+Process.swift
│   │   │   ├── Environment+Secret.swift
│   │   │   └── Environment.swift
│   │   ├── Error/
│   │   │   ├── Abort.swift
│   │   │   ├── AbortError.swift
│   │   │   ├── DebuggableError.swift
│   │   │   ├── Demangler.swift
│   │   │   ├── ErrorSource.swift
│   │   │   └── StackTrace.swift
│   │   ├── Exports.swift
│   │   ├── HTTP/
│   │   │   ├── Application+HTTP.swift
│   │   │   ├── BasicResponder.swift
│   │   │   ├── BodyStream.swift
│   │   │   ├── Client/
│   │   │   │   ├── Application+HTTP+Client.swift
│   │   │   │   └── EventLoopHTTPClient.swift
│   │   │   ├── EndpointCache.swift
│   │   │   ├── HTTPMethod+String.swift
│   │   │   ├── HTTPStatus.swift
│   │   │   ├── Headers/
│   │   │   │   ├── HTTPCookies.swift
│   │   │   │   ├── HTTPHeaderCacheControl.swift
│   │   │   │   ├── HTTPHeaderExpires.swift
│   │   │   │   ├── HTTPHeaderLastModified.swift
│   │   │   │   ├── HTTPHeaders+Cache.swift
│   │   │   │   ├── HTTPHeaders+Connection.swift
│   │   │   │   ├── HTTPHeaders+ContentDisposition.swift
│   │   │   │   ├── HTTPHeaders+ContentRange.swift
│   │   │   │   ├── HTTPHeaders+Directive.swift
│   │   │   │   ├── HTTPHeaders+Forwarded.swift
│   │   │   │   ├── HTTPHeaders+Link.swift
│   │   │   │   ├── HTTPHeaders+Name.swift
│   │   │   │   ├── HTTPHeaders+ResponseCompression.swift
│   │   │   │   ├── HTTPHeaders.swift
│   │   │   │   ├── HTTPMediaType.swift
│   │   │   │   └── HTTPMediaTypePreference.swift
│   │   │   ├── Responder.swift
│   │   │   └── Server/
│   │   │       ├── Application+HTTP+Server.swift
│   │   │       ├── HTTPServer.swift
│   │   │       ├── HTTPServerConfiguration+RequestDecompressionConfiguration.swift
│   │   │       ├── HTTPServerConfiguration+ResponseCompressionConfiguration.swift
│   │   │       ├── HTTPServerHandler.swift
│   │   │       ├── HTTPServerRequestDecoder.swift
│   │   │       ├── HTTPServerResponseEncoder.swift
│   │   │       └── HTTPServerUpgradeHandler.swift
│   │   ├── Logging/
│   │   │   ├── Logger+Report.swift
│   │   │   └── LoggingSystem+Environment.swift
│   │   ├── Middleware/
│   │   │   ├── Application+Middleware.swift
│   │   │   ├── CORSMiddleware.swift
│   │   │   ├── ErrorMiddleware.swift
│   │   │   ├── FileMiddleware.swift
│   │   │   ├── Middleware.swift
│   │   │   ├── MiddlewareConfiguration.swift
│   │   │   ├── ResponseCompressionMiddleware.swift
│   │   │   ├── RouteLoggingMiddleware.swift
│   │   │   └── TracingMiddleware.swift
│   │   ├── Multipart/
│   │   │   ├── File+Multipart.swift
│   │   │   ├── FormDataDecoder+Content.swift
│   │   │   └── FormDataEncoder+Content.swift
│   │   ├── Passwords/
│   │   │   ├── Application+Password.swift
│   │   │   ├── Application+Passwords.swift
│   │   │   ├── AsyncPasswordHasher.swift
│   │   │   ├── BcryptHasher.swift
│   │   │   ├── PasswordHasher.swift
│   │   │   ├── PlaintextHasher.swift
│   │   │   └── Request+Password.swift
│   │   ├── Request/
│   │   │   ├── Redirect.swift
│   │   │   ├── Request+Body.swift
│   │   │   ├── Request+BodyStream.swift
│   │   │   └── Request.swift
│   │   ├── Responder/
│   │   │   ├── Application+Responder.swift
│   │   │   └── DefaultResponder.swift
│   │   ├── Response/
│   │   │   ├── Response+Body.swift
│   │   │   ├── Response.swift
│   │   │   └── ResponseCodable.swift
│   │   ├── Routing/
│   │   │   ├── Application+Routes.swift
│   │   │   ├── Parameters+Require.swift
│   │   │   ├── Request+WebSocket.swift
│   │   │   ├── Route.swift
│   │   │   ├── RouteCollection.swift
│   │   │   ├── Routes.swift
│   │   │   ├── RoutesBuilder+Group.swift
│   │   │   ├── RoutesBuilder+Method.swift
│   │   │   ├── RoutesBuilder+Middleware.swift
│   │   │   ├── RoutesBuilder+WebSocket.swift
│   │   │   └── RoutesBuilder.swift
│   │   ├── Security/
│   │   │   ├── OTP.swift
│   │   │   └── ValidatedCertificateChain.swift
│   │   ├── Server/
│   │   │   ├── Application+Servers.swift
│   │   │   └── Server.swift
│   │   ├── Services/
│   │   │   ├── App+Service.swift
│   │   │   ├── Req+Service.swift
│   │   │   └── Service.swift
│   │   ├── Sessions/
│   │   │   ├── Application+Sessions.swift
│   │   │   ├── MemorySessions.swift
│   │   │   ├── Request+Session.swift
│   │   │   ├── Session.swift
│   │   │   ├── SessionCache.swift
│   │   │   ├── SessionData.swift
│   │   │   ├── SessionDriver.swift
│   │   │   ├── SessionsConfiguration.swift
│   │   │   └── SessionsMiddleware.swift
│   │   ├── URLEncodedForm/
│   │   │   ├── URLEncodedFormData.swift
│   │   │   ├── URLEncodedFormDecoder.swift
│   │   │   ├── URLEncodedFormEncoder.swift
│   │   │   ├── URLEncodedFormError.swift
│   │   │   ├── URLEncodedFormParser.swift
│   │   │   ├── URLEncodedFormSerializer.swift
│   │   │   └── URLQueryFragmentConvertible.swift
│   │   ├── Utilities/
│   │   │   ├── AnyResponse.swift
│   │   │   ├── Array+Random.swift
│   │   │   ├── Base32.swift
│   │   │   ├── Base64.swift
│   │   │   ├── BaseN.swift
│   │   │   ├── BasicCodingKey.swift
│   │   │   ├── ByteCount.swift
│   │   │   ├── Bytes+Hex.swift
│   │   │   ├── Bytes+SecureCompare.swift
│   │   │   ├── Collection+Safe.swift
│   │   │   ├── DataProtocol+Copy.swift
│   │   │   ├── DecoderUnwrapper.swift
│   │   │   ├── DirectoryConfiguration.swift
│   │   │   ├── DotEnv.swift
│   │   │   ├── Extendable.swift
│   │   │   ├── File.swift
│   │   │   ├── FileIO.swift
│   │   │   ├── LifecycleHandler.swift
│   │   │   ├── OptionalType.swift
│   │   │   ├── RFC1123.swift
│   │   │   ├── SocketAddress+Hostname.swift
│   │   │   ├── Storage.swift
│   │   │   ├── String+IsIPAddress.swift
│   │   │   ├── Thread.swift
│   │   │   ├── URI.swift
│   │   │   └── VaporSendableMetadataType.swift
│   │   ├── Validation/
│   │   │   ├── RangeResult.swift
│   │   │   ├── Validatable.swift
│   │   │   ├── Validation.swift
│   │   │   ├── ValidationKey.swift
│   │   │   ├── Validations.swift
│   │   │   ├── ValidationsError.swift
│   │   │   ├── Validator.swift
│   │   │   ├── ValidatorResult.swift
│   │   │   └── Validators/
│   │   │       ├── And.swift
│   │   │       ├── Case.swift
│   │   │       ├── CharacterSet.swift
│   │   │       ├── Count.swift
│   │   │       ├── Custom.swift
│   │   │       ├── Email.swift
│   │   │       ├── Empty.swift
│   │   │       ├── In.swift
│   │   │       ├── Nil.swift
│   │   │       ├── NilIgnoring.swift
│   │   │       ├── Not.swift
│   │   │       ├── Or.swift
│   │   │       ├── Pattern.swift
│   │   │       ├── Range.swift
│   │   │       ├── URL.swift
│   │   │       └── Valid.swift
│   │   ├── View/
│   │   │   ├── Application+Views.swift
│   │   │   ├── PlaintextRenderer.swift
│   │   │   ├── Request+View.swift
│   │   │   ├── View.swift
│   │   │   └── ViewRenderer.swift
│   │   └── _Deprecations.swift
│   ├── VaporTestUtils/
│   │   ├── TestingApplication.swift
│   │   ├── TestingHTTPRequest.swift
│   │   ├── TestingHTTPResponse.swift
│   │   └── Utilities.swift
│   ├── VaporTesting/
│   │   ├── +TestingHTTPResponse.swift
│   │   ├── Docs.docc/
│   │   │   └── index.md
│   │   ├── Exports.swift
│   │   ├── TestingApplicationTester.swift
│   │   ├── VaporTestingContext.swift
│   │   ├── XCTest+Migration.swift
│   │   └── withApp.swift
│   └── XCTVapor/
│       ├── +Application.swift
│       ├── +XCTHTTPResponse.swift
│       ├── Docs.docc/
│       │   └── index.md
│       ├── Exports.swift
│       ├── XCTApplicationTester.swift
│       ├── XCTVaporContext.swift
│       ├── XCTVaporTests.swift
│       └── typealiases.swift
└── Tests/
    └── VaporTests/
        ├── ApplicationCreationTests.swift
        ├── ApplicationTests.swift
        ├── AsyncAuthTests.swift
        ├── AsyncCacheTests.swift
        ├── AsyncClientTests.swift
        ├── AsyncCommandsTests.swift
        ├── AsyncEnvironmentTests.swift
        ├── AsyncFileTests.swift
        ├── AsyncMiddlewareTests.swift
        ├── AsyncPasswordTests.swift
        ├── AsyncRequestTests.swift
        ├── AsyncRouteTests.swift
        ├── AsyncSessionTests.swift
        ├── AsyncWebSocketTests.swift
        ├── AuthenticationTests.swift
        ├── BaseNTests.swift
        ├── BcryptTests.swift
        ├── BodyStreamStateTests.swift
        ├── CacheTests.swift
        ├── ClientTests.swift
        ├── ConditionalResponseCompressionTests.swift
        ├── ContentTests.swift
        ├── DotEnvTests.swift
        ├── EndpointCacheTests.swift
        ├── EnvironmentSecretTests.swift
        ├── ErrorTests.swift
        ├── FileTests.swift
        ├── HTTPCacheTests.swift
        ├── HTTPHeaderTests.swift
        ├── HTTPMediaTypeSetTests.swift
        ├── LoggingTests.swift
        ├── MetricsTests.swift
        ├── MiddlewareTests.swift
        ├── PasswordTests.swift
        ├── PipelineTests.swift
        ├── QueryTests.swift
        ├── RequestTests.swift
        ├── RouteTests.swift
        ├── SecurityTests.swift
        ├── ServerTests.swift
        ├── ServiceTests.swift
        ├── SessionTests.swift
        ├── URITests.swift
        ├── URLEncodedFormTests.swift
        ├── Utilities/
        │   ├── ByteBuffer+Helpers.swift
        │   ├── CapturingMetricsSystem.swift
        │   ├── ResponderClient.swift
        │   ├── SubUtilities/
        │   │   └── index.html
        │   ├── TestLogging.swift
        │   ├── TestTracer.swift
        │   ├── ThreadSafe.swift
        │   ├── expired.crt
        │   ├── expired.key
        │   ├── foo bar.html
        │   ├── foo.txt
        │   ├── index.html
        │   ├── long-test-file.txt
        │   ├── my-secret-env-content
        │   └── test.env
        ├── UtilityTests.swift
        ├── ValidationTests.swift
        ├── VaporTesting.swift
        ├── ViewTests.swift
        └── WebSocketTests.swift

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/CODEOWNERS
================================================
* @0xTim @gwynne


================================================
FILE: .github/contributing.md
================================================
# Contributing to Vapor

👋 Welcome to the Vapor team! 

## Testing

Once in Xcode, select the `vapor-Package` scheme and use `CMD+U` to run the tests.

You can use the `Development` executables for testing out your code.

Don't forget to add tests for your new features.

If you are fixing a single GitHub issue in particular, you can add a test named `testGH<issue number>` to ensure
that your fix is working. This will also help prevent regression.

## API Documentation

Make sure that any new public API is covered by API documentation and update any existing documentation where relevant. See [Formatting Quick Help](https://developer.apple.com/library/archive/documentation/Xcode/Reference/xcode_markup_formatting_ref/SymbolDocumentation.html#//apple_ref/doc/uid/TP40016497-CH51-SW1) and [Swift Documentation](https://nshipster.com/swift-documentation/) for more information.

## Style Guide

When contributing code to Vapor, please try to follow existing style for consistency. 

### Xcode Formatting

Avoid using "Xcode style" indentation where possible. This can be difficult to recreate in other editors.

❌
```swift
func foo(bar: String,
         baz: Int) {
    ...
}
```

Use normal indentation instead.

✅
```swift
func foo(
    bar: String,
    baz: Int
) {
    ...
}
```

### Explicit self

When accessing member properties and methods, use explicit `self`. 

```swift
struct Foo {
    var bar: Int
    func baz() {
        // ❌
        print(bar)
        // ✅
        print(self.bar)
    }
}
```

This makes it easier to tell whether a local variable is being used or not, especially when reading code without syntax highlighting.

## SemVer

Vapor follows [SemVer](https://semver.org). This means that any changes to the source code that can cause
existing code to stop compiling _must_ wait until the next major version to be included. 

Code that is only additive and will not break any existing code can be included in the next minor release.

## Releases

All vapor/* packages use automated releases. When a PR is merged, the Vapor bot will check for certain PR labels and ship a new release right away. This ensures users get access to new features as soon as possible and helps to reduce human error. 

The release will use the PR's title and body directly. It will also include a note about who authored the release and who merged it. 

### Release title

The release title should be concise description. For example:

- ✅ HTTP streaming improvements 
- ✅ Add case-insensitive routing
- ✅ Fix `routes` command symbol usage

The release titles should use sentence capitalization and not be too verbose. They should also use present tense.

- ❌ Fix `routes` Command Symbol Usage
- ❌ Add new method on RouteBuilder called `caseInsensitive` which can be used to enable case-insensitive routing 
- ❌ Fixed `routes` command symbol usage

### Release body

The release body (or description) should contain more in-depth information about the change and code examples if possible. 

✅

````md

Allows configuring case-insensitive routing (#2354, fixes #1928).

```swift
// Enables case-insensitive routing.
// Defaults to false.
app.routes.caseInsensitive = true
```

````

The release body should include links to any associated PRs and issues. Issues that are fixed by this change should be prefixed with `fixes` so that they are closed automatically. The first line of the release body should be a concise description of the change. This can be followed by a more detailed explanation and code examples. 

Releases with a large number of changes can separated using bullets. Special comments or notes can be added using quote blocks `>`. 

✅

```md

Improves HTTP request and response streaming (#2404).

- Streaming request body skipping will only happen if the entire response has been sent before the user _starts_ reading the request body (fixes #2393).

> Note: Previously, streaming request bodies would be drained automatically by Vapor as soon as the response head was sent. This made it impossible to implement realtime streaming, like an echo server. With these changes, you have much more control over streaming HTTP while still preventing hanging if the request body is ignored entirely. 

- Response body stream now supports omitting the `count` parameter (fixes #2393).

> Note: Previously streaming bodies required a count and would always set the `content-length` header. Now, setting a count of `-1` indicates a stream with indeterminate length. `-1` will be used if the stream count is omitted. This results in `transfer-encoding: chunked` being used automatically. 

```

Release bodies should be in present tense third person. They should mention only information relevant to release notes. Any additional information or questions can be included in PR comments.

❌

```md

I've implemented two fixes to HTTP request streaming. I'm wondering if I need to implement three?

Here's what I've done so far:

...

```

The following PR labels are supported by Vapor's release bot.

- `semver-patch`: Bumps the patch version. 0.0.x
- `semver-minor`: Bumps the minor version: 0.x.0
- `semver-major`: Bumps the major version: x.0.0 (rarely used)
- `release`: Advances the pre-release identifier (alpha -> beta -> rc)

When Vapor's release bot makes a release, it will automatically notify the `#release` channel in Vapor's team chat and include a link to the release on the merged PR.

## Maintainers

Each repo under the Vapor organization has at least one [volunteer maintainer.](maintainers.md) [vapor/vapor's](https://github.com/vapor/vapor) current list of maintainers is:

- [@MrLotU](https://github.com/MrLotU)
- [@Joannis](https://github.com/Joannis)
- [@0xTim](https://github.com/0xtim)
- [@gwynne](https://github.com/gwynne)
- [@siemensikkema](https://github.com/siemensikkema)

## Extras

Here are some bash functions to help you test Swift on Linux easily from macOS (you must have Docker installed).

### Swift Linux

```bash
# Starts docker-machine and exports env variables.
_docker_start() {
    docker-machine start default
    eval "$(docker-machine env default)"
}
alias docker-start='_docker_start'

# Executes /usr/bin/swift in a Swift 4.1 docker container
_swift_linux() {
    _docker_start
    docker run -it -v $PWD:/root/code -w /root/code norionomura/swift:swift-4.1-branch /usr/bin/swift $1
}
alias swift-linux='_swift_linux'
```

You can add these methods to your `~/.bash_profile`. Just run `source ~/.bash_profile` after or restart your terminal.

Once added, you can run the following to test Swift projects on both macOS and Linux.

```sh
swift test
swift-linux test
```

### Clean SPM

Add the following code to your bash profile to make cleaning SPM temporary files easy.

```bash
# Cleans out all temporary SPM files
_spm_clean() {
	rm Package.resolved
	rm -rf .build
	rm -rf *.xcodeproj
	rm -rf Packages
}
alias spm-clean='_spm_clean'
```

Once added, you can run `spm-clean`.

```sh
spm-clean
```

----------

Join us on Discord if you have any questions: [http://vapor.team](http://vapor.team).

&mdash; Thanks! 🙌


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "daily"
    allow:
      - dependency-type: all
    groups:
      dependencies:
        patterns:
          - "*"
  - package-ecosystem: "swift"
    directory: "/"
    schedule:
      interval: "daily"
    allow:
      - dependency-type: all
    groups:
      dependencies:
        patterns:
          - "*"


================================================
FILE: .github/maintainers.md
================================================
# Being a Maintainer

If you would like to volunteer to be a maintainer for this repo, or any other repo under the Vapor org, submit
a PR to that repo adding your handle to the current maintainers list. The core team in addition to the existing
maintainers will determine if you are a good fit and either accept and merge the PR or provide steps that need
to be taken in order to be accepted.

## Perks
- Special "Maintainer" role in Discord with purple highlight.
- Write access to maintained repo (including approve and merge permissions). 
- Invite to "Maintainers" team on GitHub.
- Opportunity to actively participate in deciding on new features in package. 
- Access to private `#maintainers` channel in Discord.
- Name listed as maintainer in repo's `contributing.md`. 

## Responsibilities
- Merge PRs.
- Tag releases. 
- Resolve issues.
- Curate `contributing.md` and related docs.

## Rules
- Maintainers can review, approve, merge, and tag any `0.0.x`, or "patch", releases. 
- Maintainers can review, approve, and tag any `0.x`, or "minor", releases. Core team is required to merge.
- Maintainers can close resolved or off-topic issues.
- PRs will be open for 24 hours before they are closed or merged to allow time for review by all maintainers.


================================================
FILE: .github/workflows/api-docs.yml
================================================
name: deploy-api-docs
on:
  push:
    branches:
      - main
permissions:
  contents: read
  id-token: write

jobs:
  build-and-deploy:
     uses: vapor/api-docs/.github/workflows/build-and-deploy-docs-workflow.yml@main
     secrets: inherit
     with:
       package_name: vapor
       modules: Vapor,XCTVapor,VaporTesting
       pathsToInvalidate: /vapor/* /xctvapor/* /vaportesting/*


================================================
FILE: .github/workflows/sponsors.yml
================================================
name: Generate Sponsors README
on: workflow_dispatch
permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v6

      - name: Get token
        id: get-token
        uses: actions/create-github-app-token@v3
        with:
          app-id: ${{ vars.PENNY_APP_ID }}
          private-key: ${{ secrets.PENNY_APP_PRIVATE_KEY }}

      - name: Generate Sponsors
        uses: JamesIves/github-sponsors-readme-action@v1
        with:
          token: ${{ steps.get-token.outputs.token }}
          file: "README.md"
          minimum: 500
          maximum: 9900
          marker: "backers"
          organization: true

      - name: Commit and create PR
        uses: peter-evans/create-pull-request@v8
        with:
          token: ${{ steps.get-token.outputs.token }}
          commit-message: "[skip ci] Update README with new sponsor"
          committer: "Penny[bot] <360798+penny[bot]@vapor.codes>"
          author: "Penny[bot] <360798+penny[bot]@vapor.codes>"
          branch: update-sponsors
          delete-branch: true
          title: Update README with new sponsor
          body: Update README adding new sponsor
          labels: no-release-needed,sponsors
          reviewers: 0xTim


================================================
FILE: .github/workflows/test.yml
================================================
name: test
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
on:
  pull_request: { types: [opened, reopened, synchronize, ready_for_review] }
  push: { branches: [ main ] }

jobs:
  test-providers:
    permissions:
      contents: read
    if: ${{ !(github.event.pull_request.draft || false) }}
    strategy:
      fail-fast: false
      matrix:
        provider:
          - vapor/jwt
          - vapor/fluent
          - vapor/leaf
          - vapor/queues
          - vapor/apns
    runs-on: ubuntu-latest
    container: swift:6.2
    steps:
      - name: Check out Vapor
        uses: actions/checkout@v6
        with:
          path: vapor
      - name: Check out provider
        uses: actions/checkout@v6
        with:
          repository: ${{ matrix.provider }}
          path: provider
      - name: Use local Vapor
        run: swift package --package-path ./provider edit vapor --path ./vapor
      - name: Run tests
        run: swift test --package-path ./provider

  unit-tests:
    permissions:
      contents: read
    uses: vapor/ci/.github/workflows/run-unit-tests.yml@main
    with:
      with_release_mode_testing: true
      with_tsan: false
      with_musl: true
      extra_musl_flags: --target Vapor
      ios_xcodebuild_action: ''
      ios_scheme_name: Vapor
    secrets: inherit

  submit-dependencies:
    permissions:
      contents: write
    if: ${{ github.event_name == 'push' }}
    uses: vapor/ci/.github/workflows/submit-deps.yml@main
    secrets: inherit

  test-parallel:
    permissions:
      contents: read
    if: ${{ !(github.event.pull_request.draft || false) }}
    runs-on: ubuntu-latest
    container: swift:6.2
    steps:
      - name: Check out Vapor
        uses: actions/checkout@v6
      - name: Run tests
        run: swift test --parallel


================================================
FILE: .gitignore
================================================
Packages
.build
.index-build
.DS_Store
*.xcodeproj
DerivedData/
Package.resolved
.swiftpm
Tests/LinuxMain.swift
.vscode
.bash_history
.cache/

# API Docs Generation
generate-package-api-docs.swift
public/
theme-settings.json


================================================
FILE: .spi.yml
================================================
version: 1
metadata:
  authors: "Maintained by the Vapor Core Team with hundreds of contributions from the Vapor Community."
external_links:
  documentation: "https://docs.vapor.codes"

================================================
FILE: AGENTS.md
================================================
# AI & Automated Agent Policy

This document outlines our policy on AI-assisted contributions and automated agents interacting with this project.

## Issues

### Good First Issues

Issues tagged with `good-first-issue` are there to allow new contributors to learn the processs of contributing to open source and Vapor with relatively easy tasks, to help grow open source. These issues are written by human maintainers and are intended to be solved by humans learning the codebase. **Do not use automated agents to claim, triage, or submit solutions to `good-first-issue` tickets.**

### Security Issues

Security vulnerabilities must be reported by humans through our responsible disclosure process. Automated scanning tools may identify potential issues, but all security reports must be reviewed, verified, and submitted by a human. Automated or AI-generated security reports will be closed without action. See our [organisation security policy](https://github.com/vapor/.github/blob/main/SECURITY.md) for disclosure instructions.

### General Issues

Issues must reflect genuine, human-identified bugs or feature requests. We will close issues that appear to be generated entirely by an automated agent without meaningful human review. Low-effort, bot-generated issues waste maintainer time and will not be tolerated.

## Pull Requests

We welcome AI-assisted contributions under the following conditions:

- **A human must author and submit the PR.** Using AI tools (Copilot, Claude, Cursor, etc.) to help write or refine code is fine, but a human must understand, review, and take responsibility for every change in the PR.
- **Fully automated PRs will be closed.** If a PR appears to have been generated and submitted by an agent with no meaningful human involvement, we will close it.
- **Contributors must be able to discuss their changes.** Maintainers may ask questions about implementation choices during review. You should be able to explain and defend your approach.
- **AI-generated code must meet the same standards as any other contribution.** It must pass CI, follow project conventions, include tests where appropriate, and be consistent with the existing codebase.

## How We Identify Automated Contributions

We look for patterns such as:

- Generic or templated issue descriptions with no project-specific context
- PRs submitted moments after an issue is opened
- Inability to respond to review feedback in a meaningful way
- Bulk submissions across multiple issues in a short timeframe
- Commit messages or PR descriptions that read like raw LLM output

Maintainers reserve the right to close any issue or PR that we believe violates this policy. These decisions are made at our discretion and are final.

## Why This Policy Exists

Open source thrives on human collaboration. Automated noise—whether from bots filing low-quality issues or agents submitting unreviewed code—drains maintainer energy and undermines the community we are building. This policy exists to protect contributor experience, maintain code quality, and keep Vapor a welcoming place for people who want to learn and contribute.


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2020 Qutheory, LLC

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: NOTICES.txt
================================================

//===----------------------------------------------------------------------===//
//
// This source file is part of the Vapor open source project
//
// Copyright (c) 2017-2021 Vapor project authors
// Licensed under MIT
//
// See LICENSE for license information
//
// SPDX-License-Identifier: MIT
//
//===----------------------------------------------------------------------===//

This product contains a derivation of the TestMetrics test implementation
from Swift Metrics.

  * LICENSE (Apache License 2.0):
    * https://www.apache.org/licenses/LICENSE-2.0
  * HOMEPAGE:
    * https://github.com/apple/swift-metrics
    
This product contains an implementation of AsyncLazySequence taken from Async
HTTP Client

  * LICENSE (Apache License 2.0):
    * https://www.apache.org/licenses/LICENSE-2.0
  * HOMEPAGE:
    * https://github.com/swift-server/async-http-client



================================================
FILE: Package.swift
================================================
// swift-tools-version:6.0
import PackageDescription

let package = Package(
    name: "vapor",
    platforms: [
        .macOS(.v10_15),
        .iOS(.v13),
        .tvOS(.v13),
        .watchOS(.v6)
    ],
    products: [
        .library(name: "Vapor", targets: ["Vapor"]),
        .library(name: "XCTVapor", targets: ["XCTVapor"]),
        .library(name: "VaporTesting", targets: ["VaporTesting"]),
    ],
    dependencies: [
        // HTTP client library built on SwiftNIO
        .package(url: "https://github.com/swift-server/async-http-client.git", from: "1.24.0"),

        // Sugary extensions for the SwiftNIO library
        .package(url: "https://github.com/vapor/async-kit.git", from: "1.15.0"),

        // 💻 APIs for creating interactive CLI tools.
        .package(url: "https://github.com/vapor/console-kit.git", from: "4.14.0"),

        // 🔑 Hashing (SHA2, HMAC), encryption (AES), public-key (RSA), and random data generation.
        .package(url: "https://github.com/apple/swift-crypto.git", "1.0.0" ..< "5.0.0"),

        // 🚍 High-performance trie-node router.
        .package(url: "https://github.com/vapor/routing-kit.git", from: "4.9.0"),

        // Event-driven network application framework for high performance protocol servers & clients, non-blocking.
        .package(url: "https://github.com/apple/swift-nio.git", from: "2.81.0"),

        // Bindings to OpenSSL-compatible libraries for TLS support in SwiftNIO
        .package(url: "https://github.com/apple/swift-nio-ssl.git", from: "2.34.0"),

        // HTTP/2 support for SwiftNIO
        .package(url: "https://github.com/apple/swift-nio-http2.git", from: "1.28.0"),

        // Useful code around SwiftNIO.
        .package(url: "https://github.com/apple/swift-nio-extras.git", from: "1.24.0"),

        // Swift logging API
        .package(url: "https://github.com/apple/swift-log.git", from: "1.8.0"),

        // Swift metrics API
        .package(url: "https://github.com/apple/swift-metrics.git", from: "2.5.0"),
        
        // Swift tracing API
        .package(url: "https://github.com/apple/swift-distributed-tracing.git", from: "1.1.0"),
        
        // Swift service context
        .package(url: "https://github.com/apple/swift-service-context.git", from: "1.0.0"),

        // Swift collection algorithms
        .package(url: "https://github.com/apple/swift-algorithms.git", from: "1.0.0"),

        // WebSocket client library built on SwiftNIO
        .package(url: "https://github.com/vapor/websocket-kit.git", from: "2.13.0"),

        // MultipartKit, Multipart encoding and decoding
        .package(url: "https://github.com/vapor/multipart-kit.git", from: "4.2.1"),

        // Low-level atomic operations
        .package(url: "https://github.com/apple/swift-atomics.git", from: "1.1.0"),

        // X509 certificate types for the Swift ecosystem
        .package(url: "https://github.com/apple/swift-certificates.git", from: "1.14.0"),

        // Work with certificate encoding schemes
        .package(url: "https://github.com/apple/swift-asn1.git", from: "1.0.0")
    ],
    targets: [
        // C helpers
        .target(name: "CVaporBcrypt"),
        
        // Vapor
        .target(
            name: "Vapor",
            dependencies: [
                .product(name: "AsyncHTTPClient", package: "async-http-client"),
                .product(name: "AsyncKit", package: "async-kit"),
                .target(name: "CVaporBcrypt"),
                .product(name: "ConsoleKit", package: "console-kit"),
                .product(name: "Logging", package: "swift-log"),
                .product(name: "Metrics", package: "swift-metrics"),
                .product(name: "Tracing", package: "swift-distributed-tracing"),
                .product(name: "ServiceContextModule", package: "swift-service-context"),
                .product(name: "NIO", package: "swift-nio"),
                .product(name: "NIOConcurrencyHelpers", package: "swift-nio"),
                .product(name: "NIOCore", package: "swift-nio"),
                .product(name: "NIOExtras", package: "swift-nio-extras"),
                .product(name: "NIOFoundationCompat", package: "swift-nio"),
                .product(name: "NIOHTTPCompression", package: "swift-nio-extras"),
                .product(name: "NIOHTTP1", package: "swift-nio"),
                .product(name: "NIOHTTP2", package: "swift-nio-http2"),
                .product(name: "NIOSSL", package: "swift-nio-ssl"),
                .product(name: "NIOWebSocket", package: "swift-nio"),
                .product(name: "Crypto", package: "swift-crypto"),
                .product(name: "Algorithms", package: "swift-algorithms"),
                .product(name: "RoutingKit", package: "routing-kit"),
                .product(name: "WebSocketKit", package: "websocket-kit"),
                .product(name: "MultipartKit", package: "multipart-kit"),
                .product(name: "Atomics", package: "swift-atomics"),
                .product(name: "_NIOFileSystem", package: "swift-nio"),
                .product(name: "_NIOFileSystemFoundationCompat", package: "swift-nio"),
                .product(name: "X509", package: "swift-certificates"),
                .product(name: "SwiftASN1", package: "swift-asn1"),
            ],
            swiftSettings: swiftSettings
        ),

        // Development
        .executableTarget(
            name: "Development",
            dependencies: [
                .target(name: "Vapor"),
            ],
            resources: [.copy("Resources")],
            swiftSettings: swiftSettings
        ),

        // Testing
        .target(
            name: "VaporTestUtils",
            dependencies: [
                .target(name: "Vapor"),
            ],
            swiftSettings: swiftSettings
        ),
        .target(
            name: "VaporTesting",
            dependencies: [
                .target(name: "VaporTestUtils"),
                .target(name: "Vapor"),
            ],
            swiftSettings: swiftSettings
        ),
        .target(
            name: "XCTVapor",
            dependencies: [
                .target(name: "VaporTestUtils"),
                .target(name: "Vapor"),
            ],
            swiftSettings: swiftSettings
        ),
        .testTarget(
            name: "VaporTests",
            dependencies: [
                .product(name: "NIOTestUtils", package: "swift-nio"),
                .product(name: "SwiftASN1", package: "swift-asn1"),
                .target(name: "XCTVapor"),
                .target(name: "VaporTesting"),
                .target(name: "Vapor"),
            ],
            resources: [
                .copy("Utilities/foo.txt"),
                .copy("Utilities/index.html"),
                .copy("Utilities/SubUtilities/"),
                .copy("Utilities/foo bar.html"),
                .copy("Utilities/test.env"),
                .copy("Utilities/my-secret-env-content"),
                .copy("Utilities/expired.crt"),
                .copy("Utilities/expired.key"),
                .copy("Utilities/long-test-file.txt"),
            ],
            swiftSettings: swiftSettings
        ),
    ]
)

var swiftSettings: [SwiftSetting] { [
    //.enableUpcomingFeature("ExistentialAny"),
    //.enableUpcomingFeature("InternalImportsByDefault"),
    .enableUpcomingFeature("MemberImportVisibility"),
    .enableUpcomingFeature("InferIsolatedConformances"),
    //.enableUpcomingFeature("NonisolatedNonsendingByDefault"),
    .enableUpcomingFeature("ImmutableWeakCaptures"),
] }


================================================
FILE: README.md
================================================
<a href="https://discord.gg/vapor">

![Vapor](https://user-images.githubusercontent.com/1342803/75634175-4876d680-5bd9-11ea-90d6-12c7b6a9ee3f.png)

</a>

<p align="center">
    <a href="https://docs.vapor.codes/4.0/">
        <img src="https://design.vapor.codes/images/readthedocs.svg" alt="Documentation">
    </a>
    <a href="https://discord.gg/vapor">
        <img src="https://design.vapor.codes/images/discordchat.svg" alt="Team Chat">
    </a>
    <a href="LICENSE">
        <img src="https://design.vapor.codes/images/mitlicense.svg" alt="MIT License">
    </a>
    <a href="https://github.com/vapor/vapor/actions/workflows/test.yml">
        <img src="https://img.shields.io/github/actions/workflow/status/vapor/vapor/test.yml?event=push&style=plastic&logo=github&label=tests&logoColor=%23ccc" alt="Continuous Integration">
    </a>
    <a href="https://codecov.io/gh/vapor/vapor">
        <img src="https://img.shields.io/codecov/c/github/vapor/vapor?style=plastic&logo=codecov&label=codecov" alt="Code Coverage">
    </a>
    <a href="https://swift.org">
        <img src="https://design.vapor.codes/images/swift60up.svg" alt="Swift 6.0+">
    </a>
    <a href="https://hachyderm.io/@codevapor">
        <img src="https://img.shields.io/badge/%20-@codevapor-6364f6.svg?style=plastic&logo=mastodon&labelColor=gray&logoColor=%239394ff" alt="Mastodon">
    </a>
</p>

<br>

Vapor is an HTTP web framework for Swift. It provides a beautifully expressive and easy-to-use foundation for your next website, API, or cloud project.

Take a look at some of the [awesome stuff](https://github.com/vapor-community/awesome-vapor) created with Vapor.

### 💧 Community

Join the welcoming community of fellow Vapor developers on [Discord](https://vapor.team).

### 🚀 Contributing

To contribute a **feature or idea** to Vapor, [create an issue](https://github.com/vapor/vapor/issues/new) explaining your idea or bring it up on [Discord](https://vapor.team).

If you find a **bug**, please [create an issue](https://github.com/vapor/vapor/issues/new). 

If you find a **security vulnerability**, please contact [security@vapor.codes](mailto:security@vapor.codes) as soon as possible.

### 💛 Sponsors

Support Vapor's development by [becoming a sponsor](https://github.com/sponsors/vapor).

<a href="https://www.brokenhands.io">
    <img src="https://user-images.githubusercontent.com/9938337/137103192-21f99099-6aaa-4cc1-a1a7-21ee767a72d1.png" height="100px" alt="Broken Hands">
</a>
<a href="https://www.emergetools.com">
    <img src="https://user-images.githubusercontent.com/9938337/265658253-cb37d2fa-3251-497f-8eeb-ba7c95af373b.svg" height="100px" alt="Emerge Tools">
</a>
<a href="https://github.com/MrLotU">
    <img src="https://user-images.githubusercontent.com/1342803/79599312-426a8580-80b3-11ea-89b3-8b2722485e37.png" height="100px" alt="Jari">
</a>
<a href="https://github.com/DonutDane">
    <img src="https://user-images.githubusercontent.com/9938337/265657642-6b6b1705-9611-4547-8e2f-a3773fda87c6.png" height="100px" alt="Donut Dane">
</a>
<a href="https://macstadium.com">
    <img src="https://uploads-ssl.webflow.com/5ac3c046c82724970fc60918/5c019d917bba312af7553b49_MacStadium-developerlogo.png" height="100px" alt="MacStadium">
</a>



### 💚 Backers
Support Vapor's development by [becoming a backer](https://github.com/sponsors/vapor).

<!-- backers --><a href="https://github.com/slashmo"><img src="https://github.com/slashmo.png" width="60px" alt="Moritz Lang" /></a><a href="https://github.com/maartene"><img src="https://github.com/maartene.png" width="60px" alt="Maarten Engels" /></a><a href="https://github.com/tkrajacic"><img src="https://github.com/tkrajacic.png" width="60px" alt="Thomas Krajacic" /></a><a href="https://github.com/jessetipton"><img src="https://github.com/jessetipton.png" width="60px" alt="Jesse Tipton" /></a><a href="https://github.com/steve-h"><img src="https://github.com/steve-h.png" width="60px" alt="Steve Hume" /></a><a href="https://github.com/mikkelu"><img src="https://github.com/mikkelu.png" width="60px" alt="Mikkel Ulstrup" /></a><a href="https://github.com/g-Off"><img src="https://github.com/g-Off.png" width="60px" alt="Geoffrey Foster" /></a><a href="https://github.com/PSchmiedmayer"><img src="https://github.com/PSchmiedmayer.png" width="60px" alt="Paul Schmiedmayer" /></a><a href="https://github.com/ScottRobbins"><img src="https://github.com/ScottRobbins.png" width="60px" alt="Scott Robbins" /></a><a href="https://github.com/finestructure"><img src="https://github.com/finestructure.png" width="60px" alt="Sven A. Schmidt" /></a><a href="https://github.com/SpencerCurtis"><img src="https://github.com/SpencerCurtis.png" width="60px" alt="Spencer Curtis" /></a><a href="https://github.com/rausnitz"><img src="https://github.com/rausnitz.png" width="60px" alt="Zach Rausnitz" /></a><a href="https://github.com/masterofinsanity"><img src="https://github.com/masterofinsanity.png" width="60px" alt="Tim „Timinator“ Kretzschmar" /></a><a href="https://github.com/klaas"><img src="https://github.com/klaas.png" width="60px" alt="Klaas" /></a><a href="https://github.com/Andrewangeta"><img src="https://github.com/Andrewangeta.png" width="60px" alt="Andrew Edwards" /></a><a href="https://github.com/addli"><img src="https://github.com/addli.png" width="60px" alt="+Li, Inc." /></a><a href="https://github.com/doozMen"><img src="https://github.com/doozMen.png" width="60px" alt="Stijn Willems" /></a><a href="https://github.com/bitwit"><img src="https://github.com/bitwit.png" width="60px" alt="Kyle Newsome" /></a><a href="https://github.com/viaaurelia"><img src="https://github.com/viaaurelia.png" width="60px" alt="Via Aurelia Solutions" /></a><a href="https://github.com/kkiermasz"><img src="https://github.com/kkiermasz.png" width="60px" alt="Jakub Kiermasz" /></a><a href="https://github.com/bdrelling"><img src="https://github.com/bdrelling.png" width="60px" alt="Brian Drelling" /></a><a href="https://github.com/mayondigital"><img src="https://github.com/mayondigital.png" width="60px" alt="" /></a><a href="https://github.com/mattesmohr"><img src="https://github.com/mattesmohr.png" width="60px" alt="Mattes Mohr" /></a><a href="https://github.com/scibidoo"><img src="https://github.com/scibidoo.png" width="60px" alt="Jamie" /></a><a href="https://github.com/GalenRhodes"><img src="https://github.com/GalenRhodes.png" width="60px" alt="Galen Rhodes" /></a><a href="https://github.com/litmaps"><img src="https://github.com/litmaps.png" width="60px" alt="Litmaps" /></a><a href="https://github.com/davdroman"><img src="https://github.com/davdroman.png" width="60px" alt="David Roman" /></a><a href="https://github.com/Strobocop"><img src="https://github.com/Strobocop.png" width="60px" alt="Brian Strobach" /></a><a href="https://github.com/kishikawakatsumi"><img src="https://github.com/kishikawakatsumi.png" width="60px" alt="Kishikawa Katsumi" /></a><a href="https://github.com/mkll"><img src="https://github.com/mkll.png" width="60px" alt="Alex Sherbakov" /></a><a href="https://github.com/getsidetrack"><img src="https://github.com/getsidetrack.png" width="60px" alt="Sidetrack" /></a><a href="https://github.com/GregKarpati"><img src="https://github.com/GregKarpati.png" width="60px" alt="Greg Karpati" /></a><a href="https://github.com/fananek"><img src="https://github.com/fananek.png" width="60px" alt="František Mikš" /></a><a href="https://github.com/jagreenwood"><img src="https://github.com/jagreenwood.png" width="60px" alt="Jeremy Greenwood" /></a><a href="https://github.com/rayfix"><img src="https://github.com/rayfix.png" width="60px" alt="Ray Fix" /></a><a href="https://github.com/micomiloloza"><img src="https://github.com/micomiloloza.png" width="60px" alt="Mićo Miloloža" /></a><a href="https://github.com/awamser"><img src="https://github.com/awamser.png" width="60px" alt="Alan" /></a><a href="https://github.com/Suboptimierer"><img src="https://github.com/Suboptimierer.png" width="60px" alt="Jonas Sannewald" /></a><a href="https://github.com/TapEnvy-us-LLC"><img src="https://github.com/TapEnvy-us-LLC.png" width="60px" alt="TapEnvy.us, LLC" /></a><a href="https://github.com/JawadHF"><img src="https://github.com/JawadHF.png" width="60px" alt="Jawad" /></a><a href="https://github.com/PARAIPAN9"><img src="https://github.com/PARAIPAN9.png" width="60px" alt="PARAIPAN SORIN" /></a><a href="https://github.com/KalynDavis"><img src="https://github.com/KalynDavis.png" width="60px" alt="Kalyn Davis" /></a><a href="https://github.com/stevapple"><img src="https://github.com/stevapple.png" width="60px" alt="YR Chen" /></a><a href="https://github.com/roncuevas"><img src="https://github.com/roncuevas.png" width="60px" alt="Aarón Martínez Cuevas" /></a><!-- backers -->

<a href="https://opencollective.com/vapor/backer/0/website" target="_blank"><img src="https://opencollective.com/vapor/backer/0/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/1/website" target="_blank"><img src="https://opencollective.com/vapor/backer/1/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/2/website" target="_blank"><img src="https://opencollective.com/vapor/backer/2/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/3/website" target="_blank"><img src="https://opencollective.com/vapor/backer/3/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/4/website" target="_blank"><img src="https://opencollective.com/vapor/backer/4/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/5/website" target="_blank"><img src="https://opencollective.com/vapor/backer/5/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/6/website" target="_blank"><img src="https://opencollective.com/vapor/backer/6/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/7/website" target="_blank"><img src="https://opencollective.com/vapor/backer/7/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/8/website" target="_blank"><img src="https://opencollective.com/vapor/backer/8/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/9/website" target="_blank"><img src="https://opencollective.com/vapor/backer/9/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/10/website" target="_blank"><img src="https://opencollective.com/vapor/backer/10/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/11/website" target="_blank"><img src="https://opencollective.com/vapor/backer/11/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/12/website" target="_blank"><img src="https://opencollective.com/vapor/backer/12/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/13/website" target="_blank"><img src="https://opencollective.com/vapor/backer/13/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/14/website" target="_blank"><img src="https://opencollective.com/vapor/backer/14/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/15/website" target="_blank"><img src="https://opencollective.com/vapor/backer/15/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/16/website" target="_blank"><img src="https://opencollective.com/vapor/backer/16/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/17/website" target="_blank"><img src="https://opencollective.com/vapor/backer/17/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/18/website" target="_blank"><img src="https://opencollective.com/vapor/backer/18/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/19/website" target="_blank"><img src="https://opencollective.com/vapor/backer/19/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/20/website" target="_blank"><img src="https://opencollective.com/vapor/backer/20/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/21/website" target="_blank"><img src="https://opencollective.com/vapor/backer/21/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/22/website" target="_blank"><img src="https://opencollective.com/vapor/backer/22/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/23/website" target="_blank"><img src="https://opencollective.com/vapor/backer/23/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/24/website" target="_blank"><img src="https://opencollective.com/vapor/backer/24/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/25/website" target="_blank"><img src="https://opencollective.com/vapor/backer/25/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/26/website" target="_blank"><img src="https://opencollective.com/vapor/backer/26/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/27/website" target="_blank"><img src="https://opencollective.com/vapor/backer/27/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/28/website" target="_blank"><img src="https://opencollective.com/vapor/backer/28/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/29/website" target="_blank"><img src="https://opencollective.com/vapor/backer/29/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/30/website" target="_blank"><img src="https://opencollective.com/vapor/backer/30/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/31/website" target="_blank"><img src="https://opencollective.com/vapor/backer/31/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/32/website" target="_blank"><img src="https://opencollective.com/vapor/backer/32/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/33/website" target="_blank"><img src="https://opencollective.com/vapor/backer/33/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/34/website" target="_blank"><img src="https://opencollective.com/vapor/backer/34/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/35/website" target="_blank"><img src="https://opencollective.com/vapor/backer/35/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/36/website" target="_blank"><img src="https://opencollective.com/vapor/backer/36/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/37/website" target="_blank"><img src="https://opencollective.com/vapor/backer/37/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/38/website" target="_blank"><img src="https://opencollective.com/vapor/backer/38/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/39/website" target="_blank"><img src="https://opencollective.com/vapor/backer/39/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/40/website" target="_blank"><img src="https://opencollective.com/vapor/backer/40/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/41/website" target="_blank"><img src="https://opencollective.com/vapor/backer/41/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/42/website" target="_blank"><img src="https://opencollective.com/vapor/backer/42/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/43/website" target="_blank"><img src="https://opencollective.com/vapor/backer/43/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/44/website" target="_blank"><img src="https://opencollective.com/vapor/backer/44/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/45/website" target="_blank"><img src="https://opencollective.com/vapor/backer/45/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/46/website" target="_blank"><img src="https://opencollective.com/vapor/backer/46/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/47/website" target="_blank"><img src="https://opencollective.com/vapor/backer/47/avatar.svg"></a>
<a href="https://opencollective.com/vapor/backer/48/website" target="_blank"><img src="https://opencollective.com/vapor/backer/48/avatar.svg"></a>


================================================
FILE: Sources/CVaporBcrypt/bcrypt.c
================================================
/*    $OpenBSD: bcrypt.c,v 1.55 2015/09/13 15:33:48 guenther Exp $    */

/*
 * Copyright (c) 2014 Ted Unangst <tedu@openbsd.org>
 * Copyright (c) 1997 Niels Provos <provos@umich.edu>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
/* This password hashing algorithm was designed by David Mazieres
 * <dm@lcs.mit.edu> and works as follows:
 *
 * 1. state := InitState ()
 * 2. state := ExpandKey (state, salt, password)
 * 3. REPEAT rounds:
 *      state := ExpandKey (state, 0, password)
 *    state := ExpandKey (state, 0, salt)
 * 4. ctext := "OrpheanBeholderScryDoubt"
 * 5. REPEAT 64:
 *     ctext := Encrypt_ECB (state, ctext);
 * 6. RETURN Concatenate (salt, ctext);
 *
 */

#include <sys/types.h>
#include "blf.h"
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bcrypt.h"

char   *bcrypt_gensalt(u_int8_t);

static int decode_base64(u_int8_t *, size_t, const char *);

/*
 * the core bcrypt function
 */
int
vapor_bcrypt_hashpass(const char *key, const char *salt, char *encrypted,
                      size_t encryptedlen)
{
    blf_ctx state;
    u_int32_t rounds, i, k;
    u_int16_t j;
    size_t key_len;
    u_int8_t salt_len, logr, minor;
    u_int8_t ciphertext[4 * BCRYPT_WORDS] = "OrpheanBeholderScryDoubt";
    u_int8_t csalt[BCRYPT_MAXSALT];
    u_int32_t cdata[BCRYPT_WORDS];

    if (encryptedlen < BCRYPT_HASHSPACE)
        goto inval;

    /* Check and discard "$" identifier */
    if (salt[0] != '$')
        goto inval;
    salt += 1;

    if (salt[0] != BCRYPT_VERSION)
        goto inval;

    /* Check for minor versions */
    switch ((minor = salt[1])) {
        case 'a':
            key_len = (u_int8_t)(strlen(key) + 1);
            break;
        case 'b':
            /* strlen() returns a size_t, but the function calls
             * below result in implicit casts to a narrower integer
             * type, so cap key_len at the actual maximum supported
             * length here to avoid integer wraparound */
            key_len = strlen(key);
            if (key_len > 72)
                key_len = 72;
            key_len++; /* include the NUL */
            break;
        default:
            goto inval;
    }
    if (salt[2] != '$')
        goto inval;
    /* Discard version + "$" identifier */
    salt += 3;

    /* Check and parse num rounds */
    if (!isdigit((unsigned char)salt[0]) ||
        !isdigit((unsigned char)salt[1]) || salt[2] != '$')
        goto inval;
    logr = (salt[1] - '0') + ((salt[0] - '0') * 10);
    if (logr < BCRYPT_MINLOGROUNDS || logr > 31)
        goto inval;
    /* Computer power doesn't increase linearly, 2^x should be fine */
    rounds = 1U << logr;

    /* Discard num rounds + "$" identifier */
    salt += 3;

    if (strlen(salt) * 3 / 4 < BCRYPT_MAXSALT)
        goto inval;

    /* We dont want the base64 salt but the raw data */
    if (decode_base64(csalt, BCRYPT_MAXSALT, salt))
        goto inval;
    salt_len = BCRYPT_MAXSALT;

    /* Setting up S-Boxes and Subkeys */
    Vapor_Blowfish_initstate(&state);
    Vapor_Blowfish_expandstate(&state, csalt, salt_len,
                               (u_int8_t *) key, key_len);
    for (k = 0; k < rounds; k++) {
        Vapor_Blowfish_expand0state(&state, (u_int8_t *) key, key_len);
        Vapor_Blowfish_expand0state(&state, csalt, salt_len);
    }

    /* This can be precomputed later */
    j = 0;
    for (i = 0; i < BCRYPT_WORDS; i++)
        cdata[i] = Vapor_Blowfish_stream2word(ciphertext, 4 * BCRYPT_WORDS, &j);

    /* Now do the encryption */
    for (k = 0; k < 64; k++)
        vapor_blf_enc(&state, cdata, BCRYPT_WORDS / 2);

    for (i = 0; i < BCRYPT_WORDS; i++) {
        ciphertext[4 * i + 3] = cdata[i] & 0xff;
        cdata[i] = cdata[i] >> 8;
        ciphertext[4 * i + 2] = cdata[i] & 0xff;
        cdata[i] = cdata[i] >> 8;
        ciphertext[4 * i + 1] = cdata[i] & 0xff;
        cdata[i] = cdata[i] >> 8;
        ciphertext[4 * i + 0] = cdata[i] & 0xff;
    }


    snprintf(encrypted, 8, "$2%c$%2.2u$", minor, logr);
    vapor_encode_base64(encrypted + 7, csalt, BCRYPT_MAXSALT);
    vapor_encode_base64(encrypted + 7 + 22, ciphertext, 4 * BCRYPT_WORDS - 1);
    explicit_bzero(&state, sizeof(state));
    explicit_bzero(ciphertext, sizeof(ciphertext));
    explicit_bzero(csalt, sizeof(csalt));
    explicit_bzero(cdata, sizeof(cdata));
    return 0;

inval:
    errno = EINVAL;
    return -1;
}

/*
 * internal utilities
 */
static const u_int8_t Base64Code[] =
"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

static const u_int8_t index_64[128] = {
    255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 0, 1, 54, 55,
    56, 57, 58, 59, 60, 61, 62, 63, 255, 255,
    255, 255, 255, 255, 255, 2, 3, 4, 5, 6,
    7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
    17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
    255, 255, 255, 255, 255, 255, 28, 29, 30,
    31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
    41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
    51, 52, 53, 255, 255, 255, 255, 255
};
#define CHAR64(c)  ( (c) > 127 ? 255 : index_64[(c)])

/*
 * read buflen (after decoding) bytes of data from b64data
 */
static int
decode_base64(u_int8_t *buffer, size_t len, const char *b64data)
{
    u_int8_t *bp = buffer;
    const u_int8_t *p = (u_int8_t *)b64data;
    u_int8_t c1, c2, c3, c4;

    while (bp < buffer + len) {
        c1 = CHAR64(*p);
        /* Invalid data */
        if (c1 == 255)
            return -1;

        c2 = CHAR64(*(p + 1));
        if (c2 == 255)
            return -1;

        *bp++ = (c1 << 2) | ((c2 & 0x30) >> 4);
        if (bp >= buffer + len)
            break;

        c3 = CHAR64(*(p + 2));
        if (c3 == 255)
            return -1;

        *bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);
        if (bp >= buffer + len)
            break;

        c4 = CHAR64(*(p + 3));
        if (c4 == 255)
            return -1;
        *bp++ = ((c3 & 0x03) << 6) | c4;

        p += 4;
    }
    return 0;
}

/*
 * Turn len bytes of data into base64 encoded data.
 * This works without = padding.
 */
int
vapor_encode_base64(char *b64buffer, const u_int8_t *data, size_t len)
{
    u_int8_t *bp = (u_int8_t *)b64buffer;
    const u_int8_t *p = data;
    u_int8_t c1, c2;

    while (p < data + len) {
        c1 = *p++;
        *bp++ = Base64Code[(c1 >> 2)];
        c1 = (c1 & 0x03) << 4;
        if (p >= data + len) {
            *bp++ = Base64Code[c1];
            break;
        }
        c2 = *p++;
        c1 |= (c2 >> 4) & 0x0f;
        *bp++ = Base64Code[c1];
        c1 = (c2 & 0x0f) << 2;
        if (p >= data + len) {
            *bp++ = Base64Code[c1];
            break;
        }
        c2 = *p++;
        c1 |= (c2 >> 6) & 0x03;
        *bp++ = Base64Code[c1];
        *bp++ = Base64Code[c2 & 0x3f];
    }
    *bp = '\0';
    return 0;
}


================================================
FILE: Sources/CVaporBcrypt/bcrypt.h
================================================
#include <sys/types.h>
#include <string.h>
#include <stdio.h>

#if defined(_WIN32)
typedef unsigned char uint8_t;
typedef uint8_t u_int8_t;
typedef unsigned short uint16_t;
typedef uint16_t u_int16_t;
typedef unsigned uint32_t;
typedef uint32_t u_int32_t;
typedef unsigned long long uint64_t;
typedef uint64_t u_int64_t;
#define snprintf _snprintf
#define __attribute__(unused)
#else
#include <stdint.h>
#endif

#define explicit_bzero(s,n) memset(s, 0, n)
#define DEF_WEAK(f)


/* This implementation is adaptable to current computing power.
 * You can have up to 2^31 rounds which should be enough for some
 * time to come.
 */

#define BCRYPT_VERSION '2'
#define BCRYPT_MAXSALT 16    /* Precomputation is just so nice */
#define BCRYPT_WORDS 6        /* Ciphertext words */
#define BCRYPT_MINLOGROUNDS 4    /* we have log2(rounds) in salt */

#define    BCRYPT_SALTSPACE    (7 + (BCRYPT_MAXSALT * 4 + 2) / 3 + 1)
#define    BCRYPT_HASHSPACE    61


int vapor_bcrypt_hashpass(const char *key, const char *salt, char *encrypted, size_t encryptedlen);
int vapor_encode_base64(char *, const u_int8_t *, size_t);


================================================
FILE: Sources/CVaporBcrypt/blf.c
================================================
/*    $OpenBSD: blf.c,v 1.7 2007/11/26 09:28:34 martynas Exp $    */

/*
 * Blowfish block cipher for OpenBSD
 * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
 * All rights reserved.
 *
 * Implementation advice by David Mazieres <dm@lcs.mit.edu>.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by Niels Provos.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * This code is derived from section 14.3 and the given source
 * in section V of Applied Cryptography, second edition.
 * Blowfish is an unpatented fast block cipher designed by
 * Bruce Schneier.
 */

#include <sys/types.h>

#include "blf.h"

#undef inline
#ifdef __GNUC__
#define inline __inline
#else                /* !__GNUC__ */
#define inline
#endif                /* !__GNUC__ */

/* Function for Feistel Networks */

#define F(s, x) ((((s)[        (((x)>>24)&0xFF)]  \
+ (s)[0x100 + (((x)>>16)&0xFF)]) \
^ (s)[0x200 + (((x)>> 8)&0xFF)]) \
+ (s)[0x300 + ( (x)     &0xFF)])

#define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n])

void
Vapor_Blowfish_encipher(blf_ctx *c, u_int32_t *x)
{
    u_int32_t Xl;
    u_int32_t Xr;
    u_int32_t *s = c->S[0];
    u_int32_t *p = c->P;

    Xl = x[0];
    Xr = x[1];

    Xl ^= p[0];
    BLFRND(s, p, Xr, Xl, 1); BLFRND(s, p, Xl, Xr, 2);
    BLFRND(s, p, Xr, Xl, 3); BLFRND(s, p, Xl, Xr, 4);
    BLFRND(s, p, Xr, Xl, 5); BLFRND(s, p, Xl, Xr, 6);
    BLFRND(s, p, Xr, Xl, 7); BLFRND(s, p, Xl, Xr, 8);
    BLFRND(s, p, Xr, Xl, 9); BLFRND(s, p, Xl, Xr, 10);
    BLFRND(s, p, Xr, Xl, 11); BLFRND(s, p, Xl, Xr, 12);
    BLFRND(s, p, Xr, Xl, 13); BLFRND(s, p, Xl, Xr, 14);
    BLFRND(s, p, Xr, Xl, 15); BLFRND(s, p, Xl, Xr, 16);

    x[0] = Xr ^ p[17];
    x[1] = Xl;
}

void
Vapor_Blowfish_decipher(blf_ctx *c, u_int32_t *x)
{
    u_int32_t Xl;
    u_int32_t Xr;
    u_int32_t *s = c->S[0];
    u_int32_t *p = c->P;

    Xl = x[0];
    Xr = x[1];

    Xl ^= p[17];
    BLFRND(s, p, Xr, Xl, 16); BLFRND(s, p, Xl, Xr, 15);
    BLFRND(s, p, Xr, Xl, 14); BLFRND(s, p, Xl, Xr, 13);
    BLFRND(s, p, Xr, Xl, 12); BLFRND(s, p, Xl, Xr, 11);
    BLFRND(s, p, Xr, Xl, 10); BLFRND(s, p, Xl, Xr, 9);
    BLFRND(s, p, Xr, Xl, 8); BLFRND(s, p, Xl, Xr, 7);
    BLFRND(s, p, Xr, Xl, 6); BLFRND(s, p, Xl, Xr, 5);
    BLFRND(s, p, Xr, Xl, 4); BLFRND(s, p, Xl, Xr, 3);
    BLFRND(s, p, Xr, Xl, 2); BLFRND(s, p, Xl, Xr, 1);

    x[0] = Xr ^ p[0];
    x[1] = Xl;
}

void
Vapor_Blowfish_initstate(blf_ctx *c)
{
    /* P-box and S-box tables initialized with digits of Pi */

    static const blf_ctx initstate =

    { {
        {
            0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
            0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
            0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
            0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
            0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
            0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
            0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
            0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
            0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
            0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
            0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
            0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
            0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
            0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
            0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
            0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
            0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
            0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
            0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
            0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
            0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
            0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
            0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
            0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
            0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
            0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
            0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
            0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
            0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
            0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
            0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
            0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
            0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
            0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
            0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
            0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
            0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
            0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
            0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
            0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
            0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
            0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
            0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
            0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
            0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
            0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
            0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
            0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
            0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
            0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
            0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
            0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
            0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
            0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
            0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
            0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
            0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
            0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
            0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
            0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
            0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
            0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
            0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
            0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a},
        {
            0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
            0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
            0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
            0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
            0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
            0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
            0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
            0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
            0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
            0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
            0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
            0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
            0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
            0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
            0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
            0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
            0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
            0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
            0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
            0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
            0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
            0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
            0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
            0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
            0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
            0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
            0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
            0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
            0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
            0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
            0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
            0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
            0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
            0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
            0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
            0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
            0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
            0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
            0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
            0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
            0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
            0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
            0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
            0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
            0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
            0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
            0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
            0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
            0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
            0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
            0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
            0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
            0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
            0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
            0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
            0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
            0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
            0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
            0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
            0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
            0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
            0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
            0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
            0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7},
        {
            0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
            0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
            0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
            0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
            0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
            0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
            0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
            0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
            0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
            0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
            0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
            0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
            0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
            0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
            0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
            0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
            0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
            0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
            0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
            0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
            0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
            0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
            0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
            0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
            0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
            0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
            0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
            0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
            0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
            0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
            0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
            0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
            0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
            0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
            0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
            0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
            0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
            0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
            0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
            0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
            0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
            0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
            0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
            0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
            0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
            0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
            0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
            0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
            0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
            0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
            0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
            0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
            0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
            0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
            0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
            0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
            0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
            0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
            0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
            0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
            0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
            0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
            0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
            0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0},
        {
            0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
            0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
            0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
            0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
            0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
            0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
            0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
            0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
            0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
            0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
            0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
            0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
            0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
            0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
            0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
            0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
            0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
            0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
            0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
            0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
            0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
            0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
            0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
            0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
            0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
            0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
            0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
            0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
            0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
            0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
            0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
            0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
            0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
            0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
            0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
            0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
            0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
            0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
            0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
            0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
            0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
            0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
            0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
            0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
            0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
            0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
            0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
            0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
            0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
            0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
            0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
            0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
            0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
            0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
            0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
            0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
            0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
            0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
            0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
            0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
            0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
            0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
            0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
            0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6}
    },
        {
            0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
            0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
            0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
            0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
            0x9216d5d9, 0x8979fb1b
        } };

    *c = initstate;
}

u_int32_t
Vapor_Blowfish_stream2word(const u_int8_t *data, u_int16_t databytes,
                           u_int16_t *current)
{
    u_int8_t i;
    u_int16_t j;
    u_int32_t temp;

    temp = 0x00000000;
    j = *current;

    for (i = 0; i < 4; i++, j++) {
        if (j >= databytes)
            j = 0;
        temp = (temp << 8) | data[j];
    }

    *current = j;
    return temp;
}

void
Vapor_Blowfish_expand0state(blf_ctx *c, const u_int8_t *key, u_int16_t keybytes)
{
    u_int16_t i;
    u_int16_t j;
    u_int16_t k;
    u_int32_t temp;
    u_int32_t data[2];

    j = 0;
    for (i = 0; i < BLF_N + 2; i++) {
        /* Extract 4 int8 to 1 int32 from keystream */
        temp = Vapor_Blowfish_stream2word(key, keybytes, &j);
        c->P[i] = c->P[i] ^ temp;
    }

    j = 0;
    data[0] = 0x00000000;
    data[1] = 0x00000000;
    for (i = 0; i < BLF_N + 2; i += 2) {
        Vapor_Blowfish_encipher(c, data);

        c->P[i] = data[0];
        c->P[i + 1] = data[1];
    }

    for (i = 0; i < 4; i++) {
        for (k = 0; k < 256; k += 2) {
            Vapor_Blowfish_encipher(c, data);

            c->S[i][k] = data[0];
            c->S[i][k + 1] = data[1];
        }
    }
}


void
Vapor_Blowfish_expandstate(blf_ctx *c, const u_int8_t *data, u_int16_t databytes,
                           const u_int8_t *key, u_int16_t keybytes)
{
    u_int16_t i;
    u_int16_t j;
    u_int16_t k;
    u_int32_t temp;
    u_int32_t d[2];

    j = 0;
    for (i = 0; i < BLF_N + 2; i++) {
        /* Extract 4 int8 to 1 int32 from keystream */
        temp = Vapor_Blowfish_stream2word(key, keybytes, &j);
        c->P[i] = c->P[i] ^ temp;
    }

    j = 0;
    d[0] = 0x00000000;
    d[1] = 0x00000000;
    for (i = 0; i < BLF_N + 2; i += 2) {
        d[0] ^= Vapor_Blowfish_stream2word(data, databytes, &j);
        d[1] ^= Vapor_Blowfish_stream2word(data, databytes, &j);
        Vapor_Blowfish_encipher(c, d);

        c->P[i] = d[0];
        c->P[i + 1] = d[1];
    }

    for (i = 0; i < 4; i++) {
        for (k = 0; k < 256; k += 2) {
            d[0] ^= Vapor_Blowfish_stream2word(data, databytes, &j);
            d[1] ^= Vapor_Blowfish_stream2word(data, databytes, &j);
            Vapor_Blowfish_encipher(c, d);

            c->S[i][k] = d[0];
            c->S[i][k + 1] = d[1];
        }
    }

}

void
vapor_blf_key(blf_ctx *c, const u_int8_t *k, u_int16_t len)
{
    /* Initialize S-boxes and subkeys with Pi */
    Vapor_Blowfish_initstate(c);

    /* Transform S-boxes and subkeys with key */
    Vapor_Blowfish_expand0state(c, k, len);
}

void
vapor_blf_enc(blf_ctx *c, u_int32_t *data, u_int16_t blocks)
{
    u_int32_t *d;
    u_int16_t i;

    d = data;
    for (i = 0; i < blocks; i++) {
        Vapor_Blowfish_encipher(c, d);
        d += 2;
    }
}

void
vapor_blf_dec(blf_ctx *c, u_int32_t *data, u_int16_t blocks)
{
    u_int32_t *d;
    u_int16_t i;

    d = data;
    for (i = 0; i < blocks; i++) {
        Vapor_Blowfish_decipher(c, d);
        d += 2;
    }
}

void
vapor_blf_ecb_encrypt(blf_ctx *c, u_int8_t *data, u_int32_t len)
{
    u_int32_t l, r, d[2];
    u_int32_t i;

    for (i = 0; i < len; i += 8) {
        l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
        r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
        d[0] = l;
        d[1] = r;
        Vapor_Blowfish_encipher(c, d);
        l = d[0];
        r = d[1];
        data[0] = l >> 24 & 0xff;
        data[1] = l >> 16 & 0xff;
        data[2] = l >> 8 & 0xff;
        data[3] = l & 0xff;
        data[4] = r >> 24 & 0xff;
        data[5] = r >> 16 & 0xff;
        data[6] = r >> 8 & 0xff;
        data[7] = r & 0xff;
        data += 8;
    }
}

void
vapor_blf_ecb_decrypt(blf_ctx *c, u_int8_t *data, u_int32_t len)
{
    u_int32_t l, r, d[2];
    u_int32_t i;

    for (i = 0; i < len; i += 8) {
        l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
        r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
        d[0] = l;
        d[1] = r;
        Vapor_Blowfish_decipher(c, d);
        l = d[0];
        r = d[1];
        data[0] = l >> 24 & 0xff;
        data[1] = l >> 16 & 0xff;
        data[2] = l >> 8 & 0xff;
        data[3] = l & 0xff;
        data[4] = r >> 24 & 0xff;
        data[5] = r >> 16 & 0xff;
        data[6] = r >> 8 & 0xff;
        data[7] = r & 0xff;
        data += 8;
    }
}

void
vapor_blf_cbc_encrypt(blf_ctx *c, u_int8_t *iv, u_int8_t *data, u_int32_t len)
{
    u_int32_t l, r, d[2];
    u_int32_t i, j;

    for (i = 0; i < len; i += 8) {
        for (j = 0; j < 8; j++)
            data[j] ^= iv[j];
        l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
        r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
        d[0] = l;
        d[1] = r;
        Vapor_Blowfish_encipher(c, d);
        l = d[0];
        r = d[1];
        data[0] = l >> 24 & 0xff;
        data[1] = l >> 16 & 0xff;
        data[2] = l >> 8 & 0xff;
        data[3] = l & 0xff;
        data[4] = r >> 24 & 0xff;
        data[5] = r >> 16 & 0xff;
        data[6] = r >> 8 & 0xff;
        data[7] = r & 0xff;
        iv = data;
        data += 8;
    }
}

void
vapor_blf_cbc_decrypt(blf_ctx *c, u_int8_t *iva, u_int8_t *data, u_int32_t len)
{
    u_int32_t l, r, d[2];
    u_int8_t *iv;
    u_int32_t i, j;

    iv = data + len - 16;
    data = data + len - 8;
    for (i = len - 8; i >= 8; i -= 8) {
        l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
        r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
        d[0] = l;
        d[1] = r;
        Vapor_Blowfish_decipher(c, d);
        l = d[0];
        r = d[1];
        data[0] = l >> 24 & 0xff;
        data[1] = l >> 16 & 0xff;
        data[2] = l >> 8 & 0xff;
        data[3] = l & 0xff;
        data[4] = r >> 24 & 0xff;
        data[5] = r >> 16 & 0xff;
        data[6] = r >> 8 & 0xff;
        data[7] = r & 0xff;
        for (j = 0; j < 8; j++)
            data[j] ^= iv[j];
        iv -= 8;
        data -= 8;
    }
    l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
    r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
    d[0] = l;
    d[1] = r;
    Vapor_Blowfish_decipher(c, d);
    l = d[0];
    r = d[1];
    data[0] = l >> 24 & 0xff;
    data[1] = l >> 16 & 0xff;
    data[2] = l >> 8 & 0xff;
    data[3] = l & 0xff;
    data[4] = r >> 24 & 0xff;
    data[5] = r >> 16 & 0xff;
    data[6] = r >> 8 & 0xff;
    data[7] = r & 0xff;
    for (j = 0; j < 8; j++)
        data[j] ^= iva[j];
}


================================================
FILE: Sources/CVaporBcrypt/blf.h
================================================
/*    $OpenBSD: blf.h,v 1.6 2007/02/21 19:25:40 grunk Exp $    */

/*
 * Blowfish - a fast block cipher designed by Bruce Schneier
 *
 * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by Niels Provos.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _BLF_H_
#define _BLF_H_

#include "bcrypt.h"

/* Schneier states the maximum key length to be 56 bytes.
 * The way how the subkeys are initialized by the key up
 * to (N+2)*4 i.e. 72 bytes are utilized.
 * Warning: For normal blowfish encryption only 56 bytes
 * of the key affect all cipherbits.
 */

#define BLF_N    16            /* Number of Subkeys */
#define BLF_MAXKEYLEN ((BLF_N-2)*4)    /* 448 bits */
#define BLF_MAXUTILIZED ((BLF_N+2)*4)    /* 576 bits */

/* Blowfish context */
typedef struct BlowfishContext {
    u_int32_t S[4][256];    /* S-Boxes */
    u_int32_t P[BLF_N + 2];    /* Subkeys */
} blf_ctx;

/* Raw access to customized Blowfish
 *    blf_key is just:
 *    Blowfish_initstate( state )
 *    Blowfish_expand0state( state, key, keylen )
 */

void Vapor_Blowfish_encipher(blf_ctx *, u_int32_t *);
void Vapor_Blowfish_decipher(blf_ctx *, u_int32_t *);
void Vapor_Blowfish_initstate(blf_ctx *);
void Vapor_Blowfish_expand0state(blf_ctx *, const u_int8_t *, u_int16_t);
void Vapor_Blowfish_expandstate(blf_ctx *, const u_int8_t *, u_int16_t, const u_int8_t *, u_int16_t);

/* Standard Blowfish */

void vapor_blf_key(blf_ctx *, const u_int8_t *, u_int16_t);
void vapor_blf_enc(blf_ctx *, u_int32_t *, u_int16_t);
void vapor_blf_dec(blf_ctx *, u_int32_t *, u_int16_t);

/* Converts u_int8_t to u_int32_t */
u_int32_t Vapor_Blowfish_stream2word(const u_int8_t *, u_int16_t ,
                                     u_int16_t *);

void vapor_blf_ecb_encrypt(blf_ctx *, u_int8_t *, u_int32_t);
void vapor_blf_ecb_decrypt(blf_ctx *, u_int8_t *, u_int32_t);

void vapor_blf_cbc_encrypt(blf_ctx *, u_int8_t *, u_int8_t *, u_int32_t);
void vapor_blf_cbc_decrypt(blf_ctx *, u_int8_t *, u_int8_t *, u_int32_t);
#endif


================================================
FILE: Sources/CVaporBcrypt/include/module.modulemap
================================================
module CVaporBcrypt [system][extern_c] {
 header "../bcrypt.h"
 export *
}


================================================
FILE: Sources/Development/Resources/fileio.txt
================================================
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ut eleifend turpis, quis vestibulum odio. Sed vestibulum, lorem at sagittis mattis, nunc sem euismod augue, id accumsan ipsum turpis bibendum leo. Praesent in faucibus nulla. Sed egestas aliquam velit eu tempor. Quisque egestas risus non justo posuere, id imperdiet erat porta. Phasellus commodo, justo ut volutpat elementum, tortor felis egestas metus, vel congue elit sem in ipsum. Suspendisse potenti. Fusce pharetra pellentesque nulla at blandit. Proin at dui eu ex lacinia tempus. Donec faucibus est vel erat faucibus ullamcorper. Integer vel nisi erat. Sed porta risus magna, eu ultricies massa tempus quis. Donec dignissim fringilla lobortis. Morbi sapien sem, cursus quis sollicitudin id, varius eget purus. Morbi at commodo diam. Duis efficitur blandit nisl nec ultricies. Praesent ultrices nulla eget mattis lobortis. Morbi euismod pharetra purus quis efficitur. Cras nec elit nec purus ullamcorper consequat ut in libero. Duis ultricies hendrerit odio vitae hendrerit. Pellentesque pharetra malesuada purus tincidunt tincidunt. Aliquam volutpat, nisl et porta vehicula, lorem elit ultricies purus, et cursus massa lectus vitae leo. Donec ornare lacinia sem non mollis. Aenean quis nulla vel diam tempus malesuada. Vestibulum in orci purus. Donec et leo luctus, congue massa sed, blandit diam. Aliquam non purus vitae nisl sollicitudin malesuada. Vivamus sed urna convallis, mattis nisi ac, pellentesque dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nullam laoreet erat id vehicula lacinia. In hac habitasse platea dictumst. Duis dapibus, sapien nec dignissim tempus, nulla massa interdum enim, posuere imperdiet nulla justo semper leo. Curabitur tempus rutrum magna, vitae tristique tortor porttitor vitae. Donec molestie nibh sit amet quam elementum, eget maximus neque scelerisque. Pellentesque a elit sed arcu faucibus tempor. Morbi congue, nunc a imperdiet sodales, dolor elit placerat nisl, eu elementum elit mi id diam. Duis pretium quam in tellus scelerisque aliquam. Curabitur egestas euismod nunc, ut tempus est pellentesque sed. Aenean dignissim sodales lorem, quis convallis nibh pretium id. Suspendisse sed elementum lacus. Fusce congue magna hendrerit purus dictum consectetur. Duis ut purus a ipsum facilisis aliquet. Suspendisse nec sollicitudin tellus. Quisque sit amet leo sit amet lorem tincidunt euismod. Cras ut lectus quis lorem fermentum commodo. Quisque euismod non nisi tempor rhoncus. Nam sodales, ante id vehicula pretium, tortor turpis porta ligula, et malesuada ex velit non odio. Proin scelerisque tellus iaculis vulputate tempus. Fusce gravida odio eget dignissim luctus. Phasellus hendrerit ultricies nibh, id consequat libero maximus et. Suspendisse rhoncus orci eget leo fermentum, in pretium ligula fringilla. Ut mollis dictum condimentum. Quisque lacus ipsum, molestie in tristique in, porttitor vel massa. Proin sagittis metus et eleifend rhoncus. Cras porta non turpis vel molestie. Duis bibendum nisl nec lectus cursus pretium. Nam porta nisi id tortor hendrerit, quis feugiat diam eleifend. Ut luctus sagittis nulla. Aliquam at libero lectus. Praesent sed egestas sem, sed tempus neque. Duis ultrices nisl nec laoreet ultricies. Nulla id urna quis lacus tincidunt scelerisque. Sed erat arcu, efficitur sed sagittis nec, venenatis et est. Integer viverra laoreet odio ut posuere. Pellentesque quis libero risus. Ut interdum id magna pellentesque aliquet. Pellentesque id commodo est, a tincidunt ex. Donec elementum urna leo, ac gravida ligula tempus vel. Suspendisse molestie aliquet ligula nec lobortis. Aenean vel elementum massa, at dapibus elit. Fusce ac pellentesque risus, at hendrerit erat. Aenean vel placerat tortor, non finibus risus. Vestibulum ultrices rutrum blandit. Integer id ultrices arcu. Nunc molestie urna vel bibendum imperdiet. Mauris finibus lorem non leo vulputate auctor. Praesent mollis velit vitae magna faucibus venenatis. Donec egestas euismod tortor, quis vehicula elit porta in. Cras tempor justo ut tortor.


================================================
FILE: Sources/Development/configure.swift
================================================
import Vapor
import NIOConcurrencyHelpers
import NIOSSL

public func configure(_ app: Application) throws {
    app.logger.logLevel = Environment.process.LOG_LEVEL ?? .debug
    
    app.http.server.configuration.hostname = "127.0.0.1"
    if app.environment == .tls {
        app.http.server.configuration.port = 8443
        try app.http.server.configuration.tlsConfiguration = .makeServerConfiguration(
            certificateChain: NIOSSLCertificate.fromPEMBytes(TLSData.sampleServerCertificatePEM).map { .certificate($0) },
            privateKey: .privateKey(.init(bytes: TLSData.sampleServerPrivateKeyPEM, format: .pem))
        )
    }
    
    // routes
    try routes(app)
}

actor MemoryCache {
    var storage: [String: String] = [:]

    func get(_ key: String) -> String? { self.storage[key] }
    func set(_ key: String, to value: String?) { self.storage[key] = value }
}

extension Environment {
    static var tls: Environment { .custom(name: "tls") }
}

enum TLSData {
    static var sampleServerCertificatePEM: [UInt8] { .init("""
        -----BEGIN CERTIFICATE-----
        MIIDeTCCAmGgAwIBAgIUMJzqelT95d/JU2Yp4/XHuqhJTs4wDQYJKoZIhvcNAQEL\nBQAwTDELMAkGA1UEBhMCVVMxKTAnBgNVBAoMIFZhcG9yIERldmVsb3BtZW50IEV4
        YW1wbGUgU2VydmVyMRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMjMwMzEwMTIyNjQw\nWhcNMjcwMzEwMTIyNjQwWjBMMQswCQYDVQQGEwJVUzEpMCcGA1UECgwgVmFwb3Ig
        RGV2ZWxvcG1lbnQgRXhhbXBsZSBTZXJ2ZXIxEjAQBgNVBAMMCWxvY2FsaG9zdDCC\nASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALavC7FuHyTwEbYUEtUDHPdE
        LCglZGypp1+qE1XuhQ1qPgx7FMBKXAYYLjSyEfK1GaorBXfLGW5xNHfSrJYVmhm2\nUOGPJbZvFtXZeufQz8B31u6sfXEJNWbJ6K8HUZkPyNRJROS5IBhDRiKxUTJOT+Ph
        pT1ZooRNd/9/v/0JoM4HEXE4oO7KIb4fM4IuVIfTdib42aMH7jKMVfVr7N2zOFnm\nMd0fmc5y0Gx/tvr13EN92lGlS3V4+YTWr7KsueQYvplJiDJ0E3AipLXRYtarsJqD
        nWhktpvbknbf9LntKJo9yL+O6CRifS8zBn/cqfFo7vuIRQyhd2q/ndjiqQoOqx8C\nAwEAAaNTMFEwHQYDVR0OBBYEFDNaYh5eewiz63D/z4Imzmd3Ey+kMB8GA1UdIwQY
        MBaAFDNaYh5eewiz63D/z4Imzmd3Ey+kMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI\nhvcNAQELBQADggEBAEOxFji5Jlx3LdTjVG3cy5PnZWFGrREw4JE6vl258upGTEaz
        m/TQOBiSWxEG5SfMSFjaNzoHu5BU+uTUyr/gCUseFoseA+C+wsCikfSPKpmfLEW0\nNF49c6fPYWCu39wMpNCgrcXgde29V3Sar5WfYclFnQUEHqSRL22Yq+JNPnokFrja
        L9jOe/0MbZ34Gurjj9LMlVDg3p8FTKJJ9qipPMVBPy+/8ABm4qu7vx0Kacuskgc8\nu8RErJ0sqir7ggBGqgRp+Z+DC5UcqlMUZZQPKSLpCqfdrOIcDrTK9u/PU9cGdALh
        C+4n5ZIHWu66eCvARnqbCTwcOwGMxkKX/4FpI54=
        -----END CERTIFICATE-----
        """.utf8)
    }
    static var sampleServerPrivateKeyPEM: [UInt8] { .init("""
        -----BEGIN PRIVATE KEY-----
        MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC2rwuxbh8k8BG2\nFBLVAxz3RCwoJWRsqadfqhNV7oUNaj4MexTASlwGGC40shHytRmqKwV3yxlucTR3
        0qyWFZoZtlDhjyW2bxbV2Xrn0M/Ad9burH1xCTVmyeivB1GZD8jUSUTkuSAYQ0Yi\nsVEyTk/j4aU9WaKETXf/f7/9CaDOBxFxOKDuyiG+HzOCLlSH03Ym+NmjB+4yjFX1
        a+zdszhZ5jHdH5nOctBsf7b69dxDfdpRpUt1ePmE1q+yrLnkGL6ZSYgydBNwIqS1\n0WLWq7Cag51oZLab25J23/S57SiaPci/jugkYn0vMwZ/3KnxaO77iEUMoXdqv53Y
        4qkKDqsfAgMBAAECggEANfp17YjY2fy3dwHqaJdhZSx3Eauuxy6/3lPuH6t5E/Qq\n/lwVzxWJqGFXsclV5U2eljndBT71Nj1r3+XXigc6/9Lvhh5aadPcPvbiSoHYCQo/
        70j3TcGHTmZlguYaNaxEznkRyrVqptCl9hVHpSIfl/lx7jVAgHA1f0CblWRVZ9qM\nhX42ye0xxamUdfcUFYvZ4n7Tz5G36HP+cOKlrN6nGfhmOf3hb3ILuPymCJdECvFM
        xsCXpHA2r4biYMRwkWO2+X5Scx7nVrQYizJG1iTdZnY6g1heRhzUDTcf7yjyr2++\nd+9VRI0KW5gO7q0sIarHgy7ItAAWgjGhGBASU4rebQKBgQC5xeE47WUzA1zQoDof
        u55tSp32hHKkw2ysdIO3LUSVHS/VhMMNHTo0fqhvgY7Wd25M9OBVmWbTvnSNmcU+\niVdVcd9rmD+jPEBftwjRKtXkQgJpMNuDszOQ3bJYqAUkRfT7ceuiil3H4Awdq6UE
        qvynmn7MYZN7CxcefvOQlSdpKwKBgQD7vjXAOJn7ZyGRsb1lKxNCHL9GvZthsM1h\nvyH8uvUm94Ztw5g9ON2qgPZQIwZxEY+LxnjfqaooKHE38rNdKYHMLsfgNQ2tdopR
        2sEqVL0aQP25YAYiL4jI7hGI7GwgiSiywvmhGWjU5ZIu8fKqc+8pZy4vW/EgVctQ\nuLntBvgj3QKBgGaSLEV7RcoBzEhgf1cwB0w+y7Ll9EqmoCUj++mys9BFGjkhIXTn
        M1DysdtHRG+D58HT3t1EYrL80GuygGaD/FVwFzTYDiL5zG1MqTCcHxb1n1EnKbyw\nwAL3dVZgBt69RYNjpf/Lt/X47ZegQu+t3OxJcEM2iPCB8hTjcWXeBLGbAoGAEjcT
        IJN34M73iNk5gQZ64D/AP1gc1Ba85aO0y9qjPmyOl4adj2B7+YhXSjkekDPbFRwJ\nRvW50CoM9yVigQ0tzR5dbAWqtbBsFbwkWfHDtRCayzz9dJ/H3/IJ5sRkln4WKckd
        0uBJy43I5AixrE+zMGW828RlUBelHHQhT9s/PSkCgYA6kQyV5FLBLrmnV5B8bdiU\ndEF7H/YHrRMvzH3bwfgaw7CxjUcreQ2LX84fkUFtZXzR2VS5bdZKGFDmSX0QVGPq
        zmVLrxbf0kgQjEEaSHsdIutYblHJg3bSjKoyOC20TB34sps7hpBRq6joJwjWH/rz\n6XoqNBpphe8vTBZn/FSkog==
        -----END PRIVATE KEY-----
        """.utf8)
    }
}


================================================
FILE: Sources/Development/entrypoint.swift
================================================
import Vapor
import Logging

@main
struct Entrypoint {
    static func main() async throws {
        var env = try Environment.detect()
        try LoggingSystem.bootstrap(from: &env)

        let app = try await Application.make(env)
        do {
            try configure(app)
            try await app.execute()
            try await app.asyncShutdown()
        } catch {
            try? await app.asyncShutdown()
            throw error
        }
    }
}



================================================
FILE: Sources/Development/routes.swift
================================================
import class Foundation.Bundle
import Vapor
import NIOCore
import NIOHTTP1
import NIOConcurrencyHelpers
import _NIOFileSystem

struct Creds: Content {
    var email: String
    var password: String
}

public func routes(_ app: Application) throws {
    app.on(.GET, "ping") { req -> StaticString in
        return "123" as StaticString
    }


    // ( echo -e 'POST /slow-stream HTTP/1.1\r\nContent-Length: 1000000000\r\n\r\n'; dd if=/dev/zero; ) | nc localhost 8080
    app.on(.POST, "slow-stream", body: .stream) { req -> EventLoopFuture<String> in
        let done = req.eventLoop.makePromise(of: String.self)

        let totalBox = NIOLoopBoundBox(0, eventLoop: req.eventLoop)
        req.body.drain { result in
            let promise = req.eventLoop.makePromise(of: Void.self)

            switch result {
            case .buffer(let buffer):
                req.eventLoop.scheduleTask(in: .milliseconds(1000)) {
                    totalBox.value += buffer.readableBytes
                    promise.succeed(())
                }
            case .error(let error):
                done.fail(error)
            case .end:
                promise.succeed(())
                done.succeed(totalBox.value.description)
            }

            // manually return pre-completed future
            // this should balloon in memory
            // return req.eventLoop.makeSucceededFuture(())
            
            // return real future that indicates bytes were handled
            // this should use very little memory
            return promise.futureResult
        }

        return done.futureResult
    }

    app.get("test", "head") { req -> String in
        return "OK!"
    }

    app.post("test", "head") { req -> String in
        return "OK!"
    }
    
    app.post("login") { req -> String in
        let creds = try req.content.decode(Creds.self)
        return "\(creds)"
    }
    
    app.on(.POST, "large-file", body: .collect(maxSize: 1_000_000_000)) { req -> String in
        return req.body.data?.readableBytes.description  ?? "none"
    }

    app.get("json") { req -> [String: String] in
        return ["foo": "bar"]
    }.description("returns some test json")
    
    app.webSocket("ws") { req, ws in
        ws.onText { ws, text in
            ws.send(text.reversed())
            if text == "close" {
                ws.close(promise: nil)
            }
        }

        let ip = req.remoteAddress?.description ?? "<no ip>"
        ws.send("Hello 👋 \(ip)")
    }
    
    app.on(.POST, "file", body: .stream) { req -> EventLoopFuture<String> in
        let promise = req.eventLoop.makePromise(of: String.self)
        req.body.drain { result in
            switch result {
            case .buffer(let buffer):
                debugPrint(buffer)
            case .error(let error):
                promise.fail(error)
            case .end:
                promise.succeed("Done")
            }
            return req.eventLoop.makeSucceededFuture(())
        }
        return promise.futureResult
    }

    app.get("shutdown") { req -> HTTPStatus in
        guard let running = req.application.running else {
            throw Abort(.internalServerError)
        }
        running.stop()
        return .ok
    }

    let cache = MemoryCache()
    app.get("cache", "get", ":key") { req -> String in
        guard let key = req.parameters.get("key") else {
            throw Abort(.internalServerError)
        }
        return "\(key) = \(await cache.get(key) ?? "nil")"
    }
    app.get("cache", "set", ":key", ":value") { req -> String in
        guard let key = req.parameters.get("key") else {
            throw Abort(.internalServerError)
        }
        guard let value = req.parameters.get("value") else {
            throw Abort(.internalServerError)
        }
        await cache.set(key, to: value)
        return "\(key) = \(value)"
    }

    app.get("hello", ":name") { req in
        return req.parameters.get("name") ?? "<nil>"
    }

    app.get("search") { req in
        return req.query["q"] ?? "none"
    }

    let sessions = app.grouped("sessions")
        .grouped(app.sessions.middleware)
    sessions.get("set", ":value") { req -> HTTPStatus in
        req.session.data["name"] = req.parameters.get("value")
        return .ok
    }
    sessions.get("get") { req -> String in
        req.session.data["name"] ?? "n/a"
    }
    sessions.get("del") { req -> String in
        req.session.destroy()
        return "done"
    }

    app.get("client") { req in
        return req.client.get("http://httpbin.org/status/201").map { $0.description }
    }

    app.get("client-json") { req -> EventLoopFuture<String> in
        struct HTTPBinResponse: Decodable {
            struct Slideshow: Decodable {
                var title: String
            }
            var slideshow: Slideshow
        }
        return req.client.get("http://httpbin.org/json")
            .flatMapThrowing { try $0.content.decode(HTTPBinResponse.self) }
            .map { $0.slideshow.title }
    }
    
    let users = app.grouped("users")
    users.get { req in
        return "users"
    }
    users.get(":userID") { req in
        return req.parameters.get("userID") ?? "no id"
    }
    
    app.directory.viewsDirectory = "/Users/tanner/Desktop"
    app.get("view") { req in
        req.view.render("hello.txt", ["name": "world"])
    }

    app.get("error") { req -> String in
        throw TestError()
    }

    app.get("secret") { req in
        guard let secret = try await Environment.secret(path: "PASSWORD_SECRET") else {
            throw Abort(.badRequest)
        }
        return secret
    }

    app.on(.POST, "max-256", body: .collect(maxSize: 256)) { req -> HTTPStatus in
        print("in route")
        return .ok
    }

    @available(*, deprecated, message: "Testing deprecated functions")
    func deprecatedUploadHandler(_ req: Request) -> EventLoopFuture<HTTPStatus> {
        enum BodyStreamWritingToDiskError: Error {
            case streamFailure(Error)
            case fileHandleClosedFailure(Error)
            case multipleFailures([BodyStreamWritingToDiskError])
        }

        return req.application.fileio.openFile(
            path: Bundle.module.url(forResource: "Resources/fileio", withExtension: "txt")?.path ?? "",
            mode: .write,
            flags: .allowFileCreation(),
            eventLoop: req.eventLoop
        ).flatMap { fileHandle in
            let promise = req.eventLoop.makePromise(of: HTTPStatus.self)
            let fileHandleBox = NIOLoopBound(fileHandle, eventLoop: req.eventLoop)
            req.body.drain { part in
                let fileHandle = fileHandleBox.value
                switch part {
                case .buffer(let buffer):
                    return req.application.fileio.write(
                        fileHandle: fileHandle,
                        buffer: buffer,
                        eventLoop: req.eventLoop
                    )
                case .error(let drainError):
                    do {
                        try fileHandle.close()
                        promise.fail(BodyStreamWritingToDiskError.streamFailure(drainError))
                    } catch {
                        promise.fail(BodyStreamWritingToDiskError.multipleFailures([
                            .fileHandleClosedFailure(error),
                            .streamFailure(drainError)
                        ]))
                    }
                    return req.eventLoop.makeSucceededFuture(())
                case .end:
                    do {
                        try fileHandle.close()
                        promise.succeed(.ok)
                    } catch {
                        promise.fail(BodyStreamWritingToDiskError.fileHandleClosedFailure(error))
                    }
                    return req.eventLoop.makeSucceededFuture(())
                }
            }
            return promise.futureResult
        }
    }
    app.on(.POST, "upload", body: .stream) { req -> HTTPStatus in
        return try await FileSystem.shared.withFileHandle(
            forWritingAt: .init(Bundle.module.url(forResource: "Resources/fileio", withExtension: "txt")?.path ?? ""),
            options: .newFile(replaceExisting: true)) { handle in
                var writer = handle.bufferedWriter()
                for try await part in req.body {
                    try await writer.write(contentsOf: part)
                }
                return .ok
            }
    }

    let asyncRoutes = app.grouped("async").grouped(TestAsyncMiddleware(number: 1))
    asyncRoutes.get("client") { req async throws -> String in
        let response = try await req.client.get("https://www.google.com")
        guard let body = response.body else {
            throw Abort(.internalServerError)
        }
        return String(buffer: body)
    }

    asyncRoutes.get("client2") { req -> String in
        let response = try await req.client.get("https://www.google.com")
        guard let body = response.body else {
            throw Abort(.internalServerError)
        }
        return String(buffer: body)
    }
    
    asyncRoutes.get("content") { req in
        Creds(email: "name", password: "password")
    }
    
    asyncRoutes.get("content2") { req async throws -> Creds in
        return Creds(email: "name", password: "password")
    }
    
    asyncRoutes.get("contentArray") { req async throws -> [Creds] in
        let cred1 = Creds(email: "name", password: "password")
        return [cred1]
    }
    
    @Sendable
    func opaqueRouteTester(_ req: Request) async throws -> some AsyncResponseEncodable {
        "Hello World"
    }
    asyncRoutes.get("opaque", use: opaqueRouteTester)
    
    // Make sure jumping between multiple different types of middleware works
    asyncRoutes.grouped(TestAsyncMiddleware(number: 2), TestMiddleware(number: 3), TestAsyncMiddleware(number: 4), TestMiddleware(number: 5)).get("middleware") { req async throws -> String in
        return "OK"
    }
    
    let basicAuthRoutes = asyncRoutes.grouped(Test.authenticator(), Test.guardMiddleware())
    basicAuthRoutes.get("auth") { req async throws -> String in
        return try req.auth.require(Test.self).name
    }
    
    struct Test: Authenticatable {
        static func authenticator() -> AsyncAuthenticator {
            TestAuthenticator()
        }

        var name: String
    }

    struct TestAuthenticator: AsyncBasicAuthenticator {
        typealias User = Test

        func authenticate(basic: BasicAuthorization, for request: Request) async throws {
            if basic.username == "test" && basic.password == "secret" {
                let test = Test(name: "Vapor")
                request.auth.login(test)
            }
        }
    }
}

struct TestError: AbortError, DebuggableError {
    var status: HTTPResponseStatus {
        .internalServerError
    }

    var reason: String {
        "This is a test."
    }

    var source: ErrorSource?

    init(
        file: String = #fileID,
        function: String = #function,
        line: UInt = #line,
        column: UInt = #column,
        range: Range<UInt>? = nil
    ) {
        self.source = .init(
            file: file,
            function: function,
            line: line,
            column: column,
            range: range
        )
    }
}

struct TestAsyncMiddleware: AsyncMiddleware {
    let number: Int
    
    func respond(to request: Request, chainingTo next: AsyncResponder) async throws -> Response {
        request.logger.debug("In async middleware - \(number)")
        let response = try await next.respond(to: request)
        request.logger.debug("In async middleware way out - \(number)")
        return response
    }
}

struct TestMiddleware: Middleware {
    let number: Int
    
    func respond(to request: Request, chainingTo next: Responder) -> EventLoopFuture<Response> {
        request.logger.debug("In non-async middleware - \(number)")
        return next.respond(to: request).map { response in
            request.logger.debug("In non-async middleware way out - \(self.number)")
            return response
        }
    }
}


================================================
FILE: Sources/Vapor/Application.swift
================================================
import ConsoleKit
import Logging
import NIOConcurrencyHelpers
import NIOCore
import NIOPosix

/// Core type representing a Vapor application.
public final class Application: Sendable {
    public var environment: Environment {
        get {
            self._environment.withLockedValue { $0 }
        }
        set {
            self._environment.withLockedValue { $0 = newValue }
        }
    }
    
    public var storage: Storage {
        get {
            self._storage.withLockedValue { $0 }
        }
        set {
            self._storage.withLockedValue { $0 = newValue }
        }
    }
    
    public var didShutdown: Bool {
        self._didShutdown.withLockedValue { $0 }
    }
    
    public var logger: Logger {
        get {
            self._logger.withLockedValue { $0 }
        }
        set {
            self._logger.withLockedValue { $0 = newValue }
        }
    }
    
    /// If enabled, tracing propagation is automatically handled by restoring & setting `request.serviceContext` automatically across Vapor-internal EventLoopFuture boundaries.
    /// If disabled, traces will not automatically nest, and the user should restore & set `request.serviceContext` manually where needed.
    /// There are performance implications to enabling this feature.
    public var traceAutoPropagation: Bool {
        get {
            self._traceAutoPropagation.withLockedValue { $0 }
        }
        set {
            self._traceAutoPropagation.withLockedValue { $0 = newValue }
        }
    }
    
    public struct Lifecycle: Sendable {
        var handlers: [LifecycleHandler]
        init() {
            self.handlers = []
        }
        
        public mutating func use(_ handler: LifecycleHandler) {
            self.handlers.append(handler)
        }
    }
    
    public var lifecycle: Lifecycle {
        get {
            self._lifecycle.withLockedValue { $0 }
        }
        set {
            self._lifecycle.withLockedValue { $0 = newValue }
        }
    }
    
    public final class Locks: Sendable {
        public let main: NIOLock
        // Is there a type we can use to make this Sendable but reuse the existing lock we already have?
        private let storage: NIOLockedValueBox<[ObjectIdentifier: NIOLock]>
        
        init() {
            self.main = .init()
            self.storage = .init([:])
        }
        
        public func lock<Key>(for key: Key.Type) -> NIOLock
        where Key: LockKey {
            self.main.withLock {
                self.storage.withLockedValue {
                    $0.insertOrReturn(.init(), at: .init(Key.self))
                }
            }
        }
    }
    
    public var locks: Locks {
        get {
            self._locks.withLockedValue { $0 }
        }
        set {
            self._locks.withLockedValue { $0 = newValue }
        }
    }
    
    public var sync: NIOLock {
        self.locks.main
    }
    
    public enum EventLoopGroupProvider: Sendable {
        case shared(EventLoopGroup)
        @available(*, deprecated, renamed: "singleton", message: "Use '.singleton' for a shared 'EventLoopGroup', for better performance")
        case createNew
        
        public static var singleton: EventLoopGroupProvider {
            .shared(MultiThreadedEventLoopGroup.singleton)
        }
    }
    
    public let eventLoopGroupProvider: EventLoopGroupProvider
    public let eventLoopGroup: EventLoopGroup
    internal let isBooted: NIOLockedValueBox<Bool>
    private let _environment: NIOLockedValueBox<Environment>
    private let _storage: NIOLockedValueBox<Storage>
    private let _didShutdown: NIOLockedValueBox<Bool>
    private let _logger: NIOLockedValueBox<Logger>
    private let _traceAutoPropagation: NIOLockedValueBox<Bool>
    private let _lifecycle: NIOLockedValueBox<Lifecycle>
    private let _locks: NIOLockedValueBox<Locks>
    
    @available(*, noasync, message: "This initialiser cannot be used in async contexts, use Application.make(_:_:) instead")
    @available(*, deprecated, message: "Migrate to using the async APIs. Use use Application.make(_:_:) instead")
    public convenience init(
        _ environment: Environment = .development,
        _ eventLoopGroupProvider: EventLoopGroupProvider = .singleton
    ) {
        self.init(environment, eventLoopGroupProvider, async: false, logger: Logger(label: "codes.vapor.application"))
        self.asyncCommands.use(self.servers.command, as: "serve", isDefault: true)
        DotEnvFile.load(for: environment, on: .shared(self.eventLoopGroup), fileio: self.fileio, logger: self.logger)
    }
    
    // async flag here is just to stop the compiler from complaining about duplicates
    private init(_ environment: Environment = .development, _ eventLoopGroupProvider: EventLoopGroupProvider = .singleton, async: Bool, logger: Logger) {
        self._environment = .init(environment)
        self.eventLoopGroupProvider = eventLoopGroupProvider
        switch eventLoopGroupProvider {
        case .shared(let group):
            self.eventLoopGroup = group
        case .createNew:
            self.eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount)
        }
        self._locks = .init(.init())
        self._didShutdown = .init(false)
        self._logger = .init(logger)
        self._traceAutoPropagation = .init(false)
        self._storage = .init(.init(logger: logger))
        self._lifecycle = .init(.init())
        self.isBooted = .init(false)
        self.core.initialize(asyncEnvironment: async)
        self.caches.initialize()
        self.views.initialize()
        self.passwords.use(.bcrypt)
        self.sessions.initialize()
        self.sessions.use(.memory)
        self.responder.initialize()
        self.responder.use(.default)
        self.servers.initialize()
        self.servers.use(.http)
        self.clients.initialize()
        self.clients.use(.http)
        self.asyncCommands.use(RoutesCommand(), as: "routes")
    }
    
    public static func make(_ environment: Environment = .development, _ eventLoopGroupProvider: EventLoopGroupProvider = .singleton) async throws -> Application {
        try await make(environment, eventLoopGroupProvider, logger: Logger(label: "codes.vapor.application"))
    }

    public static func make(_ environment: Environment = .development, _ eventLoopGroupProvider: EventLoopGroupProvider = .singleton, logger: Logger) async throws -> Application {
        let app = Application(environment, eventLoopGroupProvider, async: true, logger: logger)
        await app.asyncCommands.use(app.servers.asyncCommand, as: "serve", isDefault: true)
        await DotEnvFile.load(for: app.environment, fileio: app.fileio, logger: app.logger)
        return app
    }

    /// Starts the ``Application`` using the ``start()`` method, then waits for any running tasks to complete.
    /// If your application is started without arguments, the default argument is used.
    ///
    /// Under normal circumstances, ``run()`` runs until a shutdown is triggered, then waits for the web server to
    /// (manually) shut down before returning.
    ///
    /// > Warning: You should probably be using ``execute()`` instead of this method.
    @available(*, noasync, message: "Use the async execute() method instead.")
    public func run() throws {
        do {
            try self.start()
            try self.running?.onStop.wait()
        } catch {
            self.logger.report(error: error)
            throw error
        }
    }
    
    /// Starts the ``Application`` asynchronous using the ``startup()`` method, then waits for any running tasks
    /// to complete. If your application is started without arguments, the default argument is used.
    ///
    /// Under normal circumstances, ``execute()`` runs until a shutdown is triggered, then wait for the web server to
    /// (manually) shut down before returning.
    public func execute() async throws {
        do {
            try await self.startup()
            try await self.running?.onStop.get()
        } catch {
            self.logger.report(error: error)
            throw error
        }
    }

    /// When called, this will execute the startup command provided through an argument. If no startup command is
    /// provided, the default is used. Under normal circumstances, this will start running Vapor's webserver.
    ///
    /// If you start Vapor through this method, you'll need to prevent your Swift Executable from closing yourself.
    /// If you want to run your ``Application`` indefinitely, or until your code shuts the application down,
    /// use ``run()`` instead.
    ///
    /// > Warning: You should probably be using ``startup()`` instead of this method.
    @available(*, noasync, message: "Use the async startup() method instead.")
    public func start() throws {
        try self.eventLoopGroup.any().makeFutureWithTask { try await self.startup() }.wait()
    }
    
    /// When called, this will asynchronously execute the startup command provided through an argument. If no startup
    /// command is provided, the default is used. Under normal circumstances, this will start running Vapor's webserver.
    ///
    /// If you start Vapor through this method, you'll need to prevent your Swift Executable from closing yourself.
    /// If you want to run your ``Application`` indefinitely, or until your code shuts the application down,
    /// use ``execute()`` instead.
    public func startup() async throws {
        try await self.asyncBoot()

        let combinedCommands = AsyncCommands(
            commands: self.asyncCommands.commands.merging(self.commands.commands) { $1 },
            defaultCommand: self.asyncCommands.defaultCommand ?? self.commands.defaultCommand,
            enableAutocomplete: self.asyncCommands.enableAutocomplete || self.commands.enableAutocomplete
        ).group()

        var context = CommandContext(console: self.console, input: self.environment.commandInput)
        context.application = self
        try await self.console.run(combinedCommands, with: context)
    }

    
    @available(*, noasync, message: "This can potentially block the thread and should not be called in an async context", renamed: "asyncBoot()")
    /// Called when the applications starts up, will trigger the lifecycle handlers
    public func boot() throws {
        try self.isBooted.withLockedValue { booted in
            guard !booted else {
                return
            }
            booted = true
            try self.lifecycle.handlers.forEach { try $0.willBoot(self) }
            try self.lifecycle.handlers.forEach { try $0.didBoot(self) }
        }
    }
    
    /// Called when the applications starts up, will trigger the lifecycle handlers. The asynchronous version of ``boot()``
    public func asyncBoot() async throws {
        /// Skip the boot process if already booted
        guard !self.isBooted.withLockedValue({
            var result = true
            swap(&$0, &result)
            return result
        }) else {
            return
        }

        for handler in self.lifecycle.handlers {
            try await handler.willBootAsync(self)
        }
        for handler in self.lifecycle.handlers {
            try await handler.didBootAsync(self)
        }
    }

    @available(*, noasync, message: "This can block the thread and should not be called in an async context", renamed: "asyncShutdown()")
    public func shutdown() {
        assert(!self.didShutdown, "Application has already shut down")
        self.logger.debug("Application shutting down")

        self.logger.trace("Shutting down providers")
        self.lifecycle.handlers.reversed().forEach { $0.shutdown(self) }
        self.lifecycle.handlers = []

        self.logger.trace("Clearing Application storage")
        self.storage.shutdown()
        self.storage.clear()

        switch self.eventLoopGroupProvider {
        case .shared:
            self.logger.trace("Running on shared EventLoopGroup. Not shutting down EventLoopGroup.")
        case .createNew:
            self.logger.trace("Shutting down EventLoopGroup")
            do {
                try self.eventLoopGroup.syncShutdownGracefully()
            } catch {
                self.logger.warning("Shutting down EventLoopGroup failed: \(error)")
            }
        }

        self._didShutdown.withLockedValue { $0 = true }
        self.logger.trace("Application shutdown complete")
    }
    
    public func asyncShutdown() async throws {
        assert(!self.didShutdown, "Application has already shut down")
        self.logger.debug("Application shutting down")

        self.logger.trace("Shutting down providers")
        for handler in self.lifecycle.handlers.reversed()  {
            await handler.shutdownAsync(self)
        }
        self.lifecycle.handlers = []

        self.logger.trace("Clearing Application storage")
        await self.storage.asyncShutdown()
        self.storage.clear()

        switch self.eventLoopGroupProvider {
        case .shared:
            self.logger.trace("Running on shared EventLoopGroup. Not shutting down EventLoopGroup.")
        case .createNew:
            self.logger.trace("Shutting down EventLoopGroup")
            do {
                try await self.eventLoopGroup.shutdownGracefully()
            } catch {
                self.logger.warning("Shutting down EventLoopGroup failed: \(error)")
            }
        }

        self._didShutdown.withLockedValue { $0 = true }
        self.logger.trace("Application shutdown complete")
    }

    deinit {
        self.logger.trace("Application deinitialized, goodbye!")
        if !self.didShutdown {
            self.logger.error("Application.shutdown() was not called before Application deinitialized.")
            self.shutdown()
        }
    }
}

public protocol LockKey {}

extension Dictionary {
    fileprivate mutating func insertOrReturn(_ value: @autoclosure () -> Value, at key: Key) -> Value {
        if let existing = self[key] {
            return existing
        }
        let newValue = value()
        self[key] = newValue
        return newValue
    }
}


================================================
FILE: Sources/Vapor/Authentication/AuthenticationCache.swift
================================================
import NIOConcurrencyHelpers

extension Request {
    /// Helper for accessing authenticated objects.
    /// See `Authenticator` for more information.
    public var auth: Authentication {
        return .init(request: self)
    }

    /// Request helper for storing and fetching authenticated objects.
    public struct Authentication {
        let request: Request
        init(request: Request) {
            self.request = request
        }
    }
}

extension Request.Authentication {
    /// Authenticates the supplied instance for this request.
    public func login<A>(_ instance: A)
        where A: Authenticatable
    {
        self.cache[A.self] = UnsafeAuthenticationBox(instance)
    }

    /// Unauthenticates an authenticatable type.
    public func logout<A>(_ type: A.Type = A.self)
        where A: Authenticatable
    {
        self.cache[A.self] = nil
    }

    /// Returns an instance of the supplied type. Throws if no
    /// instance of that type has been authenticated or if there
    /// was a problem.
    @discardableResult public func require<A>(_ type: A.Type = A.self) throws -> A
        where A: Authenticatable
    {
        guard let a = self.get(A.self) else {
            throw Abort(.unauthorized)
        }
        return a
    }

    /// Returns the authenticated instance of the supplied type.
    /// - note: `nil` if no type has been authed.
    public func get<A>(_ type: A.Type = A.self) -> A?
        where A: Authenticatable
    {
        return self.cache[A.self]?.authenticated
    }

    /// Returns `true` if the type has been authenticated.
    public func has<A>(_ type: A.Type = A.self) -> Bool
        where A: Authenticatable
    {
        return self.get(A.self) != nil
    }

    private final class Cache: Sendable {
        private let storage: NIOLockedValueBox<[ObjectIdentifier: Sendable]>

        init() {
            self.storage = .init([:])
        }

        internal subscript<A>(_ type: A.Type) -> UnsafeAuthenticationBox<A>?
            where A: Authenticatable
            {
            get { 
                storage.withLockedValue { $0[ObjectIdentifier(A.self)] as? UnsafeAuthenticationBox<A> }
            }
            set { 
                storage.withLockedValue { $0[ObjectIdentifier(A.self)] = newValue }
            }
        }
    }

    private struct CacheKey: StorageKey {
        typealias Value = Cache
    }

    private var cache: Cache {
        get {
            if let existing = self.request.storage[CacheKey.self] {
                return existing
            } else {
                let new = Cache()
                self.request.storage[CacheKey.self] = new
                return new
            }
        }
        set {
            self.request.storage[CacheKey.self] = newValue
        }
    }
}

// This is to get around the fact that for legacy reasons we can't enforce Sendability on Authenticatable
// types (e.g. Fluent 4 models can never be Sendable because they're reference types with mutable values
// required by protocols and property wrappers). This allows us to store the Authenticatable type in a
// safe-most-of-the-time way. This does introduce an edge case where type could be stored and mutated in
// multiple places. But given how Vapor and its users use Authentication this should almost never
// occur and it was decided the trade-off was acceptable
// As the name implies, the usage of this is unsafe because it disables the sendable checking of the
// compiler and does not add any synchronization.
@usableFromInline
internal struct UnsafeAuthenticationBox<A>: @unchecked Sendable {
    @usableFromInline
    let authenticated: A
    
    @inlinable
    init(_ authenticated: A) {
        self.authenticated = authenticated
    }
}


================================================
FILE: Sources/Vapor/Authentication/Authenticator.swift
================================================
import NIOCore

/// Capable of being authenticated.
public protocol Authenticatable { }

/// Helper for creating authentication middleware.
///
/// See `RequestAuthenticator` and `SessionAuthenticator` for more information.
public protocol Authenticator: Middleware { }

/// Help for creating authentication middleware based on `Request`.
///
/// `Authenticator`'s use the incoming request to check for authentication information.
/// If valid authentication credentials are present, the authenticated user is added to `req.auth`.
public protocol RequestAuthenticator: Authenticator {
    func authenticate(request: Request) -> EventLoopFuture<Void>
}

extension RequestAuthenticator {
    public func respond(to request: Request, chainingTo next: Responder) -> EventLoopFuture<Response> {
        return self.authenticate(request: request).flatMap {
            next.respond(to: request)
        }
    }
}

// MARK: Basic

/// Helper for creating authentication middleware using the Basic authorization header.
public protocol BasicAuthenticator: RequestAuthenticator {
    func authenticate(basic: BasicAuthorization, for request: Request) -> EventLoopFuture<Void>
}

extension BasicAuthenticator {
    public func authenticate(request: Request) -> EventLoopFuture<Void> {
        guard let basicAuthorization = request.headers.basicAuthorization else {
            return request.eventLoop.makeSucceededFuture(())
        }
        return self.authenticate(basic: basicAuthorization, for: request)
    }
}

// MARK: Bearer

/// Helper for creating authentication middleware using the Bearer authorization header.
public protocol BearerAuthenticator: RequestAuthenticator {
    func authenticate(bearer: BearerAuthorization, for request: Request) -> EventLoopFuture<Void>
}

extension BearerAuthenticator {
    public func authenticate(request: Request) -> EventLoopFuture<Void> {
        guard let bearerAuthorization = request.headers.bearerAuthorization else {
            return request.eventLoop.makeSucceededFuture(())
        }
        return self.authenticate(bearer: bearerAuthorization, for: request)
    }
}

// MARK: Credentials

/// Helper for creating authentication middleware using request body contents.
public protocol CredentialsAuthenticator: RequestAuthenticator {
    associatedtype Credentials: Content
    func authenticate(credentials: Credentials, for request: Request) -> EventLoopFuture<Void>
}

extension CredentialsAuthenticator {
    public func authenticate(request: Request) -> EventLoopFuture<Void> {
        return request.body.collect(max: nil).flatMap { _ -> EventLoopFuture<Void> in
            let credentials: Credentials
            do {
                credentials = try request.content.decode(Credentials.self)
            } catch {
                return request.eventLoop.makeSucceededFuture(())
            }
            return self.authenticate(credentials: credentials, for: request)
        }
    }
}


================================================
FILE: Sources/Vapor/Authentication/BasicAuthorization.swift
================================================
import Foundation
import NIOHTTP1

/// A basic username and password.
public struct BasicAuthorization: Sendable {
    /// The username, sometimes an email address
    public let username: String

    /// The plaintext password
    public let password: String

    /// Create a new `BasicAuthorization`.
    public init(username: String, password: String) {
        self.username = username
        self.password = password
    }
}

extension HTTPHeaders {
    /// Access or set the `Authorization: Basic: ...` header.
    public var basicAuthorization: BasicAuthorization? {
        get {
            guard let string = self.first(name: .authorization) else {
                return nil
            }

            let headerParts = string.split(separator: " ")
            guard headerParts.count == 2 else {
                return nil
            }
            guard headerParts[0].lowercased() == "basic" else {
                return nil
            }
            guard let decodedToken = Data(base64Encoded: .init(headerParts[1])) else {
                return nil
            }
            let parts = String.init(decoding: decodedToken, as: UTF8.self).split(separator: ":", maxSplits: 1, omittingEmptySubsequences: false)

            guard parts.count == 2 else {
                return nil
            }

            return .init(username: .init(parts[0]), password: .init(parts[1]))
        }
        set {
            if let basic = newValue {
                let credentials = "\(basic.username):\(basic.password)"
                let encoded = Data(credentials.utf8).base64EncodedString()
                replaceOrAdd(name: .authorization, value: "Basic \(encoded)")
            } else {
                remove(name: .authorization)
            }
        }
    }
}


================================================
FILE: Sources/Vapor/Authentication/BearerAuthorization.swift
================================================
import NIOHTTP1

/// A bearer token.
public struct BearerAuthorization: Sendable {
    /// The plaintext token
    public let token: String

    /// Create a new `BearerAuthorization`
    public init(token: String) {
        self.token = token
    }
}

extension HTTPHeaders {
    /// Access or set the `Authorization: Bearer: ...` header.
    public var bearerAuthorization: BearerAuthorization? {
        get {
            guard let string = self.first(name: .authorization) else {
                return nil
            }

            let headerParts = string.split(separator: " ")
            guard headerParts.count == 2 else {
                return nil
            }
            guard headerParts[0].lowercased() == "bearer" else {
                return nil
            }
            return .init(token: String(headerParts[1]))
        }
        set {
            if let bearer = newValue {
                replaceOrAdd(name: .authorization, value: "Bearer \(bearer.token)")
            } else {
                remove(name: .authorization)
            }
        }
    }
}


================================================
FILE: Sources/Vapor/Authentication/GuardMiddleware.swift
================================================
import NIOCore

extension Authenticatable {
    /// This middleware ensures that an `Authenticatable` type `A` has been authenticated
    /// by a previous `Middleware` or throws an `Error`. The middlewares that actually perform
    /// authentication will _not_ throw errors if they fail to authenticate the user (except in
    /// some exceptional cases like malformed data). This allows the middlewares to be composed
    /// together to create chains of authentication for multiple user types.
    ///
    /// Use this middleware to protect routes that might not otherwise attempt to access the
    /// authenticated user (which always requires prior authentication).
    ///
    /// Use `Authenticatable.guardMiddleware(...)` to create an instance.
    ///
    /// Use this middleware in conjunction with other middleware such as `BearerAuthenticator`
    /// and `BasicAuthenticator` to do the actual authentication.
    ///
    /// - parameters:
    ///     - throwing: `Error` to throw if the type is not authed.
    public static func guardMiddleware(
        throwing error: Error = Abort(.unauthorized, reason: "\(Self.self) not authenticated.")
    ) -> Middleware {
        return GuardAuthenticationMiddleware<Self>(throwing: error)
    }
}



private final class GuardAuthenticationMiddleware<A>: Middleware
    where A: Authenticatable
{
    /// Error to throw when guard fails.
    private let error: Error

    /// Creates a new `GuardAuthenticationMiddleware`.
    ///
    /// - parameters:
    ///     - type: `Authenticatable` type to ensure is authed.
    ///     - error: `Error` to throw if the type is not authed.
    internal init(_ type: A.Type = A.self, throwing error: Error) {
        self.error = error
    }

    public func respond(to request: Request, chainingTo next: Responder) -> EventLoopFuture<Response> {
        guard request.auth.has(A.self) else {
            return request.eventLoop.makeFailedFuture(self.error)
        }
        return next.respond(to: request)
    }
}


================================================
FILE: Sources/Vapor/Authentication/RedirectMiddleware.swift
================================================
import NIOCore

extension Authenticatable {
    /// Basic middleware to redirect unauthenticated requests to the supplied path
    ///
    /// - parameters:
    ///    - path: The path to redirect to if the request is not authenticated
    public static func redirectMiddleware(path: String) -> Middleware {
        self.redirectMiddleware(makePath: { _ in path })
    }
    
    /// Basic middleware to redirect unauthenticated requests to the supplied path
    ///
    /// - parameters:
    ///    - makePath: The closure that returns the redirect path based on the given `Request` object
    @preconcurrency public static func redirectMiddleware(makePath: @Sendable @escaping (Request) -> String) -> Middleware {
        RedirectMiddleware<Self>(Self.self, makePath: makePath)
    }
}


private final class RedirectMiddleware<A>: Middleware
    where A: Authenticatable
{
    let makePath: @Sendable (Request) -> String
    
    @preconcurrency init(_ authenticatableType: A.Type = A.self, makePath: @Sendable @escaping (Request) -> String) {
        self.makePath = makePath
    }

    func respond(to request: Request, chainingTo next: Responder) -> EventLoopFuture<Response> {
        if request.auth.has(A.self) {
            return next.respond(to: request)
        }

        let redirect = request.redirect(to: self.makePath(request))
        return request.eventLoop.makeSucceededFuture(redirect)
    }
}


================================================
FILE: Sources/Vapor/Authentication/SessionAuthenticatable.swift
================================================
import NIOCore

/// Helper for creating authentication middleware in conjunction with `SessionsMiddleware`.
public protocol SessionAuthenticator: Authenticator {
    associatedtype User: SessionAuthenticatable

    /// Authenticate a model with the supplied ID.
    func authenticate(sessionID: User.SessionID, for request: Request) -> EventLoopFuture<Void>
}

extension SessionAuthenticator {
    public func respond(to request: Request, chainingTo next: Responder) -> EventLoopFuture<Response> {
        // if the user has already been authenticated
        // by a previous middleware, continue
        if request.auth.has(User.self) {
            return next.respond(to: request)
        }

        let future: EventLoopFuture<Void>
        if request.hasSession, let aID = request.session.authenticated(User.self) {
            // try to find user with id from session
            future = self.authenticate(sessionID: aID, for: request)
        } else {
            // no need to authenticate
            future = request.eventLoop.makeSucceededFuture(())
        }

        // map the auth future to a response
        return future.flatMap { _ in
            // respond to the request
            return next.respond(to: request).map { response in
                if let user = request.auth.get(User.self) {
                    // if a user has been authed (or is still authed), store in the session
                    request.session.authenticate(user)
                } else if request.hasSession {
                    // if no user is authed, it's possible they've been unauthed.
                    // remove from session.
                    request.session.unauthenticate(User.self)
                }
                return response
            }
        }
    }
}

/// Models conforming to this protocol can have their authentication
/// status cached using `SessionAuthenticator`.
public protocol SessionAuthenticatable: Authenticatable {
    /// Session identifier type.
    associatedtype SessionID: LosslessStringConvertible

    /// Unique session identifier.
    var sessionID: SessionID { get }
}

private extension SessionAuthenticatable {
    static var sessionName: String {
        return "\(Self.self)"
    }
}

extension Session {
    /// Authenticates the model into the session.
    public func authenticate<A>(_ a: A)
        where A: SessionAuthenticatable
    {
        self.data["_" + A.sessionName + "Session"] = a.sessionID.description
    }

    /// Un-authenticates the model from the session.
    public func unauthenticate<A>(_ a: A.Type)
        where A: SessionAuthenticatable
    {
        self.data["_" + A.sessionName + "Session"] = nil
    }

    /// Returns the authenticatable type's ID if it exists
    /// in the session data.
    public func authenticated<A>(_ a: A.Type) -> A.SessionID?
        where A: SessionAuthenticatable
    {
        self.data["_" + A.sessionName + "Session"]
            .flatMap { A.SessionID.init($0) }
    }
}


================================================
FILE: Sources/Vapor/Bcrypt/Bcrypt.swift
================================================
import Foundation
import CVaporBcrypt

// MARK: BCrypt

/// Creates and verifies BCrypt hashes.
///
/// Use BCrypt to create hashes for sensitive information like passwords.
///
///     try BCrypt.hash("vapor", cost: 4)
///
/// BCrypt uses a random salt each time it creates a hash. To verify hashes, use the `verify(_:matches)` method.
///
///     let hash = try BCrypt.hash("vapor", cost: 4)
///     try BCrypt.verify("vapor", created: hash) // true
///
/// https://en.wikipedia.org/wiki/Bcrypt
public var Bcrypt: BCryptDigest {
    return .init()
}


/// Creates and verifies BCrypt hashes. Normally you will not need to initialize one of these classes and you will
/// use the global `BCrypt` convenience instead.
///
///     try BCrypt.hash("vapor", cost: 4)
///
/// See `BCrypt` for more information.
public final class BCryptDigest {
    /// Creates a new `BCryptDigest`. Use the global `BCrypt` convenience variable.
    public init() { }

    /// Creates a new BCrypt hash with a randomly generated salt.
    /// The result can be stored in a database.
    public func hash(_ plaintext: String, cost: Int = 12) throws -> String {
        guard cost >= BCRYPT_MINLOGROUNDS && cost <= 31 else {
            throw BcryptError.invalidCost
        }
        return try self.hash(plaintext, salt: self.generateSalt(cost: cost))
    }

    public func hash(_ plaintext: String, salt: String) throws -> String {
        guard isSaltValid(salt) else {
            throw BcryptError.invalidSalt
        }

        let originalAlgorithm: Algorithm
        if salt.count == Algorithm.saltCount {
            // user provided salt
            originalAlgorithm = ._2b
        } else {
            // full salt, not user provided
            let revisionString = String(salt.prefix(4))
            if let parsedRevision = Algorithm(rawValue: revisionString) {
                originalAlgorithm = parsedRevision
            } else {
                throw BcryptError.invalidSalt
            }
        }

        // OpenBSD doesn't support 2y revision.
        let normalizedSalt: String
        if originalAlgorithm == Algorithm._2y {
            // Replace with 2b.
            normalizedSalt = Algorithm._2b.rawValue + salt.dropFirst(originalAlgorithm.revisionCount)
        } else {
            normalizedSalt = salt
        }

        let hashedBytes = UnsafeMutablePointer<Int8>.allocate(capacity: 128)
        defer { hashedBytes.deallocate() }
        let hashingResult = vapor_bcrypt_hashpass(
            plaintext,
            normalizedSalt,
            hashedBytes,
            128
        )

        guard hashingResult == 0 else {
            throw BcryptError.hashFailure
        }
        return originalAlgorithm.rawValue
            + String(cString: hashedBytes)
                .dropFirst(originalAlgorithm.revisionCount)
    }

    /// Verifies an existing BCrypt hash matches the supplied plaintext value. Verification works by parsing the salt and version from
    /// the existing digest and using that information to hash the plaintext data. If hash digests match, this method returns `true`.
    ///
    ///     let hash = try BCrypt.hash("vapor", cost: 4)
    ///     try BCrypt.verify("vapor", created: hash) // true
    ///     try BCrypt.verify("foo", created: hash) // false
    ///
    /// - parameters:
    ///     - plaintext: Plaintext data to digest and verify.
    ///     - hash: Existing BCrypt hash to parse version, salt, and existing digest from.
    /// - throws: `CryptoError` if hashing fails or if data conversion fails.
    /// - returns: `true` if the hash was created from the supplied plaintext data.
    public func verify(_ plaintext: String, created hash: String) throws -> Bool {
        guard let hashVersion = Algorithm(rawValue: String(hash.prefix(4))) else {
            throw BcryptError.invalidHash
        }

        let hashSalt = String(hash.prefix(hashVersion.fullSaltCount))
        guard !hashSalt.isEmpty, hashSalt.count == hashVersion.fullSaltCount else {
            throw BcryptError.invalidHash
        }

        let hashChecksum = String(hash.suffix(hashVersion.checksumCount))
        guard !hashChecksum.isEmpty, hashChecksum.count == hashVersion.checksumCount else {
            throw BcryptError.invalidHash
        }

        let messageHash = try self.hash(plaintext, salt: hashSalt)
        let messageHashChecksum = String(messageHash.suffix(hashVersion.checksumCount))
        return messageHashChecksum.secureCompare(to: hashChecksum)
    }

    // MARK: Private

    /// Generates string (29 chars total) containing the algorithm information + the cost + base-64 encoded 22 character salt
    ///
    ///     E.g:  $2b$05$J/dtt5ybYUTCJ/dtt5ybYO
    ///           $AA$ => Algorithm
    ///              $CC$ => Cost
    ///                  SSSSSSSSSSSSSSSSSSSSSS => Salt
    ///
    /// Allowed charset for the salt: [./A-Za-z0-9]
    ///
    /// - parameters:
    ///     - cost: Desired complexity. Larger `cost` values take longer to hash and verify.
    ///     - algorithm: Revision to use (2b by default)
    ///     - seed: Salt (without revision data). Generated if not provided. Must be 16 chars long.
    /// - returns: Complete salt
    private func generateSalt(cost: Int, algorithm: Algorithm = ._2b, seed: [UInt8]? = nil) -> String {
        let randomData: [UInt8]
        if let seed = seed {
            randomData = seed
        } else {
            randomData = [UInt8].random(count: 16)
        }
        let encodedSalt = base64Encode(randomData)

        return
            algorithm.rawValue +
            (cost < 10 ? "0\(cost)" : "\(cost)" ) + // 0 padded
            "$" +
            encodedSalt
    }

    /// Checks whether the provided salt is valid or not
    ///
    /// - parameters:
    ///     - salt: Salt to be checked
    /// - returns: True if the provided salt is valid
    private func isSaltValid(_ salt: String) -> Bool {
        // Includes revision and cost info (count should be 29)
        let revisionString = String(salt.prefix(4))
        if let algorithm = Algorithm(rawValue: revisionString) {
            return salt.count == algorithm.fullSaltCount
        } else {
            // Does not include revision and cost info (count should be 22)
            return salt.count == Algorithm.saltCount
        }
    }

    /// Encodes the provided plaintext using OpenBSD's custom base-64 encoding (Radix-64)
    ///
    /// - parameters:
    ///     - data: Data to be base64 encoded.
    /// - returns: Base 64 encoded plaintext
    private func base64Encode(_ data: [UInt8]) -> String {
        let encodedBytes = UnsafeMutablePointer<Int8>.allocate(capacity: 25)
        defer { encodedBytes.deallocate() }
        let res = data.withUnsafeBytes { bytes in
            vapor_encode_base64(encodedBytes, bytes.baseAddress?.assumingMemoryBound(to: UInt8.self), bytes.count)
        }
        assert(res == 0, "base64 convert failed")
        return String(cString: encodedBytes)
    }

    /// Specific BCrypt algorithm.
    private enum Algorithm: String, RawRepresentable {
        /// older version
        case _2a = "$2a$"
        /// format specific to the crypt_blowfish BCrypt implementation, identical to `2b` in all but name.
        case _2y = "$2y$"
        /// latest revision of the official BCrypt algorithm, current default
        case _2b = "$2b$"

        /// Revision's length, including the `$` symbols
        var revisionCount: Int {
            return 4
        }

        /// Salt's length (includes revision and cost info)
        var fullSaltCount: Int {
            return 29
        }

        /// Checksum's length
        var checksumCount: Int {
            return 31
        }

        /// Salt's length (does NOT include neither revision nor cost info)
        static var saltCount: Int {
            return 22
        }
    }
}

public enum BcryptError: Swift.Error, CustomStringConvertible, LocalizedError {
    case invalidCost
    case invalidSalt
    case hashFailure
    case invalidHash

    public var errorDescription: String? {
        return self.description
    }

    public var description: String {
        return "Bcrypt error: \(self.reason)"
    }

    var reason: String {
        switch self {
        case .invalidCost:
            return "Cost should be between 4 and 31"
        case .invalidSalt:
            return "Provided salt has the incorrect format"
        case .hashFailure:
            return "Unable to compute hash"
        case .invalidHash:
            return "Invalid hash formatting"
        }
    }
}


================================================
FILE: Sources/Vapor/Cache/Application+Cache.swift
================================================
import NIOConcurrencyHelpers

extension Application {
    /// Controls application's configured caches.
    ///
    ///     app.caches.use(.memory)
    ///
    public var caches: Caches {
        .init(application: self)
    }

    /// Current application cache. See `Request.cache` for caching in request handlers.
    public var cache: Cache {
        guard let makeCache = self.caches.storage.makeCache.withLockedValue({ $0.factory }) else {
            fatalError("No cache configured. Configure with app.caches.use(...)")
        }
        return makeCache(self)
    }

    public struct Caches: Sendable {
        public struct Provider: Sendable {
            let run: @Sendable (Application) -> ()

            @preconcurrency public init(_ run: @Sendable @escaping (Application) -> ()) {
                self.run = run
            }
        }
        
        final class Storage: Sendable {
            struct CacheFactory {
                let factory: (@Sendable (Application) -> Cache)?
            }
            let makeCache: NIOLockedValueBox<CacheFactory>
            init() {
                self.makeCache = .init(.init(factory: nil))
            }
        }

        struct Key: StorageKey, Sendable {
            typealias Value = Storage
        }

        public let application: Application

        public func use(_ provider: Provider) {
            provider.run(self.application)
        }

        @preconcurrency public func use(_ makeCache: @Sendable @escaping (Application) -> (Cache)) {
            self.storage.makeCache.withLockedValue { $0 = .init(factory: makeCache) }
        }

        func initialize() {
            self.application.storage[Key.self] = .init()
            self.use(.memory)
        }

        var storage: Storage {
            guard let storage = self.application.storage[Key.self] else {
                fatalError("Caches not configured. Configure with app.caches.initialize()")
            }
            return storage
        }
    }
}


================================================
FILE: Sources/Vapor/Cache/Cache.swift
================================================
import NIOCore
/// Codable key-value pair cache.
public protocol Cache {
    /// Gets a decodable value from the cache. Returns `nil` if not found.
    func get<T>(_ key: String, as type: T.Type) -> EventLoopFuture<T?>
        where T: Decodable
    
    /// Sets an encodable value into the cache. Existing values are replaced. If `nil`, removes value.
    func set<T>(_ key: String, to value: T?) -> EventLoopFuture<Void>
        where T: Encodable
    
    /// Sets an encodable value into the cache with an expiry time. Existing values are replaced. If `nil`, removes value.
    func set<T>(_ key: String, to value: T?, expiresIn expirationTime: CacheExpirationTime?) -> EventLoopFuture<Void>
        where T: Encodable
        
    /// Creates a request-specific cache instance.
    func `for`(_ request: Request) -> Self
}

extension Cache {
    /// Sets an encodable value into the cache with an expiry time. Existing values are replaced. If `nil`, removes value.
    public func set<T>(_ key: String, to value: T?, expiresIn expirationTime: CacheExpirationTime?) -> EventLoopFuture<Void>
        where T: Encodable
    {
        return self.set(key, to: value)
    }
    
    public func delete(_ key: String) -> EventLoopFuture<Void>
    {
        return self.set(key, to: String?.none)
    }
    
    /// Gets a decodable value from the cache. Returns `nil` if not found.
    public func get<T>(_ key: String) -> EventLoopFuture<T?>
        where T: Decodable
    {
        return self.get(key, as: T.self)
    }
}


================================================
FILE: Sources/Vapor/Cache/CacheExpirationTime.swift
================================================
/// Defines the lifetime of an entry in a cache.
public enum CacheExpirationTime: Sendable {
    case seconds(Int)
    case minutes(Int)
    case hours(Int)
    case days(Int)
    
    /// Returns the amount of time in seconds.
    public var seconds: Int {
        switch self {
        case let .seconds(seconds):
            return seconds
        case let .minutes(minutes):
            return minutes * 60
        case let .hours(hours):
            return hours * 60 * 60
        case let .days(days):
            return days * 24 * 60 * 60
        }
    }
}


================================================
FILE: Sources/Vapor/Cache/MemoryCache.swift
================================================
import Foundation
import NIOCore
import NIOConcurrencyHelpers

extension Application.Caches {
    /// In-memory cache. Thread safe.
    /// Not shared between multiple instances of your application.
    public var memory: Cache {
        MemoryCache(storage: self.memoryStorage, on: self.application.eventLoopGroup.next())
    }

    private var memoryStorage: MemoryCacheStorage {
        let lock = self.application.locks.lock(for: MemoryCacheKey.self)
        lock.lock()
        defer { lock.unlock() }
        if let existing = self.application.storage.get(MemoryCacheKey.self) {
            return existing
        } else {
            let new = MemoryCacheStorage()
            self.application.storage.set(MemoryCacheKey.self, to: new)
            return new
        }
    }
}

extension Application.Caches.Provider {
    /// In-memory cache. Thread safe.
    /// Not shared between multiple instances of your application.
    public static var memory: Self {
        .init {
            $0.caches.use { $0.caches.memory }
        }
    }
}

private struct MemoryCacheKey: LockKey, StorageKey {
    typealias Value = MemoryCacheStorage
}

private actor MemoryCacheStorage: Sendable {
    struct CacheEntryBox<T> {
        var expiresAt: Date?
        var value: T
        
        init(_ value: T) {
            self.expiresAt = nil
            self.value = value
        }
    }
    
    private var storage: [String: Any]
    private var lock: NIOLock
    
    init() {
        self.storage = [:]
        self.lock = .init()
    }
    
    func get<T>(_ key: String) -> T?
        where T: Decodable
    {
        self.lock.lock()
        defer { self.lock.unlock() }
        
        guard let box = self.storage[key] as? CacheEntryBox<T> else { return nil }
        if let expiresAt = box.expiresAt, expiresAt < Date() {
            self.storage.removeValue(forKey: key)
            return nil
        }
        
        return box.value
    }
    
    func set<T>(_ key: String, to value: T?, expiresIn expirationTime: CacheExpirationTime?)
        where T: Encodable
    {
        self.lock.lock()
        defer { self.lock.unlock() }
        if let value = value {
            var box = CacheEntryBox(value)
            if let expirationTime = expirationTime {
                box.expiresAt = Date().addingTimeInterval(TimeInterval(expirationTime.seconds))
            }
            self.storage[key] = box
        } else {
            self.storage.removeValue(forKey: key)
        }
    }
}

private struct MemoryCache: Cache {
    let storage: MemoryCacheStorage
    let eventLoop: EventLoop
    
    init(storage: MemoryCacheStorage, on eventLoop: EventLoop) {
        self.storage = storage
        self.eventLoop = eventLoop
    }
    
    func get<T>(_ key: String, as type: T.Type) -> EventLoopFuture<T?>
        where T: Decodable & Sendable
    {
        self.eventLoop.makeFutureWithTask {
            await self.storage.get(key)
        }
    }
    
    func set<T>(_ key: String, to value: T?) -> EventLoopFuture<Void>
        where T: Encodable & Sendable
    {
        self.set(key, to: value, expiresIn: nil)
    }
    
    func set<T>(_ key: String, to value: T?, expiresIn expirationTime: CacheExpirationTime?) -> EventLoopFuture<Void>
        where T: Encodable & Sendable
    {
        self.eventLoop.makeFutureWithTask {
            await self.storage.set(key, to: value, expiresIn: expirationTime)
        }
    }
    
    func `for`(_ request: Request) -> MemoryCache {
        .init(storage: self.storage, on: request.eventLoop)
    }
}


================================================
FILE: Sources/Vapor/Cache/Request+Cache.swift
================================================
extension Request {
    public var cache: Cache {
        self.application.cache.for(self)
    }
}


================================================
FILE: Sources/Vapor/Client/Application+Clients.swift
================================================
import NIOConcurrencyHelpers

extension Application {
    public var clients: Clients {
        .init(application: self)
    }
    
    public var client: Client {
        guard let makeClient = self.clients.storage.makeClient.withLockedValue({ $0.factory }) else {
            fatalError("No client configured. Configure with app.clients.use(...)")
        }
        return makeClient(self)
    }

    public struct Clients: Sendable {
        public struct Provider {
            let run: @Sendable (Application) -> ()

            @preconcurrency public init(_ run: @Sendable @escaping (Application) -> ()) {
                self.run = run
            }
        }
        
        final class Storage: Sendable {
            struct ClientFactory {
                let factory: (@Sendable (Application) -> Client)?
            }
            let makeClient: NIOLockedValueBox<ClientFactory>
            init() {
                self.makeClient = .init(.init(factory: nil))
            }
        }
        
        struct Key: StorageKey, Sendable {
            typealias Value = Storage
        }

        func initialize() {
            self.application.storage[Key.self] = .init()
        }
        
        public func use(_ provider: Provider) {
            provider.run(self.application)
        }

        @preconcurrency public func use(_ makeClient: @Sendable @escaping (Application) -> (Client)) {
            self.storage.makeClient.withLockedValue { $0 = .init(factory: makeClient) }
        }

        public let application: Application
        
        var storage: Storage {
            guard let storage = self.application.storage[Key.self] else {
                fatalError("Clients not initialized. Initialize with app.clients.initialize()")
            }
            return storage
        }
    }
}


================================================
FILE: Sources/Vapor/Client/Client.swift
================================================
import NIOCore
import Logging
import NIOHTTP1

public protocol Client: Sendable {
    var eventLoop: EventLoop { get }
    var byteBufferAllocator: ByteBufferAllocator { get }
    func delegating(to eventLoop: EventLoop) -> Client
    func logging(to logger: Logger) -> Client
    func allocating(to byteBufferAllocator: ByteBufferAllocator) -> Client
    func send(_ request: ClientRequest) -> EventLoopFuture<ClientResponse>
}

extension Client {
    public func logging(to logger: Logger) -> Client {
        return self
    }

    public func allocating(to byteBufferAllocator: ByteBufferAllocator) -> Client {
        return self
    }

    public var byteBufferAllocator: ByteBufferAllocator {
        return ByteBufferAllocator()
    }
}

extension Client {
    public func get(_ url: URI, headers: HTTPHeaders = [:], beforeSend: (inout ClientRequest) throws -> () = { _ in }) -> EventLoopFuture<ClientResponse> {
        return self.send(.GET, headers: headers, to: url, beforeSend: beforeSend)
    }

    public func post(_ url: URI, headers: HTTPHeaders = [:], beforeSend: (inout ClientRequest) throws -> () = { _ in }) -> EventLoopFuture<ClientResponse> {
        return self.send(.POST, headers: headers, to: url, beforeSend: beforeSend)
    }

    public func patch(_ url: URI, headers: HTTPHeaders = [:], beforeSend: (inout ClientRequest) throws -> () = { _ in }) -> EventLoopFuture<ClientResponse> {
        return self.send(.PATCH, headers: headers, to: url, beforeSend: beforeSend)
    }

    public func put(_ url: URI, headers: HTTPHeaders = [:], beforeSend: (inout ClientRequest) throws -> () = { _ in }) -> EventLoopFuture<ClientResponse> {
        return self.send(.PUT, headers: headers, to: url, beforeSend: beforeSend)
    }

    public func delete(_ url: URI, headers: HTTPHeaders = [:], beforeSend: (inout ClientRequest) throws -> () = { _ in }) -> EventLoopFuture<ClientResponse> {
        return self.send(.DELETE, headers: headers, to: url, beforeSend: beforeSend)
    }
    
    public func post<T>(_ url: URI, headers: HTTPHeaders = [:], content: T) -> EventLoopFuture<ClientResponse> where T: Content {
        return self.post(url, headers: headers, beforeSend: { try $0.content.encode(content) })
    }

    public func patch<T>(_ url: URI, headers: HTTPHeaders = [:], content: T) -> EventLoopFuture<ClientResponse> where T: Content {
        return self.patch(url, headers: headers, beforeSend: { try $0.content.encode(content) })
    }

    public func put<T>(_ url: URI, headers: HTTPHeaders = [:], content: T) -> EventLoopFuture<ClientResponse> where T: Content {
        return self.put(url, headers: headers, beforeSend: { try $0.content.encode(content) })
    }

    public func send(
        _ method: HTTPMethod,
        headers: HTTPHeaders = [:],
        to url: URI,
        beforeSend: (inout ClientRequest) throws -> () = { _ in }
    ) -> EventLoopFuture<ClientResponse> {
        var request = ClientRequest(method: method, url: url, headers: headers, body: nil, byteBufferAllocator: self.byteBufferAllocator)
        do {
            try beforeSend(&request)
        } catch {
            return self.eventLoop.makeFailedFuture(error)
        }
        return self.send(request)
    }
}


================================================
FILE: Sources/Vapor/Client/ClientRequest.swift
================================================
import NIOCore
import NIOHTTP1
import Foundation

public struct ClientRequest: Sendable {
    public var method: HTTPMethod
    public var url: URI
    public var headers: HTTPHeaders
    public var body: ByteBuffer?
    public var timeout: TimeAmount?
    private let byteBufferAllocator: ByteBufferAllocator

    public init(
        method: HTTPMethod = .GET,
        url: URI = "/",
        headers: HTTPHeaders = [:],
        body: ByteBuffer? = nil,
        timeout: TimeAmount?,
        byteBufferAllocator: ByteBufferAllocator = ByteBufferAllocator()
    ) {
        self.method = method
        self.url = url
        self.headers = headers
        self.body = body
        self.timeout = timeout
        self.byteBufferAllocator = byteBufferAllocator
    }

    public init(
        method: HTTPMethod = .GET,
        url: URI = "/",
        headers: HTTPHeaders = [:],
        body: ByteBuffer? = nil,
        byteBufferAllocator: ByteBufferAllocator = ByteBufferAllocator()
    ) {
        self.init(method: method,
                  url: url,
                  headers: headers,
                  body: body,
                  timeout: nil,
                  byteBufferAllocator: byteBufferAllocator)
    }
}

extension ClientRequest {
    private struct _URLQueryContainer: URLQueryContainer {
        var url: URI

        func decode<D>(_ decodable: D.Type, using decoder: URLQueryDecoder) throws -> D
            where D: Decodable
        {
            return try decoder.decode(D.self, from: self.url)
        }

        mutating func encode<E>(_ encodable: E, using encoder: URLQueryEncoder) throws
            where E: Encodable
        {
            try encoder.encode(encodable, to: &self.url)
        }
    }

    public var query: URLQueryContainer {
        get {
            return _URLQueryContainer(url: self.url)
        }
        set {
            self.url = (newValue as! _URLQueryContainer).url
        }
    }

    private struct _ContentContainer: ContentContainer {
        var body: ByteBuffer?
        var headers: HTTPHeaders
        let byteBufferAllocator: ByteBufferAllocator

        var contentType: HTTPMediaType? {
            return self.headers.contentType
        }

        mutating func encode<E>(_ encodable: E, using encoder: ContentEncoder) throws where E : Encodable {
            var body = self.byteBufferAllocator.buffer(capacity: 0)
            try encoder.encode(encodable, to: &body, headers: &self.headers)
            self.body = body
        }

        func decode<D>(_ decodable: D.Type, using decoder: ContentDecoder) throws -> D where D : Decodable {
            guard let body = self.body else {
                throw Abort(.lengthRequired)
            }
            return try decoder.decode(D.self, from: body, headers: self.headers)
        }

        mutating func encode<C>(_ content: C, using encoder: ContentEncoder) throws where C : Content {
            var content = content
            try content.beforeEncode()
            var body = self.byteBufferAllocator.buffer(capacity: 0)
            try encoder.encode(content, to: &body, headers: &self.headers)
            self.body = body
        }

        func decode<C>(_ content: C.Type, using decoder: ContentDecoder) throws -> C where C : Content {
            guard let body = self.body else {
                throw Abort(.lengthRequired)
            }
            var decoded = try decoder.decode(C.self, from: body, headers: self.headers)
            try decoded.afterDecode()
            return decoded
        }
    }

    public var content: ContentContainer {
        get {
            return _ContentContainer(body: self.body, headers: self.headers, byteBufferAllocator: self.byteBufferAllocator)
        }
        set {
            let container = (newValue as! _ContentContainer)
            self.body = container.body
            self.headers = container.headers
        }
    }
}


================================================
FILE: Sources/Vapor/Client/ClientResponse.swift
================================================
import NIOCore
import NIOHTTP1
import Foundation

public struct ClientResponse: Sendable {
    public var status: HTTPStatus
    public var headers: HTTPHeaders
    public var body: ByteBuffer?
    private let byteBufferAllocator: ByteBufferAllocator

    public init(status: HTTPStatus = .ok, headers: HTTPHeaders = [:], body: ByteBuffer? = nil, byteBufferAllocator: ByteBufferAllocator = ByteBufferAllocator()) {
        self.status = status
        self.headers = headers
        self.body = body
        self.byteBufferAllocator = byteBufferAllocator
    }
}

extension ClientResponse {
    private struct _ContentContainer: ContentContainer {
        var body: ByteBuffer?
        var headers: HTTPHeaders
        let allocator: ByteBufferAllocator

        var contentType: HTTPMediaType? {
            return self.headers.contentType
        }

        mutating func encode<E>(_ encodable: E, using encoder: ContentEncoder) throws where E : Encodable {
            var body = self.allocator.buffer(capacity: 0)
            try encoder.encode(encodable, to: &body, headers: &self.headers)
            self.body = body
        }

        func decode<D>(_ decodable: D.Type, using decoder: ContentDecoder) throws -> D where D : Decodable {
            guard let body = self.body else {
                throw Abort(.lengthRequired)
            }
            return try decoder.decode(D.self, from: body, headers: self.headers)
        }

        mutating func encode<C>(_ content: C, using encoder: ContentEncoder) throws where C : Content {
            var body = self.allocator.buffer(capacity: 0)
            var content = content
            try content.beforeEncode()
            try encoder.encode(content, to: &body, headers: &self.headers)
            self.body = body
        }

        func decode<C>(_ content: C.Type, using decoder: ContentDecoder) throws -> C where C : Content {
            guard let body = self.body else {
                throw Abort(.lengthRequired)
            }
            var decoded = try decoder.decode(C.self, from: body, headers: self.headers)
            try decoded.afterDecode()
            return decoded
        }
    }

    public var content: ContentContainer {
        get {
            return _ContentContainer(body: self.body, headers: self.headers, allocator: self.byteBufferAllocator)
        }
        set {
            let container = (newValue as! _ContentContainer)
            self.body = container.body
            self.headers = container.headers
        }
    }
}

extension ClientResponse: CustomStringConvertible {
    public var description: String {
        var desc = ["HTTP/1.1 \(status.code) \(status.reasonPhrase)"]
        desc += self.headers.map { "\($0.name): \($0.value)" }
        if var body = self.body {
            let string = body.readString(length: body.readableBytes) ?? ""
            desc += ["", string]
        }
        return desc.joined(separator: "\n")
    }
}

extension ClientResponse: ResponseEncodable {
    public func encodeResponse(for request: Request) -> EventLoopFuture<Response> {
        let body: Response.Body
        if let buffer = self.body {
            body = .init(buffer: buffer, byteBufferAllocator: request.byteBufferAllocator)
        } else {
            body = .empty
        }
        let response = Response(
            status: self.status,
            headers: self.headers,
            body: body
        )
        return request.eventLoop.makeSucceededFuture(response)
    }
}

extension ClientResponse: Codable {
    private enum CodingKeys: String, CodingKey {
        case status = "status"
        case headers = "headers"
        case body = "body"
    }

    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.status = try container.decode(HTTPStatus.self, forKey: .status)
        self.headers = try container.decode(HTTPHeaders.self, forKey: .headers)
        let bodyString = try container.decode(String?.self, forKey: .body)
        guard let s = bodyString, let bodyData = [UInt8].init(decodingBase64: s) else {
            throw Abort(.internalServerError, reason: "Could not decode client response body from base64 string")
        }
        self.byteBufferAllocator = ByteBufferAllocator()
        self.body = self.byteBufferAllocator.buffer(bytes: bodyData)
    }

    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(self.status, forKey: .status)
        try container.encode(self.headers, forKey: .headers)
        if let body = self.body {
            let string = body.readableBytesView.base64String()
            try container.encode(string, forKey: .body)
        } else {
            try container.encodeNil(forKey: .body)
        }
    }
}

extension ClientResponse: Equatable {
    public static func == (lhs: Self, rhs: Self) -> Bool {
        return lhs.status == rhs.status && lhs.headers == rhs.headers && lhs.body == rhs.body
    }
}


================================================
FILE: Sources/Vapor/Client/Request+Client.swift
================================================
extension Request {
    public var client: Client {
        self.application.client.delegating(to: self.eventLoop).logging(to: self.logger).allocating(to: self.byteBufferAllocator)
    }
}


================================================
FILE: Sources/Vapor/Commands/BootCommand.swift
================================================
import ConsoleKit

/// Boots the `Application` then exits successfully.
///
///     $ swift run Run boot
///     Done.
///
public final class BootCommand: AsyncCommand {
    // See `AsyncCommand`.
    public struct Signature: CommandSignature {
        public init() { }
    }

    // See `AsyncCommand`.
    public var help: String {
        return "Boots the application's providers."
    }

    /// Create a new `BootCommand`.
    public init() { }

    // See `AsyncCommand`.
    public func run(using context: ConsoleKitCommands.CommandContext, signature: Signature) async throws {
        context.console.success("Done.")
    }
}


================================================
FILE: Sources/Vapor/Commands/CommandContext+Application.swift
================================================
import ConsoleKit

extension CommandContext {
    public var application: Application {
        get {
            guard let application = self.userInfo["application"] as? Application else {
                fatalError("Application not set on context")
            }
            return application
        }
        set {
            self.userInfo["application"] = newValue
        }
    }
}


================================================
FILE: Sources/Vapor/Commands/RoutesCommand.swift
================================================
import ConsoleKit
import RoutingKit

/// Displays all routes registered to the `Application`'s `Router` in an ASCII-formatted table.
///
///     $ swift run Run routes
///     +------+------------------+
///     | GET  | /search          |
///     +------+------------------+
///     | GET  | /hash/:string    |
///     +------+------------------+
///
/// A colon preceding a path component indicates a variable parameter. A colon with no text following
/// is a parameter whose result will be discarded.
///
/// The path will be displayed with the same syntax that is used to register a route.
public final class RoutesCommand: AsyncCommand {
    public struct Signature: CommandSignature {
        public init() { }
    }

    public var help: String {
        return "Displays all registered routes."
    }

    init() { }
    
    public func run(using context: ConsoleKitCommands.CommandContext, signature: Signature) async throws {
        let routes = context.application.routes
        let includeDescription = !routes.all.filter { $0.userInfo["description"] != nil }.isEmpty
        let pathSeparator = "/".consoleText()
        context.console.outputASCIITable(routes.all.map { route -> [ConsoleText] in
            var column = [route.method.rawValue.consoleText()]
            if route.path.isEmpty {
                column.append(pathSeparator)
            } else {
                column.append(route.path
                    .map { pathSeparator + $0.consoleText() }
                    .reduce("".consoleText(), +)
                )
            }
            if includeDescription {
                let desc = route.userInfo["description"]
                    .flatMap { $0 as? String }
                    .flatMap { $0.consoleText() } ?? ""
                column.append(desc)
            }
            return column
        })
    }
}

extension PathComponent {
    func consoleText() -> ConsoleText {
        switch self {
        case .constant:
            return description.consoleText()
        default:
            return description.consoleText(.info)
        }
    }
}

extension Console {
    func outputASCIITable(_ rows: [[ConsoleText]]) {
        var columnWidths: [Int] = []

        // calculate longest columns
        for row in rows {
            for (i, column) in row.enumerated() {
                if columnWidths.count <= i {
                    columnWidths.append(0)
                }
                if column.description.count > columnWidths[i] {
                    columnWidths[i] = column.description.count
                }
            }
        }
        
        func hr() {
            var text: ConsoleText = ""
            for columnWidth in columnWidths {
                text += "+"
                text += "-"
                for _ in 0..<columnWidth {
                    text += "-"
                }
                text += "-"
            }
            text += "+"
            self.output(text)
        }
        
        for row in rows {
            hr()
            var text: ConsoleText = ""
            for (i, column) in row.enumerated() {
                text += "| "
                text += column
                for _ in 0..<(columnWidths[i] - column.description.count) {
                    text += " "
                }
                text += " "
            }
            text += "|"
            self.output(text)
        }
        
        hr()
    }
}


================================================
FILE: Sources/Vapor/Commands/ServeCommand.swift
================================================
@preconcurrency import Dispatch
import Foundation
import ConsoleKit
import NIOConcurrencyHelpers

/// Boots the application's server. Listens for `SIGINT` and `SIGTERM` for graceful shutdown.
///
///     $ swift run Run serve
///     Server starting on http://localhost:8080
///
public final class ServeCommand: AsyncCommand, Sendable {
    public struct Signature: CommandSignature, Sendable {
        @Option(name: "hostname", short: "H", help: "Set the hostname the server will run on.")
        var hostname: String?
        
        @Option(name: "port", short: "p", help: "Set the port the server will run on.")
        var port: Int?
        
        @Option(name: "bind", short: "b", help: "Convenience for setting hostname and port together.")
        var bind: String?

        @Option(name: "unix-socket", short: nil, help: "Set the path for the unix domain socket file the server will bind to.")
        var socketPath: String?

        public init() { }
    }

    /// Errors that may be thrown when serving a server
    public enum Error: Swift.Error {
        /// Incompatible flags were used together (for instance, specifying a socket path along with a port)
        case incompatibleFlags
    }

    // See `AsyncCommand`.
    public let signature = Signature()

    // See `AsyncCommand`.
    public var help: String {
        return "Begins serving the app over HTTP."
    }
    
    struct SendableBox: Sendable {
        var didShutdown: Bool
        var running: Application.Running?
        var signalSources: [DispatchSourceSignal]
        var server: Server?
    }

    private let box: NIOLockedValueBox<SendableBox>

    /// Create a new `ServeCommand`.
    init() {
        let box = SendableBox(didShutdown: false, signalSources: [])
        self.box = .init(box)
    }

    // See `AsyncCommand`.
    public func run(using context: CommandContext, signature: Signature) async throws {
        switch (signature.hostname, signature.port, signature.bind, signature.socketPath) {
        case (.none, .none, .none, .none): // use defaults
            try await context.application.server.start(address: nil)
            
        case (.none, .none, .none, .some(let socketPath)): // unix socket
            try await context.application.server.start(address: .unixDomainSocket(path: socketPath))
            
        case (.none, .none, .some(let address), .none): // bind ("hostname:port")
            let hostname = address.split(separator: ":").first.flatMap(String.init)
            let port = address.split(separator: ":").last.flatMap(String.init).flatMap(Int.init)
            
            try await context.application.server.start(address: .hostname(hostname, port: port))
            
        case (let hostname, let port, .none, .none): // hostname / port
            try await context.application.server.start(address: .hostname(hostname, port: port))
            
        default: throw Error.incompatibleFlags
        }
        
        var box = self.box.withLockedValue { $0 }
        box.server = context.application.server

        // allow the server to be stopped or waited for
        let promise = context.application.eventLoopGroup.next().makePromise(of: Void.self)
        context.application.running = .start(using: promise)
        box.running = context.application.running

        // setup signal sources for shutdown
        let signalQueue = DispatchQueue(label: "codes.vapor.server.shutdown")
        func makeSignalSource(_ code: Int32) {
            #if canImport(Darwin)
            /// https://github.com/swift-server/swift-service-lifecycle/blob/main/Sources/UnixSignals/UnixSignalsSequence.swift#L77-L82
            signal(code, SIG_IGN)
            #endif
            
            let source = DispatchSource.makeSignalSource(signal: code, queue: signalQueue)
            source.setEventHandler {
                print() // clear ^C
                promise.succeed(())
            }
            source.resume()
            box.signalSources.append(source)
        }
        makeSignalSource(SIGTERM)
        makeSignalSource(SIGINT)
        self.box.withLockedValue { $0 = box }
    }

    @available(*, noasync, message: "Use the async asyncShutdown() method instead.")
    func shutdown() {
        var box = self.box.withLockedValue { $0 }
        box.didShutdown = true
        box.running?.stop()
        if let server = box.server {
            server.shutdown()
        }
        box.signalSources.forEach { $0.cancel() } // clear refs
        box.signalSources = []
        self.box.withLockedValue { $0 = box }
    }
    
    func asyncShutdown() async {
        var box = self.box.withLockedValue { $0 }
        box.didShutdown = true
        box.running?.stop()
        await box.server?.shutdown()
        box.signalSources.forEach { $0.cancel() } // clear refs
        box.signalSources = []
        self.box.withLockedValue { $0 = box }
    }
    
    deinit {
        assert(self.box.withLockedValue({ $0.didShutdown }), "ServeCommand did not shutdown before deinit")
    }
}


================================================
FILE: Sources/Vapor/Concurrency/AnyResponse+Concurrency.swift
================================================
import NIOCore

/// A type erased response useful for routes that can return more than one type.
///
///     router.get("foo") { req -> AnyAsyncResponse in
///         if /* something */ {
///             return AnyAsyncResponse(42)
///         } else {
///             return AnyAsyncResponse("string")
///         }
///     }
///
/// This can also be done using a `AsyncResponseEncodable` enum.
///
///     enum IntOrString: AsyncResponseEncodable {
///         case int(Int)
///         case string(String)
///
///         func encode(for req: Request) throws -> EventLoopFuture<Response> {
///             switch self {
///             case .int(let i): return try i.encode(for: req)
///             case .string(let s): return try s.encode(for: req)
///             }
///         }
///     }
///
///     router.get("foo") { req -> IntOrString in
///         if /* something */ {
///             return .int(42)
///         } else {
///             return .string("string")
///         }
///     }
///
public struct AnyAsyncResponse: AsyncResponseEncodable {
    /// The wrapped `AsyncResponseEncodable` type.
    private let encodable: AsyncResponseEncodable

    /// Creates a new `AnyAsyncResponse`.
    ///
    /// - parameters:
    ///     - encodable: Something `AsyncResponseEncodable`.
    public init(_ encodable: AsyncResponseEncodable) {
        self.encodable = encodable
    }

    public func encodeResponse(for request: Request) async throws -> Response {
        return try await self.encodable.encodeResponse(for: request)
    }
}



================================================
FILE: Sources/Vapor/Concurrency/AsyncBasicResponder.swift
================================================
import NIOCore

/// A basic, async closure-based `Responder`.
public struct AsyncBasicResponder: AsyncResponder {
    /// The stored responder closure.
    private let closure: @Sendable (Request) async throws -> Response

    /// Create a new `BasicResponder`.
    ///
    ///     let notFound: Responder = BasicResponder { req in
    ///         let res = req.response(http: .init(status: .notFound))
    ///         return req.eventLoop.newSucceededFuture(result: res)
    ///     }
    ///
    /// - parameters:
    ///     - closure: Responder closure.
    public init(
        closure: @Sendable @escaping (Request) async throws -> Response
    ) {
        self.closure = closure
    }

    public func respond(to request: Request) async throws -> Response {
        return try await closure(request)
    }
}


================================================
FILE: Sources/Vapor/Concurrency/AsyncMiddleware.swift
================================================
import NIOCore

/// `AsyncMiddleware` is placed between the server and your router. It is capable of
/// mutating both incoming requests and outgoing responses. `AsyncMiddleware` can choose
/// to pass requests on to the next `AsyncMiddleware` in a chain, or they can short circuit and
/// return a custom `Response` if desired.
///
/// This is an async version of `Middleware`
public protocol AsyncMiddleware: Middleware {
    /// Called with each `Request` that passes through this middleware.
    /// - parameters:
    ///     - request: The incoming `Request`.
    ///     - next: Next `Responder` in the chain, potentially another middleware or the main router.
    /// - returns: An asynchronous `Response`.
    func respond(to request: Request, chainingTo next: AsyncResponder) async throws -> Response
}

extension AsyncMiddleware {
    public func respond(to request: Request, chainingTo next: Responder) -> EventLoopFuture<Response> {
        let promise = request.eventLoop.makePromise(of: Response.self)
        promise.completeWithTask {
            let asyncResponder = AsyncBasicResponder { req in
                return try await next.respond(to: req).get()
            }
            return try await respond(to: request, chainingTo: asyncResponder)
        }
        return promise.futureResult
    }
}


================================================
FILE: Sources/Vapor/Concurrency/AsyncPasswordHasher+Concurrency.swift
================================================
import NIOCore
import Foundation

extension AsyncPasswordHasher {
    public func hash<Password>(_ password: Password) async throws -> [UInt8]
        where Password: DataProtocol & Sendable
    {
        try await self.hash(password).get()
    }

    public func verify<Password, Digest>(
        _ password: Password,
        created digest: Digest
    ) async throws -> Bool
        where Password: DataProtocol & Sendable, Digest: DataProtocol & Sendable
    {
        try await self.verify(password, created: digest).get()
    }

    public func hash(_ password: String) async throws -> String {
        try await self.hash(password).get()
    }

    public func verify(_ password: String, created digest: String) async throws -> Bool {
        try await self.verify(password, created: digest).get()
    }
}


================================================
FILE: Sources/Vapor/Concurrency/AsyncSessionDriver.swift
================================================
import NIOCore

/// Capable of managing CRUD operations for `Session`s.
///
/// This is an async version of `SessionDriver`
public protocol AsyncSessionDriver: SessionDriver {
    func createSession(_ data: SessionData, for request: Request) async throws -> SessionID
    func readSession(_ sessionID: SessionID, for request: Request) async throws -> SessionData?
    func updateSession(_ sessionID: SessionID, to data: SessionData, for request: Request) async throws -> SessionID
    func deleteSession(_ sessionID: SessionID, for request: Request) async throws
}

extension AsyncSessionDriver {
    public func createSession(_ data: SessionData, for request: Request) -> EventLoopFuture<SessionID> {
        let promise = request.eventLoop.makePromise(of: SessionID.self)
        promise.completeWithTask {
            try await self.createSession(data, for: request)
        }
        return promise.futureResult
    }
    
    public func readSession(_ sessionID: SessionID, for request: Request) -> EventLoopFuture<SessionData?> {
        let promise = request.eventLoop.makePromise(of: SessionData?.self)
        promise.completeWithTask {
            try await self.readSession(sessionID, for: request)
        }
        return promise.futureResult
    }
    
    public func updateSession(_ sessionID: SessionID, to data: SessionData, for request: Request) -> EventLoopFuture<SessionID> {
        let promise = request.eventLoop.makePromise(of: SessionID.self)
        promise.completeWithTask {
            try await self.updateSession(sessionID, to: data, for: request)
        }
        return promise.futureResult
    }
    
    public func deleteSession(_ sessionID: SessionID, for request: Request) -> EventLoopFuture<Void> {
        let promise = request.eventLoop.makePromise(of: Void.self)
        promise.completeWithTask {
            try await self.deleteSession(sessionID, for: request)
        }
        return promise.futureResult
    }
}


================================================
FILE: Sources/Vapor/Concurrency/Authentication+Concurrency.swift
================================================
import NIOCore

/// Helper for creating authentication middleware.
///
/// See `AsyncRequestAuthenticator` and `AsyncSessionAuthenticator` for more information.
///
/// This is an async version of `Authenticator`
public protocol AsyncAuthenticator: AsyncMiddleware { }

/// Help for creating authentication middleware based on `Request`.
///
/// `Authenticator`'s use the incoming request to check for authentication information.
/// If valid authentication credentials are present, the authenticated user is added to `req.auth`.
///
/// This is an async version of `RequestAuthenticator`
public protocol AsyncRequestAuthenticator: AsyncAuthenticator {
    func authenticate(request: Request) async throws
}

extension AsyncRequestAuthenticator {
    public func respond(to request: Request, chainingTo next: AsyncResponder) async throws -> Response {
        try await self.authenticate(request: request)
        return try await next.respond(to: request)
    }
}

// MARK: Basic

/// Helper for creating authentication middleware using the Basic authorization header.
///
/// This is an async version of `BasicAuthenticator`
public protocol AsyncBasicAuthenticator: AsyncRequestAuthenticator {
    func authenticate(basic: BasicAuthorization, for request: Request) async throws
}

extension AsyncBasicAuthenticator {
    public func authenticate(request: Request) async throws {
        guard let basicAuthorization = request.headers.basicAuthorization else {
            return
        }
        return try await self.authenticate(basic: basicAuthorization, for: request)
    }
}

// MARK: Bearer

/// Helper for creating authentication middleware using the Bearer authorization header.
///
/// This is an async version of `BearerAuthenticator`
public protocol AsyncBearerAuthenticator: AsyncRequestAuthenticator {
    func authenticate(bearer: BearerAuthorization, for request: Request) async throws
}

extension AsyncBearerAuthenticator {
    public func authenticate(request: Request) async throws {
        guard let bearerAuthorization = request.headers.bearerAuthorization else {
            return
        }
        return try await self.authenticate(bearer: bearerAuthorization, for: request)
    }
}

// MARK: Credentials

/// Helper for creating authentication middleware using request body contents.
///
/// This is an async version of `CredentialsAuthenticator`
public protocol AsyncCredentialsAuthenticator: AsyncRequestAuthenticator {
    associatedtype Credentials: Content
    func authenticate(credentials: Credentials, for request: Request) async throws
}

extension AsyncCredentialsAuthenticator {
    public func authenticate(request: Request) async throws {
        let credentials: Credentials
        do {
            credentials = try request.content.decode(Credentials.self)
        } catch {
            return
        }
        return try await self.authenticate(credentials: credentials, for: request)
    }
}

/// Helper for creating authentication middleware in conjunction with `SessionsMiddleware`.
///
/// This is an async version of `SessionAuthenticator`
public protocol AsyncSessionAuthenticator: AsyncAuthenticator {
    associatedtype User: SessionAuthenticatable

    /// Authenticate a model with the supplied ID.
    func authenticate(sessionID: User.SessionID, for request: Request) async throws
}

extension AsyncSessionAuthenticator {
    public func respond(to request: Request, chainingTo next: AsyncResponder) async throws -> Response {
        // if the user has already been authenticated
        // by a previous middleware, continue
        if request.auth.has(User.self) {
            return try await next.respond(to: request)
        }

        if request.hasSession, let aID = request.session.authenticated(User.self) {
            // try to find user with id from session
            try await self.authenticate(sessionID: aID, for: request)
        }
        
        // respond to the request
        let response = try await next.respond(to: request)
        if let user = request.auth.get(User.self) {
            // if a user has been authed (or is still authed), store in the session
            request.session.authenticate(user)
        } else if request.hasSession {
            // if no user is authed, it's possible they've been unauthed.
            // remove from session.
            request.session.unauthenticate(User.self)
        }
        return response
    }
}


================================================
FILE: Sources/Vapor/Concurrency/Cache+Concurrency.swift
================================================
import NIOCore

public extension Cache {

    /// Gets a decodable value from the cache. Returns `nil` if not found.
    func get<T>(_ key: String, as type: T.Type) async throws -> T? where T: Decodable & Sendable {
        try await self.get(key, as: type).get()
    }

    /// Sets an encodable value into the cache. Existing values are replaced. If `nil`, removes value.
    func set<T>(_ key: String, to value: T?) async throws where T: Encodable & Sendable {
        try await self.set(key, to: value).get()
    }

    /// Sets an encodable value into the cache with an expiry time. Existing values are replaced. If `nil`, removes value.
    func set<T>(_ key: String, to value: T?, expiresIn expirationTime: CacheExpirationTime?) async throws where T: Encodable & Sendable {
        try await self.set(key, to: value, expiresIn: expirationTime).get()
    }
    
    func delete(_ key: String) async throws {
        try await self.delete(key).get()
    }

    /// Gets a decodable value from the cache. Returns `nil` if not found.
    func get<T>(_ key: String) async throws -> T? where T: Decodable & Sendable {
        try await self.get(key).get()
    }
}


================================================
FILE: Sources/Vapor/Concurrency/Client+Concurrency.swift
================================================
import NIOCore
import NIOHTTP1

extension Client {
    public func get(_ url: URI, headers: HTTPHeaders = [:], beforeSend: (inout ClientRequest) throws -> () = { _ in }) async throws -> ClientResponse {
        return try await self.send(.GET, headers: headers, to: url, beforeSend: beforeSend).get()
    }

    public func post(_ url: URI, headers: HTTPHeaders = [:], beforeSend: (inout ClientRequest) throws -> () = { _ in }) async throws -> ClientResponse {
        return try await self.send(.POST, headers: headers, to: url, beforeSend: beforeSend).get()
    }

    public func patch(_ url: URI, headers: HTTPHeaders = [:], beforeSend: (inout ClientRequest) throws -> () = { _ in }) async throws -> ClientResponse {
        return try await self.send(.PATCH, headers: headers, to: url, beforeSend: beforeSend).get()
    }

    public func put(_ url: URI, headers: HTTPHeaders = [:], beforeSend: (inout ClientRequest) throws -> () = { _ in }) async throws -> ClientResponse {
        return try await self.send(.PUT, headers: headers, to: url, beforeSend: beforeSend).get()
    }

    public func delete(_ url: URI, headers: HTTPHeaders = [:], beforeSend: (inout ClientRequest) throws -> () = { _ in }) async throws -> ClientResponse {
        return try await self.send(.DELETE, headers: headers, to: url, beforeSend: beforeSend).get()
    }
        
    public func post<T>(_ url: URI, headers: HTTPHeaders = [:], content: T) async throws -> ClientResponse where T: Content {
        return try await self.post(url, headers: headers, beforeSend: { try $0.content.encode(content) })
    }
    
    public func patch<T>(_ url: URI, headers: HTTPHeaders = [:], content: T) async throws -> ClientResponse where T: Content {
        return try await self.patch(url, headers: headers, beforeSend: { try $0.content.encode(content) })
    }
    
    public func put<T>(_ url: URI, headers: HTTPHeaders = [:], content: T) async throws -> ClientResponse where T: Content {
        return try await self.put(url, headers: headers, beforeSend: { try $0.content.encode(content) })
    }

    public func send(
        _ method: HTTPMethod,
        headers: HTTPHeaders = [:],
        to url: URI,
        beforeSend: (inout ClientRequest) throws -> () = { _ in }
    ) async throws -> ClientResponse {
        var request = ClientRequest(method: method, url: url, headers: headers, body: nil, byteBufferAllocator: self.byteBufferAllocator)
        try beforeSend(&request)
        return try await self.send(request).get()
    }
    
    public func send(_ request: ClientRequest) async throws -> ClientResponse {
        return try await self.send(request).get()
    }
}


================================================
FILE: Sources/Vapor/Concurrency/RequestBody+Concurrency.swift
================================================
import NIOCore
import NIOConcurrencyHelpers

// MARK: - Request.Body.AsyncSequenceDelegate
extension Request.Body {
    
    /// `Request.Body.AsyncSequenceDelegate` bridges between EventLoop
    /// and AsyncSequence. Crucially, this type handles backpressure
    /// by synchronizing bytes on the `EventLoop`
    ///
    /// `AsyncSequenceDelegate` can be created and **must be retained**
    /// in `Request.Body/makeAsyncIterator()` method.
    fileprivate final class AsyncSequenceDelegate: @unchecked Sendable, NIOAsyncSequenceProducerDelegate {
        private enum State {
            case notCalledYet
            case noSignalReceived
            case waitingForSignalFromConsumer(EventLoopPromise<Void>)
        }

        private var _state: State = .notCalledYet
        private let eventLoop: any EventLoop

        init(eventLoop: any EventLoop) {
            self.eventLoop = eventLoop
        }

        private func produceMore0() {
            self.eventLoop.preconditionInEventLoop()
            switch self._state {
            case .notCalledYet:
                // We can just return here to sign to the producer that we want more data
                break
            case .noSignalReceived:
                preconditionFailure()
            case .waitingForSignalFromConsumer(let promise):
                self._state = .noSignalReceived
                promise.succeed(())
            }
        }

        private func didTerminate0() {
            self.eventLoop.preconditionInEventLoop()
            switch self._state {
            case .notCalledYet:
                // Means didn't hit the backpressure limits, so just return
                break
            case .noSignalReceived:
                // we will inform the producer, since the next write will fail.
                break
            case .waitingForSignalFromConsumer(let promise):
                self._state = .noSignalReceived
                promise.fail(CancellationError())
            }
        }

        func registerBackpressurePromise(_ promise: EventLoopPromise<Void>) {
            self.eventLoop.preconditionInEventLoop()
            switch self._state {
            case .noSignalReceived, .notCalledYet:
                self._state = .waitingForSignalFromConsumer(promise)
            case .waitingForSignalFromConsumer:
                preconditionFailure()
            }
        }

        func didTerminate() {
            self.eventLoop.execute { self.didTerminate0() }
        }

        func produceMore() {
            self.eventLoop.execute { self.produceMore0() }
        }
    }
}

// MARK: - Request.Body.AsyncSequence
extension Request.Body: AsyncSequence {
    public typealias Element = ByteBuffer
    
    /// This wrapper generalizes our implementation.
    /// `RequestBody.AsyncIterator` is the override point for
    /// using another implementation
    public struct AsyncIterator: AsyncIteratorProtocol {
        public typealias Element = ByteBuffer

        fileprivate typealias Underlying = NIOThrowingAsyncSequenceProducer<ByteBuffer, any Error, NIOAsyncSequenceProducerBackPressureStrategies.HighLowWatermark, Request.Body.AsyncSequenceDelegate>.AsyncIterator

        private var underlying: Underlying

        fileprivate init(underlying: Underlying) {
            self.underlying = underlying
        }

        public mutating func next() async throws -> ByteBuffer? {
            return try await self.underlying.next()
        }
    }
    
    /// Checks that the request has a body suitable for an AsyncSequence
    ///
    /// AsyncSequence streaming should use a body of type .stream().
    /// Using `.collected(_)` will load the entire request into memory
    /// which should be avoided for large file uploads.
    ///
    /// Example: app.on(.POST, "/upload", body: .stream) { ... }
    private func checkBodyStorage() {
        switch request.bodyStorage.withLockedValue({ $0 }) {
        case .stream(_):
            break
        case .collected(_):
            break
        default:
            preconditionFailure("""
            AsyncSequence streaming should use a body of type .stream()
            Example: app.on(.POST, "/upload", body: .stream) { ... }
           """)
        }
    }
    
    /// Generates an `AsyncIterator` to stream the body’s content as
    /// `ByteBuffer` sequences. This implementation supports backpressure using
    /// `NIOAsyncSequenceProducerBackPressureStrategies`
    /// - Returns: `AsyncIterator` containing the `Request.Body` as a
    /// `ByteBuffer` sequence
    public func makeAsyncIterator() -> AsyncIterator {
        let delegate = AsyncSequenceDelegate(eventLoop: request.eventLoop)
        
        let producer = NIOThrowingAsyncSequenceProducer.makeSequence(
            elementType: ByteBuffer.self,
            failureType: Error.self,
            backPressureStrategy: NIOAsyncSequenceProducerBackPressureStrategies
                .HighLowWatermark(lowWatermark: 5, highWatermark: 20),
            finishOnDeinit: true,
            delegate: delegate
        )
        
        let source = producer.source
        
        self.drain { streamResult in
            switch streamResult {
            case .buffer(let buffer):
                // Send the buffer to the async sequence
                let result = source.yield(buffer)
                // Inspect the source view and handle outcomes
                switch result {
                case .dropped:
                    // The consumer dropped the sequence.
                    // Inform the producer that we don't want more data
                    // by returning an error in the future.
                    delegate.didTerminate()
                    return request.eventLoop.makeFailedFuture(CancellationError())
                case .stopProducing:
                    // The consumer is too slow.
                    // We need to create a promise that w
Download .txt
gitextract_n1aicf92/

├── .github/
│   ├── CODEOWNERS
│   ├── contributing.md
│   ├── dependabot.yml
│   ├── maintainers.md
│   └── workflows/
│       ├── api-docs.yml
│       ├── sponsors.yml
│       └── test.yml
├── .gitignore
├── .spi.yml
├── AGENTS.md
├── LICENSE
├── NOTICES.txt
├── Package.swift
├── README.md
├── Sources/
│   ├── CVaporBcrypt/
│   │   ├── bcrypt.c
│   │   ├── bcrypt.h
│   │   ├── blf.c
│   │   ├── blf.h
│   │   └── include/
│   │       └── module.modulemap
│   ├── Development/
│   │   ├── Resources/
│   │   │   └── fileio.txt
│   │   ├── configure.swift
│   │   ├── entrypoint.swift
│   │   └── routes.swift
│   ├── Vapor/
│   │   ├── Application.swift
│   │   ├── Authentication/
│   │   │   ├── AuthenticationCache.swift
│   │   │   ├── Authenticator.swift
│   │   │   ├── BasicAuthorization.swift
│   │   │   ├── BearerAuthorization.swift
│   │   │   ├── GuardMiddleware.swift
│   │   │   ├── RedirectMiddleware.swift
│   │   │   └── SessionAuthenticatable.swift
│   │   ├── Bcrypt/
│   │   │   └── Bcrypt.swift
│   │   ├── Cache/
│   │   │   ├── Application+Cache.swift
│   │   │   ├── Cache.swift
│   │   │   ├── CacheExpirationTime.swift
│   │   │   ├── MemoryCache.swift
│   │   │   └── Request+Cache.swift
│   │   ├── Client/
│   │   │   ├── Application+Clients.swift
│   │   │   ├── Client.swift
│   │   │   ├── ClientRequest.swift
│   │   │   ├── ClientResponse.swift
│   │   │   └── Request+Client.swift
│   │   ├── Commands/
│   │   │   ├── BootCommand.swift
│   │   │   ├── CommandContext+Application.swift
│   │   │   ├── RoutesCommand.swift
│   │   │   └── ServeCommand.swift
│   │   ├── Concurrency/
│   │   │   ├── AnyResponse+Concurrency.swift
│   │   │   ├── AsyncBasicResponder.swift
│   │   │   ├── AsyncMiddleware.swift
│   │   │   ├── AsyncPasswordHasher+Concurrency.swift
│   │   │   ├── AsyncSessionDriver.swift
│   │   │   ├── Authentication+Concurrency.swift
│   │   │   ├── Cache+Concurrency.swift
│   │   │   ├── Client+Concurrency.swift
│   │   │   ├── RequestBody+Concurrency.swift
│   │   │   ├── Responder+Concurrency.swift
│   │   │   ├── ResponseCodable+Concurrency.swift
│   │   │   ├── RoutesBuilder+Concurrency.swift
│   │   │   ├── ViewRenderer+Concurrency.swift
│   │   │   └── WebSocket+Concurrency.swift
│   │   ├── Content/
│   │   │   ├── ContainerGetPathExecutor.swift
│   │   │   ├── Content.swift
│   │   │   ├── ContentCoders.swift
│   │   │   ├── ContentConfiguration.swift
│   │   │   ├── ContentContainer.swift
│   │   │   ├── JSONCoder+Custom.swift
│   │   │   ├── JSONCoders+Content.swift
│   │   │   ├── PlaintextDecoder.swift
│   │   │   ├── PlaintextEncoder.swift
│   │   │   ├── URLQueryCoders.swift
│   │   │   └── URLQueryContainer.swift
│   │   ├── Core/
│   │   │   ├── Core.swift
│   │   │   └── Running.swift
│   │   ├── Deprecations/
│   │   │   ├── CORSMiddleware+AllowOriginSetting.swift
│   │   │   ├── CORSMiddleware+Configuration+exposedHeaders.swift
│   │   │   ├── DotEnvFile+load.swift
│   │   │   ├── Routes+caseInsenstive.swift
│   │   │   └── Validatable+validate.swift
│   │   ├── Docs.docc/
│   │   │   └── index.md
│   │   ├── Environment/
│   │   │   ├── Environment+Process.swift
│   │   │   ├── Environment+Secret.swift
│   │   │   └── Environment.swift
│   │   ├── Error/
│   │   │   ├── Abort.swift
│   │   │   ├── AbortError.swift
│   │   │   ├── DebuggableError.swift
│   │   │   ├── Demangler.swift
│   │   │   ├── ErrorSource.swift
│   │   │   └── StackTrace.swift
│   │   ├── Exports.swift
│   │   ├── HTTP/
│   │   │   ├── Application+HTTP.swift
│   │   │   ├── BasicResponder.swift
│   │   │   ├── BodyStream.swift
│   │   │   ├── Client/
│   │   │   │   ├── Application+HTTP+Client.swift
│   │   │   │   └── EventLoopHTTPClient.swift
│   │   │   ├── EndpointCache.swift
│   │   │   ├── HTTPMethod+String.swift
│   │   │   ├── HTTPStatus.swift
│   │   │   ├── Headers/
│   │   │   │   ├── HTTPCookies.swift
│   │   │   │   ├── HTTPHeaderCacheControl.swift
│   │   │   │   ├── HTTPHeaderExpires.swift
│   │   │   │   ├── HTTPHeaderLastModified.swift
│   │   │   │   ├── HTTPHeaders+Cache.swift
│   │   │   │   ├── HTTPHeaders+Connection.swift
│   │   │   │   ├── HTTPHeaders+ContentDisposition.swift
│   │   │   │   ├── HTTPHeaders+ContentRange.swift
│   │   │   │   ├── HTTPHeaders+Directive.swift
│   │   │   │   ├── HTTPHeaders+Forwarded.swift
│   │   │   │   ├── HTTPHeaders+Link.swift
│   │   │   │   ├── HTTPHeaders+Name.swift
│   │   │   │   ├── HTTPHeaders+ResponseCompression.swift
│   │   │   │   ├── HTTPHeaders.swift
│   │   │   │   ├── HTTPMediaType.swift
│   │   │   │   └── HTTPMediaTypePreference.swift
│   │   │   ├── Responder.swift
│   │   │   └── Server/
│   │   │       ├── Application+HTTP+Server.swift
│   │   │       ├── HTTPServer.swift
│   │   │       ├── HTTPServerConfiguration+RequestDecompressionConfiguration.swift
│   │   │       ├── HTTPServerConfiguration+ResponseCompressionConfiguration.swift
│   │   │       ├── HTTPServerHandler.swift
│   │   │       ├── HTTPServerRequestDecoder.swift
│   │   │       ├── HTTPServerResponseEncoder.swift
│   │   │       └── HTTPServerUpgradeHandler.swift
│   │   ├── Logging/
│   │   │   ├── Logger+Report.swift
│   │   │   └── LoggingSystem+Environment.swift
│   │   ├── Middleware/
│   │   │   ├── Application+Middleware.swift
│   │   │   ├── CORSMiddleware.swift
│   │   │   ├── ErrorMiddleware.swift
│   │   │   ├── FileMiddleware.swift
│   │   │   ├── Middleware.swift
│   │   │   ├── MiddlewareConfiguration.swift
│   │   │   ├── ResponseCompressionMiddleware.swift
│   │   │   ├── RouteLoggingMiddleware.swift
│   │   │   └── TracingMiddleware.swift
│   │   ├── Multipart/
│   │   │   ├── File+Multipart.swift
│   │   │   ├── FormDataDecoder+Content.swift
│   │   │   └── FormDataEncoder+Content.swift
│   │   ├── Passwords/
│   │   │   ├── Application+Password.swift
│   │   │   ├── Application+Passwords.swift
│   │   │   ├── AsyncPasswordHasher.swift
│   │   │   ├── BcryptHasher.swift
│   │   │   ├── PasswordHasher.swift
│   │   │   ├── PlaintextHasher.swift
│   │   │   └── Request+Password.swift
│   │   ├── Request/
│   │   │   ├── Redirect.swift
│   │   │   ├── Request+Body.swift
│   │   │   ├── Request+BodyStream.swift
│   │   │   └── Request.swift
│   │   ├── Responder/
│   │   │   ├── Application+Responder.swift
│   │   │   └── DefaultResponder.swift
│   │   ├── Response/
│   │   │   ├── Response+Body.swift
│   │   │   ├── Response.swift
│   │   │   └── ResponseCodable.swift
│   │   ├── Routing/
│   │   │   ├── Application+Routes.swift
│   │   │   ├── Parameters+Require.swift
│   │   │   ├── Request+WebSocket.swift
│   │   │   ├── Route.swift
│   │   │   ├── RouteCollection.swift
│   │   │   ├── Routes.swift
│   │   │   ├── RoutesBuilder+Group.swift
│   │   │   ├── RoutesBuilder+Method.swift
│   │   │   ├── RoutesBuilder+Middleware.swift
│   │   │   ├── RoutesBuilder+WebSocket.swift
│   │   │   └── RoutesBuilder.swift
│   │   ├── Security/
│   │   │   ├── OTP.swift
│   │   │   └── ValidatedCertificateChain.swift
│   │   ├── Server/
│   │   │   ├── Application+Servers.swift
│   │   │   └── Server.swift
│   │   ├── Services/
│   │   │   ├── App+Service.swift
│   │   │   ├── Req+Service.swift
│   │   │   └── Service.swift
│   │   ├── Sessions/
│   │   │   ├── Application+Sessions.swift
│   │   │   ├── MemorySessions.swift
│   │   │   ├── Request+Session.swift
│   │   │   ├── Session.swift
│   │   │   ├── SessionCache.swift
│   │   │   ├── SessionData.swift
│   │   │   ├── SessionDriver.swift
│   │   │   ├── SessionsConfiguration.swift
│   │   │   └── SessionsMiddleware.swift
│   │   ├── URLEncodedForm/
│   │   │   ├── URLEncodedFormData.swift
│   │   │   ├── URLEncodedFormDecoder.swift
│   │   │   ├── URLEncodedFormEncoder.swift
│   │   │   ├── URLEncodedFormError.swift
│   │   │   ├── URLEncodedFormParser.swift
│   │   │   ├── URLEncodedFormSerializer.swift
│   │   │   └── URLQueryFragmentConvertible.swift
│   │   ├── Utilities/
│   │   │   ├── AnyResponse.swift
│   │   │   ├── Array+Random.swift
│   │   │   ├── Base32.swift
│   │   │   ├── Base64.swift
│   │   │   ├── BaseN.swift
│   │   │   ├── BasicCodingKey.swift
│   │   │   ├── ByteCount.swift
│   │   │   ├── Bytes+Hex.swift
│   │   │   ├── Bytes+SecureCompare.swift
│   │   │   ├── Collection+Safe.swift
│   │   │   ├── DataProtocol+Copy.swift
│   │   │   ├── DecoderUnwrapper.swift
│   │   │   ├── DirectoryConfiguration.swift
│   │   │   ├── DotEnv.swift
│   │   │   ├── Extendable.swift
│   │   │   ├── File.swift
│   │   │   ├── FileIO.swift
│   │   │   ├── LifecycleHandler.swift
│   │   │   ├── OptionalType.swift
│   │   │   ├── RFC1123.swift
│   │   │   ├── SocketAddress+Hostname.swift
│   │   │   ├── Storage.swift
│   │   │   ├── String+IsIPAddress.swift
│   │   │   ├── Thread.swift
│   │   │   ├── URI.swift
│   │   │   └── VaporSendableMetadataType.swift
│   │   ├── Validation/
│   │   │   ├── RangeResult.swift
│   │   │   ├── Validatable.swift
│   │   │   ├── Validation.swift
│   │   │   ├── ValidationKey.swift
│   │   │   ├── Validations.swift
│   │   │   ├── ValidationsError.swift
│   │   │   ├── Validator.swift
│   │   │   ├── ValidatorResult.swift
│   │   │   └── Validators/
│   │   │       ├── And.swift
│   │   │       ├── Case.swift
│   │   │       ├── CharacterSet.swift
│   │   │       ├── Count.swift
│   │   │       ├── Custom.swift
│   │   │       ├── Email.swift
│   │   │       ├── Empty.swift
│   │   │       ├── In.swift
│   │   │       ├── Nil.swift
│   │   │       ├── NilIgnoring.swift
│   │   │       ├── Not.swift
│   │   │       ├── Or.swift
│   │   │       ├── Pattern.swift
│   │   │       ├── Range.swift
│   │   │       ├── URL.swift
│   │   │       └── Valid.swift
│   │   ├── View/
│   │   │   ├── Application+Views.swift
│   │   │   ├── PlaintextRenderer.swift
│   │   │   ├── Request+View.swift
│   │   │   ├── View.swift
│   │   │   └── ViewRenderer.swift
│   │   └── _Deprecations.swift
│   ├── VaporTestUtils/
│   │   ├── TestingApplication.swift
│   │   ├── TestingHTTPRequest.swift
│   │   ├── TestingHTTPResponse.swift
│   │   └── Utilities.swift
│   ├── VaporTesting/
│   │   ├── +TestingHTTPResponse.swift
│   │   ├── Docs.docc/
│   │   │   └── index.md
│   │   ├── Exports.swift
│   │   ├── TestingApplicationTester.swift
│   │   ├── VaporTestingContext.swift
│   │   ├── XCTest+Migration.swift
│   │   └── withApp.swift
│   └── XCTVapor/
│       ├── +Application.swift
│       ├── +XCTHTTPResponse.swift
│       ├── Docs.docc/
│       │   └── index.md
│       ├── Exports.swift
│       ├── XCTApplicationTester.swift
│       ├── XCTVaporContext.swift
│       ├── XCTVaporTests.swift
│       └── typealiases.swift
└── Tests/
    └── VaporTests/
        ├── ApplicationCreationTests.swift
        ├── ApplicationTests.swift
        ├── AsyncAuthTests.swift
        ├── AsyncCacheTests.swift
        ├── AsyncClientTests.swift
        ├── AsyncCommandsTests.swift
        ├── AsyncEnvironmentTests.swift
        ├── AsyncFileTests.swift
        ├── AsyncMiddlewareTests.swift
        ├── AsyncPasswordTests.swift
        ├── AsyncRequestTests.swift
        ├── AsyncRouteTests.swift
        ├── AsyncSessionTests.swift
        ├── AsyncWebSocketTests.swift
        ├── AuthenticationTests.swift
        ├── BaseNTests.swift
        ├── BcryptTests.swift
        ├── BodyStreamStateTests.swift
        ├── CacheTests.swift
        ├── ClientTests.swift
        ├── ConditionalResponseCompressionTests.swift
        ├── ContentTests.swift
        ├── DotEnvTests.swift
        ├── EndpointCacheTests.swift
        ├── EnvironmentSecretTests.swift
        ├── ErrorTests.swift
        ├── FileTests.swift
        ├── HTTPCacheTests.swift
        ├── HTTPHeaderTests.swift
        ├── HTTPMediaTypeSetTests.swift
        ├── LoggingTests.swift
        ├── MetricsTests.swift
        ├── MiddlewareTests.swift
        ├── PasswordTests.swift
        ├── PipelineTests.swift
        ├── QueryTests.swift
        ├── RequestTests.swift
        ├── RouteTests.swift
        ├── SecurityTests.swift
        ├── ServerTests.swift
        ├── ServiceTests.swift
        ├── SessionTests.swift
        ├── URITests.swift
        ├── URLEncodedFormTests.swift
        ├── Utilities/
        │   ├── ByteBuffer+Helpers.swift
        │   ├── CapturingMetricsSystem.swift
        │   ├── ResponderClient.swift
        │   ├── SubUtilities/
        │   │   └── index.html
        │   ├── TestLogging.swift
        │   ├── TestTracer.swift
        │   ├── ThreadSafe.swift
        │   ├── expired.crt
        │   ├── expired.key
        │   ├── foo bar.html
        │   ├── foo.txt
        │   ├── index.html
        │   ├── long-test-file.txt
        │   ├── my-secret-env-content
        │   └── test.env
        ├── UtilityTests.swift
        ├── ValidationTests.swift
        ├── VaporTesting.swift
        ├── ViewTests.swift
        └── WebSocketTests.swift
Download .txt
SYMBOL INDEX (21 symbols across 4 files)

FILE: Sources/CVaporBcrypt/bcrypt.c
  function vapor_bcrypt_hashpass (line 50) | int
  function decode_base64 (line 187) | static int
  function vapor_encode_base64 (line 230) | int

FILE: Sources/CVaporBcrypt/bcrypt.h
  type u_int8_t (line 7) | typedef uint8_t u_int8_t;
  type u_int16_t (line 9) | typedef uint16_t u_int16_t;
  type u_int32_t (line 11) | typedef uint32_t u_int32_t;
  type u_int64_t (line 13) | typedef uint64_t u_int64_t;

FILE: Sources/CVaporBcrypt/blf.c
  function Vapor_Blowfish_encipher (line 63) | void
  function Vapor_Blowfish_decipher (line 88) | void
  function Vapor_Blowfish_initstate (line 113) | void
  function u_int32_t (line 393) | u_int32_t
  function Vapor_Blowfish_expand0state (line 414) | void
  function Vapor_Blowfish_expandstate (line 451) | void
  function vapor_blf_key (line 493) | void
  function vapor_blf_enc (line 503) | void
  function vapor_blf_dec (line 516) | void
  function vapor_blf_ecb_encrypt (line 529) | void
  function vapor_blf_ecb_decrypt (line 555) | void
  function vapor_blf_cbc_encrypt (line 581) | void
  function vapor_blf_cbc_decrypt (line 610) | void

FILE: Sources/CVaporBcrypt/blf.h
  type blf_ctx (line 52) | typedef struct BlowfishContext {
Condensed preview — 325 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,839K chars).
[
  {
    "path": ".github/CODEOWNERS",
    "chars": 17,
    "preview": "* @0xTim @gwynne\n"
  },
  {
    "path": ".github/contributing.md",
    "chars": 7084,
    "preview": "# Contributing to Vapor\n\n👋 Welcome to the Vapor team! \n\n## Testing\n\nOnce in Xcode, select the `vapor-Package` scheme and"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 417,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"daily\"\n   "
  },
  {
    "path": ".github/maintainers.md",
    "chars": 1259,
    "preview": "# Being a Maintainer\n\nIf you would like to volunteer to be a maintainer for this repo, or any other repo under the Vapor"
  },
  {
    "path": ".github/workflows/api-docs.yml",
    "chars": 387,
    "preview": "name: deploy-api-docs\non:\n  push:\n    branches:\n      - main\npermissions:\n  contents: read\n  id-token: write\n\njobs:\n  bu"
  },
  {
    "path": ".github/workflows/sponsors.yml",
    "chars": 1300,
    "preview": "name: Generate Sponsors README\non: workflow_dispatch\npermissions:\n  id-token: write\n  contents: read\n\njobs:\n  deploy:\n  "
  },
  {
    "path": ".github/workflows/test.yml",
    "chars": 1833,
    "preview": "name: test\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.ref }}\n  cancel-in-progress: true\non:\n  pull_request:"
  },
  {
    "path": ".gitignore",
    "chars": 225,
    "preview": "Packages\n.build\n.index-build\n.DS_Store\n*.xcodeproj\nDerivedData/\nPackage.resolved\n.swiftpm\nTests/LinuxMain.swift\n.vscode\n"
  },
  {
    "path": ".spi.yml",
    "chars": 184,
    "preview": "version: 1\nmetadata:\n  authors: \"Maintained by the Vapor Core Team with hundreds of contributions from the Vapor Communi"
  },
  {
    "path": "AGENTS.md",
    "chars": 3123,
    "preview": "# AI & Automated Agent Policy\n\nThis document outlines our policy on AI-assisted contributions and automated agents inter"
  },
  {
    "path": "LICENSE",
    "chars": 1080,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2020 Qutheory, LLC\n\nPermission is hereby granted, free of charge, to any person obt"
  },
  {
    "path": "NOTICES.txt",
    "chars": 871,
    "preview": "\n//===----------------------------------------------------------------------===//\n//\n// This source file is part of the "
  },
  {
    "path": "Package.swift",
    "chars": 7577,
    "preview": "// swift-tools-version:6.0\nimport PackageDescription\n\nlet package = Package(\n    name: \"vapor\",\n    platforms: [\n       "
  },
  {
    "path": "README.md",
    "chars": 15953,
    "preview": "<a href=\"https://discord.gg/vapor\">\n\n![Vapor](https://user-images.githubusercontent.com/1342803/75634175-4876d680-5bd9-1"
  },
  {
    "path": "Sources/CVaporBcrypt/bcrypt.c",
    "chars": 7717,
    "preview": "/*    $OpenBSD: bcrypt.c,v 1.55 2015/09/13 15:33:48 guenther Exp $    */\n\n/*\n * Copyright (c) 2014 Ted Unangst <tedu@ope"
  },
  {
    "path": "Sources/CVaporBcrypt/bcrypt.h",
    "chars": 1110,
    "preview": "#include <sys/types.h>\n#include <string.h>\n#include <stdio.h>\n\n#if defined(_WIN32)\ntypedef unsigned char uint8_t;\ntypede"
  },
  {
    "path": "Sources/CVaporBcrypt/blf.c",
    "chars": 26238,
    "preview": "/*    $OpenBSD: blf.c,v 1.7 2007/11/26 09:28:34 martynas Exp $    */\n\n/*\n * Blowfish block cipher for OpenBSD\n * Copyrig"
  },
  {
    "path": "Sources/CVaporBcrypt/blf.h",
    "chars": 3559,
    "preview": "/*    $OpenBSD: blf.h,v 1.6 2007/02/21 19:25:40 grunk Exp $    */\n\n/*\n * Blowfish - a fast block cipher designed by Bruc"
  },
  {
    "path": "Sources/CVaporBcrypt/include/module.modulemap",
    "chars": 75,
    "preview": "module CVaporBcrypt [system][extern_c] {\n header \"../bcrypt.h\"\n export *\n}\n"
  },
  {
    "path": "Sources/Development/Resources/fileio.txt",
    "chars": 4104,
    "preview": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ut eleifend turpis, quis vestibulum odio. Sed vestibulum, "
  },
  {
    "path": "Sources/Development/configure.swift",
    "chars": 4369,
    "preview": "import Vapor\nimport NIOConcurrencyHelpers\nimport NIOSSL\n\npublic func configure(_ app: Application) throws {\n    app.logg"
  },
  {
    "path": "Sources/Development/entrypoint.swift",
    "chars": 461,
    "preview": "import Vapor\nimport Logging\n\n@main\nstruct Entrypoint {\n    static func main() async throws {\n        var env = try Envir"
  },
  {
    "path": "Sources/Development/routes.swift",
    "chars": 12195,
    "preview": "import class Foundation.Bundle\nimport Vapor\nimport NIOCore\nimport NIOHTTP1\nimport NIOConcurrencyHelpers\nimport _NIOFileS"
  },
  {
    "path": "Sources/Vapor/Application.swift",
    "chars": 14182,
    "preview": "import ConsoleKit\nimport Logging\nimport NIOConcurrencyHelpers\nimport NIOCore\nimport NIOPosix\n\n/// Core type representing"
  },
  {
    "path": "Sources/Vapor/Authentication/AuthenticationCache.swift",
    "chars": 3761,
    "preview": "import NIOConcurrencyHelpers\n\nextension Request {\n    /// Helper for accessing authenticated objects.\n    /// See `Authe"
  },
  {
    "path": "Sources/Vapor/Authentication/Authenticator.swift",
    "chars": 2952,
    "preview": "import NIOCore\n\n/// Capable of being authenticated.\npublic protocol Authenticatable { }\n\n/// Helper for creating authent"
  },
  {
    "path": "Sources/Vapor/Authentication/BasicAuthorization.swift",
    "chars": 1778,
    "preview": "import Foundation\nimport NIOHTTP1\n\n/// A basic username and password.\npublic struct BasicAuthorization: Sendable {\n    /"
  },
  {
    "path": "Sources/Vapor/Authentication/BearerAuthorization.swift",
    "chars": 1081,
    "preview": "import NIOHTTP1\n\n/// A bearer token.\npublic struct BearerAuthorization: Sendable {\n    /// The plaintext token\n    publi"
  },
  {
    "path": "Sources/Vapor/Authentication/GuardMiddleware.swift",
    "chars": 2016,
    "preview": "import NIOCore\n\nextension Authenticatable {\n    /// This middleware ensures that an `Authenticatable` type `A` has been "
  },
  {
    "path": "Sources/Vapor/Authentication/RedirectMiddleware.swift",
    "chars": 1416,
    "preview": "import NIOCore\n\nextension Authenticatable {\n    /// Basic middleware to redirect unauthenticated requests to the supplie"
  },
  {
    "path": "Sources/Vapor/Authentication/SessionAuthenticatable.swift",
    "chars": 2991,
    "preview": "import NIOCore\n\n/// Helper for creating authentication middleware in conjunction with `SessionsMiddleware`.\npublic proto"
  },
  {
    "path": "Sources/Vapor/Bcrypt/Bcrypt.swift",
    "chars": 8603,
    "preview": "import Foundation\nimport CVaporBcrypt\n\n// MARK: BCrypt\n\n/// Creates and verifies BCrypt hashes.\n///\n/// Use BCrypt to cr"
  },
  {
    "path": "Sources/Vapor/Cache/Application+Cache.swift",
    "chars": 1998,
    "preview": "import NIOConcurrencyHelpers\n\nextension Application {\n    /// Controls application's configured caches.\n    ///\n    /// "
  },
  {
    "path": "Sources/Vapor/Cache/Cache.swift",
    "chars": 1525,
    "preview": "import NIOCore\n/// Codable key-value pair cache.\npublic protocol Cache {\n    /// Gets a decodable value from the cache. "
  },
  {
    "path": "Sources/Vapor/Cache/CacheExpirationTime.swift",
    "chars": 565,
    "preview": "/// Defines the lifetime of an entry in a cache.\npublic enum CacheExpirationTime: Sendable {\n    case seconds(Int)\n    c"
  },
  {
    "path": "Sources/Vapor/Cache/MemoryCache.swift",
    "chars": 3575,
    "preview": "import Foundation\nimport NIOCore\nimport NIOConcurrencyHelpers\n\nextension Application.Caches {\n    /// In-memory cache. T"
  },
  {
    "path": "Sources/Vapor/Cache/Request+Cache.swift",
    "chars": 99,
    "preview": "extension Request {\n    public var cache: Cache {\n        self.application.cache.for(self)\n    }\n}\n"
  },
  {
    "path": "Sources/Vapor/Client/Application+Clients.swift",
    "chars": 1820,
    "preview": "import NIOConcurrencyHelpers\n\nextension Application {\n    public var clients: Clients {\n        .init(application: self)"
  },
  {
    "path": "Sources/Vapor/Client/Client.swift",
    "chars": 3239,
    "preview": "import NIOCore\nimport Logging\nimport NIOHTTP1\n\npublic protocol Client: Sendable {\n    var eventLoop: EventLoop { get }\n "
  },
  {
    "path": "Sources/Vapor/Client/ClientRequest.swift",
    "chars": 3923,
    "preview": "import NIOCore\nimport NIOHTTP1\nimport Foundation\n\npublic struct ClientRequest: Sendable {\n    public var method: HTTPMet"
  },
  {
    "path": "Sources/Vapor/Client/ClientResponse.swift",
    "chars": 5065,
    "preview": "import NIOCore\nimport NIOHTTP1\nimport Foundation\n\npublic struct ClientResponse: Sendable {\n    public var status: HTTPSt"
  },
  {
    "path": "Sources/Vapor/Client/Request+Client.swift",
    "chars": 189,
    "preview": "extension Request {\n    public var client: Client {\n        self.application.client.delegating(to: self.eventLoop).loggi"
  },
  {
    "path": "Sources/Vapor/Commands/BootCommand.swift",
    "chars": 636,
    "preview": "import ConsoleKit\n\n/// Boots the `Application` then exits successfully.\n///\n///     $ swift run Run boot\n///     Done.\n/"
  },
  {
    "path": "Sources/Vapor/Commands/CommandContext+Application.swift",
    "chars": 390,
    "preview": "import ConsoleKit\n\nextension CommandContext {\n    public var application: Application {\n        get {\n            guard "
  },
  {
    "path": "Sources/Vapor/Commands/RoutesCommand.swift",
    "chars": 3429,
    "preview": "import ConsoleKit\nimport RoutingKit\n\n/// Displays all routes registered to the `Application`'s `Router` in an ASCII-form"
  },
  {
    "path": "Sources/Vapor/Commands/ServeCommand.swift",
    "chars": 5057,
    "preview": "@preconcurrency import Dispatch\nimport Foundation\nimport ConsoleKit\nimport NIOConcurrencyHelpers\n\n/// Boots the applicat"
  },
  {
    "path": "Sources/Vapor/Concurrency/AnyResponse+Concurrency.swift",
    "chars": 1553,
    "preview": "import NIOCore\n\n/// A type erased response useful for routes that can return more than one type.\n///\n///     router.get("
  },
  {
    "path": "Sources/Vapor/Concurrency/AsyncBasicResponder.swift",
    "chars": 815,
    "preview": "import NIOCore\n\n/// A basic, async closure-based `Responder`.\npublic struct AsyncBasicResponder: AsyncResponder {\n    //"
  },
  {
    "path": "Sources/Vapor/Concurrency/AsyncMiddleware.swift",
    "chars": 1320,
    "preview": "import NIOCore\n\n/// `AsyncMiddleware` is placed between the server and your router. It is capable of\n/// mutating both i"
  },
  {
    "path": "Sources/Vapor/Concurrency/AsyncPasswordHasher+Concurrency.swift",
    "chars": 813,
    "preview": "import NIOCore\nimport Foundation\n\nextension AsyncPasswordHasher {\n    public func hash<Password>(_ password: Password) a"
  },
  {
    "path": "Sources/Vapor/Concurrency/AsyncSessionDriver.swift",
    "chars": 1962,
    "preview": "import NIOCore\n\n/// Capable of managing CRUD operations for `Session`s.\n///\n/// This is an async version of `SessionDriv"
  },
  {
    "path": "Sources/Vapor/Concurrency/Authentication+Concurrency.swift",
    "chars": 4441,
    "preview": "import NIOCore\n\n/// Helper for creating authentication middleware.\n///\n/// See `AsyncRequestAuthenticator` and `AsyncSes"
  },
  {
    "path": "Sources/Vapor/Concurrency/Cache+Concurrency.swift",
    "chars": 1165,
    "preview": "import NIOCore\n\npublic extension Cache {\n\n    /// Gets a decodable value from the cache. Returns `nil` if not found.\n   "
  },
  {
    "path": "Sources/Vapor/Concurrency/Client+Concurrency.swift",
    "chars": 2665,
    "preview": "import NIOCore\nimport NIOHTTP1\n\nextension Client {\n    public func get(_ url: URI, headers: HTTPHeaders = [:], beforeSen"
  },
  {
    "path": "Sources/Vapor/Concurrency/RequestBody+Concurrency.swift",
    "chars": 6965,
    "preview": "import NIOCore\nimport NIOConcurrencyHelpers\n\n// MARK: - Request.Body.AsyncSequenceDelegate\nextension Request.Body {\n    "
  },
  {
    "path": "Sources/Vapor/Concurrency/Responder+Concurrency.swift",
    "chars": 437,
    "preview": "import NIOCore\n\npublic protocol AsyncResponder: Responder {\n    func respond(to request: Request) async throws -> Respon"
  },
  {
    "path": "Sources/Vapor/Concurrency/ResponseCodable+Concurrency.swift",
    "chars": 4023,
    "preview": "import NIOCore\nimport NIOHTTP1\n\n/// Can convert `self` to a `Response`.\n///\n/// Types that conform to this protocol can "
  },
  {
    "path": "Sources/Vapor/Concurrency/RoutesBuilder+Concurrency.swift",
    "chars": 4936,
    "preview": "import NIOCore\nimport NIOHTTP1\nimport RoutingKit\n\nextension RoutesBuilder {\n    @discardableResult\n    @preconcurrency\n "
  },
  {
    "path": "Sources/Vapor/Concurrency/ViewRenderer+Concurrency.swift",
    "chars": 646,
    "preview": "import NIOCore\n\npublic extension ViewRenderer {\n    func render<E>(_ name: String, _ context: E) async throws -> View wh"
  },
  {
    "path": "Sources/Vapor/Concurrency/WebSocket+Concurrency.swift",
    "chars": 5427,
    "preview": "import NIOCore\nimport NIOHTTP1\nimport WebSocketKit\nimport RoutingKit\nimport Foundation\n\nextension Request {\n\n    /// Upg"
  },
  {
    "path": "Sources/Vapor/Content/ContainerGetPathExecutor.swift",
    "chars": 3644,
    "preview": "/// Decodes nested single values from data at a key path.\ninternal struct ContainerGetPathExecutor<D: Decodable>: Decoda"
  },
  {
    "path": "Sources/Vapor/Content/Content.swift",
    "chars": 4551,
    "preview": "import NIOCore\n\n/// Convertible to / from content in an HTTP message.\n///\n/// Conformance to this protocol consists of:\n"
  },
  {
    "path": "Sources/Vapor/Content/ContentCoders.swift",
    "chars": 3640,
    "preview": "import Foundation\nimport NIOCore\nimport NIOHTTP1\n\n/// Conform a type to this protocol to make it usable for encoding dat"
  },
  {
    "path": "Sources/Vapor/Content/ContentConfiguration.swift",
    "chars": 5977,
    "preview": "import Foundation\nimport MultipartKit\nimport NIOConcurrencyHelpers\n\n/// Configures which ``Encoder``s and ``Decoder``s t"
  },
  {
    "path": "Sources/Vapor/Content/ContentContainer.swift",
    "chars": 6410,
    "preview": "import NIOHTTP1\nimport NIOCore\n\npublic protocol ContentContainer {\n    /// The type of data stored in the container.\n   "
  },
  {
    "path": "Sources/Vapor/Content/JSONCoder+Custom.swift",
    "chars": 3212,
    "preview": "import Foundation\n\nextension JSONEncoder {\n    /// Convenience for creating a customized ``Foundation/JSONEncoder``.\n   "
  },
  {
    "path": "Sources/Vapor/Content/JSONCoders+Content.swift",
    "chars": 3225,
    "preview": "import Foundation\nimport NIOCore\nimport NIOFoundationCompat\nimport NIOHTTP1\n\n#if canImport(Darwin)\nextension JSONEncoder"
  },
  {
    "path": "Sources/Vapor/Content/PlaintextDecoder.swift",
    "chars": 4041,
    "preview": "import NIOCore\nimport NIOHTTP1\n\n/// Decodes data as plaintext, utf8.\npublic struct PlaintextDecoder: ContentDecoder {\n  "
  },
  {
    "path": "Sources/Vapor/Content/PlaintextEncoder.swift",
    "chars": 5525,
    "preview": "import Foundation\nimport NIOCore\nimport NIOHTTP1\n\n/// Encodes data as plaintext, utf8.\npublic struct PlaintextEncoder: C"
  },
  {
    "path": "Sources/Vapor/Content/URLQueryCoders.swift",
    "chars": 996,
    "preview": "public protocol URLQueryDecoder: Sendable {\n    func decode<D>(_ decodable: D.Type, from url: URI) throws -> D\n        w"
  },
  {
    "path": "Sources/Vapor/Content/URLQueryContainer.swift",
    "chars": 4363,
    "preview": "import NIOHTTP1\nimport NIOCore\n\n/// Helper for encoding and decoding data from an HTTP request query string.\n///\n/// See"
  },
  {
    "path": "Sources/Vapor/Core/Core.swift",
    "chars": 6226,
    "preview": "import ConsoleKit\nimport NIOCore\nimport NIOPosix\nimport NIOConcurrencyHelpers\n\nextension Application {\n    public var co"
  },
  {
    "path": "Sources/Vapor/Core/Running.swift",
    "chars": 672,
    "preview": "import NIOCore\nimport NIOConcurrencyHelpers\n\nextension Application {\n    public struct Running: Sendable {\n        final"
  },
  {
    "path": "Sources/Vapor/Deprecations/CORSMiddleware+AllowOriginSetting.swift",
    "chars": 186,
    "preview": "extension CORSMiddleware.AllowOriginSetting {\n    @available(*, deprecated, renamed: \"any\")\n    public static func white"
  },
  {
    "path": "Sources/Vapor/Deprecations/CORSMiddleware+Configuration+exposedHeaders.swift",
    "chars": 1464,
    "preview": "import NIOHTTP1\n\nextension CORSMiddleware.Configuration {\n    /// Instantiate a CORSConfiguration struct that can be use"
  },
  {
    "path": "Sources/Vapor/Deprecations/DotEnvFile+load.swift",
    "chars": 2802,
    "preview": "import Logging\nimport NIOCore\nimport NIOPosix\n\nextension DotEnvFile {\n    /// Reads the dotenv files relevant to the env"
  },
  {
    "path": "Sources/Vapor/Deprecations/Routes+caseInsenstive.swift",
    "chars": 239,
    "preview": "extension Routes {\n    @available(*, deprecated, renamed: \"caseInsensitive\")\n    public var caseInsenstive: Bool {\n     "
  },
  {
    "path": "Sources/Vapor/Deprecations/Validatable+validate.swift",
    "chars": 221,
    "preview": "extension Validatable {\n    @available(*, deprecated, renamed: \"validate(content:)\")\n    public static func validate(_ r"
  },
  {
    "path": "Sources/Vapor/Docs.docc/index.md",
    "chars": 354,
    "preview": "# ``Vapor``\n\nVapor is a framework for building server applications, APIs and websites in Swift. It provides a safe, perf"
  },
  {
    "path": "Sources/Vapor/Environment/Environment+Process.swift",
    "chars": 1863,
    "preview": "import Foundation\n\nextension Environment {    \n    /// The process information of an environment. Wraps `ProcessInto.pro"
  },
  {
    "path": "Sources/Vapor/Environment/Environment+Secret.swift",
    "chars": 4477,
    "preview": "import NIOCore\nimport NIOPosix\nimport AsyncKit\nimport _NIOFileSystem\n\nextension Environment {\n    /// Reads a file's con"
  },
  {
    "path": "Sources/Vapor/Environment/Environment.swift",
    "chars": 7254,
    "preview": "import Foundation\nimport ConsoleKit\n\n/// The environment the application is running in, i.e., production, dev, etc. All "
  },
  {
    "path": "Sources/Vapor/Error/Abort.swift",
    "chars": 4110,
    "preview": "import NIOHTTP1\n\n/// Default implementation of `AbortError`. You can use this as a convenient method for throwing\n/// `A"
  },
  {
    "path": "Sources/Vapor/Error/AbortError.swift",
    "chars": 3392,
    "preview": "import NIOHTTP1\n\n/// Errors conforming to this protocol will always be displayed by\n/// Vapor to the end-user (even in p"
  },
  {
    "path": "Sources/Vapor/Error/DebuggableError.swift",
    "chars": 7058,
    "preview": "import Foundation\nimport Logging\n\n/// `Debuggable` provides an interface that allows a type\n/// to be more easily debugg"
  },
  {
    "path": "Sources/Vapor/Error/Demangler.swift",
    "chars": 1042,
    "preview": "import Foundation\n\n/// Here be dragons! _stdlib_demangleImpl is linked into the stdlib. Use at your own risk!\n@_silgen_n"
  },
  {
    "path": "Sources/Vapor/Error/ErrorSource.swift",
    "chars": 1286,
    "preview": "/// A source-code location.\npublic struct ErrorSource: Sendable {\n    /// File in which this location exists.\n    public"
  },
  {
    "path": "Sources/Vapor/Error/StackTrace.swift",
    "chars": 1388,
    "preview": "import Foundation\nimport NIOConcurrencyHelpers\n\n@available(*, deprecated, message: \"Captured stack traces are no longer "
  },
  {
    "path": "Sources/Vapor/Exports.swift",
    "chars": 2461,
    "preview": "@_documentation(visibility: internal) @_exported import AsyncKit\n@_documentation(visibility: internal) @_exported import"
  },
  {
    "path": "Sources/Vapor/HTTP/Application+HTTP.swift",
    "chars": 169,
    "preview": "extension Application {\n    public var http: HTTP {\n        .init(application: self)\n    }\n\n    public struct HTTP {\n   "
  },
  {
    "path": "Sources/Vapor/HTTP/BasicResponder.swift",
    "chars": 1036,
    "preview": "import NIOCore\n\n/// A basic, closure-based `Responder`.\npublic struct BasicResponder: Responder {\n    /// The stored res"
  },
  {
    "path": "Sources/Vapor/HTTP/BodyStream.swift",
    "chars": 2936,
    "preview": "import NIOCore\n\npublic enum BodyStreamResult: Sendable {\n    /// A normal data chunk.\n    /// There will be 0 or more of"
  },
  {
    "path": "Sources/Vapor/HTTP/Client/Application+HTTP+Client.swift",
    "chars": 1969,
    "preview": "import AsyncHTTPClient\n\nextension Application.Clients.Provider {\n    public static var http: Self {\n        .init {\n    "
  },
  {
    "path": "Sources/Vapor/HTTP/Client/EventLoopHTTPClient.swift",
    "chars": 2471,
    "preview": "import NIOCore\nimport AsyncHTTPClient\nimport Logging\nimport Foundation\n\nextension HTTPClient {\n    func delegating(to ev"
  },
  {
    "path": "Sources/Vapor/HTTP/EndpointCache.swift",
    "chars": 7845,
    "preview": "import Foundation\nimport NIOConcurrencyHelpers\nimport NIOCore\nimport Logging\nimport NIOHTTP1\n\npublic enum EndpointCacheE"
  },
  {
    "path": "Sources/Vapor/HTTP/HTTPMethod+String.swift",
    "chars": 207,
    "preview": "import NIOHTTP1\n\nextension HTTPMethod {\n    /// `String` representation of this `HTTPMethod`.\n    @available(*, deprecat"
  },
  {
    "path": "Sources/Vapor/HTTP/HTTPStatus.swift",
    "chars": 853,
    "preview": "import NIOHTTP1\nimport NIOCore\n\n/// Less verbose typealias for `HTTPResponseStatus`.\npublic typealias HTTPStatus = HTTPR"
  },
  {
    "path": "Sources/Vapor/HTTP/Headers/HTTPCookies.swift",
    "chars": 9738,
    "preview": "import Foundation\nimport NIOHTTP1\n\nextension HTTPHeaders {\n    /// Get and set `HTTPCookies` for an HTTP request\n    ///"
  },
  {
    "path": "Sources/Vapor/HTTP/Headers/HTTPHeaderCacheControl.swift",
    "chars": 9610,
    "preview": "import Foundation\nimport NIOHTTP1\n\n// Comments on these properties are copied from the mozilla doc URL shown below.\nexte"
  },
  {
    "path": "Sources/Vapor/HTTP/Headers/HTTPHeaderExpires.swift",
    "chars": 2044,
    "preview": "import Foundation\nimport NIOHTTP1\n\nextension HTTPHeaders {\n    public struct Expires {\n        /// The date represented "
  },
  {
    "path": "Sources/Vapor/HTTP/Headers/HTTPHeaderLastModified.swift",
    "chars": 1580,
    "preview": "import Foundation\nimport NIOHTTP1\n\nextension HTTPHeaders {\n    /// Represents the HTTP `Last-Modified` header.\n    /// -"
  },
  {
    "path": "Sources/Vapor/HTTP/Headers/HTTPHeaders+Cache.swift",
    "chars": 1306,
    "preview": "import Foundation\nimport NIOHTTP1\n\nextension HTTPHeaders {\n    /// Determines when the cached data should be expired.\n  "
  },
  {
    "path": "Sources/Vapor/HTTP/Headers/HTTPHeaders+Connection.swift",
    "chars": 809,
    "preview": "import NIOHTTP1\n\nextension HTTPHeaders {\n    public struct Connection: ExpressibleByStringLiteral, Equatable, Sendable {"
  },
  {
    "path": "Sources/Vapor/HTTP/Headers/HTTPHeaders+ContentDisposition.swift",
    "chars": 2621,
    "preview": "import NIOHTTP1\n\nextension HTTPHeaders {\n    /// Convenience for accessing the Content-Disposition header.\n    ///\n    /"
  },
  {
    "path": "Sources/Vapor/HTTP/Headers/HTTPHeaders+ContentRange.swift",
    "chars": 10569,
    "preview": "import Foundation\nimport NIOHTTP1\n\nextension HTTPHeaders {\n    \n    /// The unit in which `ContentRange`s and `Range`s a"
  },
  {
    "path": "Sources/Vapor/HTTP/Headers/HTTPHeaders+Directive.swift",
    "chars": 10344,
    "preview": "import NIOHTTP1\n\nextension HTTPHeaders {\n    struct Directive: Equatable, CustomStringConvertible {\n        var value: S"
  },
  {
    "path": "Sources/Vapor/HTTP/Headers/HTTPHeaders+Forwarded.swift",
    "chars": 3653,
    "preview": "import NIOHTTP1\n\nextension HTTPHeaders {\n    /// Convenience for accessing the Forwarded header. This header is added by"
  },
  {
    "path": "Sources/Vapor/HTTP/Headers/HTTPHeaders+Link.swift",
    "chars": 6084,
    "preview": "import NIOHTTP1\n\nextension HTTPHeaders {\n    /// Convenience for accessing the Link header as an array of provided links"
  },
  {
    "path": "Sources/Vapor/HTTP/Headers/HTTPHeaders+Name.swift",
    "chars": 23602,
    "preview": "import NIOHTTP1\n\nextension HTTPHeaders {\n    /// Type used for the name of a HTTP header in the `HTTPHeaders` storage.\n "
  },
  {
    "path": "Sources/Vapor/HTTP/Headers/HTTPHeaders+ResponseCompression.swift",
    "chars": 1873,
    "preview": "import Foundation\nimport NIOHTTP1\n\nextension HTTPHeaders {\n    /// A marker header internal to vapor that explicitly all"
  },
  {
    "path": "Sources/Vapor/HTTP/Headers/HTTPHeaders.swift",
    "chars": 2600,
    "preview": "import NIOHTTP1\n\nextension HTTPHeaders {\n    /// `MediaType` specified by this message's `\"Content-Type\"` header.\n    pu"
  },
  {
    "path": "Sources/Vapor/HTTP/Headers/HTTPMediaType.swift",
    "chars": 53510,
    "preview": "import NIOHTTP1\n\n/// Represents an encoded data-format, used in HTTP, HTML, email, and elsewhere.\n///\n///     text/plain"
  },
  {
    "path": "Sources/Vapor/HTTP/Headers/HTTPMediaTypePreference.swift",
    "chars": 2182,
    "preview": "import Foundation\nimport NIOHTTP1\n\n/// Represents a `MediaType` and its associated preference, `q`.\npublic struct HTTPMe"
  },
  {
    "path": "Sources/Vapor/HTTP/Responder.swift",
    "chars": 123,
    "preview": "import NIOCore\n\npublic protocol Responder: Sendable {\n    func respond(to request: Request) -> EventLoopFuture<Response>"
  },
  {
    "path": "Sources/Vapor/HTTP/Server/Application+HTTP+Server.swift",
    "chars": 2625,
    "preview": "extension Application.Servers.Provider {\n    public static var http: Self {\n        .init {\n            $0.servers.use {"
  },
  {
    "path": "Sources/Vapor/HTTP/Server/HTTPServer.swift",
    "chars": 36655,
    "preview": "import NIOCore\nimport NIOExtras\nimport NIOHTTP1\nimport NIOHTTP2\nimport NIOHTTPCompression\nimport NIOSSL\nimport Logging\ni"
  },
  {
    "path": "Sources/Vapor/HTTP/Server/HTTPServerConfiguration+RequestDecompressionConfiguration.swift",
    "chars": 1101,
    "preview": "extension HTTPServer.Configuration {\n    /// Supported HTTP decompression options.\n    public struct RequestDecompressio"
  },
  {
    "path": "Sources/Vapor/HTTP/Server/HTTPServerConfiguration+ResponseCompressionConfiguration.swift",
    "chars": 8743,
    "preview": "extension HTTPServer.Configuration {\n    /// Supported HTTP response compression options.\n    public struct ResponseComp"
  },
  {
    "path": "Sources/Vapor/HTTP/Server/HTTPServerHandler.swift",
    "chars": 3776,
    "preview": "import NIOCore\nimport Logging\n\nfinal class HTTPServerHandler: ChannelInboundHandler, RemovableChannelHandler {\n    typea"
  },
  {
    "path": "Sources/Vapor/HTTP/Server/HTTPServerRequestDecoder.swift",
    "chars": 15049,
    "preview": "import Logging\nimport NIOCore\nimport NIOHTTP1\nimport Foundation\nimport X509\n\nfinal class HTTPServerRequestDecoder: Chann"
  },
  {
    "path": "Sources/Vapor/HTTP/Server/HTTPServerResponseEncoder.swift",
    "chars": 10004,
    "preview": "import NIOCore\nimport NIOHTTP1\nimport NIOConcurrencyHelpers\n\nfinal class HTTPServerResponseEncoder: ChannelOutboundHandl"
  },
  {
    "path": "Sources/Vapor/HTTP/Server/HTTPServerUpgradeHandler.swift",
    "chars": 6420,
    "preview": "import NIOCore\nimport NIOHTTP1\nimport NIOWebSocket\nimport WebSocketKit\n\nfinal class HTTPServerUpgradeHandler: ChannelDup"
  },
  {
    "path": "Sources/Vapor/Logging/Logger+Report.swift",
    "chars": 1365,
    "preview": "import Foundation\nimport Logging\n\nextension Logger {\n    /// Reports an `Error` to this `Logger`.\n    ///\n    /// - para"
  },
  {
    "path": "Sources/Vapor/Logging/LoggingSystem+Environment.swift",
    "chars": 1302,
    "preview": "import Logging\nimport ConsoleKit\n\nextension LoggingSystem {\n    @preconcurrency\n    public static func bootstrap(from en"
  },
  {
    "path": "Sources/Vapor/Middleware/Application+Middleware.swift",
    "chars": 672,
    "preview": "extension Application {\n    public var middleware: Middlewares {\n        get {\n            if let existing = self.storag"
  },
  {
    "path": "Sources/Vapor/Middleware/CORSMiddleware.swift",
    "chars": 7964,
    "preview": "import NIOHTTP1\nimport NIOCore\n\n/// Middleware that adds support for CORS settings in request responses.\n/// For configu"
  },
  {
    "path": "Sources/Vapor/Middleware/ErrorMiddleware.swift",
    "chars": 4098,
    "preview": "import Foundation\nimport NIOCore\nimport NIOHTTP1\n\n/// Captures all errors and transforms them into an internal server er"
  },
  {
    "path": "Sources/Vapor/Middleware/FileMiddleware.swift",
    "chars": 10961,
    "preview": "import Foundation\nimport NIOCore\nimport _NIOFileSystem\n\n/// Serves static files from a public directory.\n///\n/// `FileMi"
  },
  {
    "path": "Sources/Vapor/Middleware/Middleware.swift",
    "chars": 2179,
    "preview": "import NIOCore\n\n/// `Middleware` is placed between the server and your router. It is capable of\n/// mutating both incomi"
  },
  {
    "path": "Sources/Vapor/Middleware/MiddlewareConfiguration.swift",
    "chars": 1129,
    "preview": "/// Configures an application's active `Middleware`.\n/// Middleware will be used in the order they are added.\npublic str"
  },
  {
    "path": "Sources/Vapor/Middleware/ResponseCompressionMiddleware.swift",
    "chars": 4530,
    "preview": "/// Overrides the response compression settings for a route.\n///\n/// This is useful when a set of static routes does not"
  },
  {
    "path": "Sources/Vapor/Middleware/RouteLoggingMiddleware.swift",
    "chars": 649,
    "preview": "import NIOCore\nimport Logging\n\n/// Emits a log message containing the request method and path to a `Request`'s logger.\n/"
  },
  {
    "path": "Sources/Vapor/Middleware/TracingMiddleware.swift",
    "chars": 4819,
    "preview": "import Tracing\n\n/// Creates a trace and metadata for every request\n///\n/// See https://opentelemetry.io/docs/specs/semco"
  },
  {
    "path": "Sources/Vapor/Multipart/File+Multipart.swift",
    "chars": 1631,
    "preview": "import MultipartKit\nimport NIOHTTP1\n\nextension File: MultipartPartConvertible {\n    public var multipart: MultipartPart?"
  },
  {
    "path": "Sources/Vapor/Multipart/FormDataDecoder+Content.swift",
    "chars": 1309,
    "preview": "import MultipartKit\nimport NIOHTTP1\nimport NIOCore\n\nextension FormDataDecoder: ContentDecoder {\n    public func decode<D"
  },
  {
    "path": "Sources/Vapor/Multipart/FormDataEncoder+Content.swift",
    "chars": 1245,
    "preview": "import MultipartKit\nimport NIOHTTP1\nimport NIOCore\n\nextension FormDataEncoder: ContentEncoder {\n    public func encode<E"
  },
  {
    "path": "Sources/Vapor/Passwords/Application+Password.swift",
    "chars": 1226,
    "preview": "import Foundation\n\nextension Application {\n    public var password: Password {\n        .init(application: self)\n    }\n\n "
  },
  {
    "path": "Sources/Vapor/Passwords/Application+Passwords.swift",
    "chars": 1517,
    "preview": "import NIOConcurrencyHelpers\n\nextension Application {\n    public var passwords: Passwords {\n        .init(application: s"
  },
  {
    "path": "Sources/Vapor/Passwords/AsyncPasswordHasher.swift",
    "chars": 1722,
    "preview": "import NIOCore\nimport NIOPosix\nimport Foundation\n\nextension PasswordHasher {\n    public func async(\n        on threadPoo"
  },
  {
    "path": "Sources/Vapor/Passwords/BcryptHasher.swift",
    "chars": 1023,
    "preview": "import Foundation\n\nextension Application.Passwords.Provider {\n    public static var bcrypt: Self {\n        .bcrypt(cost:"
  },
  {
    "path": "Sources/Vapor/Passwords/PasswordHasher.swift",
    "chars": 721,
    "preview": "import Foundation\n\npublic protocol PasswordHasher: Sendable {\n    func hash<Password>(_ password: Password) throws -> [U"
  },
  {
    "path": "Sources/Vapor/Passwords/PlaintextHasher.swift",
    "chars": 654,
    "preview": "import Foundation\n\nextension Application.Passwords.Provider {\n    public static var plaintext: Self {\n        .init {\n  "
  },
  {
    "path": "Sources/Vapor/Passwords/Request+Password.swift",
    "chars": 1029,
    "preview": "import Foundation\n\nextension Request {\n    public var password: Password {\n        .init(request: self)\n    }\n    \n    p"
  },
  {
    "path": "Sources/Vapor/Request/Redirect.swift",
    "chars": 4132,
    "preview": "extension Request {\n    /// Creates a redirect `Response`.\n    ///\n    ///     router.get(\"redirect\") { req in\n    ///  "
  },
  {
    "path": "Sources/Vapor/Request/Request+Body.swift",
    "chars": 2244,
    "preview": "import NIOCore\n\nextension Request {\n    public struct Body: CustomStringConvertible, Sendable {\n        let request: Req"
  },
  {
    "path": "Sources/Vapor/Request/Request+BodyStream.swift",
    "chars": 4586,
    "preview": "import NIOCore\nimport NIOConcurrencyHelpers\n\nextension Request {\n    final class BodyStream: BodyStreamWriter, AsyncBody"
  },
  {
    "path": "Sources/Vapor/Request/Request.swift",
    "chars": 15820,
    "preview": "import Foundation\nimport NIOCore\nimport NIOHTTP1\nimport Logging\nimport RoutingKit\nimport NIOConcurrencyHelpers\nimport Se"
  },
  {
    "path": "Sources/Vapor/Responder/Application+Responder.swift",
    "chars": 2496,
    "preview": "import NIOCore\nimport NIOConcurrencyHelpers\n\nextension Application {\n    public var responder: Responder {\n        .init"
  },
  {
    "path": "Sources/Vapor/Responder/DefaultResponder.swift",
    "chars": 5609,
    "preview": "import Foundation\nimport Metrics\n@preconcurrency import RoutingKit\nimport NIOCore\nimport NIOHTTP1\nimport Logging\n\n/// Va"
  },
  {
    "path": "Sources/Vapor/Response/Response+Body.swift",
    "chars": 13565,
    "preview": "@preconcurrency import Dispatch\nimport Foundation\nimport NIOCore\nimport NIOFoundationCompat\nimport NIOConcurrencyHelpers"
  },
  {
    "path": "Sources/Vapor/Response/Response.swift",
    "chars": 8276,
    "preview": "import NIOCore\nimport NIOHTTP1\nimport NIOFoundationCompat\nimport NIOConcurrencyHelpers\n\n/// An HTTP response from a serv"
  },
  {
    "path": "Sources/Vapor/Response/ResponseCodable.swift",
    "chars": 3628,
    "preview": "import NIOCore\nimport NIOHTTP1\n\n/// Can convert `self` to a `Response`.\n///\n/// Types that conform to this protocol can "
  },
  {
    "path": "Sources/Vapor/Routing/Application+Routes.swift",
    "chars": 360,
    "preview": "extension Application {\n    public var routes: Routes {\n        if let existing = self.storage[RoutesKey.self] {\n       "
  },
  {
    "path": "Sources/Vapor/Routing/Parameters+Require.swift",
    "chars": 1601,
    "preview": "import RoutingKit\n\nextension Parameters {\n    /// Grabs the named parameter from the parameter bag.\n    /// If the param"
  },
  {
    "path": "Sources/Vapor/Routing/Request+WebSocket.swift",
    "chars": 702,
    "preview": "import NIOCore\nimport WebSocketKit\nimport NIOHTTP1\n\nextension Request {\n     @preconcurrency public func webSocket(\n    "
  },
  {
    "path": "Sources/Vapor/Routing/Route.swift",
    "chars": 2679,
    "preview": "import NIOHTTP1\nimport RoutingKit\nimport NIOConcurrencyHelpers\n\npublic final class Route: CustomStringConvertible, Senda"
  },
  {
    "path": "Sources/Vapor/Routing/RouteCollection.swift",
    "chars": 586,
    "preview": "/// Groups collections of routes together for adding to a router.\npublic protocol RouteCollection {\n    /// Registers ro"
  },
  {
    "path": "Sources/Vapor/Routing/Routes.swift",
    "chars": 1863,
    "preview": "import NIOConcurrencyHelpers\n\npublic final class Routes: RoutesBuilder, CustomStringConvertible, Sendable {\n    public v"
  },
  {
    "path": "Sources/Vapor/Routing/RoutesBuilder+Group.swift",
    "chars": 3145,
    "preview": "import RoutingKit\n\nextension RoutesBuilder {\n    // MARK: Path\n    \n    /// Creates a new `Router` that will automatical"
  },
  {
    "path": "Sources/Vapor/Routing/RoutesBuilder+Method.swift",
    "chars": 6221,
    "preview": "import RoutingKit\nimport NIOHTTP1\n\n/// Determines how an incoming HTTP request's body is collected.\npublic enum HTTPBody"
  },
  {
    "path": "Sources/Vapor/Routing/RoutesBuilder+Middleware.swift",
    "chars": 3097,
    "preview": "extension RoutesBuilder {\n    // MARK: Middleware\n\n    /// Creates a new `Router` wrapped in the supplied variadic `Midd"
  },
  {
    "path": "Sources/Vapor/Routing/RoutesBuilder+WebSocket.swift",
    "chars": 2877,
    "preview": "import RoutingKit\nimport WebSocketKit\nimport NIOCore\nimport NIOHTTP1\n\npublic struct WebSocketMaxFrameSize: Sendable, Exp"
  },
  {
    "path": "Sources/Vapor/Routing/RoutesBuilder.swift",
    "chars": 237,
    "preview": "import Foundation\n\npublic protocol RoutesBuilder {\n    func add(_ route: Route)\n}\n\nextension Foundation.UUID: Swift.Loss"
  },
  {
    "path": "Sources/Vapor/Security/OTP.swift",
    "chars": 10634,
    "preview": "import Foundation\n#if canImport(Darwin) && compiler(>=6.1)\nimport Crypto\n#else\n@preconcurrency import Crypto\n#endif\n\n///"
  },
  {
    "path": "Sources/Vapor/Security/ValidatedCertificateChain.swift",
    "chars": 906,
    "preview": "import X509\nimport NIOSSL\nimport SwiftASN1\n\nextension NIOSSLCertificate {\n    // Convert NIOSSL certificate to X509 cert"
  },
  {
    "path": "Sources/Vapor/Server/Application+Servers.swift",
    "chars": 2865,
    "preview": "import NIOConcurrencyHelpers\n\nextension Application {\n    public var servers: Servers {\n        .init(application: self)"
  },
  {
    "path": "Sources/Vapor/Server/Server.swift",
    "chars": 4465,
    "preview": "import NIOCore\n\n// TODO: Remove these deprecated methods along with ServerStartError in the major release.\npublic protoc"
  },
  {
    "path": "Sources/Vapor/Services/App+Service.swift",
    "chars": 181,
    "preview": "extension Application {\n    public struct Services {\n        public let application: Application\n    }\n\n    public var s"
  },
  {
    "path": "Sources/Vapor/Services/Req+Service.swift",
    "chars": 246,
    "preview": "extension Request {\n    public struct Services {\n        public let request: Request\n        init(request: Request) {\n  "
  },
  {
    "path": "Sources/Vapor/Services/Service.swift",
    "chars": 2683,
    "preview": "import NIOConcurrencyHelpers\n\nextension Application {\n    public struct Service<ServiceType> {\n\n        let application:"
  },
  {
    "path": "Sources/Vapor/Sessions/Application+Sessions.swift",
    "chars": 2792,
    "preview": "import NIOConcurrencyHelpers\n\nextension Application {\n    public var sessions: Sessions {\n        .init(application: sel"
  },
  {
    "path": "Sources/Vapor/Sessions/MemorySessions.swift",
    "chars": 2175,
    "preview": "import Foundation\nimport NIOCore\nimport NIOConcurrencyHelpers\n\n/// Simple in-memory sessions implementation.\npublic stru"
  },
  {
    "path": "Sources/Vapor/Sessions/Request+Session.swift",
    "chars": 1607,
    "preview": "extension Request {\n    /// Returns the current `Session` or creates one.\n    ///\n    ///     router.get(\"session\") { re"
  },
  {
    "path": "Sources/Vapor/Sessions/Session.swift",
    "chars": 2061,
    "preview": "import NIOConcurrencyHelpers\n\n/// Sessions are a method for associating data with a client accessing your app.\n///\n/// E"
  },
  {
    "path": "Sources/Vapor/Sessions/SessionCache.swift",
    "chars": 503,
    "preview": "import NIOConcurrencyHelpers\n\n/// Singleton service cache for a `Session`. Used with a message's private container.\ninte"
  },
  {
    "path": "Sources/Vapor/Sessions/SessionData.swift",
    "chars": 2092,
    "preview": "/// A container for storing data associated with a given `SessionID`.\n///\n/// You can add data to an instance of `Sessio"
  },
  {
    "path": "Sources/Vapor/Sessions/SessionDriver.swift",
    "chars": 638,
    "preview": "import NIOCore\n\n/// Capable of managing CRUD operations for `Session`s.\npublic protocol SessionDriver: Sendable {\n    fu"
  },
  {
    "path": "Sources/Vapor/Sessions/SessionsConfiguration.swift",
    "chars": 1619,
    "preview": "import Foundation\n\n/// Configuration options for sessions.\npublic struct SessionsConfiguration: Sendable {\n    /// Creat"
  },
  {
    "path": "Sources/Vapor/Sessions/SessionsMiddleware.swift",
    "chars": 4371,
    "preview": "import NIOCore\n\n/// Uses HTTP cookies to save and restore sessions for connecting clients.\n///\n/// If a cookie matching "
  },
  {
    "path": "Sources/Vapor/URLEncodedForm/URLEncodedFormData.swift",
    "chars": 3738,
    "preview": "import Logging\n\n/// Keeps track if the string was percent encoded or not.\n/// Prevents double encoding/double decoding\ne"
  },
  {
    "path": "Sources/Vapor/URLEncodedForm/URLEncodedFormDecoder.swift",
    "chars": 24011,
    "preview": "import NIOCore\nimport Foundation\nimport NIOHTTP1\n\n/// Decodes instances of `Decodable` types from `application/x-www-for"
  },
  {
    "path": "Sources/Vapor/URLEncodedForm/URLEncodedFormEncoder.swift",
    "chars": 18378,
    "preview": "import Foundation\nimport NIOHTTP1\nimport NIOCore\n\n/// Encodes `Encodable` instances to `application/x-www-form-urlencode"
  },
  {
    "path": "Sources/Vapor/URLEncodedForm/URLEncodedFormError.swift",
    "chars": 576,
    "preview": "import NIOHTTP1\n\n/// Errors thrown while encoding/decoding `application/x-www-form-urlencoded` data.\nenum URLEncodedForm"
  },
  {
    "path": "Sources/Vapor/URLEncodedForm/URLEncodedFormParser.swift",
    "chars": 1711,
    "preview": "/// Parses a URL Query `single=value&arr=1&arr=2&obj[key]=objValue` into\ninternal struct URLEncodedFormParser {\n    init"
  },
  {
    "path": "Sources/Vapor/URLEncodedForm/URLEncodedFormSerializer.swift",
    "chars": 2671,
    "preview": "import struct Foundation.CharacterSet\n\nstruct URLEncodedFormSerializer: Sendable {\n    let splitVariablesOn: Character\n "
  },
  {
    "path": "Sources/Vapor/URLEncodedForm/URLQueryFragmentConvertible.swift",
    "chars": 4092,
    "preview": "import Foundation\n\n/// Capable of converting to / from `URLQueryFragment`.\nprotocol URLQueryFragmentConvertible {\n    //"
  },
  {
    "path": "Sources/Vapor/Utilities/AnyResponse.swift",
    "chars": 1486,
    "preview": "import NIOCore\n\n/// A type erased response useful for routes that can return more than one type.\n///\n///     router.get("
  },
  {
    "path": "Sources/Vapor/Utilities/Array+Random.swift",
    "chars": 985,
    "preview": "extension FixedWidthInteger {\n    public static func random() -> Self {\n        return Self.random(in: .min ... .max)\n  "
  },
  {
    "path": "Sources/Vapor/Utilities/Base32.swift",
    "chars": 7320,
    "preview": "/// IMPORTANT:\n///\n/// These APIs are `internal` rather than `public` on purpose - specifically due to the high risk of "
  },
  {
    "path": "Sources/Vapor/Utilities/Base64.swift",
    "chars": 8672,
    "preview": "/// IMPORTANT:\n///\n/// These APIs are `internal` rather than `public` on purpose - specifically due to the high risk of "
  },
  {
    "path": "Sources/Vapor/Utilities/BaseN.swift",
    "chars": 9294,
    "preview": "import Algorithms\n\n/// IMPORTANT:\n///\n/// These APIs are `internal` rather than `public` on purpose - partially because "
  },
  {
    "path": "Sources/Vapor/Utilities/BasicCodingKey.swift",
    "chars": 2738,
    "preview": "#if os(Linux)\npublic typealias CodingKeyRepresentable = Swift.CodingKeyRepresentable\n#else\n/// This is an unwelcome stan"
  },
  {
    "path": "Sources/Vapor/Utilities/ByteCount.swift",
    "chars": 1994,
    "preview": "import Foundation\n\n/// Represents a number of bytes:\n///\n/// let bytes: ByteCount = \"1mb\"\n/// print(bytes.value) // 1048"
  },
  {
    "path": "Sources/Vapor/Utilities/Bytes+Hex.swift",
    "chars": 1684,
    "preview": "extension Sequence where Element == UInt8 {\n    public var hex: String {\n        self.hexEncodedString()\n    }\n\n    publ"
  },
  {
    "path": "Sources/Vapor/Utilities/Bytes+SecureCompare.swift",
    "chars": 1355,
    "preview": "extension Collection where Element: Equatable {\n    /// Performs a full-comparison of all elements in two collections. I"
  },
  {
    "path": "Sources/Vapor/Utilities/Collection+Safe.swift",
    "chars": 226,
    "preview": "extension Collection {\n    /// Returns the element at the specified index if it is within bounds, otherwise nil.\n    sub"
  },
  {
    "path": "Sources/Vapor/Utilities/DataProtocol+Copy.swift",
    "chars": 106,
    "preview": "import Foundation\n\nextension DataProtocol {\n    func copyBytes() -> [UInt8] {\n        Array(self)\n    }\n}\n"
  },
  {
    "path": "Sources/Vapor/Utilities/DecoderUnwrapper.swift",
    "chars": 255,
    "preview": "@available(*, deprecated, message: \"This type violates Codable invariants; using it is not safe.\")\npublic struct Decoder"
  },
  {
    "path": "Sources/Vapor/Utilities/DirectoryConfiguration.swift",
    "chars": 2398,
    "preview": "#if canImport(Glibc)\nimport Glibc\n#elseif canImport(Musl)\nimport Musl\n#elseif canImport(Android)\nimport Android\n#else\nim"
  },
  {
    "path": "Sources/Vapor/Utilities/DotEnv.swift",
    "chars": 17296,
    "preview": "#if canImport(Glibc)\nimport Glibc\n#elseif canImport(Musl)\nimport Musl\n#elseif canImport(Android)\nimport Android\n#else\nim"
  }
]

// ... and 125 more files (download for full content)

About this extraction

This page contains the full source code of the vapor/vapor GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 325 files (1.7 MB), approximately 428.1k tokens, and a symbol index with 21 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!