Full Code of actix/actix-web for AI

main 1398919140b6 cached
413 files
2.8 MB
757.1k tokens
4671 symbols
1 requests
Download .txt
Showing preview only (3,020K chars total). Download the full file or copy to clipboard to get everything.
Repository: actix/actix-web
Branch: main
Commit: 1398919140b6
Files: 413
Total size: 2.8 MB

Directory structure:
gitextract_9omv_u5c/

├── .clippy.toml
├── .codecov.yml
├── .cspell.yml
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   └── config.yml
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── dependabot.yml
│   ├── labeler.yml
│   └── workflows/
│       ├── bench.yml
│       ├── ci-post-merge.yml
│       ├── ci.yml
│       ├── coverage.yml
│       ├── labeler.yml
│       ├── lint.yml
│       └── semver-labeler.yml
├── .gitignore
├── .prettierrc.yml
├── .rustfmt.toml
├── .taplo.toml
├── CHANGES.md
├── CODE_OF_CONDUCT.md
├── Cargo.toml
├── LICENSE-APACHE
├── LICENSE-MIT
├── actix-files/
│   ├── CHANGES.md
│   ├── Cargo.toml
│   ├── README.md
│   ├── examples/
│   │   └── guarded-listing.rs
│   ├── src/
│   │   ├── chunked.rs
│   │   ├── directory.rs
│   │   ├── encoding.rs
│   │   ├── error.rs
│   │   ├── files.rs
│   │   ├── lib.rs
│   │   ├── named.rs
│   │   ├── path_buf.rs
│   │   ├── range.rs
│   │   └── service.rs
│   └── tests/
│       ├── encoding.rs
│       ├── fixtures/
│       │   └── guards/
│       │       ├── first/
│       │       │   └── index.txt
│       │       └── second/
│       │           └── index.txt
│       ├── guard.rs
│       ├── pre_epoch_mtime.rs
│       ├── test space.binary
│       ├── test.binary
│       ├── test.js
│       ├── traversal.rs
│       ├── utf8.txt
│       └── utf8.txt.br
├── actix-http/
│   ├── CHANGES.md
│   ├── Cargo.toml
│   ├── README.md
│   ├── benches/
│   │   ├── date-formatting.rs
│   │   └── response-body-compression.rs
│   ├── examples/
│   │   ├── actix-web.rs
│   │   ├── bench.rs
│   │   ├── echo.rs
│   │   ├── echo2.rs
│   │   ├── h2c-detect.rs
│   │   ├── h2spec.rs
│   │   ├── hello-world.rs
│   │   ├── streaming-error.rs
│   │   ├── tls_rustls.rs
│   │   └── ws.rs
│   ├── src/
│   │   ├── body/
│   │   │   ├── body_stream.rs
│   │   │   ├── boxed.rs
│   │   │   ├── either.rs
│   │   │   ├── message_body.rs
│   │   │   ├── mod.rs
│   │   │   ├── none.rs
│   │   │   ├── size.rs
│   │   │   ├── sized_stream.rs
│   │   │   └── utils.rs
│   │   ├── builder.rs
│   │   ├── config.rs
│   │   ├── date.rs
│   │   ├── encoding/
│   │   │   ├── decoder.rs
│   │   │   ├── encoder.rs
│   │   │   └── mod.rs
│   │   ├── error.rs
│   │   ├── extensions.rs
│   │   ├── h1/
│   │   │   ├── chunked.rs
│   │   │   ├── client.rs
│   │   │   ├── codec.rs
│   │   │   ├── decoder.rs
│   │   │   ├── dispatcher.rs
│   │   │   ├── dispatcher_tests.rs
│   │   │   ├── encoder.rs
│   │   │   ├── expect.rs
│   │   │   ├── mod.rs
│   │   │   ├── payload.rs
│   │   │   ├── service.rs
│   │   │   ├── timer.rs
│   │   │   ├── upgrade.rs
│   │   │   └── utils.rs
│   │   ├── h2/
│   │   │   ├── dispatcher.rs
│   │   │   ├── mod.rs
│   │   │   └── service.rs
│   │   ├── header/
│   │   │   ├── as_name.rs
│   │   │   ├── common.rs
│   │   │   ├── into_pair.rs
│   │   │   ├── into_value.rs
│   │   │   ├── map.rs
│   │   │   ├── mod.rs
│   │   │   ├── shared/
│   │   │   │   ├── charset.rs
│   │   │   │   ├── content_encoding.rs
│   │   │   │   ├── extended.rs
│   │   │   │   ├── http_date.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── quality.rs
│   │   │   │   └── quality_item.rs
│   │   │   └── utils.rs
│   │   ├── helpers.rs
│   │   ├── http_message.rs
│   │   ├── keep_alive.rs
│   │   ├── lib.rs
│   │   ├── message.rs
│   │   ├── notify_on_drop.rs
│   │   ├── payload.rs
│   │   ├── requests/
│   │   │   ├── head.rs
│   │   │   ├── mod.rs
│   │   │   └── request.rs
│   │   ├── responses/
│   │   │   ├── builder.rs
│   │   │   ├── head.rs
│   │   │   ├── mod.rs
│   │   │   └── response.rs
│   │   ├── service.rs
│   │   ├── test.rs
│   │   └── ws/
│   │       ├── codec.rs
│   │       ├── dispatcher.rs
│   │       ├── frame.rs
│   │       ├── mask.rs
│   │       ├── mod.rs
│   │       └── proto.rs
│   └── tests/
│       ├── test.binary
│       ├── test_client.rs
│       ├── test_h2_timer.rs
│       ├── test_openssl.rs
│       ├── test_rustls.rs
│       ├── test_server.rs
│       └── test_ws.rs
├── actix-http-test/
│   ├── CHANGES.md
│   ├── Cargo.toml
│   ├── README.md
│   └── src/
│       └── lib.rs
├── actix-multipart/
│   ├── CHANGES.md
│   ├── Cargo.toml
│   ├── README.md
│   ├── examples/
│   │   └── form.rs
│   └── src/
│       ├── error.rs
│       ├── extractor.rs
│       ├── field.rs
│       ├── form/
│       │   ├── bytes.rs
│       │   ├── json.rs
│       │   ├── mod.rs
│       │   ├── tempfile.rs
│       │   └── text.rs
│       ├── lib.rs
│       ├── multipart.rs
│       ├── payload.rs
│       ├── safety.rs
│       └── test.rs
├── actix-multipart-derive/
│   ├── CHANGES.md
│   ├── Cargo.toml
│   ├── README.md
│   ├── src/
│   │   └── lib.rs
│   └── tests/
│       ├── trybuild/
│       │   ├── all-required.rs
│       │   ├── deny-duplicates.rs
│       │   ├── deny-parse-fail.rs
│       │   ├── deny-parse-fail.stderr
│       │   ├── deny-unknown.rs
│       │   ├── optional-and-list.rs
│       │   ├── rename.rs
│       │   ├── size-limit-parse-fail.rs
│       │   ├── size-limit-parse-fail.stderr
│       │   └── size-limits.rs
│       └── trybuild.rs
├── actix-router/
│   ├── CHANGES.md
│   ├── Cargo.toml
│   ├── README.md
│   ├── benches/
│   │   ├── quoter.rs
│   │   └── router.rs
│   └── src/
│       ├── de.rs
│       ├── lib.rs
│       ├── path.rs
│       ├── pattern.rs
│       ├── quoter.rs
│       ├── regex_set.rs
│       ├── resource.rs
│       ├── resource_path.rs
│       ├── router.rs
│       └── url.rs
├── actix-test/
│   ├── CHANGES.md
│   ├── Cargo.toml
│   ├── README.md
│   └── src/
│       └── lib.rs
├── actix-web/
│   ├── CHANGES.md
│   ├── Cargo.toml
│   ├── MIGRATION-0.x.md
│   ├── MIGRATION-1.0.md
│   ├── MIGRATION-2.0.md
│   ├── MIGRATION-3.0.md
│   ├── MIGRATION-4.0.md
│   ├── README.md
│   ├── benches/
│   │   ├── responder.rs
│   │   ├── server.rs
│   │   └── service.rs
│   ├── examples/
│   │   ├── README.md
│   │   ├── basic.rs
│   │   ├── from_fn.rs
│   │   ├── introspection.rs
│   │   ├── introspection_multi_servers.rs
│   │   ├── macroless.rs
│   │   ├── middleware_from_fn.rs
│   │   ├── on-connect.rs
│   │   ├── uds.rs
│   │   └── worker-cpu-pin.rs
│   ├── src/
│   │   ├── app.rs
│   │   ├── app_service.rs
│   │   ├── config.rs
│   │   ├── data.rs
│   │   ├── dev.rs
│   │   ├── error/
│   │   │   ├── error.rs
│   │   │   ├── internal.rs
│   │   │   ├── macros.rs
│   │   │   ├── mod.rs
│   │   │   └── response_error.rs
│   │   ├── extract.rs
│   │   ├── guard/
│   │   │   ├── acceptable.rs
│   │   │   ├── host.rs
│   │   │   └── mod.rs
│   │   ├── handler.rs
│   │   ├── helpers.rs
│   │   ├── http/
│   │   │   ├── header/
│   │   │   │   ├── accept.rs
│   │   │   │   ├── accept_charset.rs
│   │   │   │   ├── accept_encoding.rs
│   │   │   │   ├── accept_language.rs
│   │   │   │   ├── allow.rs
│   │   │   │   ├── any_or_some.rs
│   │   │   │   ├── cache_control.rs
│   │   │   │   ├── content_disposition.rs
│   │   │   │   ├── content_language.rs
│   │   │   │   ├── content_length.rs
│   │   │   │   ├── content_range.rs
│   │   │   │   ├── content_type.rs
│   │   │   │   ├── date.rs
│   │   │   │   ├── encoding.rs
│   │   │   │   ├── entity.rs
│   │   │   │   ├── etag.rs
│   │   │   │   ├── expires.rs
│   │   │   │   ├── if_match.rs
│   │   │   │   ├── if_modified_since.rs
│   │   │   │   ├── if_none_match.rs
│   │   │   │   ├── if_range.rs
│   │   │   │   ├── if_unmodified_since.rs
│   │   │   │   ├── last_modified.rs
│   │   │   │   ├── macros.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── preference.rs
│   │   │   │   └── range.rs
│   │   │   └── mod.rs
│   │   ├── info.rs
│   │   ├── introspection.rs
│   │   ├── lib.rs
│   │   ├── middleware/
│   │   │   ├── authors-guide.md
│   │   │   ├── compat.rs
│   │   │   ├── compress.rs
│   │   │   ├── condition.rs
│   │   │   ├── default_headers.rs
│   │   │   ├── err_handlers.rs
│   │   │   ├── from_fn.rs
│   │   │   ├── identity.rs
│   │   │   ├── logger.rs
│   │   │   ├── mod.rs
│   │   │   └── normalize.rs
│   │   ├── redirect.rs
│   │   ├── request.rs
│   │   ├── request_data.rs
│   │   ├── resource.rs
│   │   ├── response/
│   │   │   ├── builder.rs
│   │   │   ├── customize_responder.rs
│   │   │   ├── http_codes.rs
│   │   │   ├── mod.rs
│   │   │   ├── responder.rs
│   │   │   └── response.rs
│   │   ├── rmap.rs
│   │   ├── route.rs
│   │   ├── rt.rs
│   │   ├── scope.rs
│   │   ├── server.rs
│   │   ├── service.rs
│   │   ├── test/
│   │   │   ├── mod.rs
│   │   │   ├── test_request.rs
│   │   │   ├── test_services.rs
│   │   │   └── test_utils.rs
│   │   ├── thin_data.rs
│   │   ├── types/
│   │   │   ├── either.rs
│   │   │   ├── form.rs
│   │   │   ├── header.rs
│   │   │   ├── html.rs
│   │   │   ├── json.rs
│   │   │   ├── mod.rs
│   │   │   ├── path.rs
│   │   │   ├── payload.rs
│   │   │   ├── query.rs
│   │   │   └── readlines.rs
│   │   └── web.rs
│   └── tests/
│       ├── compression.rs
│       ├── fixtures/
│       │   ├── lorem.txt
│       │   ├── lorem.txt.br
│       │   ├── lorem.txt.xz
│       │   └── lorem.txt.zst
│       ├── introspection.rs
│       ├── test-macro-import-conflict.rs
│       ├── test_error_propagation.rs
│       ├── test_httpserver.rs
│       ├── test_server.rs
│       ├── test_streaming_response.rs
│       ├── test_weird_poll.rs
│       ├── utils.rs
│       └── weird_poll.rs
├── actix-web-actors/
│   ├── CHANGES.md
│   ├── Cargo.toml
│   ├── README.md
│   ├── src/
│   │   ├── context.rs
│   │   ├── lib.rs
│   │   └── ws.rs
│   └── tests/
│       └── test_ws.rs
├── actix-web-codegen/
│   ├── CHANGES.md
│   ├── Cargo.toml
│   ├── README.md
│   ├── src/
│   │   ├── lib.rs
│   │   ├── route.rs
│   │   └── scope.rs
│   └── tests/
│       ├── routes.rs
│       ├── scopes.rs
│       ├── trybuild/
│       │   ├── docstring-ok.rs
│       │   ├── route-custom-lowercase.rs
│       │   ├── route-custom-lowercase.stderr
│       │   ├── route-custom-method.rs
│       │   ├── route-duplicate-method-fail.rs
│       │   ├── route-duplicate-method-fail.stderr
│       │   ├── route-malformed-path-fail.rs
│       │   ├── route-malformed-path-fail.stderr
│       │   ├── route-missing-method-fail.rs
│       │   ├── route-missing-method-fail.stderr
│       │   ├── route-ok.rs
│       │   ├── routes-missing-args-fail.rs
│       │   ├── routes-missing-args-fail.stderr
│       │   ├── routes-missing-method-fail.rs
│       │   ├── routes-missing-method-fail.stderr
│       │   ├── routes-ok.rs
│       │   ├── scope-invalid-args.rs
│       │   ├── scope-invalid-args.stderr
│       │   ├── scope-missing-args.rs
│       │   ├── scope-missing-args.stderr
│       │   ├── scope-on-handler.rs
│       │   ├── scope-on-handler.stderr
│       │   ├── scope-trailing-slash.rs
│       │   ├── scope-trailing-slash.stderr
│       │   ├── simple-fail.rs
│       │   ├── simple-fail.stderr
│       │   ├── simple.rs
│       │   └── test-runtime.rs
│       └── trybuild.rs
├── awc/
│   ├── CHANGES.md
│   ├── Cargo.toml
│   ├── README.md
│   ├── examples/
│   │   └── client.rs
│   ├── src/
│   │   ├── any_body.rs
│   │   ├── builder.rs
│   │   ├── client/
│   │   │   ├── config.rs
│   │   │   ├── connection.rs
│   │   │   ├── connector.rs
│   │   │   ├── error.rs
│   │   │   ├── h1proto.rs
│   │   │   ├── h2proto.rs
│   │   │   ├── mod.rs
│   │   │   └── pool.rs
│   │   ├── connect.rs
│   │   ├── error.rs
│   │   ├── frozen.rs
│   │   ├── lib.rs
│   │   ├── middleware/
│   │   │   ├── mod.rs
│   │   │   └── redirect.rs
│   │   ├── request.rs
│   │   ├── responses/
│   │   │   ├── json_body.rs
│   │   │   ├── mod.rs
│   │   │   ├── read_body.rs
│   │   │   ├── response.rs
│   │   │   └── response_body.rs
│   │   ├── sender.rs
│   │   ├── test.rs
│   │   └── ws.rs
│   └── tests/
│       ├── test_client.rs
│       ├── test_connector.rs
│       ├── test_empty_stream.rs
│       ├── test_rustls_client.rs
│       ├── test_ssl_client.rs
│       ├── test_ws.rs
│       └── utils.rs
├── deny.toml
├── docs/
│   └── graphs/
│       ├── .gitignore
│       ├── README.md
│       ├── net-only.dot
│       ├── web-focus.dot
│       └── web-only.dot
├── justfile
└── scripts/
    ├── bump
    ├── free-disk-space.sh
    ├── publish
    └── unreleased

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

================================================
FILE: .clippy.toml
================================================
disallowed-names = [
  "..",
  "e", # no single letter error bindings
]
disallowed-methods = [
  { path = "std::cell::RefCell::default()", reason = "prefer explicit inner type default (remove allow-invalid when rust-lang/rust-clippy/#8581 is fixed)", allow-invalid = true },
  { path = "std::rc::Rc::default()", reason = "prefer explicit inner type default (remove allow-invalid when rust-lang/rust-clippy/#8581 is fixed)", allow-invalid = true },
]


================================================
FILE: .codecov.yml
================================================
comment: false

coverage:
  status:
    project:
      default:
        threshold: 100% # make CI green
    patch:
      default:
        threshold: 100% # make CI green

ignore: # ignore code coverage on following paths
  - "**/tests"
  - "**/benches"
  - "**/examples"


================================================
FILE: .cspell.yml
================================================
version: "0.2"
words:
  - actix
  - addrs
  - ALPN
  - bytestring
  - httparse
  - MSRV
  - realip
  - rustls
  - rustup
  - serde
  - uring
  - webpki
  - zstd


================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms

github: [robjtede, JohnTitor]


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug Report
about: Create a bug report.
---

Your issue may already be reported! Please search on the [Actix Web issue tracker](https://github.com/actix/actix-web/issues) before creating one.

## Expected Behavior

<!--- If you're describing a bug, tell us what should happen -->
<!--- If you're suggesting a change/improvement, tell us how it should work -->

## Current Behavior

<!--- If describing a bug, tell us what happens instead of the expected behavior -->
<!--- If suggesting a change/improvement, explain the difference from current behavior -->

## Possible Solution

<!--- Not obligatory, but suggest a fix/reason for the bug, -->
<!--- or ideas how to implement the addition or change -->

## Steps to Reproduce (for bugs)

<!--- Provide a link to a live example, or an unambiguous set of steps to -->
<!--- reproduce this bug. Include code to reproduce, if relevant -->

1.
2.
3.
4.

## Context

<!--- How has this issue affected you? What are you trying to accomplish? -->
<!--- Providing context helps us come up with a solution that is most useful in the real world -->

## Your Environment

<!--- Include as many relevant details about the environment you experienced the bug in -->

- Rust Version (I.e, output of `rustc -V`):
- Actix Web Version:


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: true
contact_links:
  - name: Actix Discord
    url: https://discord.gg/NWpN5mmg3x
    about: Actix developer discussion and community chat
  - name: GitHub Discussions
    url: https://github.com/actix/actix-web/discussions
    about: Actix Web Q&A


================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
<!-- Thanks for considering contributing actix! -->
<!-- Please fill out the following to get your PR reviewed quicker. -->

## PR Type

<!-- What kind of change does this PR make? -->
<!-- Bug Fix / Feature / Refactor / Code Style / Other -->

PR_TYPE

## PR Checklist

<!-- Check your PR fulfills the following items. -->
<!-- For draft PRs check the boxes as you complete them. -->

- [ ] Tests for the changes have been added / updated.
- [ ] Documentation comments have been added / updated.
- [ ] A changelog entry has been made for the appropriate packages.
- [ ] Format code with the latest stable rustfmt.
- [ ] (Team) Label with affected crates and semver status.

## Overview

<!-- Describe the current and new behavior. -->
<!-- Emphasize any breaking changes. -->

<!-- If this PR fixes or closes an issue, reference it here. -->
<!-- Closes #000 -->


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  - package-ecosystem: github-actions
    directory: /
    schedule:
      interval: weekly
  - package-ecosystem: cargo
    directory: /
    schedule:
      interval: weekly
    versioning-strategy: lockfile-only


================================================
FILE: .github/labeler.yml
================================================
A-files:
  - changed-files:
      - any-glob-to-any-file: actix-files/**

A-http:
  - changed-files:
      - any-glob-to-any-file: actix-http/**

A-http-test:
  - changed-files:
      - any-glob-to-any-file: actix-http-test/**

A-multipart:
  - changed-files:
      - any-glob-to-any-file: actix-multipart/**

A-multipart-derive:
  - changed-files:
      - any-glob-to-any-file: actix-multipart-derive/**

A-router:
  - changed-files:
      - any-glob-to-any-file: actix-router/**

A-test:
  - changed-files:
      - any-glob-to-any-file: actix-test/**

A-web:
  - changed-files:
      - any-glob-to-any-file: actix-web/**

A-web-actors:
  - changed-files:
      - any-glob-to-any-file: actix-web-actors/**

A-web-codegen:
  - changed-files:
      - any-glob-to-any-file: actix-web-codegen/**

A-awc:
  - changed-files:
      - any-glob-to-any-file: awc/**


================================================
FILE: .github/workflows/bench.yml
================================================
name: Benchmark

on:
  push:
    branches: [main]

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  check_benchmark:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Install Rust
        run: |
          rustup set profile minimal
          rustup install nightly
          rustup override set nightly

      - name: Check benchmark
        run: cargo bench --bench=server -- --sample-size=15


================================================
FILE: .github/workflows/ci-post-merge.yml
================================================
name: CI (post-merge)

on:
  push:
    branches: [main]

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  build_and_test_nightly:
    strategy:
      fail-fast: false
      matrix:
        # prettier-ignore
        target:
          - { name: Linux, os: ubuntu-latest, triple: x86_64-unknown-linux-gnu }
          - { name: macOS, os: macos-latest, triple: x86_64-apple-darwin }
          - { name: Windows, os: windows-latest, triple: x86_64-pc-windows-msvc }
        version:
          - { name: nightly, version: nightly }

    name: ${{ matrix.target.name }} / ${{ matrix.version.name }}
    runs-on: ${{ matrix.target.os }}

    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Install nasm
        if: matrix.target.os == 'windows-latest'
        uses: ilammy/setup-nasm@72793074d3c8cdda771dba85f6deafe00623038b # v1.5.2

      - name: Install OpenSSL
        if: matrix.target.os == 'windows-latest'
        shell: bash
        run: |
          set -e
          choco install openssl --version=1.1.1.2100 -y --no-progress
          echo 'OPENSSL_DIR=C:\Program Files\OpenSSL' >> $GITHUB_ENV
          echo "RUSTFLAGS=-C target-feature=+crt-static" >> $GITHUB_ENV

      - name: Install Rust (${{ matrix.version.name }})
        uses: actions-rust-lang/setup-rust-toolchain@150fca883cd4034361b621bd4e6a9d34e5143606 # v1.15.4
        with:
          toolchain: ${{ matrix.version.version }}

      - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean
        uses: taiki-e/install-action@f916cfac5d8efd040e250d0cd6b967616504b3a4 # v2.68.32
        with:
          tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean

      - name: check minimal
        run: just check-min

      - name: check default
        run: just check-default

      - name: tests
        timeout-minutes: 60
        run: just test

      - name: CI cache clean
        run: cargo-ci-cache-clean

  ci_feature_powerset_check:
    name: Verify Feature Combinations
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Free Disk Space
        run: ./scripts/free-disk-space.sh

      - name: Setup mold linker
        uses: rui314/setup-mold@725a8794d15fc7563f59595bd9556495c0564878 # v1

      - name: Install Rust
        uses: actions-rust-lang/setup-rust-toolchain@150fca883cd4034361b621bd4e6a9d34e5143606 # v1.15.4

      - name: Install just, cargo-hack
        uses: taiki-e/install-action@f916cfac5d8efd040e250d0cd6b967616504b3a4 # v2.68.32
        with:
          tool: just,cargo-hack

      - name: Check feature combinations
        run: just check-feature-combinations


================================================
FILE: .github/workflows/ci.yml
================================================
name: CI

on:
  pull_request:
    types: [opened, synchronize, reopened]
  merge_group:
    types: [checks_requested]
  push:
    branches: [main]

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  read_msrv:
    name: Read MSRV
    uses: actions-rust-lang/msrv/.github/workflows/msrv.yml@8b553824444060021f2843d7b4d803f3624d15e5 # v0.1.0

  build_and_test:
    needs: read_msrv

    strategy:
      fail-fast: false
      matrix:
        # prettier-ignore
        target:
          - { name: Linux, os: ubuntu-latest, triple: x86_64-unknown-linux-gnu }
          - { name: macOS, os: macos-latest, triple: x86_64-apple-darwin }
          - { name: Windows, os: windows-latest, triple: x86_64-pc-windows-msvc }
        version:
          - { name: msrv, version: "${{ needs.read_msrv.outputs.msrv }}" }
          - { name: stable, version: stable }

    name: ${{ matrix.target.name }} / ${{ matrix.version.name }}
    runs-on: ${{ matrix.target.os }}

    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Install nasm
        if: matrix.target.os == 'windows-latest'
        uses: ilammy/setup-nasm@72793074d3c8cdda771dba85f6deafe00623038b # v1.5.2

      - name: Install OpenSSL
        if: matrix.target.os == 'windows-latest'
        shell: bash
        run: |
          set -e
          choco install openssl --version=1.1.1.2100 -y --no-progress
          echo 'OPENSSL_DIR=C:\Program Files\OpenSSL' >> $GITHUB_ENV
          echo "RUSTFLAGS=-C target-feature=+crt-static" >> $GITHUB_ENV

      - name: Setup mold linker
        if: matrix.target.os == 'ubuntu-latest'
        uses: rui314/setup-mold@725a8794d15fc7563f59595bd9556495c0564878 # v1

      - name: Install Rust (${{ matrix.version.name }})
        uses: actions-rust-lang/setup-rust-toolchain@150fca883cd4034361b621bd4e6a9d34e5143606 # v1.15.4
        with:
          toolchain: ${{ matrix.version.version }}

      - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean
        uses: taiki-e/install-action@f916cfac5d8efd040e250d0cd6b967616504b3a4 # v2.68.32
        with:
          tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean

      - name: workaround MSRV issues
        if: matrix.version.name == 'msrv'
        run: just downgrade-for-msrv

      - name: check minimal
        run: just check-min

      - name: check default
        run: just check-default

      - name: tests
        timeout-minutes: 30
        run: just test

      - name: CI cache clean
        run: cargo-ci-cache-clean

      - name: deny check
        if: matrix.version.name == 'stable' && matrix.target.os == 'ubuntu-latest'
        uses: EmbarkStudios/cargo-deny-action@3fd3802e88374d3fe9159b834c7714ec57d6c979 # v2.0.15

  io-uring:
    name: io-uring tests
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Install Rust
        uses: actions-rust-lang/setup-rust-toolchain@150fca883cd4034361b621bd4e6a9d34e5143606 # v1.15.4
        with:
          toolchain: nightly

      - name: tests (io-uring)
        timeout-minutes: 30
        run: >
          sudo bash -c "ulimit -Sl 512 && ulimit -Hl 512 && PATH=$PATH:/usr/share/rust/.cargo/bin && RUSTUP_TOOLCHAIN=stable cargo test --lib --tests -p=actix-files --all-features"

  rustdoc:
    name: doc tests
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Install Rust (nightly)
        uses: actions-rust-lang/setup-rust-toolchain@150fca883cd4034361b621bd4e6a9d34e5143606 # v1.15.4
        with:
          toolchain: nightly

      - name: Install just
        uses: taiki-e/install-action@f916cfac5d8efd040e250d0cd6b967616504b3a4 # v2.68.32
        with:
          tool: just

      - name: doc tests
        run: just test-docs


================================================
FILE: .github/workflows/coverage.yml
================================================
name: Coverage

on:
  push:
    branches: [main]

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  coverage:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Install Rust (nightly)
        uses: actions-rust-lang/setup-rust-toolchain@150fca883cd4034361b621bd4e6a9d34e5143606 # v1.15.4
        with:
          toolchain: nightly
          components: llvm-tools

      - name: Install just, cargo-llvm-cov, cargo-nextest
        uses: taiki-e/install-action@f916cfac5d8efd040e250d0cd6b967616504b3a4 # v2.68.32
        with:
          tool: just,cargo-llvm-cov,cargo-nextest

      - name: Generate code coverage
        run: just test-coverage-codecov

      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
        with:
          files: codecov.json
          fail_ci_if_error: true
        env:
          CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}


================================================
FILE: .github/workflows/labeler.yml
================================================
name: Labeler

on:
  pull_request_target:
    types: [opened, synchronize, reopened]

permissions:
  contents: read
  pull-requests: write

jobs:
  labeler:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - uses: actions/labeler@634933edcd8ababfe52f92936142cc22ac488b1b # v6.0.1


================================================
FILE: .github/workflows/lint.yml
================================================
name: Lint

on:
  pull_request:
    types: [opened, synchronize, reopened]

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  fmt:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Install Rust (nightly)
        uses: actions-rust-lang/setup-rust-toolchain@150fca883cd4034361b621bd4e6a9d34e5143606 # v1.15.4
        with:
          toolchain: nightly
          components: rustfmt

      - name: Check with Rustfmt
        run: cargo fmt --all -- --check

  clippy:
    permissions:
      contents: read
      checks: write # to add clippy checks to PR diffs

    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Install Rust
        uses: actions-rust-lang/setup-rust-toolchain@150fca883cd4034361b621bd4e6a9d34e5143606 # v1.15.4
        with:
          components: clippy

      - name: Check with Clippy
        uses: giraffate/clippy-action@13b9d32482f25d29ead141b79e7e04e7900281e0 # v1.0.1
        with:
          reporter: github-pr-check
          github_token: ${{ secrets.GITHUB_TOKEN }}
          clippy_flags: >-
            --workspace --all-features --tests --examples --bins --
            -A unknown_lints -D clippy::todo -D clippy::dbg_macro

  lint-docs:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Install Rust (nightly)
        uses: actions-rust-lang/setup-rust-toolchain@150fca883cd4034361b621bd4e6a9d34e5143606 # v1.15.4
        with:
          toolchain: nightly
          components: rust-docs

      - name: Check for broken intra-doc links
        env:
          RUSTDOCFLAGS: -D warnings
        run: cargo +nightly doc --no-deps --workspace --all-features

  check-external-types:
    if: false # rustdoc mismatch currently
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Install Rust (${{ vars.RUST_VERSION_EXTERNAL_TYPES }})
        uses: actions-rust-lang/setup-rust-toolchain@150fca883cd4034361b621bd4e6a9d34e5143606 # v1.15.4
        with:
          toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }}

      - name: Install just
        uses: taiki-e/install-action@f916cfac5d8efd040e250d0cd6b967616504b3a4 # v2.68.32
        with:
          tool: just

      - name: Install cargo-check-external-types
        uses: taiki-e/cache-cargo-install-action@59027ebf20a9617c4e819eb53ccd2673cb162b89 # v3.0.3
        with:
          tool: cargo-check-external-types

      - name: check external types
        run: just check-external-types-all +${{ vars.RUST_VERSION_EXTERNAL_TYPES }}


================================================
FILE: .github/workflows/semver-labeler.yml
================================================
name: Semver Labeler

on:
  workflow_run:
    workflows: [CI]
    types: [completed]

jobs:
  semver-label:
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write
      contents: read
    env:
      ACTIONS_STEP_DEBUG: true
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          ref: ${{ github.event.workflow_run.head_sha }}

      - name: Install Rust
        uses: actions-rust-lang/setup-rust-toolchain@150fca883cd4034361b621bd4e6a9d34e5143606 # v1.15.4
        with:
          toolchain: stable

      - uses: JohnTitor/cargo-semver-checks@3b76737b550e48ad0bd5912e2757e80eee6294b0 # v0.2.1
        with:
          label-prefix: B-semver-
          label-strategy: skip-if-human


================================================
FILE: .gitignore
================================================
target/
guide/build/
/gh-pages

*.so
*.out
*.pyc
*.pid
*.sock
*~
.DS_Store

# These are backup files generated by rustfmt
**/*.rs.bk

# Configuration directory generated by CLion
.idea

# Configuration directory generated by VSCode
.vscode

# code coverage
/lcov.info
/codecov.json


================================================
FILE: .prettierrc.yml
================================================
overrides:
  - files: "*.md"
    options:
      printWidth: 9999
      proseWrap: never


================================================
FILE: .rustfmt.toml
================================================
group_imports = "StdExternalCrate"
imports_granularity = "Crate"
use_field_init_shorthand = true


================================================
FILE: .taplo.toml
================================================
exclude = ["target/*"]
include = ["**/*.toml"]

[formatting]
column_width = 100
align_comments = false

[[rule]]
include = ["**/Cargo.toml"]
keys = ["features"]
formatting.column_width = 105
formatting.reorder_keys = false

[[rule]]
include = ["**/Cargo.toml"]
keys = [
  "dependencies",
  "*-dependencies",
  "workspace.dependencies",
  "workspace.*-dependencies",
  "target.*.dependencies",
  "target.*.*-dependencies",
]
formatting.column_width = 120
formatting.reorder_keys = true

[[rule]]
include = ["**/Cargo.toml"]
keys = [
  "dependencies.*",
  "*-dependencies.*",
  "workspace.dependencies.*",
  "workspace.*-dependencies.*",
  "target.*.dependencies",
  "target.*.*-dependencies",
]
formatting.column_width = 120
formatting.reorder_keys = false


================================================
FILE: CHANGES.md
================================================
# Changelog

Changelogs are kept separately for each crate in this repo.

Actix Web changelog [is now here &rarr;](./actix-web/CHANGES.md).


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment include:

- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

- The use of sexualized language or imagery and unwelcome sexual attention or advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at robjtede@icloud.com ([@robjtede]) or huyuumi@neet.club ([@JohnTitor]). The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

[@robjtede]: https://github.com/robjtede
[@JohnTitor]: https://github.com/JohnTitor

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]

[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/


================================================
FILE: Cargo.toml
================================================
[workspace]
resolver = "2"
members = [
  "actix-files",
  "actix-http-test",
  "actix-http",
  "actix-multipart",
  "actix-multipart-derive",
  "actix-router",
  "actix-test",
  "actix-web-codegen",
  "actix-web",
  "awc",
]

[workspace.package]
homepage = "https://actix.rs"
repository = "https://github.com/actix/actix-web"
license = "MIT OR Apache-2.0"
edition = "2021"
rust-version = "1.88"

[profile.dev]
# Disabling debug info speeds up builds a bunch and we don't rely on it for debugging that much.
debug = 0

[profile.release]
lto = true
opt-level = 3
codegen-units = 1

[patch.crates-io]
actix-files = { path = "actix-files" }
actix-http = { path = "actix-http" }
actix-http-test = { path = "actix-http-test" }
actix-multipart = { path = "actix-multipart" }
actix-multipart-derive = { path = "actix-multipart-derive" }
actix-router = { path = "actix-router" }
actix-test = { path = "actix-test" }
actix-web = { path = "actix-web" }
actix-web-codegen = { path = "actix-web-codegen" }
awc = { path = "awc" }

# uncomment for quick testing against local actix-net repo
# actix-service = { path = "../actix-net/actix-service" }
# actix-macros = { path = "../actix-net/actix-macros" }
# actix-rt = { path = "../actix-net/actix-rt" }
# actix-codec = { path = "../actix-net/actix-codec" }
# actix-utils = { path = "../actix-net/actix-utils" }
# actix-tls = { path = "../actix-net/actix-tls" }
# actix-server = { path = "../actix-net/actix-server" }

[workspace.lints.rust]
rust_2018_idioms = { level = "deny" }
future_incompatible = { level = "deny" }
nonstandard_style = { level = "deny" }

[workspace.lints.clippy]
# clone_on_ref_ptr = { level = "deny" }


================================================
FILE: LICENSE-APACHE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "{}"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright 2017-NOW Actix Team

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: LICENSE-MIT
================================================
Copyright (c) 2017-NOW Actix Team

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: actix-files/CHANGES.md
================================================
# Changes

## Unreleased

- Add `Files::try_compressed()` to support serving pre-compressed static files [#2615]
- Fix handling of `bytes=0-`
- Fix `NamedFile` panic when serving files with pre-UNIX epoch modification times. [#2748]
- Fix invalid `Content-Encoding: identity` header in `NamedFile` range responses. [#3191]

[#2615]: https://github.com/actix/actix-web/pull/2615
[#2748]: https://github.com/actix/actix-web/issues/2748
[#3191]: https://github.com/actix/actix-web/issues/3191

## 0.6.10

### Security Notice

We addressed 2 vulnerabilities in this release:

- Do not panic with empty Range header.
- Avoid serving CWD on invalid `Files::new` inputs.

We encourage updating your `actix-files` version as soon as possible.

### Other changes

- Minimum supported Rust version (MSRV) is now 1.88.
- `PathBufWrap` & `UriSegmentError` made public. [#3694]

[#3694]: https://github.com/actix/actix-web/pull/3694

## 0.6.9

- Correct `derive_more` dependency feature requirements.

## 0.6.8

- Add `Files::with_permanent_redirect()` method.
- Change default redirect status code to 307 Temporary Redirect.

## 0.6.7

- Add `{Files, NamedFile}::read_mode_threshold()` methods to allow faster synchronous reads of small files.
- Minimum supported Rust version (MSRV) is now 1.75.

## 0.6.6

- Update `tokio-uring` dependency to `0.4`.
- Minimum supported Rust version (MSRV) is now 1.72.

## 0.6.5

- Fix handling of special characters in filenames.

## 0.6.4

- Fix handling of newlines in filenames.
- Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency.

## 0.6.3

- XHTML files now use `Content-Disposition: inline` instead of `attachment`. [#2903]
- Minimum supported Rust version (MSRV) is now 1.59 due to transitive `time` dependency.
- Update `tokio-uring` dependency to `0.4`.

[#2903]: https://github.com/actix/actix-web/pull/2903

## 0.6.2

- Allow partial range responses for video content to start streaming sooner. [#2817]
- Minimum supported Rust version (MSRV) is now 1.57 due to transitive `time` dependency.

[#2817]: https://github.com/actix/actix-web/pull/2817

## 0.6.1

- Add `NamedFile::{modified, metadata, content_type, content_disposition, encoding}()` getters. [#2021]
- Update `tokio-uring` dependency to `0.3`.
- Audio files now use `Content-Disposition: inline` instead of `attachment`. [#2645]
- Minimum supported Rust version (MSRV) is now 1.56 due to transitive `hashbrown` dependency.

[#2021]: https://github.com/actix/actix-web/pull/2021
[#2645]: https://github.com/actix/actix-web/pull/2645

## 0.6.0

- No significant changes since `0.6.0-beta.16`.

## 0.6.0-beta.16

- No significant changes since `0.6.0-beta.15`.

## 0.6.0-beta.15

- No significant changes since `0.6.0-beta.14`.

## 0.6.0-beta.14

- The `prefer_utf8` option introduced in `0.4.0` is now true by default. [#2583]

[#2583]: https://github.com/actix/actix-web/pull/2583

## 0.6.0-beta.13

- The `Files` service now rejects requests with URL paths that include `%2F` (decoded: `/`). [#2398]
- The `Files` service now correctly decodes `%25` in the URL path to `%` for the file path. [#2398]
- Minimum supported Rust version (MSRV) is now 1.54.

[#2398]: https://github.com/actix/actix-web/pull/2398

## 0.6.0-beta.12

- No significant changes since `0.6.0-beta.11`.

## 0.6.0-beta.11

- No significant changes since `0.6.0-beta.10`.

## 0.6.0-beta.10

- No significant changes since `0.6.0-beta.9`.

## 0.6.0-beta.9

- Add crate feature `experimental-io-uring`, enabling async file I/O to be utilized. This feature is only available on Linux OSes with recent kernel versions. This feature is semver-exempt. [#2408]
- Add `NamedFile::open_async`. [#2408]
- Fix 304 Not Modified responses to omit the Content-Length header, as per the spec. [#2453]
- The `Responder` impl for `NamedFile` now has a boxed future associated type. [#2408]
- The `Service` impl for `NamedFileService` now has a boxed future associated type. [#2408]
- Add `impl Clone` for `FilesService`. [#2408]

[#2408]: https://github.com/actix/actix-web/pull/2408
[#2453]: https://github.com/actix/actix-web/pull/2453

## 0.6.0-beta.8

- Minimum supported Rust version (MSRV) is now 1.52.

## 0.6.0-beta.7

- Minimum supported Rust version (MSRV) is now 1.51.

## 0.6.0-beta.6

- Added `Files::path_filter()`. [#2274]
- `Files::show_files_listing()` can now be used with `Files::index_file()` to show files listing as a fallback when the index file is not found. [#2228]

[#2274]: https://github.com/actix/actix-web/pull/2274
[#2228]: https://github.com/actix/actix-web/pull/2228

## 0.6.0-beta.5

- `NamedFile` now implements `ServiceFactory` and `HttpServiceFactory` making it much more useful in routing. For example, it can be used directly as a default service. [#2135]
- For symbolic links, `Content-Disposition` header no longer shows the filename of the original file. [#2156]
- `Files::redirect_to_slash_directory()` now works as expected when used with `Files::show_files_listing()`. [#2225]
- `application/{javascript, json, wasm}` mime type now have `inline` disposition by default. [#2257]

[#2135]: https://github.com/actix/actix-web/pull/2135
[#2156]: https://github.com/actix/actix-web/pull/2156
[#2225]: https://github.com/actix/actix-web/pull/2225
[#2257]: https://github.com/actix/actix-web/pull/2257

## 0.6.0-beta.4

- Add support for `.guard` in `Files` to selectively filter `Files` services. [#2046]

[#2046]: https://github.com/actix/actix-web/pull/2046

## 0.6.0-beta.3

- No notable changes.

## 0.6.0-beta.2

- Fix If-Modified-Since and If-Unmodified-Since to not compare using sub-second timestamps. [#1887]
- Replace `v_htmlescape` with `askama_escape`. [#1953]

[#1887]: https://github.com/actix/actix-web/pull/1887
[#1953]: https://github.com/actix/actix-web/pull/1953

## 0.6.0-beta.1

- `HttpRange::parse` now has its own error type.
- Update `bytes` to `1.0`. [#1813]

[#1813]: https://github.com/actix/actix-web/pull/1813

## 0.5.0

- Optionally support hidden files/directories. [#1811]

[#1811]: https://github.com/actix/actix-web/pull/1811

## 0.4.1

- Clarify order of parameters in `Files::new` and improve docs.

## 0.4.0

- Add `Files::prefer_utf8` option that adds UTF-8 charset on certain response types. [#1714]

[#1714]: https://github.com/actix/actix-web/pull/1714

## 0.3.0

- No significant changes from 0.3.0-beta.1.

## 0.3.0-beta.1

- Update `v_htmlescape` to 0.10
- Update `actix-web` and `actix-http` dependencies to beta.1

## 0.3.0-alpha.1

- Update `actix-web` and `actix-http` dependencies to alpha
- Fix some typos in the docs
- Bump minimum supported Rust version to 1.40
- Support sending Content-Length when Content-Range is specified [#1384]

[#1384]: https://github.com/actix/actix-web/pull/1384

## 0.2.1

- Use the same format for file URLs regardless of platforms

## 0.2.0

- Fix BodyEncoding trait import #1220

## 0.2.0-alpha.1

- Migrate to `std::future`

## 0.1.7

- Add an additional `filename*` param in the `Content-Disposition` header of `actix_files::NamedFile` to be more compatible. (#1151)

## 0.1.6

- Add option to redirect to a slash-ended path `Files` #1132

## 0.1.5

- Bump up `mime_guess` crate version to 2.0.1
- Bump up `percent-encoding` crate version to 2.1
- Allow user defined request guards for `Files` #1113

## 0.1.4

- Allow to disable `Content-Disposition` header #686

## 0.1.3

- Do not set `Content-Length` header, let actix-http set it #930

## 0.1.2

- Content-Length is 0 for NamedFile HEAD request #914
- Fix ring dependency from actix-web default features for #741

## 0.1.1

- Static files are incorrectly served as both chunked and with length #812

## 0.1.0

- NamedFile last-modified check always fails due to nano-seconds in file modified date #820

## 0.1.0-beta.4

- Update actix-web to beta.4

## 0.1.0-beta.1

- Update actix-web to beta.1

## 0.1.0-alpha.6

- Update actix-web to alpha6

## 0.1.0-alpha.4

- Update actix-web to alpha4

## 0.1.0-alpha.2

- Add default handler support

## 0.1.0-alpha.1

- Initial impl


================================================
FILE: actix-files/Cargo.toml
================================================
[package]
name = "actix-files"
version = "0.6.10"
authors = ["Nikolay Kim <fafhrd91@gmail.com>", "Rob Ede <robjtede@icloud.com>"]
description = "Static file serving for Actix Web"
keywords = ["actix", "http", "async", "futures"]
homepage = "https://actix.rs"
repository = "https://github.com/actix/actix-web"
categories = ["asynchronous", "web-programming::http-server"]
license = "MIT OR Apache-2.0"
edition = "2021"

[package.metadata.cargo_check_external_types]
allowed_external_types = ["actix_http::*", "actix_service::*", "actix_web::*", "http::*", "mime::*"]

[features]
experimental-io-uring = ["actix-web/experimental-io-uring", "tokio-uring"]

[dependencies]
actix-http = "3"
actix-service = "2"
actix-utils = "3"
actix-web = { version = "4", default-features = false }

bitflags = "2"
bytes = "1"
derive_more = { version = "2", features = ["deref", "deref_mut", "display", "error", "from"] }
futures-core = { version = "0.3.17", default-features = false, features = ["alloc"] }
http-range = "0.1.4"
log = "0.4"
mime = "0.3.9"
mime_guess = "2.0.1"
percent-encoding = "2.1"
pin-project-lite = "0.2.7"
v_htmlescape = "0.15.5"

# experimental-io-uring
[target.'cfg(target_os = "linux")'.dependencies]
tokio-uring = { version = "0.5", optional = true, features = ["bytes"] }
actix-server = { version = "2.4", optional = true } # ensure matching tokio-uring versions

[dev-dependencies]
actix-rt = "2.7"
actix-test = "0.1"
actix-web = "4"
env_logger = "0.11"
filetime = "0.2"
tempfile = "3.2"

[lints]
workspace = true


================================================
FILE: actix-files/README.md
================================================
# `actix-files`

<!-- prettier-ignore-start -->

[![crates.io](https://img.shields.io/crates/v/actix-files?label=latest)](https://crates.io/crates/actix-files)
[![Documentation](https://docs.rs/actix-files/badge.svg?version=0.6.9)](https://docs.rs/actix-files/0.6.9)
![Version](https://img.shields.io/badge/rustc-1.88+-ab6000.svg)
![License](https://img.shields.io/crates/l/actix-files.svg)
<br />
[![dependency status](https://deps.rs/crate/actix-files/0.6.9/status.svg)](https://deps.rs/crate/actix-files/0.6.9)
[![Download](https://img.shields.io/crates/d/actix-files.svg)](https://crates.io/crates/actix-files)
[![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x)

<!-- prettier-ignore-end -->

<!-- cargo-rdme start -->

Static file serving for Actix Web.

Provides a non-blocking service for serving static files from disk.

## Examples

```rust
use actix_web::App;
use actix_files::Files;

let app = App::new()
    .service(Files::new("/static", ".").prefer_utf8(true));
```

<!-- cargo-rdme end -->


================================================
FILE: actix-files/examples/guarded-listing.rs
================================================
use actix_files::Files;
use actix_web::{get, guard, middleware, App, HttpServer, Responder};

const EXAMPLES_DIR: &str = concat![env!("CARGO_MANIFEST_DIR"), "/examples"];

#[get("/")]
async fn index() -> impl Responder {
    "Hello world!"
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));

    log::info!("starting HTTP server at http://localhost:8080");

    HttpServer::new(|| {
        App::new()
            .service(index)
            .service(
                Files::new("/assets", EXAMPLES_DIR)
                    .show_files_listing()
                    .guard(guard::Header("show-listing", "?1")),
            )
            .service(Files::new("/assets", EXAMPLES_DIR))
            .wrap(middleware::Compress::default())
            .wrap(middleware::Logger::default())
    })
    .bind(("127.0.0.1", 8080))?
    .workers(2)
    .run()
    .await
}


================================================
FILE: actix-files/src/chunked.rs
================================================
use std::{
    cmp, fmt,
    future::Future,
    io,
    pin::Pin,
    task::{Context, Poll},
};

use actix_web::{error::Error, web::Bytes};
#[cfg(feature = "experimental-io-uring")]
use bytes::BytesMut;
use futures_core::{ready, Stream};
use pin_project_lite::pin_project;

use super::named::File;

#[derive(Debug, Clone, Copy)]
pub(crate) enum ReadMode {
    Sync,
    Async,
}

pin_project! {
    /// Adapter to read a `std::file::File` in chunks.
    #[doc(hidden)]
    pub struct ChunkedReadFile<F, Fut> {
        size: u64,
        offset: u64,
        #[pin]
        state: ChunkedReadFileState<Fut>,
        counter: u64,
        callback: F,
        read_mode: ReadMode,
    }
}

#[cfg(not(feature = "experimental-io-uring"))]
pin_project! {
    #[project = ChunkedReadFileStateProj]
    #[project_replace = ChunkedReadFileStateProjReplace]
    enum ChunkedReadFileState<Fut> {
        File { file: Option<File>, },
        Future { #[pin] fut: Fut },
    }
}

#[cfg(feature = "experimental-io-uring")]
pin_project! {
    #[project = ChunkedReadFileStateProj]
    #[project_replace = ChunkedReadFileStateProjReplace]
    enum ChunkedReadFileState<Fut> {
        File { file: Option<(File, BytesMut)> },
        Future { #[pin] fut: Fut },
    }
}

impl<F, Fut> fmt::Debug for ChunkedReadFile<F, Fut> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str("ChunkedReadFile")
    }
}

pub(crate) fn new_chunked_read(
    size: u64,
    offset: u64,
    file: File,
    read_mode_threshold: u64,
) -> impl Stream<Item = Result<Bytes, Error>> {
    ChunkedReadFile {
        size,
        offset,
        #[cfg(not(feature = "experimental-io-uring"))]
        state: ChunkedReadFileState::File { file: Some(file) },
        #[cfg(feature = "experimental-io-uring")]
        state: ChunkedReadFileState::File {
            file: Some((file, BytesMut::new())),
        },
        counter: 0,
        callback: chunked_read_file_callback,
        read_mode: if size < read_mode_threshold {
            ReadMode::Sync
        } else {
            ReadMode::Async
        },
    }
}

#[cfg(not(feature = "experimental-io-uring"))]
fn chunked_read_file_callback_sync(
    mut file: File,
    offset: u64,
    max_bytes: usize,
) -> Result<(File, Bytes), io::Error> {
    use io::{Read as _, Seek as _};

    let mut buf = Vec::with_capacity(max_bytes);

    file.seek(io::SeekFrom::Start(offset))?;

    let n_bytes = file.by_ref().take(max_bytes as u64).read_to_end(&mut buf)?;

    if n_bytes == 0 {
        Err(io::Error::from(io::ErrorKind::UnexpectedEof))
    } else {
        Ok((file, Bytes::from(buf)))
    }
}

#[cfg(not(feature = "experimental-io-uring"))]
#[inline]
async fn chunked_read_file_callback(
    file: File,
    offset: u64,
    max_bytes: usize,
    read_mode: ReadMode,
) -> Result<(File, Bytes), Error> {
    let res = match read_mode {
        ReadMode::Sync => chunked_read_file_callback_sync(file, offset, max_bytes)?,
        ReadMode::Async => {
            actix_web::web::block(move || chunked_read_file_callback_sync(file, offset, max_bytes))
                .await??
        }
    };

    Ok(res)
}

#[cfg(feature = "experimental-io-uring")]
async fn chunked_read_file_callback(
    file: File,
    offset: u64,
    max_bytes: usize,
    mut bytes_mut: BytesMut,
) -> io::Result<(File, Bytes, BytesMut)> {
    bytes_mut.reserve(max_bytes);

    let (res, mut bytes_mut) = file.read_at(bytes_mut, offset).await;
    let n_bytes = res?;

    if n_bytes == 0 {
        return Err(io::ErrorKind::UnexpectedEof.into());
    }

    let bytes = bytes_mut.split_to(n_bytes).freeze();

    Ok((file, bytes, bytes_mut))
}

#[cfg(feature = "experimental-io-uring")]
impl<F, Fut> Stream for ChunkedReadFile<F, Fut>
where
    F: Fn(File, u64, usize, BytesMut) -> Fut,
    Fut: Future<Output = io::Result<(File, Bytes, BytesMut)>>,
{
    type Item = Result<Bytes, Error>;

    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
        let mut this = self.as_mut().project();
        match this.state.as_mut().project() {
            ChunkedReadFileStateProj::File { file } => {
                let size = *this.size;
                let offset = *this.offset;
                let counter = *this.counter;

                if size == counter {
                    Poll::Ready(None)
                } else {
                    let max_bytes = cmp::min(size.saturating_sub(counter), 65_536) as usize;

                    let (file, bytes_mut) = file
                        .take()
                        .expect("ChunkedReadFile polled after completion");

                    let fut = (this.callback)(file, offset, max_bytes, bytes_mut);

                    this.state
                        .project_replace(ChunkedReadFileState::Future { fut });

                    self.poll_next(cx)
                }
            }
            ChunkedReadFileStateProj::Future { fut } => {
                let (file, bytes, bytes_mut) = ready!(fut.poll(cx))?;

                this.state.project_replace(ChunkedReadFileState::File {
                    file: Some((file, bytes_mut)),
                });

                *this.offset += bytes.len() as u64;
                *this.counter += bytes.len() as u64;

                Poll::Ready(Some(Ok(bytes)))
            }
        }
    }
}

#[cfg(not(feature = "experimental-io-uring"))]
impl<F, Fut> Stream for ChunkedReadFile<F, Fut>
where
    F: Fn(File, u64, usize, ReadMode) -> Fut,
    Fut: Future<Output = Result<(File, Bytes), Error>>,
{
    type Item = Result<Bytes, Error>;

    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
        let mut this = self.as_mut().project();
        match this.state.as_mut().project() {
            ChunkedReadFileStateProj::File { file } => {
                let size = *this.size;
                let offset = *this.offset;
                let counter = *this.counter;

                if size == counter {
                    Poll::Ready(None)
                } else {
                    let max_bytes = cmp::min(size.saturating_sub(counter), 65_536) as usize;

                    let file = file
                        .take()
                        .expect("ChunkedReadFile polled after completion");

                    let fut = (this.callback)(file, offset, max_bytes, *this.read_mode);

                    this.state
                        .project_replace(ChunkedReadFileState::Future { fut });

                    self.poll_next(cx)
                }
            }
            ChunkedReadFileStateProj::Future { fut } => {
                let (file, bytes) = ready!(fut.poll(cx))?;

                this.state
                    .project_replace(ChunkedReadFileState::File { file: Some(file) });

                *this.offset += bytes.len() as u64;
                *this.counter += bytes.len() as u64;

                Poll::Ready(Some(Ok(bytes)))
            }
        }
    }
}


================================================
FILE: actix-files/src/directory.rs
================================================
use std::{
    fmt::Write,
    fs::DirEntry,
    io,
    path::{Path, PathBuf},
};

use actix_web::{dev::ServiceResponse, HttpRequest, HttpResponse};
use percent_encoding::{utf8_percent_encode, CONTROLS};
use v_htmlescape::escape as escape_html_entity;

/// A directory; responds with the generated directory listing.
#[derive(Debug)]
pub struct Directory {
    /// Base directory.
    pub base: PathBuf,

    /// Path of subdirectory to generate listing for.
    pub path: PathBuf,
}

impl Directory {
    /// Create a new directory
    pub fn new(base: PathBuf, path: PathBuf) -> Directory {
        Directory { base, path }
    }

    /// Is this entry visible from this directory?
    pub fn is_visible(&self, entry: &io::Result<DirEntry>) -> bool {
        if let Ok(ref entry) = *entry {
            if let Some(name) = entry.file_name().to_str() {
                if name.starts_with('.') {
                    return false;
                }
            }
            if let Ok(ref md) = entry.metadata() {
                let ft = md.file_type();
                return ft.is_dir() || ft.is_file() || ft.is_symlink();
            }
        }
        false
    }
}

pub(crate) type DirectoryRenderer =
    dyn Fn(&Directory, &HttpRequest) -> Result<ServiceResponse, io::Error>;

/// Returns percent encoded file URL path.
macro_rules! encode_file_url {
    ($path:ident) => {
        utf8_percent_encode(&$path, CONTROLS)
    };
}

/// Returns HTML entity encoded formatter.
///
/// ```plain
/// " => &quot;
/// & => &amp;
/// ' => &#x27;
/// < => &lt;
/// > => &gt;
/// / => &#x2f;
/// ```
macro_rules! encode_file_name {
    ($entry:ident) => {
        escape_html_entity(&$entry.file_name().to_string_lossy())
    };
}

pub(crate) fn directory_listing(
    dir: &Directory,
    req: &HttpRequest,
) -> Result<ServiceResponse, io::Error> {
    let index_of = format!("Index of {}", req.path());
    let mut body = String::new();
    let base = Path::new(req.path());

    for entry in dir.path.read_dir()? {
        if dir.is_visible(&entry) {
            let entry = entry.unwrap();
            let p = match entry.path().strip_prefix(&dir.path) {
                Ok(p) if cfg!(windows) => base.join(p).to_string_lossy().replace('\\', "/"),
                Ok(p) => base.join(p).to_string_lossy().into_owned(),
                Err(_) => continue,
            };

            // if file is a directory, add '/' to the end of the name
            if let Ok(metadata) = entry.metadata() {
                if metadata.is_dir() {
                    let _ = write!(
                        body,
                        "<li><a href=\"{}\">{}/</a></li>",
                        encode_file_url!(p),
                        encode_file_name!(entry),
                    );
                } else {
                    let _ = write!(
                        body,
                        "<li><a href=\"{}\">{}</a></li>",
                        encode_file_url!(p),
                        encode_file_name!(entry),
                    );
                }
            } else {
                continue;
            }
        }
    }

    let html = format!(
        "<html>\
         <head><title>{}</title></head>\
         <body><h1>{}</h1>\
         <ul>\
         {}\
         </ul></body>\n</html>",
        index_of, index_of, body
    );
    Ok(ServiceResponse::new(
        req.clone(),
        HttpResponse::Ok()
            .content_type("text/html; charset=utf-8")
            .body(html),
    ))
}


================================================
FILE: actix-files/src/encoding.rs
================================================
use mime::Mime;

/// Transforms MIME `text/*` types into their UTF-8 equivalent, if supported.
///
/// MIME types that are converted
/// - application/javascript
/// - text/html
/// - text/css
/// - text/plain
/// - text/csv
/// - text/tab-separated-values
pub(crate) fn equiv_utf8_text(ct: Mime) -> Mime {
    // use (roughly) order of file-type popularity for a web server

    if ct == mime::APPLICATION_JAVASCRIPT {
        return mime::APPLICATION_JAVASCRIPT_UTF_8;
    }

    if ct == mime::TEXT_HTML {
        return mime::TEXT_HTML_UTF_8;
    }

    if ct == mime::TEXT_CSS {
        return mime::TEXT_CSS_UTF_8;
    }

    if ct == mime::TEXT_PLAIN {
        return mime::TEXT_PLAIN_UTF_8;
    }

    if ct == mime::TEXT_CSV {
        return mime::TEXT_CSV_UTF_8;
    }

    if ct == mime::TEXT_TAB_SEPARATED_VALUES {
        return mime::TEXT_TAB_SEPARATED_VALUES_UTF_8;
    }

    ct
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_equiv_utf8_text() {
        assert_eq!(equiv_utf8_text(mime::TEXT_PLAIN), mime::TEXT_PLAIN_UTF_8);
        assert_eq!(equiv_utf8_text(mime::TEXT_XML), mime::TEXT_XML);
        assert_eq!(equiv_utf8_text(mime::IMAGE_PNG), mime::IMAGE_PNG);
    }
}


================================================
FILE: actix-files/src/error.rs
================================================
use actix_web::{http::StatusCode, ResponseError};
use derive_more::Display;

/// Errors which can occur when serving static files.
#[derive(Debug, PartialEq, Eq, Display)]
pub enum FilesError {
    /// Path is not a directory.
    #[allow(dead_code)]
    #[display("path is not a directory. Unable to serve static files")]
    IsNotDirectory,

    /// Cannot render directory.
    #[display("unable to render directory without index file")]
    IsDirectory,
}

impl ResponseError for FilesError {
    /// Returns `404 Not Found`.
    fn status_code(&self) -> StatusCode {
        StatusCode::NOT_FOUND
    }
}

/// Error which can occur with parsing/validating a request-uri path
#[derive(Debug, PartialEq, Eq, Display)]
#[non_exhaustive]
pub enum UriSegmentError {
    /// Segment started with the wrapped invalid character.
    #[display("segment started with invalid character: ('{_0}')")]
    BadStart(char),

    /// Segment contained the wrapped invalid character.
    #[display("segment contained invalid character ('{_0}')")]
    BadChar(char),

    /// Segment ended with the wrapped invalid character.
    #[display("segment ended with invalid character: ('{_0}')")]
    BadEnd(char),

    /// Path is not a valid UTF-8 string after percent-decoding.
    #[display("path is not a valid UTF-8 string after percent-decoding")]
    NotValidUtf8,
}

impl ResponseError for UriSegmentError {
    /// Returns `400 Bad Request`.
    fn status_code(&self) -> StatusCode {
        StatusCode::BAD_REQUEST
    }
}


================================================
FILE: actix-files/src/files.rs
================================================
use std::{
    cell::RefCell,
    fmt, io,
    path::{Path, PathBuf},
    rc::Rc,
};

use actix_service::{boxed, IntoServiceFactory, ServiceFactory, ServiceFactoryExt};
use actix_web::{
    dev::{
        AppService, HttpServiceFactory, RequestHead, ResourceDef, ServiceRequest, ServiceResponse,
    },
    error::Error,
    guard::Guard,
    http::header::DispositionType,
    HttpRequest,
};
use futures_core::future::LocalBoxFuture;

use crate::{
    directory_listing, named,
    service::{FilesService, FilesServiceInner},
    Directory, DirectoryRenderer, HttpNewService, MimeOverride, PathFilter,
};

/// Static files handling service.
///
/// `Files` service must be registered with `App::service()` method.
///
/// # Examples
/// ```
/// use actix_web::App;
/// use actix_files::Files;
///
/// let app = App::new()
///     .service(Files::new("/static", "."));
/// ```
pub struct Files {
    mount_path: String,
    directory: PathBuf,
    index: Option<String>,
    show_index: bool,
    redirect_to_slash: bool,
    with_permanent_redirect: bool,
    default: Rc<RefCell<Option<Rc<HttpNewService>>>>,
    renderer: Rc<DirectoryRenderer>,
    mime_override: Option<Rc<MimeOverride>>,
    path_filter: Option<Rc<PathFilter>>,
    file_flags: named::Flags,
    use_guards: Option<Rc<dyn Guard>>,
    guards: Vec<Rc<dyn Guard>>,
    hidden_files: bool,
    try_compressed: bool,
    read_mode_threshold: u64,
}

impl fmt::Debug for Files {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str("Files")
    }
}

impl Clone for Files {
    fn clone(&self) -> Self {
        Self {
            directory: self.directory.clone(),
            index: self.index.clone(),
            show_index: self.show_index,
            redirect_to_slash: self.redirect_to_slash,
            with_permanent_redirect: self.with_permanent_redirect,
            default: self.default.clone(),
            renderer: self.renderer.clone(),
            file_flags: self.file_flags,
            mount_path: self.mount_path.clone(),
            mime_override: self.mime_override.clone(),
            path_filter: self.path_filter.clone(),
            use_guards: self.use_guards.clone(),
            guards: self.guards.clone(),
            hidden_files: self.hidden_files,
            try_compressed: self.try_compressed,
            read_mode_threshold: self.read_mode_threshold,
        }
    }
}

impl Files {
    /// Create new `Files` instance for a specified base directory.
    ///
    /// # Argument Order
    /// The first argument (`mount_path`) is the root URL at which the static files are served.
    /// For example, `/assets` will serve files at `example.com/assets/...`.
    ///
    /// The second argument (`serve_from`) is the location on disk at which files are loaded.
    /// This can be a relative path. For example, `./` would serve files from the current
    /// working directory.
    ///
    /// # Implementation Notes
    /// If the mount path is set as the root path `/`, services registered after this one will
    /// be inaccessible. Register more specific handlers and services first.
    ///
    /// If `serve_from` cannot be canonicalized at startup, an error is logged and the original
    /// path is preserved. Requests will return `404 Not Found` until the path exists.
    ///
    /// `Files` utilizes the existing Tokio thread-pool for blocking filesystem operations.
    /// The number of running threads is adjusted over time as needed, up to a maximum of 512 times
    /// the number of server [workers](actix_web::HttpServer::workers), by default.
    pub fn new<T: Into<PathBuf>>(mount_path: &str, serve_from: T) -> Files {
        let orig_dir = serve_from.into();
        let dir = match orig_dir.canonicalize() {
            Ok(canon_dir) => canon_dir,
            Err(_) => {
                log::error!("Specified path is not a directory: {:?}", orig_dir);
                // Preserve original path so requests don't fall back to CWD.
                orig_dir
            }
        };

        Files {
            mount_path: mount_path.trim_end_matches('/').to_owned(),
            directory: dir,
            index: None,
            show_index: false,
            redirect_to_slash: false,
            with_permanent_redirect: false,
            default: Rc::new(RefCell::new(None)),
            renderer: Rc::new(directory_listing),
            mime_override: None,
            path_filter: None,
            file_flags: named::Flags::default(),
            use_guards: None,
            guards: Vec::new(),
            hidden_files: false,
            try_compressed: false,
            read_mode_threshold: 0,
        }
    }

    /// Show files listing for directories.
    ///
    /// By default show files listing is disabled.
    ///
    /// When used with [`Files::index_file()`], files listing is shown as a fallback
    /// when the index file is not found.
    pub fn show_files_listing(mut self) -> Self {
        self.show_index = true;
        self
    }

    /// Redirects to a slash-ended path when browsing a directory.
    ///
    /// By default never redirect.
    pub fn redirect_to_slash_directory(mut self) -> Self {
        self.redirect_to_slash = true;
        self
    }

    /// Redirect with permanent redirect status code (308).
    ///
    /// By default redirect with temporary redirect status code (307).
    pub fn with_permanent_redirect(mut self) -> Self {
        self.with_permanent_redirect = true;
        self
    }

    /// Set custom directory renderer.
    pub fn files_listing_renderer<F>(mut self, f: F) -> Self
    where
        for<'r, 's> F:
            Fn(&'r Directory, &'s HttpRequest) -> Result<ServiceResponse, io::Error> + 'static,
    {
        self.renderer = Rc::new(f);
        self
    }

    /// Specifies MIME override callback.
    pub fn mime_override<F>(mut self, f: F) -> Self
    where
        F: Fn(&mime::Name<'_>) -> DispositionType + 'static,
    {
        self.mime_override = Some(Rc::new(f));
        self
    }

    /// Sets path filtering closure.
    ///
    /// The path provided to the closure is relative to `serve_from` path.
    /// You can safely join this path with the `serve_from` path to get the real path.
    /// However, the real path may not exist since the filter is called before checking path existence.
    ///
    /// When a path doesn't pass the filter, [`Files::default_handler`] is called if set, otherwise,
    /// `404 Not Found` is returned.
    ///
    /// # Examples
    /// ```
    /// use std::path::Path;
    /// use actix_files::Files;
    ///
    /// // prevent searching subdirectories and following symlinks
    /// let files_service = Files::new("/", "./static").path_filter(|path, _| {
    ///     path.components().count() == 1
    ///         && Path::new("./static")
    ///             .join(path)
    ///             .symlink_metadata()
    ///             .map(|m| !m.file_type().is_symlink())
    ///             .unwrap_or(false)
    /// });
    /// ```
    pub fn path_filter<F>(mut self, f: F) -> Self
    where
        F: Fn(&Path, &RequestHead) -> bool + 'static,
    {
        self.path_filter = Some(Rc::new(f));
        self
    }

    /// Sets index file for directory requests.
    ///
    /// When a directory is requested, this value is appended to the directory's path on disk.
    /// Therefore, the index file path is relative to the served directory (the `serve_from` path
    /// passed to [`Files::new`]) and should not include the `serve_from` prefix.
    ///
    /// For example, to serve `./static/index.html` when mounting `Files::new("/", "./static")`,
    /// configure it as `.index_file("index.html")` (not `.index_file("./static/index.html")`).
    ///
    /// If the index file is not found, files listing is shown as a fallback if
    /// [`Files::show_files_listing()`] is set.
    pub fn index_file<T: Into<String>>(mut self, index: T) -> Self {
        self.index = Some(index.into());
        self
    }

    /// Sets the size threshold that determines file read mode (sync/async).
    ///
    /// When a file is smaller than the threshold (bytes), the reader will use synchronous
    /// (blocking) file reads. For larger files, it switches to async reads to avoid blocking the
    /// main thread.
    ///
    /// Tweaking this value according to your expected usage may lead to significant performance
    /// gains (or losses in other handlers, if `size` is too high).
    ///
    /// When the `experimental-io-uring` crate feature is enabled, file reads are always async.
    ///
    /// Default is 0, meaning all files are read asynchronously.
    pub fn read_mode_threshold(mut self, size: u64) -> Self {
        self.read_mode_threshold = size;
        self
    }

    /// Specifies whether to use ETag or not.
    ///
    /// Default is true.
    pub fn use_etag(mut self, value: bool) -> Self {
        self.file_flags.set(named::Flags::ETAG, value);
        self
    }

    /// Specifies whether to use Last-Modified or not.
    ///
    /// Default is true.
    pub fn use_last_modified(mut self, value: bool) -> Self {
        self.file_flags.set(named::Flags::LAST_MD, value);
        self
    }

    /// Specifies whether text responses should signal a UTF-8 encoding.
    ///
    /// Default is false (but will default to true in a future version).
    pub fn prefer_utf8(mut self, value: bool) -> Self {
        self.file_flags.set(named::Flags::PREFER_UTF8, value);
        self
    }

    /// Adds a routing guard.
    ///
    /// Use this to allow multiple chained file services that respond to strictly different
    /// properties of a request. Due to the way routing works, if a guard check returns true and the
    /// request starts being handled by the file service, it will not be able to back-out and try
    /// the next service, you will simply get a 404 (or 405) error response.
    ///
    /// To allow `POST` requests to retrieve files, see [`Files::method_guard()`].
    ///
    /// # Examples
    /// ```
    /// use actix_web::{guard::Header, App};
    /// use actix_files::Files;
    ///
    /// App::new().service(
    ///     Files::new("/","/my/site/files")
    ///         .guard(Header("Host", "example.com"))
    /// );
    /// ```
    pub fn guard<G: Guard + 'static>(mut self, guard: G) -> Self {
        self.guards.push(Rc::new(guard));
        self
    }

    /// Specifies guard to check before fetching directory listings or files.
    ///
    /// Note that this guard has no effect on routing; it's main use is to guard on the request's
    /// method just before serving the file, only allowing `GET` and `HEAD` requests by default.
    /// See [`Files::guard`] for routing guards.
    pub fn method_guard<G: Guard + 'static>(mut self, guard: G) -> Self {
        self.use_guards = Some(Rc::new(guard));
        self
    }

    /// See [`Files::method_guard`].
    #[doc(hidden)]
    #[deprecated(since = "0.6.0", note = "Renamed to `method_guard`.")]
    pub fn use_guards<G: Guard + 'static>(self, guard: G) -> Self {
        self.method_guard(guard)
    }

    /// Disable `Content-Disposition` header.
    ///
    /// By default Content-Disposition` header is enabled.
    pub fn disable_content_disposition(mut self) -> Self {
        self.file_flags.remove(named::Flags::CONTENT_DISPOSITION);
        self
    }

    /// Sets default handler which is used when no matched file could be found.
    ///
    /// # Examples
    /// Setting a fallback static file handler:
    /// ```
    /// use actix_files::{Files, NamedFile};
    /// use actix_web::dev::{ServiceRequest, ServiceResponse, fn_service};
    ///
    /// # fn run() -> Result<(), actix_web::Error> {
    /// let files = Files::new("/", "./static")
    ///     .index_file("index.html")
    ///     .default_handler(fn_service(|req: ServiceRequest| async {
    ///         let (req, _) = req.into_parts();
    ///         let file = NamedFile::open_async("./static/404.html").await?;
    ///         let res = file.into_response(&req);
    ///         Ok(ServiceResponse::new(req, res))
    ///     }));
    /// # Ok(())
    /// # }
    /// ```
    pub fn default_handler<F, U>(mut self, f: F) -> Self
    where
        F: IntoServiceFactory<U, ServiceRequest>,
        U: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse, Error = Error>
            + 'static,
    {
        // create and configure default resource
        self.default = Rc::new(RefCell::new(Some(Rc::new(boxed::factory(
            f.into_factory().map_init_err(|_| ()),
        )))));

        self
    }

    /// Enables serving hidden files and directories, allowing a leading dots in url fragments.
    pub fn use_hidden_files(mut self) -> Self {
        self.hidden_files = true;
        self
    }

    /// Attempts to search for a suitable pre-compressed version of a file on disk before falling
    /// back to the uncompressed version.
    ///
    /// Currently, `.gz`, `.br`, and `.zst` files are supported.
    pub fn try_compressed(mut self) -> Self {
        self.try_compressed = true;
        self
    }
}

impl HttpServiceFactory for Files {
    fn register(mut self, config: &mut AppService) {
        let guards = if self.guards.is_empty() {
            None
        } else {
            let guards = std::mem::take(&mut self.guards);
            Some(
                guards
                    .into_iter()
                    .map(|guard| -> Box<dyn Guard> { Box::new(guard) })
                    .collect::<Vec<_>>(),
            )
        };

        if self.default.borrow().is_none() {
            *self.default.borrow_mut() = Some(config.default_service());
        }

        let rdef = if config.is_root() {
            ResourceDef::root_prefix(&self.mount_path)
        } else {
            ResourceDef::prefix(&self.mount_path)
        };

        config.register_service(rdef, guards, self, None)
    }
}

impl ServiceFactory<ServiceRequest> for Files {
    type Response = ServiceResponse;
    type Error = Error;
    type Config = ();
    type Service = FilesService;
    type InitError = ();
    type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;

    fn new_service(&self, _: ()) -> Self::Future {
        let mut inner = FilesServiceInner {
            directory: self.directory.clone(),
            index: self.index.clone(),
            show_index: self.show_index,
            redirect_to_slash: self.redirect_to_slash,
            default: None,
            renderer: self.renderer.clone(),
            mime_override: self.mime_override.clone(),
            path_filter: self.path_filter.clone(),
            file_flags: self.file_flags,
            guards: self.use_guards.clone(),
            hidden_files: self.hidden_files,
            try_compressed: self.try_compressed,
            size_threshold: self.read_mode_threshold,
            with_permanent_redirect: self.with_permanent_redirect,
        };

        if let Some(ref default) = *self.default.borrow() {
            let fut = default.new_service(());
            Box::pin(async {
                match fut.await {
                    Ok(default) => {
                        inner.default = Some(default);
                        Ok(FilesService(Rc::new(inner)))
                    }
                    Err(_) => Err(()),
                }
            })
        } else {
            Box::pin(async move { Ok(FilesService(Rc::new(inner))) })
        }
    }
}

#[cfg(test)]
mod tests {
    use actix_web::{
        http::StatusCode,
        test::{self, TestRequest},
        App, HttpResponse,
    };

    use super::*;

    #[actix_web::test]
    async fn custom_files_listing_renderer() {
        let srv = test::init_service(
            App::new().service(
                Files::new("/", "./tests")
                    .show_files_listing()
                    .files_listing_renderer(|dir, req| {
                        Ok(ServiceResponse::new(
                            req.clone(),
                            HttpResponse::Ok().body(dir.path.to_str().unwrap().to_owned()),
                        ))
                    }),
            ),
        )
        .await;

        let req = TestRequest::with_uri("/").to_request();
        let res = test::call_service(&srv, req).await;

        assert_eq!(res.status(), StatusCode::OK);
        let body = test::read_body(res).await;
        let body_str = std::str::from_utf8(&body).unwrap();
        let actual_path = Path::new(&body_str);
        let expected_path = Path::new("actix-files/tests");
        assert!(
            actual_path.ends_with(expected_path),
            "body {:?} does not end with {:?}",
            actual_path,
            expected_path
        );
    }
}


================================================
FILE: actix-files/src/lib.rs
================================================
//! Static file serving for Actix Web.
//!
//! Provides a non-blocking service for serving static files from disk.
//!
//! # Examples
//! ```
//! use actix_web::App;
//! use actix_files::Files;
//!
//! let app = App::new()
//!     .service(Files::new("/static", ".").prefer_utf8(true));
//! ```

#![warn(missing_docs, missing_debug_implementations)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
#![cfg_attr(docsrs, feature(doc_cfg))]

use std::path::Path;

use actix_service::boxed::{BoxService, BoxServiceFactory};
use actix_web::{
    dev::{RequestHead, ServiceRequest, ServiceResponse},
    error::Error,
    http::header::DispositionType,
};
use mime_guess::from_ext;

mod chunked;
mod directory;
mod encoding;
mod error;
mod files;
mod named;
mod path_buf;
mod range;
mod service;

pub use self::{
    chunked::ChunkedReadFile, directory::Directory, error::UriSegmentError, files::Files,
    named::NamedFile, path_buf::PathBufWrap, range::HttpRange, service::FilesService,
};
use self::{
    directory::{directory_listing, DirectoryRenderer},
    error::FilesError,
};

type HttpService = BoxService<ServiceRequest, ServiceResponse, Error>;
type HttpNewService = BoxServiceFactory<(), ServiceRequest, ServiceResponse, Error, ()>;

/// Return the MIME type associated with a filename extension (case-insensitive).
/// If `ext` is empty or no associated type for the extension was found, returns
/// the type `application/octet-stream`.
#[inline]
pub fn file_extension_to_mime(ext: &str) -> mime::Mime {
    from_ext(ext).first_or_octet_stream()
}

type MimeOverride = dyn Fn(&mime::Name<'_>) -> DispositionType;

type PathFilter = dyn Fn(&Path, &RequestHead) -> bool;

#[cfg(test)]
mod tests {
    use std::{
        fmt::Write as _,
        fs::{self},
        ops::Add,
        time::{Duration, SystemTime},
    };

    use actix_web::{
        dev::ServiceFactory,
        guard,
        http::{
            header::{self, ContentDisposition, DispositionParam},
            Method, StatusCode,
        },
        middleware::Compress,
        test::{self, TestRequest},
        web::{self, Bytes},
        App, HttpResponse, Responder,
    };

    use super::*;
    use crate::named::File;

    #[actix_web::test]
    async fn test_file_extension_to_mime() {
        let m = file_extension_to_mime("");
        assert_eq!(m, mime::APPLICATION_OCTET_STREAM);

        let m = file_extension_to_mime("jpg");
        assert_eq!(m, mime::IMAGE_JPEG);

        let m = file_extension_to_mime("invalid extension!!");
        assert_eq!(m, mime::APPLICATION_OCTET_STREAM);

        let m = file_extension_to_mime("");
        assert_eq!(m, mime::APPLICATION_OCTET_STREAM);
    }

    #[actix_rt::test]
    async fn test_if_modified_since_without_if_none_match() {
        let file = NamedFile::open_async("Cargo.toml").await.unwrap();
        let since = header::HttpDate::from(SystemTime::now().add(Duration::from_secs(60)));

        let req = TestRequest::default()
            .insert_header((header::IF_MODIFIED_SINCE, since))
            .to_http_request();
        let resp = file.respond_to(&req);
        assert_eq!(resp.status(), StatusCode::NOT_MODIFIED);
    }

    #[actix_rt::test]
    async fn test_if_modified_since_without_if_none_match_same() {
        let file = NamedFile::open_async("Cargo.toml").await.unwrap();
        let since = file.last_modified().unwrap();

        let req = TestRequest::default()
            .insert_header((header::IF_MODIFIED_SINCE, since))
            .to_http_request();
        let resp = file.respond_to(&req);
        assert_eq!(resp.status(), StatusCode::NOT_MODIFIED);
    }

    #[actix_rt::test]
    async fn test_if_modified_since_with_if_none_match() {
        let file = NamedFile::open_async("Cargo.toml").await.unwrap();
        let since = header::HttpDate::from(SystemTime::now().add(Duration::from_secs(60)));

        let req = TestRequest::default()
            .insert_header((header::IF_NONE_MATCH, "miss_etag"))
            .insert_header((header::IF_MODIFIED_SINCE, since))
            .to_http_request();
        let resp = file.respond_to(&req);
        assert_ne!(resp.status(), StatusCode::NOT_MODIFIED);
    }

    #[actix_rt::test]
    async fn test_if_unmodified_since() {
        let file = NamedFile::open_async("Cargo.toml").await.unwrap();
        let since = file.last_modified().unwrap();

        let req = TestRequest::default()
            .insert_header((header::IF_UNMODIFIED_SINCE, since))
            .to_http_request();
        let resp = file.respond_to(&req);
        assert_eq!(resp.status(), StatusCode::OK);
    }

    #[actix_rt::test]
    async fn test_if_unmodified_since_failed() {
        let file = NamedFile::open_async("Cargo.toml").await.unwrap();
        let since = header::HttpDate::from(SystemTime::UNIX_EPOCH);

        let req = TestRequest::default()
            .insert_header((header::IF_UNMODIFIED_SINCE, since))
            .to_http_request();
        let resp = file.respond_to(&req);
        assert_eq!(resp.status(), StatusCode::PRECONDITION_FAILED);
    }

    #[actix_rt::test]
    async fn test_named_file_text() {
        assert!(NamedFile::open_async("test--").await.is_err());
        let mut file = NamedFile::open_async("Cargo.toml").await.unwrap();
        {
            file.file();
            let _f: &File = &file;
        }
        {
            let _f: &mut File = &mut file;
        }

        let req = TestRequest::default().to_http_request();
        let resp = file.respond_to(&req);
        assert_eq!(
            resp.headers().get(header::CONTENT_TYPE).unwrap(),
            "text/x-toml"
        );
        assert_eq!(
            resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
            "inline; filename=\"Cargo.toml\""
        );
    }

    #[actix_rt::test]
    async fn test_named_file_content_disposition() {
        assert!(NamedFile::open_async("test--").await.is_err());
        let mut file = NamedFile::open_async("Cargo.toml").await.unwrap();
        {
            file.file();
            let _f: &File = &file;
        }
        {
            let _f: &mut File = &mut file;
        }

        let req = TestRequest::default().to_http_request();
        let resp = file.respond_to(&req);
        assert_eq!(
            resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
            "inline; filename=\"Cargo.toml\""
        );

        let file = NamedFile::open_async("Cargo.toml")
            .await
            .unwrap()
            .disable_content_disposition();
        let req = TestRequest::default().to_http_request();
        let resp = file.respond_to(&req);
        assert!(resp.headers().get(header::CONTENT_DISPOSITION).is_none());
    }

    #[actix_rt::test]
    async fn test_named_file_non_ascii_file_name() {
        let file = {
            #[cfg(feature = "experimental-io-uring")]
            {
                crate::named::File::open("Cargo.toml").await.unwrap()
            }

            #[cfg(not(feature = "experimental-io-uring"))]
            {
                crate::named::File::open("Cargo.toml").unwrap()
            }
        };

        let mut file = NamedFile::from_file(file, "貨物.toml").unwrap();
        {
            file.file();
            let _f: &File = &file;
        }
        {
            let _f: &mut File = &mut file;
        }

        let req = TestRequest::default().to_http_request();
        let resp = file.respond_to(&req);
        assert_eq!(
            resp.headers().get(header::CONTENT_TYPE).unwrap(),
            "text/x-toml"
        );
        assert_eq!(
            resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
            "inline; filename=\"貨物.toml\"; filename*=UTF-8''%E8%B2%A8%E7%89%A9.toml"
        );
    }

    #[actix_rt::test]
    async fn test_named_file_set_content_type() {
        let mut file = NamedFile::open_async("Cargo.toml")
            .await
            .unwrap()
            .set_content_type(mime::TEXT_XML);
        {
            file.file();
            let _f: &File = &file;
        }
        {
            let _f: &mut File = &mut file;
        }

        let req = TestRequest::default().to_http_request();
        let resp = file.respond_to(&req);
        assert_eq!(
            resp.headers().get(header::CONTENT_TYPE).unwrap(),
            "text/xml"
        );
        assert_eq!(
            resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
            "inline; filename=\"Cargo.toml\""
        );
    }

    #[actix_rt::test]
    async fn test_named_file_image() {
        let mut file = NamedFile::open_async("tests/test.png").await.unwrap();
        {
            file.file();
            let _f: &File = &file;
        }
        {
            let _f: &mut File = &mut file;
        }

        let req = TestRequest::default().to_http_request();
        let resp = file.respond_to(&req);
        assert_eq!(
            resp.headers().get(header::CONTENT_TYPE).unwrap(),
            "image/png"
        );
        assert_eq!(
            resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
            "inline; filename=\"test.png\""
        );
    }

    #[actix_rt::test]
    async fn test_named_file_javascript() {
        let file = NamedFile::open_async("tests/test.js").await.unwrap();

        let req = TestRequest::default().to_http_request();
        let resp = file.respond_to(&req);
        assert_eq!(
            resp.headers().get(header::CONTENT_TYPE).unwrap(),
            "text/javascript",
        );
        assert_eq!(
            resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
            "inline; filename=\"test.js\"",
        );
    }

    #[actix_rt::test]
    async fn test_named_file_image_attachment() {
        let cd = ContentDisposition {
            disposition: DispositionType::Attachment,
            parameters: vec![DispositionParam::Filename(String::from("test.png"))],
        };
        let mut file = NamedFile::open_async("tests/test.png")
            .await
            .unwrap()
            .set_content_disposition(cd);
        {
            file.file();
            let _f: &File = &file;
        }
        {
            let _f: &mut File = &mut file;
        }

        let req = TestRequest::default().to_http_request();
        let resp = file.respond_to(&req);
        assert_eq!(
            resp.headers().get(header::CONTENT_TYPE).unwrap(),
            "image/png"
        );
        assert_eq!(
            resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
            "attachment; filename=\"test.png\""
        );
    }

    #[actix_rt::test]
    async fn test_named_file_binary() {
        let mut file = NamedFile::open_async("tests/test.binary").await.unwrap();
        {
            file.file();
            let _f: &File = &file;
        }
        {
            let _f: &mut File = &mut file;
        }

        let req = TestRequest::default().to_http_request();
        let resp = file.respond_to(&req);
        assert_eq!(
            resp.headers().get(header::CONTENT_TYPE).unwrap(),
            "application/octet-stream"
        );
        assert_eq!(
            resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
            "attachment; filename=\"test.binary\""
        );
    }

    #[allow(deprecated)]
    #[actix_rt::test]
    async fn status_code_customize_same_output() {
        let file1 = NamedFile::open_async("Cargo.toml")
            .await
            .unwrap()
            .set_status_code(StatusCode::NOT_FOUND);

        let file2 = NamedFile::open_async("Cargo.toml")
            .await
            .unwrap()
            .customize()
            .with_status(StatusCode::NOT_FOUND);

        let req = TestRequest::default().to_http_request();
        let res1 = file1.respond_to(&req);
        let res2 = file2.respond_to(&req);

        assert_eq!(res1.status(), StatusCode::NOT_FOUND);
        assert_eq!(res2.status(), StatusCode::NOT_FOUND);
    }

    #[actix_rt::test]
    async fn test_named_file_status_code_text() {
        let mut file = NamedFile::open_async("Cargo.toml").await.unwrap();

        {
            file.file();
            let _f: &File = &file;
        }

        {
            let _f: &mut File = &mut file;
        }

        let file = file.customize().with_status(StatusCode::NOT_FOUND);

        let req = TestRequest::default().to_http_request();
        let resp = file.respond_to(&req);
        assert_eq!(
            resp.headers().get(header::CONTENT_TYPE).unwrap(),
            "text/x-toml"
        );
        assert_eq!(
            resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
            "inline; filename=\"Cargo.toml\""
        );
        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
    }

    #[actix_rt::test]
    async fn test_mime_override() {
        fn all_attachment(_: &mime::Name<'_>) -> DispositionType {
            DispositionType::Attachment
        }

        let srv = test::init_service(
            App::new().service(
                Files::new("/", ".")
                    .mime_override(all_attachment)
                    .index_file("Cargo.toml"),
            ),
        )
        .await;

        let request = TestRequest::get().uri("/").to_request();
        let response = test::call_service(&srv, request).await;
        assert_eq!(response.status(), StatusCode::OK);

        let content_disposition = response
            .headers()
            .get(header::CONTENT_DISPOSITION)
            .expect("To have CONTENT_DISPOSITION");
        let content_disposition = content_disposition
            .to_str()
            .expect("Convert CONTENT_DISPOSITION to str");
        assert_eq!(content_disposition, "attachment; filename=\"Cargo.toml\"");
    }

    #[actix_rt::test]
    async fn test_named_file_ranges_status_code() {
        let srv = test::init_service(
            App::new().service(Files::new("/test", ".").index_file("Cargo.toml")),
        )
        .await;

        // Valid range header
        let request = TestRequest::get()
            .uri("/t%65st/Cargo.toml")
            .insert_header((header::RANGE, "bytes=10-20"))
            .to_request();
        let response = test::call_service(&srv, request).await;
        assert_eq!(response.status(), StatusCode::PARTIAL_CONTENT);

        // Invalid range header
        let request = TestRequest::get()
            .uri("/t%65st/Cargo.toml")
            .insert_header((header::RANGE, "bytes=1-0"))
            .to_request();
        let response = test::call_service(&srv, request).await;

        assert_eq!(response.status(), StatusCode::RANGE_NOT_SATISFIABLE);
    }

    #[actix_rt::test]
    async fn test_named_file_empty_range_headers() {
        let srv = actix_test::start(|| App::new().service(Files::new("/", ".")));

        for range in ["", "bytes="] {
            let response = srv
                .get("/tests/test.binary")
                .insert_header((header::RANGE, range))
                .send()
                .await
                .unwrap();

            assert_eq!(response.status(), StatusCode::RANGE_NOT_SATISFIABLE);
            let content_range = response.headers().get(header::CONTENT_RANGE).unwrap();
            assert_eq!(content_range.to_str().unwrap(), "bytes */100");
        }
    }

    #[actix_rt::test]
    async fn test_named_file_content_range_headers() {
        let srv = actix_test::start(|| App::new().service(Files::new("/", ".")));

        // Valid range header
        let response = srv
            .get("/tests/test.binary")
            .insert_header((header::RANGE, "bytes=10-20"))
            .send()
            .await
            .unwrap();
        let content_range = response.headers().get(header::CONTENT_RANGE).unwrap();
        assert_eq!(content_range.to_str().unwrap(), "bytes 10-20/100");

        // Invalid range header
        let response = srv
            .get("/tests/test.binary")
            .insert_header((header::RANGE, "bytes=10-5"))
            .send()
            .await
            .unwrap();
        let content_range = response.headers().get(header::CONTENT_RANGE).unwrap();
        assert_eq!(content_range.to_str().unwrap(), "bytes */100");
    }

    #[actix_rt::test]
    async fn test_named_file_range_header_from_zero_to_end_returns_partial_content() {
        let srv = actix_test::start(|| App::new().service(Files::new("/", ".")));

        let response = srv
            .get("/tests/test.binary")
            .insert_header((header::RANGE, "bytes=0-"))
            .send()
            .await
            .unwrap();

        assert_eq!(response.status(), StatusCode::PARTIAL_CONTENT);

        let content_range = response.headers().get(header::CONTENT_RANGE).unwrap();
        assert_eq!(content_range.to_str().unwrap(), "bytes 0-99/100");

        let content_length = response.headers().get(header::CONTENT_LENGTH).unwrap();
        assert_eq!(content_length.to_str().unwrap(), "100");

        // Should be no transfer-encoding
        let transfer_encoding = response.headers().get(header::TRANSFER_ENCODING);
        assert!(transfer_encoding.is_none());
    }

    #[actix_rt::test]
    async fn test_named_file_content_length_headers() {
        let srv = actix_test::start(|| App::new().service(Files::new("/", ".")));

        // Valid range header
        let response = srv
            .get("/tests/test.binary")
            .insert_header((header::RANGE, "bytes=10-20"))
            .send()
            .await
            .unwrap();
        let content_length = response.headers().get(header::CONTENT_LENGTH).unwrap();
        assert_eq!(content_length.to_str().unwrap(), "11");

        // Valid range header, starting from 0
        let response = srv
            .get("/tests/test.binary")
            .insert_header((header::RANGE, "bytes=0-20"))
            .send()
            .await
            .unwrap();
        let content_length = response.headers().get(header::CONTENT_LENGTH).unwrap();
        assert_eq!(content_length.to_str().unwrap(), "21");

        // Without range header
        let mut response = srv.get("/tests/test.binary").send().await.unwrap();
        let content_length = response.headers().get(header::CONTENT_LENGTH).unwrap();
        assert_eq!(content_length.to_str().unwrap(), "100");

        // Should be no transfer-encoding
        let transfer_encoding = response.headers().get(header::TRANSFER_ENCODING);
        assert!(transfer_encoding.is_none());

        // Check file contents
        let bytes = response.body().await.unwrap();
        let data = web::Bytes::from(fs::read("tests/test.binary").unwrap());
        assert_eq!(bytes, data);
    }

    #[actix_rt::test]
    async fn test_head_content_length_headers() {
        let srv = actix_test::start(|| App::new().service(Files::new("/", ".")));

        let response = srv.head("/tests/test.binary").send().await.unwrap();

        let content_length = response
            .headers()
            .get(header::CONTENT_LENGTH)
            .unwrap()
            .to_str()
            .unwrap();

        assert_eq!(content_length, "100");
    }

    #[actix_rt::test]
    async fn test_static_files_with_spaces() {
        let srv =
            test::init_service(App::new().service(Files::new("/", ".").index_file("Cargo.toml")))
                .await;
        let request = TestRequest::get()
            .uri("/tests/test%20space.binary")
            .to_request();
        let response = test::call_service(&srv, request).await;
        assert_eq!(response.status(), StatusCode::OK);

        let bytes = test::read_body(response).await;
        let data = web::Bytes::from(fs::read("tests/test space.binary").unwrap());
        assert_eq!(bytes, data);
    }

    #[cfg(not(target_os = "windows"))]
    #[actix_rt::test]
    async fn test_static_files_with_special_characters() {
        // Create the file we want to test against ad-hoc. We can't check it in as otherwise
        // Windows can't even checkout this repository.
        let temp_dir = tempfile::tempdir().unwrap();
        let file_with_newlines = temp_dir.path().join("test\n\x0B\x0C\rnewline.text");
        fs::write(&file_with_newlines, "Look at my newlines").unwrap();

        let srv = test::init_service(
            App::new().service(Files::new("/", temp_dir.path()).index_file("Cargo.toml")),
        )
        .await;
        let request = TestRequest::get()
            .uri("/test%0A%0B%0C%0Dnewline.text")
            .to_request();
        let response = test::call_service(&srv, request).await;
        assert_eq!(response.status(), StatusCode::OK);

        let bytes = test::read_body(response).await;
        let data = web::Bytes::from(fs::read(file_with_newlines).unwrap());
        assert_eq!(bytes, data);
    }

    #[actix_rt::test]
    async fn test_files_not_allowed() {
        let srv = test::init_service(App::new().service(Files::new("/", "."))).await;

        let req = TestRequest::default()
            .uri("/Cargo.toml")
            .method(Method::POST)
            .to_request();

        let resp = test::call_service(&srv, req).await;
        assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);

        let srv = test::init_service(App::new().service(Files::new("/", "."))).await;
        let req = TestRequest::default()
            .method(Method::PUT)
            .uri("/Cargo.toml")
            .to_request();
        let resp = test::call_service(&srv, req).await;
        assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
    }

    #[actix_rt::test]
    async fn test_files_guards() {
        let srv = test::init_service(
            App::new().service(Files::new("/", ".").method_guard(guard::Post())),
        )
        .await;

        let req = TestRequest::default()
            .uri("/Cargo.toml")
            .method(Method::POST)
            .to_request();

        let resp = test::call_service(&srv, req).await;
        assert_eq!(resp.status(), StatusCode::OK);
    }

    #[actix_rt::test]
    async fn test_named_file_content_encoding() {
        let srv = test::init_service(App::new().wrap(Compress::default()).service(
            web::resource("/").to(|| async {
                NamedFile::open_async("Cargo.toml")
                    .await
                    .unwrap()
                    .set_content_encoding(header::ContentEncoding::Identity)
            }),
        ))
        .await;

        let request = TestRequest::get()
            .uri("/")
            .insert_header((header::ACCEPT_ENCODING, "gzip"))
            .to_request();
        let res = test::call_service(&srv, request).await;
        assert_eq!(res.status(), StatusCode::OK);
        assert!(res.headers().contains_key(header::CONTENT_ENCODING));
        assert!(!test::read_body(res).await.is_empty());
    }

    #[actix_rt::test]
    async fn test_named_file_content_encoding_gzip() {
        let srv = test::init_service(App::new().wrap(Compress::default()).service(
            web::resource("/").to(|| async {
                NamedFile::open_async("Cargo.toml")
                    .await
                    .unwrap()
                    .set_content_encoding(header::ContentEncoding::Gzip)
            }),
        ))
        .await;

        let request = TestRequest::get()
            .uri("/")
            .insert_header((header::ACCEPT_ENCODING, "gzip"))
            .to_request();
        let res = test::call_service(&srv, request).await;
        assert_eq!(res.status(), StatusCode::OK);
        assert_eq!(
            res.headers()
                .get(header::CONTENT_ENCODING)
                .unwrap()
                .to_str()
                .unwrap(),
            "gzip"
        );
    }

    #[actix_rt::test]
    async fn test_named_file_allowed_method() {
        let req = TestRequest::default().method(Method::GET).to_http_request();
        let file = NamedFile::open_async("Cargo.toml").await.unwrap();
        let resp = file.respond_to(&req);
        assert_eq!(resp.status(), StatusCode::OK);
    }

    #[actix_rt::test]
    async fn test_static_files() {
        let srv =
            test::init_service(App::new().service(Files::new("/", ".").show_files_listing())).await;
        let req = TestRequest::with_uri("/missing").to_request();

        let resp = test::call_service(&srv, req).await;
        assert_eq!(resp.status(), StatusCode::NOT_FOUND);

        let srv = test::init_service(App::new().service(Files::new("/", "."))).await;

        let req = TestRequest::default().to_request();
        let resp = test::call_service(&srv, req).await;
        assert_eq!(resp.status(), StatusCode::NOT_FOUND);

        let srv =
            test::init_service(App::new().service(Files::new("/", ".").show_files_listing())).await;
        let req = TestRequest::with_uri("/tests").to_request();
        let resp = test::call_service(&srv, req).await;
        assert_eq!(
            resp.headers().get(header::CONTENT_TYPE).unwrap(),
            "text/html; charset=utf-8"
        );

        let bytes = test::read_body(resp).await;
        assert!(format!("{:?}", bytes).contains("/tests/test.png"));
    }

    #[actix_rt::test]
    async fn test_redirect_to_slash_directory() {
        // should not redirect if no index and files listing is disabled
        let srv = test::init_service(
            App::new().service(Files::new("/", ".").redirect_to_slash_directory()),
        )
        .await;
        let req = TestRequest::with_uri("/tests").to_request();
        let resp = test::call_service(&srv, req).await;
        assert_eq!(resp.status(), StatusCode::NOT_FOUND);

        // should redirect if index present
        let srv = test::init_service(
            App::new().service(
                Files::new("/", ".")
                    .index_file("test.png")
                    .redirect_to_slash_directory(),
            ),
        )
        .await;
        let req = TestRequest::with_uri("/tests").to_request();
        let resp = test::call_service(&srv, req).await;
        assert_eq!(resp.status(), StatusCode::TEMPORARY_REDIRECT);

        // should redirect if index present with permanent redirect
        let srv = test::init_service(
            App::new().service(
                Files::new("/", ".")
                    .index_file("test.png")
                    .redirect_to_slash_directory()
                    .with_permanent_redirect(),
            ),
        )
        .await;
        let req = TestRequest::with_uri("/tests").to_request();
        let resp = test::call_service(&srv, req).await;
        assert_eq!(resp.status(), StatusCode::PERMANENT_REDIRECT);

        // should redirect if files listing is enabled
        let srv = test::init_service(
            App::new().service(
                Files::new("/", ".")
                    .show_files_listing()
                    .redirect_to_slash_directory(),
            ),
        )
        .await;
        let req = TestRequest::with_uri("/tests").to_request();
        let resp = test::call_service(&srv, req).await;
        assert_eq!(resp.status(), StatusCode::TEMPORARY_REDIRECT);

        // should not redirect if the path is wrong
        let req = TestRequest::with_uri("/not_existing").to_request();
        let resp = test::call_service(&srv, req).await;
        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
    }

    #[actix_rt::test]
    async fn test_static_files_bad_directory() {
        let service = Files::new("/", "./missing").new_service(()).await.unwrap();

        let req = TestRequest::with_uri("/").to_srv_request();
        let resp = test::call_service(&service, req).await;

        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
    }

    #[actix_rt::test]
    async fn test_static_files_bad_directory_does_not_serve_cwd_files() {
        let service = Files::new("/", "./missing").new_service(()).await.unwrap();

        let req = TestRequest::with_uri("/Cargo.toml").to_srv_request();
        let resp = test::call_service(&service, req).await;

        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
    }

    #[actix_rt::test]
    async fn test_default_handler_file_missing() {
        let st = Files::new("/", ".")
            .default_handler(|req: ServiceRequest| async {
                Ok(req.into_response(HttpResponse::Ok().body("default content")))
            })
            .new_service(())
            .await
            .unwrap();
        let req = TestRequest::with_uri("/missing").to_srv_request();
        let resp = test::call_service(&st, req).await;

        assert_eq!(resp.status(), StatusCode::OK);
        let bytes = test::read_body(resp).await;
        assert_eq!(bytes, web::Bytes::from_static(b"default content"));
    }

    #[actix_rt::test]
    async fn test_serve_index_nested() {
        let service = Files::new(".", ".")
            .index_file("lib.rs")
            .new_service(())
            .await
            .unwrap();

        let req = TestRequest::default().uri("/src").to_srv_request();
        let resp = test::call_service(&service, req).await;

        assert_eq!(resp.status(), StatusCode::OK);
        assert_eq!(
            resp.headers().get(header::CONTENT_TYPE).unwrap(),
            "text/x-rust"
        );
        assert_eq!(
            resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
            "inline; filename=\"lib.rs\""
        );
    }

    #[actix_rt::test]
    async fn integration_serve_index() {
        let srv = test::init_service(
            App::new().service(Files::new("test", ".").index_file("Cargo.toml")),
        )
        .await;

        let req = TestRequest::get().uri("/test").to_request();
        let res = test::call_service(&srv, req).await;
        assert_eq!(res.status(), StatusCode::OK);

        let bytes = test::read_body(res).await;

        let data = Bytes::from(fs::read("Cargo.toml").unwrap());
        assert_eq!(bytes, data);

        let req = TestRequest::get().uri("/test/").to_request();
        let res = test::call_service(&srv, req).await;
        assert_eq!(res.status(), StatusCode::OK);

        let bytes = test::read_body(res).await;
        let data = Bytes::from(fs::read("Cargo.toml").unwrap());
        assert_eq!(bytes, data);

        // nonexistent index file
        let req = TestRequest::get().uri("/test/unknown").to_request();
        let res = test::call_service(&srv, req).await;
        assert_eq!(res.status(), StatusCode::NOT_FOUND);

        let req = TestRequest::get().uri("/test/unknown/").to_request();
        let res = test::call_service(&srv, req).await;
        assert_eq!(res.status(), StatusCode::NOT_FOUND);
    }

    #[actix_rt::test]
    async fn integration_percent_encoded() {
        let srv = test::init_service(
            App::new().service(Files::new("test", ".").index_file("Cargo.toml")),
        )
        .await;

        let req = TestRequest::get().uri("/test/%43argo.toml").to_request();
        let res = test::call_service(&srv, req).await;
        assert_eq!(res.status(), StatusCode::OK);

        // `%2F` == `/`
        let req = TestRequest::get().uri("/test%2Ftest.binary").to_request();
        let res = test::call_service(&srv, req).await;
        assert_eq!(res.status(), StatusCode::NOT_FOUND);

        let req = TestRequest::get().uri("/test/Cargo.toml%00").to_request();
        let res = test::call_service(&srv, req).await;
        assert_eq!(res.status(), StatusCode::NOT_FOUND);
    }

    #[actix_rt::test]
    async fn test_percent_encoding_2() {
        let temp_dir = tempfile::tempdir().unwrap();
        let filename = match cfg!(unix) {
            true => "ض:?#[]{}<>()@!$&'`|*+,;= %20\n.test",
            false => "ض#[]{}()@!$&'`+,;= %20.test",
        };
        let filename_encoded = filename
            .as_bytes()
            .iter()
            .fold(String::new(), |mut buf, c| {
                write!(&mut buf, "%{:02X}", c).unwrap();
                buf
            });
        std::fs::File::create(temp_dir.path().join(filename)).unwrap();

        let srv = test::init_service(App::new().service(Files::new("/", temp_dir.path()))).await;

        let req = TestRequest::get()
            .uri(&format!("/{}", filename_encoded))
            .to_request();
        let res = test::call_service(&srv, req).await;
        assert_eq!(res.status(), StatusCode::OK);
    }

    #[actix_rt::test]
    async fn test_serve_named_file() {
        let factory = NamedFile::open_async("Cargo.toml").await.unwrap();
        let srv = test::init_service(App::new().service(factory)).await;

        let req = TestRequest::get().uri("/Cargo.toml").to_request();
        let res = test::call_service(&srv, req).await;
        assert_eq!(res.status(), StatusCode::OK);

        let bytes = test::read_body(res).await;
        let data = Bytes::from(fs::read("Cargo.toml").unwrap());
        assert_eq!(bytes, data);

        let req = TestRequest::get().uri("/test/unknown").to_request();
        let res = test::call_service(&srv, req).await;
        assert_eq!(res.status(), StatusCode::NOT_FOUND);
    }

    #[actix_rt::test]
    async fn test_serve_named_file_prefix() {
        let factory = NamedFile::open_async("Cargo.toml").await.unwrap();
        let srv =
            test::init_service(App::new().service(web::scope("/test").service(factory))).await;

        let req = TestRequest::get().uri("/test/Cargo.toml").to_request();
        let res = test::call_service(&srv, req).await;
        assert_eq!(res.status(), StatusCode::OK);

        let bytes = test::read_body(res).await;
        let data = Bytes::from(fs::read("Cargo.toml").unwrap());
        assert_eq!(bytes, data);

        let req = TestRequest::get().uri("/Cargo.toml").to_request();
        let res = test::call_service(&srv, req).await;
        assert_eq!(res.status(), StatusCode::NOT_FOUND);
    }

    #[actix_rt::test]
    async fn test_named_file_default_service() {
        let factory = NamedFile::open_async("Cargo.toml").await.unwrap();
        let srv = test::init_service(App::new().default_service(factory)).await;

        for route in ["/foobar", "/baz", "/"].iter() {
            let req = TestRequest::get().uri(route).to_request();
            let res = test::call_service(&srv, req).await;
            assert_eq!(res.status(), StatusCode::OK);

            let bytes = test::read_body(res).await;
            let data = Bytes::from(fs::read("Cargo.toml").unwrap());
            assert_eq!(bytes, data);
        }
    }

    #[actix_rt::test]
    async fn test_default_handler_named_file() {
        let factory = NamedFile::open_async("Cargo.toml").await.unwrap();
        let st = Files::new("/", ".")
            .default_handler(factory)
            .new_service(())
            .await
            .unwrap();
        let req = TestRequest::with_uri("/missing").to_srv_request();
        let resp = test::call_service(&st, req).await;

        assert_eq!(resp.status(), StatusCode::OK);
        let bytes = test::read_body(resp).await;
        let data = Bytes::from(fs::read("Cargo.toml").unwrap());
        assert_eq!(bytes, data);
    }

    #[actix_rt::test]
    async fn test_symlinks() {
        let srv = test::init_service(App::new().service(Files::new("test", "."))).await;

        let req = TestRequest::get()
            .uri("/test/tests/symlink-test.png")
            .to_request();
        let res = test::call_service(&srv, req).await;
        assert_eq!(res.status(), StatusCode::OK);
        assert_eq!(
            res.headers().get(header::CONTENT_DISPOSITION).unwrap(),
            "inline; filename=\"symlink-test.png\""
        );
    }

    #[actix_rt::test]
    async fn test_index_with_show_files_listing() {
        let service = Files::new(".", ".")
            .index_file("lib.rs")
            .show_files_listing()
            .new_service(())
            .await
            .unwrap();

        // Serve the index if exists
        let req = TestRequest::default().uri("/src").to_srv_request();
        let resp = test::call_service(&service, req).await;
        assert_eq!(resp.status(), StatusCode::OK);
        assert_eq!(
            resp.headers().get(header::CONTENT_TYPE).unwrap(),
            "text/x-rust"
        );

        // Show files listing, otherwise.
        let req = TestRequest::default().uri("/tests").to_srv_request();
        let resp = test::call_service(&service, req).await;
        assert_eq!(
            resp.headers().get(header::CONTENT_TYPE).unwrap(),
            "text/html; charset=utf-8"
        );
        let bytes = test::read_body(resp).await;
        assert!(format!("{:?}", bytes).contains("/tests/test.png"));
    }

    #[actix_rt::test]
    async fn test_path_filter() {
        // prevent searching subdirectories
        let st = Files::new("/", ".")
            .path_filter(|path, _| path.components().count() == 1)
            .new_service(())
            .await
            .unwrap();

        let req = TestRequest::with_uri("/Cargo.toml").to_srv_request();
        let resp = test::call_service(&st, req).await;
        assert_eq!(resp.status(), StatusCode::OK);

        let req = TestRequest::with_uri("/src/lib.rs").to_srv_request();
        let resp = test::call_service(&st, req).await;
        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
    }

    #[actix_rt::test]
    async fn test_default_handler_filter() {
        let st = Files::new("/", ".")
            .default_handler(|req: ServiceRequest| async {
                Ok(req.into_response(HttpResponse::Ok().body("default content")))
            })
            .path_filter(|path, _| path.extension() == Some("png".as_ref()))
            .new_service(())
            .await
            .unwrap();
        let req = TestRequest::with_uri("/Cargo.toml").to_srv_request();
        let resp = test::call_service(&st, req).await;

        assert_eq!(resp.status(), StatusCode::OK);
        let bytes = test::read_body(resp).await;
        assert_eq!(bytes, web::Bytes::from_static(b"default content"));
    }
}


================================================
FILE: actix-files/src/named.rs
================================================
use std::{
    fs::Metadata,
    io,
    path::{Path, PathBuf},
    time::{SystemTime, UNIX_EPOCH},
};

use actix_web::{
    body::{self, BoxBody, SizedStream},
    dev::{
        self, AppService, HttpServiceFactory, ResourceDef, Service, ServiceFactory, ServiceRequest,
        ServiceResponse,
    },
    http::{
        header::{
            self, Charset, ContentDisposition, ContentEncoding, DispositionParam, DispositionType,
            ExtendedValue,
        },
        StatusCode,
    },
    Error, HttpMessage, HttpRequest, HttpResponse, Responder,
};
use bitflags::bitflags;
use derive_more::{Deref, DerefMut};
use futures_core::future::LocalBoxFuture;
use mime::Mime;

use crate::{encoding::equiv_utf8_text, range::HttpRange};

bitflags! {
    #[derive(Debug, Clone, Copy)]
    pub(crate) struct Flags: u8 {
        const ETAG =                0b0000_0001;
        const LAST_MD =             0b0000_0010;
        const CONTENT_DISPOSITION = 0b0000_0100;
        const PREFER_UTF8 =         0b0000_1000;
    }
}

impl Default for Flags {
    fn default() -> Self {
        Flags::from_bits_truncate(0b0000_1111)
    }
}

/// A file with an associated name.
///
/// `NamedFile` can be registered as services:
/// ```
/// use actix_web::App;
/// use actix_files::NamedFile;
///
/// # async fn run() -> Result<(), Box<dyn std::error::Error>> {
/// let file = NamedFile::open_async("./static/index.html").await?;
/// let app = App::new().service(file);
/// # Ok(())
/// # }
/// ```
///
/// They can also be returned from handlers:
/// ```
/// use actix_web::{Responder, get};
/// use actix_files::NamedFile;
///
/// #[get("/")]
/// async fn index() -> impl Responder {
///     NamedFile::open_async("./static/index.html").await
/// }
/// ```
#[derive(Debug, Deref, DerefMut)]
pub struct NamedFile {
    #[deref]
    #[deref_mut]
    file: File,
    path: PathBuf,
    modified: Option<SystemTime>,
    pub(crate) md: Metadata,
    pub(crate) flags: Flags,
    pub(crate) status_code: StatusCode,
    pub(crate) content_type: Mime,
    pub(crate) content_disposition: ContentDisposition,
    pub(crate) encoding: Option<ContentEncoding>,
    pub(crate) read_mode_threshold: u64,
}

#[cfg(not(feature = "experimental-io-uring"))]
pub(crate) use std::fs::File;

#[cfg(feature = "experimental-io-uring")]
pub(crate) use tokio_uring::fs::File;

use super::chunked;

pub(crate) fn get_content_type_and_disposition(
    path: &Path,
) -> Result<(mime::Mime, ContentDisposition), io::Error> {
    let filename = match path.file_name() {
        Some(name) => name.to_string_lossy(),
        None => {
            return Err(io::Error::new(
                io::ErrorKind::InvalidInput,
                "Provided path has no filename",
            ));
        }
    };

    let ct = mime_guess::from_path(path).first_or_octet_stream();

    let disposition = match ct.type_() {
        mime::IMAGE | mime::TEXT | mime::AUDIO | mime::VIDEO => DispositionType::Inline,
        mime::APPLICATION => match ct.subtype() {
            mime::JAVASCRIPT | mime::JSON => DispositionType::Inline,
            name if name == "wasm" || name == "xhtml" => DispositionType::Inline,
            _ => DispositionType::Attachment,
        },
        _ => DispositionType::Attachment,
    };

    // replace special characters in filenames which could occur on some filesystems
    let filename_s = filename
        .replace('\n', "%0A") // \n line break
        .replace('\x0B', "%0B") // \v vertical tab
        .replace('\x0C', "%0C") // \f form feed
        .replace('\r', "%0D"); // \r carriage return
    let mut parameters = vec![DispositionParam::Filename(filename_s)];

    if !filename.is_ascii() {
        parameters.push(DispositionParam::FilenameExt(ExtendedValue {
            charset: Charset::Ext(String::from("UTF-8")),
            language_tag: None,
            value: filename.into_owned().into_bytes(),
        }))
    }

    let cd = ContentDisposition {
        disposition,
        parameters,
    };

    Ok((ct, cd))
}

impl NamedFile {
    /// Creates an instance from a previously opened file.
    ///
    /// The given `path` need not exist and is only used to determine the `ContentType` and
    /// `ContentDisposition` headers.
    ///
    /// # Examples
    /// ```ignore
    /// use std::{
    ///     io::{self, Write as _},
    ///     env,
    ///     fs::File
    /// };
    /// use actix_files::NamedFile;
    ///
    /// let mut file = File::create("foo.txt")?;
    /// file.write_all(b"Hello, world!")?;
    /// let named_file = NamedFile::from_file(file, "bar.txt")?;
    /// # std::fs::remove_file("foo.txt");
    /// Ok(())
    /// ```
    pub fn from_file<P: AsRef<Path>>(file: File, path: P) -> io::Result<NamedFile> {
        let path = path.as_ref().to_path_buf();

        // Get the name of the file and use it to construct default Content-Type
        // and Content-Disposition values
        let (content_type, content_disposition) = get_content_type_and_disposition(&path)?;

        let md = {
            #[cfg(not(feature = "experimental-io-uring"))]
            {
                file.metadata()?
            }

            #[cfg(feature = "experimental-io-uring")]
            {
                use std::os::unix::prelude::{AsRawFd, FromRawFd};

                let fd = file.as_raw_fd();

                // SAFETY: fd is borrowed and lives longer than the unsafe block
                unsafe {
                    let file = std::fs::File::from_raw_fd(fd);
                    let md = file.metadata();
                    // SAFETY: forget the fd before exiting block in success or error case but don't
                    // run destructor (that would close file handle)
                    std::mem::forget(file);
                    md?
                }
            }
        };

        let modified = md.modified().ok();
        let encoding = None;

        Ok(NamedFile {
            path,
            file,
            content_type,
            content_disposition,
            md,
            modified,
            encoding,
            status_code: StatusCode::OK,
            flags: Flags::default(),
            read_mode_threshold: 0,
        })
    }

    /// Attempts to open a file in read-only mode.
    ///
    /// # Examples
    /// ```
    /// use actix_files::NamedFile;
    /// let file = NamedFile::open("foo.txt");
    /// ```
    #[cfg(not(feature = "experimental-io-uring"))]
    pub fn open<P: AsRef<Path>>(path: P) -> io::Result<NamedFile> {
        let file = File::open(&path)?;
        Self::from_file(file, path)
    }

    /// Attempts to open a file asynchronously in read-only mode.
    ///
    /// When the `experimental-io-uring` crate feature is enabled, this will be async. Otherwise, it
    /// will behave just like `open`.
    ///
    /// # Examples
    /// ```
    /// use actix_files::NamedFile;
    /// # async fn open() {
    /// let file = NamedFile::open_async("foo.txt").await.unwrap();
    /// # }
    /// ```
    pub async fn open_async<P: AsRef<Path>>(path: P) -> io::Result<NamedFile> {
        let file = {
            #[cfg(not(feature = "experimental-io-uring"))]
            {
                File::open(&path)?
            }

            #[cfg(feature = "experimental-io-uring")]
            {
                File::open(&path).await?
            }
        };

        Self::from_file(file, path)
    }

    /// Returns reference to the underlying file object.
    #[inline]
    pub fn file(&self) -> &File {
        &self.file
    }

    /// Returns the filesystem path to this file.
    ///
    /// # Examples
    /// ```
    /// # use std::io;
    /// use actix_files::NamedFile;
    ///
    /// # async fn path() -> io::Result<()> {
    /// let file = NamedFile::open_async("test.txt").await?;
    /// assert_eq!(file.path().as_os_str(), "foo.txt");
    /// # Ok(())
    /// # }
    /// ```
    #[inline]
    pub fn path(&self) -> &Path {
        self.path.as_path()
    }

    /// Returns the time the file was last modified.
    ///
    /// Returns `None` only on unsupported platforms; see [`std::fs::Metadata::modified()`].
    /// Therefore, it is usually safe to unwrap this.
    #[inline]
    pub fn modified(&self) -> Option<SystemTime> {
        self.modified
    }

    /// Returns the filesystem metadata associated with this file.
    #[inline]
    pub fn metadata(&self) -> &Metadata {
        &self.md
    }

    /// Returns the `Content-Type` header that will be used when serving this file.
    #[inline]
    pub fn content_type(&self) -> &Mime {
        &self.content_type
    }

    /// Returns the `Content-Disposition` that will be used when serving this file.
    #[inline]
    pub fn content_disposition(&self) -> &ContentDisposition {
        &self.content_disposition
    }

    /// Returns the `Content-Encoding` that will be used when serving this file.
    ///
    /// A return value of `None` indicates that the content is not already using a compressed
    /// representation and may be subject to compression downstream.
    #[inline]
    pub fn content_encoding(&self) -> Option<ContentEncoding> {
        self.encoding
    }

    /// Set response status code.
    #[deprecated(since = "0.7.0", note = "Prefer `Responder::customize()`.")]
    pub fn set_status_code(mut self, status: StatusCode) -> Self {
        self.status_code = status;
        self
    }

    /// Sets the `Content-Type` header that will be used when serving this file. By default the
    /// `Content-Type` is inferred from the filename extension.
    #[inline]
    pub fn set_content_type(mut self, mime_type: Mime) -> Self {
        self.content_type = mime_type;
        self
    }

    /// Set the Content-Disposition for serving this file. This allows changing the
    /// `inline/attachment` disposition as well as the filename sent to the peer.
    ///
    /// By default the disposition is `inline` for `text/*`, `image/*`, `video/*` and
    /// `application/{javascript, json, wasm}` mime types, and `attachment` otherwise, and the
    /// filename is taken from the path provided in the `open` method after converting it to UTF-8
    /// (using `to_string_lossy`).
    #[inline]
    pub fn set_content_disposition(mut self, cd: ContentDisposition) -> Self {
        self.content_disposition = cd;
        self.flags.insert(Flags::CONTENT_DISPOSITION);
        self
    }

    /// Disables `Content-Disposition` header.
    ///
    /// By default, the `Content-Disposition` header is sent.
    #[inline]
    pub fn disable_content_disposition(mut self) -> Self {
        self.flags.remove(Flags::CONTENT_DISPOSITION);
        self
    }

    /// Sets content encoding for this file.
    ///
    /// This prevents the `Compress` middleware from modifying the file contents and signals to
    /// browsers/clients how to decode it. For example, if serving a compressed HTML file (e.g.,
    /// `index.html.gz`) then use `.set_content_encoding(ContentEncoding::Gzip)`.
    #[inline]
    pub fn set_content_encoding(mut self, enc: ContentEncoding) -> Self {
        self.encoding = Some(enc);
        self
    }

    /// Sets the size threshold that determines file read mode (sync/async).
    ///
    /// When a file is smaller than the threshold (bytes), the reader will use synchronous
    /// (blocking) file reads. For larger files, it switches to async reads to avoid blocking the
    /// main thread.
    ///
    /// Tweaking this value according to your expected usage may lead to significant performance
    /// gains (or losses in other handlers, if `size` is too high).
    ///
    /// When the `experimental-io-uring` crate feature is enabled, file reads are always async.
    ///
    /// Default is 0, meaning all files are read asynchronously.
    pub fn read_mode_threshold(mut self, size: u64) -> Self {
        self.read_mode_threshold = size;
        self
    }

    /// Specifies whether to return `ETag` header in response.
    ///
    /// Default is true.
    #[inline]
    pub fn use_etag(mut self, value: bool) -> Self {
        self.flags.set(Flags::ETAG, value);
        self
    }

    /// Specifies whether to return `Last-Modified` header in response.
    ///
    /// Default is true.
    #[inline]
    pub fn use_last_modified(mut self, value: bool) -> Self {
        self.flags.set(Flags::LAST_MD, value);
        self
    }

    /// Specifies whether text responses should signal a UTF-8 encoding.
    ///
    /// Default is false (but will default to true in a future version).
    #[inline]
    pub fn prefer_utf8(mut self, value: bool) -> Self {
        self.flags.set(Flags::PREFER_UTF8, value);
        self
    }

    /// Creates an `ETag` in a format is similar to Apache's.
    pub(crate) fn etag(&self) -> Option<header::EntityTag> {
        let mtime = self.modified?;

        Some({
            let ino = {
                #[cfg(unix)]
                {
                    #[cfg(unix)]
                    use std::os::unix::fs::MetadataExt as _;

                    self.md.ino()
                }

                #[cfg(not(unix))]
                {
                    0
                }
            };

            // Don't panic for pre-epoch modification times. Encode the timestamp as seconds and
            // sub-second nanoseconds relative to the UNIX epoch, allowing negative values.
            let (secs, nanos) = match mtime.duration_since(UNIX_EPOCH) {
                Ok(dur) => (dur.as_secs() as i64, dur.subsec_nanos()),
                Err(err) => {
                    let dur = err.duration();

                    // For timestamps before the epoch, represent the time as a negative seconds
                    // offset with positive nanoseconds (like POSIX timespec).
                    if dur.subsec_nanos() == 0 {
                        (-(dur.as_secs() as i64), 0)
                    } else {
                        (
                            -(dur.as_secs() as i64) - 1,
                            1_000_000_000 - dur.subsec_nanos(),
                        )
                    }
                }
            };

            header::EntityTag::new_strong(format!(
                "{:x}:{:x}:{:x}:{:x}",
                ino,
                self.md.len(),
                secs as u64,
                nanos
            ))
        })
    }

    pub(crate) fn last_modified(&self) -> Option<header::HttpDate> {
        let mtime = self.modified?;

        // avoid panic in `httpdate` crate when formatting as an HTTP date
        // see: https://github.com/actix/actix-web/issues/2748
        //
        // httpdate supports dates in range [1970, 9999); see:
        // https://github.com/seanmonstar/httpdate/blob/v1.0.3/src/date.rs
        let dur = mtime.duration_since(UNIX_EPOCH).ok()?;
        if dur.as_secs() >= 253_402_300_800 {
            return None;
        }

        Some(mtime.into())
    }

    /// Creates an `HttpResponse` with file as a streaming body.
    pub fn into_response(self, req: &HttpRequest) -> HttpResponse<BoxBody> {
        if self.status_code != StatusCode::OK {
            let mut res = HttpResponse::build(self.status_code);

            let ct = if self.flags.contains(Flags::PREFER_UTF8) {
                equiv_utf8_text(self.content_type.clone())
            } else {
                self.content_type
            };

            res.insert_header((header::CONTENT_TYPE, ct.to_string()));

            if self.flags.contains(Flags::CONTENT_DISPOSITION) {
                res.insert_header((
                    header::CONTENT_DISPOSITION,
                    self.content_disposition.to_string(),
                ));
            }

            if let Some(current_encoding) = self.encoding {
                res.insert_header((header::CONTENT_ENCODING, current_encoding.as_str()));
            }

            let reader =
                chunked::new_chunked_read(self.md.len(), 0, self.file, self.read_mode_threshold);

            return res.streaming(reader);
        }

        let etag = if self.flags.contains(Flags::ETAG) {
            self.etag()
        } else {
            None
        };

        let last_modified = if self.flags.contains(Flags::LAST_MD) {
            self.last_modified()
        } else {
            None
        };

        // check preconditions
        let precondition_failed = if !any_match(etag.as_ref(), req) {
            true
        } else if let (Some(ref m), Some(header::IfUnmodifiedSince(ref since))) =
            (last_modified, req.get_header())
        {
            let t1: SystemTime = (*m).into();
            let t2: SystemTime = (*since).into();

            match (t1.duration_since(UNIX_EPOCH), t2.duration_since(UNIX_EPOCH)) {
                (Ok(t1), Ok(t2)) => t1.as_secs() > t2.as_secs(),
                _ => false,
            }
        } else {
            false
        };

        // check last modified
        let not_modified = if !none_match(etag.as_ref(), req) {
            true
        } else if req.headers().contains_key(header::IF_NONE_MATCH) {
            false
        } else if let (Some(ref m), Some(header::IfModifiedSince(ref since))) =
            (last_modified, req.get_header())
        {
            let t1: SystemTime = (*m).into();
            let t2: SystemTime = (*since).into();

            match (t1.duration_since(UNIX_EPOCH), t2.duration_since(UNIX_EPOCH)) {
                (Ok(t1), Ok(t2)) => t1.as_secs() <= t2.as_secs(),
                _ => false,
            }
        } else {
            false
        };

        let mut res = HttpResponse::build(self.status_code);

        let ct = if self.flags.contains(Flags::PREFER_UTF8) {
            equiv_utf8_text(self.content_type.clone())
        } else {
            self.content_type
        };

        res.insert_header((header::CONTENT_TYPE, ct.to_string()));

        if self.flags.contains(Flags::CONTENT_DISPOSITION) {
            res.insert_header((
                header::CONTENT_DISPOSITION,
                self.content_disposition.to_string(),
            ));
        }

        if let Some(current_encoding) = self.encoding {
            res.insert_header((header::CONTENT_ENCODING, current_encoding.as_str()));
        }

        if let Some(lm) = last_modified {
            res.insert_header((header::LAST_MODIFIED, lm.to_string()));
        }

        if let Some(etag) = etag {
            res.insert_header((header::ETAG, etag.to_string()));
        }

        res.insert_header((header::ACCEPT_RANGES, "bytes"));

        let mut length = self.md.len();
        let mut offset = 0;
        let mut ranged_req = false;

        // check for range header
        if let Some(ranges) = req.headers().get(header::RANGE) {
            if let Ok(ranges_header) = ranges.to_str() {
                if let Some(range) = HttpRange::parse(ranges_header, length)
                    .ok()
                    .and_then(|ranges| ranges.first().copied())
                {
                    ranged_req = true;
                    length = range.length;
                    offset = range.start;

                    res.insert_header((
                        header::CONTENT_RANGE,
                        format!("bytes {}-{}/{}", offset, offset + length - 1, self.md.len()),
                    ));
                } else {
                    res.insert_header((header::CONTENT_RANGE, format!("bytes */{}", length)));
                    return res.status(StatusCode::RANGE_NOT_SATISFIABLE).finish();
                };
            } else {
                return res.status(StatusCode::BAD_REQUEST).finish();
            };
        };

        if precondition_failed {
            return res.status(StatusCode::PRECONDITION_FAILED).finish();
        } else if not_modified {
            return res
                .status(StatusCode::NOT_MODIFIED)
                .body(body::None::new())
                .map_into_boxed_body();
        }

        let reader = chunked::new_chunked_read(length, offset, self.file, self.read_mode_threshold);

        if ranged_req {
            res.status(StatusCode::PARTIAL_CONTENT);
        }

        res.body(SizedStream::new(length, reader))
    }
}

/// Returns true if `req` has no `If-Match` header or one which matches `etag`.
fn any_match(etag: Option<&header::EntityTag>, req: &HttpRequest) -> bool {
    match req.get_header::<header::IfMatch>() {
        None | Some(header::IfMatch::Any) => true,

        Some(header::IfMatch::Items(ref items)) => {
            if let Some(some_etag) = etag {
                for item in items {
                    if item.strong_eq(some_etag) {
                        return true;
                    }
                }
            }

            false
        }
    }
}

/// Returns true if `req` doesn't have an `If-None-Match` header matching `req`.
fn none_match(etag: Option<&header::EntityTag>, req: &HttpRequest) -> bool {
    match req.get_header::<header::IfNoneMatch>() {
        Some(header::IfNoneMatch::Any) => false,

        Some(header::IfNoneMatch::Items(ref items)) => {
            if let Some(some_etag) = etag {
                for item in items {
                    if item.weak_eq(some_etag) {
                        return false;
                    }
                }
            }

            true
        }

        None => true,
    }
}

impl Responder for NamedFile {
    type Body = BoxBody;

    fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body> {
        self.into_response(req)
    }
}

impl ServiceFactory<ServiceRequest> for NamedFile {
    type Response = ServiceResponse;
    type Error = Error;
    type Config = ();
    type Service = NamedFileService;
    type InitError = ();
    type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;

    fn new_service(&self, _: ()) -> Self::Future {
        let service = NamedFileService {
            path: self.path.clone(),
        };

        Box::pin(async move { Ok(service) })
    }
}

#[doc(hidden)]
#[derive(Debug)]
pub struct NamedFileService {
    path: PathBuf,
}

impl Service<ServiceRequest> for NamedFileService {
    type Response = ServiceResponse;
    type Error = Error;
    type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;

    dev::always_ready!();

    fn call(&self, req: ServiceRequest) -> Self::Future {
        let (req, _) = req.into_parts();

        let path = self.path.clone();
        Box::pin(async move {
            let file = NamedFile::open_async(path).await?;
            let res = file.into_response(&req);
            Ok(ServiceResponse::new(req, res))
        })
    }
}

impl HttpServiceFactory for NamedFile {
    fn register(self, config: &mut AppService) {
        config.register_service(
            ResourceDef::root_prefix(self.path.to_string_lossy().as_ref()),
            None,
            self,
            None,
        )
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn audio_files_use_inline_content_disposition() {
        let (_ct, cd) = get_content_type_and_disposition(Path::new("sound.mp3")).unwrap();
        assert_eq!(cd.disposition, DispositionType::Inline);
    }
}


================================================
FILE: actix-files/src/path_buf.rs
================================================
use std::{
    path::{Component, Path, PathBuf},
    str::FromStr,
};

use actix_utils::future::{ready, Ready};
use actix_web::{dev::Payload, FromRequest, HttpRequest};

use crate::error::UriSegmentError;

/// Secure Path Traversal Guard
///
/// This struct parses a request-uri [`PathBuf`](std::path::PathBuf)
#[derive(Debug, PartialEq, Eq)]
pub struct PathBufWrap(PathBuf);

impl FromStr for PathBufWrap {
    type Err = UriSegmentError;

    fn from_str(path: &str) -> Result<Self, Self::Err> {
        Self::parse_path(path, false)
    }
}

impl PathBufWrap {
    /// Parse a safe path from the unprocessed tail of a supplied
    /// [`HttpRequest`](actix_web::HttpRequest), given the choice of allowing hidden files to be
    /// considered valid segments.
    ///
    /// This uses [`HttpRequest::match_info`](actix_web::HttpRequest::match_info) and
    /// [`Path::unprocessed`](actix_web::dev::Path::unprocessed), which returns the part of the
    /// path not matched by route patterns. This is useful for mounted services (eg. `Files`),
    /// where only the tail should be parsed.
    ///
    /// Path traversal is guarded by this method.
    #[inline]
    pub fn parse_unprocessed_req(
        req: &HttpRequest,
        hidden_files: bool,
    ) -> Result<Self, UriSegmentError> {
        Self::parse_path(req.match_info().unprocessed(), hidden_files)
    }

    /// Parse a safe path from the full request path of a supplied
    /// [`HttpRequest`](actix_web::HttpRequest), given the choice of allowing hidden files to be
    /// considered valid segments.
    ///
    /// This uses [`HttpRequest::path`](actix_web::HttpRequest::path), and is more appropriate
    /// for non-mounted handlers that want the entire request path.
    ///
    /// Path traversal is guarded by this method.
    #[inline]
    pub fn parse_req_path(req: &HttpRequest, hidden_files: bool) -> Result<Self, UriSegmentError> {
        Self::parse_path(req.path(), hidden_files)
    }

    /// Parse a path, giving the choice of allowing hidden files to be considered valid segments.
    ///
    /// Path traversal is guarded by this method.
    pub fn parse_path(path: &str, hidden_files: bool) -> Result<Self, UriSegmentError> {
        let mut buf = PathBuf::new();

        // equivalent to `path.split('/').count()`
        let mut segment_count = path.matches('/').count() + 1;

        // we can decode the whole path here (instead of per-segment decoding)
        // because we will reject `%2F` in paths using `segment_count`.
        let path = percent_encoding::percent_decode_str(path)
            .decode_utf8()
            .map_err(|_| UriSegmentError::NotValidUtf8)?;

        // disallow decoding `%2F` into `/`
        if segment_count != path.matches('/').count() + 1 {
            return Err(UriSegmentError::BadChar('/'));
        }

        for segment in path.split('/') {
            if segment == ".." {
                segment_count -= 1;
                buf.pop();
            } else if !hidden_files && segment.starts_with('.') {
                return Err(UriSegmentError::BadStart('.'));
            } else if segment.starts_with('*') {
                return Err(UriSegmentError::BadStart('*'));
            } else if segment.ends_with(':') {
                return Err(UriSegmentError::BadEnd(':'));
            } else if segment.ends_with('>') {
                return Err(UriSegmentError::BadEnd('>'));
            } else if segment.ends_with('<') {
                return Err(UriSegmentError::BadEnd('<'));
            } else if segment.is_empty() {
                segment_count -= 1;
                continue;
            } else if cfg!(windows) && segment.contains('\\') {
                return Err(UriSegmentError::BadChar('\\'));
            } else if cfg!(windows) && segment.contains(':') {
                return Err(UriSegmentError::BadChar(':'));
            } else {
                buf.push(segment)
            }
        }

        // make sure we agree with stdlib parser
        for (i, component) in buf.components().enumerate() {
            assert!(
                matches!(component, Component::Normal(_)),
                "component `{:?}` is not normal",
                component
            );
            assert!(i < segment_count);
        }

        Ok(PathBufWrap(buf))
    }
}

impl AsRef<Path> for PathBufWrap {
    fn as_ref(&self) -> &Path {
        self.0.as_ref()
    }
}

impl FromRequest for PathBufWrap {
    type Error = UriSegmentError;
    type Future = Ready<Result<Self, Self::Error>>;

    fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
        // Uses the unprocessed tail of the request path and disallows hidden files.
        ready(req.match_info().unprocessed().parse())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_path_buf() {
        assert_eq!(
            PathBufWrap::from_str("/test/.tt").map(|t| t.0),
            Err(UriSegmentError::BadStart('.'))
        );
        assert_eq!(
            PathBufWrap::from_str("/test/*tt").map(|t| t.0),
            Err(UriSegmentError::BadStart('*'))
        );
        assert_eq!(
            PathBufWrap::from_str("/test/tt:").map(|t| t.0),
            Err(UriSegmentError::BadEnd(':'))
        );
        assert_eq!(
            PathBufWrap::from_str("/test/tt<").map(|t| t.0),
            Err(UriSegmentError::BadEnd('<'))
        );
        assert_eq!(
            PathBufWrap::from_str("/test/tt>").map(|t| t.0),
            Err(UriSegmentError::BadEnd('>'))
        );
        assert_eq!(
            PathBufWrap::from_str("/seg1/seg2/").unwrap().0,
            PathBuf::from_iter(vec!["seg1", "seg2"])
        );
        assert_eq!(
            PathBufWrap::from_str("/seg1/../seg2/").unwrap().0,
            PathBuf::from_iter(vec!["seg2"])
        );
    }

    #[test]
    fn test_parse_path() {
        assert_eq!(
            PathBufWrap::parse_path("/test/.tt", false).map(|t| t.0),
            Err(UriSegmentError::BadStart('.'))
        );

        assert_eq!(
            PathBufWrap::parse_path("/test/.tt", true).unwrap().0,
            PathBuf::from_iter(vec!["test", ".tt"])
        );
    }

    #[test]
    fn path_traversal() {
        assert_eq!(
            PathBufWrap::parse_path("/../README.md", false).unwrap().0,
            PathBuf::from_iter(vec!["README.md"])
        );

        assert_eq!(
            PathBufWrap::parse_path("/../README.md", true).unwrap().0,
            PathBuf::from_iter(vec!["README.md"])
        );

        assert_eq!(
            PathBufWrap::parse_path("/../../../../../../../../../../etc/passwd", false)
                .unwrap()
                .0,
            PathBuf::from_iter(vec!["etc/passwd"])
        );
    }

    #[test]
    #[cfg_attr(windows, should_panic)]
    fn windows_drive_traversal() {
        // detect issues in windows that could lead to path traversal
        // see <https://github.com/SergioBenitez/Rocket/issues/1949

        assert_eq!(
            PathBufWrap::parse_path("C:test.txt", false).unwrap().0,
            PathBuf::from_iter(vec!["C:test.txt"])
        );

        assert_eq!(
            PathBufWrap::parse_path("C:../whatever", false).unwrap().0,
            PathBuf::from_iter(vec!["C:../whatever"])
        );

        assert_eq!(
            PathBufWrap::parse_path(":test.txt", false).unwrap().0,
            PathBuf::from_iter(vec![":test.txt"])
        );
    }
}


================================================
FILE: actix-files/src/range.rs
================================================
use std::fmt;

use derive_more::Error;

/// Copy of `http_range::HttpRangeParseError`.
#[derive(Debug, Clone)]
enum HttpRangeParseError {
    InvalidRange,
    NoOverlap,
}

impl From<http_range::HttpRangeParseError> for HttpRangeParseError {
    fn from(err: http_range::HttpRangeParseError) -> Self {
        match err {
            http_range::HttpRangeParseError::InvalidRange => Self::InvalidRange,
            http_range::HttpRangeParseError::NoOverlap => Self::NoOverlap,
        }
    }
}

#[derive(Debug, Clone, Error)]
#[non_exhaustive]
pub struct ParseRangeErr(#[error(not(source))] HttpRangeParseError);

impl fmt::Display for ParseRangeErr {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str("invalid Range header: ")?;
        f.write_str(match self.0 {
            HttpRangeParseError::InvalidRange => "invalid syntax",
            HttpRangeParseError::NoOverlap => "range starts after end of content",
        })
    }
}

/// HTTP Range header representation.
#[derive(Debug, Clone, Copy)]
pub struct HttpRange {
    /// Start of range.
    pub start: u64,

    /// Length of range.
    pub length: u64,
}

impl HttpRange {
    /// Parses Range HTTP header string as per RFC 2616.
    ///
    /// `header` is HTTP Range header (e.g. `bytes=0-9`).
    /// `size` is full size of response (file).
    pub fn parse(header: &str, size: u64) -> Result<Vec<HttpRange>, ParseRangeErr> {
        let ranges =
            http_range::HttpRange::parse(header, size).map_err(|err| ParseRangeErr(err.into()))?;

        Ok(ranges
            .iter()
            .map(|range| HttpRange {
                start: range.start,
                length: range.length,
            })
            .collect())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    struct T(&'static str, u64, Vec<HttpRange>);

    #[test]
    fn test_parse() {
        let tests = vec![
            T("", 0, vec![]),
            T("", 1000, vec![]),
            T("foo", 0, vec![]),
            T("bytes=", 0, vec![]),
            T("bytes=7", 10, vec![]),
            T("bytes= 7 ", 10, vec![]),
            T("bytes=1-", 0, vec![]),
            T("bytes=5-4", 10, vec![]),
            T("bytes=0-2,5-4", 10, vec![]),
            T("bytes=2-5,4-3", 10, vec![]),
            T("bytes=--5,4--3", 10, vec![]),
            T("bytes=A-", 10, vec![]),
            T("bytes=A- ", 10, vec![]),
            T("bytes=A-Z", 10, vec![]),
            T("bytes= -Z", 10, vec![]),
            T("bytes=5-Z", 10, vec![]),
            T("bytes=Ran-dom, garbage", 10, vec![]),
            T("bytes=0x01-0x02", 10, vec![]),
            T("bytes=         ", 10, vec![]),
            T("bytes= , , ,   ", 10, vec![]),
            T(
                "bytes=0-9",
                10,
                vec![HttpRange {
                    start: 0,
                    length: 10,
                }],
            ),
            T(
                "bytes=0-",
                10,
                vec![HttpRange {
                    start: 0,
                    length: 10,
                }],
            ),
            T(
                "bytes=5-",
                10,
                vec![HttpRange {
                    start: 5,
                    length: 5,
                }],
            ),
            T(
                "bytes=0-20",
                10,
                vec![HttpRange {
                    start: 0,
                    length: 10,
                }],
            ),
            T(
                "bytes=15-,0-5",
                10,
                vec![HttpRange {
                    start: 0,
                    length: 6,
                }],
            ),
            T(
                "bytes=1-2,5-",
                10,
                vec![
                    HttpRange {
                        start: 1,
                        length: 2,
                    },
                    HttpRange {
                        start: 5,
                        length: 5,
                    },
                ],
            ),
            T(
                "bytes=-2 , 7-",
                11,
                vec![
                    HttpRange {
                        start: 9,
                        length: 2,
                    },
                    HttpRange {
                        start: 7,
                        length: 4,
                    },
                ],
            ),
            T(
                "bytes=0-0 ,2-2, 7-",
                11,
                vec![
                    HttpRange {
                        start: 0,
                        length: 1,
                    },
                    HttpRange {
                        start: 2,
                        length: 1,
                    },
                    HttpRange {
                        start: 7,
                        length: 4,
                    },
                ],
            ),
            T(
                "bytes=-5",
                10,
                vec![HttpRange {
                    start: 5,
                    length: 5,
                }],
            ),
            T(
                "bytes=-15",
                10,
                vec![HttpRange {
                    start: 0,
                    length: 10,
                }],
            ),
            T(
                "bytes=0-499",
                10000,
                vec![HttpRange {
                    start: 0,
                    length: 500,
                }],
            ),
            T(
                "bytes=500-999",
                10000,
                vec![HttpRange {
                    start: 500,
                    length: 500,
                }],
            ),
            T(
                "bytes=-500",
                10000,
                vec![HttpRange {
                    start: 9500,
                    length: 500,
                }],
            ),
            T(
                "bytes=9500-",
                10000,
                vec![HttpRange {
                    start: 9500,
                    length: 500,
                }],
            ),
            T(
                "bytes=0-0,-1",
                10000,
                vec![
                    HttpRange {
                        start: 0,
                        length: 1,
                    },
                    HttpRange {
                        start: 9999,
                        length: 1,
                    },
                ],
            ),
            T(
                "bytes=500-600,601-999",
                10000,
                vec![
                    HttpRange {
                        start: 500,
                        length: 101,
                    },
                    HttpRange {
                        start: 601,
                        length: 399,
                    },
                ],
            ),
            T(
                "bytes=500-700,601-999",
                10000,
                vec![
                    HttpRange {
                        start: 500,
                        length: 201,
                    },
                    HttpRange {
                        start: 601,
                        length: 399,
                    },
                ],
            ),
            // Match Apache laxity:
            T(
                "bytes=   1 -2   ,  4- 5, 7 - 8 , ,,",
                11,
                vec![
                    HttpRange {
                        start: 1,
                        length: 2,
                    },
                    HttpRange {
                        start: 4,
                        length: 2,
                    },
                    HttpRange {
                        start: 7,
                        length: 2,
                    },
                ],
            ),
        ];

        for t in tests {
            let header = t.0;
            let size = t.1;
            let expected = t.2;

            let res = HttpRange::parse(header, size);

            if let Err(err) = res {
                if expected.is_empty() {
                    continue;
                } else {
                    panic!("parse({header}, {size}) returned error {err:?}");
                }
            }

            let got = res.unwrap();

            if got.len() != expected.len() {
                panic!(
                    "len(parseRange({}, {})) = {}, want {}",
                    header,
                    size,
                    got.len(),
                    expected.len()
                );
            }

            for i in 0..expected.len() {
                if got[i].start != expected[i].start {
                    panic!(
                        "parseRange({}, {})[{}].start = {}, want {}",
                        header, size, i, got[i].start, expected[i].start
                    )
                }
                if got[i].length != expected[i].length {
                    panic!(
                        "parseRange({}, {})[{}].length = {}, want {}",
                        header, size, i, got[i].length, expected[i].length
                    )
                }
            }
        }
    }
}


================================================
FILE: actix-files/src/service.rs
================================================
use std::{
    fmt, io,
    ops::Deref,
    path::{Path, PathBuf},
    rc::Rc,
};

use actix_web::{
    body::BoxBody,
    dev::{self, Service, ServiceRequest, ServiceResponse},
    error::Error,
    guard::Guard,
    http::{header, Method},
    HttpResponse,
};
use futures_core::future::LocalBoxFuture;

use crate::{
    named, Directory, DirectoryRenderer, FilesError, HttpService, MimeOverride, NamedFile,
    PathBufWrap, PathFilter,
};

/// Assembled file serving service.
#[derive(Clone)]
pub struct FilesService(pub(crate) Rc<FilesServiceInner>);

impl Deref for FilesService {
    type Target = FilesServiceInner;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

pub struct FilesServiceInner {
    pub(crate) directory: PathBuf,
    pub(crate) index: Option<String>,
    pub(crate) show_index: bool,
    pub(crate) redirect_to_slash: bool,
    pub(crate) default: Option<HttpService>,
    pub(crate) renderer: Rc<DirectoryRenderer>,
    pub(crate) mime_override: Option<Rc<MimeOverride>>,
    pub(crate) path_filter: Option<Rc<PathFilter>>,
    pub(crate) file_flags: named::Flags,
    pub(crate) guards: Option<Rc<dyn Guard>>,
    pub(crate) hidden_files: bool,
    pub(crate) try_compressed: bool,
    pub(crate) size_threshold: u64,
    pub(crate) with_permanent_redirect: bool,
}

impl fmt::Debug for FilesServiceInner {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str("FilesServiceInner")
    }
}

impl FilesService {
    async fn handle_err(
        &self,
        err: io::Error,
        req: ServiceRequest,
    ) -> Result<ServiceResponse, Error> {
        log::debug!("error handling {}: {}", req.path(), err);

        if let Some(ref default) = self.default {
            default.call(req).await
        } else {
            Ok(req.error_response(err))
        }
    }

    fn serve_named_file_with_encoding(
        &self,
        req: ServiceRequest,
        mut named_file: NamedFile,
        encoding: header::ContentEncoding,
    ) -> ServiceResponse {
        if let Some(ref mime_override) = self.mime_override {
            let new_disposition = mime_override(&named_file.content_type.type_());
            named_file.content_disposition.disposition = new_disposition;
        }
        named_file.flags = self.file_flags;

        let (req, _) = req.into_parts();
        let mut res = named_file
            .read_mode_threshold(self.size_threshold)
            .into_response(&req);

        let header_value = match encoding {
            header::ContentEncoding::Brotli => Some("br"),
            header::ContentEncoding::Gzip => Some("gzip"),
            header::ContentEncoding::Zstd => Some("zstd"),
            header::ContentEncoding::Identity => None,
            // Only variants in SUPPORTED_PRECOMPRESSION_ENCODINGS can occur here
            _ => unreachable!(),
        };
        if let Some(header_value) = header_value {
            res.headers_mut().insert(
                header::CONTENT_ENCODING,
                header::HeaderValue::from_static(header_value),
            );
            // Response representation varies by Accept-Encoding when serving pre-compressed assets.
            res.headers_mut().append(
                header::VARY,
                header::HeaderValue::from_static("accept-encoding"),
            );
        }
        ServiceResponse::new(req, res)
    }

    fn serve_named_file(&self, req: ServiceRequest, named_file: NamedFile) -> ServiceResponse {
        self.serve_named_file_with_encoding(req, named_file, header::ContentEncoding::Identity)
    }

    fn show_index(&self, req: ServiceRequest, path: PathBuf) -> ServiceResponse {
        let dir = Directory::new(self.directory.clone(), path);

        let (req, _) = req.into_parts();

        (self.renderer)(&dir, &req).unwrap_or_else(|err| ServiceResponse::from_err(err, req))
    }
}

impl fmt::Debug for FilesService {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str("FilesService")
    }
}

impl Service<ServiceRequest> for FilesService {
    type Response = ServiceResponse<BoxBody>;
    type Error = Error;
    type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;

    dev::always_ready!();

    fn call(&self, req: ServiceRequest) -> Self::Future {
        let is_method_valid = if let Some(guard) = &self.guards {
            // execute user defined guards
            (**guard).check(&req.guard_ctx())
        } else {
            // default behavior
            matches!(*req.method(), Method::HEAD | Method::GET)
        };

        let this = self.clone();

        Box::pin(async move {
            if !is_method_valid {
                return Ok(req.into_response(
                    HttpResponse::MethodNotAllowed()
                        .insert_header(header::ContentType(mime::TEXT_PLAIN_UTF_8))
                        .body("Request did not meet this resource's requirements."),
                ));
            }

            let path_on_disk =
                match PathBufWrap::parse_path(req.match_info().unprocessed(), this.hidden_files) {
                    Ok(item) => item,
                    Err(err) => return Ok(req.error_response(err)),
                };

            if let Some(filter) = &this.path_filter {
                if !filter(path_on_disk.as_ref(), req.head()) {
                    if let Some(ref default) = this.default {
                        return default.call(req).await;
                    } else {
                        return Ok(req.into_response(HttpResponse::NotFound().finish()));
                    }
                }
            }

            // full file path
            let path = this.directory.join(&path_on_disk);

            // Try serving pre-compressed file even if the uncompressed file doesn't exist yet.
            // Still handle directories (index/listing) through the normal branch below.
            if this.try_compressed && !path.is_dir() {
                if let Some((named_file, encoding)) = find_compressed(&req, &path).await {
                    return Ok(this.serve_named_file_with_encoding(req, named_file, encoding));
                }
            }

            if let Err(err) = path.canonicalize() {
                return this.handle_err(err, req).await;
            }

            if path.is_dir() {
                if this.redirect_to_slash
                    && !req.path().ends_with('/')
                    && (this.index.is_some() || this.show_index)
                {
                    let redirect_to = format!("{}/", req.path());

                    let response = if this.with_permanent_redirect {
                        HttpResponse::PermanentRedirect()
                    } else {
                        HttpResponse::TemporaryRedirect()
                    }
                    .insert_header((header::LOCATION, redirect_to))
                    .finish();

                    return Ok(req.into_response(response));
                }

                match this.index {
                    Some(ref index) => {
                        let named_path = path.join(index);
                        if this.try_compressed {
                            if let Some((named_file, encoding)) =
                                find_compressed(&req, &named_path).await
                            {
                                return Ok(
                                    this.serve_named_file_with_encoding(req, named_file, encoding)
                                );
                            }
                        }
                        // fallback to the uncompressed version
                        match NamedFile::open_async(named_path).await {
                            Ok(named_file) => Ok(this.serve_named_file(req, named_file)),
                            Err(_) if this.show_index => Ok(this.show_index(req, path)),
                            Err(err) => this.handle_err(err, req).await,
                        }
                    }
                    None if this.show_index => Ok(this.show_index(req, path)),
                    None => Ok(ServiceResponse::from_err(
                        FilesError::IsDirectory,
                        req.into_parts().0,
                    )),
                }
            } else {
                match NamedFile::open_async(&path).await {
                    Ok(named_file) => Ok(this.serve_named_file(req, named_file)),
                    Err(err) => this.handle_err(err, req).await,
                }
            }
        })
    }
}

/// Flate doesn't have an accepted file extension, so it is not included here.
const SUPPORTED_PRECOMPRESSION_ENCODINGS: &[header::ContentEncoding] = &[
    header::ContentEncoding::Brotli,
    header::ContentEncoding::Gzip,
    header::ContentEncoding::Zstd,
    header::ContentEncoding::Identity,
];

/// Searches disk for an acceptable alternate encoding of the content at the given path, as
/// preferred by the request's `Accept-Encoding` header. Returns the corresponding `NamedFile` with
/// the most appropriate supported encoding, if any exist.
async fn find_compressed(
    req: &ServiceRequest,
    original_path: &Path,
) -> Option<(NamedFile, header::ContentEncoding)> {
    use actix_web::HttpMessage;
    use header::{AcceptEncoding, ContentEncoding, Encoding};

    // Retrieve the content type and content disposition based on the original filename. If we
    // can't get these successfully, don't even try to find a compressed file.
    let (content_type, content_disposition) =
        match crate::named::get_content_type_and_disposition(original_path) {
            Ok(values) => values,
            Err(_) => return None,
        };

    let accept_encoding = req.get_header::<AcceptEncoding>()?;

    let mut supported = SUPPORTED_PRECOMPRESSION_ENCODINGS
        .iter()
        .copied()
        .map(Encoding::Known)
        .collect::<Vec<_>>();

    // Only move the original content-type/disposition into the chosen compressed file once.
    let mut content_type = Some(content_type);
    let mut content_disposition = Some(content_disposition);

    loop {
        // Select next acceptable encoding (honouring q=0 rejections) from remaining supported set.
        let chosen = accept_encoding.negotiate(supported.iter())?;

        let encoding = match chosen {
            Encoding::Known(enc) => enc,
            // No supported encoding should ever be unknown here.
            Encoding::Unknown(_) => return None,
        };

        // Identity indicates there is no acceptable pre-compressed representation.
        if encoding == ContentEncoding::Identity {
            return None;
        }

        let extension = match encoding {
            ContentEncoding::Brotli => ".br",
            ContentEncoding::Gzip => ".gz",
            ContentEncoding::Zstd => ".zst",
            ContentEncoding::Identity => unreachable!(),
            // Only variants in SUPPORTED_PRECOMPRESSION_ENCODINGS can occur here.
            _ => unreachable!(),
        };

        let mut compressed_path = original_path.to_owned();
        let mut filename = compressed_path.file_name()?.to_owned();
        filename.push(extension);
        compressed_path.set_file_name(filename);

        match NamedFile::open_async(&compressed_path).await {
            Ok(mut named_file) => {
                named_file.content_type = content_type.take().unwrap();
                named_file.content_disposition = content_disposition.take().unwrap();
                return Some((named_file, encoding));
            }
            // Ignore errors while searching disk for a suitable encoding.
            Err(_) => {
                supported.retain(|enc| enc != &chosen);
            }
        }
    }
}


================================================
FILE: actix-files/tests/encoding.rs
================================================
use actix_files::{Files, NamedFile};
use actix_web::{
    http::{
        header::{self, HeaderValue},
        StatusCode,
    },
    test::{self, TestRequest},
    web, App,
};

#[actix_web::test]
async fn test_utf8_file_contents() {
    // use default ISO-8859-1 encoding
    let srv = test::init_service(App::new().service(Files::new("/", "./tests"))).await;

    let req = TestRequest::with_uri("/utf8.txt").to_request();
    let res = test::call_service(&srv, req).await;

    assert_eq!(res.status(), StatusCode::OK);
    assert_eq!(
        res.headers().get(header::CONTENT_TYPE),
        Some(&HeaderValue::from_static("text/plain; charset=utf-8")),
    );

    // disable UTF-8 attribute
    let srv =
        test::init_service(App::new().service(Files::new("/", "./tests").prefer_utf8(false))).await;

    let req = TestRequest::with_uri("/utf8.txt").to_request();
    let res = test::call_service(&srv, req).await;

    assert_eq!(res.status(), StatusCode::OK);
    assert_eq!(
        res.headers().get(header::CONTENT_TYPE),
        Some(&HeaderValue::from_static("text/plain")),
    );
}

#[actix_web::test]
async fn test_compression_encodings() {
    use actix_web::body::MessageBody;

    let utf8_txt_len = std::fs::metadata("./tests/utf8.txt").unwrap().len();
    let utf8_txt_br_len = std::fs::metadata("./tests/utf8.txt.br").unwrap().len();
    let utf8_txt_gz_len = std::fs::metadata("./tests/utf8.txt.gz").unwrap().len();

    let srv =
        test::init_service(App::new().service(Files::new("/", "./tests").try_compressed())).await;

    // Select the requested encoding when present
    let mut req = TestRequest::with_uri("/utf8.txt").to_request();
    req.headers_mut().insert(
        header::ACCEPT_ENCODING,
        header::HeaderValue::from_static("gzip"),
    );
    let res = test::call_service(&srv, req).await;

    assert_eq!(res.status(), StatusCode::OK);
    assert_eq!(
        res.headers().get(header::CONTENT_TYPE),
        Some(&HeaderValue::from_static("text/plain; charset=utf-8")),
    );
    assert_eq!(
        res.headers().get(header::CONTENT_ENCODING),
        Some(&HeaderValue::from_static("gzip")),
    );
    assert_eq!(
        res.headers().get(header::VARY),
        Some(&HeaderValue::from_static("accept-encoding")),
    );
    assert_eq!(
        res.into_body().size(),
        actix_web::body::BodySize::Sized(utf8_txt_gz_len),
    );

    // Select the highest priority encoding
    let mut req = TestRequest::with_uri("/utf8.txt").to_request();
    req.headers_mut().insert(
        header::ACCEPT_ENCODING,
        header::HeaderValue::from_static("gzip;q=0.6,br;q=0.8,*"),
    );
    let res = test::call_service(&srv, req).await;

    assert_eq!(res.status(), StatusCode::OK);
    assert_eq!(
        res.headers().get(header::CONTENT_TYPE),
        Some(&HeaderValue::from_static("text/plain; charset=utf-8")),
    );
    assert_eq!(
        res.headers().get(header::CONTENT_ENCODING),
        Some(&HeaderValue::from_static("br")),
    );
    assert_eq!(
        res.headers().get(header::VARY),
        Some(&HeaderValue::from_static("accept-encoding")),
    );
    assert_eq!(
        res.into_body().size(),
        actix_web::body::BodySize::Sized(utf8_txt_br_len),
    );

    // Request encoding that doesn't exist on disk and fallback to no encoding
    let mut req = TestRequest::with_uri("/utf8.txt").to_request();
    req.headers_mut().insert(
        header::ACCEPT_ENCODING,
        header::HeaderValue::from_static("zstd"),
    );
    let res = test::call_service(&srv, req).await;

    assert_eq!(res.status(), StatusCode::OK);
    assert_eq!(
        res.headers().get(header::CONTENT_TYPE),
        Some(&HeaderValue::from_static("text/plain; charset=utf-8")),
    );
    assert_eq!(res.headers().get(header::CONTENT_ENCODING), None,);
    assert_eq!(
        res.into_body().size(),
        actix_web::body::BodySize::Sized(utf8_txt_len),
    );

    // Do not select an encoding explicitly refused via q=0
    let mut req = TestRequest::with_uri("/utf8.txt").to_request();
    req.headers_mut().insert(
        header::ACCEPT_ENCODING,
        header::HeaderValue::from_static("zstd;q=1, gzip;q=0"),
    );
    let res = test::call_service(&srv, req).await;

    assert_eq!(res.status(), StatusCode::OK);
    assert_eq!(
        res.headers().get(header::CONTENT_TYPE),
        Some(&HeaderValue::from_static("text/plain; charset=utf-8")),
    );
    assert_eq!(res.headers().get(header::CONTENT_ENCODING), None,);
    assert_eq!(
        res.into_body().size(),
        actix_web::body::BodySize::Sized(utf8_txt_len),
    );

    // Can still request a compressed file directly
    let req = TestRequest::with_uri("/utf8.txt.gz").to_request();
    let res = test::call_service(&srv, req).await;

    assert_eq!(res.status(), StatusCode::OK);
    assert_eq!(
        res.headers().get(header::CONTENT_TYPE),
        Some(&HeaderValue::from_static("application/gzip")),
    );
    assert_eq!(res.headers().get(header::CONTENT_ENCODING), None,);

    // Don't try compressed files
    let srv = test::init_service(App::new().service(Files::new("/", "./tests"))).await;

    let mut req = TestRequest::with_uri("/utf8.txt").to_request();
    req.headers_mut().insert(
        header::ACCEPT_ENCODING,
        header::HeaderValue::from_static("gzip"),
    );
    let res = test::call_service(&srv, req).await;

    assert_eq!(res.status(), StatusCode::OK);
    assert_eq!(
        res.headers().get(header::CONTENT_TYPE),
        Some(&HeaderValue::from_static("text/plain; charset=utf-8")),
    );
    assert_eq!(res.headers().get(header::CONTENT_ENCODING), None);
}

#[actix_web::test]
async fn partial_range_response_encoding() {
    let srv = test::init_service(App::new().default_service(web::to(|| async {
        NamedFile::open_async("./tests/test.binary").await.unwrap()
    })))
    .await;

    // range request without accept-encoding returns no content-encoding header
    let req = TestRequest::with_uri("/")
        .append_header((header::RANGE, "bytes=10-20"))
        .to_request();
    let res = test::call_service(&srv, req).await;
    assert_eq!(res.status(), StatusCode::PARTIAL_CONTENT);
    assert!(!res.headers().contains_key(header::CONTENT_ENCODING));

    // range request with accept-encoding still returns no content-encoding header
    let req = TestRequest::with_uri("/")
        .append_header((header::RANGE, "bytes=10-20"))
        .append_header((header::ACCEPT_ENCODING, "gzip"))
        .to_request();
    let res = test::call_service(&srv, req).await;
    assert_eq!(res.status(), StatusCode::PARTIAL_CONTENT);
    assert!(!res.headers().contains_key(header::CONTENT_ENCODING));
}


================================================
FILE: actix-files/tests/fixtures/guards/first/index.txt
================================================
first

================================================
FILE: actix-files/tests/fixtures/guards/second/index.txt
================================================
second

================================================
FILE: actix-files/tests/guard.rs
================================================
use actix_files::Files;
use actix_web::{
    guard::Host,
    http::StatusCode,
    test::{self, TestRequest},
    App,
};
use bytes::Bytes;

#[actix_web::test]
async fn test_guard_filter() {
    let srv = test::init_service(
        App::new()
            .service(Files::new("/", "./tests/fixtures/guards/first").guard(Host("first.com")))
            .service(Files::new("/", "./tests/fixtures/guards/second").guard(Host("second.com"))),
    )
    .await;

    let req = TestRequest::with_uri("/index.txt")
        .append_header(("Host", "first.com"))
        .to_request();
    let res = test::call_service(&srv, req).await;

    assert_eq!(res.status(), StatusCode::OK);
    assert_eq!(test::read_body(res).await, Bytes::from("first"));

    let req = TestRequest::with_uri("/index.txt")
        .append_header(("Host", "second.com"))
        .to_request();
    let res = test::call_service(&srv, req).await;

    assert_eq!(res.status(), StatusCode::OK);
    assert_eq!(test::read_body(res).await, Bytes::from("second"));
}


================================================
FILE: actix-files/tests/pre_epoch_mtime.rs
================================================
use std::time::UNIX_EPOCH;

use actix_files::NamedFile;
use actix_web::{
    http::{header, StatusCode},
    test, web, App,
};
use filetime::{set_file_mtime, FileTime};
use tempfile::tempdir;

#[actix_web::test]
async fn serves_file_with_pre_epoch_mtime() {
    let dir = tempdir().unwrap();
    let path = dir.path().join("pre_epoch.txt");

    std::fs::write(&path, b"hello").unwrap();

    // set mtime to before UNIX epoch; this used to panic during ETag/Last-Modified generation
    set_file_mtime(&path, FileTime::from_unix_time(-60, 0)).unwrap();

    let mtime = std::fs::metadata(&path).unwrap().modified().unwrap();
    assert!(
        mtime < UNIX_EPOCH,
        "fixture mtime should be before UNIX_EPOCH"
    );

    let srv = {
        let path = path.clone();
        test::init_service(App::new().default_service(web::to(move || {
            let path = path.clone();
            async move { NamedFile::open_async(path).await.unwrap() }
        })))
        .await
    };

    let req = test::TestRequest::with_uri("/").to_request();
    let res = test::call_service(&srv, req).await;

    assert_eq!(res.status(), StatusCode::OK);

    // ETag is still generated even for pre-epoch times.
    assert!(res.headers().contains_key(header::ETAG));

    // HTTP-date formatting in the httpdate crate does not support pre-epoch times.
    assert!(!res.headers().contains_key(header::LAST_MODIFIED));

    let body = test::read_body(res).await;
    assert_eq!(&body[..], b"hello");
}


================================================
FILE: actix-files/tests/test space.binary
================================================
TǑɂV2vI\R˙evD:藽RVYp;Gp!2C.pA!ߦx	j+UcXc%;"yAI

================================================
FILE: actix-files/tests/test.binary
================================================
TǑɂV2vI\R˙evD:藽RVYp;Gp!2C.pA!ߦx	j+UcXc%;"yAI

================================================
FILE: actix-files/tests/test.js
================================================
// this file is empty.


================================================
FILE: actix-files/tests/traversal.rs
================================================
use actix_files::Files;
use actix_web::{
    http::StatusCode,
    test::{self, TestRequest},
    App,
};

#[actix_rt::test]
async fn test_directory_traversal_prevention() {
    let srv = test::init_service(App::new().service(Files::new("/", "./tests"))).await;

    let req = TestRequest::with_uri("/../../../../../../../../../../../etc/passwd").to_request();
    let res = test::call_service(&srv, req).await;
    assert_eq!(res.status(), StatusCode::NOT_FOUND);

    let req = TestRequest::with_uri(
        "/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd",
    )
    .to_request();
    let res = test::call_service(&srv, req).await;
    assert_eq!(res.status(), StatusCode::NOT_FOUND);

    let req = TestRequest::with_uri("/%00/etc/passwd%00").to_request();
    let res = test::call_service(&srv, req).await;
    assert_eq!(res.status(), StatusCode::NOT_FOUND);
}


================================================
FILE: actix-files/tests/utf8.txt
================================================
中文内容显示正确。

English is OK.


================================================
FILE: actix-http/CHANGES.md
================================================
# Changes

## Unreleased

- Encode the HTTP/1 `Connection: Upgrade` header in Camel-Case when camel-case header formatting is enabled.[#3953]
- Fix `HeaderMap` iterators' `len()` and `size_hint()` implementations for multi-value headers.

[#3953]: https://github.com/actix/actix-web/pull/3953

## 3.12.0

- Minimum supported Rust version (MSRV) is now 1.88.
- Increase default HTTP/2 flow control window sizes. [#3638]
- Expose configuration methods to improve upload throughput. [#3638]
- Fix truncated body ending without error when connection closed abnormally. [#3067]
- Add config/method for `TCP_NODELAY`. [#3918]
- Do not compress 206 Partial Content responses. [#3191]
- Fix lingering sockets and client stalls when responding early to dropped chunked request payloads. [#2972]

[#3638]: https://github.com/actix/actix-web/issues/3638
[#3067]: https://github.com/actix/actix-web/pull/3067
[#3918]: https://github.com/actix/actix-web/pull/3918
[#3191]: https://github.com/actix/actix-web/issues/3191
[#2972]: https://github.com/actix/actix-web/issues/2972

## 3.11.2

- Properly wake Payload receivers when feeding errors or EOF.
- Add `ServiceConfigBuilder` type to facilitate future configuration extensions.
- Add a configuration option to allow/disallow half closed connections in HTTP/1. This defaults to allow, reverting the change made in 3.11.1.
- Shutdown connections when HTTP Responses are written without reading full Requests.

## 3.11.1

- Prevent more hangs after client disconnects.
- More malformed WebSocket frames are now gracefully rejected.
- Using `TestRequest::set_payload()` now sets a Content-Length header.

## 3.11.0

- Update `brotli` dependency to `8`.

## 3.10.0

### Added

- Add `header::CLEAR_SITE_DATA` constant.
- Add `Extensions::get_or_insert[_with]()` methods.
- Implement `From<Bytes>` for `Payload`.
- Implement `From<Vec<u8>>` for `Payload`.

### Changed

- Update `brotli` dependency to `7`.
- Minimum supported Rust version (MSRV) is now 1.75.

## 3.9.0

### Added

- Implement `FromIterator<(HeaderName, HeaderValue)>` for `HeaderMap`.

## 3.8.0

### Added

- Add `error::InvalidStatusCode` re-export.

## 3.7.0

### Added

- Add `rustls-0_23` crate feature
- Add `{h1::H1Service, h2::H2Service, HttpService}::rustls_0_23()` and `HttpService::rustls_0_23_with_config()` service constructors.

### Changed

- Update `brotli` dependency to `6`.
- Minimum supported Rust version (MSRV) is now 1.72.

## 3.6.0

### Added

- Add `rustls-0_22` crate feature.
- Add `{h1::H1Service, h2::H2Service, HttpService}::rustls_0_22()` and `HttpService::rustls_0_22_with_config()` service constructors.
- Implement `From<&HeaderMap>` for `http::HeaderMap`.

## 3.5.1

### Fixed

- Prevent hang when returning zero-sized response bodies through compression layer.

## 3.5.0

### Added

- Implement `From<HeaderMap>` for `http::HeaderMap`.

### Changed

- Updated `zstd` dependency to `0.13`.

### Fixed

- Prevent compression of zero-sized response bodies.

## 3.4.0

### Added

- Add `rustls-0_20` crate feature.
- Add `{h1::H1Service, h2::H2Service, HttpService}::rustls_021()` and `HttpService::rustls_021_with_config()` service constructors.
- Add `body::to_bytes_limited()` function.
- Add `body::BodyLimitExceeded` error type.

### Changed

- Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency.

## 3.3.1

### Fixed

- Use correct `http` version requirement to ensure support for const `HeaderName` definitions.

## 3.3.0

### Added

- Implement `MessageBody` for `Cow<'static, str>` and `Cow<'static, [u8]>`. [#2959]
- Implement `MessageBody` for `&mut B` where `B: MessageBody + Unpin`. [#2868]
- Implement `MessageBody` for `Pin<B>` where `B::Target: MessageBody`. [#2868]
- Automatic h2c detection via new service finalizer `HttpService::tcp_auto_h2c()`. [#2957]
- `HeaderMap::retain()`. [#2955]
- Header name constants in `header` module. [#2956] [#2968]
  - `CACHE_STATUS`
  - `CDN_CACHE_CONTROL`
  - `CROSS_ORIGIN_EMBEDDER_POLICY`
  - `CROSS_ORIGIN_OPENER_POLICY`
  - `PERMISSIONS_POLICY`
  - `X_FORWARDED_FOR`
  - `X_FORWARDED_HOST`
  - `X_FORWARDED_PROTO`

### Fixed

- Fix non-empty body of HTTP/2 HEAD responses. [#2920]

### Performance

- Improve overall performance of operations on `Extensions`. [#2890]

[#2959]: https://github.com/actix/actix-web/pull/2959
[#2868]: https://github.com/actix/actix-web/pull/2868
[#2890]: https://github.com/actix/actix-web/pull/2890
[#2920]: https://github.com/actix/actix-web/pull/2920
[#2957]: https://github.com/actix/actix-web/pull/2957
[#2955]: https://github.com/actix/actix-web/pull/2955
[#2956]: https://github.com/actix/actix-web/pull/2956
[#2968]: https://github.com/actix/actix-web/pull/2968

## 3.2.2

### Changed

- Minimum supported Rust version (MSRV) is now 1.59 due to transitive `time` dependency.

### Fixed

- Avoid possibility of dispatcher getting stuck while back-pressuring I/O. [#2369]

[#2369]: https://github.com/actix/actix-web/pull/2369

## 3.2.1

### Fixed

- Fix parsing ambiguity in Transfer-Encoding and Content-Length headers for HTTP/1.0 requests. [#2794]

[#2794]: https://github.com/actix/actix-web/pull/2794

## 3.2.0

### Changed

- Minimum supported Rust version (MSRV) is now 1.57 due to transitive `time` dependency.

### Fixed

- Websocket parser no longer throws endless overflow errors after receiving an oversized frame. [#2790]
- Retain previously set Vary headers when using compression encoder. [#2798]

[#2790]: https://github.com/actix/actix-web/pull/2790
[#2798]: https://github.com/actix/actix-web/pull/2798

## 3.1.0

### Changed

- Minimum supported Rust version (MSRV) is now 1.56 due to transitive `hashbrown` dependency.

### Fixed

- Revert broken fix in [#2624] that caused erroneous 500 error responses. Temporarily re-introduces [#2357] bug. [#2779]

[#2624]: https://github.com/actix/actix-web/pull/2624
[#2357]: https://github.com/actix/actix-web/issues/2357
[#2779]: https://github.com/actix/actix-web/pull/2779

## 3.0.4

### Fixed

- Document on docs.rs with `ws` feature enabled.

## 3.0.3

### Fixed

- Allow spaces between header name and colon when parsing responses. [#2684]

[#2684]: https://github.com/actix/actix-web/pull/2684

## 3.0.2

### Fixed

- Fix encoding camel-case header names with more than one hyphen. [#2683]

[#2683]: https://github.com/actix/actix-web/pull/2683

## 3.0.1

- Fix panic in H1 dispatcher when pipelining is used with keep-alive. [#2678]

[#2678]: https://github.com/actix/actix-web/issues/2678

## 3.0.0

### Dependencies

- Updated `actix-*` to Tokio v1-based versions. [#1813]
- Updated `bytes` to `1.0`. [#1813]
- Updated `h2` to `0.3`. [#1813]
- Updated `rustls` to `0.20.0`. [#2414]
- Updated `language-tags` to `0.3`.
- Updated `tokio` to `1`.

### Added

- Crate Features:
  - `ws`; disabled by default. [#2618]
  - `http2`; disabled by default. [#2618]
  - `compress-brotli`; disabled by default. [#2618]
  - `compress-gzip`; disabled by default. [#2618]
  - `compress-zstd`; disabled by default. [#2618]
- Functions:
  - `body::to_bytes` for async collecting message body into Bytes. [#2158]
- Traits:
  - `TryIntoHeaderPair`; allows using typed and untyped headers in the same methods. [#1869]
- Types:
  - `body::BoxBody`; a boxed message body with boxed errors. [#2183]
  - `body::EitherBody` enum. [#2468]
  - `body::None` struct. [#2468]
  - Re-export `http` crate's `Error` type as `error::HttpError`. [#2171]
- Variants:
  - `ContentEncoding::Zstd` along with . [#2244]
  - `Protocol::Http3` for future compatibility and also mark `#[non_exhaustive]`. [00ba8d55]
- Methods:
  - `ContentEncoding::to_header_value()`. [#2501]
  - `header::QualityItem::{max, min}()`. [#2486]
  - `header::QualityItem::zero()` that uses `Quality::ZERO`. [#2501]
  - `HeaderMap::drain()` as an efficient draining iterator. [#1964]
  - `HeaderMap::len_keys()` has the behavior of the old `len` method. [#1964]
  - `MessageBody::boxed` trait method for wrapping boxing types efficiently. [#2520]
  - `MessageBody::try_into_bytes` trait method, with default implementation, for optimizations on body types that complete in exactly one poll. [#2522]
  - `Request::conn_data()`. [#2491]
  - `Request::take_conn_data()`. [#2491]
  - `Request::take_req_data()`. [#2487]
  - `Response::{ok, bad_request, not_found, internal_server_error}()`. [#2159]
  - `Response::into_body()` that consumes response and returns body type. [#2201]
  - `Response::map_into_boxed_body()`. [#2468]
  - `ResponseBuilder::append_header()` method which allows using typed and untyped headers. [#1869]
  - `ResponseBuilder::insert_header()` method which allows using typed and untyped headers. [#1869]
  - `ResponseHead::set_camel_case_headers()`. [#2587]
  - `TestRequest::insert_header()` method which allows using typed and untyped headers. [#1869]
- Implementations:
  - Implement `Clone for ws::HandshakeError`. [#2468]
  - Implement `Clone` for `body::AnyBody<S> where S: Clone`. [#2448]
  - Implement `Clone` for `RequestHead`. [#2487]
  - Implement `Clone` for `ResponseHead`. [#2585]
  - Implement `Copy` for `QualityItem<T> where T: Copy`. [#2501]
  - Implement `Default` for `ContentEncoding`. [#1912]
  - Implement `Default` for `HttpServiceBuilder`. [#2611]
  - Implement `Default` for `KeepAlive`. [#2611]
  - Implement `Default` for `Response`. [#2201]
  - Implement `Default` for `ws::Codec`. [#1920]
  - Implement `Display` for `header::Quality`. [#2486]
  - Implement `Eq` for `header::ContentEncoding`. [#2501]
  - Implement `ExactSizeIterator` and `FusedIterator` for all `HeaderMap` iterators. [#2470]
  - Implement `From<Duration>` for `KeepAlive`. [#2611]
  - Implement `From<Option<Duration>>` for `KeepAlive`. [#2611]
  - Implement `From<Vec<u8>>` for `Response<Vec<u8>>`. [#2625]
  - Implement `FromStr` for `ContentEncoding`. [#1912]
  - Implement `Header` for `ContentEncoding`. [#1912]
  - Implement `IntoHeaderValue` for `ContentEncoding`. [#1912]
  - Implement `IntoIterator` for `HeaderMap`. [#1964]
  - Implement `MessageBody` for `bytestring::ByteString`. [#2468]
  - Implement `MessageBody` for `Pin<Box<T>> where T: MessageBody`. [#2152]
- Misc:
  - Re-export `StatusCode`, `Method`, `Version` and `Uri` at the crate root. [#2171]
  - Re-export `ContentEncoding` and `ConnectionType` at the crate root. [#2171]
  - `Quality::ZERO` associated constant equivalent to `q=0`. [#2501]
  - `header::Quality::{MAX, MIN}` associated constants equivalent to `q=1` and `q=0.001`, respectively. [#2486]
  - Timeout for canceling HTTP/2 server side connection handshake. Configurable with `ServiceConfig::client_timeout`; defaults to 5 seconds. [#2483]
  - `#[must_use]` for `ws::Codec` to prevent subtle bugs. [#1920]

### Changed

- Traits:
  - Rename `IntoHeaderValue => TryIntoHeaderValue`. [#2510]
  - `MessageBody` now has an associated `Error` type. [#2183]
- Types:
  - `Protocol` enum is now marked `#[non_exhaustive]`.
  - `error::DispatcherError` enum is now marked `#[non_exhaustive]`. [#2624]
  - `ContentEncoding` is now marked `#[non_exhaustive]`. [#2377]
  - Error enums are marked `#[non_exhaustive]`. [#2161]
  - Rename `PayloadStream` to `BoxedPayloadStream`. [#2545]
  - The body type parameter of `Response` no longer has a default. [#2152]
- Enum Variants:
  - Rename `ContentEncoding::{Br => Brotli}`. [#2501]
  - `Payload` inner fields are now named. [#2545]
  - `ws::Message::Text` now contains a `bytestring::ByteString`. [#1864]
- Methods:
  - Rename `ServiceConfig::{client_timer_expire => client_request_deadline}`. [#2611]
  - Rename `ServiceConfig::{client_disconnect_timer => client_disconnect_deadline}`. [#2611]
  - Rename `h1::Codec::{keepalive => keep_alive}`. [#2611]
  - Rename `h1::Codec::{keepalive_enabled => keep_alive_enabled}`. [#2611]
  - Rename `h1::ClientCodec::{keepalive => keep_alive}`. [#2611]
  - Rename `h1::ClientPayloadCodec::{keepalive => keep_alive}`. [#2611]
  - Rename `header::EntityTag::{weak => new_weak, strong => new_strong}`. [#2565]
  - Rename `TryIntoHeaderValue::{try_into => try_into_value}` to avoid ambiguity with std `TryInto` trait. [#1894]
  - Deadline methods in `ServiceConfig` now return `std::time::Instant`s instead of Tokio's wrapper type. [#2611]
  - Places in `Response` where `ResponseBody<B>` was received or returned now simply use `B`. [#2201]
  - `encoding::Encoder::response` now returns `AnyBody<Encoder<B>>`. [#2448]
  - `Extensions::insert` returns replaced item. [#1904]
  - `HeaderMap::get_all` now returns a `std::slice::Iter`. [#2527]
  - `HeaderMap::insert` now returns iterator of removed values. [#1964]
  - `HeaderMap::len` now returns number of values instead of number of keys. [#1964]
  - `HeaderMap::remove` now returns iterator of removed values. [#1964]
  - `ResponseBuilder::body(B)` now returns `Response<EitherBody<B>>`. [#2468]
  - `ResponseBuilder::content_type` now takes an `impl TryIntoHeaderValue` to support using typed `mime` types. [#1894]
  - `ResponseBuilder::finish()` now returns `Response<EitherBody<()>>`. [#2468]
  - `ResponseBuilder::json` now takes `impl Serialize`. [#2052]
  - `ResponseBuilder::message_body` now returns a `Result`. [#2201]∑
  - `ServiceConfig::keep_alive` now returns a `KeepAlive`. [#2611]
  - `ws::hash_key` now returns array. [#2035]
- Trait Implementations:
  - Implementation of `Stream` for `Payload` no longer requires the `Stream` variant be `Unpin`. [#2545]
  - Implementation of `Future` for `h1::SendResponse` no longer requires the body type be `Unpin`. [#2545]
  - Implementation of `Stream` for `encoding::Decoder` no longer requires the stream type be `Unpin`. [#2545]
  - Implementation of `From` for error types now return a `Response<BoxBody>`. [#2468]
- Misc:
  - `header` module is now public. [#2171]
  - `uri` module is now public. [#2171]
  - Request-local data container is no longer part of a `RequestHead`. Instead it is a distinct part of a `Request`. [#2487]
  - All error trait bounds in server service builders have changed from `Into<Error>` to `Into<Response<BoxBody>>`. [#2253]
  - All error trait bounds in message body and stream impls changed from `Into<Error>` to `Into<Box<dyn std::error::Error>>`. [#2253]
  - Guarantee ordering of `header::GetAll` iterator to be same as insertion order. [#2467]
  - Connection data set through the `on_connect_ext` callbacks is now accessible only from the new `Request::conn_data()` method. [#2491]
  - Brotli (de)compression support is now provided by the `brotli` crate. [#2538]
  - Minimum supported Rust version (MSRV) is now 1.54.

### Fixed

- A `Vary` header is now correctly sent along with compressed content. [#2501]
- HTTP/1.1 dispatcher correctly uses client request timeout. [#2611]
- Fixed issue where handlers that took payload but then dropped without reading it to EOF it would cause keep-alive connections to become stuck. [#2624]
- `ContentEncoding`'s `Identity` variant can now be parsed from a string. [#2501]
- `HttpServer::{listen_rustls(), bind_rustls()}` now honor the ALPN protocols in the configuration parameter. [#2226]
- Remove unnecessary `Into<Error>` bound on `Encoder` body types. [#2375]
- Remove unnecessary `Unpin` bound on `ResponseBuilder::streaming`. [#2253]
- `BodyStream` and `SizedStream` are no longer restricted to `Unpin` types. [#2152]
- Fixed slice creation pointing to potential uninitialized data on h1 encoder. [#2364]
- Fixed quality parse error in Accept-Encoding header. [#2344]

### Removed

- Crate Features:
  - `compress` feature. [#2065]
  - `cookies` feature. [#2065]
  - `trust-dns` feature. [#2425]
  - `actors` optional feature and trait implementation for `actix` types. [#1969]
- Functions:
  - `header::qitem` helper. Replaced with `header::QualityItem::max`. [#2486]
- Types:
  - `body::Body`; replaced with `EitherBody` and `BoxBody`. [#2468]
  - `body::ResponseBody`. [#2446]
  - `ConnectError::SslHandshakeError` and re-export of `HandshakeError`. Due to the removal of this type from `tokio-openssl` crate. OpenSSL handshake error no
Download .txt
gitextract_9omv_u5c/

├── .clippy.toml
├── .codecov.yml
├── .cspell.yml
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   └── config.yml
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── dependabot.yml
│   ├── labeler.yml
│   └── workflows/
│       ├── bench.yml
│       ├── ci-post-merge.yml
│       ├── ci.yml
│       ├── coverage.yml
│       ├── labeler.yml
│       ├── lint.yml
│       └── semver-labeler.yml
├── .gitignore
├── .prettierrc.yml
├── .rustfmt.toml
├── .taplo.toml
├── CHANGES.md
├── CODE_OF_CONDUCT.md
├── Cargo.toml
├── LICENSE-APACHE
├── LICENSE-MIT
├── actix-files/
│   ├── CHANGES.md
│   ├── Cargo.toml
│   ├── README.md
│   ├── examples/
│   │   └── guarded-listing.rs
│   ├── src/
│   │   ├── chunked.rs
│   │   ├── directory.rs
│   │   ├── encoding.rs
│   │   ├── error.rs
│   │   ├── files.rs
│   │   ├── lib.rs
│   │   ├── named.rs
│   │   ├── path_buf.rs
│   │   ├── range.rs
│   │   └── service.rs
│   └── tests/
│       ├── encoding.rs
│       ├── fixtures/
│       │   └── guards/
│       │       ├── first/
│       │       │   └── index.txt
│       │       └── second/
│       │           └── index.txt
│       ├── guard.rs
│       ├── pre_epoch_mtime.rs
│       ├── test space.binary
│       ├── test.binary
│       ├── test.js
│       ├── traversal.rs
│       ├── utf8.txt
│       └── utf8.txt.br
├── actix-http/
│   ├── CHANGES.md
│   ├── Cargo.toml
│   ├── README.md
│   ├── benches/
│   │   ├── date-formatting.rs
│   │   └── response-body-compression.rs
│   ├── examples/
│   │   ├── actix-web.rs
│   │   ├── bench.rs
│   │   ├── echo.rs
│   │   ├── echo2.rs
│   │   ├── h2c-detect.rs
│   │   ├── h2spec.rs
│   │   ├── hello-world.rs
│   │   ├── streaming-error.rs
│   │   ├── tls_rustls.rs
│   │   └── ws.rs
│   ├── src/
│   │   ├── body/
│   │   │   ├── body_stream.rs
│   │   │   ├── boxed.rs
│   │   │   ├── either.rs
│   │   │   ├── message_body.rs
│   │   │   ├── mod.rs
│   │   │   ├── none.rs
│   │   │   ├── size.rs
│   │   │   ├── sized_stream.rs
│   │   │   └── utils.rs
│   │   ├── builder.rs
│   │   ├── config.rs
│   │   ├── date.rs
│   │   ├── encoding/
│   │   │   ├── decoder.rs
│   │   │   ├── encoder.rs
│   │   │   └── mod.rs
│   │   ├── error.rs
│   │   ├── extensions.rs
│   │   ├── h1/
│   │   │   ├── chunked.rs
│   │   │   ├── client.rs
│   │   │   ├── codec.rs
│   │   │   ├── decoder.rs
│   │   │   ├── dispatcher.rs
│   │   │   ├── dispatcher_tests.rs
│   │   │   ├── encoder.rs
│   │   │   ├── expect.rs
│   │   │   ├── mod.rs
│   │   │   ├── payload.rs
│   │   │   ├── service.rs
│   │   │   ├── timer.rs
│   │   │   ├── upgrade.rs
│   │   │   └── utils.rs
│   │   ├── h2/
│   │   │   ├── dispatcher.rs
│   │   │   ├── mod.rs
│   │   │   └── service.rs
│   │   ├── header/
│   │   │   ├── as_name.rs
│   │   │   ├── common.rs
│   │   │   ├── into_pair.rs
│   │   │   ├── into_value.rs
│   │   │   ├── map.rs
│   │   │   ├── mod.rs
│   │   │   ├── shared/
│   │   │   │   ├── charset.rs
│   │   │   │   ├── content_encoding.rs
│   │   │   │   ├── extended.rs
│   │   │   │   ├── http_date.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── quality.rs
│   │   │   │   └── quality_item.rs
│   │   │   └── utils.rs
│   │   ├── helpers.rs
│   │   ├── http_message.rs
│   │   ├── keep_alive.rs
│   │   ├── lib.rs
│   │   ├── message.rs
│   │   ├── notify_on_drop.rs
│   │   ├── payload.rs
│   │   ├── requests/
│   │   │   ├── head.rs
│   │   │   ├── mod.rs
│   │   │   └── request.rs
│   │   ├── responses/
│   │   │   ├── builder.rs
│   │   │   ├── head.rs
│   │   │   ├── mod.rs
│   │   │   └── response.rs
│   │   ├── service.rs
│   │   ├── test.rs
│   │   └── ws/
│   │       ├── codec.rs
│   │       ├── dispatcher.rs
│   │       ├── frame.rs
│   │       ├── mask.rs
│   │       ├── mod.rs
│   │       └── proto.rs
│   └── tests/
│       ├── test.binary
│       ├── test_client.rs
│       ├── test_h2_timer.rs
│       ├── test_openssl.rs
│       ├── test_rustls.rs
│       ├── test_server.rs
│       └── test_ws.rs
├── actix-http-test/
│   ├── CHANGES.md
│   ├── Cargo.toml
│   ├── README.md
│   └── src/
│       └── lib.rs
├── actix-multipart/
│   ├── CHANGES.md
│   ├── Cargo.toml
│   ├── README.md
│   ├── examples/
│   │   └── form.rs
│   └── src/
│       ├── error.rs
│       ├── extractor.rs
│       ├── field.rs
│       ├── form/
│       │   ├── bytes.rs
│       │   ├── json.rs
│       │   ├── mod.rs
│       │   ├── tempfile.rs
│       │   └── text.rs
│       ├── lib.rs
│       ├── multipart.rs
│       ├── payload.rs
│       ├── safety.rs
│       └── test.rs
├── actix-multipart-derive/
│   ├── CHANGES.md
│   ├── Cargo.toml
│   ├── README.md
│   ├── src/
│   │   └── lib.rs
│   └── tests/
│       ├── trybuild/
│       │   ├── all-required.rs
│       │   ├── deny-duplicates.rs
│       │   ├── deny-parse-fail.rs
│       │   ├── deny-parse-fail.stderr
│       │   ├── deny-unknown.rs
│       │   ├── optional-and-list.rs
│       │   ├── rename.rs
│       │   ├── size-limit-parse-fail.rs
│       │   ├── size-limit-parse-fail.stderr
│       │   └── size-limits.rs
│       └── trybuild.rs
├── actix-router/
│   ├── CHANGES.md
│   ├── Cargo.toml
│   ├── README.md
│   ├── benches/
│   │   ├── quoter.rs
│   │   └── router.rs
│   └── src/
│       ├── de.rs
│       ├── lib.rs
│       ├── path.rs
│       ├── pattern.rs
│       ├── quoter.rs
│       ├── regex_set.rs
│       ├── resource.rs
│       ├── resource_path.rs
│       ├── router.rs
│       └── url.rs
├── actix-test/
│   ├── CHANGES.md
│   ├── Cargo.toml
│   ├── README.md
│   └── src/
│       └── lib.rs
├── actix-web/
│   ├── CHANGES.md
│   ├── Cargo.toml
│   ├── MIGRATION-0.x.md
│   ├── MIGRATION-1.0.md
│   ├── MIGRATION-2.0.md
│   ├── MIGRATION-3.0.md
│   ├── MIGRATION-4.0.md
│   ├── README.md
│   ├── benches/
│   │   ├── responder.rs
│   │   ├── server.rs
│   │   └── service.rs
│   ├── examples/
│   │   ├── README.md
│   │   ├── basic.rs
│   │   ├── from_fn.rs
│   │   ├── introspection.rs
│   │   ├── introspection_multi_servers.rs
│   │   ├── macroless.rs
│   │   ├── middleware_from_fn.rs
│   │   ├── on-connect.rs
│   │   ├── uds.rs
│   │   └── worker-cpu-pin.rs
│   ├── src/
│   │   ├── app.rs
│   │   ├── app_service.rs
│   │   ├── config.rs
│   │   ├── data.rs
│   │   ├── dev.rs
│   │   ├── error/
│   │   │   ├── error.rs
│   │   │   ├── internal.rs
│   │   │   ├── macros.rs
│   │   │   ├── mod.rs
│   │   │   └── response_error.rs
│   │   ├── extract.rs
│   │   ├── guard/
│   │   │   ├── acceptable.rs
│   │   │   ├── host.rs
│   │   │   └── mod.rs
│   │   ├── handler.rs
│   │   ├── helpers.rs
│   │   ├── http/
│   │   │   ├── header/
│   │   │   │   ├── accept.rs
│   │   │   │   ├── accept_charset.rs
│   │   │   │   ├── accept_encoding.rs
│   │   │   │   ├── accept_language.rs
│   │   │   │   ├── allow.rs
│   │   │   │   ├── any_or_some.rs
│   │   │   │   ├── cache_control.rs
│   │   │   │   ├── content_disposition.rs
│   │   │   │   ├── content_language.rs
│   │   │   │   ├── content_length.rs
│   │   │   │   ├── content_range.rs
│   │   │   │   ├── content_type.rs
│   │   │   │   ├── date.rs
│   │   │   │   ├── encoding.rs
│   │   │   │   ├── entity.rs
│   │   │   │   ├── etag.rs
│   │   │   │   ├── expires.rs
│   │   │   │   ├── if_match.rs
│   │   │   │   ├── if_modified_since.rs
│   │   │   │   ├── if_none_match.rs
│   │   │   │   ├── if_range.rs
│   │   │   │   ├── if_unmodified_since.rs
│   │   │   │   ├── last_modified.rs
│   │   │   │   ├── macros.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── preference.rs
│   │   │   │   └── range.rs
│   │   │   └── mod.rs
│   │   ├── info.rs
│   │   ├── introspection.rs
│   │   ├── lib.rs
│   │   ├── middleware/
│   │   │   ├── authors-guide.md
│   │   │   ├── compat.rs
│   │   │   ├── compress.rs
│   │   │   ├── condition.rs
│   │   │   ├── default_headers.rs
│   │   │   ├── err_handlers.rs
│   │   │   ├── from_fn.rs
│   │   │   ├── identity.rs
│   │   │   ├── logger.rs
│   │   │   ├── mod.rs
│   │   │   └── normalize.rs
│   │   ├── redirect.rs
│   │   ├── request.rs
│   │   ├── request_data.rs
│   │   ├── resource.rs
│   │   ├── response/
│   │   │   ├── builder.rs
│   │   │   ├── customize_responder.rs
│   │   │   ├── http_codes.rs
│   │   │   ├── mod.rs
│   │   │   ├── responder.rs
│   │   │   └── response.rs
│   │   ├── rmap.rs
│   │   ├── route.rs
│   │   ├── rt.rs
│   │   ├── scope.rs
│   │   ├── server.rs
│   │   ├── service.rs
│   │   ├── test/
│   │   │   ├── mod.rs
│   │   │   ├── test_request.rs
│   │   │   ├── test_services.rs
│   │   │   └── test_utils.rs
│   │   ├── thin_data.rs
│   │   ├── types/
│   │   │   ├── either.rs
│   │   │   ├── form.rs
│   │   │   ├── header.rs
│   │   │   ├── html.rs
│   │   │   ├── json.rs
│   │   │   ├── mod.rs
│   │   │   ├── path.rs
│   │   │   ├── payload.rs
│   │   │   ├── query.rs
│   │   │   └── readlines.rs
│   │   └── web.rs
│   └── tests/
│       ├── compression.rs
│       ├── fixtures/
│       │   ├── lorem.txt
│       │   ├── lorem.txt.br
│       │   ├── lorem.txt.xz
│       │   └── lorem.txt.zst
│       ├── introspection.rs
│       ├── test-macro-import-conflict.rs
│       ├── test_error_propagation.rs
│       ├── test_httpserver.rs
│       ├── test_server.rs
│       ├── test_streaming_response.rs
│       ├── test_weird_poll.rs
│       ├── utils.rs
│       └── weird_poll.rs
├── actix-web-actors/
│   ├── CHANGES.md
│   ├── Cargo.toml
│   ├── README.md
│   ├── src/
│   │   ├── context.rs
│   │   ├── lib.rs
│   │   └── ws.rs
│   └── tests/
│       └── test_ws.rs
├── actix-web-codegen/
│   ├── CHANGES.md
│   ├── Cargo.toml
│   ├── README.md
│   ├── src/
│   │   ├── lib.rs
│   │   ├── route.rs
│   │   └── scope.rs
│   └── tests/
│       ├── routes.rs
│       ├── scopes.rs
│       ├── trybuild/
│       │   ├── docstring-ok.rs
│       │   ├── route-custom-lowercase.rs
│       │   ├── route-custom-lowercase.stderr
│       │   ├── route-custom-method.rs
│       │   ├── route-duplicate-method-fail.rs
│       │   ├── route-duplicate-method-fail.stderr
│       │   ├── route-malformed-path-fail.rs
│       │   ├── route-malformed-path-fail.stderr
│       │   ├── route-missing-method-fail.rs
│       │   ├── route-missing-method-fail.stderr
│       │   ├── route-ok.rs
│       │   ├── routes-missing-args-fail.rs
│       │   ├── routes-missing-args-fail.stderr
│       │   ├── routes-missing-method-fail.rs
│       │   ├── routes-missing-method-fail.stderr
│       │   ├── routes-ok.rs
│       │   ├── scope-invalid-args.rs
│       │   ├── scope-invalid-args.stderr
│       │   ├── scope-missing-args.rs
│       │   ├── scope-missing-args.stderr
│       │   ├── scope-on-handler.rs
│       │   ├── scope-on-handler.stderr
│       │   ├── scope-trailing-slash.rs
│       │   ├── scope-trailing-slash.stderr
│       │   ├── simple-fail.rs
│       │   ├── simple-fail.stderr
│       │   ├── simple.rs
│       │   └── test-runtime.rs
│       └── trybuild.rs
├── awc/
│   ├── CHANGES.md
│   ├── Cargo.toml
│   ├── README.md
│   ├── examples/
│   │   └── client.rs
│   ├── src/
│   │   ├── any_body.rs
│   │   ├── builder.rs
│   │   ├── client/
│   │   │   ├── config.rs
│   │   │   ├── connection.rs
│   │   │   ├── connector.rs
│   │   │   ├── error.rs
│   │   │   ├── h1proto.rs
│   │   │   ├── h2proto.rs
│   │   │   ├── mod.rs
│   │   │   └── pool.rs
│   │   ├── connect.rs
│   │   ├── error.rs
│   │   ├── frozen.rs
│   │   ├── lib.rs
│   │   ├── middleware/
│   │   │   ├── mod.rs
│   │   │   └── redirect.rs
│   │   ├── request.rs
│   │   ├── responses/
│   │   │   ├── json_body.rs
│   │   │   ├── mod.rs
│   │   │   ├── read_body.rs
│   │   │   ├── response.rs
│   │   │   └── response_body.rs
│   │   ├── sender.rs
│   │   ├── test.rs
│   │   └── ws.rs
│   └── tests/
│       ├── test_client.rs
│       ├── test_connector.rs
│       ├── test_empty_stream.rs
│       ├── test_rustls_client.rs
│       ├── test_ssl_client.rs
│       ├── test_ws.rs
│       └── utils.rs
├── deny.toml
├── docs/
│   └── graphs/
│       ├── .gitignore
│       ├── README.md
│       ├── net-only.dot
│       ├── web-focus.dot
│       └── web-only.dot
├── justfile
└── scripts/
    ├── bump
    ├── free-disk-space.sh
    ├── publish
    └── unreleased
Download .txt
Showing preview only (379K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (4671 symbols across 289 files)

FILE: actix-files/examples/guarded-listing.rs
  constant EXAMPLES_DIR (line 4) | const EXAMPLES_DIR: &str = concat![env!("CARGO_MANIFEST_DIR"), "/example...
  function index (line 7) | async fn index() -> impl Responder {
  function main (line 12) | async fn main() -> std::io::Result<()> {

FILE: actix-files/src/chunked.rs
  type ReadMode (line 18) | pub(crate) enum ReadMode {
  function fmt (line 58) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  function new_chunked_read (line 63) | pub(crate) fn new_chunked_read(
  function chunked_read_file_callback_sync (line 89) | fn chunked_read_file_callback_sync(
  function chunked_read_file_callback (line 111) | async fn chunked_read_file_callback(
  function chunked_read_file_callback (line 129) | async fn chunked_read_file_callback(
  type Item (line 155) | type Item = Result<Bytes, Error>;
  method poll_next (line 157) | fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Opt...
  type Item (line 204) | type Item = Result<Bytes, Error>;
  method poll_next (line 206) | fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Opt...

FILE: actix-files/src/directory.rs
  type Directory (line 14) | pub struct Directory {
    method new (line 24) | pub fn new(base: PathBuf, path: PathBuf) -> Directory {
    method is_visible (line 29) | pub fn is_visible(&self, entry: &io::Result<DirEntry>) -> bool {
  type DirectoryRenderer (line 45) | pub(crate) type DirectoryRenderer =
  function directory_listing (line 71) | pub(crate) fn directory_listing(

FILE: actix-files/src/encoding.rs
  function equiv_utf8_text (line 12) | pub(crate) fn equiv_utf8_text(ct: Mime) -> Mime {
  function test_equiv_utf8_text (line 47) | fn test_equiv_utf8_text() {

FILE: actix-files/src/error.rs
  type FilesError (line 6) | pub enum FilesError {
  method status_code (line 19) | fn status_code(&self) -> StatusCode {
  type UriSegmentError (line 27) | pub enum UriSegmentError {
  method status_code (line 47) | fn status_code(&self) -> StatusCode {

FILE: actix-files/src/files.rs
  type Files (line 38) | pub struct Files {
    method fmt (line 58) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    method new (line 107) | pub fn new<T: Into<PathBuf>>(mount_path: &str, serve_from: T) -> Files {
    method show_files_listing (line 144) | pub fn show_files_listing(mut self) -> Self {
    method redirect_to_slash_directory (line 152) | pub fn redirect_to_slash_directory(mut self) -> Self {
    method with_permanent_redirect (line 160) | pub fn with_permanent_redirect(mut self) -> Self {
    method files_listing_renderer (line 166) | pub fn files_listing_renderer<F>(mut self, f: F) -> Self
    method mime_override (line 176) | pub fn mime_override<F>(mut self, f: F) -> Self
    method path_filter (line 208) | pub fn path_filter<F>(mut self, f: F) -> Self
    method index_file (line 227) | pub fn index_file<T: Into<String>>(mut self, index: T) -> Self {
    method read_mode_threshold (line 244) | pub fn read_mode_threshold(mut self, size: u64) -> Self {
    method use_etag (line 252) | pub fn use_etag(mut self, value: bool) -> Self {
    method use_last_modified (line 260) | pub fn use_last_modified(mut self, value: bool) -> Self {
    method prefer_utf8 (line 268) | pub fn prefer_utf8(mut self, value: bool) -> Self {
    method guard (line 292) | pub fn guard<G: Guard + 'static>(mut self, guard: G) -> Self {
    method method_guard (line 302) | pub fn method_guard<G: Guard + 'static>(mut self, guard: G) -> Self {
    method use_guards (line 310) | pub fn use_guards<G: Guard + 'static>(self, guard: G) -> Self {
    method disable_content_disposition (line 317) | pub fn disable_content_disposition(mut self) -> Self {
    method default_handler (line 342) | pub fn default_handler<F, U>(mut self, f: F) -> Self
    method use_hidden_files (line 357) | pub fn use_hidden_files(mut self) -> Self {
    method try_compressed (line 366) | pub fn try_compressed(mut self) -> Self {
    type Response (line 401) | type Response = ServiceResponse;
    type Error (line 402) | type Error = Error;
    type Config (line 403) | type Config = ();
    type Service (line 404) | type Service = FilesService;
    type InitError (line 405) | type InitError = ();
    type Future (line 406) | type Future = LocalBoxFuture<'static, Result<Self::Service, Self::Init...
    method new_service (line 408) | fn new_service(&self, _: ()) -> Self::Future {
  method clone (line 64) | fn clone(&self) -> Self {
  method register (line 373) | fn register(mut self, config: &mut AppService) {
  function custom_files_listing_renderer (line 454) | async fn custom_files_listing_renderer() {

FILE: actix-files/src/lib.rs
  type HttpService (line 48) | type HttpService = BoxService<ServiceRequest, ServiceResponse, Error>;
  type HttpNewService (line 49) | type HttpNewService = BoxServiceFactory<(), ServiceRequest, ServiceRespo...
  function file_extension_to_mime (line 55) | pub fn file_extension_to_mime(ext: &str) -> mime::Mime {
  type MimeOverride (line 59) | type MimeOverride = dyn Fn(&mime::Name<'_>) -> DispositionType;
  type PathFilter (line 61) | type PathFilter = dyn Fn(&Path, &RequestHead) -> bool;
  function test_file_extension_to_mime (line 89) | async fn test_file_extension_to_mime() {
  function test_if_modified_since_without_if_none_match (line 104) | async fn test_if_modified_since_without_if_none_match() {
  function test_if_modified_since_without_if_none_match_same (line 116) | async fn test_if_modified_since_without_if_none_match_same() {
  function test_if_modified_since_with_if_none_match (line 128) | async fn test_if_modified_since_with_if_none_match() {
  function test_if_unmodified_since (line 141) | async fn test_if_unmodified_since() {
  function test_if_unmodified_since_failed (line 153) | async fn test_if_unmodified_since_failed() {
  function test_named_file_text (line 165) | async fn test_named_file_text() {
  function test_named_file_content_disposition (line 189) | async fn test_named_file_content_disposition() {
  function test_named_file_non_ascii_file_name (line 217) | async fn test_named_file_non_ascii_file_name() {
  function test_named_file_set_content_type (line 252) | async fn test_named_file_set_content_type() {
  function test_named_file_image (line 278) | async fn test_named_file_image() {
  function test_named_file_javascript (line 301) | async fn test_named_file_javascript() {
  function test_named_file_image_attachment (line 317) | async fn test_named_file_image_attachment() {
  function test_named_file_binary (line 347) | async fn test_named_file_binary() {
  function status_code_customize_same_output (line 371) | async fn status_code_customize_same_output() {
  function test_named_file_status_code_text (line 392) | async fn test_named_file_status_code_text() {
  function test_mime_override (line 420) | async fn test_mime_override() {
  function test_named_file_ranges_status_code (line 449) | async fn test_named_file_ranges_status_code() {
  function test_named_file_empty_range_headers (line 474) | async fn test_named_file_empty_range_headers() {
  function test_named_file_content_range_headers (line 492) | async fn test_named_file_content_range_headers() {
  function test_named_file_range_header_from_zero_to_end_returns_partial_content (line 517) | async fn test_named_file_range_header_from_zero_to_end_returns_partial_c...
  function test_named_file_content_length_headers (line 541) | async fn test_named_file_content_length_headers() {
  function test_head_content_length_headers (line 580) | async fn test_head_content_length_headers() {
  function test_static_files_with_spaces (line 596) | async fn test_static_files_with_spaces() {
  function test_static_files_with_special_characters (line 613) | async fn test_static_files_with_special_characters() {
  function test_files_not_allowed (line 636) | async fn test_files_not_allowed() {
  function test_files_guards (line 657) | async fn test_files_guards() {
  function test_named_file_content_encoding (line 673) | async fn test_named_file_content_encoding() {
  function test_named_file_content_encoding_gzip (line 695) | async fn test_named_file_content_encoding_gzip() {
  function test_named_file_allowed_method (line 723) | async fn test_named_file_allowed_method() {
  function test_static_files (line 731) | async fn test_static_files() {
  function test_redirect_to_slash_directory (line 759) | async fn test_redirect_to_slash_directory() {
  function test_static_files_bad_directory (line 816) | async fn test_static_files_bad_directory() {
  function test_static_files_bad_directory_does_not_serve_cwd_files (line 826) | async fn test_static_files_bad_directory_does_not_serve_cwd_files() {
  function test_default_handler_file_missing (line 836) | async fn test_default_handler_file_missing() {
  function test_serve_index_nested (line 853) | async fn test_serve_index_nested() {
  function integration_serve_index (line 875) | async fn integration_serve_index() {
  function integration_percent_encoded (line 909) | async fn integration_percent_encoded() {
  function test_percent_encoding_2 (line 930) | async fn test_percent_encoding_2() {
  function test_serve_named_file (line 955) | async fn test_serve_named_file() {
  function test_serve_named_file_prefix (line 973) | async fn test_serve_named_file_prefix() {
  function test_named_file_default_service (line 992) | async fn test_named_file_default_service() {
  function test_default_handler_named_file (line 1008) | async fn test_default_handler_named_file() {
  function test_symlinks (line 1025) | async fn test_symlinks() {
  function test_index_with_show_files_listing (line 1040) | async fn test_index_with_show_files_listing() {
  function test_path_filter (line 1069) | async fn test_path_filter() {
  function test_default_handler_filter (line 1087) | async fn test_default_handler_filter() {

FILE: actix-files/src/named.rs
  method default (line 41) | fn default() -> Self {
  type NamedFile (line 71) | pub struct NamedFile {
    method from_file (line 164) | pub fn from_file<P: AsRef<Path>>(file: File, path: P) -> io::Result<Na...
    method open (line 220) | pub fn open<P: AsRef<Path>>(path: P) -> io::Result<NamedFile> {
    method open_async (line 237) | pub async fn open_async<P: AsRef<Path>>(path: P) -> io::Result<NamedFi...
    method file (line 255) | pub fn file(&self) -> &File {
    method path (line 273) | pub fn path(&self) -> &Path {
    method modified (line 282) | pub fn modified(&self) -> Option<SystemTime> {
    method metadata (line 288) | pub fn metadata(&self) -> &Metadata {
    method content_type (line 294) | pub fn content_type(&self) -> &Mime {
    method content_disposition (line 300) | pub fn content_disposition(&self) -> &ContentDisposition {
    method content_encoding (line 309) | pub fn content_encoding(&self) -> Option<ContentEncoding> {
    method set_status_code (line 315) | pub fn set_status_code(mut self, status: StatusCode) -> Self {
    method set_content_type (line 323) | pub fn set_content_type(mut self, mime_type: Mime) -> Self {
    method set_content_disposition (line 336) | pub fn set_content_disposition(mut self, cd: ContentDisposition) -> Se...
    method disable_content_disposition (line 346) | pub fn disable_content_disposition(mut self) -> Self {
    method set_content_encoding (line 357) | pub fn set_content_encoding(mut self, enc: ContentEncoding) -> Self {
    method read_mode_threshold (line 374) | pub fn read_mode_threshold(mut self, size: u64) -> Self {
    method use_etag (line 383) | pub fn use_etag(mut self, value: bool) -> Self {
    method use_last_modified (line 392) | pub fn use_last_modified(mut self, value: bool) -> Self {
    method prefer_utf8 (line 401) | pub fn prefer_utf8(mut self, value: bool) -> Self {
    method etag (line 407) | pub(crate) fn etag(&self) -> Option<header::EntityTag> {
    method last_modified (line 456) | pub(crate) fn last_modified(&self) -> Option<header::HttpDate> {
    method into_response (line 473) | pub fn into_response(self, req: &HttpRequest) -> HttpResponse<BoxBody> {
    type Response (line 677) | type Response = ServiceResponse;
    type Error (line 678) | type Error = Error;
    type Config (line 679) | type Config = ();
    type Service (line 680) | type Service = NamedFileService;
    type InitError (line 681) | type InitError = ();
    type Future (line 682) | type Future = LocalBoxFuture<'static, Result<Self::Service, Self::Init...
    method new_service (line 684) | fn new_service(&self, _: ()) -> Self::Future {
  function get_content_type_and_disposition (line 94) | pub(crate) fn get_content_type_and_disposition(
  function any_match (line 629) | fn any_match(etag: Option<&header::EntityTag>, req: &HttpRequest) -> bool {
  function none_match (line 648) | fn none_match(etag: Option<&header::EntityTag>, req: &HttpRequest) -> bo...
  type Body (line 669) | type Body = BoxBody;
  method respond_to (line 671) | fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body> {
  type NamedFileService (line 695) | pub struct NamedFileService {
    type Response (line 700) | type Response = ServiceResponse;
    type Error (line 701) | type Error = Error;
    type Future (line 702) | type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Err...
    method call (line 706) | fn call(&self, req: ServiceRequest) -> Self::Future {
  method register (line 719) | fn register(self, config: &mut AppService) {
  function audio_files_use_inline_content_disposition (line 734) | fn audio_files_use_inline_content_disposition() {

FILE: actix-files/src/path_buf.rs
  type PathBufWrap (line 15) | pub struct PathBufWrap(PathBuf);
    method parse_unprocessed_req (line 37) | pub fn parse_unprocessed_req(
    method parse_req_path (line 53) | pub fn parse_req_path(req: &HttpRequest, hidden_files: bool) -> Result...
    method parse_path (line 60) | pub fn parse_path(path: &str, hidden_files: bool) -> Result<Self, UriS...
    method as_ref (line 118) | fn as_ref(&self) -> &Path {
  type Err (line 18) | type Err = UriSegmentError;
  method from_str (line 20) | fn from_str(path: &str) -> Result<Self, Self::Err> {
  type Error (line 124) | type Error = UriSegmentError;
  type Future (line 125) | type Future = Ready<Result<Self, Self::Error>>;
  method from_request (line 127) | fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
  function test_path_buf (line 138) | fn test_path_buf() {
  function test_parse_path (line 170) | fn test_parse_path() {
  function path_traversal (line 183) | fn path_traversal() {
  function windows_drive_traversal (line 204) | fn windows_drive_traversal() {

FILE: actix-files/src/range.rs
  type HttpRangeParseError (line 7) | enum HttpRangeParseError {
    method from (line 13) | fn from(err: http_range::HttpRangeParseError) -> Self {
  type ParseRangeErr (line 23) | pub struct ParseRangeErr(#[error(not(source))] HttpRangeParseError);
    method fmt (line 26) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  type HttpRange (line 37) | pub struct HttpRange {
    method parse (line 50) | pub fn parse(header: &str, size: u64) -> Result<Vec<HttpRange>, ParseR...
  type T (line 68) | struct T(&'static str, u64, Vec<HttpRange>);
  function test_parse (line 71) | fn test_parse() {

FILE: actix-files/src/service.rs
  type FilesService (line 25) | pub struct FilesService(pub(crate) Rc<FilesServiceInner>);
    method handle_err (line 59) | async fn handle_err(
    method serve_named_file_with_encoding (line 73) | fn serve_named_file_with_encoding(
    method serve_named_file (line 112) | fn serve_named_file(&self, req: ServiceRequest, named_file: NamedFile)...
    method show_index (line 116) | fn show_index(&self, req: ServiceRequest, path: PathBuf) -> ServiceRes...
    method fmt (line 126) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    type Response (line 132) | type Response = ServiceResponse<BoxBody>;
    type Error (line 133) | type Error = Error;
    type Future (line 134) | type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Err...
    method call (line 138) | fn call(&self, req: ServiceRequest) -> Self::Future {
  type Target (line 28) | type Target = FilesServiceInner;
  method deref (line 30) | fn deref(&self) -> &Self::Target {
  type FilesServiceInner (line 35) | pub struct FilesServiceInner {
    method fmt (line 53) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  constant SUPPORTED_PRECOMPRESSION_ENCODINGS (line 243) | const SUPPORTED_PRECOMPRESSION_ENCODINGS: &[header::ContentEncoding] = &[
  function find_compressed (line 253) | async fn find_compressed(

FILE: actix-files/tests/encoding.rs
  function test_utf8_file_contents (line 12) | async fn test_utf8_file_contents() {
  function test_compression_encodings (line 40) | async fn test_compression_encodings() {
  function partial_range_response_encoding (line 170) | async fn partial_range_response_encoding() {

FILE: actix-files/tests/guard.rs
  function test_guard_filter (line 11) | async fn test_guard_filter() {

FILE: actix-files/tests/pre_epoch_mtime.rs
  function serves_file_with_pre_epoch_mtime (line 12) | async fn serves_file_with_pre_epoch_mtime() {

FILE: actix-files/tests/traversal.rs
  function test_directory_traversal_prevention (line 9) | async fn test_directory_traversal_prevention() {

FILE: actix-http-test/src/lib.rs
  function test_server (line 57) | pub async fn test_server<F: ServerServiceFactory<TcpStream>>(factory: F)...
  function test_server_with_addr (line 63) | pub async fn test_server_with_addr<F: ServerServiceFactory<TcpStream>>(
  type TestServer (line 137) | pub struct TestServer {
    method addr (line 147) | pub fn addr(&self) -> net::SocketAddr {
    method url (line 152) | pub fn url(&self, uri: &str) -> String {
    method surl (line 161) | pub fn surl(&self, uri: &str) -> String {
    method get (line 170) | pub fn get<S: AsRef<str>>(&self, path: S) -> ClientRequest {
    method sget (line 175) | pub fn sget<S: AsRef<str>>(&self, path: S) -> ClientRequest {
    method post (line 180) | pub fn post<S: AsRef<str>>(&self, path: S) -> ClientRequest {
    method spost (line 185) | pub fn spost<S: AsRef<str>>(&self, path: S) -> ClientRequest {
    method head (line 190) | pub fn head<S: AsRef<str>>(&self, path: S) -> ClientRequest {
    method shead (line 195) | pub fn shead<S: AsRef<str>>(&self, path: S) -> ClientRequest {
    method put (line 200) | pub fn put<S: AsRef<str>>(&self, path: S) -> ClientRequest {
    method sput (line 205) | pub fn sput<S: AsRef<str>>(&self, path: S) -> ClientRequest {
    method patch (line 210) | pub fn patch<S: AsRef<str>>(&self, path: S) -> ClientRequest {
    method spatch (line 215) | pub fn spatch<S: AsRef<str>>(&self, path: S) -> ClientRequest {
    method delete (line 220) | pub fn delete<S: AsRef<str>>(&self, path: S) -> ClientRequest {
    method sdelete (line 225) | pub fn sdelete<S: AsRef<str>>(&self, path: S) -> ClientRequest {
    method options (line 230) | pub fn options<S: AsRef<str>>(&self, path: S) -> ClientRequest {
    method soptions (line 235) | pub fn soptions<S: AsRef<str>>(&self, path: S) -> ClientRequest {
    method request (line 240) | pub fn request<S: AsRef<str>>(&self, method: Method, path: S) -> Clien...
    method load_body (line 244) | pub async fn load_body<S>(
    method ws_at (line 255) | pub async fn ws_at(
    method ws (line 265) | pub async fn ws(
    method client_headers (line 275) | pub fn client_headers(&mut self) -> Option<&mut HeaderMap> {
    method stop (line 282) | pub async fn stop(&mut self) {
  method drop (line 296) | fn drop(&mut self) {
  function unused_addr (line 310) | pub fn unused_addr() -> net::SocketAddr {

FILE: actix-http/benches/date-formatting.rs
  function date_formatting (line 10) | fn date_formatting(b: Bencher<'_, '_>) {
  function main (line 18) | fn main() {

FILE: actix-http/benches/response-body-compression.rs
  function compression_responses (line 9) | fn compression_responses(c: &mut Criterion) {

FILE: actix-http/examples/actix-web.rs
  function index (line 7) | async fn index() -> impl Responder {
  function main (line 12) | async fn main() -> std::io::Result<()> {

FILE: actix-http/examples/bench.rs
  function main (line 10) | async fn main() -> io::Result<()> {

FILE: actix-http/examples/echo.rs
  function main (line 11) | async fn main() -> io::Result<()> {

FILE: actix-http/examples/echo2.rs
  function handle_request (line 8) | async fn handle_request(mut req: Request) -> Result<Response<impl Messag...
  function main (line 22) | async fn main() -> io::Result<()> {

FILE: actix-http/examples/h2c-detect.rs
  function main (line 15) | async fn main() -> io::Result<()> {

FILE: actix-http/examples/h2spec.rs
  function main (line 10) | async fn main() -> io::Result<()> {

FILE: actix-http/examples/hello-world.rs
  function main (line 8) | async fn main() -> io::Result<()> {

FILE: actix-http/examples/streaming-error.rs
  function main (line 18) | async fn main() -> io::Result<()> {

FILE: actix-http/examples/tls_rustls.rs
  function main (line 23) | async fn main() -> io::Result<()> {
  function rustls_config (line 45) | fn rustls_config() -> rustls::ServerConfig {

FILE: actix-http/examples/ws.rs
  function main (line 22) | async fn main() -> io::Result<()> {
  function handler (line 38) | async fn handler(req: Request) -> Result<Response<BodyStream<Heartbeat>>...
  type Heartbeat (line 48) | struct Heartbeat {
    method new (line 54) | fn new(codec: ws::Codec) -> Self {
  type Item (line 63) | type Item = Result<Bytes, Error>;
  method poll_next (line 65) | fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Opt...
  function tls_config (line 84) | fn tls_config() -> rustls::ServerConfig {

FILE: actix-http/src/body/body_stream.rs
  function new (line 31) | pub fn new(stream: S) -> Self {
  type Error (line 41) | type Error = E;
  method size (line 44) | fn size(&self) -> BodySize {
  method poll_next (line 52) | fn poll_next(
  function skips_empty_chunks (line 99) | async fn skips_empty_chunks() {
  function read_to_bytes (line 124) | async fn read_to_bytes() {
  type StreamErr (line 135) | struct StreamErr;
  function stream_immediate_error (line 138) | async fn stream_immediate_error() {
  function stream_string_error (line 144) | async fn stream_string_error() {
  function stream_boxed_error (line 153) | async fn stream_boxed_error() {
  function stream_delayed_error (line 168) | async fn stream_delayed_error() {

FILE: actix-http/src/body/boxed.rs
  type BoxBody (line 15) | pub struct BoxBody(BoxBodyInner);
    method new (line 39) | pub fn new<B>(body: B) -> Self
    method as_pin_mut (line 57) | pub fn as_pin_mut(&mut self) -> Pin<&mut Self> {
  type BoxBodyInner (line 17) | enum BoxBodyInner {
    method fmt (line 24) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  type Error (line 63) | type Error = Box<dyn StdError>;
  method size (line 66) | fn size(&self) -> BodySize {
  method poll_next (line 75) | fn poll_next(
  method try_into_bytes (line 87) | fn try_into_bytes(self) -> Result<Bytes, Self> {
  method boxed (line 96) | fn boxed(self) -> BoxBody {
  function nested_boxed_body (line 112) | async fn nested_boxed_body() {

FILE: actix-http/src/body/either.rs
  function new (line 41) | pub fn new(body: L) -> Self {
  function left (line 49) | pub fn left(body: L) -> Self {
  function right (line 55) | pub fn right(body: R) -> Self {
  type Error (line 65) | type Error = Error;
  method size (line 68) | fn size(&self) -> BodySize {
  method poll_next (line 76) | fn poll_next(
  method try_into_bytes (line 91) | fn try_into_bytes(self) -> Result<Bytes, Self> {
  method boxed (line 103) | fn boxed(self) -> BoxBody {
  function type_parameter_inference (line 116) | fn type_parameter_inference() {

FILE: actix-http/src/body/message_body.rs
  type MessageBody (line 55) | pub trait MessageBody {
    method size (line 65) | fn size(&self) -> BodySize;
    method poll_next (line 84) | fn poll_next(
    method try_into_bytes (line 101) | fn try_into_bytes(self) -> Result<Bytes, Self>
    method boxed (line 114) | fn boxed(self) -> BoxBody
    type Error (line 131) | type Error = B::Error;
    method size (line 133) | fn size(&self) -> BodySize {
    method poll_next (line 137) | fn poll_next(
    type Error (line 146) | type Error = Infallible;
    method size (line 148) | fn size(&self) -> BodySize {
    method poll_next (line 152) | fn poll_next(
    type Error (line 161) | type Error = Infallible;
    method size (line 164) | fn size(&self) -> BodySize {
    method poll_next (line 169) | fn poll_next(
    method try_into_bytes (line 177) | fn try_into_bytes(self) -> Result<Bytes, Self> {
    type Error (line 186) | type Error = B::Error;
    method size (line 189) | fn size(&self) -> BodySize {
    method poll_next (line 194) | fn poll_next(
    type Error (line 207) | type Error = B::Error;
    method size (line 210) | fn size(&self) -> BodySize {
    method poll_next (line 215) | fn poll_next(
    type Error (line 224) | type Error = Infallible;
    method size (line 227) | fn size(&self) -> BodySize {
    method poll_next (line 232) | fn poll_next(
    method try_into_bytes (line 244) | fn try_into_bytes(self) -> Result<Bytes, Self> {
    type Error (line 250) | type Error = Infallible;
    method size (line 253) | fn size(&self) -> BodySize {
    method poll_next (line 258) | fn poll_next(
    method try_into_bytes (line 270) | fn try_into_bytes(self) -> Result<Bytes, Self> {
    type Error (line 276) | type Error = Infallible;
    method size (line 279) | fn size(&self) -> BodySize {
    method poll_next (line 284) | fn poll_next(
    method try_into_bytes (line 296) | fn try_into_bytes(self) -> Result<Bytes, Self> {
    type Error (line 302) | type Error = Infallible;
    method size (line 305) | fn size(&self) -> BodySize {
    method poll_next (line 310) | fn poll_next(
    method try_into_bytes (line 322) | fn try_into_bytes(self) -> Result<Bytes, Self> {
    type Error (line 328) | type Error = Infallible;
    method size (line 331) | fn size(&self) -> BodySize {
    method poll_next (line 336) | fn poll_next(
    method try_into_bytes (line 352) | fn try_into_bytes(self) -> Result<Bytes, Self> {
    type Error (line 361) | type Error = Infallible;
    method size (line 364) | fn size(&self) -> BodySize {
    method poll_next (line 369) | fn poll_next(
    method try_into_bytes (line 383) | fn try_into_bytes(self) -> Result<Bytes, Self> {
    type Error (line 389) | type Error = Infallible;
    method size (line 392) | fn size(&self) -> BodySize {
    method poll_next (line 397) | fn poll_next(
    method try_into_bytes (line 410) | fn try_into_bytes(self) -> Result<Bytes, Self> {
    type Error (line 416) | type Error = Infallible;
    method size (line 419) | fn size(&self) -> BodySize {
    method poll_next (line 424) | fn poll_next(
    method try_into_bytes (line 440) | fn try_into_bytes(self) -> Result<Bytes, Self> {
    type Error (line 449) | type Error = Infallible;
    method size (line 452) | fn size(&self) -> BodySize {
    method poll_next (line 457) | fn poll_next(
    method try_into_bytes (line 466) | fn try_into_bytes(self) -> Result<Bytes, Self> {
    type Error (line 499) | type Error = E;
    method size (line 502) | fn size(&self) -> BodySize {
    method poll_next (line 506) | fn poll_next(
    method try_into_bytes (line 524) | fn try_into_bytes(self) -> Result<Bytes, Self> {
  function new (line 485) | pub(crate) fn new(body: B, mapper: F) -> Self {
  function boxing_equivalence (line 559) | async fn boxing_equivalence() {
  function mut_equivalence (line 573) | async fn mut_equivalence() {
  function test_unit (line 602) | async fn test_unit() {
  function test_static_str (line 610) | async fn test_static_str() {
  function test_static_bytes (line 620) | async fn test_static_bytes() {
  function test_vec (line 630) | async fn test_vec() {
  function test_bytes (line 640) | async fn test_bytes() {
  function test_bytes_mut (line 650) | async fn test_bytes_mut() {
  function test_string (line 660) | async fn test_string() {
  function complete_body_combinators (line 670) | async fn complete_body_combinators() {
  function complete_body_combinators_poll (line 683) | async fn complete_body_combinators_poll() {
  function none_body_combinators (line 696) | async fn none_body_combinators() {
  function test_body_casting (line 713) | async fn test_body_casting() {
  function non_owning_to_bytes (line 728) | async fn non_owning_to_bytes() {

FILE: actix-http/src/body/none.rs
  type None (line 21) | pub struct None;
    method new (line 26) | pub fn new() -> Self {
  type Error (line 32) | type Error = Infallible;
  method size (line 35) | fn size(&self) -> BodySize {
  method poll_next (line 40) | fn poll_next(
  method try_into_bytes (line 48) | fn try_into_bytes(self) -> Result<Bytes, Self> {

FILE: actix-http/src/body/size.rs
  type BodySize (line 3) | pub enum BodySize {
    constant ZERO (line 24) | pub const ZERO: Self = Self::Sized(0);
    method is_eof (line 38) | pub fn is_eof(&self) -> bool {

FILE: actix-http/src/body/sized_stream.rs
  function new (line 31) | pub fn new(size: u64, stream: S) -> Self {
  type Error (line 43) | type Error = E;
  method size (line 46) | fn size(&self) -> BodySize {
  method poll_next (line 55) | fn poll_next(
  function skips_empty_chunks (line 96) | async fn skips_empty_chunks() {
  function read_to_bytes (line 126) | async fn read_to_bytes() {
  function stream_string_error (line 140) | async fn stream_string_error() {
  function stream_boxed_error (line 152) | async fn stream_boxed_error() {

FILE: actix-http/src/body/utils.rs
  function to_bytes (line 33) | pub async fn to_bytes<B: MessageBody>(body: B) -> Result<Bytes, B::Error> {
  type BodyLimitExceeded (line 43) | pub struct BodyLimitExceeded;
  function to_bytes_limited (line 71) | pub async fn to_bytes_limited<B: MessageBody>(
  function to_bytes_complete (line 134) | async fn to_bytes_complete() {
  function to_bytes_streams (line 144) | async fn to_bytes_streams() {
  function to_bytes_limited_complete (line 153) | async fn to_bytes_limited_complete() {
  function to_bytes_limited_streams (line 171) | async fn to_bytes_limited_streams() {
  function to_body_limit_error (line 192) | async fn to_body_limit_error() {

FILE: actix-http/src/builder.rs
  type HttpServiceBuilder (line 17) | pub struct HttpServiceBuilder<T, S, X = ExpectHandler, U = UpgradeHandle...
  method default (line 40) | fn default() -> Self {
  function keep_alive (line 80) | pub fn keep_alive<W: Into<KeepAlive>>(mut self, val: W) -> Self {
  function secure (line 86) | pub fn secure(mut self) -> Self {
  function local_addr (line 92) | pub fn local_addr(mut self, addr: net::SocketAddr) -> Self {
  function client_request_timeout (line 106) | pub fn client_request_timeout(mut self, dur: Duration) -> Self {
  function client_timeout (line 113) | pub fn client_timeout(self, dur: Duration) -> Self {
  function client_disconnect_timeout (line 125) | pub fn client_disconnect_timeout(mut self, dur: Duration) -> Self {
  function tcp_nodelay (line 131) | pub fn tcp_nodelay(mut self, nodelay: bool) -> Self {
  function client_disconnect (line 138) | pub fn client_disconnect(self, dur: Duration) -> Self {
  function h1_allow_half_closed (line 149) | pub fn h1_allow_half_closed(mut self, allow: bool) -> Self {
  function h2_initial_window_size (line 157) | pub fn h2_initial_window_size(mut self, size: u32) -> Self {
  function h2_initial_connection_window_size (line 165) | pub fn h2_initial_connection_window_size(mut self, size: u32) -> Self {
  function expect (line 175) | pub fn expect<F, X1>(self, expect: F) -> HttpServiceBuilder<T, S, X1, U>
  function upgrade (line 203) | pub fn upgrade<F, U1>(self, upgrade: F) -> HttpServiceBuilder<T, S, X, U1>
  function on_connect_ext (line 232) | pub fn on_connect_ext<F>(mut self, f: F) -> Self
  function h1 (line 241) | pub fn h1<F, B>(self, service: F) -> H1Service<T, S, B, X, U>
  function h2 (line 269) | pub fn h2<F, B>(self, service: F) -> crate::h2::H2Service<T, S, B>
  function finish (line 295) | pub fn finish<F, B>(self, service: F) -> HttpService<T, S, B, X, U>

FILE: actix-http/src/config.rs
  constant DEFAULT_H2_CONN_WINDOW_SIZE (line 14) | pub(crate) const DEFAULT_H2_CONN_WINDOW_SIZE: u32 = 1024 * 1024 * 2;
  constant DEFAULT_H2_STREAM_WINDOW_SIZE (line 19) | pub(crate) const DEFAULT_H2_STREAM_WINDOW_SIZE: u32 = 1024 * 1024;
  type ServiceConfigBuilder (line 23) | pub struct ServiceConfigBuilder {
    method new (line 38) | pub fn new() -> Self {
    method secure (line 43) | pub fn secure(mut self, secure: bool) -> Self {
    method local_addr (line 49) | pub fn local_addr(mut self, local_addr: Option<SocketAddr>) -> Self {
    method keep_alive (line 55) | pub fn keep_alive(mut self, keep_alive: KeepAlive) -> Self {
    method client_request_timeout (line 61) | pub fn client_request_timeout(mut self, timeout: Duration) -> Self {
    method client_disconnect_timeout (line 68) | pub fn client_disconnect_timeout(mut self, timeout: Duration) -> Self {
    method tcp_nodelay (line 74) | pub fn tcp_nodelay(mut self, nodelay: Option<bool>) -> Self {
    method h1_allow_half_closed (line 84) | pub fn h1_allow_half_closed(mut self, allow: bool) -> Self {
    method h2_initial_window_size (line 95) | pub fn h2_initial_window_size(mut self, size: u32) -> Self {
    method h2_initial_connection_window_size (line 106) | pub fn h2_initial_connection_window_size(mut self, size: u32) -> Self {
    method build (line 112) | pub fn build(self) -> ServiceConfig {
  type ServiceConfig (line 119) | pub struct ServiceConfig(Rc<Inner>);
    method new (line 154) | pub fn new(
    method secure (line 177) | pub fn secure(&self) -> bool {
    method local_addr (line 185) | pub fn local_addr(&self) -> Option<SocketAddr> {
    method keep_alive (line 191) | pub fn keep_alive(&self) -> KeepAlive {
    method keep_alive_deadline (line 199) | pub fn keep_alive_deadline(&self) -> Option<Instant> {
    method client_request_deadline (line 211) | pub fn client_request_deadline(&self) -> Option<Instant> {
    method client_disconnect_deadline (line 217) | pub fn client_disconnect_deadline(&self) -> Option<Instant> {
    method h1_allow_half_closed (line 227) | pub fn h1_allow_half_closed(&self) -> bool {
    method tcp_nodelay (line 232) | pub fn tcp_nodelay(&self) -> Option<bool> {
    method h2_initial_window_size (line 237) | pub fn h2_initial_window_size(&self) -> u32 {
    method h2_initial_connection_window_size (line 242) | pub fn h2_initial_connection_window_size(&self) -> u32 {
    method now (line 246) | pub(crate) fn now(&self) -> Instant {
    method write_date_header (line 255) | pub fn write_date_header(&self, dst: &mut BytesMut, camel_case: bool) {
    method write_date_header_value (line 269) | pub(crate) fn write_date_header_value(&self, dst: &mut BytesMut) {
  type Inner (line 122) | struct Inner {
  method default (line 136) | fn default() -> Self {
  function test_date_service_update (line 288) | async fn test_date_service_update() {
  function test_date_service_drop (line 321) | async fn test_date_service_drop() {
  function test_date_len (line 350) | fn test_date_len() {
  function test_date (line 355) | async fn test_date() {
  function test_date_camel_case (line 368) | async fn test_date_camel_case() {

FILE: actix-http/src/date.rs
  constant DATE_VALUE_LENGTH (line 11) | pub(crate) const DATE_VALUE_LENGTH: usize = 29;
  type Date (line 14) | pub(crate) struct Date {
    method new (line 20) | fn new() -> Date {
    method update (line 29) | fn update(&mut self) {
    method write_str (line 36) | fn write_str(&mut self, s: &str) -> fmt::Result {
  type DateService (line 45) | pub(crate) struct DateService {
    method new (line 51) | pub(crate) fn new() -> Self {
    method now (line 72) | pub(crate) fn now(&self) -> Instant {
    method with_date (line 76) | pub(crate) fn with_date<F: FnMut(&Date)>(&self, mut f: F) {
    method fmt (line 82) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  method drop (line 88) | fn drop(&mut self) {

FILE: actix-http/src/encoding/decoder.rs
  constant MAX_CHUNK_SIZE_DECODE_IN_PLACE (line 24) | const MAX_CHUNK_SIZE_DECODE_IN_PLACE: usize = 2049;
  function new (line 42) | pub fn new(stream: S, encoding: ContentEncoding) -> Decoder<S> {
  function from_headers (line 79) | pub fn from_headers(stream: S, headers: &HeaderMap) -> Decoder<S> {
  type Item (line 95) | type Item = Result<Bytes, PayloadError>;
  method poll_next (line 97) | fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<...
  type ContentDecoder (line 161) | enum ContentDecoder {
    method feed_eof (line 178) | fn feed_eof(&mut self) -> io::Result<Option<Bytes>> {
    method feed_data (line 236) | fn feed_data(&mut self, data: Bytes) -> io::Result<Option<Bytes>> {

FILE: actix-http/src/encoding/encoder.rs
  constant MAX_CHUNK_SIZE_ENCODE_IN_PLACE (line 29) | const MAX_CHUNK_SIZE_ENCODE_IN_PLACE: usize = 1024;
  function none (line 42) | fn none() -> Self {
  function empty (line 53) | fn empty() -> Self {
  function response (line 62) | pub fn response(encoding: ContentEncoding, head: &mut ResponseHead, body...
  type Error (line 117) | type Error = EncoderError;
  method size (line 120) | fn size(&self) -> BodySize {
  method poll_next (line 128) | fn poll_next(
  method try_into_bytes (line 146) | fn try_into_bytes(self) -> Result<Bytes, Self>
  type Error (line 162) | type Error = EncoderError;
  method size (line 165) | fn size(&self) -> BodySize {
  method poll_next (line 173) | fn poll_next(
  method try_into_bytes (line 247) | fn try_into_bytes(mut self) -> Result<Bytes, Self>
  function update_head (line 265) | fn update_head(encoding: ContentEncoding, head: &mut ResponseHead) {
  type ContentEncoder (line 274) | enum ContentEncoder {
    method select (line 291) | fn select(encoding: ContentEncoding) -> Option<Self> {
    method take (line 319) | pub(crate) fn take(&mut self) -> Bytes {
    method finish (line 335) | fn finish(self) -> Result<Bytes, io::Error> {
    method write (line 363) | fn write(&mut self, data: &[u8]) -> Result<(), io::Error> {
  function new_brotli_compressor (line 405) | fn new_brotli_compressor() -> Box<brotli::CompressorWriter<Writer>> {
  type EncoderError (line 416) | pub enum EncoderError {
  method source (line 427) | fn source(&self) -> Option<&(dyn StdError + 'static)> {
  function from (line 436) | fn from(err: EncoderError) -> Self {

FILE: actix-http/src/encoding/mod.rs
  type Writer (line 15) | struct Writer {
    method new (line 20) | fn new() -> Writer {
    method take (line 26) | fn take(&mut self) -> Bytes {
    method write (line 32) | fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
    method flush (line 37) | fn flush(&mut self) -> io::Result<()> {

FILE: actix-http/src/error.rs
  type Error (line 11) | pub struct Error {
    method new (line 22) | fn new(kind: Kind) -> Self {
    method with_cause (line 28) | pub(crate) fn with_cause(mut self, cause: impl Into<Box<dyn StdError>>...
    method new_http (line 33) | pub(crate) fn new_http() -> Self {
    method new_parse (line 37) | pub(crate) fn new_parse() -> Self {
    method new_payload (line 41) | pub(crate) fn new_payload() -> Self {
    method new_body (line 45) | pub(crate) fn new_body() -> Self {
    method new_send_response (line 49) | pub(crate) fn new_send_response() -> Self {
    method new_io (line 54) | pub(crate) fn new_io() -> Self {
    method new_encoder (line 59) | pub(crate) fn new_encoder() -> Self {
    method new_ws (line 64) | pub(crate) fn new_ws() -> Self {
    method fmt (line 109) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    method fmt (line 118) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    method from (line 133) | fn from(err: std::convert::Infallible) -> Self {
    method from (line 139) | fn from(err: HttpError) -> Self {
    method from (line 146) | fn from(err: crate::ws::HandshakeError) -> Self {
    method from (line 153) | fn from(err: crate::ws::ProtocolError) -> Self {
    method from (line 243) | fn from(err: ParseError) -> Self {
    method from (line 319) | fn from(err: PayloadError) -> Self {
  type ErrorInner (line 15) | pub(crate) struct ErrorInner {
  function from (line 70) | fn from(err: Error) -> Self {
  type Kind (line 82) | pub(crate) enum Kind {
  method source (line 127) | fn source(&self) -> Option<&(dyn StdError + 'static)> {
  type ParseError (line 161) | pub enum ParseError {
    method from (line 205) | fn from(err: io::Error) -> ParseError {
    method from (line 211) | fn from(err: InvalidUri) -> ParseError {
    method from (line 217) | fn from(err: Utf8Error) -> ParseError {
    method from (line 223) | fn from(err: FromUtf8Error) -> ParseError {
    method from (line 229) | fn from(err: httparse::Error) -> ParseError {
  function from (line 249) | fn from(err: ParseError) -> Self {
  type PayloadError (line 257) | pub enum PayloadError {
    method source (line 285) | fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
    method from (line 301) | fn from(err: ::h2::Error) -> Self {
    method from (line 307) | fn from(err: Option<io::Error>) -> Self {
    method from (line 313) | fn from(err: io::Error) -> Self {
  type DispatchError (line 327) | pub enum DispatchError {
  method source (line 371) | fn source(&self) -> Option<&(dyn StdError + 'static)> {
  type ContentTypeError (line 390) | pub enum ContentTypeError {
  function test_into_response (line 407) | fn test_into_response() {
  function test_as_response (line 417) | fn test_as_response() {
  function test_error_display (line 427) | fn test_error_display() {
  function test_error_http_response (line 434) | fn test_error_http_response() {
  function test_payload_error (line 442) | fn test_payload_error() {
  function test_from (line 477) | fn test_from() {

FILE: actix-http/src/extensions.rs
  type NoOpHasher (line 13) | struct NoOpHasher(u64);
  method write (line 16) | fn write(&mut self, _bytes: &[u8]) {
  method write_u64 (line 20) | fn write_u64(&mut self, i: u64) {
  method finish (line 24) | fn finish(&self) -> u64 {
  type Extensions (line 33) | pub struct Extensions {
    method new (line 41) | pub fn new() -> Extensions {
    method insert (line 59) | pub fn insert<T: 'static>(&mut self, val: T) -> Option<T> {
    method contains (line 75) | pub fn contains<T: 'static>(&self) -> bool {
    method get (line 87) | pub fn get<T: 'static>(&self) -> Option<&T> {
    method get_mut (line 101) | pub fn get_mut<T: 'static>(&mut self) -> Option<&mut T> {
    method get_or_insert (line 121) | pub fn get_or_insert<T: 'static>(&mut self, value: T) -> &mut T {
    method get_or_insert_with (line 139) | pub fn get_or_insert_with<T: 'static, F: FnOnce() -> T>(&mut self, def...
    method remove (line 161) | pub fn remove<T: 'static>(&mut self) -> Option<T> {
    method clear (line 178) | pub fn clear(&mut self) {
    method extend (line 183) | pub fn extend(&mut self, other: Extensions) {
    method fmt (line 189) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  function downcast_owned (line 194) | fn downcast_owned<T: 'static>(boxed: Box<dyn Any>) -> Option<T> {
  function test_remove (line 203) | fn test_remove() {
  function test_clear (line 214) | fn test_clear() {
  function test_integers (line 236) | fn test_integers() {
  function test_composition (line 266) | fn test_composition() {
  function test_extensions (line 293) | fn test_extensions() {
  function test_extend (line 313) | fn test_extend() {

FILE: actix-http/src/h1/chunked.rs
  type ChunkedState (line 19) | pub(super) enum ChunkedState {
    method step (line 33) | pub(super) fn step(
    method read_size (line 54) | fn read_size(rdr: &mut BytesMut, size: &mut u64) -> Poll<Result<Chunke...
    method read_size_lws (line 89) | fn read_size_lws(rdr: &mut BytesMut) -> Poll<Result<ChunkedState, io::...
    method read_extension (line 101) | fn read_extension(rdr: &mut BytesMut) -> Poll<Result<ChunkedState, io:...
    method read_size_lf (line 112) | fn read_size_lf(rdr: &mut BytesMut, size: u64) -> Poll<Result<ChunkedS...
    method read_body (line 123) | fn read_body(
    method read_body_cr (line 151) | fn read_body_cr(rdr: &mut BytesMut) -> Poll<Result<ChunkedState, io::E...
    method read_body_lf (line 160) | fn read_body_lf(rdr: &mut BytesMut) -> Poll<Result<ChunkedState, io::E...
    method read_end_cr (line 169) | fn read_end_cr(rdr: &mut BytesMut) -> Poll<Result<ChunkedState, io::Er...
    method read_end_lf (line 178) | fn read_end_lf(rdr: &mut BytesMut) -> Poll<Result<ChunkedState, io::Er...
  function test_parse_chunked_payload_chunk_extension (line 224) | fn test_parse_chunked_payload_chunk_extension() {
  function test_request_chunked (line 246) | fn test_request_chunked() {
  function test_http_request_chunked_payload (line 268) | fn test_http_request_chunked_payload() {
  function test_http_request_chunked_payload_and_next_message (line 291) | fn test_http_request_chunked_payload_and_next_message() {
  function test_http_request_chunked_payload_chunks (line 321) | fn test_http_request_chunked_payload_chunks() {
  function chunk_extension_quoted (line 366) | fn chunk_extension_quoted() {
  function hrs_chunk_extension_invalid (line 385) | fn hrs_chunk_extension_invalid() {
  function hrs_chunk_size_overflow (line 407) | fn hrs_chunk_size_overflow() {

FILE: actix-http/src/h1/client.rs
  type ClientCodec (line 28) | pub struct ClientCodec {
    method fmt (line 56) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    method new (line 67) | pub fn new(config: ServiceConfig) -> Self {
    method upgrade (line 89) | pub fn upgrade(&self) -> bool {
    method keep_alive (line 94) | pub fn keep_alive(&self) -> bool {
    method message_type (line 99) | pub fn message_type(&self) -> MessageType {
    method into_payload_codec (line 110) | pub fn into_payload_codec(self) -> ClientPayloadCodec {
    type Error (line 192) | type Error = io::Error;
    method encode (line 194) | fn encode(
  type ClientPayloadCodec (line 33) | pub struct ClientPayloadCodec {
    method keep_alive (line 117) | pub fn keep_alive(&self) -> bool {
    method into_message_codec (line 122) | pub fn into_message_codec(self) -> ClientCodec {
  type ClientCodecInner (line 37) | struct ClientCodecInner {
  method default (line 50) | fn default() -> Self {
  type Item (line 128) | type Item = ResponseHead;
  type Error (line 129) | type Error = ParseError;
  method decode (line 131) | fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, S...
  type Item (line 168) | type Item = Option<Bytes>;
  type Error (line 169) | type Error = PayloadError;
  method decode (line 171) | fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, S...

FILE: actix-http/src/h1/codec.rs
  type Codec (line 24) | pub struct Codec {
    method fmt (line 43) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    method new (line 54) | pub fn new(config: ServiceConfig) -> Self {
    method upgrade (line 74) | pub fn upgrade(&self) -> bool {
    method keep_alive (line 80) | pub fn keep_alive(&self) -> bool {
    method keep_alive_enabled (line 86) | pub fn keep_alive_enabled(&self) -> bool {
    method message_type (line 92) | pub fn message_type(&self) -> MessageType {
    method config (line 103) | pub fn config(&self) -> &ServiceConfig {
    type Error (line 150) | type Error = io::Error;
    method encode (line 152) | fn encode(
  method default (line 37) | fn default() -> Self {
  type Item (line 109) | type Item = Message<Request>;
  type Error (line 110) | type Error = ParseError;
  method decode (line 112) | fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, S...
  function test_http_request_chunked_payload_and_next_message (line 205) | async fn test_http_request_chunked_payload_and_next_message() {

FILE: actix-http/src/h1/decoder.rs
  constant MAX_BUFFER_SIZE (line 14) | pub(crate) const MAX_BUFFER_SIZE: usize = 131_072;
  constant MAX_HEADERS (line 15) | const MAX_HEADERS: usize = 96;
  type MessageDecoder (line 18) | pub(crate) struct MessageDecoder<T: MessageType>(PhantomData<T>);
  type PayloadType (line 22) | pub(crate) enum PayloadType {
    method unwrap (line 570) | pub(crate) fn unwrap(self) -> PayloadDecoder {
    method is_unhandled (line 577) | pub(crate) fn is_unhandled(&self) -> bool {
  method default (line 29) | fn default() -> Self {
  type Item (line 35) | type Item = (T, PayloadType);
  type Error (line 36) | type Error = ParseError;
  method decode (line 38) | fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, S...
  type PayloadLength (line 43) | pub(crate) enum PayloadLength {
    method is_none (line 51) | fn is_none(&self) -> bool {
    method is_zero (line 56) | fn is_zero(&self) -> bool {
  type MessageType (line 66) | pub(crate) trait MessageType: Sized {
    method set_connection_type (line 67) | fn set_connection_type(&mut self, conn_type: Option<ConnectionType>);
    method set_expect (line 69) | fn set_expect(&mut self);
    method headers_mut (line 71) | fn headers_mut(&mut self) -> &mut HeaderMap;
    method decode (line 73) | fn decode(src: &mut BytesMut) -> Result<Option<(Self, PayloadType)>, P...
    method set_headers (line 75) | fn set_headers(
    method set_connection_type (line 217) | fn set_connection_type(&mut self, conn_type: Option<ConnectionType>) {
    method set_expect (line 223) | fn set_expect(&mut self) {
    method headers_mut (line 227) | fn headers_mut(&mut self) -> &mut HeaderMap {
    method decode (line 231) | fn decode(src: &mut BytesMut) -> Result<Option<(Self, PayloadType)>, P...
    method set_connection_type (line 318) | fn set_connection_type(&mut self, conn_type: Option<ConnectionType>) {
    method set_expect (line 324) | fn set_expect(&mut self) {}
    method headers_mut (line 326) | fn headers_mut(&mut self) -> &mut HeaderMap {
    method decode (line 330) | fn decode(src: &mut BytesMut) -> Result<Option<(Self, PayloadType)>, P...
  type HeaderIndex (line 408) | pub(crate) struct HeaderIndex {
    method record (line 422) | pub(crate) fn record(
  constant EMPTY_HEADER_INDEX (line 413) | pub(crate) const EMPTY_HEADER_INDEX: HeaderIndex = HeaderIndex {
  constant EMPTY_HEADER_INDEX_ARRAY (line 418) | pub(crate) const EMPTY_HEADER_INDEX_ARRAY: [HeaderIndex; MAX_HEADERS] =
  type PayloadItem (line 441) | pub enum PayloadItem {
    method chunk (line 583) | pub(crate) fn chunk(self) -> Bytes {
    method eof (line 590) | pub(crate) fn eof(&self) -> bool {
  type PayloadDecoder (line 450) | pub struct PayloadDecoder {
    method length (line 456) | pub fn length(x: u64) -> PayloadDecoder {
    method chunked (line 463) | pub fn chunked() -> PayloadDecoder {
    method eof (line 470) | pub fn eof() -> PayloadDecoder {
  type Kind (line 476) | enum Kind {
  type Item (line 501) | type Item = PayloadItem;
  type Error (line 502) | type Error = io::Error;
  method decode (line 504) | fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, S...
  function test_parse (line 618) | fn test_parse() {
  function test_parse_partial (line 633) | fn test_parse_partial() {
  function parse_h09_reject (line 647) | fn parse_h09_reject() {
  function parse_h10_get (line 668) | fn parse_h10_get() {
  function parse_h10_post (line 707) | fn parse_h10_post() {
  function test_parse_body (line 744) | fn test_parse_body() {
  function test_parse_body_crlf (line 760) | fn test_parse_body_crlf() {
  function test_parse_partial_eof (line 776) | fn test_parse_partial_eof() {
  function test_headers_split_field (line 789) | fn test_headers_split_field() {
  function test_headers_multi_value (line 816) | fn test_headers_multi_value() {
  function test_conn_default_1_0 (line 835) | fn test_conn_default_1_0() {
  function test_conn_default_1_1 (line 841) | fn test_conn_default_1_1() {
  function test_conn_close (line 847) | fn test_conn_close() {
  function test_conn_close_1_0 (line 862) | fn test_conn_close_1_0() {
  function test_conn_keep_alive_1_0 (line 871) | fn test_conn_keep_alive_1_0() {
  function test_conn_keep_alive_1_1 (line 886) | fn test_conn_keep_alive_1_1() {
  function test_conn_other_1_0 (line 895) | fn test_conn_other_1_0() {
  function test_conn_other_1_1 (line 904) | fn test_conn_other_1_1() {
  function test_conn_upgrade (line 913) | fn test_conn_upgrade() {
  function test_conn_upgrade_connect_method (line 934) | fn test_conn_upgrade_connect_method() {
  function test_headers_bad_content_length (line 944) | fn test_headers_bad_content_length() {
  function octal_ish_cl_parsed_as_decimal (line 959) | fn octal_ish_cl_parsed_as_decimal() {
  function test_invalid_header (line 973) | fn test_invalid_header() {
  function test_invalid_name (line 981) | fn test_invalid_name() {
  function test_http_request_bad_status_line (line 989) | fn test_http_request_bad_status_line() {
  function test_http_request_upgrade_websocket (line 994) | fn test_http_request_upgrade_websocket() {
  function test_http_request_upgrade_h2c (line 1009) | fn test_http_request_upgrade_h2c() {
  function test_http_request_parser_utf8 (line 1029) | fn test_http_request_parser_utf8() {
  function test_http_request_parser_two_slashes (line 1042) | fn test_http_request_parser_two_slashes() {
  function test_http_request_parser_bad_method (line 1048) | fn test_http_request_parser_bad_method() {
  function test_http_request_parser_bad_version (line 1053) | fn test_http_request_parser_bad_version() {
  function test_response_http10_read_until_eof (line 1058) | fn test_response_http10_read_until_eof() {
  function hrs_multiple_content_length (line 1070) | fn hrs_multiple_content_length() {
  function hrs_content_length_plus (line 1091) | fn hrs_content_length_plus() {
  function hrs_te_http10 (line 1102) | fn hrs_te_http10() {
  function hrs_cl_and_te_http10 (line 1118) | fn hrs_cl_and_te_http10() {
  function hrs_unknown_transfer_encoding (line 1134) | fn hrs_unknown_transfer_encoding() {
  function hrs_multiple_transfer_encoding (line 1150) | fn hrs_multiple_transfer_encoding() {
  function transfer_encoding_agrees (line 1168) | fn transfer_encoding_agrees() {

FILE: actix-http/src/h1/dispatcher.rs
  constant LW_BUFFER_SIZE (line 37) | const LW_BUFFER_SIZE: usize = 1024;
  constant HW_BUFFER_SIZE (line 38) | const HW_BUFFER_SIZE: usize = 1024 * 8;
  constant MAX_PIPELINED_MESSAGES (line 39) | const MAX_PIPELINED_MESSAGES: usize = 16;
  type DispatcherMessage (line 175) | enum DispatcherMessage {
  function is_none (line 203) | pub(super) fn is_none(&self) -> bool {
  function fmt (line 214) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  type PollResponse (line 232) | enum PollResponse {
  function new (line 255) | pub(crate) fn new(
  function can_read (line 310) | fn can_read(&self, cx: &mut Context<'_>) -> bool {
  function client_disconnected (line 323) | fn client_disconnected(self: Pin<&mut Self>) {
  function poll_flush (line 334) | fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result...
  function send_response_inner (line 364) | fn send_response_inner(
  function send_response (line 386) | fn send_response(
  function send_error_response (line 413) | fn send_error_response(
  function send_continue (line 440) | fn send_continue(self: Pin<&mut Self>) {
  function poll_response (line 446) | fn poll_response(
  function handle_request (line 655) | fn handle_request(
  function poll_request (line 740) | fn poll_request(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Resul...
  function poll_head_timer (line 889) | fn poll_head_timer(
  function poll_ka_timer (line 913) | fn poll_ka_timer(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Resu...
  function poll_shutdown_timer (line 956) | fn poll_shutdown_timer(
  function poll_timers (line 978) | fn poll_timers(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Result...
  function read_available (line 992) | fn read_available(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Result<...
  function upgrade (line 1078) | fn upgrade(self: Pin<&mut Self>, req: Request) -> U::Future {
  type Output (line 1107) | type Output = Result<(), DispatchError>;
  method poll (line 1110) | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Ou...
  function trace_timer_states (line 1299) | fn trace_timer_states(

FILE: actix-http/src/h1/dispatcher_tests.rs
  type YieldService (line 26) | struct YieldService;
    type Response (line 29) | type Response = Response<BoxBody>;
    type Error (line 30) | type Error = Response<BoxBody>;
    type Future (line 31) | type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self:...
    method call (line 35) | fn call(&self, _: Request) -> Self::Future {
  function find_slice (line 46) | fn find_slice(haystack: &[u8], needle: &[u8], from: usize) -> Option<usi...
  function stabilize_date_header (line 50) | fn stabilize_date_header(payload: &mut [u8]) {
  function ok_service (line 59) | fn ok_service() -> impl Service<Request, Response = Response<impl Messag...
  function status_service (line 63) | fn status_service(
  function echo_path_service (line 69) | fn echo_path_service() -> impl Service<Request, Response = Response<impl...
  function drop_payload_service (line 79) | fn drop_payload_service() -> impl Service<Request, Response = Response<&...
  function echo_payload_service (line 87) | fn echo_payload_service() -> impl Service<Request, Response = Response<B...
  function late_request (line 104) | async fn late_request() {
  function oneshot_connection (line 171) | async fn oneshot_connection() {
  function keep_alive_timeout (line 232) | async fn keep_alive_timeout() {
  function keep_alive_follow_up_req (line 311) | async fn keep_alive_follow_up_req() {
  function req_parse_err (line 436) | async fn req_parse_err() {
  function pipelining_ok_then_ok (line 469) | async fn pipelining_ok_then_ok() {
  function early_response_with_payload_closes_connection (line 539) | async fn early_response_with_payload_closes_connection() {
  function pipelining_ok_then_bad (line 606) | async fn pipelining_ok_then_bad() {
  function expect_handling (line 675) | async fn expect_handling() {
  function expect_eager (line 752) | async fn expect_eager() {
  function upgrade_handling (line 818) | async fn upgrade_handling() {
  function handler_drop_payload (line 880) | async fn handler_drop_payload() {
  function handler_drop_payload_drains_body (line 1025) | async fn handler_drop_payload_drains_body() {
  function allow_half_closed (line 1143) | async fn allow_half_closed() {
  function disallow_half_closed (line 1191) | async fn disallow_half_closed() {
  function http_msg (line 1227) | fn http_msg(msg: impl AsRef<str>) -> BytesMut {
  function http_msg_creates_msg (line 1247) | fn http_msg_creates_msg() {

FILE: actix-http/src/h1/encoder.rs
  constant AVERAGE_HEADER_SIZE (line 19) | const AVERAGE_HEADER_SIZE: usize = 30;
  type MessageEncoder (line 22) | pub(crate) struct MessageEncoder<T: MessageType> {
  method default (line 30) | fn default() -> Self {
  type MessageType (line 39) | pub(crate) trait MessageType: Sized {
    method status (line 40) | fn status(&self) -> Option<StatusCode>;
    method headers (line 42) | fn headers(&self) -> &HeaderMap;
    method extra_headers (line 44) | fn extra_headers(&self) -> Option<&HeaderMap>;
    method camel_case (line 46) | fn camel_case(&self) -> bool {
    method chunked (line 50) | fn chunked(&self) -> bool;
    method encode_status (line 52) | fn encode_status(&mut self, dst: &mut BytesMut) -> io::Result<()>;
    method encode_headers (line 54) | fn encode_headers(
    method write_headers (line 230) | fn write_headers<F>(&mut self, mut f: F)
    method status (line 250) | fn status(&self) -> Option<StatusCode> {
    method chunked (line 254) | fn chunked(&self) -> bool {
    method headers (line 258) | fn headers(&self) -> &HeaderMap {
    method extra_headers (line 262) | fn extra_headers(&self) -> Option<&HeaderMap> {
    method camel_case (line 266) | fn camel_case(&self) -> bool {
    method encode_status (line 272) | fn encode_status(&mut self, dst: &mut BytesMut) -> io::Result<()> {
    method status (line 285) | fn status(&self) -> Option<StatusCode> {
    method chunked (line 289) | fn chunked(&self) -> bool {
    method camel_case (line 293) | fn camel_case(&self) -> bool {
    method headers (line 297) | fn headers(&self) -> &HeaderMap {
    method extra_headers (line 301) | fn extra_headers(&self) -> Option<&HeaderMap> {
    method encode_status (line 305) | fn encode_status(&mut self, dst: &mut BytesMut) -> io::Result<()> {
  function encode_chunk (line 328) | pub fn encode_chunk(&mut self, msg: &[u8], buf: &mut BytesMut) -> io::Re...
  function encode_eof (line 333) | pub fn encode_eof(&mut self, buf: &mut BytesMut) -> io::Result<()> {
  function encode (line 338) | pub fn encode(
  type TransferEncoding (line 374) | pub(crate) struct TransferEncoding {
    method empty (line 396) | pub fn empty() -> TransferEncoding {
    method eof (line 403) | pub fn eof() -> TransferEncoding {
    method chunked (line 410) | pub fn chunked() -> TransferEncoding {
    method length (line 417) | pub fn length(len: u64) -> TransferEncoding {
    method encode (line 425) | pub fn encode(&mut self, msg: &[u8], buf: &mut BytesMut) -> io::Result...
    method encode_eof (line 470) | pub fn encode_eof(&mut self, buf: &mut BytesMut) -> io::Result<()> {
  type TransferEncodingKind (line 379) | enum TransferEncodingKind {
  function write_data (line 494) | unsafe fn write_data(value: &[u8], buf: *mut u8, len: usize) {
  function write_camel_case (line 502) | unsafe fn write_camel_case(value: &[u8], buf: *mut u8, len: usize) {
  function test_chunked_te (line 547) | fn test_chunked_te() {
  function test_camel_case (line 561) | async fn test_camel_case() {
  function test_extra_headers (line 635) | async fn test_extra_headers() {
  function test_no_content_length (line 668) | async fn test_no_content_length() {

FILE: actix-http/src/h1/expect.rs
  type ExpectHandler (line 6) | pub struct ExpectHandler;
    type Response (line 9) | type Response = Request;
    type Error (line 10) | type Error = Error;
    type Config (line 11) | type Config = ();
    type Service (line 12) | type Service = ExpectHandler;
    type InitError (line 13) | type InitError = Error;
    type Future (line 14) | type Future = Ready<Result<Self::Service, Self::InitError>>;
    method new_service (line 16) | fn new_service(&self, _: Self::Config) -> Self::Future {
    type Response (line 22) | type Response = Request;
    type Error (line 23) | type Error = Error;
    type Future (line 24) | type Future = Ready<Result<Self::Response, Self::Error>>;
    method call (line 28) | fn call(&self, req: Request) -> Self::Future {

FILE: actix-http/src/h1/mod.rs
  type Message (line 33) | pub enum Message<T> {
  function from (line 42) | fn from(item: T) -> Self {
  type MessageType (line 49) | pub enum MessageType {
  constant LW (line 55) | const LW: usize = 2 * 1024;
  constant HW (line 56) | const HW: usize = 32 * 1024;
  function reserve_readbuf (line 58) | pub(crate) fn reserve_readbuf(src: &mut BytesMut) {
  function message (line 71) | pub fn message(self) -> Request {
  function chunk (line 78) | pub fn chunk(self) -> Bytes {
  function eof (line 85) | pub fn eof(self) -> bool {

FILE: actix-http/src/h1/payload.rs
  constant MAX_BUFFER_SIZE (line 17) | pub(crate) const MAX_BUFFER_SIZE: usize = 32_768;
  type PayloadStatus (line 20) | pub enum PayloadStatus {
  type Payload (line 33) | pub struct Payload {
    method create (line 43) | pub fn create(eof: bool) -> (PayloadSender, Payload) {
    method empty (line 53) | pub(crate) fn empty() -> Payload {
    method len (line 61) | pub fn len(&self) -> usize {
    method is_empty (line 67) | pub fn is_empty(&self) -> bool {
    method unread_data (line 73) | pub fn unread_data(&mut self, data: Bytes) {
  type Item (line 79) | type Item = Result<Bytes, PayloadError>;
  method poll_next (line 81) | fn poll_next(
  type PayloadSender (line 90) | pub struct PayloadSender {
    method new (line 95) | fn new(inner: Weak<RefCell<Inner>>) -> Self {
    method set_error (line 100) | pub fn set_error(&mut self, err: PayloadError) {
    method feed_eof (line 107) | pub fn feed_eof(&mut self) {
    method feed_data (line 114) | pub fn feed_data(&mut self, data: Bytes) {
    method need_read (line 122) | pub fn need_read(&self, cx: &mut Context<'_>) -> PayloadStatus {
    method is_dropped (line 138) | pub fn is_dropped(&self) -> bool {
  type Inner (line 144) | struct Inner {
    method new (line 155) | fn new(eof: bool) -> Self {
    method wake (line 168) | fn wake(&mut self) {
    method wake_io (line 175) | fn wake_io(&mut self) {
    method register (line 183) | fn register(&mut self, cx: &Context<'_>) {
    method register_io (line 191) | fn register_io(&mut self, cx: &Context<'_>) {
    method set_error (line 202) | fn set_error(&mut self, err: PayloadError) {
    method feed_eof (line 208) | fn feed_eof(&mut self) {
    method feed_data (line 214) | fn feed_data(&mut self, data: Bytes) {
    method len (line 222) | fn len(&self) -> usize {
    method poll_next (line 226) | fn poll_next(
    method unread_data (line 251) | fn unread_data(&mut self, data: Bytes) {
  constant WAKE_TIMEOUT (line 274) | const WAKE_TIMEOUT: Duration = Duration::from_secs(2);
  function prepare_waking_test (line 276) | fn prepare_waking_test(
  function wake_on_error (line 316) | async fn wake_on_error() {
  function wake_on_eof (line 326) | async fn wake_on_eof() {
  function test_unread_data (line 336) | async fn test_unread_data() {

FILE: actix-http/src/h1/service.rs
  type H1Service (line 28) | pub struct H1Service<T, S, B, X = ExpectHandler, U = UpgradeHandler> {
  function with_config (line 46) | pub(crate) fn with_config<F: IntoServiceFactory<S, Request>>(
  function tcp (line 82) | pub fn tcp(
  function openssl (line 131) | pub fn openssl(
  function rustls (line 192) | pub fn rustls(
  function rustls_021 (line 253) | pub fn rustls_021(
  function rustls_0_22 (line 314) | pub fn rustls_0_22(
  function rustls_0_23 (line 375) | pub fn rustls_0_23(
  function expect (line 407) | pub fn expect<X1>(self, expect: X1) -> H1Service<T, S, B, X1, U>
  function upgrade (line 423) | pub fn upgrade<U1>(self, upgrade: Option<U1>) -> H1Service<T, S, B, X, U1>
  function on_connect_ext (line 440) | pub(crate) fn on_connect_ext(mut self, f: Option<Rc<ConnectCallback<T>>>...
  type Response (line 468) | type Response = ();
  type Error (line 469) | type Error = DispatchError;
  type Config (line 470) | type Config = ();
  type Service (line 471) | type Service = H1ServiceHandler<T, S::Service, B, X::Service, U::Service>;
  type InitError (line 472) | type InitError = ();
  type Future (line 473) | type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitEr...
  function new_service (line 475) | fn new_service(&self, _: ()) -> Self::Future {
  type H1ServiceHandler (line 513) | pub type H1ServiceHandler<T, S, B, X, U> = HttpServiceHandler<T, S, B, X...
  type Response (line 531) | type Response = ();
  type Error (line 532) | type Error = DispatchError;
  type Future (line 533) | type Future = Dispatcher<T, S, B, X, U>;
  function poll_ready (line 535) | fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Erro...
  function call (line 542) | fn call(&self, (io, addr): (T, Option<net::SocketAddr>)) -> Self::Future {

FILE: actix-http/src/h1/timer.rs
  type TimerState (line 7) | pub(super) enum TimerState {
    method new (line 14) | pub(super) fn new(enabled: bool) -> Self {
    method is_enabled (line 22) | pub(super) fn is_enabled(&self) -> bool {
    method set (line 26) | pub(super) fn set(&mut self, timer: Sleep, line: u32) {
    method set_and_init (line 36) | pub(super) fn set_and_init(&mut self, cx: &mut Context<'_>, timer: Sle...
    method clear (line 41) | pub(super) fn clear(&mut self, line: u32) {
    method init (line 53) | pub(super) fn init(&mut self, cx: &mut Context<'_>) {
    method fmt (line 61) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {

FILE: actix-http/src/h1/upgrade.rs
  type UpgradeHandler (line 7) | pub struct UpgradeHandler;
    type Response (line 10) | type Response = ();
    type Error (line 11) | type Error = Error;
    type Config (line 12) | type Config = ();
    type Service (line 13) | type Service = UpgradeHandler;
    type InitError (line 14) | type InitError = Error;
    type Future (line 15) | type Future = LocalBoxFuture<'static, Result<Self::Service, Self::Init...
    method new_service (line 17) | fn new_service(&self, _: ()) -> Self::Future {
    type Response (line 23) | type Response = ();
    type Error (line 24) | type Error = Error;
    type Future (line 25) | type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Err...
    method call (line 29) | fn call(&self, _: (Request, Framed<T, Codec>)) -> Self::Future {

FILE: actix-http/src/h1/utils.rs
  function new (line 34) | pub fn new(framed: Framed<T, Codec>, response: Response<B>) -> Self {
  type Output (line 51) | type Output = Result<Framed<T, Codec>, Error>;
  method poll (line 54) | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Ou...

FILE: actix-http/src/h2/dispatcher.rs
  constant CHUNK_SIZE (line 34) | const CHUNK_SIZE: usize = 16_384;
  function new (line 53) | pub(crate) fn new(
  type H2PingPong (line 85) | struct H2PingPong {
  type Output (line 107) | type Output = Result<(), crate::error::DispatchError>;
  method poll (line 110) | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
  type DispatchError (line 201) | enum DispatchError {
  function handle_response (line 207) | async fn handle_response<B>(
  function prepare_response (line 276) | fn prepare_response(

FILE: actix-http/src/h2/mod.rs
  type Payload (line 29) | pub struct Payload {
    method new (line 34) | pub(crate) fn new(stream: RecvStream) -> Self {
  type Item (line 40) | type Item = Result<Bytes, PayloadError>;
  method poll_next (line 42) | fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<...
  function handshake_with_timeout (line 60) | pub(crate) fn handshake_with_timeout<T>(io: T, config: &ServiceConfig) -...
  type HandshakeWithTimeout (line 77) | pub(crate) struct HandshakeWithTimeout<T: AsyncRead + AsyncWrite + Unpin> {
  type Output (line 86) | type Output = Result<(Connection<T, Bytes>, Option<Pin<Box<Sleep>>>), Di...
  method poll (line 88) | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {

FILE: actix-http/src/h2/service.rs
  function desired_nodelay (line 29) | fn desired_nodelay(tcp_nodelay: Option<bool>) -> Option<bool> {
  function set_nodelay (line 34) | fn set_nodelay(stream: &TcpStream, nodelay: bool) {
  type H2Service (line 39) | pub struct H2Service<T, S, B> {
  function with_config (line 56) | pub(crate) fn with_config<F: IntoServiceFactory<S, Request>>(
  function on_connect_ext (line 69) | pub(crate) fn on_connect_ext(mut self, f: Option<Rc<ConnectCallback<T>>>...
  function tcp (line 86) | pub fn tcp(
  function openssl (line 134) | pub fn openssl(
  function rustls (line 186) | pub fn rustls(
  function rustls_021 (line 241) | pub fn rustls_021(
  function rustls_0_22 (line 296) | pub fn rustls_0_22(
  function rustls_0_23 (line 351) | pub fn rustls_0_23(
  type Response (line 395) | type Response = ();
  type Error (line 396) | type Error = DispatchError;
  type Config (line 397) | type Config = ();
  type Service (line 398) | type Service = H2ServiceHandler<T, S::Service, B>;
  type InitError (line 399) | type InitError = S::InitError;
  type Future (line 400) | type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitEr...
    type Output (line 519) | type Output = Result<(), DispatchError>;
    method poll (line 521) | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::...
  function new_service (line 402) | fn new_service(&self, _: ()) -> Self::Future {
  type H2ServiceHandler (line 415) | pub struct H2ServiceHandler<T, S, B>
  function new (line 433) | fn new(
  type Response (line 456) | type Response = ();
  type Error (line 457) | type Error = DispatchError;
  type Future (line 458) | type Future = H2ServiceHandlerResponse<T, S, B>;
    type Output (line 519) | type Output = Result<(), DispatchError>;
    method poll (line 521) | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::...
  function poll_ready (line 460) | fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Erro...
  function call (line 468) | fn call(&self, (io, addr): (T, Option<net::SocketAddr>)) -> Self::Future {
  type State (line 483) | enum State<T, S: Service<Request>, B: MessageBody>
  type H2ServiceHandlerResponse (line 498) | pub struct H2ServiceHandlerResponse<T, S, B>

FILE: actix-http/src/header/as_name.rs
  type AsHeaderName (line 10) | pub trait AsHeaderName: Sealed {}
  type Seal (line 12) | pub struct Seal;
  type Sealed (line 14) | pub trait Sealed {
    method try_as_name (line 15) | fn try_as_name(&self, seal: Seal) -> Result<Cow<'_, HeaderName>, Inval...
    method try_as_name (line 20) | fn try_as_name(&self, _: Seal) -> Result<Cow<'_, HeaderName>, InvalidH...
    method try_as_name (line 28) | fn try_as_name(&self, _: Seal) -> Result<Cow<'_, HeaderName>, InvalidH...
    method try_as_name (line 36) | fn try_as_name(&self, _: Seal) -> Result<Cow<'_, HeaderName>, InvalidH...
    method try_as_name (line 44) | fn try_as_name(&self, _: Seal) -> Result<Cow<'_, HeaderName>, InvalidH...
    method try_as_name (line 52) | fn try_as_name(&self, _: Seal) -> Result<Cow<'_, HeaderName>, InvalidH...

FILE: actix-http/src/header/common.rs
  constant CACHE_STATUS (line 12) | pub const CACHE_STATUS: HeaderName = HeaderName::from_static("cache-stat...
  constant CDN_CACHE_CONTROL (line 19) | pub const CDN_CACHE_CONTROL: HeaderName = HeaderName::from_static("cdn-c...
  constant CLEAR_SITE_DATA (line 27) | pub const CLEAR_SITE_DATA: HeaderName = HeaderName::from_static("clear-s...
  constant CROSS_ORIGIN_EMBEDDER_POLICY (line 34) | pub const CROSS_ORIGIN_EMBEDDER_POLICY: HeaderName =
  constant CROSS_ORIGIN_OPENER_POLICY (line 39) | pub const CROSS_ORIGIN_OPENER_POLICY: HeaderName =
  constant CROSS_ORIGIN_RESOURCE_POLICY (line 44) | pub const CROSS_ORIGIN_RESOURCE_POLICY: HeaderName =
  constant PERMISSIONS_POLICY (line 49) | pub const PERMISSIONS_POLICY: HeaderName = HeaderName::from_static("perm...
  constant X_FORWARDED_FOR (line 53) | pub const X_FORWARDED_FOR: HeaderName = HeaderName::from_static("x-forwa...
  constant X_FORWARDED_HOST (line 57) | pub const X_FORWARDED_HOST: HeaderName = HeaderName::from_static("x-forw...
  constant X_FORWARDED_PROTO (line 61) | pub const X_FORWARDED_PROTO: HeaderName = HeaderName::from_static("x-for...

FILE: actix-http/src/header/into_pair.rs
  type TryIntoHeaderPair (line 12) | pub trait TryIntoHeaderPair: Sized {
    method try_into_pair (line 15) | fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error>;
    type Error (line 38) | type Error = InvalidHeaderPart;
    method try_into_pair (line 40) | fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Erro...
    type Error (line 54) | type Error = InvalidHeaderPart;
    method try_into_pair (line 56) | fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Erro...
    type Error (line 70) | type Error = InvalidHeaderPart;
    method try_into_pair (line 72) | fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Erro...
    type Error (line 87) | type Error = InvalidHeaderPart;
    method try_into_pair (line 89) | fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Erro...
    type Error (line 104) | type Error = InvalidHeaderPart;
    method try_into_pair (line 107) | fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Erro...
    type Error (line 114) | type Error = <T as TryIntoHeaderValue>::Error;
    method try_into_pair (line 117) | fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Erro...
  type InvalidHeaderPart (line 19) | pub enum InvalidHeaderPart {
  method from (line 25) | fn from(part_err: InvalidHeaderPart) -> Self {

FILE: actix-http/src/header/into_value.rs
  type TryIntoHeaderValue (line 8) | pub trait TryIntoHeaderValue: Sized {
    method try_into_value (line 13) | fn try_into_value(self) -> Result<HeaderValue, Self::Error>;
    type Error (line 17) | type Error = InvalidHeaderValue;
    method try_into_value (line 20) | fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
    type Error (line 26) | type Error = InvalidHeaderValue;
    method try_into_value (line 29) | fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
    type Error (line 35) | type Error = InvalidHeaderValue;
    method try_into_value (line 38) | fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
    type Error (line 44) | type Error = InvalidHeaderValue;
    method try_into_value (line 47) | fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
    type Error (line 53) | type Error = InvalidHeaderValue;
    method try_into_value (line 56) | fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
    type Error (line 62) | type Error = InvalidHeaderValue;
    method try_into_value (line 65) | fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
    type Error (line 71) | type Error = InvalidHeaderValue;
    method try_into_value (line 74) | fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
    type Error (line 80) | type Error = InvalidHeaderValue;
    method try_into_value (line 83) | fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
    type Error (line 89) | type Error = InvalidHeaderValue;
    method try_into_value (line 92) | fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
    type Error (line 98) | type Error = InvalidHeaderValue;
    method try_into_value (line 101) | fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
    type Error (line 107) | type Error = InvalidHeaderValue;
    method try_into_value (line 110) | fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
    type Error (line 116) | type Error = InvalidHeaderValue;
    method try_into_value (line 119) | fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
    type Error (line 125) | type Error = InvalidHeaderValue;
    method try_into_value (line 128) | fn try_into_value(self) -> Result<HeaderValue, Self::Error> {

FILE: actix-http/src/header/map.rs
  type HeaderMap (line 49) | pub struct HeaderMap {
    method new (line 100) | pub fn new() -> Self {
    method with_capacity (line 117) | pub fn with_capacity(capacity: usize) -> Self {
    method from_drain (line 124) | pub(crate) fn from_drain<I>(mut drain: I) -> Self
    method len (line 168) | pub fn len(&self) -> usize {
    method len_keys (line 189) | pub fn len_keys(&self) -> usize {
    method is_empty (line 204) | pub fn is_empty(&self) -> bool {
    method clear (line 224) | pub fn clear(&mut self) {
    method get_value (line 228) | fn get_value(&self, key: impl AsHeaderName) -> Option<&Value> {
    method get (line 264) | pub fn get(&self, key: impl AsHeaderName) -> Option<&HeaderValue> {
    method get_mut (line 294) | pub fn get_mut(&mut self, key: impl AsHeaderName) -> Option<&mut Heade...
    method get_all (line 323) | pub fn get_all(&self, key: impl AsHeaderName) -> std::slice::Iter<'_, ...
    method contains_key (line 345) | pub fn contains_key(&self, key: impl AsHeaderName) -> bool {
    method insert (line 387) | pub fn insert(&mut self, name: HeaderName, val: HeaderValue) -> Removed {
    method append (line 412) | pub fn append(&mut self, key: HeaderName, value: HeaderValue) {
    method remove (line 459) | pub fn remove(&mut self, key: impl AsHeaderName) -> Removed {
    method capacity (line 484) | pub fn capacity(&self) -> usize {
    method reserve (line 507) | pub fn reserve(&mut self, additional: usize) {
    method iter (line 539) | pub fn iter(&self) -> Iter<'_> {
    method keys (line 565) | pub fn keys(&self) -> Keys<'_> {
    method retain (line 590) | pub fn retain<F>(&mut self, mut retain_fn: F)
    method drain (line 628) | pub fn drain(&mut self) -> Drain<'_> {
    method from_iter (line 658) | fn from_iter<T: IntoIterator<Item = (HeaderName, HeaderValue)>>(iter: ...
    method from (line 669) | fn from(mut map: http::HeaderMap) -> Self {
  type Value (line 55) | pub(crate) struct Value {
    method one (line 60) | fn one(val: HeaderValue) -> Self {
    method first (line 66) | fn first(&self) -> &HeaderValue {
    method first_mut (line 70) | fn first_mut(&mut self) -> &mut HeaderValue {
    method append (line 74) | fn append(&mut self, new_val: HeaderValue) {
    type Target (line 80) | type Target = SmallVec<[HeaderValue; 4]>;
    method deref (line 82) | fn deref(&self) -> &Self::Target {
  type Item (line 637) | type Item = (HeaderName, HeaderValue);
  type IntoIter (line 638) | type IntoIter = IntoIter;
  method into_iter (line 641) | fn into_iter(self) -> Self::IntoIter {
  type Item (line 648) | type Item = (&'a HeaderName, &'a HeaderValue);
  type IntoIter (line 649) | type IntoIter = Iter<'a>;
  method into_iter (line 652) | fn into_iter(self) -> Self::IntoIter {
  function from (line 676) | fn from(map: HeaderMap) -> Self {
  function from (line 683) | fn from(map: &HeaderMap) -> Self {
  type Removed (line 693) | pub struct Removed {
    method new (line 698) | fn new(value: Option<Value>) -> Self {
    method is_empty (line 707) | pub fn is_empty(&self) -> bool {
  type Item (line 717) | type Item = HeaderValue;
  method next (line 720) | fn next(&mut self) -> Option<Self::Item> {
  method size_hint (line 725) | fn size_hint(&self) -> (usize, Option<usize>) {
  type Keys (line 739) | pub struct Keys<'a>(hash_map::Keys<'a, HeaderName, Value>);
  type Item (line 742) | type Item = &'a HeaderName;
  method next (line 745) | fn next(&mut self) -> Option<Self::Item> {
  method size_hint (line 750) | fn size_hint(&self) -> (usize, Option<usize>) {
  type Iter (line 761) | pub struct Iter<'a> {
  function new (line 769) | fn new(iter: hash_map::Iter<'a, HeaderName, Value>, remaining: usize) ->...
  type Item (line 780) | type Item = (&'a HeaderName, &'a HeaderValue);
  method next (line 782) | fn next(&mut self) -> Option<Self::Item> {
  method size_hint (line 807) | fn size_hint(&self) -> (usize, Option<usize>) {
  type Drain (line 820) | pub struct Drain<'a> {
  function new (line 828) | fn new(iter: hash_map::Drain<'a, HeaderName, Value>, remaining: usize) -...
  type Item (line 839) | type Item = (Option<HeaderName>, HeaderValue);
  method next (line 841) | fn next(&mut self) -> Option<Self::Item> {
  method size_hint (line 863) | fn size_hint(&self) -> (usize, Option<usize>) {
  type IntoIter (line 876) | pub struct IntoIter {
    method new (line 883) | fn new(inner: hash_map::IntoIter<HeaderName, Value>, remaining: usize)...
  type Item (line 893) | type Item = (HeaderName, HeaderValue);
  method next (line 895) | fn next(&mut self) -> Option<Self::Item> {
  method size_hint (line 918) | fn size_hint(&self) -> (usize, Option<usize>) {
  function create (line 945) | fn create() {
  function insert (line 956) | fn insert() {
  function contains (line 964) | fn contains() {
  function entries_iter (line 976) | fn entries_iter() {
  function drain_iter (line 996) | fn drain_iter() {
  function retain (line 1023) | fn retain() {
  function retain_removes_empty_value_lists (line 1051) | fn retain_removes_empty_value_lists() {
  function entries_into_iter (line 1072) | fn entries_into_iter() {
  function iter_and_into_iter_same_order (line 1087) | fn iter_and_into_iter_same_order() {
  function get_all_and_remove_same_order (line 1104) | fn get_all_and_remove_same_order() {
  function get_all_iteration_order_matches_insertion_order (line 1119) | fn get_all_iteration_order_matches_insertion_order() {
  function iter_len_counts_values (line 1169) | fn iter_len_counts_values() {
  function into_iter_len_counts_values (line 1180) | fn into_iter_len_counts_values() {
  function drain_len_counts_values (line 1191) | fn drain_len_counts_values() {
  function owned_pair (line 1202) | fn owned_pair<'a>((name, val): (&'a HeaderName, &'a HeaderValue)) -> (He...

FILE: actix-http/src/header/mod.rs
  type Header (line 60) | pub trait Header: TryIntoHeaderValue {
    method name (line 62) | fn name() -> HeaderName;
    method parse (line 65) | fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError>;
  constant HTTP_VALUE (line 70) | pub(crate) const HTTP_VALUE: &AsciiSet = &CONTROLS

FILE: actix-http/src/header/shared/charset.rs
  type Charset (line 12) | pub enum Charset {
    method label (line 66) | fn label(&self) -> &str {
    method fmt (line 98) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    type Err (line 104) | type Err = crate::Error;
    method from_str (line 106) | fn from_str(s: &str) -> Result<Charset, crate::Error> {
  function test_parse (line 142) | fn test_parse() {
  function test_display (line 151) | fn test_display() {

FILE: actix-http/src/header/shared/content_encoding.rs
  type ContentEncodingParseError (line 15) | pub struct ContentEncodingParseError;
  type ContentEncoding (line 25) | pub enum ContentEncoding {
    method as_str (line 47) | pub const fn as_str(self) -> &'static str {
    method to_header_value (line 59) | pub const fn to_header_value(self) -> HeaderValue {
    type Error (line 100) | type Error = ContentEncodingParseError;
    method try_from (line 102) | fn try_from(val: &str) -> Result<Self, Self::Error> {
  method default (line 72) | fn default() -> Self {
  type Err (line 78) | type Err = ContentEncodingParseError;
  method from_str (line 80) | fn from_str(enc: &str) -> Result<Self, Self::Err> {
  type Error (line 108) | type Error = InvalidHeaderValue;
  method try_into_value (line 110) | fn try_into_value(self) -> Result<http::HeaderValue, Self::Error> {
  method name (line 116) | fn name() -> HeaderName {
  method parse (line 120) | fn parse<T: HttpMessage>(msg: &T) -> Result<Self, ParseError> {

FILE: actix-http/src/header/shared/extended.rs
  type ExtendedValue (line 16) | pub struct ExtendedValue {
    method fmt (line 100) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  function parse_extended_value (line 66) | pub fn parse_extended_value(val: &str) -> Result<ExtendedValue, crate::e...
  function test_parse_extended_value_with_encoding_and_language_tag (line 115) | fn test_parse_extended_value_with_encoding_and_language_tag() {
  function test_parse_extended_value_with_encoding (line 132) | fn test_parse_extended_value_with_encoding() {
  function test_parse_extended_value_missing_language_tag_and_encoding (line 151) | fn test_parse_extended_value_missing_language_tag_and_encoding() {
  function test_parse_extended_value_partially_formatted (line 158) | fn test_parse_extended_value_partially_formatted() {
  function test_parse_extended_value_partially_formatted_blank (line 164) | fn test_parse_extended_value_partially_formatted_blank() {
  function test_fmt_extended_value_with_encoding_and_language_tag (line 170) | fn test_fmt_extended_value_with_encoding_and_language_tag() {
  function test_fmt_extended_value_with_encoding (line 180) | fn test_fmt_extended_value_with_encoding() {

FILE: actix-http/src/header/shared/http_date.rs
  type HttpDate (line 12) | pub struct HttpDate(SystemTime);
    method fmt (line 26) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    method from (line 46) | fn from(sys_time: SystemTime) -> HttpDate {
  type Err (line 15) | type Err = ParseError;
  method from_str (line 17) | fn from_str(s: &str) -> Result<HttpDate, ParseError> {
  type Error (line 32) | type Error = InvalidHeaderValue;
  method try_into_value (line 34) | fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
  method from (line 52) | fn from(HttpDate(sys_time): HttpDate) -> SystemTime {
  function date_header (line 64) | fn date_header() {

FILE: actix-http/src/header/shared/quality.rs
  constant MAX_QUALITY_INT (line 5) | const MAX_QUALITY_INT: u16 = 1000;
  constant MAX_QUALITY_FLOAT (line 6) | const MAX_QUALITY_FLOAT: f32 = 1.0;
  type Quality (line 33) | pub struct Quality(pub(super) u16);
    constant MAX (line 37) | pub const MAX: Quality = Quality(MAX_QUALITY_INT);
    constant MIN (line 40) | pub const MIN: Quality = Quality(1);
    constant ZERO (line 43) | pub const ZERO: Quality = Quality(0);
    method from_f32 (line 51) | fn from_f32(value: f32) -> Self {
    method fmt (line 71) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    type Error (line 133) | type Error = QualityOutOfBounds;
    method try_from (line 136) | fn try_from(value: f32) -> Result<Self, Self::Error> {
  method default (line 65) | fn default() -> Quality {
  function itoa_fmt (line 122) | pub fn itoa_fmt<W: fmt::Write, V: itoa::Integer>(mut wr: W, value: V) ->...
  type QualityOutOfBounds (line 130) | pub struct QualityOutOfBounds;
  function q (line 173) | pub fn q<T>(quality: T) -> Quality
  function q_helper (line 186) | fn q_helper() {
  function display_output (line 191) | fn display_output() {
  function negative_quality (line 213) | fn negative_quality() {
  function quality_out_of_bounds (line 219) | fn quality_out_of_bounds() {

FILE: actix-http/src/header/shared/quality_item.rs
  type QualityItem (line 34) | pub struct QualityItem<T> {
  function new (line 46) | pub fn new(item: T, quality: Quality) -> Self {
  function max (line 51) | pub fn max(item: T) -> Self {
  function min (line 56) | pub fn min(item: T) -> Self {
  function zero (line 61) | pub fn zero(item: T) -> Self {
  method partial_cmp (line 67) | fn partial_cmp(&self, other: &QualityItem<T>) -> Option<cmp::Ordering> {
  function fmt (line 73) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  type Err (line 90) | type Err = ParseError;
  function from_str (line 92) | fn from_str(q_item_str: &str) -> Result<Self, Self::Err> {
  type Encoding (line 150) | pub enum Encoding {
    method fmt (line 162) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    type Err (line 178) | type Err = crate::error::ParseError;
    method from_str (line 179) | fn from_str(s: &str) -> Result<Encoding, crate::error::ParseError> {
  function test_quality_item_fmt_q_1 (line 195) | fn test_quality_item_fmt_q_1() {
  function test_quality_item_fmt_q_0001 (line 201) | fn test_quality_item_fmt_q_0001() {
  function test_quality_item_fmt_q_05 (line 207) | fn test_quality_item_fmt_q_05() {
  function test_quality_item_fmt_q_0 (line 218) | fn test_quality_item_fmt_q_0() {
  function test_quality_item_from_str1 (line 229) | fn test_quality_item_from_str1() {
  function test_quality_item_from_str2 (line 242) | fn test_quality_item_from_str2() {
  function test_quality_item_from_str3 (line 255) | fn test_quality_item_from_str3() {
  function test_quality_item_from_str4 (line 268) | fn test_quality_item_from_str4() {
  function test_quality_item_from_str5 (line 281) | fn test_quality_item_from_str5() {
  function test_quality_item_from_str6 (line 287) | fn test_quality_item_from_str6() {
  function test_quality_item_ordering (line 293) | fn test_quality_item_ordering() {
  function test_fuzzing_bugs (line 301) | fn test_fuzzing_bugs() {

FILE: actix-http/src/header/utils.rs
  function from_comma_delimited (line 10) | pub fn from_comma_delimited<'a, I, T>(all: I) -> Result<Vec<T>, ParseError>
  function from_one_raw_str (line 36) | pub fn from_one_raw_str<T: FromStr>(val: Option<&HeaderValue>) -> Result...
  function fmt_comma_delimited (line 50) | pub fn fmt_comma_delimited<T>(f: &mut fmt::Formatter<'_>, parts: &[T]) -...
  function http_percent_encode (line 72) | pub fn http_percent_encode(f: &mut fmt::Formatter<'_>, bytes: &[u8]) -> ...
  function comma_delimited_parsing (line 82) | fn comma_delimited_parsing() {

FILE: actix-http/src/helpers.rs
  constant DIGITS_START (line 6) | const DIGITS_START: u8 = b'0';
  function write_status_line (line 8) | pub(crate) fn write_status_line<B: BufMut>(version: Version, n: u16, buf...
  function write_content_length (line 33) | pub fn write_content_length<B: BufMut>(n: u64, buf: &mut B, camel_case: ...
  type MutWriter (line 62) | pub(crate) struct MutWriter<'a, B>(pub(crate) &'a mut B);
  function write (line 68) | fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
  function flush (line 73) | fn flush(&mut self) -> io::Result<()> {
  function test_status_line (line 87) | fn test_status_line() {
  function test_write_content_length (line 105) | fn test_write_content_length() {
  function write_content_length_camel_case (line 183) | fn write_content_length_camel_case() {

FILE: actix-http/src/http_message.rs
  type HttpMessage (line 18) | pub trait HttpMessage: Sized {
    method headers (line 23) | fn headers(&self) -> &HeaderMap;
    method take_payload (line 26) | fn take_payload(&mut self) -> Payload<Self::Stream>;
    method extensions (line 29) | fn extensions(&self) -> Ref<'_, Extensions>;
    method extensions_mut (line 32) | fn extensions_mut(&self) -> RefMut<'_, Extensions>;
    method get_header (line 36) | fn get_header<H: Header>(&self) -> Option<H>
    method content_type (line 49) | fn content_type(&self) -> &str {
    method encoding (line 61) | fn encoding(&self) -> Result<&'static Encoding, ContentTypeError> {
    method mime_type (line 78) | fn mime_type(&self) -> Result<Option<Mime>, ContentTypeError> {
    method chunked (line 93) | fn chunked(&self) -> Result<bool, ParseError> {
    type Stream (line 110) | type Stream = T::Stream;
    method headers (line 112) | fn headers(&self) -> &HeaderMap {
    method take_payload (line 117) | fn take_payload(&mut self) -> Payload<Self::Stream> {
    method extensions (line 122) | fn extensions(&self) -> Ref<'_, Extensions> {
    method extensions_mut (line 127) | fn extensions_mut(&self) -> RefMut<'_, Extensions> {
  function test_content_type (line 141) | fn test_content_type() {
  function test_mime_type (line 155) | fn test_mime_type() {
  function test_mime_type_error (line 172) | fn test_mime_type_error() {
  function test_encoding (line 180) | fn test_encoding() {
  function test_encoding_error (line 196) | fn test_encoding_error() {
  function test_chunked (line 212) | fn test_chunked() {

FILE: actix-http/src/keep_alive.rs
  type KeepAlive (line 5) | pub enum KeepAlive {
    method enabled (line 23) | pub(crate) fn enabled(&self) -> bool {
    method duration (line 28) | pub(crate) fn duration(&self) -> Option<Duration> {
    method normalize (line 36) | pub(crate) fn normalize(self) -> KeepAlive {
    method from (line 51) | fn from(dur: Duration) -> Self {
    method from (line 57) | fn from(ka_dur: Option<Duration>) -> Self {
  method default (line 45) | fn default() -> Self {
  function from_impls (line 71) | fn from_impls() {

FILE: actix-http/src/lib.rs
  type Protocol (line 82) | pub enum Protocol {
  type ConnectCallback (line 88) | type ConnectCallback<IO> = dyn Fn(&IO, &mut Extensions);
  type OnConnectData (line 95) | pub(crate) struct OnConnectData(Option<Extensions>);
    method from_io (line 99) | pub(crate) fn from_io<T>(io: &T, on_connect_ext: Option<&ConnectCallba...

FILE: actix-http/src/message.rs
  type ConnectionType (line 7) | pub enum ConnectionType {
  type Head (line 31) | pub trait Head: Default + 'static {
    method clear (line 32) | fn clear(&mut self);
    method with_pool (line 34) | fn with_pool<F, R>(f: F) -> R
  type Message (line 39) | pub struct Message<T: Head> {
  function new (line 48) | pub fn new() -> Self {
  type Target (line 54) | type Target = T;
  function deref (line 56) | fn deref(&self) -> &Self::Target {
  function deref_mut (line 62) | fn deref_mut(&mut self) -> &mut Self::Target {
  method drop (line 68) | fn drop(&mut self) {
  type MessagePool (line 75) | pub struct MessagePool<T: Head>(RefCell<Vec<Rc<T>>>);
  function create (line 78) | pub(crate) fn create() -> MessagePool<T> {
  function get_message (line 84) | fn get_message(&self) -> Message<T> {
  function release (line 101) | fn release(&self, msg: Rc<T>) {

FILE: actix-http/src/notify_on_drop.rs
  function is_dropped (line 15) | pub(crate) fn is_dropped() -> bool {
  type NotifyOnDrop (line 22) | pub(crate) struct NotifyOnDrop;
    method new (line 27) | pub(crate) fn new() -> Self {
  method drop (line 42) | fn drop(&mut self) {

FILE: actix-http/src/payload.rs
  type BoxedPayloadStream (line 14) | pub type BoxedPayloadStream = Pin<Box<dyn Stream<Item = Result<Bytes, Pa...
  type PayloadStream (line 18) | pub type PayloadStream = BoxedPayloadStream;
  function from (line 45) | fn from(payload: crate::h1::Payload) -> Self {
  function from (line 52) | fn from(bytes: Bytes) -> Self {
  function from (line 61) | fn from(vec: Vec<u8>) -> Self {
  function from (line 69) | fn from(payload: crate::h2::Payload) -> Self {
  function from (line 77) | fn from(stream: ::h2::RecvStream) -> Self {
  method from (line 86) | fn from(payload: BoxedPayloadStream) -> Self {
  function take (line 94) | pub fn take(&mut self) -> Payload<S> {
  type Item (line 103) | type Item = Result<Bytes, PayloadError>;
  method poll_next (line 106) | fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<...

FILE: actix-http/src/requests/head.rs
  type RequestHead (line 14) | pub struct RequestHead {
    method headers (line 55) | pub fn headers(&self) -> &HeaderMap {
    method headers_mut (line 60) | pub fn headers_mut(&mut self) -> &mut HeaderMap {
    method camel_case_headers (line 68) | pub fn camel_case_headers(&self) -> bool {
    method set_camel_case_headers (line 74) | pub fn set_camel_case_headers(&mut self, val: bool) {
    method set_connection_type (line 84) | pub fn set_connection_type(&mut self, ctype: ConnectionType) {
    method connection_type (line 94) | pub fn connection_type(&self) -> ConnectionType {
    method upgrade (line 109) | pub fn upgrade(&self) -> bool {
    method chunked (line 124) | pub fn chunked(&self) -> bool {
    method no_chunking (line 129) | pub fn no_chunking(&mut self, val: bool) {
    method expect (line 139) | pub fn expect(&self) -> bool {
    method set_expect (line 144) | pub(crate) fn set_expect(&mut self) {
  method default (line 27) | fn default() -> RequestHead {
  method clear (line 40) | fn clear(&mut self) {
  method with_pool (line 45) | fn with_pool<F, R>(f: F) -> R
  type RequestHeadType (line 151) | pub enum RequestHeadType {
    method extra_headers (line 157) | pub fn extra_headers(&self) -> Option<&HeaderMap> {
    method as_ref (line 166) | fn as_ref(&self) -> &RequestHead {
    method from (line 175) | fn from(head: RequestHead) -> Self {

FILE: actix-http/src/requests/request.rs
  type Request (line 17) | pub struct Request<P = BoxedPayloadStream> {
  type Stream (line 25) | type Stream = P;
  method headers (line 28) | fn headers(&self) -> &HeaderMap {
  method take_payload (line 32) | fn take_payload(&mut self) -> Payload<P> {
  method extensions (line 37) | fn extensions(&self) -> Ref<'_, Extensions> {
  method extensions_mut (line 42) | fn extensions_mut(&self) -> RefMut<'_, Extensions> {
  function from (line 48) | fn from(head: Message<RequestHead>) -> Self {
  function new (line 61) | pub fn new() -> Request<BoxedPayloadStream> {
  function with_payload (line 73) | pub fn with_payload(payload: Payload<P>) -> Request<P> {
  function replace_payload (line 83) | pub fn replace_payload<P1>(self, payload: Payload<P1>) -> (Request<P1>, ...
  function payload (line 98) | pub fn payload(&mut self) -> &mut Payload<P> {
  function take_payload (line 103) | pub fn take_payload(&mut self) -> Payload<P> {
  function into_parts (line 108) | pub fn into_parts(self) -> (Message<RequestHead>, Payload<P>) {
  function head (line 114) | pub fn head(&self) -> &RequestHead {
  function head_mut (line 121) | pub fn head_mut(&mut self) -> &mut RequestHead {
  function headers_mut (line 126) | pub fn headers_mut(&mut self) -> &mut HeaderMap {
  function uri (line 132) | pub fn uri(&self) -> &Uri {
  function uri_mut (line 138) | pub fn uri_mut(&mut self) -> &mut Uri {
  function method (line 144) | pub fn method(&self) -> &Method {
  function version (line 150) | pub fn version(&self) -> Version {
  function path (line 156) | pub fn path(&self) -> &str {
  function upgrade (line 162) | pub fn upgrade(&self) -> bool {
  function peer_addr (line 178) | pub fn peer_addr(&self) -> Option<net::SocketAddr> {
  function conn_data (line 189) | pub fn conn_data<T: 'static>(&self) -> Option<&T> {
  function take_conn_data (line 199) | pub fn take_conn_data(&mut self) -> Option<Rc<Extensions>> {
  function take_req_data (line 204) | pub fn take_req_data(&mut self) -> Extensions {
  function fmt (line 210) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  function test_basics (line 238) | fn test_basics() {

FILE: actix-http/src/responses/builder.rs
  type ResponseBuilder (line 38) | pub struct ResponseBuilder {
    method new (line 53) | pub fn new(status: StatusCode) -> Self {
    method status (line 69) | pub fn status(&mut self, status: StatusCode) -> &mut Self {
    method insert_header (line 90) | pub fn insert_header(&mut self, header: impl TryIntoHeaderPair) -> &mu...
    method append_header (line 118) | pub fn append_header(&mut self, header: impl TryIntoHeaderPair) -> &mu...
    method reason (line 131) | pub fn reason(&mut self, reason: &'static str) -> &mut Self {
    method keep_alive (line 140) | pub fn keep_alive(&mut self) -> &mut Self {
    method upgrade (line 149) | pub fn upgrade<V>(&mut self, value: V) -> &mut Self
    method force_close (line 166) | pub fn force_close(&mut self) -> &mut Self {
    method no_chunking (line 175) | pub fn no_chunking(&mut self, len: u64) -> &mut Self {
    method content_type (line 187) | pub fn content_type<V>(&mut self, value: V) -> &mut Self
    method body (line 205) | pub fn body<B>(&mut self, body: B) -> Response<EitherBody<B>>
    method message_body (line 218) | pub fn message_body<B>(&mut self, body: B) -> Result<Response<B>, Erro...
    method finish (line 236) | pub fn finish(&mut self) -> Response<EitherBody<()>> {
    method take (line 241) | pub fn take(&mut self) -> ResponseBuilder {
    method inner (line 249) | fn inner(&mut self) -> Option<&mut ResponseHead> {
    method from (line 266) | fn from(res: Response<B>) -> ResponseBuilder {
    method from (line 276) | fn from(head: &'a ResponseHead) -> ResponseBuilder {
    method fmt (line 295) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  method default (line 259) | fn default() -> Self {
  function test_basic_builder (line 321) | fn test_basic_builder() {
  function test_upgrade (line 329) | fn test_upgrade() {
  function test_force_close (line 341) | fn test_force_close() {
  function test_content_type (line 347) | fn test_content_type() {
  function test_into_builder (line 360) | fn test_into_builder() {
  function response_builder_header_insert_kv (line 378) | fn response_builder_header_insert_kv() {
  function response_builder_header_insert_typed (line 390) | fn response_builder_header_insert_typed() {
  function response_builder_header_append_kv (line 402) | fn response_builder_header_append_kv() {
  function response_builder_header_append_typed (line 415) | fn response_builder_header_append_typed() {

FILE: actix-http/src/responses/head.rs
  type ResponseHead (line 12) | pub struct ResponseHead {
    method new (line 23) | pub fn new(status: StatusCode) -> ResponseHead {
    method headers (line 35) | pub fn headers(&self) -> &HeaderMap {
    method headers_mut (line 41) | pub fn headers_mut(&mut self) -> &mut HeaderMap {
    method set_camel_case_headers (line 49) | pub fn set_camel_case_headers(&mut self, camel_case: bool) {
    method set_connection_type (line 59) | pub fn set_connection_type(&mut self, ctype: ConnectionType) {
    method connection_type (line 68) | pub fn connection_type(&self) -> ConnectionType {
    method keep_alive (line 84) | pub fn keep_alive(&self) -> bool {
    method upgrade (line 90) | pub fn upgrade(&self) -> bool {
    method reason (line 96) | pub fn reason(&self) -> &str {
    method conn_type (line 105) | pub(crate) fn conn_type(&self) -> Option<ConnectionType> {
    method chunked (line 119) | pub fn chunked(&self) -> bool {
    method no_chunking (line 125) | pub fn no_chunking(&mut self, val: bool) {
  type BoxedResponseHead (line 134) | pub(crate) struct BoxedResponseHead {
    method new (line 140) | pub fn new(status: StatusCode) -> Self {
    type Target (line 146) | type Target = ResponseHead;
    method deref (line 148) | fn deref(&self) -> &Self::Target {
    method deref_mut (line 154) | fn deref_mut(&mut self) -> &mut Self::Target {
  method drop (line 160) | fn drop(&mut self) {
  type BoxedResponsePool (line 169) | pub struct BoxedResponsePool(#[allow(clippy::vec_box)] RefCell<Vec<Box<R...
    method create (line 172) | fn create() -> BoxedResponsePool {
    method get_message (line 178) | fn get_message(&self, status: StatusCode) -> BoxedResponseHead {
    method release (line 194) | fn release(&self, msg: Box<ResponseHead>) {
  function camel_case_headers (line 219) | async fn camel_case_headers() {

FILE: actix-http/src/responses/response.rs
  type Response (line 19) | pub struct Response<B> {
  function new (line 28) | pub fn new(status: StatusCode) -> Self {
  function build (line 38) | pub fn build(status: StatusCode) -> ResponseBuilder {
  function ok (line 47) | pub fn ok() -> Self {
  function bad_request (line 53) | pub fn bad_request() -> Self {
  function not_found (line 59) | pub fn not_found() -> Self {
  function internal_server_error (line 65) | pub fn internal_server_error() -> Self {
  function with_body (line 75) | pub fn with_body(status: StatusCode, body: B) -> Response<B> {
  function head (line 85) | pub fn head(&self) -> &ResponseHead {
  function head_mut (line 91) | pub fn head_mut(&mut self) -> &mut ResponseHead {
  function status (line 97) | pub fn status(&self) -> StatusCode {
  function status_mut (line 103) | pub fn status_mut(&mut self) -> &mut StatusCode {
  function headers (line 109) | pub fn headers(&self) -> &HeaderMap {
  function headers_mut (line 115) | pub fn headers_mut(&mut self) -> &mut HeaderMap {
  function upgrade (line 121) | pub fn upgrade(&self) -> bool {
  function keep_alive (line 127) | pub fn keep_alive(&self) -> bool {
  function extensions (line 133) | pub fn extensions(&self) -> Ref<'_, Extensions> {
  function extensions_mut (line 139) | pub fn extensions_mut(&mut self) -> RefMut<'_, Extensions> {
  function body (line 145) | pub fn body(&self) -> &B {
  function set_body (line 151) | pub fn set_body<B2>(self, body: B2) -> Response<B2> {
  function drop_body (line 161) | pub fn drop_body(self) -> Response<()> {
  function replace_body (line 167) | pub(crate) fn replace_body<B2>(self, body: B2) -> (Response<B2>, B) {
  function into_parts (line 184) | pub fn into_parts(self) -> (Response<()>, B) {
  function map_body (line 192) | pub fn map_body<F, B2>(mut self, f: F) -> Response<B2>
  function map_into_boxed_body (line 207) | pub fn map_into_boxed_body(self) -> Response<BoxBody>
  function into_body (line 216) | pub fn into_body(self) -> B {
  function fmt (line 225) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  method default (line 244) | fn default() -> Response<B> {
  function from (line 250) | fn from(res: Result<I, E>) -> Self {
  function from (line 259) | fn from(mut builder: ResponseBuilder) -> Self {
  function from (line 265) | fn from(val: std::convert::Infallible) -> Self {
  function from (line 271) | fn from(val: &'static str) -> Self {
  function from (line 280) | fn from(val: &'static [u8]) -> Self {
  function from (line 289) | fn from(val: Vec<u8>) -> Self {
  function from (line 298) | fn from(val: &Vec<u8>) -> Self {
  function from (line 307) | fn from(val: String) -> Self {
  function from (line 316) | fn from(val: &String) -> Self {
  function from (line 325) | fn from(val: Bytes) -> Self {
  function from (line 334) | fn from(val: BytesMut) -> Self {
  function from (line 343) | fn from(val: ByteString) -> Self {
  function test_debug (line 360) | fn test_debug() {
  function test_into_response (line 370) | async fn test_into_response() {

FILE: actix-http/src/service.rs
  function desired_nodelay (line 28) | fn desired_nodelay(tcp_nodelay: Option<bool>) -> Option<bool> {
  function set_nodelay (line 33) | fn set_nodelay(stream: &TcpStream, nodelay: bool) {
  type HttpService (line 70) | pub struct HttpService<T, S, B, X = h1::ExpectHandler, U = h1::UpgradeHa...
  function build (line 89) | pub fn build() -> HttpServiceBuilder<T, S> {
  function new (line 104) | pub fn new<F: IntoServiceFactory<S, Request>>(service: F) -> Self {
  function with_config (line 116) | pub(crate) fn with_config<F: IntoServiceFactory<S, Request>>(
  function expect (line 144) | pub fn expect<X1>(self, expect: X1) -> HttpService<T, S, B, X1, U>
  function upgrade (line 164) | pub fn upgrade<U1>(self, upgrade: Option<U1>) -> HttpService<T, S, B, X,...
  function on_connect_ext (line 181) | pub(crate) fn on_connect_ext(mut self, f: Option<Rc<ConnectCallback<T>>>...
  function tcp (line 211) | pub fn tcp(
  function tcp_auto_h2c (line 231) | pub fn tcp_auto_h2c(
  type TlsAcceptorConfig (line 268) | pub struct TlsAcceptorConfig {
    method handshake_timeout (line 275) | pub fn handshake_timeout(self, dur: std::time::Duration) -> Self {
  function openssl (line 322) | pub fn openssl(
  function openssl_with_config (line 336) | pub fn openssl_with_config(
  function rustls (line 420) | pub fn rustls(
  function rustls_with_config (line 434) | pub fn rustls_with_config(
  function rustls_021 (line 522) | pub fn rustls_021(
  function rustls_021_with_config (line 536) | pub fn rustls_021_with_config(
  function rustls_0_22 (line 624) | pub fn rustls_0_22(
  function rustls_0_22_with_config (line 638) | pub fn rustls_0_22_with_config(
  function rustls_0_23 (line 726) | pub fn rustls_0_23(
  function rustls_0_23_with_config (line 740) | pub fn rustls_0_23_with_config(
  type Response (line 814) | type Response = ();
  type Error (line 815) | type Error = DispatchError;
  type Config (line 816) | type Config = ();
  type Service (line 817) | type Service = HttpServiceHandler<T, S::Service, B, X::Service, U::Servi...
  type InitError (line 818) | type InitError = ();
  type Future (line 819) | type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitEr...
    type Output (line 1099) | type Output = Result<(), DispatchError>;
    method poll (line 1101) | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::...
  function new_service (line 821) | fn new_service(&self, _: ()) -> Self::Future {
  type HttpServiceHandler (line 859) | pub struct HttpServiceHandler<T, S, B, X, U>
  function new (line 880) | pub(super) fn new(
  function _poll_ready (line 895) | pub(super) fn _poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<()...
  type HttpFlow (line 909) | pub(super) struct HttpFlow<S, X, U> {
  function new (line 916) | pub(super) fn new(service: S, expect: X, upgrade: Option<U>) -> Rc<Self> {
  type Response (line 943) | type Response = ();
  type Error (line 944) | type Error = DispatchError;
  type Future (line 945) | type Future = HttpServiceHandlerResponse<T, S, B, X, U>;
    type Output (line 1099) | type Output = Result<(), DispatchError>;
    method poll (line 1101) | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::...
  function poll_ready (line 947) | fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Erro...
  function call (line 954) | fn call(&self, (io, proto, peer_addr): (T, Protocol, Option<net::SocketA...

FILE: actix-http/src/test.rs
  type TestRequest (line 23) | pub struct TestRequest(Option<Inner>);
    method with_uri (line 47) | pub fn with_uri(path: &str) -> TestRequest {
    method version (line 52) | pub fn version(&mut self, ver: Version) -> &mut Self {
    method method (line 58) | pub fn method(&mut self, meth: Method) -> &mut Self {
    method uri (line 67) | pub fn uri(&mut self, path: &str) -> &mut Self {
    method insert_header (line 73) | pub fn insert_header(&mut self, header: impl TryIntoHeaderPair) -> &mu...
    method append_header (line 87) | pub fn append_header(&mut self, header: impl TryIntoHeaderPair) -> &mu...
    method set_payload (line 103) | pub fn set_payload(&mut self, data: impl Into<Bytes>) -> &mut Self {
    method take (line 112) | pub fn take(&mut self) -> TestRequest {
    method finish (line 117) | pub fn finish(&mut self) -> Request {
  type Inner (line 25) | struct Inner {
  method default (line 34) | fn default() -> TestRequest {
  function parts (line 137) | fn parts(parts: &mut Option<Inner>) -> &mut Inner {
  type TestBuffer (line 143) | pub struct TestBuffer {
    method new (line 151) | pub fn new<T>(data: T) -> Self
    method clone (line 164) | pub(crate) fn clone(&self) -> Self {
    method empty (line 173) | pub fn empty() -> Self {
    method read_buf_slice (line 178) | pub(crate) fn read_buf_slice(&self) -> Ref<'_, [u8]> {
    method read_buf_slice_mut (line 183) | pub(crate) fn read_buf_slice_mut(&self) -> RefMut<'_, [u8]> {
    method write_buf_slice (line 188) | pub(crate) fn write_buf_slice(&self) -> Ref<'_, [u8]> {
    method write_buf_slice_mut (line 193) | pub(crate) fn write_buf_slice_mut(&self) -> RefMut<'_, [u8]> {
    method take_write_buf (line 198) | pub(crate) fn take_write_buf(&self) -> Bytes {
    method extend_read_buf (line 203) | pub fn extend_read_buf<T: AsRef<[u8]>>(&mut self, data: T) {
    method read (line 209) | fn read(&mut self, dst: &mut [u8]) -> Result<usize, io::Error> {
    method write (line 226) | fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
    method flush (line 231) | fn flush(&mut self) -> io::Result<()> {
  method poll_read (line 237) | fn poll_read(
  method poll_write (line 249) | fn poll_write(
  method poll_flush (line 257) | fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Res...
  method poll_shutdown (line 261) | fn poll_shutdown(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::...
  type TestSeqBuffer (line 268) | pub struct TestSeqBuffer(Rc<RefCell<TestSeqInner>>);
    method new (line 272) | pub fn new<T>(data: T) -> Self
    method empty (line 285) | pub fn empty() -> Self {
    method read_buf (line 289) | pub fn read_buf(&self) -> Ref<'_, BytesMut> {
    method write_buf (line 293) | pub fn write_buf(&self) -> Ref<'_, BytesMut> {
    method take_write_buf (line 297) | pub fn take_write_buf(&self) -> Bytes {
    method err (line 301) | pub fn err(&self) -> Ref<'_, Option<io::Error>> {
    method extend_read_buf (line 310) | pub fn extend_read_buf<T: AsRef<[u8]>>(&mut self, data: T) {
    method close_read (line 323) | pub fn close_read(&self) {
    method read (line 336) | fn read(&mut self, dst: &mut [u8]) -> Result<usize, io::Error> {
    method write (line 357) | fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
    method flush (line 362) | fn flush(&mut self) -> io::Result<()> {
  type TestSeqInner (line 328) | pub struct TestSeqInner {
  method poll_read (line 368) | fn poll_read(
  method poll_write (line 387) | fn poll_write(
  method poll_flush (line 395) | fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Res...
  method poll_shutdown (line 399) | fn poll_shutdown(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::...

FILE: actix-http/src/ws/codec.rs
  type Message (line 15) | pub enum Message {
  type Frame (line 40) | pub enum Frame {
  type Item (line 62) | pub enum Item {
  type Codec (line 71) | pub struct Codec {
    method new (line 87) | pub const fn new() -> Codec {
    method max_size (line 98) | pub fn max_size(mut self, size: usize) -> Self {
    method client_mode (line 107) | pub fn client_mode(mut self) -> Self {
    type Error (line 120) | type Error = ProtocolError;
    method encode (line 122) | fn encode(&mut self, item: Message, dst: &mut BytesMut) -> Result<(), ...
  method default (line 114) | fn default() -> Self {
  type Item (line 219) | type Item = Frame;
  type Error (line 220) | type Error = ProtocolError;
  method decode (line 222) | fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, S...

FILE: actix-http/src/ws/dispatcher.rs
  function new (line 33) | pub fn new<F: IntoService<S, Frame>>(io: T, service: F) -> Self {
  function with (line 39) | pub fn with<F: IntoService<S, Frame>>(framed: Framed<T, Codec>, service:...
  type Output (line 53) | type Output = Result<(), inner::DispatcherError<S::Error, Codec, Message>>;
  method poll (line 55) | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
  type DispatcherError (line 85) | pub enum DispatcherError<E, U, I>
  function from (line 103) | fn from(err: E) -> Self {
  function fmt (line 115) | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
  function fmt (line 137) | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
  function from (line 153) | fn from(err: DispatcherError<E, U, I>) -> Self {
  type Message (line 159) | pub enum Message<T> {
  type State (line 190) | enum State<S, U, I>
  function take_error (line 207) | fn take_error(&mut self) -> DispatcherError<S::Error, U, I> {
  function take_framed_error (line 214) | fn take_framed_error(&mut self) -> DispatcherError<S::Error, U, I> {
  function new (line 234) | pub fn new<F>(framed: Framed<T, U>, service: F) -> Self
  function with_rx (line 249) | pub fn with_rx<F>(
  function tx (line 268) | pub fn tx(&self) -> mpsc::Sender<Result<Message<I>, S::Error>> {
  function service (line 273) | pub fn service(&self) -> &S {
  function service_mut (line 278) | pub fn service_mut(&mut self) -> &mut S {
  function framed (line 283) | pub fn framed(&self) -> &Framed<T, U> {
  function framed_mut (line 288) | pub fn framed_mut(&mut self) -> &mut Framed<T, U> {
  function poll_read (line 293) | fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> bool
  function poll_write (line 337) | fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> bool
  type Output (line 399) | type Output = Result<(), DispatcherError<S::Error, U, I>>;
  method poll (line 401) | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Ou...

FILE: actix-http/src/ws/frame.rs
  type Parser (line 14) | pub struct Parser;
    method parse_metadata (line 17) | fn parse_metadata(
    method parse (line 86) | pub fn parse(
    method parse_close_payload (line 154) | pub fn parse_close_payload(payload: &[u8]) -> Option<CloseReason> {
    method write_message (line 170) | pub fn write_message<B: AsRef<[u8]>>(
    method write_close (line 216) | pub fn write_close(dst: &mut BytesMut, reason: Option<CloseReason>, ma...
  type F (line 238) | struct F {
  function is_none (line 244) | fn is_none(frm: &Result<Option<(bool, OpCode, Option<BytesMut>)>, Protoc...
  function extract (line 248) | fn extract(frm: Result<Option<(bool, OpCode, Option<BytesMut>)>, Protoco...
  function test_parse (line 262) | fn test_parse() {
  function test_parse_length0 (line 276) | fn test_parse_length0() {
  function test_parse_length2 (line 285) | fn test_parse_length2() {
  function test_parse_length4 (line 300) | fn test_parse_length4() {
  function test_parse_frame_mask (line 315) | fn test_parse_frame_mask() {
  function test_parse_frame_no_mask (line 329) | fn test_parse_frame_no_mask() {
  function test_parse_frame_max_size (line 342) | fn test_parse_frame_max_size() {
  function test_parse_frame_max_size_recoverability (line 355) | fn test_parse_frame_max_size_recoverability() {
  function test_ping_frame (line 379) | fn test_ping_frame() {
  function test_pong_frame (line 389) | fn test_pong_frame() {
  function test_close_frame (line 399) | fn test_close_frame() {
  function test_empty_close_frame (line 410) | fn test_empty_close_frame() {
  function test_parse_length_overflow (line 417) | fn test_parse_length_overflow() {

FILE: actix-http/src/ws/mask.rs
  function apply_mask (line 5) | pub fn apply_mask(buf: &mut [u8], mask: [u8; 4]) {
  function apply_mask_fallback (line 11) | fn apply_mask_fallback(buf: &mut [u8], mask: [u8; 4]) {
  function apply_mask_fast32 (line 19) | pub fn apply_mask_fast32(buf: &mut [u8], mask: [u8; 4]) {
  function test_apply_mask (line 51) | fn test_apply_mask() {

FILE: actix-http/src/ws/mod.rs
  type ProtocolError (line 28) | pub enum ProtocolError {
  type HandshakeError (line 72) | pub enum HandshakeError {
  function from (line 99) | fn from(err: HandshakeError) -> Self {
  function from (line 143) | fn from(err: &HandshakeError) -> Self {
  function handshake (line 149) | pub fn handshake(req: &RequestHead) -> Result<ResponseBuilder, Handshake...
  function verify_handshake (line 155) | pub fn verify_handshake(req: &RequestHead) -> Result<(), HandshakeError> {
  function handshake_response (line 205) | pub fn handshake_response(req: &RequestHead) -> ResponseBuilder {
  function test_handshake (line 227) | fn test_handshake() {
  function test_ws_error_http_response (line 337) | fn test_ws_error_http_response() {

FILE: actix-http/src/ws/proto.rs
  type OpCode (line 10) | pub enum OpCode {
    method fmt (line 34) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    method from (line 69) | fn from(byte: u8) -> OpCode {
  function from (line 50) | fn from(op: OpCode) -> u8 {
  type CloseCode (line 86) | pub enum CloseCode {
    method from (line 175) | fn from(code: u16) -> CloseCode {
  function from (line 152) | fn from(code: CloseCode) -> u16 {
  type CloseReason (line 199) | pub struct CloseReason {
    method from (line 208) | fn from(code: CloseCode) -> Self {
    method from (line 217) | fn from(info: (CloseCode, T)) -> Self {
  function hash_key (line 232) | pub fn hash_key(key: &[u8]) -> [u8; 28] {
  function test_to_opcode (line 276) | fn test_to_opcode() {
  function test_from_opcode (line 287) | fn test_from_opcode() {
  function test_from_opcode_debug (line 298) | fn test_from_opcode_debug() {
  function test_from_opcode_display (line 303) | fn test_from_opcode_display() {
  function test_hash_key (line 314) | fn test_hash_key() {
  function close_code_from_u16 (line 320) | fn close_code_from_u16() {
  function close_code_into_u16 (line 338) | fn close_code_into_u16() {

FILE: actix-http/tests/test_client.rs
  constant STR (line 11) | const STR: &str = "Hello World Hello World Hello World Hello World Hello...
  function h1_v2 (line 34) | async fn h1_v2() {
  function connection_close (line 62) | async fn connection_close() {
  function with_query_parameter (line 76) | async fn with_query_parameter() {
  type ExpectFailed (line 98) | struct ExpectFailed;
  function from (line 101) | fn from(_: ExpectFailed) -> Self {
  function h1_expect (line 107) | async fn h1_expect() {

FILE: actix-http/tests/test_h2_timer.rs
  function h2_ping_pong (line 8) | async fn h2_ping_pong() -> io::Result<()> {
  function h2_handshake_timeout (line 81) | async fn h2_handshake_timeout() -> io::Result<()> {

FILE: actix-http/tests/test_openssl.rs
  function load_body (line 26) | async fn load_body<S>(stream: S) -> Result<BytesMut, PayloadError>
  function tls_config (line 44) | fn tls_config() -> SslAcceptor {
  function h2 (line 71) | async fn h2() -> io::Result<()> {
  function h2_1 (line 86) | async fn h2_1() -> io::Result<()> {
  function h2_body (line 108) | async fn h2_body() -> io::Result<()> {
  function h2_content_length (line 130) | async fn h2_content_length() {
  function h2_headers (line 178) | async fn h2_headers() {
  constant STR (line 220) | const STR: &str = "Hello World Hello World Hello World Hello World Hello...
  function h2_body2 (line 243) | async fn h2_body2() {
  function h2_head_empty (line 261) | async fn h2_head_empty() {
  function h2_head_binary (line 285) | async fn h2_head_binary() {
  function h2_head_binary2 (line 308) | async fn h2_head_binary2() {
  function h2_body_length (line 327) | async fn h2_body_length() {
  function h2_body_chunked_explicit (line 351) | async fn h2_body_chunked_explicit() {
  function h2_response_http_error_handling (line 379) | async fn h2_response_http_error_handling() {
  type BadRequest (line 408) | struct BadRequest;
  function from (line 411) | fn from(err: BadRequest) -> Self {
  function h2_service_error (line 419) | async fn h2_service_error() {
  function h2_on_connect (line 437) | async fn h2_on_connect() {

FILE: actix-http/tests/test_rustls.rs
  function load_body (line 34) | async fn load_body<S>(stream: S) -> Result<BytesMut, PayloadError>
  function tls_config_with_alpn (line 56) | fn tls_config_with_alpn(protocols: &[&[u8]]) -> RustlsServerConfig {
  function tls_config (line 72) | fn tls_config() -> RustlsServerConfig {
  function tls_config_h1 (line 76) | fn tls_config_h1() -> RustlsServerConfig {
  function tls_config_h2 (line 80) | fn tls_config_h2() -> RustlsServerConfig {
  function h1_client (line 84) | fn h1_client() -> Client {
  function get_negotiated_alpn_protocol (line 99) | pub fn get_negotiated_alpn_protocol(
  function h1 (line 125) | async fn h1() -> io::Result<()> {
  function h2 (line 140) | async fn h2() -> io::Result<()> {
  function h1_1 (line 155) | async fn h1_1() -> io::Result<()> {
  function h2_1 (line 174) | async fn h2_1() -> io::Result<()> {
  function h2_tcp_nodelay_override_true (line 196) | async fn h2_tcp_nodelay_override_true() -> io::Result<()> {
  function h2_tcp_nodelay_override_false (line 218) | async fn h2_tcp_nodelay_override_false() -> io::Result<()> {
  function h2_body1 (line 240) | async fn h2_body1() -> io::Result<()> {
  function h2_content_length (line 262) | async fn h2_content_length() {
  function h2_headers (line 326) | async fn h2_headers() {
  constant STR (line 368) | const STR: &str = "Hello World Hello World Hello World Hello World Hello...
  function h2_body2 (line 391) | async fn h2_body2() {
  function h2_head_empty (line 409) | async fn h2_head_empty() {
  function h2_head_binary (line 436) | async fn h2_head_binary() {
  function h2_head_binary2 (line 462) | async fn h2_head_binary2() {
  function h2_body_length (line 485) | async fn h2_body_length() {
  function h2_body_chunked_explicit (line 508) | async fn h2_body_chunked_explicit() {
  function h2_response_http_error_handling (line 536) | async fn h2_response_http_error_handling() {
  type BadRequest (line 567) | struct BadRequest;
  function from (line 570) | fn from(_: BadRequest) -> Self {
  function h2_service_error (line 576) | async fn h2_service_error() {
  function h1_service_error (line 594) | async fn h1_service_error() {
  constant H2_ALPN_PROTOCOL (line 611) | const H2_ALPN_PROTOCOL: &[u8] = b"h2";
  constant HTTP1_1_ALPN_PROTOCOL (line 612) | const HTTP1_1_ALPN_PROTOCOL: &[u8] = b"http/1.1";
  constant CUSTOM_ALPN_PROTOCOL (line 613) | const CUSTOM_ALPN_PROTOCOL: &[u8] = b"custom";
  function alpn_h1 (line 616) | async fn alpn_h1() -> io::Result<()> {
  function alpn_h2 (line 639) | async fn alpn_h2() -> io::Result<()> {
  function alpn_h2_1 (line 666) | async fn alpn_h2_1() -> io::Result<()> {

FILE: actix-http/tests/test_server.rs
  function h1_basic (line 26) | async fn h1_basic() {
  function h1_2 (line 47) | async fn h1_2() {
  type ExpectFailed (line 70) | struct ExpectFailed;
  function from (line 73) | fn from(_: ExpectFailed) -> Self {
  function expect_continue (line 79) | async fn expect_continue() {
  function expect_continue_h1 (line 110) | async fn expect_continue_h1() {
  function chunked_payload (line 143) | async fn chunked_payload() {
  function slow_request_408 (line 203) | async fn slow_request_408() {
  function http1_malformed_request (line 239) | async fn http1_malformed_request() {
  function http1_keepalive (line 257) | async fn http1_keepalive() {
  function http1_keepalive_timeout (line 280) | async fn http1_keepalive_timeout() {
  function http1_keepalive_close (line 306) | async fn http1_keepalive_close() {
  function http10_keepalive_default_close (line 328) | async fn http10_keepalive_default_close() {
  function http10_keepalive (line 350) | async fn http10_keepalive() {
  function http1_keepalive_disabled (line 378) | async fn http1_keepalive_disabled() {
  function content_length (line 401) | async fn content_length() {
  function content_length_truncated (line 450) | async fn content_length_truncated() {
  function h1_headers (line 504) | async fn h1_headers() {
  constant STR (line 547) | const STR: &str = "Hello World Hello World Hello World Hello World Hello...
  function h1_body (line 570) | async fn h1_body() {
  function h1_head_empty (line 589) | async fn h1_head_empty() {
  function h1_head_binary (line 616) | async fn h1_head_binary() {
  function h1_head_binary2 (line 643) | async fn h1_head_binary2() {
  function h1_body_length (line 666) | async fn h1_body_length() {
  function h1_body_chunked_explicit (line 690) | async fn h1_body_chunked_explicit() {
  function h1_body_chunked_implicit (line 727) | async fn h1_body_chunked_implicit() {
  function h1_response_http_error_handling (line 758) | async fn h1_response_http_error_handling() {
  type BadRequest (line 788) | struct BadRequest;
  function from (line 791) | fn from(_: BadRequest) -> Self {
  function h1_service_error (line 797) | async fn h1_service_error() {
  function h1_on_connect (line 816) | async fn h1_on_connect() {
  function not_modified_spec_h1 (line 839) | async fn not_modified_spec_h1() {
  function h2c_auto (line 920) | async fn h2c_auto() {
  function h2_flow_control_window_sizes (line 961) | async fn h2_flow_control_window_sizes() {

FILE: actix-http/tests/test_ws.rs
  type WsService (line 22) | struct WsService(Cell<bool>);
    method new (line 25) | fn new() -> Self {
    method set_polled (line 29) | fn set_polled(&self) {
    method was_polled (line 33) | fn was_polled(&self) -> bool {
    type Response (line 70) | type Response = ();
    type Error (line 71) | type Error = WsServiceError;
    type Future (line 72) | type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Err...
    method poll_ready (line 74) | fn poll_ready(&self, _: &mut Context<'_>) -> Poll<Result<(), Self::Err...
    method call (line 79) | fn call(&self, (req, mut framed): (Request, Framed<T, h1::Codec>)) -> ...
  type WsServiceError (line 39) | enum WsServiceError {
  function from (line 54) | fn from(err: WsServiceError) -> Self {
  function service (line 98) | async fn service(msg: Frame) -> Result<Message, Error> {
  function simple (line 112) | async fn simple() {

FILE: actix-multipart-derive/src/lib.rs
  type DuplicateField (line 20) | enum DuplicateField {
  type MultipartFormAttrs (line 29) | struct MultipartFormAttrs {
  type FieldAttrs (line 37) | struct FieldAttrs {
  type ParsedField (line 42) | struct ParsedField<'t> {
  function impl_multipart_form (line 150) | pub fn impl_multipart_form(input: proc_macro::TokenStream) -> proc_macro...
  function compile_err (line 308) | fn compile_err(err: syn::Error) -> TokenStream {

FILE: actix-multipart-derive/tests/trybuild.rs
  function compile_macros (line 3) | fn compile_macros() {

FILE: actix-multipart-derive/tests/trybuild/all-required.rs
  type ImageUpload (line 6) | struct ImageUpload {
  function handler (line 12) | async fn handler(_form: MultipartForm<ImageUpload>) -> impl Responder {
  function main (line 17) | async fn main() {

FILE: actix-multipart-derive/tests/trybuild/deny-duplicates.rs
  type Form (line 7) | struct Form {}
  function handler (line 9) | async fn handler(_form: MultipartForm<Form>) -> impl Responder {
  function main (line 14) | async fn main() {

FILE: actix-multipart-derive/tests/trybuild/deny-parse-fail.rs
  type Form (line 5) | struct Form {}
  function main (line 7) | fn main() {}

FILE: actix-multipart-derive/tests/trybuild/deny-unknown.rs
  type Form (line 7) | struct Form {}
  function handler (line 9) | async fn handler(_form: MultipartForm<Form>) -> impl Responder {
  function main (line 14) | async fn main() {

FILE: actix-multipart-derive/tests/trybuild/optional-and-list.rs
  type Form (line 6) | struct Form {
  function handler (line 11) | async fn handler(_form: MultipartForm<Form>) -> impl Responder {
  function main (line 16) | async fn main() {

FILE: actix-multipart-derive/tests/trybuild/rename.rs
  type Form (line 6) | struct Form {
  function handler (line 11) | async fn handler(_form: MultipartForm<Form>) -> impl Responder {
  function main (line 16) | async fn main() {

FILE: actix-multipart-derive/tests/trybuild/size-limit-parse-fail.rs
  type Form (line 4) | struct Form {
  type Form2 (line 10) | struct Form2 {
  type Form3 (line 16) | struct Form3 {
  function main (line 21) | fn main() {}

FILE: actix-multipart-derive/tests/trybuild/size-limits.rs
  type Form (line 6) | struct Form {
  function handler (line 14) | async fn handler(_form: MultipartForm<Form>) -> impl Responder {
  function main (line 19) | async fn main() {

FILE: actix-multipart/examples/form.rs
  type Metadata (line 8) | struct Metadata {
  type UploadForm (line 13) | struct UploadForm {
  function post_video (line 21) | async fn post_video(MultipartForm(form): MultipartForm<UploadForm>) -> i...
  function main (line 31) | async fn main() -> std::io::Result<()> {

FILE: actix-multipart/src/error.rs
  type Error (line 13) | pub enum Error {
  method status_code (line 99) | fn status_code(&self) -> StatusCode {
  function test_multipart_error (line 113) | fn test_multipart_error() {

FILE: actix-multipart/src/extractor.rs
  type Error (line 32) | type Error = Error;
  type Future (line 33) | type Future = Ready<Result<Multipart, Error>>;
  method from_request (line 36) | fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {

FILE: actix-multipart/src/field.rs
  type LimitExceeded (line 30) | pub struct LimitExceeded;
  type Field (line 33) | pub struct Field {
    method new (line 56) | pub(crate) fn new(
    method headers (line 75) | pub fn headers(&self) -> &HeaderMap {
    method content_type (line 84) | pub fn content_type(&self) -> Option<&Mime> {
    method content_disposition (line 104) | pub fn content_disposition(&self) -> Option<&ContentDisposition> {
    method name (line 112) | pub fn name(&self) -> Option<&str> {
    method bytes (line 126) | pub async fn bytes(&mut self, limit: usize) -> Result<Result<Bytes, Er...
    method fmt (line 194) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  type Item (line 168) | type Item = Result<Bytes, Error>;
  method poll_next (line 170) | fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<...
  type InnerField (line 209) | pub(crate) struct InnerField {
    method new_in_rc (line 224) | pub(crate) fn new_in_rc(
    method new (line 232) | pub(crate) fn new(
    method read_len (line 257) | pub(crate) fn read_len(
    method read_stream (line 288) | pub(crate) fn read_stream(
    method poll (line 362) | pub(crate) fn poll(&mut self, safety: &Safety) -> Poll<Option<Result<B...
  function create_double_request_with_header (line 420) | fn create_double_request_with_header() -> (Bytes, HeaderMap) {
  function bytes_unlimited (line 446) | async fn bytes_unlimited() {
  function bytes_limited (line 475) | async fn bytes_limited() {

FILE: actix-multipart/src/form/bytes.rs
  type Bytes (line 15) | pub struct Bytes {
    type Future (line 27) | type Future = LocalBoxFuture<'t, Result<Self, MultipartError>>;
    method read_field (line 29) | fn read_field(_: &'t HttpRequest, mut field: Field, limits: &'t mut Li...

FILE: actix-multipart/src/form/json.rs
  type Json (line 18) | pub struct Json<T: DeserializeOwned>(pub T);
  function into_inner (line 21) | pub fn into_inner(self) -> T {
  type Future (line 30) | type Future = LocalBoxFuture<'t, Result<Self, MultipartError>>;
  function read_field (line 32) | fn read_field(req: &'t HttpRequest, field: Field, limits: &'t mut Limits...
  type JsonFieldError (line 67) | pub enum JsonFieldError {
  method status_code (line 78) | fn status_code(&self) -> StatusCode {
  type JsonConfig (line 85) | pub struct JsonConfig {
    method error_handler (line 96) | pub fn error_handler<F>(mut self, f: F) -> Self
    method from_req (line 106) | fn from_req(req: &HttpRequest) -> &Self {
    method map_error (line 112) | fn map_error(&self, req: &HttpRequest, err: JsonFieldError) -> Error {
    method validate_content_type (line 121) | pub fn validate_content_type(mut self, validate_content_type: bool) ->...
  constant DEFAULT_CONFIG (line 90) | const DEFAULT_CONFIG: JsonConfig = JsonConfig {
  method default (line 128) | fn default() -> Self {
  type JsonForm (line 145) | struct JsonForm {
  function test_json_route (line 149) | async fn test_json_route(form: MultipartForm<JsonForm>) -> impl Responder {
  constant TEST_JSON (line 157) | const TEST_JSON: &str = r#"{"key1": "value1", "key2": "value2"}"#;
  function test_json_without_content_type (line 160) | async fn test_json_without_content_type() {
  function test_content_type_validation (line 180) | async fn test_content_type_validation() {

FILE: actix-multipart/src/form/mod.rs
  type FieldErrorHandler (line 26) | type FieldErrorHandler<T> = Option<Arc<dyn Fn(T, &HttpRequest) -> Error ...
  type FieldReader (line 31) | pub trait FieldReader<'t>: Sized + Any {
    method read_field (line 44) | fn read_field(req: &'t HttpRequest, field: Field, limits: &'t mut Limi...
  type State (line 50) | pub struct State(pub HashMap<String, Box<dyn Any>>);
  type FieldGroupReader (line 54) | pub trait FieldGroupReader<'t>: Sized + Any {
    method handle_field (line 58) | fn handle_field(
    method from_state (line 67) | fn from_state(name: &str, state: &'t mut State) -> Result<Self, Multip...
  type Future (line 74) | type Future = LocalBoxFuture<'t, Result<(), MultipartError>>;
  function handle_field (line 76) | fn handle_field(
  function from_state (line 105) | fn from_state(name: &str, state: &'t mut State) -> Result<Self, Multipar...
  type Future (line 114) | type Future = LocalBoxFuture<'t, Result<(), MultipartError>>;
  function handle_field (line 116) | fn handle_field(
  function from_state (line 139) | fn from_state(name: &str, state: &'t mut State) -> Result<Self, Multipar...
  type Future (line 151) | type Future = LocalBoxFuture<'t, Result<(), MultipartError>>;
  method handle_field (line 153) | fn handle_field(
  method from_state (line 182) | fn from_state(name: &str, state: &'t mut State) -> Result<Self, Multipar...
  type Future (line 194) | type Future = LocalBoxFuture<'t, Result<(), MultipartError>>;
  function handle_field (line 196) | fn handle_field(
  function from_state (line 219) | fn from_state(name: &str, state: &'t mut State) -> Result<Self, Multipar...
  type MultipartCollect (line 232) | pub trait MultipartCollect: Sized {
    method limit (line 235) | fn limit(field_name: &str) -> Option<usize>;
    method handle_field (line 239) | fn handle_field<'t>(
    method from_state (line 248) | fn from_state(state: State) -> Result<Self, MultipartError>;
  type DuplicateField (line 252) | pub enum DuplicateField {
  type Limits (line 264) | pub struct Limits {
    method new (line 271) | pub fn new(total_limit: usize, memory_limit: usize) -> Self {
    method try_consume_limits (line 286) | pub fn try_consume_limits(
  type MultipartForm (line 326) | pub struct MultipartForm<T: MultipartCollect>(pub T);
  function into_inner (line 330) | pub fn into_inner(self) -> T {
  type Error (line 339) | type Error = Error;
  type Future (line 340) | type Future = LocalBoxFuture<'static, Result<Self, Self::Error>>;
  method from_request (line 343) | fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::...
  type MultipartFormErrorHandler (line 403) | type MultipartFormErrorHandler =
  type MultipartFormConfig (line 410) | pub struct MultipartFormConfig {
    method total_limit (line 418) | pub fn total_limit(mut self, total_limit: usize) -> Self {
    method memory_limit (line 424) | pub fn memory_limit(mut self, memory_limit: usize) -> Self {
    method error_handler (line 430) | pub fn error_handler<F>(mut self, f: F) -> Self
    method from_req (line 440) | fn from_req(req: &HttpRequest) -> &Self {
  constant DEFAULT_CONFIG (line 447) | const DEFAULT_CONFIG: MultipartFormConfig = MultipartFormConfig {
  method default (line 454) | fn default() -> Self {
  function send_form (line 479) | pub async fn send_form(
  type TestOptions (line 494) | struct TestOptions {
  function test_options_route (line 499) | async fn test_options_route(form: MultipartForm<TestOptions>) -> impl Re...
  function test_options (line 506) | async fn test_options() {
  type TestVec (line 518) | struct TestVec {
  function test_vec_route (line 523) | async fn test_vec_route(form: MultipartForm<TestVec>) -> impl Responder {
  function test_vec (line 536) | async fn test_vec() {
  type TestOptionVec (line 550) | struct TestOptionVec {
  function test_option_vec_route (line 555) | async fn test_option_vec_route(form: MultipartForm<TestOptionVec>) -> im...
  function test_option_vec (line 569) | async fn test_option_vec() {
  type TestFieldRenaming (line 584) | struct TestFieldRenaming {
  function test_field_renaming_route (line 592) | async fn test_field_renaming_route(form: MultipartForm<TestFieldRenaming...
  function test_field_renaming (line 600) | async fn test_field_renaming() {
  type TestDenyUnknown (line 616) | struct TestDenyUnknown {}
  type TestAllowUnknown (line 619) | struct TestAllowUnknown {}
  function test_deny_unknown_route (line 621) | async fn test_deny_unknown_route(_: MultipartForm<TestDenyUnknown>) -> i...
  function test_allow_unknown_route (line 625) | async fn test_allow_unknown_route(_: MultipartForm<TestAllowUnknown>) ->...
  function test_deny_unknown (line 630) | async fn test_deny_unknown() {
  type TestDuplicateDeny (line 651) | struct TestDuplicateDeny {
  type TestDuplicateReplace (line 657) | struct TestDuplicateReplace {
  type TestDuplicateIgnore (line 663) | struct TestDuplicateIgnore {
  function test_duplicate_deny_route (line 667) | async fn test_duplicate_deny_route(_: MultipartForm<TestDuplicateDeny>) ...
  function test_duplicate_replace_route (line 671) | async fn test_duplicate_replace_route(
  function test_duplicate_ignore_route (line 678) | async fn test_duplicate_ignore_route(
  function test_duplicate_field (line 686) | async fn test_duplicate_field() {
  type TestMemoryUploadLimits (line 715) | struct TestMemoryUploadLimits {
  type TestFileUploadLimits (line 720) | struct TestFileUploadLimits {
  function test_upload_limits_memory (line 724) | async fn test_upload_limits_memory(
  function test_upload_limits_file (line 731) | async fn test_upload_limits_file(form: MultipartForm<TestFileUploadLimit...
  function test_memory_limits (line 737) | async fn test_memory_limits() {
  function test_total_limit (line 763) | async fn test_total_limit() {
  type TestFieldLevelLimits (line 795) | struct TestFieldLevelLimits {
  function test_field_level_limits_route (line 800) | async fn test_field_level_limits_route(
  function test_field_level_limits (line 808) | async fn test_field_level_limits() {
  function non_multipart_form_data (line 847) | async fn non_multipart_form_data() {
  function field_try_next_panic (line 883) | async fn field_try_next_panic() {

FILE: actix-multipart/src/form/tempfile.rs
  type TempFile (line 25) | pub struct TempFile {
    type Future (line 40) | type Future = LocalBoxFuture<'t, Result<Self, MultipartError>>;
    method read_field (line 42) | fn read_field(req: &'t HttpRequest, mut field: Field, limits: &'t mut ...
  type TempFileError (line 83) | pub enum TempFileError {
  method status_code (line 90) | fn status_code(&self) -> StatusCode {
  type TempFileConfig (line 97) | pub struct TempFileConfig {
    method create_tempfile (line 103) | fn create_tempfile(&self) -> io::Result<NamedTempFile> {
    method error_handler (line 114) | pub fn error_handler<F>(mut self, f: F) -> Self
    method from_req (line 124) | fn from_req(req: &HttpRequest) -> &Self {
    method map_error (line 130) | fn map_error(&self, req: &HttpRequest, field_name: &str, err: TempFile...
    method directory (line 146) | pub fn directory(mut self, dir: impl AsRef<Path>) -> Self {
  constant DEFAULT_CONFIG (line 152) | const DEFAULT_CONFIG: TempFileConfig = TempFileConfig {
  method default (line 158) | fn default() -> Self {
  type FileForm (line 173) | struct FileForm {
  function test_file_route (line 177) | async fn test_file_route(form: MultipartForm<FileForm>) -> impl Responder {
  function test_file_upload (line 188) | async fn test_file_upload() {

FILE: actix-multipart/src/form/text.rs
  type Text (line 21) | pub struct Text<T: DeserializeOwned>(pub T);
  function into_inner (line 25) | pub fn into_inner(self) -> T {
  type Future (line 34) | type Future = LocalBoxFuture<'t, Result<Self, MultipartError>>;
  function read_field (line 36) | fn read_field(req: &'t HttpRequest, field: Field, limits: &'t mut Limits...
  type TextError (line 78) | pub enum TextError {
  method status_code (line 93) | fn status_code(&self) -> StatusCode {
  type TextConfig (line 100) | pub struct TextConfig {
    method error_handler (line 107) | pub fn error_handler<F>(mut self, f: F) -> Self
    method from_req (line 117) | fn from_req(req: &HttpRequest) -> &Self {
    method map_error (line 123) | fn map_error(&self, req: &HttpRequest, err: TextError) -> Error {
    method validate_content_type (line 135) | pub fn validate_content_type(mut self, validate_content_type: bool) ->...
  constant DEFAULT_CONFIG (line 141) | const DEFAULT_CONFIG: TextConfig = TextConfig {
  method default (line 147) | fn default() -> Self {
  type TextForm (line 166) | struct TextForm {
  function test_text_route (line 170) | async fn test_text_route(form: MultipartForm<TextForm>) -> impl Responder {
  function test_content_type_validation (line 176) | async fn test_content_type_validation() {

FILE: actix-multipart/src/multipart.rs
  constant MAX_HEADERS (line 28) | const MAX_HEADERS: usize = 32;
  type Multipart (line 35) | pub struct Multipart {
    method new (line 49) | pub fn new<S>(headers: &HeaderMap, stream: S) -> Self
    method from_req (line 60) | pub(crate) fn from_req(req: &HttpRequest, payload: &mut dev::Payload) ...
    method find_ct_and_boundary (line 68) | pub(crate) fn find_ct_and_boundary(headers: &HeaderMap) -> Result<(Mim...
    method from_ct_and_boundary (line 91) | pub(crate) fn from_ct_and_boundary<S>(ct: Mime, boundary: String, stre...
    method from_error (line 108) | pub(crate) fn from_error(err: Error) -> Multipart {
    method content_type_or_bail (line 116) | pub(crate) fn content_type_or_bail(&mut self) -> Result<mime::Mime, Er...
  type Flow (line 40) | enum Flow {
  type Item (line 127) | type Item = Result<Field, Error>;
  method poll_next (line 129) | fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<...
  type State (line 155) | enum State {
  type Item (line 169) | enum Item {
  type Inner (line 174) | struct Inner {
    method read_field_headers (line 191) | fn read_field_headers(payload: &mut PayloadBuffer) -> Result<Option<He...
    method read_boundary (line 241) | fn read_boundary(payload: &mut PayloadBuffer, boundary: &str) -> Resul...
    method skip_until_boundary (line 286) | fn skip_until_boundary(
    method poll (line 328) | fn poll(&mut self, safety: &Safety, cx: &Context<'_>) -> Poll<Option<R...
  method drop (line 466) | fn drop(&mut self) {
  constant BOUNDARY (line 492) | const BOUNDARY: &str = "abbc761f78ff4d7cb7573b5a23f96ef0";
  function test_boundary (line 495) | async fn test_boundary() {
  function create_stream (line 537) | fn create_stream() -> (
  function create_simple_request_with_header (line 549) | fn create_simple_request_with_header() -> (Bytes, HeaderMap) {
  function create_double_request_with_header (line 569) | fn create_double_request_with_header() -> (Bytes, HeaderMap) {
  function test_multipart_no_end_crlf (line 593) | async fn test_multipart_no_end_crlf() {
  function test_multipart (line 620) | async fn test_multipart() {
  function get_whole_field (line 672) | async fn get_whole_field(field: &mut Field) -> BytesMut {
  function test_stream (line 684) | async fn test_stream() {
  function test_multipart_from_error (line 722) | async fn test_multipart_from_error() {
  function test_multipart_from_boundary (line 729) | async fn test_multipart_from_boundary() {
  function test_multipart_payload_consumption (line 737) | async fn test_multipart_payload_consumption() {
  function no_content_disposition_form_data (line 755) | async fn no_content_disposition_form_data() {
  function no_content_disposition_non_form_data (line 787) | async fn no_content_disposition_non_form_data() {
  function no_name_in_form_data_content_disposition (line 814) | async fn no_name_in_form_data_content_disposition() {
  function test_drop_multipart_dont_hang (line 845) | async fn test_drop_multipart_dont_hang() {
  function test_drop_field_awaken_multipart (line 864) | async fn test_drop_field_awaken_multipart() {

FILE: actix-multipart/src/payload.rs
  type PayloadRef (line 17) | pub(crate) struct PayloadRef {
    method new (line 22) | pub(crate) fn new(payload: PayloadBuffer) -> PayloadRef {
    method get_mut (line 28) | pub(crate) fn get_mut(&self, safety: &Safety) -> Option<RefMut<'_, Pay...
  method clone (line 38) | fn clone(&self) -> PayloadRef {
  type PayloadBuffer (line 46) | pub(crate) struct PayloadBuffer {
    method new (line 55) | pub(crate) fn new<S>(stream: S) -> Self
    method poll_stream (line 66) | pub(crate) fn poll_stream(&mut self, cx: &mut Context<'_>) -> Result<(...
    method read_exact (line 86) | pub(crate) fn read_exact(&mut self, size: usize) -> Option<Bytes> {
    method read_max (line 94) | pub(crate) fn read_max(&mut self, size: u64) -> Result<Option<Bytes>, ...
    method read_until (line 112) | pub(crate) fn read_until(&mut self, needle: &[u8]) -> Result<Option<By...
    method readline (line 133) | pub(crate) fn readline(&mut self) -> Result<Option<Bytes>, Error> {
    method readline_or_eof (line 139) | pub(crate) fn readline_or_eof(&mut self) -> Result<Option<Bytes>, Erro...
    method unprocessed (line 147) | pub(crate) fn unprocessed(&mut self, data: Bytes) {
  function basic (line 163) | async fn basic() {
  function eof (line 173) | async fn eof() {
  function err (line 189) | async fn err() {
  function read_max (line 198) | async fn read_max() {
  function read_exactly (line 215) | async fn read_exactly() {
  function read_until (line 233) | async fn read_until() {

FILE: actix-multipart/src/safety.rs
  type Safety (line 12) | pub(crate) struct Safety {
    method new (line 20) | pub(crate) fn new() -> Safety {
    method current (line 30) | pub(crate) fn current(&self) -> bool {
    method is_clean (line 34) | pub(crate) fn is_clean(&self) -> bool {
    method clone (line 38) | pub(crate) fn clone(&self, cx: &task::Context<'_>) -> Safety {
  method drop (line 52) | fn drop(&mut self) {

FILE: actix-multipart/src/test.rs
  constant CRLF (line 10) | const CRLF: &[u8] = b"\r\n";
  constant CRLF_CRLF (line 11) | const CRLF_CRLF: &[u8] = b"\r\n\r\n";
  constant HYPHENS (line 12) | const HYPHENS: &[u8] = b"--";
  constant BOUNDARY_PREFIX (line 13) | const BOUNDARY_PREFIX: &str = "------------------------";
  function create_form_data_payload_and_headers (line 58) | pub fn create_form_data_payload_and_headers(
  function create_form_data_payload_and_headers_with_boundary (line 78) | pub fn create_form_data_payload_and_headers_with_boundary(
  function find_boundary (line 135) | fn find_boundary(headers: &HeaderMap) -> String {
  function wire_format (line 150) | fn wire_format() {
  function ecosystem_compat (line 198) | async fn ecosystem_compat() {

FILE: actix-router/benches/quoter.rs
  function compare_quoters (line 5) | fn compare_quoters(c: &mut Criterion) {

FILE: actix-router/benches/router.rs
  function call (line 154) | fn call() -> impl Iterator<Item = &'static str> {
  function compare_routers (line 166) | fn compare_routers(c: &mut Criterion) {

FILE: actix-router/src/de.rs
  type PathDeserializer (line 75) | pub struct PathDeserializer<'de, T: ResourcePath> {
  function new (line 80) | pub fn new(path: &'de Path<T>) -> Self {
  type Error (line 86) | type Error = de::value::Error;
  function deserialize_map (line 88) | fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
  function deserialize_struct (line 98) | fn deserialize_struct<V>(
  function deserialize_unit (line 110) | fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
  function deserialize_unit_struct (line 117) | fn deserialize_unit_struct<V>(
  function deserialize_newtype_struct (line 128) | fn deserialize_newtype_struct<V>(
  function deserialize_tuple (line 139) | fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value...
  function deserialize_tuple_struct (line 159) | fn deserialize_tuple_struct<V>(
  function deserialize_enum (line 184) | fn deserialize_enum<V>(
  function deserialize_seq (line 202) | fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
  type ParamsDeserializer (line 234) | struct ParamsDeserializer<'de, T: ResourcePath> {
  type Error (line 240) | type Error = de::value::Error;
  function next_key_seed (line 242) | fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self...
  function next_value_seed (line 253) | fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
  type Key (line 265) | struct Key<'de> {
  type Error (line 270) | type Error = de::value::Error;
  function deserialize_identifier (line 272) | fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self:...
  function deserialize_any (line 279) | fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
  type Value (line 293) | struct Value<'de> {
  type Error (line 298) | type Error = de::value::Error;
  function deserialize_ignored_any (line 313) | fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self...
  function deserialize_unit (line 320) | fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
  function deserialize_unit_struct (line 327) | fn deserialize_unit_struct<V>(
  function deserialize_str (line 338) | fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
  function deserialize_bytes (line 348) | fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
  function deserialize_byte_buf (line 358) | fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::E...
  function deserialize_string (line 365) | fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
  function deserialize_option (line 372) | fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
  function deserialize_enum (line 379) | fn deserialize_enum<V>(
  function deserialize_newtype_struct (line 391) | fn deserialize_newtype_struct<V>(
  function deserialize_tuple (line 402) | fn deserialize_tuple<V>(self, _: usize, _: V) -> Result<V::Value, Self::...
  function deserialize_struct (line 409) | fn deserialize_struct<V>(
  function deserialize_tuple_struct (line 421) | fn deserialize_tuple_struct<V>(
  function deserialize_any (line 433) | fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
  type ParamsSeq (line 471) | struct ParamsSeq<'de, T: ResourcePath> {
  type Error (line 476) | type Error = de::value::Error;
  function next_element_seed (line 478) | fn next_element_seed<U>(&mut self, seed: U) -> Result<Option<U::Value>, ...
  type ValueEnum (line 489) | struct ValueEnum<'de> {
  type Error (line 494) | type Error = de::value::Error;
  type Variant (line 495) | type Variant = UnitVariant;
  function variant_seed (line 497) | fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), S...
  type UnitVariant (line 505) | struct UnitVariant;
    type Error (line 508) | type Error = de::value::Error;
    method unit_variant (line 510) | fn unit_variant(self) -> Result<(), Self::Error> {
    method newtype_variant_seed (line 514) | fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::E...
    method tuple_variant (line 521) | fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value...
    method struct_variant (line 528) | fn struct_variant<V>(self, _: &'static [&'static str], _: V) -> Result...
  type MyStruct (line 544) | struct MyStruct {
  type Test1 (line 550) | struct Test1(String, u32);
  type Test2 (line 553) | struct Test2 {
  type TestEnum (line 560) | enum TestEnum {
  type Test3 (line 566) | struct Test3 {
  function test_request_extract (line 571) | fn test_request_extract() {
  function test_extract_path_single (line 613) | fn test_extract_path_single() {
  function test_extract_enum (line 625) | fn test_extract_enum() {
  function test_extract_enum_value (line 647) | fn test_extract_enum_value() {
  function test_extract_errors (line 666) | fn test_extract_errors() {
  function deserialize_path_decode_string (line 696) | fn deserialize_path_decode_string() {
  function deserialize_path_decode_seq (line 713) | fn deserialize_path_decode_seq() {
  function deserialize_path_decode_map (line 725) | fn deserialize_path_decode_map() {
  function deserialize_path_decode_any (line 743) | fn deserialize_path_decode_any() {
  function deserialize_borrowed (line 856) | fn deserialize_borrowed() {

FILE: actix-router/src/path.rs
  type PathItem (line 11) | pub(crate) enum PathItem {
  method default (line 17) | fn default() -> Self {
  type Path (line 26) | pub struct Path<T> {
  function new (line 38) | pub fn new(path: T) -> Path<T> {
  function get_ref (line 48) | pub fn get_ref(&self) -> &T {
  function get_mut (line 54) | pub fn get_mut(&mut self) -> &mut T {
  function as_str (line 60) | pub fn as_str(&self) -> &str {
  function unprocessed (line 68) | pub fn unprocessed(&self) -> &str {
  function path (line 78) | pub fn path(&self) -> &str {
  function set (line 90) | pub fn set(&mut self, path: T) {
  function update_with_reindex (line 101) | pub fn update_with_reindex<F>(&mut self, path: T, mut reindex: F)
  function reset (line 137) | pub fn reset(&mut self) {
  function skip (line 144) | pub fn skip(&mut self, n: u16) {
  function add (line 148) | pub(crate) fn add(&mut self, name: impl Into<Cow<'static, str>>, value: ...
  function add_static (line 159) | pub fn add_static(
  function is_empty (line 170) | pub fn is_empty(&self) -> bool {
  function segment_count (line 176) | pub fn segment_count(&self) -> usize {
  function get (line 181) | pub fn get(&self, name: &str) -> Option<&str> {
  function query (line 199) | pub fn query(&self, key: &str) -> &str {
  function iter (line 204) | pub fn iter(&self) -> PathIter<'_, T> {
  function load (line 216) | pub fn load<'de, U: Deserialize<'de>>(&'de self) -> Result<U, de::value:...
  function clamp_to_char_boundary (line 221) | fn clamp_to_char_boundary(path: &str, idx: u16) -> u16 {
  type PathIter (line 232) | pub struct PathIter<'a, T> {
  type Item (line 238) | type Item = (&'a str, &'a str);
  method next (line 241) | fn next(&mut self) -> Option<(&'a str, &'a str)> {
  type Output (line 258) | type Output = str;
  function index (line 260) | fn index(&self, name: &'a str) -> &str {
  type Output (line 267) | type Output = str;
  function index (line 269) | fn index(&self, idx: usize) -> &str {
  type Path (line 278) | type Path = T;
  method resource_path (line 280) | fn resource_path(&mut self) -> &mut Path<Self::Path> {
  type Path (line 290) | type Path = P;
  method resource_path (line 292) | fn resource_path(&mut self) -> &mut Path<Self::Path> {
  function deref_impls (line 305) | fn deref_impls() {

FILE: actix-router/src/pattern.rs
  type Patterns (line 3) | pub enum Patterns {
    method is_empty (line 9) | pub fn is_empty(&self) -> bool {
  type IntoPatterns (line 18) | pub trait IntoPatterns {
    method patterns (line 19) | fn patterns(&self) -> Patterns;
    method patterns (line 23) | fn patterns(&self) -> Patterns {
    method patterns (line 29) | fn patterns(&self) -> Patterns {
    method patterns (line 35) | fn patterns(&self) -> Patterns {
    method patterns (line 41) | fn patterns(&self) -> Patterns {
    method patterns (line 47) | fn patterns(&self) -> Patterns {
    method patterns (line 53) | fn patterns(&self) -> Patterns {
    method patterns (line 59) | fn patterns(&self) -> Patterns {

FILE: actix-router/src/quoter.rs
  type Quoter (line 14) | pub struct Quoter {
    method new (line 26) | pub fn new(_: &[u8], protected: &[u8]) -> Quoter {
    method decode_next (line 39) | fn decode_next<'a>(&self, val: &mut &'a [u8]) -> Option<(&'a [u8], u8)> {
    method requote (line 62) | pub fn requote(&self, val: &[u8]) -> Option<Vec<u8>> {
    method requote_str_lossy (line 89) | pub(crate) fn requote_str_lossy(&self, val: &str) -> Option<String> {
  function hex_pair_to_char (line 103) | fn hex_pair_to_char(d1: u8, d2: u8) -> Option<u8> {
  type AsciiBitmap (line 112) | struct AsciiBitmap {
    method set_bit (line 121) | fn set_bit(&mut self, ch: u8) {
    method bit_at (line 129) | fn bit_at(&self, ch: u8) -> bool {
  function custom_quoter (line 139) | fn custom_quoter() {
  function non_ascii (line 154) | fn non_ascii() {
  function invalid_sequences (line 161) | fn invalid_sequences() {
  function quoter_no_modification (line 168) | fn quoter_no_modification() {

FILE: actix-router/src/regex_set.rs
  type RegexSet (line 12) | pub(crate) struct RegexSet(regex::RegexSet);
    method new (line 24) | pub(crate) fn new(re_set: Vec<String>) -> Self {
    method empty (line 35) | pub(crate) fn empty() -> Self {
    method is_match (line 46) | pub(crate) fn is_match(&self, path: &str) -> bool {
    method first_match_idx (line 57) | pub(crate) fn first_match_idx(&self, path: &str) -> Option<usize> {
  type RegexSet (line 16) | pub(crate) struct RegexSet(Vec<regex_lite::Regex>);
    method new (line 24) | pub(crate) fn new(re_set: Vec<String>) -> Self {
    method empty (line 35) | pub(crate) fn empty() -> Self {
    method is_match (line 46) | pub(crate) fn is_match(&self, path: &str) -> bool {
    method first_match_idx (line 57) | pub(crate) fn first_match_idx(&self, path: &str) -> Option<usize> {

FILE: actix-router/src/resource.rs
  constant MAX_DYNAMIC_SEGMENTS (line 16) | const MAX_DYNAMIC_SEGMENTS: usize = 16;
  constant REGEX_FLAGS (line 21) | const REGEX_FLAGS: &str = "(?s-m)";
  type ResourceDef (line 212) | pub struct ResourceDef {
    method new (line 276) | pub fn new<T: IntoPatterns>(paths: T) -> Self {
    method prefix (line 303) | pub fn prefix<T: IntoPatterns>(paths: T) -> Self {
    method root_prefix (line 327) | pub fn root_prefix(path: &str) -> Self {
    method id (line 344) | pub fn id(&self) -> u16 {
    method set_id (line 357) | pub fn set_id(&mut self, id: u16) {
    method name (line 371) | pub fn name(&self) -> Option<&str> {
    method set_name (line 387) | pub fn set_name(&mut self, name: impl Into<String>) {
    method is_prefix (line 403) | pub fn is_prefix(&self) -> bool {
    method pattern (line 421) | pub fn pattern(&self) -> Option<&str> {
    method pattern_iter (line 443) | pub fn pattern_iter(&self) -> impl Iterator<Item = &str> {
    method join (line 503) | pub fn join(&self, other: &ResourceDef) -> ResourceDef {
    method is_match (line 555) | pub fn is_match(&self, path: &str) -> bool {
    method find_match (line 602) | pub fn find_match(&self, path: &str) -> Option<usize> {
    method capture_match_info (line 636) | pub fn capture_match_info<R: Resource>(&self, resource: &mut R) -> bool {
    method capture_match_info_fn (line 677) | pub fn capture_match_info_fn<R, F>(&self, resource: &mut R, check_fn: ...
    method build_resource_path (line 754) | fn build_resource_path<F, I>(&self, path: &mut String, mut vars: F) ->...
    method resource_path_from_iter (line 788) | pub fn resource_path_from_iter<I>(&self, path: &mut String, values: I)...
    method resource_path_from_map (line 818) | pub fn resource_path_from_map<K, V, S>(
    method static_match (line 832) | fn static_match(&self, pattern: &str, path: &str) -> Option<usize> {
    method construct (line 847) | fn construct<T: IntoPatterns>(paths: T, is_prefix: bool) -> Self {
    method parse_param (line 906) | fn parse_param(pattern: &str) -> (PatternSegment, String, &str, bool) {
    method parse (line 971) | fn parse(
    method from (line 1097) | fn from(path: &'a str) -> ResourceDef {
    method from (line 1103) | fn from(path: String) -> ResourceDef {
  type PatternSegment (line 231) | enum PatternSegment {
  type PatternType (line 241) | enum PatternType {
  method eq (line 1085) | fn eq(&self, other: &ResourceDef) -> bool {
  method hash (line 1091) | fn hash<H: Hasher>(&self, state: &mut H) {
  function insert_slash (line 1108) | pub(crate) fn insert_slash(path: &str) -> Cow<'_, str> {
  function equivalence (line 1125) | fn equivalence() {
  function parse_static (line 1152) | fn parse_static() {
  function parse_param (line 1197) | fn parse_param() {
  function dynamic_set (line 1239) | fn dynamic_set() {
  function dynamic_set_prefix (line 1305) | fn dynamic_set_prefix() {
  function parse_tail (line 1323) | fn parse_tail() {
  function static_tail (line 1344) | fn static_tail() {
  function dynamic_tail (line 1363) | fn dynamic_tail() {
  function newline_patterns_and_paths (line 1375) | fn newline_patterns_and_paths() {
  function parse_urlencoded_param (line 1402) | fn parse_urlencoded_param() {
  function prefix_static (line 1420) | fn prefix_static() {
  function prefix_dynamic (line 1469) | fn prefix_dynamic() {
  function prefix_empty (line 1501) | fn prefix_empty() {
  function build_path_list (line 1512) | fn build_path_list() {
  function multi_pattern_build_path (line 1552) | fn multi_pattern_build_path() {
  function multi_pattern_capture_segment_values (line 1560) | fn multi_pattern_capture_segment_values() {
  function dynamic_prefix_proper_segmentation (line 1585) | fn dynamic_prefix_proper_segmentation() {
  function build_path_map (line 1600) | fn build_path_map() {
  function build_path_tail (line 1617) | fn build_path_tail() {
  function prefix_trailing_slash (line 1635) | fn prefix_trailing_slash() {
  function join (line 1649) | fn join() {
  function match_methods_agree (line 1698) | fn match_methods_agree() {
  function duplicate_segment_name (line 1737) | fn duplicate_segment_name() {
  function invalid_dynamic_segment_delimiter (line 1743) | fn invalid_dynamic_segment_delimiter() {
  function invalid_dynamic_segment_name (line 1749) | fn invalid_dynamic_segment_name() {
  function invalid_too_many_dynamic_segments (line 1755) | fn invalid_too_many_dynamic_segments() {
  function invalid_custom_regex_for_tail (line 1765) | fn invalid_custom_regex_for_tail() {
  function invalid_unnamed_tail_segment (line 1771) | fn invalid_unnamed_tail_segment() {
  function prefix_plus_tail_match_disallowed (line 1777) | fn prefix_plus_tail_match_disallowed() {

FILE: actix-router/src/resource_path.rs
  type Resource (line 9) | pub trait Resource {
    method resource_path (line 14) | fn resource_path(&mut self) -> &mut Path<Self::Path>;
  type ResourcePath (line 17) | pub trait ResourcePath {
    method path (line 18) | fn path(&self) -> &str;
    method path (line 22) | fn path(&self) -> &str {
    method path (line 28) | fn path(&self) -> &str {
    method path (line 34) | fn path(&self) -> &str {
    method path (line 41) | fn path(&self) -> &str {

FILE: actix-router/src/router.rs
  type ResourceId (line 4) | pub struct ResourceId(pub u16);
  type Router (line 14) | pub struct Router<T, U = ()> {
  function build (line 20) | pub fn build() -> RouterBuilder<T, U> {
  function recognize (line 27) | pub fn recognize<R>(&self, resource: &mut R) -> Option<(&T, ResourceId)>
  function recognize_mut (line 35) | pub fn recognize_mut<R>(&mut self, resource: &mut R) -> Option<(&mut T, ...
  function recognize_fn (line 49) | pub fn recognize_fn<R, F>(&self, resource: &mut R, mut check: F) -> Opti...
  function recognize_mut_fn (line 65) | pub fn recognize_mut_fn<R, F>(
  type RouterBuilder (line 85) | pub struct RouterBuilder<T, U = ()> {
  function push (line 93) | pub fn push(
  function finish (line 108) | pub fn finish(self) -> Router<T, U> {
  function path (line 121) | pub fn path(&mut self, path: impl IntoPatterns, val: T) -> (&mut Resourc...
  function prefix (line 126) | pub fn prefix(
  function rdef (line 135) | pub fn rdef(&mut self, rdef: ResourceDef, val: T) -> (&mut ResourceDef, ...
  function test_recognizer_1 (line 150) | fn test_recognizer_1() {
  function test_recognizer_2 (line 218) | fn test_recognizer_2() {
  function test_recognizer_with_prefix (line 234) | fn test_recognizer_with_prefix() {

FILE: actix-router/src/url.rs
  type Url (line 8) | pub struct Url {
    method new (line 15) | pub fn new(uri: http::Uri) -> Url {
    method new_with_quoter (line 21) | pub fn new_with_quoter(uri: http::Uri, quoter: &Quoter) -> Url {
    method uri (line 30) | pub fn uri(&self) -> &http::Uri {
    method path (line 36) | pub fn path(&self) -> &str {
    method update (line 44) | pub fn update(&mut self, uri: &http::Uri) {
    method update_with_quoter (line 50) | pub fn update_with_quoter(&mut self, uri: &http::Uri, quoter: &Quoter) {
  method path (line 58) | fn path(&self) -> &str {
  constant PROTECTED (line 72) | const PROTECTED: &[u8] = b"%/+";
  function match_url (line 74) | fn match_url(pattern: &'static str, url: impl AsRef<str>) -> Path<Url> {
  function percent_encode (line 82) | fn percent_encode(data: &[u8]) -> String {
  function parse_url (line 91) | fn parse_url() {
  function protected_chars (line 99) | fn protected_chars() {
  function non_protected_ascii (line 117) | fn non_protected_ascii() {
  function valid_utf8_multi_byte (line 127) | fn valid_utf8_multi_byte() {
  function invalid_utf8 (line 135) | fn invalid_utf8() {

FILE: actix-test/src/lib.rs
  function start (line 81) | pub fn start<F, I, S, B>(factory: F) -> TestServer
  function start_with (line 120) | pub fn start_with<F, I, S, B>(cfg: TestServerConfig, factory: F) -> Test...
  type HttpVer (line 484) | enum HttpVer {
  type StreamType (line 492) | enum StreamType {
  function config (line 507) | pub fn config() -> TestServerConfig {
  type TestServerConfig (line 512) | pub struct TestServerConfig {
    method new (line 530) | pub(crate) fn new() -> TestServerConfig {
    method h1 (line 543) | pub fn h1(mut self) -> Self {
    method h2 (line 549) | pub fn h2(mut self) -> Self {
    method openssl (line 556) | pub fn openssl(mut self, acceptor: openssl::ssl::SslAcceptor) -> Self {
    method rustls (line 564) | pub fn rustls(mut self, config: tls_rustls_0_20::ServerConfig) -> Self {
    method rustls_0_20 (line 571) | pub fn rustls_0_20(mut self, config: tls_rustls_0_20::ServerConfig) ->...
    method rustls_021 (line 579) | pub fn rustls_021(mut self, config: tls_rustls_0_21::ServerConfig) -> ...
    method rustls_0_21 (line 586) | pub fn rustls_0_21(mut self, config: tls_rustls_0_21::ServerConfig) ->...
    method rustls_0_22 (line 593) | pub fn rustls_0_22(mut self, config: tls_rustls_0_22::ServerConfig) ->...
    method rustls_0_23 (line 600) | pub fn rustls_0_23(mut self, config: tls_rustls_0_23::ServerConfig) ->...
    method client_request_timeout (line 606) | pub fn client_request_timeout(mut self, dur: Duration) -> Self {
    method listen_address (line 614) | pub fn listen_address(mut self, addr: impl Into<String>) -> Self {
    method port (line 622) | pub fn port(mut self, port: u16) -> Self {
    method workers (line 630) | pub fn workers(mut self, workers: usize) -> Self {
    method disable_redirects (line 639) | pub fn disable_redirects(mut self) -> Self {
  method default (line 523) | fn default() -> Self {
  type TestServer (line 649) | pub struct TestServer {
    method addr (line 660) | pub fn addr(&self) -> net::SocketAddr {
    method url (line 665) | pub fn url(&self, uri: &str) -> String {
    method get (line 676) | pub fn get(&self, path: impl AsRef<str>) -> ClientRequest {
    method post (line 681) | pub fn post(&self, path: impl AsRef<str>) -> ClientRequest {
    method head (line 686) | pub fn head(&self, path: impl AsRef<str>) -> ClientRequest {
    method put (line 691) | pub fn put(&self, path: impl AsRef<str>) -> ClientRequest {
    method patch (line 696) | pub fn patch(&self, path: impl AsRef<str>) -> ClientRequest {
    method delete (line 701) | pub fn delete(&self, path: impl AsRef<str>) -> ClientRequest {
    method options (line 706) | pub fn options(&self, path: impl AsRef<str>) -> ClientRequest {
    method request (line 711) | pub fn request(&self, method: Method, path: impl AsRef<str>) -> Client...
    method load_body (line 715) | pub async fn load_body<S>(
    method ws_at (line 726) | pub async fn ws_at(
    method ws (line 736) | pub async fn ws(
    method client_headers (line 746) | pub fn client_headers(&mut self) -> Option<&mut HeaderMap> {
    method stop (line 753) | pub async fn stop(mut self) {
  method drop (line 767) | fn drop(&mut self) {

FILE: actix-web-actors/src/context.rs
  type HttpContext (line 71) | pub struct HttpContext<A>
  method stop (line 83) | fn stop(&mut self) {
  method terminate (line 86) | fn terminate(&mut self) {
  method state (line 89) | fn state(&self) -> ActorState {
  function spawn (line 99) | fn spawn<F>(&mut self, fut: F) -> SpawnHandle
  function wait (line 107) | fn wait<F>(&mut self, fut: F)
  function waiting (line 116) | fn waiting(&self) -> bool {
  function cancel_future (line 123) | fn cancel_future(&mut self, handle: SpawnHandle) -> bool {
  function address (line 128) | fn address(&self) -> Addr<A> {
  function create (line 139) | pub fn create(actor: A) -> impl Stream<Item = Result<Bytes, Error>> {
  function with_factory (line 149) | pub fn with_factory<F>(f: F) -> impl Stream<Item = Result<Bytes, Error>>
  function write (line 170) | pub fn write(&mut self, data: Bytes) {
  function write_eof (line 176) | pub fn write_eof(&mut self) {
  function handle (line 183) | pub fn handle(&self) -> SpawnHandle {
  function parts (line 192) | fn parts(&mut self) -> &mut ContextParts<A> {
  type HttpContextFut (line 197) | struct HttpContextFut<A>
  function new (line 208) | fn new(ctx: HttpContext<A>, act: A, mailbox: Mailbox<A>) -> Self {
  type Item (line 218) | type Item = Result<Bytes, Error>;
  method poll_next (line 220) | fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Opt...
  function pack (line 242) | fn pack(msg: M, tx: Option<Sender<M::Result>>) -> Envelope<A> {
  type MyActor (line 259) | struct MyActor {
    method write (line 272) | fn write(&mut self, ctx: &mut HttpContext<Self>) {
  type Context (line 264) | type Context = HttpContext<Self>;
  method started (line 266) | fn started(&mut self, ctx: &mut Self::Context) {
  function test_default_resource (line 284) | async fn test_default_resource() {

FILE: actix-web-actors/src/ws.rs
  type WsResponseBuilder (line 142) | pub struct WsResponseBuilder<'a, A, T>
  function new (line 163) | pub fn new(actor: A, req: &'a HttpRequest, stream: T) -> Self {
  function protocols (line 175) | pub fn protocols(mut self, protocols: &'a [&'a str]) -> Self {
  function frame_size (line 183) | pub fn frame_size(mut self, frame_size: usize) -> Self {
  function codec (line 190) | pub fn codec(mut self, codec: Codec) -> Self {
  function handshake_resp (line 195) | fn handshake_resp(&self) -> Result<HttpResponseBuilder, HandshakeError> {
  function set_frame_size (line 202) | fn set_frame_size(&mut self) {
  function create_with_codec_addr (line 224) | fn create_with_codec_addr<S>(
  function start (line 255) | pub fn start(mut self) -> Result<HttpResponse, Error> {
  function start_with_addr (line 281) | pub fn start_with_addr(mut self) -> Result<(Addr<A>, HttpResponse), Erro...
  function start (line 303) | pub fn start<A, T>(actor: A, req: &HttpRequest, stream: T) -> Result<Htt...
  function start_with_addr (line 323) | pub fn start_with_addr<A, T>(
  function start_with_protocols (line 344) | pub fn start_with_protocols<A, T>(
  function handshake (line 362) | pub fn handshake(req: &HttpRequest) -> Result<HttpResponseBuilder, Hands...
  function handshake_with_protocols (line 373) | pub fn handshake_with_protocols(
  type WebsocketContext (line 454) | pub struct WebsocketContext<A>
  method stop (line 466) | fn stop(&mut self) {
  method terminate (line 470) | fn terminate(&mut self) {
  method state (line 474) | fn state(&self) -> ActorState {
  function spawn (line 483) | fn spawn<F>(&mut self, fut: F) -> SpawnHandle
  function wait (line 490) | fn wait<F>(&mut self, fut: F)
  function waiting (line 499) | fn waiting(&self) -> bool {
  function cancel_future (line 505) | fn cancel_future(&mut self, handle: SpawnHandle) -> bool {
  function address (line 510) | fn address(&self) -> Addr<A> {
  function create (line 521) | pub fn create<S>(actor: A, stream: S) -> impl Stream<Item = Result<Bytes...
  function create_with_addr (line 535) | pub fn create_with_addr<S>(
  function with_codec (line 556) | pub fn with_codec<S>(
  function with_factory (line 576) | pub fn with_factory<S, F>(stream: S, f: F) -> impl Stream<Item = Result<...
  function write_raw (line 606) | pub fn write_raw(&mut self, msg: Message) {
  function text (line 612) | pub fn text(&mut self, text: impl Into<ByteString>) {
  function binary (line 618) | pub fn binary(&mut self, data: impl Into<Bytes>) {
  function ping (line 624) | pub fn ping(&mut self, message: &[u8]) {
  function pong (line 630) | pub fn pong(&mut self, message: &[u8]) {
  function close (line 636) | pub fn close(&mut self, reason: Option<CloseReason>) {
  function handle (line 643) | pub fn handle(&self) -> SpawnHandle {
  function set_mailbox_capacity (line 650) | pub fn set_mailbox_capacity(&mut self, cap: usize) {
  function parts (line 659) | fn parts(&mut self) -> &mut ContextParts<A> {
  type WebsocketContextFut (line 664) | struct WebsocketContextFut<A>
  function new (line 678) | fn new(ctx: WebsocketContext<A>, act: A, mailbox: Mailbox<A>, codec: Cod...
  type Item (line 693) | type Item = Result<Bytes, Error>;
  method poll_next (line 695) | fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<...
  function pack (line 728) | fn pack(msg: M, tx: Option<oneshot::Sender<M::Result>>) -> Envelope<A> {
  function new (line 748) | fn new(stream: S, codec: Codec) -> Self {
  type Item (line 762) | type Item = Result<Message, ProtocolError>;
  method poll_next (line 764) | fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Opt...
  function test_handshake (line 818) | fn test_handshake() {

FILE: actix-web-actors/tests/test_ws.rs
  type Ws (line 8) | struct Ws;
    method handle (line 15) | fn handle(&mut self, msg: Result<ws::Message, ws::ProtocolError>, ctx:...
  type Context (line 11) | type Context = ws::WebsocketContext<Self>;
  constant MAX_FRAME_SIZE (line 26) | const MAX_FRAME_SIZE: usize = 10_000;
  constant DEFAULT_FRAME_SIZE (line 27) | const DEFAULT_FRAME_SIZE: usize = 10;
  function common_test_code (line 29) | async fn common_test_code(mut srv: actix_test::TestServer, frame_size: u...
  function simple_builder (line 58) | async fn simple_builder() {
  function builder_with_frame_size (line 71) | async fn builder_with_frame_size() {
  function builder_with_frame_size_exceeded (line 86) | async fn builder_with_frame_size_exceeded() {
  function builder_with_codec (line 115) | async fn builder_with_codec() {
  function builder_with_protocols (line 130) | async fn builder_with_protocols() {
  function builder_with_codec_and_frame_size (line 145) | async fn builder_with_codec_and_frame_size() {
  function builder_full (line 161) | async fn builder_full() {
  function simple_start (line 178) | async fn simple_start() {

FILE: actix-web-codegen/src/lib.rs
  function route (line 116) | pub fn route(args: TokenStream, input: TokenStream) -> TokenStream {
  function routes (line 149) | pub fn routes(_: TokenStream, input: TokenStream) -> TokenStream {
  function scope (line 232) | pub fn scope(args: TokenStream, input: TokenStream) -> TokenStream {
  function main (line 250) | pub fn main(_: TokenStream, item: TokenStream) -> TokenStream {
  function test (line 270) | pub fn test(_: TokenStream, item: TokenStream) -> TokenStream {
  function input_and_compile_error (line 286) | fn input_and_compile_error(mut item: TokenStream, err: syn::Error) -> To...

FILE: actix-web-codegen/src/route.rs
  type RouteArgs (line 12) | pub struct RouteArgs {
    method parse (line 18) | fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {
  type Error (line 107) | type Error = syn::Error;
  method try_from (line 109) | fn try_from(value: &syn::LitStr) -> Result<Self, Self::Error> {
  method to_tokens (line 116) | fn to_tokens(&self, stream: &mut TokenStream2) {
  type MethodTypeExt (line 123) | enum MethodTypeExt {
    method to_tokens_single_guard (line 130) | fn to_tokens_single_guard(&self) -> TokenStream2 {
    method to_tokens_multi_guard (line 148) | fn to_tokens_multi_guard(&self, or_chain: Vec<impl ToTokens>) -> Token...
    method to_tokens_multi_guard_or_chain (line 180) | fn to_tokens_multi_guard_or_chain(&self) -> TokenStream2 {
    type Error (line 213) | type Error = syn::Error;
    method try_from (line 215) | fn try_from(value: &syn::LitStr) -> Result<Self, Self::Error> {
  method to_tokens (line 201) | fn to_tokens(&self, stream: &mut TokenStream2) {
  type Args (line 226) | struct Args {
    method new (line 235) | fn new(args: RouteArgs, method: Option<MethodType>) -> syn::Result<Sel...
  type Route (line 327) | pub struct Route {
    method new (line 344) | pub fn new(args: RouteArgs, ast: syn::ItemFn, method: Option<MethodTyp...
    method multiple (line 380) | fn multiple(args: Vec<Args>, ast: syn::ItemFn) -> syn::Result<Self> {
  method to_tokens (line 409) | fn to_tokens(&self, output: &mut TokenStream2) {
  function with_method (line 485) | pub(crate) fn with_method(
  function with_methods (line 509) | pub(crate) fn with_methods(input: TokenStream) -> TokenStream {

FILE: actix-web-codegen/src/scope.rs
  function with_scope (line 10) | pub fn with_scope(args: TokenStream, input: TokenStream) -> TokenStream {
  function with_scope_inner (line 17) | fn with_scope_inner(args: TokenStream, input: TokenStream) -> syn::Resul...
  function modify_attribute_with_scope (line 66) | fn modify_attribute_with_scope(attr: &syn::Attribute, scope_path: &str) ...
  function has_allowed_methods_in_scope (line 99) | fn has_allowed_methods_in_scope(attr: &syn::Attribute) -> bool {

FILE: actix-web-codegen/tests/routes.rs
  function config (line 20) | async fn config() -> impl Responder {
  function test_handler (line 25) | async fn test_handler() -> impl Responder {
  function put_test (line 30) | async fn put_test() -> impl Responder {
  function patch_test (line 35) | async fn patch_test() -> impl Responder {
  function post_test (line 40) | async fn post_test() -> impl Responder {
  function head_test (line 45) | async fn head_test() -> impl Responder {
  function connect_test (line 50) | async fn connect_test() -> impl Responder {
  function options_test (line 55) | async fn options_test() -> impl Responder {
  function trace_test (line 60) | async fn trace_test() -> impl Responder {
  function auto_async (line 65) | fn auto_async() -> impl Future<Output = Result<HttpResponse, actix_web::...
  function auto_sync (line 70) | fn auto_sync() -> impl Future<Output = Result<HttpResponse, actix_web::E...
  function put_param_test (line 75) | async fn put_param_test(_: web::Path<String>) -> impl Responder {
  function delete_param_test (line 80) | async fn delete_param_test(_: web::Path<String>) -> impl Responder {
  function get_param_test (line 85) | async fn get_param_test(_: web::Path<String>) -> impl Responder {
  function custom_route_test (line 90) | async fn custom_route_test() -> impl Responder {
  function route_test (line 101) | async fn route_test() -> impl Responder {
  function routes_test (line 109) | async fn routes_test() -> impl Responder {
  function routes_overlapping_test (line 117) | async fn routes_overlapping_test(req: HttpRequest) -> impl Responder {
  function routes_overlapping_inaccessible_test (line 131) | async fn routes_overlapping_inaccessible_test(req: HttpRequest) -> impl ...
  function custom_resource_name_test (line 139) | async fn custom_resource_name_test(req: HttpRequest) -> impl Responder {
  function guard (line 148) | pub fn guard(ctx: &GuardContext<'_>) -> bool {
  function guard_test (line 156) | async fn guard_test() -> impl Responder {
  type ChangeStatusCode (line 160) | pub struct ChangeStatusCode;
    type Response (line 168) | type Response = ServiceResponse<B>;
    type Error (line 169) | type Error = Error;
    type Transform (line 170) | type Transform = ChangeStatusCodeMiddleware<S>;
    type InitError (line 171) | type InitError = ();
    type Future (line 172) | type Future = Ready<Result<Self::Transform, Self::InitError>>;
    method new_transform (line 174) | fn new_transform(&self, service: S) -> Self::Future {
  type ChangeStatusCodeMiddleware (line 179) | pub struct ChangeStatusCodeMiddleware<S> {
  type Response (line 189) | type Response = ServiceResponse<B>;
  type Error (line 190) | type Error = Error;
  type Future (line 191) | type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
  function call (line 195) | fn call(&self, req: ServiceRequest) -> Self::Future {
  function get_wrap (line 210) | async fn get_wrap(_: web::Path<String>) -> impl Responder {
  function get_catalog (line 224) | async fn get_catalog() -> impl Responder {
  function test_params (line 229) | async fn test_params() {
  function test_body (line 251) | async fn test_body() {
  function test_auto_async (line 367) | async fn test_auto_async() {
  function test_wrap (line 376) | async fn test_wrap() {

FILE: actix-web-codegen/tests/scopes.rs
  function image_guard (line 4) | pub fn image_guard(ctx: &GuardContext<'_>) -> bool {
  function guard (line 16) | pub async fn guard() -> impl Responder {
  function test (line 21) | pub async fn test() -> impl Responder {
  function twice (line 26) | pub async fn twice(value: web::Path<String>) -> impl actix_web::Responder {
  function post (line 33) | pub async fn post() -> impl Responder {
  function delete (line 38) | pub async fn delete() -> impl Responder {
  function multiple_shared_path (line 43) | pub async fn multiple_shared_path() -> impl Responder {
  function multiple_separate_paths (line 52) | pub async fn multiple_separate_paths() -> impl Responder {
  function mod_common (line 57) | pub fn mod_common(message: String) -> impl actix_web::Responder {
  function test (line 69) | pub async fn test() -> impl Responder {
  type TestEnum (line 79) | enum TestEnum {
  function test (line 84) | pub async fn test() -> impl Responder {
  function scope_get_async (line 95) | async fn scope_get_async() {
  function scope_get_param_async (line 104) | async fn scope_get_param_async() {
  function scope_post_async (line 115) | async fn scope_post_async() {
  function multiple_shared_path_async (line 126) | async fn multiple_shared_path_async() {
  function multiple_multi_path_async (line 139) | async fn multiple_multi_path_async() {
  function scope_delete_async (line 160) | async fn scope_delete_async() {
  function scope_get_with_guard_async (line 171) | async fn scope_get_with_guard_async() {
  function scope_v1_v2_async (line 182) | async fn scope_v1_v2_async() {

FILE: actix-web-codegen/tests/trybuild.rs
  function compile_macros (line 3) | fn compile_macros() {

FILE: actix-web-codegen/tests/trybuild/docstring-ok.rs
  function index (line 6) | async fn index() -> impl Responder {
  function main (line 11) | async fn main() {

FILE: actix-web-codegen/tests/trybuild/route-custom-lowercase.rs
  function index (line 6) | async fn index() -> String {
  function main (line 11) | async fn main() {

FILE: actix-web-codegen/tests/trybuild/route-custom-method.rs
  function index (line 7) | async fn index() -> String {
  function custom (line 12) | async fn custom() -> String {
  function main (line 17) | async fn main() {

FILE: actix-web-codegen/tests/trybuild/route-duplicate-method-fail.rs
  function index (line 4) | async fn index() -> String {
  function main (line 9) | async fn main() {

FILE: actix-web-codegen/tests/trybuild/route-malformed-path-fail.rs
  function zero (line 4) | async fn zero() -> &'static str {
  function one (line 9) | async fn one() -> &'static str {
  function two (line 14) | async fn two() -> &'static str {
  function three (line 19) | async fn three() -> &'static str {
  function four (line 24) | async fn four() -> &'static str {
  function five (line 29) | async fn five() -> &'static str {
  function main (line 33) | fn main() {}

FILE: actix-web-codegen/tests/trybuild/route-missing-method-fail.rs
  function index (line 4) | async fn index() -> String {
  function main (line 9) | async fn main() {

FILE: actix-web-codegen/tests/trybuild/route-ok.rs
  function index (line 4) | async fn index() -> String {
  function main (line 9) | async fn main() {

FILE: actix-web-codegen/tests/trybuild/routes-missing-args-fail.rs
  function index (line 5) | async fn index() -> String {
  function main (line 10) | async fn main() {

FILE: actix-web-codegen/tests/trybuild/routes-missing-method-fail.rs
  function index (line 4) | async fn index() -> String {
  function main (line 9) | async fn main() {

FILE: actix-web-codegen/tests/trybuild/routes-ok.rs
  function index (line 6) | async fn index() -> String {
  function main (line 11) | async fn main() {

FILE: actix-web-codegen/tests/trybuild/scope-invalid-args.rs
  constant PATH (line 3) | const PATH: &str = "/api";
  function main (line 14) | fn main() {}

FILE: actix-web-codegen/tests/trybuild/scope-missing-args.rs
  function main (line 6) | fn main() {}

FILE: actix-web-codegen/tests/trybuild/scope-on-handler.rs
  function index (line 4) | async fn index() -> &'static str {
  function main (line 8) | fn main() {}

FILE: actix-web-codegen/tests/trybuild/scope-trailing-slash.rs
  function main (line 6) | fn main() {}

FILE: actix-web-codegen/tests/trybuild/simple-fail.rs
  function one (line 4) | async fn one() -> String {
  function two (line 9) | async fn two() -> String {
  function three (line 16) | async fn three() -> String {
  function four (line 21) | async fn four() -> String {
  function five (line 26) | async fn five() -> String {
  function main (line 30) | fn main() {}

FILE: actix-web-codegen/tests/trybuild/simple.rs
  function config (line 5) | async fn config() -> impl Responder {
  function main (line 10) | async fn main() {

FILE: actix-web-codegen/tests/trybuild/test-runtime.rs
  function my_test (line 2) | async fn my_test() {
  function main (line 6) | fn main() {}

FILE: actix-web/benches/responder.rs
  type FutureResponder (line 10) | trait FutureResponder {
    method future_respond_to (line 14) | fn future_respond_to(self, req: &HttpRequest) -> Self::Future;
    type Error (line 21) | type Error = Error;
    type Future (line 22) | type Future = Ready<Result<HttpResponse, Self::Error>>;
    method future_respond_to (line 24) | fn future_respond_to(self, _: &HttpRequest) -> Self::Future {
  type StringResponder (line 18) | struct StringResponder(String);
  type Body (line 33) | type Body = BoxBody;
  method respond_to (line 35) | fn respond_to(self, _: &HttpRequest) -> HttpResponse<Self::Body> {
  function future_responder (line 42) | fn future_responder(c: &mut Criterion) {
  function responder (line 65) | fn responder(c: &mut Criterion) {

FILE: actix-web/benches/server.rs
  constant STR (line 6) | const STR: &str = "Hello World Hello World Hello World Hello World Hello...
  function bench_async_burst (line 29) | fn bench_async_burst(c: &mut Criterion) {

FILE: actix-web/benches/service.rs
  function bench_async_service (line 25) | pub fn bench_async_service<S>(c: &mut Criterion, srv: S, name: &str)
  function index (line 61) | async fn index(req: ServiceRequest) -> Result<ServiceResponse, Error> {
  function async_web_service (line 69) | fn async_web_service(c: &mut Criterion) {
  function service_benches (line 102) | pub fn service_benches() {

FILE: actix-web/examples/basic.rs
  function index (line 4) | async fn index(req: HttpRequest, name: web::Path<String>) -> String {
  function index_async (line 9) | async fn index_async(req: HttpRequest) -> &'static str {
  function no_params (line 15) | async fn no_params() -> &'static str {
  function main (line 20) | async fn main() -> std::io::Result<()> {

FILE: actix-web/examples/from_fn.rs
  function noop (line 15) | async fn noop<B>(req: ServiceRequest, next: Next<B>) -> Result<ServiceRe...
  function print_range_header (line 19) | async fn print_range_header<B>(
  function mutate_body_type (line 33) | async fn mutate_body_type(
  function mutate_body_type_with_extractors (line 41) | async fn mutate_body_type_with_extractors(
  function timeout_10secs (line 55) | async fn timeout_10secs(
  type MyMw (line 65) | struct MyMw(bool);
    method mw_cb (line 68) | async fn mw_cb(
    method into_middleware (line 84) | pub fn into_middleware<S, B>(
  function main (line 106) | async fn main() -> io::Result<()> {

FILE: actix-web/examples/introspection.rs
  function main (line 5) | async fn main() -> std::io::Result<()> {

FILE: actix-web/examples/introspection_multi_servers.rs
  function main (line 5) | async fn main() -> std::io::Result<()> {

FILE: actix-web/examples/macroless.rs
  function index (line 3) | async fn index(req: HttpRequest) -> &'static str {
  function main (line 8) | fn main() -> std::io::Result<()> {

FILE: actix-web/examples/middleware_from_fn.rs
  function noop (line 14) | async fn noop<B>(req: ServiceRequest, next: Next<B>) -> Result<ServiceRe...
  function print_range_header (line 18) | async fn print_range_header<B>(
  function mutate_body_type (line 32) | async fn mutate_body_type(
  function mutate_body_type_with_extractors (line 40) | async fn mutate_body_type_with_extractors(
  function timeout_10secs (line 54) | async fn timeout_10secs(
  type MyMw (line 64) | struct MyMw(bool);
    method mw_cb (line 67) | async fn mw_cb(
    method into_middleware (line 83) | pub fn into_middleware<S, B>(
  function main (line 105) | async fn main() -> io::Result<()> {

FILE: actix-web/examples/on-connect.rs
  type ConnectionInfo (line 15) | struct ConnectionInfo {
  function route_whoami (line 21) | async fn route_whoami(req: HttpRequest) -> impl Responder {
  function get_conn_info (line 30) | fn get_conn_info(connection: &dyn Any, data: &mut Extensions) {
  function main (line 43) | async fn main() -> io::Result<()> {

FILE: actix-web/examples/uds.rs
  function index (line 6) | async fn index(req: HttpRequest, name: web::Path<String>) -> String {
  function index_async (line 12) | async fn index_async(req: HttpRequest) -> Result<&'static str, Error> {
  function no_params (line 18) | async fn no_params() -> &'static str {
  function main (line 24) | async fn main() -> std::io::Result<()> {
  function main (line 49) | fn main() {}

FILE: actix-web/examples/worker-cpu-pin.rs
  function hello (line 12) | async fn hello() -> &'static str {
  function main (line 17) | async fn main() -> io::Result<()> {

FILE: actix-web/src/app.rs
  type App (line 25) | pub struct App<T> {
  function new (line 40) | pub fn new() -> Self {
  function app_data (line 121) | pub fn app_data<U: 'static>(mut self, data: U) -> Self {
  function data (line 130) | pub fn data<U: 'static>(self, data: U) -> Self {
  function data_factory (line 140) | pub fn data_factory<F, Out, D, E>(mut self, data: F) -> Self
  function configure (line 191) | pub fn configure<F>(mut self, f: F) -> Self
  function route (line 227) | pub fn route(self, path: &str, mut route: Route) -> Self {
  function service (line 243) | pub fn service<F>(mut self, factory: F) -> Self
  function default_service (line 271) | pub fn default_service<F, U>(mut self, svc: F) -> Self
  function external_resource (line 307) | pub fn external_resource<N, U>(mut self, name: N, url: U) -> Self
  function wrap (line 345) | pub fn wrap<M, B>(
  function wrap_fn (line 415) | pub fn wrap_fn<F, R, B>(
  function into_factory (line 457) | fn into_factory(self) -> AppInit<T, B> {
  function test_default_resource (line 490) | async fn test_default_resource() {
  function test_data_factory (line 535) | async fn test_data_factory() {
  function test_data_factory_errors (line 560) | async fn test_data_factory_errors() {
  function test_extension (line 572) | async fn test_extension() {
  function test_wrap (line 586) | async fn test_wrap() {
  function test_router_wrap (line 606) | async fn test_router_wrap() {
  function test_wrap_fn (line 626) | async fn test_wrap_fn() {
  function test_router_wrap_fn (line 651) | async fn test_router_wrap_fn() {
  function test_external_resource (line 676) | async fn test_external_resource() {
  function can_be_returned_from_fn (line 697) | fn can_be_returned_from_fn() {

FILE: actix-web/src/app_service.rs
  type AppInit (line 27) | pub struct AppInit<T, B>
  type Response (line 59) | type Response = ServiceResponse<B>;
  type Error (line 60) | type Error = T::Error;
  type Config (line 61) | type Config = AppConfig;
  type Service (line 62) | type Service = AppInitService<T::Service, B>;
  type InitError (line 63) | type InitError = T::InitError;
  type Future (line 64) | type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitEr...
  function new_service (line 66) | fn new_service(&self, config: AppConfig) -> Self::Future {
  type AppInitService (line 166) | pub struct AppInitService<T, B>
  type AppInitServiceState (line 176) | pub(crate) struct AppInitServiceState {
    method new (line 184) | pub(crate) fn new(rmap: Rc<ResourceMap>, config: AppConfig) -> Rc<Self> {
    method rmap (line 194) | pub(crate) fn rmap(&self) -> &ResourceMap {
    method config (line 200) | pub(crate) fn config(&self) -> &AppConfig {
    method pool (line 206) | pub(crate) fn pool(&self) -> &HttpRequestPool {
  type Response (line 215) | type Response = ServiceResponse<B>;
  type Error (line 216) | type Error = T::Error;
  type Future (line 217) | type Future = T::Future;
  function call (line 221) | fn call(
Condensed preview — 413 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,090K chars).
[
  {
    "path": ".clippy.toml",
    "chars": 450,
    "preview": "disallowed-names = [\n  \"..\",\n  \"e\", # no single letter error bindings\n]\ndisallowed-methods = [\n  { path = \"std::cell::Re"
  },
  {
    "path": ".codecov.yml",
    "chars": 271,
    "preview": "comment: false\n\ncoverage:\n  status:\n    project:\n      default:\n        threshold: 100% # make CI green\n    patch:\n     "
  },
  {
    "path": ".cspell.yml",
    "chars": 161,
    "preview": "version: \"0.2\"\nwords:\n  - actix\n  - addrs\n  - ALPN\n  - bytestring\n  - httparse\n  - MSRV\n  - realip\n  - rustls\n  - rustup"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 77,
    "preview": "# These are supported funding model platforms\n\ngithub: [robjtede, JohnTitor]\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 1278,
    "preview": "---\nname: Bug Report\nabout: Create a bug report.\n---\n\nYour issue may already be reported! Please search on the [Actix We"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 272,
    "preview": "blank_issues_enabled: true\ncontact_links:\n  - name: Actix Discord\n    url: https://discord.gg/NWpN5mmg3x\n    about: Acti"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "chars": 864,
    "preview": "<!-- Thanks for considering contributing actix! -->\n<!-- Please fill out the following to get your PR reviewed quicker. "
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 234,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: github-actions\n    directory: /\n    schedule:\n      interval: weekly\n  - pack"
  },
  {
    "path": ".github/labeler.yml",
    "chars": 857,
    "preview": "A-files:\n  - changed-files:\n      - any-glob-to-any-file: actix-files/**\n\nA-http:\n  - changed-files:\n      - any-glob-to"
  },
  {
    "path": ".github/workflows/bench.yml",
    "chars": 560,
    "preview": "name: Benchmark\n\non:\n  push:\n    branches: [main]\n\npermissions:\n  contents: read\n\nconcurrency:\n  group: ${{ github.workf"
  },
  {
    "path": ".github/workflows/ci-post-merge.yml",
    "chars": 2798,
    "preview": "name: CI (post-merge)\n\non:\n  push:\n    branches: [main]\n\npermissions:\n  contents: read\n\nconcurrency:\n  group: ${{ github"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 3965,
    "preview": "name: CI\n\non:\n  pull_request:\n    types: [opened, synchronize, reopened]\n  merge_group:\n    types: [checks_requested]\n  "
  },
  {
    "path": ".github/workflows/coverage.yml",
    "chars": 1090,
    "preview": "name: Coverage\n\non:\n  push:\n    branches: [main]\n\npermissions:\n  contents: read\n\nconcurrency:\n  group: ${{ github.workfl"
  },
  {
    "path": ".github/workflows/labeler.yml",
    "chars": 356,
    "preview": "name: Labeler\n\non:\n  pull_request_target:\n    types: [opened, synchronize, reopened]\n\npermissions:\n  contents: read\n  pu"
  },
  {
    "path": ".github/workflows/lint.yml",
    "chars": 2832,
    "preview": "name: Lint\n\non:\n  pull_request:\n    types: [opened, synchronize, reopened]\n\npermissions:\n  contents: read\n\nconcurrency:\n"
  },
  {
    "path": ".github/workflows/semver-labeler.yml",
    "chars": 760,
    "preview": "name: Semver Labeler\n\non:\n  workflow_run:\n    workflows: [CI]\n    types: [completed]\n\njobs:\n  semver-label:\n    runs-on:"
  },
  {
    "path": ".gitignore",
    "chars": 282,
    "preview": "target/\nguide/build/\n/gh-pages\n\n*.so\n*.out\n*.pyc\n*.pid\n*.sock\n*~\n.DS_Store\n\n# These are backup files generated by rustfm"
  },
  {
    "path": ".prettierrc.yml",
    "chars": 88,
    "preview": "overrides:\n  - files: \"*.md\"\n    options:\n      printWidth: 9999\n      proseWrap: never\n"
  },
  {
    "path": ".rustfmt.toml",
    "chars": 97,
    "preview": "group_imports = \"StdExternalCrate\"\nimports_granularity = \"Crate\"\nuse_field_init_shorthand = true\n"
  },
  {
    "path": ".taplo.toml",
    "chars": 756,
    "preview": "exclude = [\"target/*\"]\ninclude = [\"**/*.toml\"]\n\n[formatting]\ncolumn_width = 100\nalign_comments = false\n\n[[rule]]\ninclude"
  },
  {
    "path": "CHANGES.md",
    "chars": 140,
    "preview": "# Changelog\n\nChangelogs are kept separately for each crate in this repo.\n\nActix Web changelog [is now here &rarr;](./act"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 3351,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
  },
  {
    "path": "Cargo.toml",
    "chars": 1660,
    "preview": "[workspace]\nresolver = \"2\"\nmembers = [\n  \"actix-files\",\n  \"actix-http-test\",\n  \"actix-http\",\n  \"actix-multipart\",\n  \"act"
  },
  {
    "path": "LICENSE-APACHE",
    "chars": 11344,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "LICENSE-MIT",
    "chars": 1058,
    "preview": "Copyright (c) 2017-NOW Actix Team\n\nPermission is hereby granted, free of charge, to any\nperson obtaining a copy of this "
  },
  {
    "path": "actix-files/CHANGES.md",
    "chars": 8042,
    "preview": "# Changes\n\n## Unreleased\n\n- Add `Files::try_compressed()` to support serving pre-compressed static files [#2615]\n- Fix h"
  },
  {
    "path": "actix-files/Cargo.toml",
    "chars": 1524,
    "preview": "[package]\nname = \"actix-files\"\nversion = \"0.6.10\"\nauthors = [\"Nikolay Kim <fafhrd91@gmail.com>\", \"Rob Ede <robjtede@iclo"
  },
  {
    "path": "actix-files/README.md",
    "chars": 1081,
    "preview": "# `actix-files`\n\n<!-- prettier-ignore-start -->\n\n[![crates.io](https://img.shields.io/crates/v/actix-files?label=latest)"
  },
  {
    "path": "actix-files/examples/guarded-listing.rs",
    "chars": 955,
    "preview": "use actix_files::Files;\nuse actix_web::{get, guard, middleware, App, HttpServer, Responder};\n\nconst EXAMPLES_DIR: &str ="
  },
  {
    "path": "actix-files/src/chunked.rs",
    "chars": 7018,
    "preview": "use std::{\n    cmp, fmt,\n    future::Future,\n    io,\n    pin::Pin,\n    task::{Context, Poll},\n};\n\nuse actix_web::{error:"
  },
  {
    "path": "actix-files/src/directory.rs",
    "chars": 3518,
    "preview": "use std::{\n    fmt::Write,\n    fs::DirEntry,\n    io,\n    path::{Path, PathBuf},\n};\n\nuse actix_web::{dev::ServiceResponse"
  },
  {
    "path": "actix-files/src/encoding.rs",
    "chars": 1213,
    "preview": "use mime::Mime;\n\n/// Transforms MIME `text/*` types into their UTF-8 equivalent, if supported.\n///\n/// MIME types that a"
  },
  {
    "path": "actix-files/src/error.rs",
    "chars": 1514,
    "preview": "use actix_web::{http::StatusCode, ResponseError};\nuse derive_more::Display;\n\n/// Errors which can occur when serving sta"
  },
  {
    "path": "actix-files/src/files.rs",
    "chars": 16805,
    "preview": "use std::{\n    cell::RefCell,\n    fmt, io,\n    path::{Path, PathBuf},\n    rc::Rc,\n};\n\nuse actix_service::{boxed, IntoSer"
  },
  {
    "path": "actix-files/src/lib.rs",
    "chars": 38163,
    "preview": "//! Static file serving for Actix Web.\n//!\n//! Provides a non-blocking service for serving static files from disk.\n//!\n/"
  },
  {
    "path": "actix-files/src/named.rs",
    "chars": 23201,
    "preview": "use std::{\n    fs::Metadata,\n    io,\n    path::{Path, PathBuf},\n    time::{SystemTime, UNIX_EPOCH},\n};\n\nuse actix_web::{"
  },
  {
    "path": "actix-files/src/path_buf.rs",
    "chars": 7446,
    "preview": "use std::{\n    path::{Component, Path, PathBuf},\n    str::FromStr,\n};\n\nuse actix_utils::future::{ready, Ready};\nuse acti"
  },
  {
    "path": "actix-files/src/range.rs",
    "chars": 9191,
    "preview": "use std::fmt;\n\nuse derive_more::Error;\n\n/// Copy of `http_range::HttpRangeParseError`.\n#[derive(Debug, Clone)]\nenum Http"
  },
  {
    "path": "actix-files/src/service.rs",
    "chars": 11800,
    "preview": "use std::{\n    fmt, io,\n    ops::Deref,\n    path::{Path, PathBuf},\n    rc::Rc,\n};\n\nuse actix_web::{\n    body::BoxBody,\n "
  },
  {
    "path": "actix-files/tests/encoding.rs",
    "chars": 6708,
    "preview": "use actix_files::{Files, NamedFile};\nuse actix_web::{\n    http::{\n        header::{self, HeaderValue},\n        StatusCod"
  },
  {
    "path": "actix-files/tests/fixtures/guards/first/index.txt",
    "chars": 5,
    "preview": "first"
  },
  {
    "path": "actix-files/tests/fixtures/guards/second/index.txt",
    "chars": 6,
    "preview": "second"
  },
  {
    "path": "actix-files/tests/guard.rs",
    "chars": 1030,
    "preview": "use actix_files::Files;\nuse actix_web::{\n    guard::Host,\n    http::StatusCode,\n    test::{self, TestRequest},\n    App,\n"
  },
  {
    "path": "actix-files/tests/pre_epoch_mtime.rs",
    "chars": 1497,
    "preview": "use std::time::UNIX_EPOCH;\n\nuse actix_files::NamedFile;\nuse actix_web::{\n    http::{header, StatusCode},\n    test, web, "
  },
  {
    "path": "actix-files/tests/test space.binary",
    "chars": 56,
    "preview": "TǑɂV2vI\\R˙e\u0004vD:藽R\u0010V\u0003Yp\u001f;\u0007Gp!2C.\fpA\u000b\u0010!ߦx\tj+UcX\u0013c%\u0017;\"y\u0010AI"
  },
  {
    "path": "actix-files/tests/test.binary",
    "chars": 56,
    "preview": "TǑɂV2vI\\R˙e\u0004vD:藽R\u0010V\u0003Yp\u001f;\u0007Gp!2C.\fpA\u000b\u0010!ߦx\tj+UcX\u0013c%\u0017;\"y\u0010AI"
  },
  {
    "path": "actix-files/tests/test.js",
    "chars": 23,
    "preview": "// this file is empty.\n"
  },
  {
    "path": "actix-files/tests/traversal.rs",
    "chars": 904,
    "preview": "use actix_files::Files;\nuse actix_web::{\n    http::StatusCode,\n    test::{self, TestRequest},\n    App,\n};\n\n#[actix_rt::t"
  },
  {
    "path": "actix-files/tests/utf8.txt",
    "chars": 26,
    "preview": "中文内容显示正确。\n\nEnglish is OK.\n"
  },
  {
    "path": "actix-http/CHANGES.md",
    "chars": 52117,
    "preview": "# Changes\n\n## Unreleased\n\n- Encode the HTTP/1 `Connection: Upgrade` header in Camel-Case when camel-case header formatti"
  },
  {
    "path": "actix-http/Cargo.toml",
    "chars": 4774,
    "preview": "[package]\nname = \"actix-http\"\nversion = \"3.12.0\"\nauthors = [\"Nikolay Kim <fafhrd91@gmail.com>\", \"Rob Ede <robjtede@iclou"
  },
  {
    "path": "actix-http/README.md",
    "chars": 1701,
    "preview": "# `actix-http`\n\n> HTTP types and services for the Actix ecosystem.\n\n<!-- prettier-ignore-start -->\n\n[![crates.io](https:"
  },
  {
    "path": "actix-http/benches/date-formatting.rs",
    "chars": 401,
    "preview": "use std::time::SystemTime;\n\nuse actix_http::header::HttpDate;\nuse divan::{black_box, AllocProfiler, Bencher};\n\n#[global_"
  },
  {
    "path": "actix-http/benches/response-body-compression.rs",
    "chars": 2833,
    "preview": "use std::convert::Infallible;\n\nuse actix_http::{encoding::Encoder, ContentEncoding, Request, Response, StatusCode};\nuse "
  },
  {
    "path": "actix-http/examples/actix-web.rs",
    "chars": 835,
    "preview": "use actix_http::HttpService;\nuse actix_server::Server;\nuse actix_service::map_config;\nuse actix_web::{dev::AppConfig, ge"
  },
  {
    "path": "actix-http/examples/bench.rs",
    "chars": 928,
    "preview": "use std::{convert::Infallible, io, time::Duration};\n\nuse actix_http::{HttpService, Request, Response, StatusCode};\nuse a"
  },
  {
    "path": "actix-http/examples/echo.rs",
    "chars": 1290,
    "preview": "use std::{io, time::Duration};\n\nuse actix_http::{Error, HttpService, Request, Response, StatusCode};\nuse actix_server::S"
  },
  {
    "path": "actix-http/examples/echo2.rs",
    "chars": 987,
    "preview": "use std::io;\n\nuse actix_http::{\n    body::{BodyStream, MessageBody},\n    header, Error, HttpMessage, HttpService, Reques"
  },
  {
    "path": "actix-http/examples/h2c-detect.rs",
    "chars": 1173,
    "preview": "//! An example that supports automatic selection of plaintext h1/h2c connections.\n//!\n//! Notably, both the following co"
  },
  {
    "path": "actix-http/examples/h2spec.rs",
    "chars": 739,
    "preview": "use std::{convert::Infallible, io};\n\nuse actix_http::{HttpService, Request, Response, StatusCode};\nuse actix_server::Ser"
  },
  {
    "path": "actix-http/examples/hello-world.rs",
    "chars": 1244,
    "preview": "use std::{convert::Infallible, io, time::Duration};\n\nuse actix_http::{header::HeaderValue, HttpService, Request, Respons"
  },
  {
    "path": "actix-http/examples/streaming-error.rs",
    "chars": 1212,
    "preview": "//! Example showing response body (chunked) stream erroring.\n//!\n//! Test using `nc` or `curl`.\n//! ```sh\n//! $ curl -vN"
  },
  {
    "path": "actix-http/examples/tls_rustls.rs",
    "chars": 1894,
    "preview": "//! Demonstrates TLS configuration (via Rustls) for HTTP/1.1 and HTTP/2 connections.\n//!\n//! Test using cURL:\n//!\n//! ``"
  },
  {
    "path": "actix-http/examples/ws.rs",
    "chars": 2749,
    "preview": "//! Sets up a WebSocket server over TCP and TLS.\n//! Sends a heartbeat message every 4 seconds but does not respond to a"
  },
  {
    "path": "actix-http/src/body/body_stream.rs",
    "chars": 6473,
    "preview": "use std::{\n    error::Error as StdError,\n    pin::Pin,\n    task::{Context, Poll},\n};\n\nuse bytes::Bytes;\nuse futures_core"
  },
  {
    "path": "actix-http/src/body/boxed.rs",
    "chars": 3387,
    "preview": "use std::{\n    error::Error as StdError,\n    fmt,\n    pin::Pin,\n    task::{Context, Poll},\n};\n\nuse bytes::Bytes;\n\nuse su"
  },
  {
    "path": "actix-http/src/body/either.rs",
    "chars": 3524,
    "preview": "use std::{\n    pin::Pin,\n    task::{Context, Poll},\n};\n\nuse bytes::Bytes;\nuse pin_project_lite::pin_project;\n\nuse super:"
  },
  {
    "path": "actix-http/src/body/message_body.rs",
    "chars": 21359,
    "preview": "//! [`MessageBody`] trait and foreign implementations.\n\nuse std::{\n    convert::Infallible,\n    error::Error as StdError"
  },
  {
    "path": "actix-http/src/body/mod.rs",
    "chars": 737,
    "preview": "//! Traits and structures to aid consuming and writing HTTP payloads.\n//!\n//! \"Body\" and \"payload\" are used somewhat int"
  },
  {
    "path": "actix-http/src/body/none.rs",
    "chars": 1176,
    "preview": "use std::{\n    convert::Infallible,\n    pin::Pin,\n    task::{Context, Poll},\n};\n\nuse bytes::Bytes;\n\nuse super::{BodySize"
  },
  {
    "path": "actix-http/src/body/size.rs",
    "chars": 1297,
    "preview": "/// Body size hint.\n#[derive(Debug, Clone, Copy, PartialEq, Eq)]\npub enum BodySize {\n    /// Implicitly empty body.\n    "
  },
  {
    "path": "actix-http/src/body/sized_stream.rs",
    "chars": 4925,
    "preview": "use std::{\n    error::Error as StdError,\n    pin::Pin,\n    task::{Context, Poll},\n};\n\nuse bytes::Bytes;\nuse futures_core"
  },
  {
    "path": "actix-http/src/body/utils.rs",
    "chars": 6442,
    "preview": "use std::task::Poll;\n\nuse actix_rt::pin;\nuse actix_utils::future::poll_fn;\nuse bytes::{Bytes, BytesMut};\nuse derive_more"
  },
  {
    "path": "actix-http/src/builder.rs",
    "chars": 12236,
    "preview": "use std::{fmt, marker::PhantomData, net, rc::Rc, time::Duration};\n\nuse actix_codec::Framed;\nuse actix_service::{IntoServ"
  },
  {
    "path": "actix-http/src/config.rs",
    "chars": 12438,
    "preview": "use std::{\n    net::SocketAddr,\n    rc::Rc,\n    time::{Duration, Instant},\n};\n\nuse bytes::BytesMut;\n\nuse crate::{date::D"
  },
  {
    "path": "actix-http/src/date.rs",
    "chars": 2457,
    "preview": "use std::{\n    cell::Cell,\n    fmt::{self, Write},\n    rc::Rc,\n    time::{Duration, Instant, SystemTime},\n};\n\nuse actix_"
  },
  {
    "path": "actix-http/src/encoding/decoder.rs",
    "chars": 9496,
    "preview": "//! Stream decoders.\n\nuse std::{\n    future::Future,\n    io::{self, Write as _},\n    pin::Pin,\n    task::{Context, Poll}"
  },
  {
    "path": "actix-http/src/encoding/encoder.rs",
    "chars": 13159,
    "preview": "//! Stream encoders.\n\nuse std::{\n    error::Error as StdError,\n    future::Future,\n    io::{self, Write as _},\n    pin::"
  },
  {
    "path": "actix-http/src/encoding/mod.rs",
    "chars": 715,
    "preview": "//! Content-Encoding support.\n\nuse std::io;\n\nuse bytes::{Bytes, BytesMut};\n\nmod decoder;\nmod encoder;\n\npub use self::{de"
  },
  {
    "path": "actix-http/src/error.rs",
    "chars": 13144,
    "preview": "//! Error and Result module\n\nuse std::{error::Error as StdError, fmt, io, str::Utf8Error, string::FromUtf8Error};\n\nuse d"
  },
  {
    "path": "actix-http/src/extensions.rs",
    "chars": 9724,
    "preview": "use std::{\n    any::{Any, TypeId},\n    collections::HashMap,\n    fmt,\n    hash::{BuildHasherDefault, Hasher},\n};\n\n/// A "
  },
  {
    "path": "actix-http/src/h1/chunked.rs",
    "chars": 13948,
    "preview": "use std::{io, task::Poll};\n\nuse bytes::{Buf as _, Bytes, BytesMut};\nuse tracing::{debug, trace};\n\nmacro_rules! byte (\n  "
  },
  {
    "path": "actix-http/src/h1/client.rs",
    "chars": 7003,
    "preview": "use std::{fmt, io};\n\nuse bitflags::bitflags;\nuse bytes::{Bytes, BytesMut};\nuse http::{Method, Version};\nuse tokio_util::"
  },
  {
    "path": "actix-http/src/h1/codec.rs",
    "chars": 6870,
    "preview": "use std::{fmt, io};\n\nuse bitflags::bitflags;\nuse bytes::BytesMut;\nuse http::{Method, Version};\nuse tokio_util::codec::{D"
  },
  {
    "path": "actix-http/src/h1/decoder.rs",
    "chars": 38751,
    "preview": "use std::{io, marker::PhantomData, mem::MaybeUninit, task::Poll};\n\nuse actix_codec::Decoder;\nuse bytes::{Bytes, BytesMut"
  },
  {
    "path": "actix-http/src/h1/dispatcher.rs",
    "chars": 50729,
    "preview": "use std::{\n    collections::VecDeque,\n    fmt,\n    future::Future,\n    io, mem, net,\n    pin::Pin,\n    rc::Rc,\n    task:"
  },
  {
    "path": "actix-http/src/h1/dispatcher_tests.rs",
    "chars": 34754,
    "preview": "use std::{\n    future::Future,\n    pin::Pin,\n    str,\n    task::{Context, Poll},\n    time::Duration,\n};\n\nuse actix_codec"
  },
  {
    "path": "actix-http/src/h1/encoder.rs",
    "chars": 21763,
    "preview": "use std::{\n    cmp,\n    io::{self, Write as _},\n    marker::PhantomData,\n    ptr::copy_nonoverlapping,\n    slice::from_r"
  },
  {
    "path": "actix-http/src/h1/expect.rs",
    "chars": 878,
    "preview": "use actix_service::{Service, ServiceFactory};\nuse actix_utils::future::{ready, Ready};\n\nuse crate::{Error, Request};\n\npu"
  },
  {
    "path": "actix-http/src/h1/mod.rs",
    "chars": 1764,
    "preview": "//! HTTP/1 protocol implementation.\n\nuse bytes::{Bytes, BytesMut};\n\nmod chunked;\nmod client;\nmod codec;\nmod decoder;\nmod"
  },
  {
    "path": "actix-http/src/h1/payload.rs",
    "chars": 9233,
    "preview": "//! Payload stream\n\nuse std::{\n    cell::RefCell,\n    collections::VecDeque,\n    pin::Pin,\n    rc::{Rc, Weak},\n    task:"
  },
  {
    "path": "actix-http/src/h1/service.rs",
    "chars": 16287,
    "preview": "use std::{\n    fmt,\n    marker::PhantomData,\n    net,\n    rc::Rc,\n    task::{Context, Poll},\n};\n\nuse actix_codec::{Async"
  },
  {
    "path": "actix-http/src/h1/timer.rs",
    "chars": 2268,
    "preview": "use std::{fmt, future::Future, pin::Pin, task::Context};\n\nuse actix_rt::time::{Instant, Sleep};\nuse tracing::trace;\n\n#[d"
  },
  {
    "path": "actix-http/src/h1/upgrade.rs",
    "chars": 892,
    "preview": "use actix_codec::Framed;\nuse actix_service::{Service, ServiceFactory};\nuse futures_core::future::LocalBoxFuture;\n\nuse cr"
  },
  {
    "path": "actix-http/src/h1/utils.rs",
    "chars": 4108,
    "preview": "use std::{\n    future::Future,\n    pin::Pin,\n    task::{Context, Poll},\n};\n\nuse actix_codec::{AsyncRead, AsyncWrite, Fra"
  },
  {
    "path": "actix-http/src/h2/dispatcher.rs",
    "chars": 11751,
    "preview": "use std::{\n    cmp,\n    error::Error as StdError,\n    future::Future,\n    marker::PhantomData,\n    net,\n    pin::{pin, P"
  },
  {
    "path": "actix-http/src/h2/mod.rs",
    "chars": 3021,
    "preview": "//! HTTP/2 protocol.\n\nuse std::{\n    future::Future,\n    pin::Pin,\n    task::{Context, Poll},\n};\n\nuse actix_codec::{Asyn"
  },
  {
    "path": "actix-http/src/h2/service.rs",
    "chars": 16827,
    "preview": "use std::{\n    future::Future,\n    marker::PhantomData,\n    mem, net,\n    pin::Pin,\n    rc::Rc,\n    task::{Context, Poll"
  },
  {
    "path": "actix-http/src/header/as_name.rs",
    "chars": 1522,
    "preview": "//! Sealed [`AsHeaderName`] trait and implementations.\n\nuse std::{borrow::Cow, str::FromStr as _};\n\nuse http::header::{H"
  },
  {
    "path": "actix-http/src/header/common.rs",
    "chars": 3157,
    "preview": "//! Common header names not defined in [`http`].\n//!\n//! Any headers added to this file will need to be re-exported from"
  },
  {
    "path": "actix-http/src/header/into_pair.rs",
    "chars": 3340,
    "preview": "//! [`TryIntoHeaderPair`] trait and implementations.\n\nuse super::{\n    Header, HeaderName, HeaderValue, InvalidHeaderNam"
  },
  {
    "path": "actix-http/src/header/into_value.rs",
    "chars": 3112,
    "preview": "//! [`TryIntoHeaderValue`] trait and implementations.\n\nuse bytes::Bytes;\nuse http::{header::InvalidHeaderValue, Error as"
  },
  {
    "path": "actix-http/src/header/map.rs",
    "chars": 40218,
    "preview": "//! A multi-value [`HeaderMap`] and its iterators.\n\nuse std::{borrow::Cow, collections::hash_map, iter, ops};\n\nuse foldh"
  },
  {
    "path": "actix-http/src/header/mod.rs",
    "chars": 3544,
    "preview": "//! Pre-defined `HeaderName`s, traits for parsing and conversion, and other header utility methods.\n\n// declaring new he"
  },
  {
    "path": "actix-http/src/header/shared/charset.rs",
    "chars": 4113,
    "preview": "use std::{fmt, str};\n\nuse self::Charset::*;\n\n/// A MIME character set.\n///\n/// The string representation is normalized t"
  },
  {
    "path": "actix-http/src/header/shared/content_encoding.rs",
    "chars": 3523,
    "preview": "use std::str::FromStr;\n\nuse derive_more::{Display, Error};\nuse http::header::InvalidHeaderValue;\n\nuse crate::{\n    error"
  },
  {
    "path": "actix-http/src/header/shared/extended.rs",
    "chars": 7065,
    "preview": "//! Originally taken from `hyper::header::parsing`.\n\nuse std::{fmt, str::FromStr};\n\nuse language_tags::LanguageTag;\n\nuse"
  },
  {
    "path": "actix-http/src/header/shared/http_date.rs",
    "chars": 2300,
    "preview": "use std::{fmt, io::Write, str::FromStr, time::SystemTime};\n\nuse bytes::BytesMut;\nuse http::header::{HeaderValue, Invalid"
  },
  {
    "path": "actix-http/src/header/shared/mod.rs",
    "chars": 401,
    "preview": "//! Originally taken from `hyper::header::shared`.\n\npub use language_tags::LanguageTag;\n\nmod charset;\nmod content_encodi"
  },
  {
    "path": "actix-http/src/header/shared/quality.rs",
    "chars": 6621,
    "preview": "use std::fmt;\n\nuse derive_more::{Display, Error};\n\nconst MAX_QUALITY_INT: u16 = 1000;\nconst MAX_QUALITY_FLOAT: f32 = 1.0"
  },
  {
    "path": "actix-http/src/header/shared/quality_item.rs",
    "chars": 9227,
    "preview": "use std::{cmp, fmt, str};\n\nuse super::Quality;\nuse crate::error::ParseError;\n\n/// Represents an item with a quality valu"
  },
  {
    "path": "actix-http/src/header/utils.rs",
    "chars": 2827,
    "preview": "//! Header parsing utilities.\n\nuse std::{fmt, str::FromStr};\n\nuse super::HeaderValue;\nuse crate::{error::ParseError, hea"
  },
  {
    "path": "actix-http/src/helpers.rs",
    "chars": 6633,
    "preview": "use std::io;\n\nuse bytes::BufMut;\nuse http::Version;\n\nconst DIGITS_START: u8 = b'0';\n\npub(crate) fn write_status_line<B: "
  },
  {
    "path": "actix-http/src/http_message.rs",
    "chars": 7059,
    "preview": "use std::{\n    cell::{Ref, RefMut},\n    str,\n};\n\nuse encoding_rs::{Encoding, UTF_8};\nuse http::header;\nuse mime::Mime;\n\n"
  },
  {
    "path": "actix-http/src/keep_alive.rs",
    "chars": 2069,
    "preview": "use std::time::Duration;\n\n/// Connection keep-alive config.\n#[derive(Debug, Clone, Copy, PartialEq, Eq)]\npub enum KeepAl"
  },
  {
    "path": "actix-http/src/lib.rs",
    "chars": 3351,
    "preview": "//! HTTP types and services for the Actix ecosystem.\n//!\n//! ## Crate Features\n//!\n//! | Feature             | Functiona"
  },
  {
    "path": "actix-http/src/message.rs",
    "chars": 2680,
    "preview": "use std::{cell::RefCell, ops, rc::Rc};\n\nuse bitflags::bitflags;\n\n/// Represents various types of connection\n#[derive(Deb"
  },
  {
    "path": "actix-http/src/notify_on_drop.rs",
    "chars": 1297,
    "preview": "/// Test Module for checking the drop state of certain async tasks that are spawned\n/// with `actix_rt::spawn`\n///\n/// T"
  },
  {
    "path": "actix-http/src/payload.rs",
    "chars": 3060,
    "preview": "use std::{\n    mem,\n    pin::Pin,\n    task::{Context, Poll},\n};\n\nuse bytes::Bytes;\nuse futures_core::Stream;\nuse pin_pro"
  },
  {
    "path": "actix-http/src/requests/head.rs",
    "chars": 4555,
    "preview": "use std::{net, rc::Rc};\n\nuse crate::{\n    header::{self, HeaderMap},\n    message::{Flags, Head, MessagePool},\n    Connec"
  },
  {
    "path": "actix-http/src/requests/mod.rs",
    "chars": 127,
    "preview": "//! HTTP requests.\n\nmod head;\nmod request;\n\npub use self::{\n    head::{RequestHead, RequestHeadType},\n    request::Reque"
  },
  {
    "path": "actix-http/src/requests/request.rs",
    "chars": 6704,
    "preview": "//! HTTP requests.\n\nuse std::{\n    cell::{Ref, RefCell, RefMut},\n    fmt, mem, net,\n    rc::Rc,\n    str,\n};\n\nuse http::{"
  },
  {
    "path": "actix-http/src/responses/builder.rs",
    "chars": 13059,
    "preview": "//! HTTP response builder.\n\nuse std::{cell::RefCell, fmt, str};\n\nuse crate::{\n    body::{EitherBody, MessageBody},\n    e"
  },
  {
    "path": "actix-http/src/responses/head.rs",
    "chars": 7862,
    "preview": "//! Response head type and caching pool.\n\nuse std::{cell::RefCell, ops};\n\nuse crate::{header::HeaderMap, message::Flags,"
  },
  {
    "path": "actix-http/src/responses/mod.rs",
    "chars": 221,
    "preview": "//! HTTP response.\n\nmod builder;\nmod head;\n#[allow(clippy::module_inception)]\nmod response;\n\npub(crate) use self::head::"
  },
  {
    "path": "actix-http/src/responses/response.rs",
    "chars": 13059,
    "preview": "//! HTTP response.\n\nuse std::{\n    cell::{Ref, RefCell, RefMut},\n    fmt, str,\n};\n\nuse bytes::{Bytes, BytesMut};\nuse byt"
  },
  {
    "path": "actix-http/src/service.rs",
    "chars": 36583,
    "preview": "use std::{\n    fmt,\n    future::Future,\n    marker::PhantomData,\n    net,\n    pin::Pin,\n    rc::Rc,\n    task::{Context, "
  },
  {
    "path": "actix-http/src/test.rs",
    "chars": 11204,
    "preview": "//! Various testing helpers for use in internal and app tests.\n\nuse std::{\n    cell::{Ref, RefCell, RefMut},\n    io::{se"
  },
  {
    "path": "actix-http/src/ws/codec.rs",
    "chars": 10166,
    "preview": "use bitflags::bitflags;\nuse bytes::{Bytes, BytesMut};\nuse bytestring::ByteString;\nuse tokio_util::codec::{Decoder, Encod"
  },
  {
    "path": "actix-http/src/ws/dispatcher.rs",
    "chars": 14264,
    "preview": "use std::{\n    future::Future,\n    pin::Pin,\n    task::{Context, Poll},\n};\n\nuse actix_codec::{AsyncRead, AsyncWrite, Fra"
  },
  {
    "path": "actix-http/src/ws/frame.rs",
    "chars": 12852,
    "preview": "use std::cmp::min;\n\nuse bytes::{Buf, BufMut, BytesMut};\nuse tracing::debug;\n\nuse super::{\n    mask::apply_mask,\n    prot"
  },
  {
    "path": "actix-http/src/ws/mask.rs",
    "chars": 2229,
    "preview": "//! This is code from [Tungstenite project](https://github.com/snapview/tungstenite-rs)\n\n/// Mask/unmask a frame.\n#[inli"
  },
  {
    "path": "actix-http/src/ws/mod.rs",
    "chars": 11166,
    "preview": "//! WebSocket protocol implementation.\n//!\n//! To setup a WebSocket, first perform the WebSocket handshake then on succe"
  },
  {
    "path": "actix-http/src/ws/proto.rs",
    "chars": 11245,
    "preview": "use std::fmt;\n\nuse base64::prelude::*;\nuse tracing::error;\n\n/// Operation codes defined in [RFC 6455 §11.8].\n///\n/// [RF"
  },
  {
    "path": "actix-http/tests/test.binary",
    "chars": 56,
    "preview": "TǑɂV2vI\\R˙e\u0004vD:藽R\u0010V\u0003Yp\u001f;\u0007Gp!2C.\fpA\u000b\u0010!ߦx\tj+UcX\u0013c%\u0017;\"y\u0010AI"
  },
  {
    "path": "actix-http/tests/test_client.rs",
    "chars": 5763,
    "preview": "use std::convert::Infallible;\n\nuse actix_http::{body::BoxBody, HttpMessage, HttpService, Request, Response, StatusCode};"
  },
  {
    "path": "actix-http/tests/test_h2_timer.rs",
    "chars": 5037,
    "preview": "use std::{io, time::Duration};\n\nuse actix_http::{error::Error, HttpService, Response};\nuse actix_server::Server;\nuse tok"
  },
  {
    "path": "actix-http/tests/test_openssl.rs",
    "chars": 15497,
    "preview": "#![cfg(feature = \"openssl\")]\n\nextern crate tls_openssl as openssl;\n\nuse std::{convert::Infallible, io, time::Duration};\n"
  },
  {
    "path": "actix-http/tests/test_rustls.rs",
    "chars": 22758,
    "preview": "#![cfg(feature = \"rustls-0_23\")]\n\nextern crate tls_openssl as openssl;\nextern crate tls_rustls_023 as rustls;\n\nuse std::"
  },
  {
    "path": "actix-http/tests/test_server.rs",
    "chars": 32919,
    "preview": "use std::{\n    convert::Infallible,\n    io::{Read, Write},\n    net, thread,\n    time::{Duration, Instant},\n};\n\nuse actix"
  },
  {
    "path": "actix-http/tests/test_ws.rs",
    "chars": 5433,
    "preview": "use std::{\n    cell::Cell,\n    convert::Infallible,\n    task::{Context, Poll},\n};\n\nuse actix_codec::{AsyncRead, AsyncWri"
  },
  {
    "path": "actix-http-test/CHANGES.md",
    "chars": 3512,
    "preview": "# Changes\n\n## Unreleased\n\n- Minimum supported Rust version (MSRV) is now 1.88.\n\n## 3.2.0\n\n- Minimum supported Rust versi"
  },
  {
    "path": "actix-http-test/Cargo.toml",
    "chars": 1373,
    "preview": "[package]\nname = \"actix-http-test\"\nversion = \"3.2.0\"\nauthors = [\"Nikolay Kim <fafhrd91@gmail.com>\"]\ndescription = \"Vario"
  },
  {
    "path": "actix-http-test/README.md",
    "chars": 940,
    "preview": "# `actix-http-test`\n\n<!-- prettier-ignore-start -->\n\n[![crates.io](https://img.shields.io/crates/v/actix-http-test?label"
  },
  {
    "path": "actix-http-test/src/lib.rs",
    "chars": 10008,
    "preview": "//! Various helpers for Actix applications to use during testing.\n\n#![doc(html_logo_url = \"https://actix.rs/img/logo.png"
  },
  {
    "path": "actix-multipart/CHANGES.md",
    "chars": 4111,
    "preview": "# Changes\n\n## Unreleased\n\n- Add `MultipartForm` support for `Option<Vec<T>>` fields. [#3577]\n- Minimum supported Rust ve"
  },
  {
    "path": "actix-multipart/Cargo.toml",
    "chars": 1894,
    "preview": "[package]\nname = \"actix-multipart\"\nversion = \"0.7.2\"\nauthors = [\n  \"Nikolay Kim <fafhrd91@gmail.com>\",\n  \"Jacob Halsey <"
  },
  {
    "path": "actix-multipart/README.md",
    "chars": 3027,
    "preview": "# `actix-multipart`\n\n<!-- prettier-ignore-start -->\n\n[![crates.io](https://img.shields.io/crates/v/actix-multipart?label"
  },
  {
    "path": "actix-multipart/examples/form.rs",
    "chars": 1299,
    "preview": "use actix_multipart::form::{\n    json::Json as MpJson, tempfile::TempFile, MultipartForm, MultipartFormConfig,\n};\nuse ac"
  },
  {
    "path": "actix-multipart/src/error.rs",
    "chars": 3856,
    "preview": "//! Error and Result module\n\nuse actix_web::{\n    error::{ParseError, PayloadError},\n    http::StatusCode,\n    ResponseE"
  },
  {
    "path": "actix-multipart/src/extractor.rs",
    "chars": 1140,
    "preview": "use actix_utils::future::{ready, Ready};\nuse actix_web::{dev::Payload, Error, FromRequest, HttpRequest};\n\nuse crate::mul"
  },
  {
    "path": "actix-multipart/src/field.rs",
    "chars": 16633,
    "preview": "use std::{\n    cell::RefCell,\n    cmp, fmt,\n    future::poll_fn,\n    mem,\n    pin::Pin,\n    rc::Rc,\n    task::{ready, Co"
  },
  {
    "path": "actix-multipart/src/form/bytes.rs",
    "chars": 1452,
    "preview": "//! Reads a field into memory.\n\nuse actix_web::{web::BytesMut, HttpRequest};\nuse futures_core::future::LocalBoxFuture;\nu"
  },
  {
    "path": "actix-multipart/src/form/json.rs",
    "chars": 6375,
    "preview": "//! Deserializes a field as JSON.\n\nuse std::sync::Arc;\n\nuse actix_web::{http::StatusCode, web, Error, HttpRequest, Respo"
  },
  {
    "path": "actix-multipart/src/form/mod.rs",
    "chars": 30355,
    "preview": "//! Extract and process typed data from fields of a `multipart/form-data` request.\n\nuse std::{\n    any::Any,\n    collect"
  },
  {
    "path": "actix-multipart/src/form/tempfile.rs",
    "chars": 5997,
    "preview": "//! Writes a field to a temporary file on disk.\n\nuse std::{\n    io,\n    path::{Path, PathBuf},\n    sync::Arc,\n};\n\nuse ac"
  },
  {
    "path": "actix-multipart/src/form/text.rs",
    "chars": 6115,
    "preview": "//! Deserializes a field from plain text.\n\nuse std::{str, sync::Arc};\n\nuse actix_web::{http::StatusCode, web, Error, Htt"
  },
  {
    "path": "actix-multipart/src/lib.rs",
    "chars": 2577,
    "preview": "//! Multipart request & form support for Actix Web.\n//!\n//! The [`Multipart`] extractor aims to support all kinds of `mu"
  },
  {
    "path": "actix-multipart/src/multipart.rs",
    "chars": 29847,
    "preview": "//! Multipart response payload support.\n\nuse std::{\n    cell::RefCell,\n    pin::Pin,\n    rc::Rc,\n    task::{Context, Pol"
  },
  {
    "path": "actix-multipart/src/payload.rs",
    "chars": 7911,
    "preview": "use std::{\n    cell::{RefCell, RefMut},\n    cmp, mem,\n    pin::Pin,\n    rc::Rc,\n    task::{Context, Poll},\n};\n\nuse actix"
  },
  {
    "path": "actix-multipart/src/safety.rs",
    "chars": 1721,
    "preview": "use std::{cell::Cell, marker::PhantomData, rc::Rc, task};\n\nuse local_waker::LocalWaker;\n\n/// Counter. It tracks of numbe"
  },
  {
    "path": "actix-multipart/src/test.rs",
    "chars": 6208,
    "preview": "//! Multipart testing utilities.\n\nuse actix_web::{\n    http::header::{self, HeaderMap},\n    web::{BufMut as _, Bytes, By"
  },
  {
    "path": "actix-multipart-derive/CHANGES.md",
    "chars": 324,
    "preview": "# Changes\n\n## Unreleased\n\n- Minimum supported Rust version (MSRV) is now 1.88.\n\n## 0.7.0\n\n- Minimum supported Rust versi"
  },
  {
    "path": "actix-multipart-derive/Cargo.toml",
    "chars": 648,
    "preview": "[package]\nname = \"actix-multipart-derive\"\nversion = \"0.7.0\"\nauthors = [\"Jacob Halsey <jacob@jhalsey.com>\"]\ndescription ="
  },
  {
    "path": "actix-multipart-derive/README.md",
    "chars": 964,
    "preview": "# `actix-multipart-derive`\n\n> The derive macro implementation for actix-multipart-derive.\n\n<!-- prettier-ignore-start --"
  },
  {
    "path": "actix-multipart-derive/src/lib.rs",
    "chars": 9832,
    "preview": "//! Multipart form derive macro for Actix Web.\n//!\n//! See [`macro@MultipartForm`] for usage examples.\n\n#![doc(html_logo"
  },
  {
    "path": "actix-multipart-derive/tests/trybuild/all-required.rs",
    "chars": 433,
    "preview": "use actix_web::{web, App, Responder};\n\nuse actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm};\n\n#[de"
  },
  {
    "path": "actix-multipart-derive/tests/trybuild/deny-duplicates.rs",
    "chars": 338,
    "preview": "use actix_web::{web, App, Responder};\n\nuse actix_multipart::form::MultipartForm;\n\n#[derive(MultipartForm)]\n#[multipart(d"
  },
  {
    "path": "actix-multipart-derive/tests/trybuild/deny-parse-fail.rs",
    "chars": 134,
    "preview": "use actix_multipart::form::MultipartForm;\n\n#[derive(MultipartForm)]\n#[multipart(duplicate_field = \"no\")]\nstruct Form {}\n"
  },
  {
    "path": "actix-multipart-derive/tests/trybuild/deny-parse-fail.stderr",
    "chars": 162,
    "preview": "error: Unknown literal value `no`\n --> tests/trybuild/deny-parse-fail.rs:4:31\n  |\n4 | #[multipart(duplicate_field = \"no\""
  },
  {
    "path": "actix-multipart-derive/tests/trybuild/deny-unknown.rs",
    "chars": 333,
    "preview": "use actix_web::{web, App, Responder};\n\nuse actix_multipart::form::MultipartForm;\n\n#[derive(MultipartForm)]\n#[multipart(d"
  },
  {
    "path": "actix-multipart-derive/tests/trybuild/optional-and-list.rs",
    "chars": 396,
    "preview": "use actix_web::{web, App, Responder};\n\nuse actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm};\n\n#[de"
  },
  {
    "path": "actix-multipart-derive/tests/trybuild/rename.rs",
    "chars": 385,
    "preview": "use actix_web::{web, App, Responder};\n\nuse actix_multipart::form::{tempfile::TempFile, MultipartForm};\n\n#[derive(Multipa"
  },
  {
    "path": "actix-multipart-derive/tests/trybuild/size-limit-parse-fail.rs",
    "chars": 407,
    "preview": "use actix_multipart::form::{text::Text, MultipartForm};\n\n#[derive(MultipartForm)]\nstruct Form {\n    #[multipart(limit = "
  },
  {
    "path": "actix-multipart-derive/tests/trybuild/size-limit-parse-fail.stderr",
    "chars": 716,
    "preview": "error: Could not parse size limit `2 bytes`: couldn't parse \"bytes\" into a known SI unit, Failed to parse unit \"byt...\"\n"
  },
  {
    "path": "actix-multipart-derive/tests/trybuild/size-limits.rs",
    "chars": 462,
    "preview": "use actix_web::{web, App, Responder};\n\nuse actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm};\n\n#[de"
  },
  {
    "path": "actix-multipart-derive/tests/trybuild.rs",
    "chars": 498,
    "preview": "#[rustversion_msrv::msrv]\n#[test]\nfn compile_macros() {\n    let t = trybuild::TestCases::new();\n\n    t.pass(\"tests/trybu"
  },
  {
    "path": "actix-router/CHANGES.md",
    "chars": 10525,
    "preview": "# Changes\n\n## Unreleased\n\n## 0.5.4\n\n- Minimum supported Rust version (MSRV) is now 1.88.\n- Support `deserialize_any` in "
  },
  {
    "path": "actix-router/Cargo.toml",
    "chars": 1129,
    "preview": "[package]\nname = \"actix-router\"\nversion = \"0.5.4\"\nauthors = [\n  \"Nikolay Kim <fafhrd91@gmail.com>\",\n  \"Ali MJ Al-Nasrawy"
  },
  {
    "path": "actix-router/README.md",
    "chars": 889,
    "preview": "# `actix-router`\n\n<!-- prettier-ignore-start -->\n\n[![crates.io](https://img.shields.io/crates/v/actix-router?label=lates"
  },
  {
    "path": "actix-router/benches/quoter.rs",
    "chars": 1554,
    "preview": "use std::{borrow::Cow, fmt::Write as _};\n\nuse criterion::{black_box, criterion_group, criterion_main, Criterion};\n\nfn co"
  },
  {
    "path": "actix-router/benches/router.rs",
    "chars": 8883,
    "preview": "//! Based on https://github.com/ibraheemdev/matchit/blob/master/benches/bench.rs\n\nuse criterion::{black_box, criterion_g"
  },
  {
    "path": "actix-router/src/de.rs",
    "chars": 28687,
    "preview": "use std::borrow::Cow;\n\nuse serde::{\n    de::{self, Deserializer, Error as DeError, Visitor},\n    forward_to_deserialize_"
  },
  {
    "path": "actix-router/src/lib.rs",
    "chars": 625,
    "preview": "//! Resource path matching and router.\n\n#![doc(html_logo_url = \"https://actix.rs/img/logo.png\")]\n#![doc(html_favicon_url"
  },
  {
    "path": "actix-router/src/path.rs",
    "chars": 7970,
    "preview": "use std::{\n    borrow::Cow,\n    ops::{DerefMut, Index},\n};\n\nuse serde::{de, Deserialize};\n\nuse crate::{de::PathDeseriali"
  },
  {
    "path": "actix-router/src/pattern.rs",
    "chars": 2253,
    "preview": "/// One or many patterns.\n#[derive(Debug, Clone, PartialEq, Eq, Hash)]\npub enum Patterns {\n    Single(String),\n    List("
  },
  {
    "path": "actix-router/src/quoter.rs",
    "chars": 5492,
    "preview": "/// Partial percent-decoding.\n///\n/// Performs percent-decoding on a slice but can selectively skip decoding certain seq"
  },
  {
    "path": "actix-router/src/regex_set.rs",
    "chars": 1893,
    "preview": "//! Abstraction over `regex` and `regex-lite` depending on whether we have `unicode` crate feature\n//! enabled.\n\nuse cfg"
  },
  {
    "path": "actix-router/src/resource.rs",
    "chars": 63358,
    "preview": "use std::{\n    borrow::{Borrow, Cow},\n    collections::HashMap,\n    hash::{BuildHasher, Hash, Hasher},\n    mem,\n};\n\nuse "
  },
  {
    "path": "actix-router/src/resource_path.rs",
    "chars": 1104,
    "preview": "use crate::Path;\n\n/// Abstraction over types that can provide a mutable [`Path`] for routing.\n///\n/// This trait is used"
  },
  {
    "path": "actix-router/src/router.rs",
    "chars": 9848,
    "preview": "use crate::{IntoPatterns, Resource, ResourceDef};\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq)]\npub struct ResourceId(pu"
  },
  {
    "path": "actix-router/src/url.rs",
    "chars": 3992,
    "preview": "use crate::{Quoter, ResourcePath};\n\nthread_local! {\n    static DEFAULT_QUOTER: Quoter = Quoter::new(b\"\", b\"%/+\");\n}\n\n#[d"
  },
  {
    "path": "actix-test/CHANGES.md",
    "chars": 2482,
    "preview": "# Changes\n\n## Unreleased\n\n- Minimum supported Rust version (MSRV) is now 1.88.\n\n## 0.1.5\n\n- Add `TestServerConfig::liste"
  },
  {
    "path": "actix-test/Cargo.toml",
    "chars": 2425,
    "preview": "[package]\nname = \"actix-test\"\nversion = \"0.1.5\"\nauthors = [\"Nikolay Kim <fafhrd91@gmail.com>\", \"Rob Ede <robjtede@icloud"
  },
  {
    "path": "actix-test/README.md",
    "chars": 1589,
    "preview": "# `actix-test`\n\n<!-- prettier-ignore-start -->\n\n[![crates.io](https://img.shields.io/crates/v/actix-test?label=latest)]("
  },
  {
    "path": "actix-test/src/lib.rs",
    "chars": 28022,
    "preview": "//! Integration testing tools for Actix Web applications.\n//!\n//! The main integration testing tool is [`TestServer`]. I"
  },
  {
    "path": "actix-web/CHANGES.md",
    "chars": 58478,
    "preview": "# Changelog\n\n## Unreleased\n\n- Panic when calling `Route::to()` or `Route::service()` after `Route::wrap()` to prevent si"
  },
  {
    "path": "actix-web/Cargo.toml",
    "chars": 6200,
    "preview": "[package]\nname = \"actix-web\"\nversion = \"4.13.0\"\ndescription = \"Actix Web is a powerful, pragmatic, and extremely fast we"
  },
  {
    "path": "actix-web/MIGRATION-0.x.md",
    "chars": 5467,
    "preview": "# 0.7.15\n\n- The `' '` character is not percent decoded anymore before matching routes. If you need to use it in your rou"
  },
  {
    "path": "actix-web/MIGRATION-1.0.md",
    "chars": 7744,
    "preview": "## 1.0.1\n\n- Cors middleware has been moved to `actix-cors` crate\n\n  instead of\n\n  ```rust\n  use actix_web::middleware::c"
  }
]

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

About this extraction

This page contains the full source code of the actix/actix-web GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 413 files (2.8 MB), approximately 757.1k tokens, and a symbol index with 4671 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!