mirror of https://github.com/nginx/nginx
Compare commits
No commits in common. "master" and "release-1.29.0" have entirely different histories.
master
...
release-1.
|
|
@ -1,15 +0,0 @@
|
||||||
---
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
For NGINX troubleshooting/technical help, please visit our community forum instead of asking your questions here. We will politely redirect these types of questions to the forum.
|
|
||||||
- type: textarea
|
|
||||||
id: general
|
|
||||||
attributes:
|
|
||||||
label: What would you like to discuss?
|
|
||||||
description: Please provide as much context as possible. Remember that only general discussions related to the NGINX codebase will be addressed on GitHub. For anything else, please visit our [community forum](https://community.nginx.org/).
|
|
||||||
value: |
|
|
||||||
I would like to discuss...
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
---
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
For NGINX troubleshooting/technical help, please visit our community forum instead of asking your questions here. We will politely redirect these types of questions to the forum.
|
|
||||||
- type: textarea
|
|
||||||
id: ideas
|
|
||||||
attributes:
|
|
||||||
label: What idea would you like to discuss?
|
|
||||||
description: Please provide as much context as possible. Remember that only ideas related to the NGINX codebase will be addressed on GitHub. For anything else, please visit our [community forum](https://community.nginx.org/).
|
|
||||||
value: |
|
|
||||||
I have an idea for...
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
---
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
For NGINX troubleshooting/technical help, please visit our community forum instead of asking your questions here. We will politely redirect these types of questions to the forum.
|
|
||||||
- type: textarea
|
|
||||||
id: q-a
|
|
||||||
attributes:
|
|
||||||
label: What question do you have?
|
|
||||||
description: Please provide as much context as possible. Remember that only questions related to the NGINX codebase will be addressed on GitHub. For anything else, please visit our [community forum](https://community.nginx.org/).
|
|
||||||
value: |
|
|
||||||
I would like to know...
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ""
|
||||||
|
labels: "bug"
|
||||||
|
---
|
||||||
|
|
||||||
|
### Environment
|
||||||
|
|
||||||
|
Include the result of the following commands:
|
||||||
|
- `nginx -V`
|
||||||
|
- `uname -a`
|
||||||
|
|
||||||
|
### Description
|
||||||
|
|
||||||
|
Describe the bug in full detail including expected and actual behavior.
|
||||||
|
Specify conditions that caused it. Provide the relevant part of nginx
|
||||||
|
configuration and debug log.
|
||||||
|
|
||||||
|
- [ ] The bug is reproducible with the latest version of nginx
|
||||||
|
- [ ] The nginx configuration is minimized to the smallest possible
|
||||||
|
to reproduce the issue and doesn't contain third-party modules
|
||||||
|
|
||||||
|
#### nginx configuration
|
||||||
|
|
||||||
|
```
|
||||||
|
# Your nginx configuration here
|
||||||
|
```
|
||||||
|
or share the configuration in [gist](https://gist.github.com/).
|
||||||
|
|
||||||
|
#### nginx debug log
|
||||||
|
|
||||||
|
It is advised to enable
|
||||||
|
[debug logging](http://nginx.org/en/docs/debugging_log.html).
|
||||||
|
```
|
||||||
|
# Your nginx debug log here
|
||||||
|
```
|
||||||
|
or share the debug log in [gist](https://gist.github.com/).
|
||||||
|
|
@ -1,106 +0,0 @@
|
||||||
---
|
|
||||||
name: 🐛 Bug report
|
|
||||||
description: Create a report to help us improve
|
|
||||||
labels: bug
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
Thanks for taking the time to fill out this bug report!
|
|
||||||
|
|
||||||
Before you continue filling out this report, please take a moment to check that your bug has not been [already reported on GitHub][issue search], is reproducible with the latest version of nginx, and does not involve any third-party modules 🙌
|
|
||||||
|
|
||||||
Remember to redact any sensitive information such as authentication credentials and/or license keys!
|
|
||||||
|
|
||||||
**Note:** If you are seeking community support, please start a new topic in the [NGINX Community forum][forum]. If you wish to discuss the codebase, please start a new thread via [GitHub discussions][discussions].
|
|
||||||
|
|
||||||
[issue search]: https://github.com/nginx/nginx/search?q=is%3Aissue&type=issues
|
|
||||||
[discussions]: https://github.com/nginx/nginx/discussions
|
|
||||||
[forum]: https://community.nginx.org
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
id: overview
|
|
||||||
attributes:
|
|
||||||
label: Bug Overview
|
|
||||||
description: A clear and concise overview of the bug.
|
|
||||||
placeholder: When I do "X", "Y" happens instead of "Z".
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
id: behavior
|
|
||||||
attributes:
|
|
||||||
label: Expected Behavior
|
|
||||||
description: A clear and concise description of what you expected to happen.
|
|
||||||
placeholder: When I do "X", I expect "Z" to happen.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
id: steps
|
|
||||||
attributes:
|
|
||||||
label: Steps to Reproduce the Bug
|
|
||||||
description: Detail the series of steps required to reproduce the bug.
|
|
||||||
placeholder: When I run "X" using [...], "X" fails with "Y" error message. If I check the terminal outputs and/or logs, I see the following info.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
id: configuration
|
|
||||||
attributes:
|
|
||||||
label: NGINX Configuration
|
|
||||||
description: Please provide your NGINX configuration. Minimize it to the smallest possible configuration that reproduces the issue.
|
|
||||||
value: |
|
|
||||||
```
|
|
||||||
# Your NGINX configuration
|
|
||||||
```
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
id: version
|
|
||||||
attributes:
|
|
||||||
label: NGINX version and build configuration options
|
|
||||||
description: Please provide details about your NGINX build.
|
|
||||||
value: |
|
|
||||||
The output of `nginx -V`: [...]
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
id: environment
|
|
||||||
attributes:
|
|
||||||
label: Environment where NGINX is being built and/or deployed
|
|
||||||
description: Please provide details about your environment.
|
|
||||||
value: |
|
|
||||||
- Target deployment platform: [e.g. AWS/GCP/local cluster/etc...]
|
|
||||||
- Target OS: [e.g. RHEL 9/Ubuntu 24.04/etc...]
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
id: architecture
|
|
||||||
attributes:
|
|
||||||
label: Architecture where NGINX is being built and/or deployed
|
|
||||||
description: Please provide details about your deployment environment.
|
|
||||||
value: |
|
|
||||||
The output of `uname -a`: [...]
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
id: logs
|
|
||||||
attributes:
|
|
||||||
label: NGINX Debug Log
|
|
||||||
description: Please provide your NGINX debug log. See this [doc](http://nginx.org/en/docs/debugging_log.html) for details on how to enable it.
|
|
||||||
value: |
|
|
||||||
```
|
|
||||||
# Your NGINX debug log
|
|
||||||
```
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
id: context
|
|
||||||
attributes:
|
|
||||||
label: Additional Context
|
|
||||||
description: Add any other context about the problem here.
|
|
||||||
placeholder: Feel free to add any other context/information/screenshots/etc... that you think might be relevant to this issue in here.
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
---
|
|
||||||
blank_issues_enabled: false
|
|
||||||
contact_links:
|
|
||||||
- name: 💬 Talk to the NGINX community!
|
|
||||||
url: https://community.nginx.org
|
|
||||||
about: A community forum for NGINX users, developers, and contributors
|
|
||||||
- name: 📝 Code of Conduct
|
|
||||||
url: https://www.contributor-covenant.org/version/2/1/code_of_conduct
|
|
||||||
about: NGINX follows the Contributor Covenant Code of Conduct to ensure a safe and inclusive community
|
|
||||||
- name: 💼 For commercial & enterprise users
|
|
||||||
url: https://www.f5.com/products/nginx
|
|
||||||
about: F5 offers a wide range of NGINX products for commercial & enterprise users
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest a feature for nginx
|
||||||
|
title: ""
|
||||||
|
labels: "feature"
|
||||||
|
---
|
||||||
|
|
||||||
|
### Describe the feature you'd like to add to nginx
|
||||||
|
|
||||||
|
A clear and concise description of the feature.
|
||||||
|
|
||||||
|
### Describe the problem this feature solves
|
||||||
|
|
||||||
|
A clear and concise description of the problem.
|
||||||
|
|
||||||
|
### Additional context
|
||||||
|
|
||||||
|
Add any other context about the feature request here.
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
---
|
|
||||||
name: ✨ Feature request
|
|
||||||
description: Suggest an idea for this project
|
|
||||||
labels: enhancement
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
Thanks for taking the time to fill out this feature request!
|
|
||||||
|
|
||||||
Before you continue filling out this request, please take a moment to check that your feature has not been [already requested on GitHub][issue search] 🙌
|
|
||||||
|
|
||||||
**Note:** If you are seeking community support, please start a new topic in the [NGINX Community forum][forum]. If you wish to discuss the codebase, please start a new thread via [GitHub discussions][discussions].
|
|
||||||
|
|
||||||
[issue search]: https://github.com/nginx/nginx/search?q=is%3Aissue&type=issues
|
|
||||||
[discussions]: https://github.com/nginx/nginx/discussions
|
|
||||||
[forum]: https://community.nginx.org
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
id: overview
|
|
||||||
attributes:
|
|
||||||
label: Feature Overview
|
|
||||||
description: A clear and concise description of what the feature request is.
|
|
||||||
placeholder: I would like this project to be able to do "X".
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
id: alternatives
|
|
||||||
attributes:
|
|
||||||
label: Alternatives Considered
|
|
||||||
description: Detail any potential alternative solutions/workarounds you've used or considered.
|
|
||||||
placeholder: I have done/might be able to do "X" in this project by doing "Y".
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
id: context
|
|
||||||
attributes:
|
|
||||||
label: Additional Context
|
|
||||||
description: Add any other context about the problem here.
|
|
||||||
placeholder: Feel free to add any other context/information/screenshots/etc... that you think might be relevant to this feature request here.
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
### Proposed changes
|
### Proposed changes
|
||||||
|
|
||||||
Describe the use case and detail of the change. If this PR addresses an issue on GitHub, make sure to include a link to that issue using one of the [supported keywords](https://docs.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue) in this PR's description or commit message.
|
Describe the use case and detail of the change.
|
||||||
|
|
||||||
### Checklist
|
If this pull request addresses an issue on GitHub, make sure to reference that
|
||||||
|
issue using one of the
|
||||||
|
[supported keywords](https://docs.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue).
|
||||||
|
|
||||||
Before creating a PR, run through this checklist and mark each as complete:
|
Before creating a pull request, make sure to comply with the
|
||||||
|
[Contributing Guidelines](https://github.com/nginx/nginx/blob/master/CONTRIBUTING.md).
|
||||||
- [ ] I have read the [contributing guidelines](/CONTRIBUTING.md).
|
|
||||||
- [ ] I have checked that NGINX compiles and runs after adding my changes.
|
|
||||||
|
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
---
|
|
||||||
name: F5 CLA
|
|
||||||
on:
|
|
||||||
issue_comment:
|
|
||||||
types: [created]
|
|
||||||
pull_request_target:
|
|
||||||
types: [opened, closed, synchronize]
|
|
||||||
permissions: read-all
|
|
||||||
jobs:
|
|
||||||
f5-cla:
|
|
||||||
name: F5 CLA
|
|
||||||
runs-on: ubuntu-24.04
|
|
||||||
permissions:
|
|
||||||
actions: write
|
|
||||||
pull-requests: write
|
|
||||||
statuses: write
|
|
||||||
steps:
|
|
||||||
- name: Run F5 Contributor License Agreement (CLA) assistant
|
|
||||||
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have hereby read the F5 CLA and agree to its terms') || github.event_name == 'pull_request_target'
|
|
||||||
uses: contributor-assistant/github-action@ca4a40a7d1004f18d9960b404b97e5f30a505a08 # v2.6.1
|
|
||||||
with:
|
|
||||||
# Path to the CLA document.
|
|
||||||
path-to-document: https://github.com/f5/f5-cla/blob/main/docs/f5_cla.md
|
|
||||||
# Custom CLA messages.
|
|
||||||
custom-notsigned-prcomment: '🎉 Thank you for your contribution! It appears you have not yet signed the [F5 Contributor License Agreement (CLA)](https://github.com/f5/f5-cla/blob/main/docs/f5_cla.md), which is required for your changes to be incorporated into an F5 Open Source Software (OSS) project. Please kindly read the [F5 CLA](https://github.com/f5/f5-cla/blob/main/docs/f5_cla.md) and reply on a new comment with the following text to agree:'
|
|
||||||
custom-pr-sign-comment: 'I have hereby read the F5 CLA and agree to its terms'
|
|
||||||
custom-allsigned-prcomment: '✅ All required contributors have signed the F5 CLA for this PR. Thank you!'
|
|
||||||
# Remote repository storing CLA signatures.
|
|
||||||
remote-organization-name: f5
|
|
||||||
remote-repository-name: f5-cla-data
|
|
||||||
# Branch where CLA signatures are stored.
|
|
||||||
branch: main
|
|
||||||
path-to-signatures: signatures/signatures.json
|
|
||||||
# Comma separated list of usernames for maintainers or any other individuals who should not be prompted for a CLA.
|
|
||||||
# NOTE: You will want to edit the usernames to suit your project needs.
|
|
||||||
allowlist: bot*
|
|
||||||
# Do not lock PRs after a merge.
|
|
||||||
lock-pullrequest-aftermerge: false
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
PERSONAL_ACCESS_TOKEN: ${{ secrets.F5_CLA_TOKEN }}
|
|
||||||
|
|
@ -5,34 +5,34 @@ We really appreciate that you are considering contributing!
|
||||||
|
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
|
- [Ask a Question](#ask-a-question)
|
||||||
- [Report a Bug](#report-a-bug)
|
- [Report a Bug](#report-a-bug)
|
||||||
- [Suggest a Feature or Enhancement](#suggest-a-feature-or-enhancement)
|
- [Suggest a Feature or Enhancement](#suggest-a-feature-or-enhancement)
|
||||||
- [Open a Discussion](#open-a-discussion)
|
- [Open a Discussion](#open-a-discussion)
|
||||||
- [Submit a Pull Request](#submit-a-pull-request)
|
- [Submit a Pull Request](#submit-a-pull-request)
|
||||||
- [Issue Lifecycle](#issue-lifecycle)
|
- [Issue Lifecycle](#issue-lifecycle)
|
||||||
|
|
||||||
|
## Ask a Question
|
||||||
|
|
||||||
|
To ask a question, open an issue on GitHub with the label `question`.
|
||||||
|
|
||||||
## Report a Bug
|
## Report a Bug
|
||||||
|
|
||||||
To report a bug, open an issue on GitHub with the label `bug` using the
|
To report a bug, open an issue on GitHub with the label `bug` using the
|
||||||
available [bug report issue form](/.github/ISSUE_TEMPLATE/bug_report.yml).
|
available bug report issue template. Before reporting a bug, make sure the
|
||||||
Please ensure the bug has not already been reported. **If the bug is a
|
issue has not already been reported.
|
||||||
potential security vulnerability, please report it using our
|
|
||||||
[security policy](/SECURITY.md).**
|
|
||||||
|
|
||||||
## Suggest a Feature or Enhancement
|
## Suggest a Feature or Enhancement
|
||||||
|
|
||||||
To suggest a feature or enhancement, please create an issue on GitHub with the
|
To suggest a feature or enhancement, open an issue on GitHub with the label
|
||||||
label `enhancement` using the available
|
`feature` or `enhancement` using the available feature request issue template.
|
||||||
[feature request issue form](/.github/ISSUE_TEMPLATE/feature_request.yml).
|
|
||||||
Please ensure the feature or enhancement has not already been suggested.
|
Please ensure the feature or enhancement has not already been suggested.
|
||||||
|
|
||||||
## Open a Discussion
|
## Open a Discussion
|
||||||
|
|
||||||
If you want to engage in a conversation with the community and maintainers,
|
If you want to engage in a conversation with the community and maintainers,
|
||||||
we encourage you to use
|
we encourage you to use
|
||||||
[GitHub Discussions](https://github.com/nginx/nginx/discussions) to discuss
|
[GitHub Discussions](https://github.com/nginx/nginx/discussions).
|
||||||
the NGINX codebase or the [NGINX Community forum](https://community.nginx.org)
|
|
||||||
to chat anything else NGINX (including troubleshooting).
|
|
||||||
|
|
||||||
## Submit a Pull Request
|
## Submit a Pull Request
|
||||||
|
|
||||||
|
|
@ -89,20 +89,7 @@ git clone https://github.com/nginx/nginx-tests.git
|
||||||
```
|
```
|
||||||
|
|
||||||
- Submitting a change implies granting project a permission to use it under the
|
- Submitting a change implies granting project a permission to use it under the
|
||||||
[BSD-2-Clause license](/LICENSE)
|
[BSD-2-Clause license](https://github.com/nginx/nginx/blob/master/LICENSE)
|
||||||
|
|
||||||
### F5 Contributor License Agreement (CLA)
|
|
||||||
|
|
||||||
F5 requires all contributors to agree to the terms of the F5 CLA
|
|
||||||
(available [here](https://github.com/f5/f5-cla/blob/main/docs/f5_cla.md))
|
|
||||||
before any of their changes can be incorporated into an F5 Open Source
|
|
||||||
repository (even contributions to the F5 CLA itself!).
|
|
||||||
|
|
||||||
If you have not yet agreed to the F5 CLA terms and submit a PR to this
|
|
||||||
repository, a bot will prompt you to view and agree to the F5 CLA.
|
|
||||||
You will have to agree to the F5 CLA terms through a comment in the PR
|
|
||||||
before any of your changes can be merged. Your agreement signature
|
|
||||||
will be safely stored by F5 and no longer be required in future PRs.
|
|
||||||
|
|
||||||
## Issue Lifecycle
|
## Issue Lifecycle
|
||||||
|
|
||||||
|
|
|
||||||
10
README.md
10
README.md
|
|
@ -4,11 +4,6 @@
|
||||||
<img alt="NGINX Banner">
|
<img alt="NGINX Banner">
|
||||||
</picture>
|
</picture>
|
||||||
|
|
||||||
[](https://www.repostatus.org/#active)
|
|
||||||
[](https://community.nginx.org)
|
|
||||||
[](/LICENSE)
|
|
||||||
[](/CODE_OF_CONDUCT.md)
|
|
||||||
|
|
||||||
NGINX (pronounced "engine x" or "en-jin-eks") is the world's most popular Web Server, high performance Load Balancer, Reverse Proxy, API Gateway and Content Cache.
|
NGINX (pronounced "engine x" or "en-jin-eks") is the world's most popular Web Server, high performance Load Balancer, Reverse Proxy, API Gateway and Content Cache.
|
||||||
|
|
||||||
NGINX is free and open source software, distributed under the terms of a simplified [2-clause BSD-like license](LICENSE).
|
NGINX is free and open source software, distributed under the terms of a simplified [2-clause BSD-like license](LICENSE).
|
||||||
|
|
@ -65,6 +60,7 @@ nginx -V
|
||||||
```
|
```
|
||||||
> See [Configuring the build](#configuring-the-build) for information on how to include specific Static modules into your nginx build.
|
> See [Configuring the build](#configuring-the-build) for information on how to include specific Static modules into your nginx build.
|
||||||
|
|
||||||
|
|
||||||
## Configurations
|
## Configurations
|
||||||
NGINX is highly flexible and configurable. Provisioning the software is achieved via text-based config file(s) accepting parameters called "[Directives](https://nginx.org/en/docs/dirindex.html)". See [Configuration File's Structure](https://nginx.org/en/docs/beginners_guide.html#conf_structure) for a comprehensive description of how NGINX configuration files work.
|
NGINX is highly flexible and configurable. Provisioning the software is achieved via text-based config file(s) accepting parameters called "[Directives](https://nginx.org/en/docs/dirindex.html)". See [Configuration File's Structure](https://nginx.org/en/docs/beginners_guide.html#conf_structure) for a comprehensive description of how NGINX configuration files work.
|
||||||
|
|
||||||
|
|
@ -213,7 +209,9 @@ The output of which should start with:
|
||||||
```
|
```
|
||||||
|
|
||||||
# Asking questions and reporting issues
|
# Asking questions and reporting issues
|
||||||
See our [Support](SUPPORT.md) guidelines for information on how discuss the codebase, ask troubleshooting questions, and report issues.
|
We encourage you to engage with us.
|
||||||
|
- [NGINX GitHub Discussions](https://github.com/nginx/nginx/discussions), is the go-to place to start asking questions and sharing your thoughts.
|
||||||
|
- Our [GitHub Issues](https://github.com/nginx/nginx/issues) page offers space to submit and discuss specific issues, report bugs, and suggest enhancements.
|
||||||
|
|
||||||
# Contributing code
|
# Contributing code
|
||||||
Please see the [Contributing](CONTRIBUTING.md) guide for information on how to contribute code.
|
Please see the [Contributing](CONTRIBUTING.md) guide for information on how to contribute code.
|
||||||
|
|
|
||||||
48
SUPPORT.md
48
SUPPORT.md
|
|
@ -1,48 +0,0 @@
|
||||||
# Support
|
|
||||||
|
|
||||||
## Ask a Question
|
|
||||||
|
|
||||||
We use GitHub issues for tracking bugs and feature requests
|
|
||||||
related to this project.
|
|
||||||
|
|
||||||
If you don't know how something in the codebase works, are curious if NGINX
|
|
||||||
is capable of achieving your desired functionality or want to discuss the
|
|
||||||
implementation of an existing or in development feature, please start a
|
|
||||||
GitHub discussion!
|
|
||||||
|
|
||||||
## NGINX Specific Questions and/or Issues
|
|
||||||
|
|
||||||
This project isn't the right place to get support for NGINX and/or NGINX
|
|
||||||
troubleshooting questions, but the following resources are available below.
|
|
||||||
Thanks for your understanding!
|
|
||||||
|
|
||||||
### Community Forum
|
|
||||||
|
|
||||||
We have a [community forum](https://community.nginx.org/)!
|
|
||||||
If you have any NGINX specific questions and/or issues,
|
|
||||||
try checking out the [`NGINX category`](https://community.nginx.org/c/projects/nginx/23).
|
|
||||||
For general discussions around anything tangentially NGINX related,
|
|
||||||
check out the [`General Discussion category`](https://community.nginx.org/c/general-discussion/34).
|
|
||||||
Both fellow community members and NGINXers might be able to help you! :)
|
|
||||||
|
|
||||||
### Documentation
|
|
||||||
|
|
||||||
For a comprehensive list of all NGINX directives, check out <https://nginx.org>.
|
|
||||||
|
|
||||||
For a comprehensive list of administration and deployment guides for all
|
|
||||||
NGINX products, check out <https://docs.nginx.com>.
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
Please see the [contributing guide](/CONTRIBUTING.md) for guidelines
|
|
||||||
on how to best contribute to this project.
|
|
||||||
|
|
||||||
## Commercial Support
|
|
||||||
|
|
||||||
Commercial support for this project is available.
|
|
||||||
Please get in touch with [F5 sales](https://www.f5.com/products/get-f5/)
|
|
||||||
or check your contract details for more information!
|
|
||||||
|
|
||||||
## Community Support
|
|
||||||
|
|
||||||
Community support is offered on a best effort basis through any of our active communities.
|
|
||||||
|
|
@ -5,6 +5,15 @@
|
||||||
# clang
|
# clang
|
||||||
|
|
||||||
|
|
||||||
|
NGX_CLANG_VER=`$CC -v 2>&1 | grep 'version' 2>&1 \
|
||||||
|
| sed -n -e 's/^.*clang version \(.*\)/\1/p' \
|
||||||
|
-e 's/^.*LLVM version \(.*\)/\1/p'`
|
||||||
|
|
||||||
|
echo " + clang version: $NGX_CLANG_VER"
|
||||||
|
|
||||||
|
have=NGX_COMPILER value="\"clang $NGX_CLANG_VER\"" . auto/define
|
||||||
|
|
||||||
|
|
||||||
CC_TEST_FLAGS="-pipe"
|
CC_TEST_FLAGS="-pipe"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
12
auto/cc/gcc
12
auto/cc/gcc
|
|
@ -8,6 +8,14 @@
|
||||||
# 4.0.0, 4.0.1, 4.1.0
|
# 4.0.0, 4.0.1, 4.1.0
|
||||||
|
|
||||||
|
|
||||||
|
NGX_GCC_VER=`$CC -v 2>&1 | grep 'gcc version' 2>&1 \
|
||||||
|
| sed -e 's/^.* version \(.*\)/\1/'`
|
||||||
|
|
||||||
|
echo " + gcc version: $NGX_GCC_VER"
|
||||||
|
|
||||||
|
have=NGX_COMPILER value="\"gcc $NGX_GCC_VER\"" . auto/define
|
||||||
|
|
||||||
|
|
||||||
# Solaris 7's /usr/ccs/bin/as does not support "-pipe"
|
# Solaris 7's /usr/ccs/bin/as does not support "-pipe"
|
||||||
|
|
||||||
CC_TEST_FLAGS="-pipe"
|
CC_TEST_FLAGS="-pipe"
|
||||||
|
|
@ -104,7 +112,7 @@ esac
|
||||||
|
|
||||||
CC_AUX_FLAGS="$CC_AUX_FLAGS $CPU_OPT"
|
CC_AUX_FLAGS="$CC_AUX_FLAGS $CPU_OPT"
|
||||||
|
|
||||||
case "$NGX_CC_VER" in
|
case "$NGX_GCC_VER" in
|
||||||
2.7*)
|
2.7*)
|
||||||
# batch build
|
# batch build
|
||||||
CPU_OPT=
|
CPU_OPT=
|
||||||
|
|
@ -137,7 +145,7 @@ CFLAGS="$CFLAGS -Wall -Wpointer-arith"
|
||||||
#CFLAGS="$CFLAGS -Winline"
|
#CFLAGS="$CFLAGS -Winline"
|
||||||
#CFLAGS="$CFLAGS -Wmissing-prototypes"
|
#CFLAGS="$CFLAGS -Wmissing-prototypes"
|
||||||
|
|
||||||
case "$NGX_CC_VER" in
|
case "$NGX_GCC_VER" in
|
||||||
2.*)
|
2.*)
|
||||||
# we have a lot of the unused function arguments
|
# we have a lot of the unused function arguments
|
||||||
CFLAGS="$CFLAGS -Wno-unused"
|
CFLAGS="$CFLAGS -Wno-unused"
|
||||||
|
|
|
||||||
10
auto/cc/icc
10
auto/cc/icc
|
|
@ -5,6 +5,14 @@
|
||||||
|
|
||||||
# Intel C++ compiler 7.1, 8.0, 8.1, 9.0, 11.1
|
# Intel C++ compiler 7.1, 8.0, 8.1, 9.0, 11.1
|
||||||
|
|
||||||
|
NGX_ICC_VER=`$CC -V 2>&1 | grep 'Version' 2>&1 \
|
||||||
|
| sed -e 's/^.* Version \([^ ]*\) *Build.*$/\1/'`
|
||||||
|
|
||||||
|
echo " + icc version: $NGX_ICC_VER"
|
||||||
|
|
||||||
|
have=NGX_COMPILER value="\"Intel C Compiler $NGX_ICC_VER\"" . auto/define
|
||||||
|
|
||||||
|
|
||||||
# optimizations
|
# optimizations
|
||||||
|
|
||||||
CFLAGS="$CFLAGS -O"
|
CFLAGS="$CFLAGS -O"
|
||||||
|
|
@ -75,7 +83,7 @@ CFLAGS="$CFLAGS -wd1418"
|
||||||
# external declaration in primary source file
|
# external declaration in primary source file
|
||||||
CFLAGS="$CFLAGS -wd1419"
|
CFLAGS="$CFLAGS -wd1419"
|
||||||
|
|
||||||
case "$NGX_CC_VER" in
|
case "$NGX_ICC_VER" in
|
||||||
9.*)
|
9.*)
|
||||||
# "cc" clobber ignored, warnings for Linux's htonl()/htons()
|
# "cc" clobber ignored, warnings for Linux's htonl()/htons()
|
||||||
CFLAGS="$CFLAGS -wd1469"
|
CFLAGS="$CFLAGS -wd1469"
|
||||||
|
|
|
||||||
12
auto/cc/msvc
12
auto/cc/msvc
|
|
@ -11,12 +11,20 @@
|
||||||
# MSVC 2015 (14.0) cl 19.00
|
# MSVC 2015 (14.0) cl 19.00
|
||||||
|
|
||||||
|
|
||||||
ngx_msvc_ver=`echo $NGX_CC_VER | sed -e 's/^\([0-9]*\).*/\1/'`
|
NGX_MSVC_VER=`$NGX_WINE $CC 2>&1 | grep 'C/C++.* [0-9][0-9]*\.[0-9]' 2>&1 \
|
||||||
|
| sed -e 's/^.* \([0-9][0-9]*\.[0-9].*\)/\1/'`
|
||||||
|
|
||||||
|
echo " + cl version: $NGX_MSVC_VER"
|
||||||
|
|
||||||
|
have=NGX_COMPILER value="\"cl $NGX_MSVC_VER\"" . auto/define
|
||||||
|
|
||||||
|
|
||||||
|
ngx_msvc_ver=`echo $NGX_MSVC_VER | sed -e 's/^\([0-9]*\).*/\1/'`
|
||||||
|
|
||||||
|
|
||||||
# detect x64 builds
|
# detect x64 builds
|
||||||
|
|
||||||
case "$NGX_CC_VER" in
|
case "$NGX_MSVC_VER" in
|
||||||
|
|
||||||
*ARM64)
|
*ARM64)
|
||||||
NGX_MACHINE=arm64
|
NGX_MACHINE=arm64
|
||||||
|
|
|
||||||
33
auto/cc/name
33
auto/cc/name
|
|
@ -28,13 +28,6 @@ if [ "$CC" = cl ]; then
|
||||||
NGX_CC_NAME=msvc
|
NGX_CC_NAME=msvc
|
||||||
echo " + using Microsoft Visual C++ compiler"
|
echo " + using Microsoft Visual C++ compiler"
|
||||||
|
|
||||||
NGX_CC_VER=`$NGX_WINE $CC 2>&1 \
|
|
||||||
| grep 'C/C++.* [0-9][0-9]*\.[0-9]' 2>&1 \
|
|
||||||
| sed -e 's/^.* \([0-9][0-9]*\.[0-9].*\)/\1/'`
|
|
||||||
echo " + cl version: $NGX_CC_VER"
|
|
||||||
|
|
||||||
have=NGX_COMPILER value="\"cl $NGX_CC_VER\"" . auto/define
|
|
||||||
|
|
||||||
elif [ "$CC" = wcl386 ]; then
|
elif [ "$CC" = wcl386 ]; then
|
||||||
NGX_CC_NAME=owc
|
NGX_CC_NAME=owc
|
||||||
echo " + using Open Watcom C compiler"
|
echo " + using Open Watcom C compiler"
|
||||||
|
|
@ -47,48 +40,22 @@ elif `$CC -V 2>&1 | grep '^Intel(R) C' >/dev/null 2>&1`; then
|
||||||
NGX_CC_NAME=icc
|
NGX_CC_NAME=icc
|
||||||
echo " + using Intel C++ compiler"
|
echo " + using Intel C++ compiler"
|
||||||
|
|
||||||
NGX_CC_VER=`$CC -V 2>&1 \
|
|
||||||
| sed -n -e 's/^.* Version \([^ ]*\) *Build.*$/\1/p'`
|
|
||||||
echo " + icc version: $NGX_CC_VER"
|
|
||||||
|
|
||||||
have=NGX_COMPILER value="\"Intel C Compiler $NGX_CC_VER\"" . auto/define
|
|
||||||
|
|
||||||
elif `$CC -v 2>&1 | grep 'gcc version' >/dev/null 2>&1`; then
|
elif `$CC -v 2>&1 | grep 'gcc version' >/dev/null 2>&1`; then
|
||||||
NGX_CC_NAME=gcc
|
NGX_CC_NAME=gcc
|
||||||
echo " + using GNU C compiler"
|
echo " + using GNU C compiler"
|
||||||
|
|
||||||
NGX_CC_VER=`$CC -v 2>&1 | sed -n -e 's/^.*gcc version \(.*\)/\1/p'`
|
|
||||||
echo " + gcc version: $NGX_CC_VER"
|
|
||||||
|
|
||||||
have=NGX_COMPILER value="\"gcc $NGX_CC_VER\"" . auto/define
|
|
||||||
|
|
||||||
elif `$CC -v 2>&1 | grep 'clang version' >/dev/null 2>&1`; then
|
elif `$CC -v 2>&1 | grep 'clang version' >/dev/null 2>&1`; then
|
||||||
NGX_CC_NAME=clang
|
NGX_CC_NAME=clang
|
||||||
echo " + using Clang C compiler"
|
echo " + using Clang C compiler"
|
||||||
|
|
||||||
NGX_CC_VER=`$CC -v 2>&1 | sed -n -e 's/^.*clang version \(.*\)/\1/p'`
|
|
||||||
echo " + clang version: $NGX_CC_VER"
|
|
||||||
|
|
||||||
have=NGX_COMPILER value="\"clang $NGX_CC_VER\"" . auto/define
|
|
||||||
|
|
||||||
elif `$CC -v 2>&1 | grep 'LLVM version' >/dev/null 2>&1`; then
|
elif `$CC -v 2>&1 | grep 'LLVM version' >/dev/null 2>&1`; then
|
||||||
NGX_CC_NAME=clang
|
NGX_CC_NAME=clang
|
||||||
echo " + using Clang C compiler"
|
echo " + using Clang C compiler"
|
||||||
|
|
||||||
NGX_CC_VER=`$CC -v 2>&1 | sed -n -e 's/^.*LLVM version \(.*\)/\1/p'`
|
|
||||||
echo " + clang version: $NGX_CC_VER"
|
|
||||||
|
|
||||||
have=NGX_COMPILER value="\"clang $NGX_CC_VER\"" . auto/define
|
|
||||||
|
|
||||||
elif `$CC -V 2>&1 | grep 'Sun C' >/dev/null 2>&1`; then
|
elif `$CC -V 2>&1 | grep 'Sun C' >/dev/null 2>&1`; then
|
||||||
NGX_CC_NAME=sunc
|
NGX_CC_NAME=sunc
|
||||||
echo " + using Sun C compiler"
|
echo " + using Sun C compiler"
|
||||||
|
|
||||||
NGX_CC_VER=`$CC -V 2>&1 | sed -n -e 's/^.* Sun C \(.*\)/\1/p'`
|
|
||||||
echo " + Sun C version: $NGX_CC_VER"
|
|
||||||
|
|
||||||
have=NGX_COMPILER value="\"Sun C $NGX_CC_VER\"" . auto/define
|
|
||||||
|
|
||||||
elif `$CC -V 2>&1 | grep '^Compaq C' >/dev/null 2>&1`; then
|
elif `$CC -V 2>&1 | grep '^Compaq C' >/dev/null 2>&1`; then
|
||||||
NGX_CC_NAME=ccc
|
NGX_CC_NAME=ccc
|
||||||
echo " + using Compaq C compiler"
|
echo " + using Compaq C compiler"
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,13 @@
|
||||||
# Sun C 5.13 SunOS_i386 2014/10/20 Oracle Solaris Studio 12.4
|
# Sun C 5.13 SunOS_i386 2014/10/20 Oracle Solaris Studio 12.4
|
||||||
# Sun C 5.14 SunOS_i386 2016/05/31 Oracle Developer Studio 12.5
|
# Sun C 5.14 SunOS_i386 2016/05/31 Oracle Developer Studio 12.5
|
||||||
|
|
||||||
|
NGX_SUNC_VER=`$CC -V 2>&1 | grep 'Sun C' 2>&1 \
|
||||||
|
| sed -e 's/^.* Sun C \(.*\)/\1/'`
|
||||||
|
|
||||||
|
echo " + Sun C version: $NGX_SUNC_VER"
|
||||||
|
|
||||||
|
have=NGX_COMPILER value="\"Sun C $NGX_SUNC_VER\"" . auto/define
|
||||||
|
|
||||||
|
|
||||||
cat << END > $NGX_AUTOTEST.c
|
cat << END > $NGX_AUTOTEST.c
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,6 @@ if [ $PCRE_LIBRARY = PCRE2 ]; then
|
||||||
pcre2_xclass.c"
|
pcre2_xclass.c"
|
||||||
|
|
||||||
ngx_pcre_test="pcre2_chkdint.c \
|
ngx_pcre_test="pcre2_chkdint.c \
|
||||||
pcre2_compile_cgroup.c \
|
|
||||||
pcre2_compile_class.c \
|
pcre2_compile_class.c \
|
||||||
pcre2_convert.c \
|
pcre2_convert.c \
|
||||||
pcre2_extuni.c \
|
pcre2_extuni.c \
|
||||||
|
|
|
||||||
13
auto/modules
13
auto/modules
|
|
@ -729,7 +729,7 @@ if [ $HTTP = YES ]; then
|
||||||
|
|
||||||
ngx_module_name=ngx_http_proxy_module
|
ngx_module_name=ngx_http_proxy_module
|
||||||
ngx_module_incs=
|
ngx_module_incs=
|
||||||
ngx_module_deps=src/http/modules/ngx_http_proxy_module.h
|
ngx_module_deps=
|
||||||
ngx_module_srcs=src/http/modules/ngx_http_proxy_module.c
|
ngx_module_srcs=src/http/modules/ngx_http_proxy_module.c
|
||||||
ngx_module_libs=
|
ngx_module_libs=
|
||||||
ngx_module_link=$HTTP_PROXY
|
ngx_module_link=$HTTP_PROXY
|
||||||
|
|
@ -781,17 +781,6 @@ if [ $HTTP = YES ]; then
|
||||||
. auto/module
|
. auto/module
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $HTTP_PROXY = YES -a $HTTP_V2 = YES ]; then
|
|
||||||
ngx_module_name=ngx_http_proxy_v2_module
|
|
||||||
ngx_module_incs=
|
|
||||||
ngx_module_deps=
|
|
||||||
ngx_module_srcs=src/http/modules/ngx_http_proxy_v2_module.c
|
|
||||||
ngx_module_libs=
|
|
||||||
ngx_module_link=$HTTP_V2
|
|
||||||
|
|
||||||
. auto/module
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $HTTP_PERL != NO ]; then
|
if [ $HTTP_PERL != NO ]; then
|
||||||
ngx_module_name=ngx_http_perl_module
|
ngx_module_name=ngx_http_perl_module
|
||||||
ngx_module_incs=src/http/modules/perl
|
ngx_module_incs=src/http/modules/perl
|
||||||
|
|
|
||||||
20
auto/unix
20
auto/unix
|
|
@ -129,6 +129,26 @@ if test -z "$NGX_KQUEUE_CHECKED"; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [ "$NGX_SYSTEM" = "NetBSD" ]; then
|
||||||
|
|
||||||
|
# NetBSD 2.0 incompatibly defines kevent.udata as "intptr_t"
|
||||||
|
|
||||||
|
cat << END >> $NGX_AUTO_CONFIG_H
|
||||||
|
|
||||||
|
#define NGX_KQUEUE_UDATA_T
|
||||||
|
|
||||||
|
END
|
||||||
|
|
||||||
|
else
|
||||||
|
cat << END >> $NGX_AUTO_CONFIG_H
|
||||||
|
|
||||||
|
#define NGX_KQUEUE_UDATA_T (void *)
|
||||||
|
|
||||||
|
END
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
ngx_feature="crypt()"
|
ngx_feature="crypt()"
|
||||||
ngx_feature_name="NGX_HAVE_CRYPT"
|
ngx_feature_name="NGX_HAVE_CRYPT"
|
||||||
ngx_feature_run=no
|
ngx_feature_run=no
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,8 @@ http {
|
||||||
listen 80;
|
listen 80;
|
||||||
server_name localhost;
|
server_name localhost;
|
||||||
|
|
||||||
|
#charset koi8-r;
|
||||||
|
|
||||||
#access_log logs/host.access.log main;
|
#access_log logs/host.access.log main;
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
|
|
|
||||||
|
|
@ -5,336 +5,6 @@
|
||||||
<change_log title="nginx">
|
<change_log title="nginx">
|
||||||
|
|
||||||
|
|
||||||
<changes ver="1.29.4" date="2025-12-09">
|
|
||||||
|
|
||||||
<change type="feature">
|
|
||||||
<para lang="ru">
|
|
||||||
модуль ngx_http_proxy_module поддерживает HTTP/2.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
the ngx_http_proxy_module supports HTTP/2.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="feature">
|
|
||||||
<para lang="ru">
|
|
||||||
поддержка расширения TLS Encrypted ClientHello
|
|
||||||
при использовании ветки разработки ECH OpenSSL;
|
|
||||||
директива ssl_ech_file.<br/>
|
|
||||||
Спасибо Stephen Farrell.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
Encrypted ClientHello TLS extension support
|
|
||||||
when using OpenSSL ECH feature branch;
|
|
||||||
the "ssl_ech_file" directive.<br/>
|
|
||||||
Thanks to Stephen Farrell.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="change">
|
|
||||||
<para lang="ru">
|
|
||||||
валидация хоста и порта в строке запроса,
|
|
||||||
в заголовке "Host" и псевдо-заголовке ":authority"
|
|
||||||
изменена на соответствующую RFC 3986.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
validation of host and port in the request line,
|
|
||||||
"Host" header field, and ":authority" pseudo-header field
|
|
||||||
has been changed to follow RFC 3986.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="change">
|
|
||||||
<para lang="ru">
|
|
||||||
теперь одиночный символ LF, используемый для перевода строки
|
|
||||||
в chunked-теле запроса или ответа, считается ошибкой.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
now a single LF used as a line terminator
|
|
||||||
in a chunked request or response body is considered an error.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="bugfix">
|
|
||||||
<para lang="ru">
|
|
||||||
при использовании HTTP/3 с OpenSSL 3.5.1 и новее
|
|
||||||
в рабочем процессе мог произойти segmentation fault;
|
|
||||||
ошибка появилась в 1.29.1.<br/>
|
|
||||||
Спасибо Jan Svojanovsky.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
when using HTTP/3 with OpenSSL 3.5.1 or newer
|
|
||||||
a segmentation fault might occur in a worker process;
|
|
||||||
the bug had appeared in 1.29.1.<br/>
|
|
||||||
Thanks to Jan Svojanovsky.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="bugfix">
|
|
||||||
<para lang="ru">
|
|
||||||
при совместном использовании директив try_files и proxy_pass с URI
|
|
||||||
в рабочем процессе мог произойти segmentation fault.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
a segmentation fault might occur in a worker process
|
|
||||||
if the "try_files" directive and "proxy_pass" with a URI were used.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
</changes>
|
|
||||||
|
|
||||||
|
|
||||||
<changes ver="1.29.3" date="2025-10-28">
|
|
||||||
|
|
||||||
<change type="feature">
|
|
||||||
<para lang="ru">
|
|
||||||
директивы add_header_inherit и add_trailer_inherit.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
the "add_header_inherit" and "add_trailer_inherit" directives.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="feature">
|
|
||||||
<para lang="ru">
|
|
||||||
переменные $request_port и $is_request_port.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
the $request_port and $is_request_port variables.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="feature">
|
|
||||||
<para lang="ru">
|
|
||||||
переменные $ssl_sigalg и $ssl_client_sigalg.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
the $ssl_sigalg and $ssl_client_sigalg variables.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="feature">
|
|
||||||
<para lang="ru">
|
|
||||||
параметр volatile директивы geo.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
the "volatile" parameter of the "geo" directive.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="feature">
|
|
||||||
<para lang="ru">
|
|
||||||
теперь сжатие сертификатов доступно с BoringSSL.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
now certificate compression is available with BoringSSL.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="bugfix">
|
|
||||||
<para lang="ru">
|
|
||||||
теперь сжатие сертификатов запрещено при включенном OCSP stapling.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
now certificate compression is disabled with OCSP stapling.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
</changes>
|
|
||||||
|
|
||||||
|
|
||||||
<changes ver="1.29.2" date="2025-10-07">
|
|
||||||
|
|
||||||
<change type="feature">
|
|
||||||
<para lang="ru">
|
|
||||||
теперь nginx можно собрать с AWS-LC.<br/>
|
|
||||||
Спасибо Samuel Chiang.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
now nginx can be built with AWS-LC.<br/>
|
|
||||||
Thanks Samuel Chiang.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="bugfix">
|
|
||||||
<para lang="ru">
|
|
||||||
теперь директива ssl_protocols работает
|
|
||||||
в виртуальном сервере, отличном от сервера по умолчанию,
|
|
||||||
при использовании OpenSSL 1.1.1 и новее.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
now the "ssl_protocols" directive works
|
|
||||||
in a virtual server different from the default server
|
|
||||||
when using OpenSSL 1.1.1 or newer.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="bugfix">
|
|
||||||
<para lang="ru">
|
|
||||||
при использовании TLSv1.3 с OpenSSL и клиентских сертификатов
|
|
||||||
SSL handshake всегда завершался ошибкой
|
|
||||||
при восстановлении сессии с другим значением SNI;
|
|
||||||
ошибка появилась в 1.27.4.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
SSL handshake always failed
|
|
||||||
when using TLSv1.3 with OpenSSL and client certificates
|
|
||||||
and resuming a session with a different SNI value;
|
|
||||||
the bug had appeared in 1.27.4.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="bugfix">
|
|
||||||
<para lang="ru">
|
|
||||||
при использовании QUIC и директивы ssl_reject_handshake
|
|
||||||
в логах могли появляться сообщения
|
|
||||||
"ignoring stale global SSL error";
|
|
||||||
ошибка появилась в 1.29.0.<br/>
|
|
||||||
Спасибо Владимиру Хомутову.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
the "ignoring stale global SSL error"
|
|
||||||
alerts might appear in logs
|
|
||||||
when using QUIC and the "ssl_reject_handshake" directive;
|
|
||||||
the bug had appeared in 1.29.0.<br/>
|
|
||||||
Thanks to Vladimir Homutov.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="bugfix">
|
|
||||||
<para lang="ru">
|
|
||||||
в обработке delta-seconds
|
|
||||||
в строке "Cache-Control" в заголовке ответа бэкенда.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
in delta-seconds processing
|
|
||||||
in the "Cache-Control" backend response header line.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="bugfix">
|
|
||||||
<para lang="ru">
|
|
||||||
команда XCLIENT не использовала кодировку xtext.<br/>
|
|
||||||
Спасибо Igor Morgenstern из Aisle Research.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
an XCLIENT command didn't use the xtext encoding.<br/>
|
|
||||||
Thanks to Igor Morgenstern of Aisle Research.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="bugfix">
|
|
||||||
<para lang="ru">
|
|
||||||
в кешировании SSL-сертификатов во время переконфигурации.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
in SSL certificate caching during reconfiguration.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
</changes>
|
|
||||||
|
|
||||||
|
|
||||||
<changes ver="1.29.1" date="2025-08-13">
|
|
||||||
|
|
||||||
<change type="security">
|
|
||||||
<para lang="ru">
|
|
||||||
обработка специально созданного логина/пароля при использовании
|
|
||||||
метода аутентификации "none" в модуле ngx_mail_smtp_module
|
|
||||||
могла приводить к отправке серверу аутентификации
|
|
||||||
части содержимого памяти рабочего процесса (CVE-2025-53859).
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
processing of a specially crafted login/password when using
|
|
||||||
the "none" authentication method in the ngx_mail_smtp_module
|
|
||||||
might cause worker process memory disclosure
|
|
||||||
to the authentication server (CVE-2025-53859).
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="change">
|
|
||||||
<para lang="ru">
|
|
||||||
теперь сжатие сертификатов в протоколе TLSv1.3 по умолчанию запрещено.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
now TLSv1.3 certificate compression is disabled by default.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="feature">
|
|
||||||
<para lang="ru">
|
|
||||||
директива ssl_certificate_compression.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
the "ssl_certificate_compression" directive.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="feature">
|
|
||||||
<para lang="ru">
|
|
||||||
поддержка 0-RTT в QUIC при использовании OpenSSL 3.5.1 и новее.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
support for 0-RTT in QUIC when using OpenSSL 3.5.1 or newer.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="bugfix">
|
|
||||||
<para lang="ru">
|
|
||||||
при использовании HTTP/2 и директивы early_hints
|
|
||||||
ответ 103 мог буферизироваться.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
the 103 response might be buffered
|
|
||||||
when using HTTP/2 and the "early_hints" directive.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="bugfix">
|
|
||||||
<para lang="ru">
|
|
||||||
в обработке заголовков запроса "Host" и ":authority"
|
|
||||||
с одинаковыми значениями при использовании HTTP/2;
|
|
||||||
ошибка появилась в 1.17.9.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
in handling "Host" and ":authority" header lines
|
|
||||||
with equal values when using HTTP/2;
|
|
||||||
the bug had appeared in 1.17.9.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="bugfix">
|
|
||||||
<para lang="ru">
|
|
||||||
в обработке заголовка запроса "Host" с портом
|
|
||||||
при использовании HTTP/3.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
in handling "Host" header lines with a port
|
|
||||||
when using HTTP/3.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="bugfix">
|
|
||||||
<para lang="ru">
|
|
||||||
nginx не собирался под NetBSD 10.0.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
nginx could not be built on NetBSD 10.0.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
<change type="bugfix">
|
|
||||||
<para lang="ru">
|
|
||||||
в работе параметра none директивы smtp_auth.
|
|
||||||
</para>
|
|
||||||
<para lang="en">
|
|
||||||
in the "none" parameter of the "smtp_auth" directive.
|
|
||||||
</para>
|
|
||||||
</change>
|
|
||||||
|
|
||||||
</changes>
|
|
||||||
|
|
||||||
|
|
||||||
<changes ver="1.29.0" date="2025-06-24">
|
<changes ver="1.29.0" date="2025-06-24">
|
||||||
|
|
||||||
<change type="feature">
|
<change type="feature">
|
||||||
|
|
@ -8966,7 +8636,7 @@ Thanks to Piotr Sikora.
|
||||||
Спасибо Piotr Sikora.
|
Спасибо Piotr Sikora.
|
||||||
</para>
|
</para>
|
||||||
<para lang="en">
|
<para lang="en">
|
||||||
now nginx can be built with BoringSSL and LibreSSL.<br/>
|
now nginx can be build with BoringSSL and LibreSSL.<br/>
|
||||||
Thanks to Piotr Sikora.
|
Thanks to Piotr Sikora.
|
||||||
</para>
|
</para>
|
||||||
</change>
|
</change>
|
||||||
|
|
@ -26249,7 +25919,7 @@ the ECONNABORTED error log level was changed to "error" from "crit".
|
||||||
модуль ngx_http_perl_module не собирался без модуля ngx_http_ssi_filter_module.
|
модуль ngx_http_perl_module не собирался без модуля ngx_http_ssi_filter_module.
|
||||||
</para>
|
</para>
|
||||||
<para lang="en">
|
<para lang="en">
|
||||||
the ngx_http_perl_module could not be built without
|
the ngx_http_perl_module could not be build without
|
||||||
the ngx_http_ssi_filter_module.
|
the ngx_http_ssi_filter_module.
|
||||||
</para>
|
</para>
|
||||||
</change>
|
</change>
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@ TEMP = tmp
|
||||||
|
|
||||||
CC = cl
|
CC = cl
|
||||||
OBJS = objs.msvc8
|
OBJS = objs.msvc8
|
||||||
OPENSSL = openssl-3.5.4
|
OPENSSL = openssl-3.5.0
|
||||||
ZLIB = zlib-1.3.1
|
ZLIB = zlib-1.3.1
|
||||||
PCRE = pcre2-10.46
|
PCRE = pcre2-10.45
|
||||||
|
|
||||||
|
|
||||||
release: export
|
release: export
|
||||||
|
|
@ -110,7 +110,7 @@ zip: export
|
||||||
cp -p $(OBJS)/lib/$(OPENSSL)/LICENSE.txt \
|
cp -p $(OBJS)/lib/$(OPENSSL)/LICENSE.txt \
|
||||||
$(TEMP)/$(NGINX)/docs/OpenSSL.LICENSE
|
$(TEMP)/$(NGINX)/docs/OpenSSL.LICENSE
|
||||||
|
|
||||||
cp -p $(OBJS)/lib/$(PCRE)/LICENCE.md \
|
cp -p $(OBJS)/lib/$(PCRE)/LICENCE \
|
||||||
$(TEMP)/$(NGINX)/docs/PCRE.LICENCE
|
$(TEMP)/$(NGINX)/docs/PCRE.LICENCE
|
||||||
|
|
||||||
sed -ne '/^ (C) 1995-20/,/^ jloup@gzip\.org/p' \
|
sed -ne '/^ (C) 1995-20/,/^ jloup@gzip\.org/p' \
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ make -f misc/GNUmakefile release
|
||||||
|
|
||||||
the required tools:
|
the required tools:
|
||||||
*) xsltproc to build CHANGES,
|
*) xsltproc to build CHANGES,
|
||||||
*) xslscript.pl ( https://github.com/nginx/xslscript ) to build XSLTs
|
*) xslscript.pl ( http://hg.nginx.org/xslscript ) to build XSLTs
|
||||||
from XSLScript sources.
|
from XSLScript sources.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@
|
||||||
#define _NGINX_H_INCLUDED_
|
#define _NGINX_H_INCLUDED_
|
||||||
|
|
||||||
|
|
||||||
#define nginx_version 1029005
|
#define nginx_version 1029000
|
||||||
#define NGINX_VERSION "1.29.5"
|
#define NGINX_VERSION "1.29.0"
|
||||||
#define NGINX_VER "nginx/" NGINX_VERSION
|
#define NGINX_VER "nginx/" NGINX_VERSION
|
||||||
|
|
||||||
#ifdef NGX_BUILD
|
#ifdef NGX_BUILD
|
||||||
|
|
|
||||||
|
|
@ -1494,9 +1494,8 @@ ngx_utf8_cpystrn(u_char *dst, u_char *src, size_t n, size_t len)
|
||||||
uintptr_t
|
uintptr_t
|
||||||
ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
|
ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
|
||||||
{
|
{
|
||||||
u_char prefix;
|
|
||||||
uint32_t *escape;
|
|
||||||
ngx_uint_t n;
|
ngx_uint_t n;
|
||||||
|
uint32_t *escape;
|
||||||
static u_char hex[] = "0123456789ABCDEF";
|
static u_char hex[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1634,36 +1633,11 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
|
||||||
|
|
||||||
/* mail_auth is the same as memcached */
|
/* mail_auth is the same as memcached */
|
||||||
|
|
||||||
/* " ", "+", "=", not allowed */
|
|
||||||
|
|
||||||
static uint32_t mail_xtext[] = {
|
|
||||||
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
|
||||||
|
|
||||||
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
|
|
||||||
0x20000801, /* 0010 0000 0000 0000 0000 1000 0000 0001 */
|
|
||||||
|
|
||||||
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
|
|
||||||
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
|
|
||||||
|
|
||||||
/* ~}| {zyx wvut srqp onml kjih gfed cba` */
|
|
||||||
0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
|
|
||||||
|
|
||||||
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
|
||||||
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
|
||||||
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
|
||||||
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
|
||||||
};
|
|
||||||
|
|
||||||
static uint32_t *map[] =
|
static uint32_t *map[] =
|
||||||
{ uri, args, uri_component, html, refresh, memcached, memcached,
|
{ uri, args, uri_component, html, refresh, memcached, memcached };
|
||||||
mail_xtext };
|
|
||||||
|
|
||||||
static u_char map_char[] =
|
|
||||||
{ '%', '%', '%', '%', '%', '%', '%', '+' };
|
|
||||||
|
|
||||||
|
|
||||||
escape = map[type];
|
escape = map[type];
|
||||||
prefix = map_char[type];
|
|
||||||
|
|
||||||
if (dst == NULL) {
|
if (dst == NULL) {
|
||||||
|
|
||||||
|
|
@ -1684,7 +1658,7 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
|
||||||
|
|
||||||
while (size) {
|
while (size) {
|
||||||
if (escape[*src >> 5] & (1U << (*src & 0x1f))) {
|
if (escape[*src >> 5] & (1U << (*src & 0x1f))) {
|
||||||
*dst++ = prefix;
|
*dst++ = '%';
|
||||||
*dst++ = hex[*src >> 4];
|
*dst++ = hex[*src >> 4];
|
||||||
*dst++ = hex[*src & 0xf];
|
*dst++ = hex[*src & 0xf];
|
||||||
src++;
|
src++;
|
||||||
|
|
|
||||||
|
|
@ -203,7 +203,6 @@ u_char *ngx_utf8_cpystrn(u_char *dst, u_char *src, size_t n, size_t len);
|
||||||
#define NGX_ESCAPE_REFRESH 4
|
#define NGX_ESCAPE_REFRESH 4
|
||||||
#define NGX_ESCAPE_MEMCACHED 5
|
#define NGX_ESCAPE_MEMCACHED 5
|
||||||
#define NGX_ESCAPE_MAIL_AUTH 6
|
#define NGX_ESCAPE_MAIL_AUTH 6
|
||||||
#define NGX_ESCAPE_MAIL_XTEXT 7
|
|
||||||
|
|
||||||
#define NGX_UNESCAPE_URI 1
|
#define NGX_UNESCAPE_URI 1
|
||||||
#define NGX_UNESCAPE_REDIRECT 2
|
#define NGX_UNESCAPE_REDIRECT 2
|
||||||
|
|
|
||||||
|
|
@ -10,15 +10,6 @@
|
||||||
#include <ngx_event.h>
|
#include <ngx_event.h>
|
||||||
|
|
||||||
|
|
||||||
/* NetBSD up to 10.0 incompatibly defines kevent.udata as "intptr_t" */
|
|
||||||
|
|
||||||
#if (__NetBSD__ && __NetBSD_Version__ < 1000000000)
|
|
||||||
#define NGX_KQUEUE_UDATA_T
|
|
||||||
#else
|
|
||||||
#define NGX_KQUEUE_UDATA_T (void *)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_uint_t changes;
|
ngx_uint_t changes;
|
||||||
ngx_uint_t events;
|
ngx_uint_t events;
|
||||||
|
|
@ -200,7 +191,7 @@ ngx_kqueue_init(ngx_cycle_t *cycle, ngx_msec_t timer)
|
||||||
kev.flags = EV_ADD|EV_ENABLE;
|
kev.flags = EV_ADD|EV_ENABLE;
|
||||||
kev.fflags = 0;
|
kev.fflags = 0;
|
||||||
kev.data = timer;
|
kev.data = timer;
|
||||||
kev.udata = NGX_KQUEUE_UDATA_T (uintptr_t) 0;
|
kev.udata = 0;
|
||||||
|
|
||||||
ts.tv_sec = 0;
|
ts.tv_sec = 0;
|
||||||
ts.tv_nsec = 0;
|
ts.tv_nsec = 0;
|
||||||
|
|
@ -246,7 +237,7 @@ ngx_kqueue_notify_init(ngx_log_t *log)
|
||||||
notify_kev.data = 0;
|
notify_kev.data = 0;
|
||||||
notify_kev.flags = EV_ADD|EV_CLEAR;
|
notify_kev.flags = EV_ADD|EV_CLEAR;
|
||||||
notify_kev.fflags = 0;
|
notify_kev.fflags = 0;
|
||||||
notify_kev.udata = NGX_KQUEUE_UDATA_T (uintptr_t) 0;
|
notify_kev.udata = 0;
|
||||||
|
|
||||||
if (kevent(ngx_kqueue, ¬ify_kev, 1, NULL, 0, NULL) == -1) {
|
if (kevent(ngx_kqueue, ¬ify_kev, 1, NULL, 0, NULL) == -1) {
|
||||||
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
|
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,6 @@
|
||||||
#include <ngx_core.h>
|
#include <ngx_core.h>
|
||||||
#include <ngx_event.h>
|
#include <ngx_event.h>
|
||||||
|
|
||||||
#if (NGX_ZLIB && defined TLSEXT_cert_compression_zlib)
|
|
||||||
#include <zlib.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define NGX_SSL_PASSWORD_BUFFER_SIZE 4096
|
#define NGX_SSL_PASSWORD_BUFFER_SIZE 4096
|
||||||
|
|
||||||
|
|
@ -23,13 +19,6 @@ typedef struct {
|
||||||
|
|
||||||
|
|
||||||
static ngx_inline ngx_int_t ngx_ssl_cert_already_in_hash(void);
|
static ngx_inline ngx_int_t ngx_ssl_cert_already_in_hash(void);
|
||||||
#if (NGX_ZLIB && defined TLSEXT_cert_compression_zlib)
|
|
||||||
static int ngx_ssl_cert_compression_callback(ngx_ssl_conn_t *ssl_conn,
|
|
||||||
CBB *out, const uint8_t *in, size_t in_len);
|
|
||||||
static void *ngx_ssl_cert_compression_alloc(void *opaque, u_int items,
|
|
||||||
u_int size);
|
|
||||||
static void ngx_ssl_cert_compression_free(void *opaque, void *address);
|
|
||||||
#endif
|
|
||||||
static int ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store);
|
static int ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store);
|
||||||
static void ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where,
|
static void ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where,
|
||||||
int ret);
|
int ret);
|
||||||
|
|
@ -139,8 +128,6 @@ int ngx_ssl_ticket_keys_index;
|
||||||
int ngx_ssl_ocsp_index;
|
int ngx_ssl_ocsp_index;
|
||||||
int ngx_ssl_index;
|
int ngx_ssl_index;
|
||||||
int ngx_ssl_certificate_name_index;
|
int ngx_ssl_certificate_name_index;
|
||||||
int ngx_ssl_certificate_comp_index;
|
|
||||||
int ngx_ssl_client_hello_arg_index;
|
|
||||||
|
|
||||||
|
|
||||||
u_char ngx_ssl_session_buffer[NGX_SSL_MAX_SESSION_SIZE];
|
u_char ngx_ssl_session_buffer[NGX_SSL_MAX_SESSION_SIZE];
|
||||||
|
|
@ -283,21 +270,6 @@ ngx_ssl_init(ngx_log_t *log)
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_ssl_certificate_comp_index = X509_get_ex_new_index(0, NULL, NULL, NULL,
|
|
||||||
NULL);
|
|
||||||
if (ngx_ssl_certificate_comp_index == -1) {
|
|
||||||
ngx_ssl_error(NGX_LOG_ALERT, log, 0, "X509_get_ex_new_index() failed");
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngx_ssl_client_hello_arg_index = SSL_CTX_get_ex_new_index(0, NULL, NULL,
|
|
||||||
NULL, NULL);
|
|
||||||
if (ngx_ssl_client_hello_arg_index == -1) {
|
|
||||||
ngx_ssl_error(NGX_LOG_ALERT, log, 0,
|
|
||||||
"SSL_CTX_get_ex_new_index() failed");
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -415,11 +387,6 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
|
||||||
SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_COMPRESSION);
|
SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_COMPRESSION);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SSL_OP_NO_TX_CERTIFICATE_COMPRESSION
|
|
||||||
SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TX_CERTIFICATE_COMPRESSION);
|
|
||||||
SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_RX_CERTIFICATE_COMPRESSION);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SSL_OP_NO_ANTI_REPLAY
|
#ifdef SSL_OP_NO_ANTI_REPLAY
|
||||||
SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_ANTI_REPLAY);
|
SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_ANTI_REPLAY);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -477,18 +444,10 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
|
||||||
{
|
{
|
||||||
char *err;
|
char *err;
|
||||||
X509 *x509, **elm;
|
X509 *x509, **elm;
|
||||||
u_long n;
|
|
||||||
EVP_PKEY *pkey;
|
EVP_PKEY *pkey;
|
||||||
ngx_uint_t mask;
|
|
||||||
STACK_OF(X509) *chain;
|
STACK_OF(X509) *chain;
|
||||||
|
|
||||||
mask = 0;
|
chain = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_CERT, &err, cert, NULL);
|
||||||
elm = NULL;
|
|
||||||
|
|
||||||
retry:
|
|
||||||
|
|
||||||
chain = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_CERT | mask,
|
|
||||||
&err, cert, NULL);
|
|
||||||
if (chain == NULL) {
|
if (chain == NULL) {
|
||||||
if (err != NULL) {
|
if (err != NULL) {
|
||||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
||||||
|
|
@ -528,7 +487,6 @@ retry:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elm == NULL) {
|
|
||||||
elm = ngx_array_push(&ssl->certs);
|
elm = ngx_array_push(&ssl->certs);
|
||||||
if (elm == NULL) {
|
if (elm == NULL) {
|
||||||
X509_free(x509);
|
X509_free(x509);
|
||||||
|
|
@ -536,10 +494,6 @@ retry:
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
X509_free(*elm);
|
|
||||||
}
|
|
||||||
|
|
||||||
*elm = x509;
|
*elm = x509;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -560,21 +514,11 @@ retry:
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
/* SSL_CTX_set0_chain() is only available in OpenSSL 1.0.2+ */
|
/* SSL_CTX_set0_chain() is only available in OpenSSL 1.0.2+ */
|
||||||
|
|
||||||
#ifdef SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS
|
|
||||||
/* OpenSSL 1.0.1+ */
|
|
||||||
SSL_CTX_clear_extra_chain_certs(ssl->ctx);
|
|
||||||
#else
|
|
||||||
|
|
||||||
if (ssl->ctx->extra_certs) {
|
|
||||||
sk_X509_pop_free(ssl->ctx->extra_certs, X509_free);
|
|
||||||
ssl->ctx->extra_certs = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
n = sk_X509_num(chain);
|
n = sk_X509_num(chain);
|
||||||
|
|
||||||
while (n--) {
|
while (n--) {
|
||||||
|
|
@ -590,11 +534,10 @@ retry:
|
||||||
}
|
}
|
||||||
|
|
||||||
sk_X509_free(chain);
|
sk_X509_free(chain);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pkey = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_PKEY | mask,
|
pkey = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_PKEY, &err, key, passwords);
|
||||||
&err, key, passwords);
|
|
||||||
if (pkey == NULL) {
|
if (pkey == NULL) {
|
||||||
if (err != NULL) {
|
if (err != NULL) {
|
||||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
||||||
|
|
@ -606,23 +549,9 @@ retry:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SSL_CTX_use_PrivateKey(ssl->ctx, pkey) == 0) {
|
if (SSL_CTX_use_PrivateKey(ssl->ctx, pkey) == 0) {
|
||||||
EVP_PKEY_free(pkey);
|
|
||||||
|
|
||||||
/* there can be mismatched pairs on uneven cache update */
|
|
||||||
|
|
||||||
n = ERR_peek_last_error();
|
|
||||||
|
|
||||||
if (ERR_GET_LIB(n) == ERR_LIB_X509
|
|
||||||
&& ERR_GET_REASON(n) == X509_R_KEY_VALUES_MISMATCH
|
|
||||||
&& mask == 0)
|
|
||||||
{
|
|
||||||
ERR_clear_error();
|
|
||||||
mask = NGX_SSL_CACHE_INVALIDATE;
|
|
||||||
goto retry;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
||||||
"SSL_CTX_use_PrivateKey(\"%s\") failed", key->data);
|
"SSL_CTX_use_PrivateKey(\"%s\") failed", key->data);
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -730,197 +659,6 @@ retry:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t
|
|
||||||
ngx_ssl_certificate_compression(ngx_conf_t *cf, ngx_ssl_t *ssl,
|
|
||||||
ngx_uint_t enable)
|
|
||||||
{
|
|
||||||
if (!enable) {
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SSL_OP_NO_TX_CERTIFICATE_COMPRESSION
|
|
||||||
|
|
||||||
if (SSL_CTX_compress_certs(ssl->ctx, 0) == 0) {
|
|
||||||
ngx_ssl_error(NGX_LOG_WARN, ssl->log, 0,
|
|
||||||
"SSL_CTX_compress_certs() failed, ignored");
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
SSL_CTX_clear_options(ssl->ctx, SSL_OP_NO_TX_CERTIFICATE_COMPRESSION);
|
|
||||||
|
|
||||||
#elif (NGX_ZLIB && defined TLSEXT_cert_compression_zlib)
|
|
||||||
|
|
||||||
if (SSL_CTX_add_cert_compression_alg(ssl->ctx, TLSEXT_cert_compression_zlib,
|
|
||||||
ngx_ssl_cert_compression_callback,
|
|
||||||
NULL)
|
|
||||||
== 0)
|
|
||||||
{
|
|
||||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
|
||||||
"SSL_CTX_add_cert_compression_alg() failed");
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
|
|
||||||
"\"ssl_certificate_compression\" is not supported "
|
|
||||||
"on this platform, ignored");
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if (NGX_ZLIB && defined TLSEXT_cert_compression_zlib)
|
|
||||||
|
|
||||||
static int
|
|
||||||
ngx_ssl_cert_compression_callback(ngx_ssl_conn_t *ssl_conn, CBB *out,
|
|
||||||
const uint8_t *in, size_t in_len)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
X509 *cert;
|
|
||||||
u_char *p;
|
|
||||||
z_stream zstream;
|
|
||||||
ngx_str_t *comp, tmp;
|
|
||||||
ngx_pool_t *pool;
|
|
||||||
ngx_connection_t *c;
|
|
||||||
|
|
||||||
#ifdef OPENSSL_IS_BORINGSSL
|
|
||||||
{
|
|
||||||
SSL_CTX *ssl_ctx;
|
|
||||||
ngx_ssl_t *ssl;
|
|
||||||
|
|
||||||
/* BoringSSL doesn't have certificate slots, we take the last set */
|
|
||||||
|
|
||||||
ssl_ctx = SSL_get_SSL_CTX(ssl_conn);
|
|
||||||
ssl = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_index);
|
|
||||||
cert = ((X509 **) ssl->certs.elts)[ssl->certs.nelts - 1];
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AWS-LC saves leaf certificate in SSL to associate with SSL_CTX,
|
|
||||||
* see https://github.com/aws/aws-lc/commit/e1ba2b3e5
|
|
||||||
*/
|
|
||||||
|
|
||||||
cert = SSL_get_certificate(ssl_conn);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
comp = X509_get_ex_data(cert, ngx_ssl_certificate_comp_index);
|
|
||||||
|
|
||||||
if (comp != NULL) {
|
|
||||||
return CBB_add_bytes(out, comp->data, comp->len);
|
|
||||||
}
|
|
||||||
|
|
||||||
c = ngx_ssl_get_connection(ssl_conn);
|
|
||||||
|
|
||||||
pool = ngx_create_pool(256, c->log);
|
|
||||||
if (pool == NULL) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pool->log = c->log;
|
|
||||||
|
|
||||||
ngx_memzero(&zstream, sizeof(z_stream));
|
|
||||||
|
|
||||||
zstream.zalloc = ngx_ssl_cert_compression_alloc;
|
|
||||||
zstream.zfree = ngx_ssl_cert_compression_free;
|
|
||||||
zstream.opaque = pool;
|
|
||||||
|
|
||||||
rc = deflateInit(&zstream, Z_DEFAULT_COMPRESSION);
|
|
||||||
|
|
||||||
if (rc != Z_OK) {
|
|
||||||
ngx_log_error(NGX_LOG_ALERT, c->log, 0, "deflateInit() failed: %d", rc);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp.len = deflateBound(&zstream, in_len);
|
|
||||||
tmp.data = ngx_palloc(pool, tmp.len);
|
|
||||||
if (tmp.data == NULL) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
zstream.next_in = (u_char *) in;
|
|
||||||
zstream.avail_in = in_len;
|
|
||||||
zstream.next_out = tmp.data;
|
|
||||||
zstream.avail_out = tmp.len;
|
|
||||||
|
|
||||||
rc = deflate(&zstream, Z_FINISH);
|
|
||||||
|
|
||||||
if (rc != Z_STREAM_END) {
|
|
||||||
ngx_log_error(NGX_LOG_ALERT, c->log, 0,
|
|
||||||
"deflate(Z_FINISH) failed: %d", rc);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp.len -= zstream.avail_out;
|
|
||||||
|
|
||||||
rc = deflateEnd(&zstream);
|
|
||||||
|
|
||||||
if (rc != Z_OK) {
|
|
||||||
ngx_log_error(NGX_LOG_ALERT, c->log, 0, "deflateEnd() failed: %d", rc);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = ngx_alloc(sizeof(ngx_str_t) + tmp.len, c->log);
|
|
||||||
if (p == NULL) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
comp = (ngx_str_t *) p;
|
|
||||||
|
|
||||||
comp->len = tmp.len;
|
|
||||||
comp->data = p + sizeof(ngx_str_t);
|
|
||||||
|
|
||||||
ngx_memcpy(comp->data, tmp.data, tmp.len);
|
|
||||||
|
|
||||||
if (X509_set_ex_data(cert, ngx_ssl_certificate_comp_index, p) == 0) {
|
|
||||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_set_ex_data() failed");
|
|
||||||
ngx_free(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = CBB_add_bytes(out, tmp.data, tmp.len);
|
|
||||||
|
|
||||||
ngx_destroy_pool(pool);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
error:
|
|
||||||
|
|
||||||
ngx_destroy_pool(pool);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void *
|
|
||||||
ngx_ssl_cert_compression_alloc(void *opaque, u_int items, u_int size)
|
|
||||||
{
|
|
||||||
ngx_pool_t *pool = opaque;
|
|
||||||
|
|
||||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pool->log, 0,
|
|
||||||
"cert compression alloc: n:%ud s:%ud", items, size);
|
|
||||||
|
|
||||||
return ngx_palloc(pool, items * size);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
ngx_ssl_cert_compression_free(void *opaque, void *address)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
ngx_pool_t *pool = opaque;
|
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pool->log, 0,
|
|
||||||
"cert compression free: %p", address);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t
|
ngx_int_t
|
||||||
ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers,
|
ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers,
|
||||||
ngx_uint_t prefer_server_ciphers)
|
ngx_uint_t prefer_server_ciphers)
|
||||||
|
|
@ -1636,7 +1374,7 @@ ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file)
|
||||||
if (SSL_CTX_set0_tmp_dh_pkey(ssl->ctx, dh) != 1) {
|
if (SSL_CTX_set0_tmp_dh_pkey(ssl->ctx, dh) != 1) {
|
||||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
||||||
"SSL_CTX_set0_tmp_dh_pkey(\"%s\") failed", file->data);
|
"SSL_CTX_set0_tmp_dh_pkey(\"%s\") failed", file->data);
|
||||||
#if (OPENSSL_VERSION_NUMBER >= 0x30000010L)
|
#if (OPENSSL_VERSION_NUMBER >= 0x3000001fL)
|
||||||
EVP_PKEY_free(dh);
|
EVP_PKEY_free(dh);
|
||||||
#endif
|
#endif
|
||||||
BIO_free(bio);
|
BIO_free(bio);
|
||||||
|
|
@ -1653,105 +1391,6 @@ ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t
|
|
||||||
ngx_ssl_ech_files(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *filenames)
|
|
||||||
{
|
|
||||||
#ifdef SSL_OP_ECH_GREASE
|
|
||||||
int numkeys;
|
|
||||||
BIO *in;
|
|
||||||
ngx_int_t rc;
|
|
||||||
ngx_str_t *filename;
|
|
||||||
ngx_uint_t i;
|
|
||||||
OSSL_ECHSTORE *es;
|
|
||||||
|
|
||||||
if (filenames == NULL) {
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
es = OSSL_ECHSTORE_new(NULL, NULL);
|
|
||||||
if (es == NULL) {
|
|
||||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "OSSL_ECHSTORE_new() failed");
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = NGX_ERROR;
|
|
||||||
filename = filenames->elts;
|
|
||||||
|
|
||||||
for (i = 0; i < filenames->nelts; i++) {
|
|
||||||
|
|
||||||
if (ngx_conf_full_name(cf->cycle, &filename[i], 1) != NGX_OK) {
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
in = BIO_new_file((char *) filename[i].data, "r");
|
|
||||||
if (in == NULL) {
|
|
||||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
|
||||||
"BIO_new_file(\"%s\") failed", filename[i].data);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We only set the ECHConfigList from the first file read to use
|
|
||||||
* in ECH retry-configs.
|
|
||||||
*
|
|
||||||
* That allows many sensible key rotation schemes so that the
|
|
||||||
* values sent in ECH retry-configs are smaller and current.
|
|
||||||
* For example, if the first file name has the current ECH
|
|
||||||
* private key, and a second one has the previously used key
|
|
||||||
* that some clients may still use due to DNS caching.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (OSSL_ECHSTORE_read_pem(es, in, i ? OSSL_ECH_NO_RETRY
|
|
||||||
: OSSL_ECH_FOR_RETRY)
|
|
||||||
!= 1)
|
|
||||||
{
|
|
||||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
|
||||||
"OSSL_ECHSTORE_read_pem(%s) failed",
|
|
||||||
filename[i].data);
|
|
||||||
BIO_free(in);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
BIO_free(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* load the ECH store after checking there's at least one ECH
|
|
||||||
* private key in there (the PEM file spec allows zero or one
|
|
||||||
* private key per file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (OSSL_ECHSTORE_num_keys(es, &numkeys) != 1) {
|
|
||||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
|
||||||
"OSSL_ECHSTORE_num_keys(%s) failed");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (numkeys > 0 && SSL_CTX_set1_echstore(ssl->ctx, es) != 1) {
|
|
||||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
|
||||||
"SSL_CTX_set1_echstore() failed");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = NGX_OK;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
|
|
||||||
OSSL_ECHSTORE_free(es);
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
#else
|
|
||||||
if (filenames != NULL) {
|
|
||||||
ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
|
|
||||||
"\"ssl_ech_file\" is not supported on this platform, "
|
|
||||||
"ignored");
|
|
||||||
}
|
|
||||||
|
|
||||||
return NGX_OK;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t
|
ngx_int_t
|
||||||
ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name)
|
ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name)
|
||||||
{
|
{
|
||||||
|
|
@ -1971,131 +1610,6 @@ ngx_ssl_new_client_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t
|
|
||||||
ngx_ssl_set_client_hello_callback(ngx_ssl_t *ssl, ngx_ssl_client_hello_arg *cb)
|
|
||||||
{
|
|
||||||
#ifdef SSL_CLIENT_HELLO_SUCCESS
|
|
||||||
|
|
||||||
SSL_CTX_set_client_hello_cb(ssl->ctx, ngx_ssl_client_hello_callback, NULL);
|
|
||||||
|
|
||||||
if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_client_hello_arg_index, cb) == 0)
|
|
||||||
{
|
|
||||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
|
||||||
"SSL_CTX_set_ex_data() failed");
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined OPENSSL_IS_BORINGSSL
|
|
||||||
|
|
||||||
SSL_CTX_set_select_certificate_cb(ssl->ctx, ngx_ssl_select_certificate);
|
|
||||||
|
|
||||||
if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_client_hello_arg_index, cb) == 0)
|
|
||||||
{
|
|
||||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
|
||||||
"SSL_CTX_set_ex_data() failed");
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef SSL_CLIENT_HELLO_SUCCESS
|
|
||||||
|
|
||||||
int
|
|
||||||
ngx_ssl_client_hello_callback(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
|
||||||
{
|
|
||||||
u_char *p;
|
|
||||||
size_t len;
|
|
||||||
ngx_int_t rc;
|
|
||||||
ngx_str_t host;
|
|
||||||
ngx_connection_t *c;
|
|
||||||
ngx_ssl_client_hello_arg *cb;
|
|
||||||
|
|
||||||
c = ngx_ssl_get_connection(ssl_conn);
|
|
||||||
cb = SSL_CTX_get_ex_data(c->ssl->session_ctx,
|
|
||||||
ngx_ssl_client_hello_arg_index);
|
|
||||||
|
|
||||||
if (SSL_client_hello_get0_ext(ssl_conn, TLSEXT_TYPE_server_name,
|
|
||||||
(const unsigned char **) &p, &len)
|
|
||||||
== 0)
|
|
||||||
{
|
|
||||||
ngx_str_null(&host);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* RFC 6066 mandates non-zero HostName length, we follow OpenSSL.
|
|
||||||
* No more than one ServerName is expected.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (len < 5
|
|
||||||
|| (size_t) (p[0] << 8) + p[1] + 2 != len
|
|
||||||
|| p[2] != TLSEXT_NAMETYPE_host_name
|
|
||||||
|| (size_t) (p[3] << 8) + p[4] + 2 + 3 != len)
|
|
||||||
{
|
|
||||||
*ad = SSL_AD_DECODE_ERROR;
|
|
||||||
return SSL_CLIENT_HELLO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
len -= 5;
|
|
||||||
p += 5;
|
|
||||||
|
|
||||||
if (len > TLSEXT_MAXLEN_host_name || ngx_strlchr(p, p + len, '\0')) {
|
|
||||||
*ad = SSL_AD_UNRECOGNIZED_NAME;
|
|
||||||
return SSL_CLIENT_HELLO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
host.len = len;
|
|
||||||
host.data = p;
|
|
||||||
|
|
||||||
done:
|
|
||||||
|
|
||||||
rc = cb->servername(ssl_conn, ad, &host);
|
|
||||||
|
|
||||||
if (rc == SSL_TLSEXT_ERR_ALERT_FATAL) {
|
|
||||||
return SSL_CLIENT_HELLO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return SSL_CLIENT_HELLO_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined OPENSSL_IS_BORINGSSL
|
|
||||||
|
|
||||||
enum ssl_select_cert_result_t ngx_ssl_select_certificate(
|
|
||||||
const SSL_CLIENT_HELLO *client_hello)
|
|
||||||
{
|
|
||||||
int ad;
|
|
||||||
ngx_int_t rc;
|
|
||||||
ngx_ssl_conn_t *ssl_conn;
|
|
||||||
ngx_connection_t *c;
|
|
||||||
ngx_ssl_client_hello_arg *cb;
|
|
||||||
|
|
||||||
ssl_conn = client_hello->ssl;
|
|
||||||
c = ngx_ssl_get_connection(ssl_conn);
|
|
||||||
cb = SSL_CTX_get_ex_data(c->ssl->session_ctx,
|
|
||||||
ngx_ssl_client_hello_arg_index);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* BoringSSL sends a hardcoded "handshake_failure" alert on errors,
|
|
||||||
* we use it to map SSL_AD_INTERNAL_ERROR. To preserve other alert
|
|
||||||
* values, error handling is postponed to the servername callback.
|
|
||||||
*/
|
|
||||||
|
|
||||||
rc = cb->servername(ssl_conn, &ad, NULL);
|
|
||||||
|
|
||||||
if (rc == SSL_TLSEXT_ERR_ALERT_FATAL && ad == SSL_AD_INTERNAL_ERROR) {
|
|
||||||
return ssl_select_cert_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ssl_select_cert_success;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t
|
ngx_int_t
|
||||||
ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags)
|
ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags)
|
||||||
{
|
{
|
||||||
|
|
@ -4012,7 +3526,6 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
|
||||||
|| n == SSL_R_TLSV1_ALERT_USER_CANCELLED /* 1090 */
|
|| n == SSL_R_TLSV1_ALERT_USER_CANCELLED /* 1090 */
|
||||||
|| n == SSL_R_TLSV1_ALERT_NO_RENEGOTIATION /* 1100 */
|
|| n == SSL_R_TLSV1_ALERT_NO_RENEGOTIATION /* 1100 */
|
||||||
#endif
|
#endif
|
||||||
|| n == 1121 /* SSL_R_TLSV1_ALERT_ECH_REQUIRED */
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
switch (c->log_error) {
|
switch (c->log_error) {
|
||||||
|
|
@ -5244,19 +4757,10 @@ ngx_ssl_cleanup_ctx(void *data)
|
||||||
ngx_ssl_t *ssl = data;
|
ngx_ssl_t *ssl = data;
|
||||||
|
|
||||||
X509 *cert;
|
X509 *cert;
|
||||||
u_char *p;
|
|
||||||
ngx_uint_t i;
|
ngx_uint_t i;
|
||||||
|
|
||||||
for (i = 0; i < ssl->certs.nelts; i++) {
|
for (i = 0; i < ssl->certs.nelts; i++) {
|
||||||
cert = ((X509 **) ssl->certs.elts)[i];
|
cert = ((X509 **) ssl->certs.elts)[i];
|
||||||
|
|
||||||
p = X509_get_ex_data(cert, ngx_ssl_certificate_comp_index);
|
|
||||||
|
|
||||||
if (p) {
|
|
||||||
ngx_free(p);
|
|
||||||
X509_set_ex_data(cert, ngx_ssl_certificate_comp_index, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
X509_free(cert);
|
X509_free(cert);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5551,7 +5055,11 @@ ngx_ssl_get_curve(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (OPENSSL_VERSION_NUMBER >= 0x3000000fL)
|
||||||
name = SSL_group_to_name(c->ssl->connection, nid);
|
name = SSL_group_to_name(c->ssl->connection, nid);
|
||||||
|
#else
|
||||||
|
name = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
s->len = name ? ngx_strlen(name) : sizeof("0x0000") - 1;
|
s->len = name ? ngx_strlen(name) : sizeof("0x0000") - 1;
|
||||||
s->data = ngx_pnalloc(pool, s->len);
|
s->data = ngx_pnalloc(pool, s->len);
|
||||||
|
|
@ -5605,7 +5113,11 @@ ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
||||||
nid = curves[i];
|
nid = curves[i];
|
||||||
|
|
||||||
if (nid & TLSEXT_nid_unknown) {
|
if (nid & TLSEXT_nid_unknown) {
|
||||||
|
#if (OPENSSL_VERSION_NUMBER >= 0x3000000fL)
|
||||||
name = SSL_group_to_name(c->ssl->connection, nid);
|
name = SSL_group_to_name(c->ssl->connection, nid);
|
||||||
|
#else
|
||||||
|
name = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
len += name ? ngx_strlen(name) : sizeof("0x0000") - 1;
|
len += name ? ngx_strlen(name) : sizeof("0x0000") - 1;
|
||||||
|
|
||||||
|
|
@ -5627,7 +5139,11 @@ ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
||||||
nid = curves[i];
|
nid = curves[i];
|
||||||
|
|
||||||
if (nid & TLSEXT_nid_unknown) {
|
if (nid & TLSEXT_nid_unknown) {
|
||||||
|
#if (OPENSSL_VERSION_NUMBER >= 0x3000000fL)
|
||||||
name = SSL_group_to_name(c->ssl->connection, nid);
|
name = SSL_group_to_name(c->ssl->connection, nid);
|
||||||
|
#else
|
||||||
|
name = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
p = name ? ngx_cpymem(p, name, ngx_strlen(name))
|
p = name ? ngx_cpymem(p, name, ngx_strlen(name))
|
||||||
: ngx_sprintf(p, "0x%04xd", nid & 0xffff);
|
: ngx_sprintf(p, "0x%04xd", nid & 0xffff);
|
||||||
|
|
@ -5653,32 +5169,6 @@ ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t
|
|
||||||
ngx_ssl_get_sigalg(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
|
||||||
{
|
|
||||||
#ifdef SSL_get0_signature_name
|
|
||||||
|
|
||||||
const char *name;
|
|
||||||
|
|
||||||
if (SSL_get0_signature_name(c->ssl->connection, &name)) {
|
|
||||||
s->len = ngx_strlen(name);
|
|
||||||
s->data = ngx_pnalloc(pool, s->len);
|
|
||||||
if (s->data == NULL) {
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngx_memcpy(s->data, name, s->len);
|
|
||||||
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
s->len = 0;
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t
|
ngx_int_t
|
||||||
ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
||||||
{
|
{
|
||||||
|
|
@ -5808,81 +5298,6 @@ ngx_ssl_get_alpn_protocol(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t
|
|
||||||
ngx_ssl_get_ech_status(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
|
||||||
{
|
|
||||||
#ifdef SSL_OP_ECH_GREASE
|
|
||||||
int echrv;
|
|
||||||
char *inner_sni, *outer_sni;
|
|
||||||
|
|
||||||
inner_sni = NULL;
|
|
||||||
outer_sni = NULL;
|
|
||||||
|
|
||||||
echrv = SSL_ech_get1_status(c->ssl->connection, &inner_sni, &outer_sni);
|
|
||||||
|
|
||||||
switch (echrv) {
|
|
||||||
case SSL_ECH_STATUS_NOT_TRIED:
|
|
||||||
ngx_str_set(s, "NOT_TRIED");
|
|
||||||
break;
|
|
||||||
case SSL_ECH_STATUS_SUCCESS:
|
|
||||||
ngx_str_set(s, "SUCCESS");
|
|
||||||
break;
|
|
||||||
case SSL_ECH_STATUS_GREASE:
|
|
||||||
ngx_str_set(s, "GREASE");
|
|
||||||
break;
|
|
||||||
case SSL_ECH_STATUS_BACKEND:
|
|
||||||
ngx_str_set(s, "BACKEND");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ngx_str_set(s, "FAILED");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
OPENSSL_free(inner_sni);
|
|
||||||
OPENSSL_free(outer_sni);
|
|
||||||
#else
|
|
||||||
s->len = 0;
|
|
||||||
#endif
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t
|
|
||||||
ngx_ssl_get_ech_outer_server_name(ngx_connection_t *c, ngx_pool_t *pool,
|
|
||||||
ngx_str_t *s)
|
|
||||||
{
|
|
||||||
#if defined(SSL_OP_ECH_GREASE)
|
|
||||||
int echrv;
|
|
||||||
char *inner_sni, *outer_sni;
|
|
||||||
|
|
||||||
inner_sni = NULL;
|
|
||||||
outer_sni = NULL;
|
|
||||||
|
|
||||||
echrv = SSL_ech_get1_status(c->ssl->connection, &inner_sni, &outer_sni);
|
|
||||||
|
|
||||||
if (echrv == SSL_ECH_STATUS_SUCCESS && outer_sni) {
|
|
||||||
s->len = ngx_strlen(outer_sni);
|
|
||||||
|
|
||||||
s->data = ngx_pnalloc(pool, s->len);
|
|
||||||
if (s->data == NULL) {
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngx_memcpy(s->data, outer_sni, s->len);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
s->len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
OPENSSL_free(inner_sni);
|
|
||||||
OPENSSL_free(outer_sni);
|
|
||||||
#else
|
|
||||||
s->len = 0;
|
|
||||||
#endif
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t
|
ngx_int_t
|
||||||
ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
||||||
{
|
{
|
||||||
|
|
@ -6499,32 +5914,6 @@ ngx_ssl_parse_time(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t
|
|
||||||
ngx_ssl_get_client_sigalg(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
|
||||||
{
|
|
||||||
#ifdef SSL_get0_peer_signature_name
|
|
||||||
|
|
||||||
const char *name;
|
|
||||||
|
|
||||||
if (SSL_get0_peer_signature_name(c->ssl->connection, &name)) {
|
|
||||||
s->len = ngx_strlen(name);
|
|
||||||
s->data = ngx_pnalloc(pool, s->len);
|
|
||||||
if (s->data == NULL) {
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngx_memcpy(s->data, name, s->len);
|
|
||||||
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
s->len = 0;
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
ngx_openssl_create_conf(ngx_cycle_t *cycle)
|
ngx_openssl_create_conf(ngx_cycle_t *cycle)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,14 @@
|
||||||
#include <openssl/engine.h>
|
#include <openssl/engine.h>
|
||||||
#endif
|
#endif
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
#if (NGX_QUIC)
|
||||||
|
#ifdef OPENSSL_IS_BORINGSSL
|
||||||
|
#include <openssl/hkdf.h>
|
||||||
|
#include <openssl/chacha.h>
|
||||||
|
#else
|
||||||
|
#include <openssl/kdf.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
#include <openssl/hmac.h>
|
#include <openssl/hmac.h>
|
||||||
#ifndef OPENSSL_NO_OCSP
|
#ifndef OPENSSL_NO_OCSP
|
||||||
#include <openssl/ocsp.h>
|
#include <openssl/ocsp.h>
|
||||||
|
|
@ -88,11 +96,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if (OPENSSL_VERSION_NUMBER < 0x30000000L)
|
|
||||||
#define SSL_group_to_name(s, nid) NULL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct ngx_ssl_ocsp_s ngx_ssl_ocsp_t;
|
typedef struct ngx_ssl_ocsp_s ngx_ssl_ocsp_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -143,7 +146,6 @@ struct ngx_ssl_connection_s {
|
||||||
unsigned in_ocsp:1;
|
unsigned in_ocsp:1;
|
||||||
unsigned early_preread:1;
|
unsigned early_preread:1;
|
||||||
unsigned write_blocked:1;
|
unsigned write_blocked:1;
|
||||||
unsigned sni_accepted:1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -190,13 +192,6 @@ typedef struct {
|
||||||
} ngx_ssl_session_cache_t;
|
} ngx_ssl_session_cache_t;
|
||||||
|
|
||||||
|
|
||||||
typedef int (*ngx_ssl_servername_pt)(ngx_ssl_conn_t *, int *, void *);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
ngx_ssl_servername_pt servername;
|
|
||||||
} ngx_ssl_client_hello_arg;
|
|
||||||
|
|
||||||
|
|
||||||
#define NGX_SSL_SSLv2 0x0002
|
#define NGX_SSL_SSLv2 0x0002
|
||||||
#define NGX_SSL_SSLv3 0x0004
|
#define NGX_SSL_SSLv3 0x0004
|
||||||
#define NGX_SSL_TLSv1 0x0008
|
#define NGX_SSL_TLSv1 0x0008
|
||||||
|
|
@ -236,8 +231,6 @@ ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
|
||||||
ngx_int_t ngx_ssl_connection_certificate(ngx_connection_t *c, ngx_pool_t *pool,
|
ngx_int_t ngx_ssl_connection_certificate(ngx_connection_t *c, ngx_pool_t *pool,
|
||||||
ngx_str_t *cert, ngx_str_t *key, ngx_ssl_cache_t *cache,
|
ngx_str_t *cert, ngx_str_t *key, ngx_ssl_cache_t *cache,
|
||||||
ngx_array_t *passwords);
|
ngx_array_t *passwords);
|
||||||
ngx_int_t ngx_ssl_certificate_compression(ngx_conf_t *cf, ngx_ssl_t *ssl,
|
|
||||||
ngx_uint_t enable);
|
|
||||||
|
|
||||||
ngx_int_t ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers,
|
ngx_int_t ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers,
|
||||||
ngx_uint_t prefer_server_ciphers);
|
ngx_uint_t prefer_server_ciphers);
|
||||||
|
|
@ -271,8 +264,6 @@ ngx_array_t *ngx_ssl_read_password_file(ngx_conf_t *cf, ngx_str_t *file);
|
||||||
ngx_array_t *ngx_ssl_preserve_passwords(ngx_conf_t *cf,
|
ngx_array_t *ngx_ssl_preserve_passwords(ngx_conf_t *cf,
|
||||||
ngx_array_t *passwords);
|
ngx_array_t *passwords);
|
||||||
ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file);
|
ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file);
|
||||||
ngx_int_t ngx_ssl_ech_files(ngx_conf_t *cf, ngx_ssl_t *ssl,
|
|
||||||
ngx_array_t *filename);
|
|
||||||
ngx_int_t ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name);
|
ngx_int_t ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name);
|
||||||
ngx_int_t ngx_ssl_early_data(ngx_conf_t *cf, ngx_ssl_t *ssl,
|
ngx_int_t ngx_ssl_early_data(ngx_conf_t *cf, ngx_ssl_t *ssl,
|
||||||
ngx_uint_t enable);
|
ngx_uint_t enable);
|
||||||
|
|
@ -288,15 +279,6 @@ ngx_int_t ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl,
|
||||||
ngx_array_t *paths);
|
ngx_array_t *paths);
|
||||||
ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data);
|
ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data);
|
||||||
|
|
||||||
ngx_int_t ngx_ssl_set_client_hello_callback(ngx_ssl_t *ssl,
|
|
||||||
ngx_ssl_client_hello_arg *cb);
|
|
||||||
#ifdef SSL_CLIENT_HELLO_SUCCESS
|
|
||||||
int ngx_ssl_client_hello_callback(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg);
|
|
||||||
#elif defined OPENSSL_IS_BORINGSSL
|
|
||||||
enum ssl_select_cert_result_t ngx_ssl_select_certificate(
|
|
||||||
const SSL_CLIENT_HELLO *client_hello);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ngx_int_t ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c,
|
ngx_int_t ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c,
|
||||||
ngx_uint_t flags);
|
ngx_uint_t flags);
|
||||||
|
|
||||||
|
|
@ -330,8 +312,6 @@ ngx_int_t ngx_ssl_get_curve(ngx_connection_t *c, ngx_pool_t *pool,
|
||||||
ngx_str_t *s);
|
ngx_str_t *s);
|
||||||
ngx_int_t ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool,
|
ngx_int_t ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool,
|
||||||
ngx_str_t *s);
|
ngx_str_t *s);
|
||||||
ngx_int_t ngx_ssl_get_sigalg(ngx_connection_t *c, ngx_pool_t *pool,
|
|
||||||
ngx_str_t *s);
|
|
||||||
ngx_int_t ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool,
|
ngx_int_t ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool,
|
||||||
ngx_str_t *s);
|
ngx_str_t *s);
|
||||||
ngx_int_t ngx_ssl_get_session_reused(ngx_connection_t *c, ngx_pool_t *pool,
|
ngx_int_t ngx_ssl_get_session_reused(ngx_connection_t *c, ngx_pool_t *pool,
|
||||||
|
|
@ -340,10 +320,6 @@ ngx_int_t ngx_ssl_get_early_data(ngx_connection_t *c, ngx_pool_t *pool,
|
||||||
ngx_str_t *s);
|
ngx_str_t *s);
|
||||||
ngx_int_t ngx_ssl_get_server_name(ngx_connection_t *c, ngx_pool_t *pool,
|
ngx_int_t ngx_ssl_get_server_name(ngx_connection_t *c, ngx_pool_t *pool,
|
||||||
ngx_str_t *s);
|
ngx_str_t *s);
|
||||||
ngx_int_t ngx_ssl_get_ech_status(ngx_connection_t *c, ngx_pool_t *pool,
|
|
||||||
ngx_str_t *s);
|
|
||||||
ngx_int_t ngx_ssl_get_ech_outer_server_name(ngx_connection_t *c,
|
|
||||||
ngx_pool_t *pool, ngx_str_t *s);
|
|
||||||
ngx_int_t ngx_ssl_get_alpn_protocol(ngx_connection_t *c, ngx_pool_t *pool,
|
ngx_int_t ngx_ssl_get_alpn_protocol(ngx_connection_t *c, ngx_pool_t *pool,
|
||||||
ngx_str_t *s);
|
ngx_str_t *s);
|
||||||
ngx_int_t ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool,
|
ngx_int_t ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool,
|
||||||
|
|
@ -372,8 +348,6 @@ ngx_int_t ngx_ssl_get_client_v_end(ngx_connection_t *c, ngx_pool_t *pool,
|
||||||
ngx_str_t *s);
|
ngx_str_t *s);
|
||||||
ngx_int_t ngx_ssl_get_client_v_remain(ngx_connection_t *c, ngx_pool_t *pool,
|
ngx_int_t ngx_ssl_get_client_v_remain(ngx_connection_t *c, ngx_pool_t *pool,
|
||||||
ngx_str_t *s);
|
ngx_str_t *s);
|
||||||
ngx_int_t ngx_ssl_get_client_sigalg(ngx_connection_t *c, ngx_pool_t *pool,
|
|
||||||
ngx_str_t *s);
|
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t ngx_ssl_handshake(ngx_connection_t *c);
|
ngx_int_t ngx_ssl_handshake(ngx_connection_t *c);
|
||||||
|
|
@ -401,8 +375,6 @@ extern int ngx_ssl_ticket_keys_index;
|
||||||
extern int ngx_ssl_ocsp_index;
|
extern int ngx_ssl_ocsp_index;
|
||||||
extern int ngx_ssl_index;
|
extern int ngx_ssl_index;
|
||||||
extern int ngx_ssl_certificate_name_index;
|
extern int ngx_ssl_certificate_name_index;
|
||||||
extern int ngx_ssl_certificate_comp_index;
|
|
||||||
extern int ngx_ssl_client_hello_arg_index;
|
|
||||||
|
|
||||||
|
|
||||||
extern u_char ngx_ssl_session_buffer[NGX_SSL_MAX_SESSION_SIZE];
|
extern u_char ngx_ssl_session_buffer[NGX_SSL_MAX_SESSION_SIZE];
|
||||||
|
|
|
||||||
|
|
@ -193,7 +193,6 @@ ngx_ssl_cache_fetch(ngx_conf_t *cf, ngx_uint_t index, char **err,
|
||||||
time_t mtime;
|
time_t mtime;
|
||||||
uint32_t hash;
|
uint32_t hash;
|
||||||
ngx_int_t rc;
|
ngx_int_t rc;
|
||||||
ngx_uint_t invalidate;
|
|
||||||
ngx_file_uniq_t uniq;
|
ngx_file_uniq_t uniq;
|
||||||
ngx_file_info_t fi;
|
ngx_file_info_t fi;
|
||||||
ngx_ssl_cache_t *cache, *old_cache;
|
ngx_ssl_cache_t *cache, *old_cache;
|
||||||
|
|
@ -203,17 +202,10 @@ ngx_ssl_cache_fetch(ngx_conf_t *cf, ngx_uint_t index, char **err,
|
||||||
|
|
||||||
*err = NULL;
|
*err = NULL;
|
||||||
|
|
||||||
invalidate = index & NGX_SSL_CACHE_INVALIDATE;
|
|
||||||
index &= ~NGX_SSL_CACHE_INVALIDATE;
|
|
||||||
|
|
||||||
if (ngx_ssl_cache_init_key(cf->pool, index, path, &id) != NGX_OK) {
|
if (ngx_ssl_cache_init_key(cf->pool, index, path, &id) != NGX_OK) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id.type == NGX_SSL_CACHE_DATA) {
|
|
||||||
invalidate = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
cache = (ngx_ssl_cache_t *) ngx_get_conf(cf->cycle->conf_ctx,
|
cache = (ngx_ssl_cache_t *) ngx_get_conf(cf->cycle->conf_ctx,
|
||||||
ngx_openssl_cache_module);
|
ngx_openssl_cache_module);
|
||||||
|
|
||||||
|
|
@ -223,14 +215,9 @@ ngx_ssl_cache_fetch(ngx_conf_t *cf, ngx_uint_t index, char **err,
|
||||||
cn = ngx_ssl_cache_lookup(cache, type, &id, hash);
|
cn = ngx_ssl_cache_lookup(cache, type, &id, hash);
|
||||||
|
|
||||||
if (cn != NULL) {
|
if (cn != NULL) {
|
||||||
if (!invalidate) {
|
|
||||||
return type->ref(err, cn->value);
|
return type->ref(err, cn->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
type->free(cn->value);
|
|
||||||
ngx_rbtree_delete(&cache->rbtree, &cn->node);
|
|
||||||
}
|
|
||||||
|
|
||||||
value = NULL;
|
value = NULL;
|
||||||
|
|
||||||
if (id.type == NGX_SSL_CACHE_PATH
|
if (id.type == NGX_SSL_CACHE_PATH
|
||||||
|
|
@ -249,7 +236,7 @@ ngx_ssl_cache_fetch(ngx_conf_t *cf, ngx_uint_t index, char **err,
|
||||||
|
|
||||||
old_cache = ngx_ssl_cache_get_old_conf(cf->cycle);
|
old_cache = ngx_ssl_cache_get_old_conf(cf->cycle);
|
||||||
|
|
||||||
if (old_cache && old_cache->inheritable && !invalidate) {
|
if (old_cache && old_cache->inheritable) {
|
||||||
cn = ngx_ssl_cache_lookup(old_cache, type, &id, hash);
|
cn = ngx_ssl_cache_lookup(old_cache, type, &id, hash);
|
||||||
|
|
||||||
if (cn != NULL) {
|
if (cn != NULL) {
|
||||||
|
|
|
||||||
|
|
@ -12,14 +12,16 @@
|
||||||
#include <ngx_core.h>
|
#include <ngx_core.h>
|
||||||
|
|
||||||
|
|
||||||
#if (OPENSSL_VERSION_NUMBER >= 0x30500010L)
|
#ifdef OSSL_RECORD_PROTECTION_LEVEL_NONE
|
||||||
#define NGX_QUIC_OPENSSL_API 1
|
#ifndef NGX_QUIC_OPENSSL_API
|
||||||
|
#define NGX_QUIC_BORINGSSL_API 1
|
||||||
|
#define NGX_QUIC_OPENSSL_COMPAT 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#elif (defined SSL_R_MISSING_QUIC_TRANSPORT_PARAMETERS_EXTENSION)
|
#elif (defined SSL_R_MISSING_QUIC_TRANSPORT_PARAMETERS_EXTENSION)
|
||||||
#define NGX_QUIC_QUICTLS_API 1
|
#define NGX_QUIC_QUICTLS_API 1
|
||||||
|
|
||||||
#elif (defined OPENSSL_IS_BORINGSSL || defined OPENSSL_IS_AWSLC \
|
#elif (defined OPENSSL_IS_BORINGSSL || defined LIBRESSL_VERSION_NUMBER)
|
||||||
|| defined LIBRESSL_VERSION_NUMBER)
|
|
||||||
#define NGX_QUIC_BORINGSSL_API 1
|
#define NGX_QUIC_BORINGSSL_API 1
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,6 @@
|
||||||
#include <ngx_core.h>
|
#include <ngx_core.h>
|
||||||
#include <ngx_event.h>
|
#include <ngx_event.h>
|
||||||
#include <ngx_event_quic_connection.h>
|
#include <ngx_event_quic_connection.h>
|
||||||
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
|
||||||
#include <openssl/hkdf.h>
|
|
||||||
#include <openssl/chacha.h>
|
|
||||||
#else
|
|
||||||
#include <openssl/kdf.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* RFC 9001, 5.4.1. Header Protection Application: 5-byte mask */
|
/* RFC 9001, 5.4.1. Header Protection Application: 5-byte mask */
|
||||||
|
|
@ -39,7 +33,7 @@ static uint64_t ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask,
|
||||||
|
|
||||||
static ngx_int_t ngx_quic_crypto_open(ngx_quic_secret_t *s, ngx_str_t *out,
|
static ngx_int_t ngx_quic_crypto_open(ngx_quic_secret_t *s, ngx_str_t *out,
|
||||||
const u_char *nonce, ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log);
|
const u_char *nonce, ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log);
|
||||||
#if !(NGX_QUIC_BORINGSSL_EVP_API)
|
#ifndef OPENSSL_IS_BORINGSSL
|
||||||
static ngx_int_t ngx_quic_crypto_common(ngx_quic_secret_t *s, ngx_str_t *out,
|
static ngx_int_t ngx_quic_crypto_common(ngx_quic_secret_t *s, ngx_str_t *out,
|
||||||
const u_char *nonce, ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log);
|
const u_char *nonce, ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -64,7 +58,7 @@ ngx_quic_ciphers(ngx_uint_t id, ngx_quic_ciphers_t *ciphers)
|
||||||
switch (id) {
|
switch (id) {
|
||||||
|
|
||||||
case TLS1_3_CK_AES_128_GCM_SHA256:
|
case TLS1_3_CK_AES_128_GCM_SHA256:
|
||||||
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
#ifdef OPENSSL_IS_BORINGSSL
|
||||||
ciphers->c = EVP_aead_aes_128_gcm();
|
ciphers->c = EVP_aead_aes_128_gcm();
|
||||||
#else
|
#else
|
||||||
ciphers->c = EVP_aes_128_gcm();
|
ciphers->c = EVP_aes_128_gcm();
|
||||||
|
|
@ -75,7 +69,7 @@ ngx_quic_ciphers(ngx_uint_t id, ngx_quic_ciphers_t *ciphers)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TLS1_3_CK_AES_256_GCM_SHA384:
|
case TLS1_3_CK_AES_256_GCM_SHA384:
|
||||||
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
#ifdef OPENSSL_IS_BORINGSSL
|
||||||
ciphers->c = EVP_aead_aes_256_gcm();
|
ciphers->c = EVP_aead_aes_256_gcm();
|
||||||
#else
|
#else
|
||||||
ciphers->c = EVP_aes_256_gcm();
|
ciphers->c = EVP_aes_256_gcm();
|
||||||
|
|
@ -86,12 +80,12 @@ ngx_quic_ciphers(ngx_uint_t id, ngx_quic_ciphers_t *ciphers)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TLS1_3_CK_CHACHA20_POLY1305_SHA256:
|
case TLS1_3_CK_CHACHA20_POLY1305_SHA256:
|
||||||
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
#ifdef OPENSSL_IS_BORINGSSL
|
||||||
ciphers->c = EVP_aead_chacha20_poly1305();
|
ciphers->c = EVP_aead_chacha20_poly1305();
|
||||||
#else
|
#else
|
||||||
ciphers->c = EVP_chacha20_poly1305();
|
ciphers->c = EVP_chacha20_poly1305();
|
||||||
#endif
|
#endif
|
||||||
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
#ifdef OPENSSL_IS_BORINGSSL
|
||||||
ciphers->hp = (const EVP_CIPHER *) EVP_aead_chacha20_poly1305();
|
ciphers->hp = (const EVP_CIPHER *) EVP_aead_chacha20_poly1305();
|
||||||
#else
|
#else
|
||||||
ciphers->hp = EVP_chacha20();
|
ciphers->hp = EVP_chacha20();
|
||||||
|
|
@ -100,7 +94,7 @@ ngx_quic_ciphers(ngx_uint_t id, ngx_quic_ciphers_t *ciphers)
|
||||||
len = 32;
|
len = 32;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if !(NGX_QUIC_BORINGSSL_EVP_API)
|
#ifndef OPENSSL_IS_BORINGSSL
|
||||||
case TLS1_3_CK_AES_128_CCM_SHA256:
|
case TLS1_3_CK_AES_128_CCM_SHA256:
|
||||||
ciphers->c = EVP_aes_128_ccm();
|
ciphers->c = EVP_aes_128_ccm();
|
||||||
ciphers->hp = EVP_aes_128_ctr();
|
ciphers->hp = EVP_aes_128_ctr();
|
||||||
|
|
@ -269,7 +263,7 @@ static ngx_int_t
|
||||||
ngx_hkdf_expand(u_char *out_key, size_t out_len, const EVP_MD *digest,
|
ngx_hkdf_expand(u_char *out_key, size_t out_len, const EVP_MD *digest,
|
||||||
const uint8_t *prk, size_t prk_len, const u_char *info, size_t info_len)
|
const uint8_t *prk, size_t prk_len, const u_char *info, size_t info_len)
|
||||||
{
|
{
|
||||||
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
#ifdef OPENSSL_IS_BORINGSSL
|
||||||
|
|
||||||
if (HKDF_expand(out_key, out_len, digest, prk, prk_len, info, info_len)
|
if (HKDF_expand(out_key, out_len, digest, prk, prk_len, info, info_len)
|
||||||
== 0)
|
== 0)
|
||||||
|
|
@ -331,7 +325,7 @@ ngx_hkdf_extract(u_char *out_key, size_t *out_len, const EVP_MD *digest,
|
||||||
const u_char *secret, size_t secret_len, const u_char *salt,
|
const u_char *secret, size_t secret_len, const u_char *salt,
|
||||||
size_t salt_len)
|
size_t salt_len)
|
||||||
{
|
{
|
||||||
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
#ifdef OPENSSL_IS_BORINGSSL
|
||||||
|
|
||||||
if (HKDF_extract(out_key, out_len, digest, secret, secret_len, salt,
|
if (HKDF_extract(out_key, out_len, digest, secret, secret_len, salt,
|
||||||
salt_len)
|
salt_len)
|
||||||
|
|
@ -394,7 +388,7 @@ ngx_quic_crypto_init(const ngx_quic_cipher_t *cipher, ngx_quic_secret_t *s,
|
||||||
ngx_quic_md_t *key, ngx_int_t enc, ngx_log_t *log)
|
ngx_quic_md_t *key, ngx_int_t enc, ngx_log_t *log)
|
||||||
{
|
{
|
||||||
|
|
||||||
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
#ifdef OPENSSL_IS_BORINGSSL
|
||||||
EVP_AEAD_CTX *ctx;
|
EVP_AEAD_CTX *ctx;
|
||||||
|
|
||||||
ctx = EVP_AEAD_CTX_new(cipher, key->data, key->len,
|
ctx = EVP_AEAD_CTX_new(cipher, key->data, key->len,
|
||||||
|
|
@ -454,7 +448,7 @@ static ngx_int_t
|
||||||
ngx_quic_crypto_open(ngx_quic_secret_t *s, ngx_str_t *out, const u_char *nonce,
|
ngx_quic_crypto_open(ngx_quic_secret_t *s, ngx_str_t *out, const u_char *nonce,
|
||||||
ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log)
|
ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log)
|
||||||
{
|
{
|
||||||
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
#ifdef OPENSSL_IS_BORINGSSL
|
||||||
if (EVP_AEAD_CTX_open(s->ctx, out->data, &out->len, out->len, nonce,
|
if (EVP_AEAD_CTX_open(s->ctx, out->data, &out->len, out->len, nonce,
|
||||||
s->iv.len, in->data, in->len, ad->data, ad->len)
|
s->iv.len, in->data, in->len, ad->data, ad->len)
|
||||||
!= 1)
|
!= 1)
|
||||||
|
|
@ -474,7 +468,7 @@ ngx_int_t
|
||||||
ngx_quic_crypto_seal(ngx_quic_secret_t *s, ngx_str_t *out, const u_char *nonce,
|
ngx_quic_crypto_seal(ngx_quic_secret_t *s, ngx_str_t *out, const u_char *nonce,
|
||||||
ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log)
|
ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log)
|
||||||
{
|
{
|
||||||
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
#ifdef OPENSSL_IS_BORINGSSL
|
||||||
if (EVP_AEAD_CTX_seal(s->ctx, out->data, &out->len, out->len, nonce,
|
if (EVP_AEAD_CTX_seal(s->ctx, out->data, &out->len, out->len, nonce,
|
||||||
s->iv.len, in->data, in->len, ad->data, ad->len)
|
s->iv.len, in->data, in->len, ad->data, ad->len)
|
||||||
!= 1)
|
!= 1)
|
||||||
|
|
@ -490,7 +484,7 @@ ngx_quic_crypto_seal(ngx_quic_secret_t *s, ngx_str_t *out, const u_char *nonce,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if !(NGX_QUIC_BORINGSSL_EVP_API)
|
#ifndef OPENSSL_IS_BORINGSSL
|
||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_quic_crypto_common(ngx_quic_secret_t *s, ngx_str_t *out,
|
ngx_quic_crypto_common(ngx_quic_secret_t *s, ngx_str_t *out,
|
||||||
|
|
@ -569,7 +563,7 @@ void
|
||||||
ngx_quic_crypto_cleanup(ngx_quic_secret_t *s)
|
ngx_quic_crypto_cleanup(ngx_quic_secret_t *s)
|
||||||
{
|
{
|
||||||
if (s->ctx) {
|
if (s->ctx) {
|
||||||
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
#ifdef OPENSSL_IS_BORINGSSL
|
||||||
EVP_AEAD_CTX_free(s->ctx);
|
EVP_AEAD_CTX_free(s->ctx);
|
||||||
#else
|
#else
|
||||||
EVP_CIPHER_CTX_free(s->ctx);
|
EVP_CIPHER_CTX_free(s->ctx);
|
||||||
|
|
@ -585,7 +579,7 @@ ngx_quic_crypto_hp_init(const EVP_CIPHER *cipher, ngx_quic_secret_t *s,
|
||||||
{
|
{
|
||||||
EVP_CIPHER_CTX *ctx;
|
EVP_CIPHER_CTX *ctx;
|
||||||
|
|
||||||
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
#ifdef OPENSSL_IS_BORINGSSL
|
||||||
if (cipher == (EVP_CIPHER *) EVP_aead_chacha20_poly1305()) {
|
if (cipher == (EVP_CIPHER *) EVP_aead_chacha20_poly1305()) {
|
||||||
/* no EVP interface */
|
/* no EVP interface */
|
||||||
s->hp_ctx = NULL;
|
s->hp_ctx = NULL;
|
||||||
|
|
@ -621,7 +615,7 @@ ngx_quic_crypto_hp(ngx_quic_secret_t *s, u_char *out, u_char *in,
|
||||||
|
|
||||||
ctx = s->hp_ctx;
|
ctx = s->hp_ctx;
|
||||||
|
|
||||||
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
#ifdef OPENSSL_IS_BORINGSSL
|
||||||
uint32_t cnt;
|
uint32_t cnt;
|
||||||
|
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
|
|
|
||||||
|
|
@ -22,12 +22,10 @@
|
||||||
#define NGX_QUIC_MAX_MD_SIZE 48
|
#define NGX_QUIC_MAX_MD_SIZE 48
|
||||||
|
|
||||||
|
|
||||||
#if (defined OPENSSL_IS_BORINGSSL || defined OPENSSL_IS_AWSLC)
|
#ifdef OPENSSL_IS_BORINGSSL
|
||||||
#define NGX_QUIC_BORINGSSL_EVP_API 1
|
|
||||||
#define ngx_quic_cipher_t EVP_AEAD
|
#define ngx_quic_cipher_t EVP_AEAD
|
||||||
#define ngx_quic_crypto_ctx_t EVP_AEAD_CTX
|
#define ngx_quic_crypto_ctx_t EVP_AEAD_CTX
|
||||||
#else
|
#else
|
||||||
#define NGX_QUIC_BORINGSSL_EVP_API 0
|
|
||||||
#define ngx_quic_cipher_t EVP_CIPHER
|
#define ngx_quic_cipher_t EVP_CIPHER
|
||||||
#define ngx_quic_crypto_ctx_t EVP_CIPHER_CTX
|
#define ngx_quic_crypto_ctx_t EVP_CIPHER_CTX
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -185,13 +185,7 @@ ngx_quic_cbs_release_rcd(ngx_ssl_conn_t *ssl_conn, size_t bytes_read, void *arg)
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||||
"quic ngx_quic_cbs_release_rcd len:%uz", bytes_read);
|
"quic ngx_quic_cbs_release_rcd len:%uz", bytes_read);
|
||||||
|
|
||||||
/* already closed on handshake failure */
|
|
||||||
|
|
||||||
qc = ngx_quic_get_connection(c);
|
qc = ngx_quic_get_connection(c);
|
||||||
if (qc == NULL) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = ngx_quic_get_send_ctx(qc, qc->read_level);
|
ctx = ngx_quic_get_send_ctx(qc, qc->read_level);
|
||||||
|
|
||||||
cl = ngx_quic_read_buffer(c, &ctx->crypto, bytes_read);
|
cl = ngx_quic_read_buffer(c, &ctx->crypto, bytes_read);
|
||||||
|
|
@ -701,35 +695,30 @@ ngx_quic_handshake(ngx_connection_t *c)
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n);
|
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n);
|
||||||
|
|
||||||
|
if (qc->error) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (n <= 0) {
|
if (n <= 0) {
|
||||||
sslerr = SSL_get_error(ssl_conn, n);
|
sslerr = SSL_get_error(ssl_conn, n);
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d",
|
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d",
|
||||||
sslerr);
|
sslerr);
|
||||||
|
|
||||||
|
if (sslerr != SSL_ERROR_WANT_READ) {
|
||||||
|
|
||||||
if (c->ssl->handshake_rejected) {
|
if (c->ssl->handshake_rejected) {
|
||||||
ngx_connection_error(c, 0, "handshake rejected");
|
ngx_connection_error(c, 0, "handshake rejected");
|
||||||
ERR_clear_error();
|
ERR_clear_error();
|
||||||
|
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qc->error) {
|
|
||||||
ngx_connection_error(c, 0, "SSL_do_handshake() failed");
|
|
||||||
ERR_clear_error();
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sslerr != SSL_ERROR_WANT_READ) {
|
|
||||||
ngx_ssl_connection_error(c, sslerr, 0, "SSL_do_handshake() failed");
|
ngx_ssl_connection_error(c, sslerr, 0, "SSL_do_handshake() failed");
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qc->error) {
|
|
||||||
ngx_connection_error(c, 0, "SSL_do_handshake() failed");
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SSL_is_init_finished(ssl_conn)) {
|
if (!SSL_is_init_finished(ssl_conn)) {
|
||||||
if (ngx_quic_keys_available(qc->keys, NGX_QUIC_ENCRYPTION_EARLY_DATA, 0)
|
if (ngx_quic_keys_available(qc->keys, NGX_QUIC_ENCRYPTION_EARLY_DATA, 0)
|
||||||
&& qc->client_tp_done)
|
&& qc->client_tp_done)
|
||||||
|
|
@ -979,7 +968,7 @@ ngx_quic_init_connection(ngx_connection_t *c)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined OPENSSL_IS_BORINGSSL || defined OPENSSL_IS_AWSLC)
|
#ifdef OPENSSL_IS_BORINGSSL
|
||||||
if (SSL_set_quic_early_data_context(ssl_conn, p, clen) == 0) {
|
if (SSL_set_quic_early_data_context(ssl_conn, p, clen) == 0) {
|
||||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
|
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
|
||||||
"quic SSL_set_quic_early_data_context() failed");
|
"quic SSL_set_quic_early_data_context() failed");
|
||||||
|
|
|
||||||
|
|
@ -253,8 +253,7 @@ ngx_http_auth_basic_handler(ngx_http_request_t *r)
|
||||||
pwd.len = i - passwd;
|
pwd.len = i - passwd;
|
||||||
pwd.data = ngx_pnalloc(r->pool, pwd.len + 1);
|
pwd.data = ngx_pnalloc(r->pool, pwd.len + 1);
|
||||||
if (pwd.data == NULL) {
|
if (pwd.data == NULL) {
|
||||||
rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
|
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_cpystrn(pwd.data, &buf[passwd], pwd.len + 1);
|
ngx_cpystrn(pwd.data, &buf[passwd], pwd.len + 1);
|
||||||
|
|
|
||||||
|
|
@ -66,9 +66,7 @@ ngx_http_chunked_header_filter(ngx_http_request_t *r)
|
||||||
|| r->headers_out.status == NGX_HTTP_NO_CONTENT
|
|| r->headers_out.status == NGX_HTTP_NO_CONTENT
|
||||||
|| r->headers_out.status < NGX_HTTP_OK
|
|| r->headers_out.status < NGX_HTTP_OK
|
||||||
|| r != r->main
|
|| r != r->main
|
||||||
|| r->method == NGX_HTTP_HEAD
|
|| r->method == NGX_HTTP_HEAD)
|
||||||
|| (r->method == NGX_HTTP_CONNECT
|
|
||||||
&& r->headers_out.status < NGX_HTTP_SPECIAL_RESPONSE))
|
|
||||||
{
|
{
|
||||||
return ngx_http_next_header_filter(r);
|
return ngx_http_next_header_filter(r);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,6 @@ typedef struct {
|
||||||
unsigned allow_binary_include:1;
|
unsigned allow_binary_include:1;
|
||||||
unsigned binary_include:1;
|
unsigned binary_include:1;
|
||||||
unsigned proxy_recursive:1;
|
unsigned proxy_recursive:1;
|
||||||
unsigned no_cacheable:1;
|
|
||||||
} ngx_http_geo_conf_ctx_t;
|
} ngx_http_geo_conf_ctx_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -464,7 +463,6 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||||
+ sizeof(ngx_http_variable_value_t)
|
+ sizeof(ngx_http_variable_value_t)
|
||||||
+ 0x10000 * sizeof(ngx_http_geo_range_t *);
|
+ 0x10000 * sizeof(ngx_http_geo_range_t *);
|
||||||
ctx.allow_binary_include = 1;
|
ctx.allow_binary_include = 1;
|
||||||
ctx.no_cacheable = 0;
|
|
||||||
|
|
||||||
save = *cf;
|
save = *cf;
|
||||||
cf->pool = pool;
|
cf->pool = pool;
|
||||||
|
|
@ -480,10 +478,6 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.no_cacheable) {
|
|
||||||
var->flags |= NGX_HTTP_VAR_NOCACHEABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
geo->proxies = ctx.proxies;
|
geo->proxies = ctx.proxies;
|
||||||
geo->proxy_recursive = ctx.proxy_recursive;
|
geo->proxy_recursive = ctx.proxy_recursive;
|
||||||
|
|
||||||
|
|
@ -629,12 +623,6 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
|
||||||
rv = NGX_CONF_OK;
|
rv = NGX_CONF_OK;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (ngx_strcmp(value[0].data, "volatile") == 0) {
|
|
||||||
ctx->no_cacheable = 1;
|
|
||||||
rv = NGX_CONF_OK;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cf->args->nelts != 2) {
|
if (cf->args->nelts != 2) {
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,6 @@
|
||||||
#include <ngx_http.h>
|
#include <ngx_http.h>
|
||||||
|
|
||||||
|
|
||||||
#define NGX_HTTP_HEADERS_INHERIT_OFF 0
|
|
||||||
#define NGX_HTTP_HEADERS_INHERIT_ON 1
|
|
||||||
#define NGX_HTTP_HEADERS_INHERIT_MERGE 2
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct ngx_http_header_val_s ngx_http_header_val_t;
|
typedef struct ngx_http_header_val_s ngx_http_header_val_t;
|
||||||
|
|
||||||
typedef ngx_int_t (*ngx_http_set_header_pt)(ngx_http_request_t *r,
|
typedef ngx_int_t (*ngx_http_set_header_pt)(ngx_http_request_t *r,
|
||||||
|
|
@ -54,8 +49,6 @@ typedef struct {
|
||||||
ngx_http_complex_value_t *expires_value;
|
ngx_http_complex_value_t *expires_value;
|
||||||
ngx_array_t *headers;
|
ngx_array_t *headers;
|
||||||
ngx_array_t *trailers;
|
ngx_array_t *trailers;
|
||||||
ngx_uint_t headers_inherit;
|
|
||||||
ngx_uint_t trailers_inherit;
|
|
||||||
} ngx_http_headers_conf_t;
|
} ngx_http_headers_conf_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -104,14 +97,6 @@ static ngx_http_set_header_t ngx_http_set_headers[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static ngx_conf_enum_t ngx_http_headers_inherit[] = {
|
|
||||||
{ ngx_string("off"), NGX_HTTP_HEADERS_INHERIT_OFF },
|
|
||||||
{ ngx_string("on"), NGX_HTTP_HEADERS_INHERIT_ON },
|
|
||||||
{ ngx_string("merge"), NGX_HTTP_HEADERS_INHERIT_MERGE },
|
|
||||||
{ ngx_null_string, 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static ngx_command_t ngx_http_headers_filter_commands[] = {
|
static ngx_command_t ngx_http_headers_filter_commands[] = {
|
||||||
|
|
||||||
{ ngx_string("expires"),
|
{ ngx_string("expires"),
|
||||||
|
|
@ -138,22 +123,6 @@ static ngx_command_t ngx_http_headers_filter_commands[] = {
|
||||||
offsetof(ngx_http_headers_conf_t, trailers),
|
offsetof(ngx_http_headers_conf_t, trailers),
|
||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("add_header_inherit"),
|
|
||||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
|
||||||
|NGX_CONF_TAKE1,
|
|
||||||
ngx_conf_set_enum_slot,
|
|
||||||
NGX_HTTP_LOC_CONF_OFFSET,
|
|
||||||
offsetof(ngx_http_headers_conf_t, headers_inherit),
|
|
||||||
&ngx_http_headers_inherit },
|
|
||||||
|
|
||||||
{ ngx_string("add_trailer_inherit"),
|
|
||||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
|
||||||
|NGX_CONF_TAKE1,
|
|
||||||
ngx_conf_set_enum_slot,
|
|
||||||
NGX_HTTP_LOC_CONF_OFFSET,
|
|
||||||
offsetof(ngx_http_headers_conf_t, trailers_inherit),
|
|
||||||
&ngx_http_headers_inherit },
|
|
||||||
|
|
||||||
ngx_null_command
|
ngx_null_command
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -688,8 +657,6 @@ ngx_http_headers_create_conf(ngx_conf_t *cf)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
conf->expires = NGX_HTTP_EXPIRES_UNSET;
|
conf->expires = NGX_HTTP_EXPIRES_UNSET;
|
||||||
conf->headers_inherit = NGX_CONF_UNSET_UINT;
|
|
||||||
conf->trailers_inherit = NGX_CONF_UNSET_UINT;
|
|
||||||
|
|
||||||
return conf;
|
return conf;
|
||||||
}
|
}
|
||||||
|
|
@ -701,8 +668,6 @@ ngx_http_headers_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
ngx_http_headers_conf_t *prev = parent;
|
ngx_http_headers_conf_t *prev = parent;
|
||||||
ngx_http_headers_conf_t *conf = child;
|
ngx_http_headers_conf_t *conf = child;
|
||||||
|
|
||||||
ngx_http_header_val_t *hv;
|
|
||||||
|
|
||||||
if (conf->expires == NGX_HTTP_EXPIRES_UNSET) {
|
if (conf->expires == NGX_HTTP_EXPIRES_UNSET) {
|
||||||
conf->expires = prev->expires;
|
conf->expires = prev->expires;
|
||||||
conf->expires_time = prev->expires_time;
|
conf->expires_time = prev->expires_time;
|
||||||
|
|
@ -713,43 +678,12 @@ ngx_http_headers_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_conf_merge_uint_value(conf->headers_inherit, prev->headers_inherit,
|
|
||||||
NGX_HTTP_HEADERS_INHERIT_ON);
|
|
||||||
ngx_conf_merge_uint_value(conf->trailers_inherit, prev->trailers_inherit,
|
|
||||||
NGX_HTTP_HEADERS_INHERIT_ON);
|
|
||||||
|
|
||||||
if (conf->headers_inherit != NGX_HTTP_HEADERS_INHERIT_OFF
|
|
||||||
&& prev->headers)
|
|
||||||
{
|
|
||||||
if (conf->headers == NULL) {
|
if (conf->headers == NULL) {
|
||||||
conf->headers = prev->headers;
|
conf->headers = prev->headers;
|
||||||
|
|
||||||
} else if (conf->headers_inherit == NGX_HTTP_HEADERS_INHERIT_MERGE) {
|
|
||||||
hv = ngx_array_push_n(conf->headers, prev->headers->nelts);
|
|
||||||
if (hv == NULL) {
|
|
||||||
return NGX_CONF_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_memcpy(hv, prev->headers->elts,
|
|
||||||
sizeof(ngx_http_header_val_t) * prev->headers->nelts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conf->trailers_inherit != NGX_HTTP_HEADERS_INHERIT_OFF
|
|
||||||
&& prev->trailers)
|
|
||||||
{
|
|
||||||
if (conf->trailers == NULL) {
|
if (conf->trailers == NULL) {
|
||||||
conf->trailers = prev->trailers;
|
conf->trailers = prev->trailers;
|
||||||
|
|
||||||
} else if (conf->trailers_inherit == NGX_HTTP_HEADERS_INHERIT_MERGE) {
|
|
||||||
hv = ngx_array_push_n(conf->trailers, prev->trailers->nelts);
|
|
||||||
if (hv == NULL) {
|
|
||||||
return NGX_CONF_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngx_memcpy(hv, prev->trailers->elts,
|
|
||||||
sizeof(ngx_http_header_val_t) * prev->trailers->nelts);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
|
|
|
||||||
|
|
@ -490,7 +490,7 @@ ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||||
if (value[i].len == 0) {
|
if (value[i].len == 0) {
|
||||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
"index \"%V\" in \"index\" directive is invalid",
|
"index \"%V\" in \"index\" directive is invalid",
|
||||||
&value[i]);
|
&value[1]);
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
#include <ngx_config.h>
|
#include <ngx_config.h>
|
||||||
#include <ngx_core.h>
|
#include <ngx_core.h>
|
||||||
#include <ngx_http.h>
|
#include <ngx_http.h>
|
||||||
#include <ngx_http_proxy_module.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define NGX_HTTP_PROXY_COOKIE_SECURE 0x0001
|
#define NGX_HTTP_PROXY_COOKIE_SECURE 0x0001
|
||||||
|
|
@ -24,6 +23,11 @@
|
||||||
#define NGX_HTTP_PROXY_COOKIE_SAMESITE_OFF 0x0400
|
#define NGX_HTTP_PROXY_COOKIE_SAMESITE_OFF 0x0400
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ngx_array_t caches; /* ngx_http_file_cache_t * */
|
||||||
|
} ngx_http_proxy_main_conf_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct ngx_http_proxy_rewrite_s ngx_http_proxy_rewrite_t;
|
typedef struct ngx_http_proxy_rewrite_s ngx_http_proxy_rewrite_t;
|
||||||
|
|
||||||
typedef ngx_int_t (*ngx_http_proxy_rewrite_pt)(ngx_http_request_t *r,
|
typedef ngx_int_t (*ngx_http_proxy_rewrite_pt)(ngx_http_request_t *r,
|
||||||
|
|
@ -57,6 +61,96 @@ typedef struct {
|
||||||
} ngx_http_proxy_cookie_flags_t;
|
} ngx_http_proxy_cookie_flags_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ngx_str_t key_start;
|
||||||
|
ngx_str_t schema;
|
||||||
|
ngx_str_t host_header;
|
||||||
|
ngx_str_t port;
|
||||||
|
ngx_str_t uri;
|
||||||
|
} ngx_http_proxy_vars_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ngx_array_t *flushes;
|
||||||
|
ngx_array_t *lengths;
|
||||||
|
ngx_array_t *values;
|
||||||
|
ngx_hash_t hash;
|
||||||
|
} ngx_http_proxy_headers_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ngx_http_upstream_conf_t upstream;
|
||||||
|
|
||||||
|
ngx_array_t *body_flushes;
|
||||||
|
ngx_array_t *body_lengths;
|
||||||
|
ngx_array_t *body_values;
|
||||||
|
ngx_str_t body_source;
|
||||||
|
|
||||||
|
ngx_http_proxy_headers_t headers;
|
||||||
|
#if (NGX_HTTP_CACHE)
|
||||||
|
ngx_http_proxy_headers_t headers_cache;
|
||||||
|
#endif
|
||||||
|
ngx_array_t *headers_source;
|
||||||
|
|
||||||
|
ngx_array_t *proxy_lengths;
|
||||||
|
ngx_array_t *proxy_values;
|
||||||
|
|
||||||
|
ngx_array_t *redirects;
|
||||||
|
ngx_array_t *cookie_domains;
|
||||||
|
ngx_array_t *cookie_paths;
|
||||||
|
ngx_array_t *cookie_flags;
|
||||||
|
|
||||||
|
ngx_http_complex_value_t *method;
|
||||||
|
ngx_str_t location;
|
||||||
|
ngx_str_t url;
|
||||||
|
|
||||||
|
#if (NGX_HTTP_CACHE)
|
||||||
|
ngx_http_complex_value_t cache_key;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ngx_http_proxy_vars_t vars;
|
||||||
|
|
||||||
|
ngx_flag_t redirect;
|
||||||
|
|
||||||
|
ngx_uint_t http_version;
|
||||||
|
|
||||||
|
ngx_uint_t headers_hash_max_size;
|
||||||
|
ngx_uint_t headers_hash_bucket_size;
|
||||||
|
|
||||||
|
#if (NGX_HTTP_SSL)
|
||||||
|
ngx_uint_t ssl;
|
||||||
|
ngx_uint_t ssl_protocols;
|
||||||
|
ngx_str_t ssl_ciphers;
|
||||||
|
ngx_uint_t ssl_verify_depth;
|
||||||
|
ngx_str_t ssl_trusted_certificate;
|
||||||
|
ngx_str_t ssl_crl;
|
||||||
|
ngx_array_t *ssl_conf_commands;
|
||||||
|
#endif
|
||||||
|
} ngx_http_proxy_loc_conf_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ngx_http_status_t status;
|
||||||
|
ngx_http_chunked_t chunked;
|
||||||
|
ngx_http_proxy_vars_t vars;
|
||||||
|
off_t internal_body_length;
|
||||||
|
|
||||||
|
ngx_chain_t *free;
|
||||||
|
ngx_chain_t *busy;
|
||||||
|
|
||||||
|
ngx_buf_t *trailers;
|
||||||
|
|
||||||
|
unsigned head:1;
|
||||||
|
unsigned internal_chunked:1;
|
||||||
|
unsigned header_sent:1;
|
||||||
|
} ngx_http_proxy_ctx_t;
|
||||||
|
|
||||||
|
|
||||||
|
static ngx_int_t ngx_http_proxy_eval(ngx_http_request_t *r,
|
||||||
|
ngx_http_proxy_ctx_t *ctx, ngx_http_proxy_loc_conf_t *plcf);
|
||||||
|
#if (NGX_HTTP_CACHE)
|
||||||
|
static ngx_int_t ngx_http_proxy_create_key(ngx_http_request_t *r);
|
||||||
|
#endif
|
||||||
static ngx_int_t ngx_http_proxy_create_request(ngx_http_request_t *r);
|
static ngx_int_t ngx_http_proxy_create_request(ngx_http_request_t *r);
|
||||||
static ngx_int_t ngx_http_proxy_reinit_request(ngx_http_request_t *r);
|
static ngx_int_t ngx_http_proxy_reinit_request(ngx_http_request_t *r);
|
||||||
static ngx_int_t ngx_http_proxy_body_output_filter(void *data, ngx_chain_t *in);
|
static ngx_int_t ngx_http_proxy_body_output_filter(void *data, ngx_chain_t *in);
|
||||||
|
|
@ -84,14 +178,15 @@ static ngx_int_t ngx_http_proxy_port_variable(ngx_http_request_t *r,
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r,
|
ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r,
|
||||||
ngx_http_variable_value_t *v, uintptr_t data);
|
ngx_http_variable_value_t *v, uintptr_t data);
|
||||||
static ngx_int_t
|
|
||||||
ngx_http_proxy_internal_connection_variable(ngx_http_request_t *r,
|
|
||||||
ngx_http_variable_value_t *v, uintptr_t data);
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_proxy_internal_body_length_variable(ngx_http_request_t *r,
|
ngx_http_proxy_internal_body_length_variable(ngx_http_request_t *r,
|
||||||
ngx_http_variable_value_t *v, uintptr_t data);
|
ngx_http_variable_value_t *v, uintptr_t data);
|
||||||
static ngx_int_t ngx_http_proxy_internal_chunked_variable(ngx_http_request_t *r,
|
static ngx_int_t ngx_http_proxy_internal_chunked_variable(ngx_http_request_t *r,
|
||||||
ngx_http_variable_value_t *v, uintptr_t data);
|
ngx_http_variable_value_t *v, uintptr_t data);
|
||||||
|
static ngx_int_t ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r,
|
||||||
|
ngx_table_elt_t *h, size_t prefix);
|
||||||
|
static ngx_int_t ngx_http_proxy_rewrite_cookie(ngx_http_request_t *r,
|
||||||
|
ngx_table_elt_t *h);
|
||||||
static ngx_int_t ngx_http_proxy_parse_cookie(ngx_str_t *value,
|
static ngx_int_t ngx_http_proxy_parse_cookie(ngx_str_t *value,
|
||||||
ngx_array_t *attrs);
|
ngx_array_t *attrs);
|
||||||
static ngx_int_t ngx_http_proxy_rewrite_cookie_value(ngx_http_request_t *r,
|
static ngx_int_t ngx_http_proxy_rewrite_cookie_value(ngx_http_request_t *r,
|
||||||
|
|
@ -198,9 +293,6 @@ static ngx_conf_post_t ngx_http_proxy_ssl_conf_command_post =
|
||||||
static ngx_conf_enum_t ngx_http_proxy_http_version[] = {
|
static ngx_conf_enum_t ngx_http_proxy_http_version[] = {
|
||||||
{ ngx_string("1.0"), NGX_HTTP_VERSION_10 },
|
{ ngx_string("1.0"), NGX_HTTP_VERSION_10 },
|
||||||
{ ngx_string("1.1"), NGX_HTTP_VERSION_11 },
|
{ ngx_string("1.1"), NGX_HTTP_VERSION_11 },
|
||||||
#if (NGX_HTTP_V2)
|
|
||||||
{ ngx_string("2"), NGX_HTTP_VERSION_20 },
|
|
||||||
#endif
|
|
||||||
{ ngx_null_string, 0 }
|
{ ngx_null_string, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -748,8 +840,8 @@ static char ngx_http_proxy_version_11[] = " HTTP/1.1" CRLF;
|
||||||
|
|
||||||
|
|
||||||
static ngx_keyval_t ngx_http_proxy_headers[] = {
|
static ngx_keyval_t ngx_http_proxy_headers[] = {
|
||||||
{ ngx_string("Host"), ngx_string("$proxy_internal_host") },
|
{ ngx_string("Host"), ngx_string("$proxy_host") },
|
||||||
{ ngx_string("Connection"), ngx_string("$proxy_internal_connection") },
|
{ ngx_string("Connection"), ngx_string("close") },
|
||||||
{ ngx_string("Content-Length"), ngx_string("$proxy_internal_body_length") },
|
{ ngx_string("Content-Length"), ngx_string("$proxy_internal_body_length") },
|
||||||
{ ngx_string("Transfer-Encoding"), ngx_string("$proxy_internal_chunked") },
|
{ ngx_string("Transfer-Encoding"), ngx_string("$proxy_internal_chunked") },
|
||||||
{ ngx_string("TE"), ngx_string("") },
|
{ ngx_string("TE"), ngx_string("") },
|
||||||
|
|
@ -776,8 +868,8 @@ static ngx_str_t ngx_http_proxy_hide_headers[] = {
|
||||||
#if (NGX_HTTP_CACHE)
|
#if (NGX_HTTP_CACHE)
|
||||||
|
|
||||||
static ngx_keyval_t ngx_http_proxy_cache_headers[] = {
|
static ngx_keyval_t ngx_http_proxy_cache_headers[] = {
|
||||||
{ ngx_string("Host"), ngx_string("$proxy_internal_host") },
|
{ ngx_string("Host"), ngx_string("$proxy_host") },
|
||||||
{ ngx_string("Connection"), ngx_string("$proxy_internal_connection") },
|
{ ngx_string("Connection"), ngx_string("close") },
|
||||||
{ ngx_string("Content-Length"), ngx_string("$proxy_internal_body_length") },
|
{ ngx_string("Content-Length"), ngx_string("$proxy_internal_body_length") },
|
||||||
{ ngx_string("Transfer-Encoding"), ngx_string("$proxy_internal_chunked") },
|
{ ngx_string("Transfer-Encoding"), ngx_string("$proxy_internal_chunked") },
|
||||||
{ ngx_string("TE"), ngx_string("") },
|
{ ngx_string("TE"), ngx_string("") },
|
||||||
|
|
@ -812,14 +904,6 @@ static ngx_http_variable_t ngx_http_proxy_vars[] = {
|
||||||
{ ngx_string("proxy_add_via"), NULL, NULL, 0, NGX_HTTP_VAR_NOHASH, 0 },
|
{ ngx_string("proxy_add_via"), NULL, NULL, 0, NGX_HTTP_VAR_NOHASH, 0 },
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{ ngx_string("proxy_internal_host"), NULL,
|
|
||||||
ngx_http_proxy_host_variable, 1,
|
|
||||||
NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
|
|
||||||
|
|
||||||
{ ngx_string("proxy_internal_connection"), NULL,
|
|
||||||
ngx_http_proxy_internal_connection_variable, 0,
|
|
||||||
NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
|
|
||||||
|
|
||||||
{ ngx_string("proxy_internal_body_length"), NULL,
|
{ ngx_string("proxy_internal_body_length"), NULL,
|
||||||
ngx_http_proxy_internal_body_length_variable, 0,
|
ngx_http_proxy_internal_body_length_variable, 0,
|
||||||
NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
|
NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
|
||||||
|
|
@ -878,14 +962,6 @@ ngx_http_proxy_handler(ngx_http_request_t *r)
|
||||||
ngx_http_proxy_main_conf_t *pmcf;
|
ngx_http_proxy_main_conf_t *pmcf;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
|
|
||||||
|
|
||||||
#if (NGX_HTTP_V2)
|
|
||||||
if (plcf->http_version == NGX_HTTP_VERSION_20) {
|
|
||||||
return ngx_http_proxy_v2_handler(r);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (ngx_http_upstream_create(r) != NGX_OK) {
|
if (ngx_http_upstream_create(r) != NGX_OK) {
|
||||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||||
}
|
}
|
||||||
|
|
@ -895,10 +971,10 @@ ngx_http_proxy_handler(ngx_http_request_t *r)
|
||||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->legacy = 1;
|
|
||||||
|
|
||||||
ngx_http_set_ctx(r, ctx, ngx_http_proxy_module);
|
ngx_http_set_ctx(r, ctx, ngx_http_proxy_module);
|
||||||
|
|
||||||
|
plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
|
||||||
|
|
||||||
u = r->upstream;
|
u = r->upstream;
|
||||||
|
|
||||||
if (plcf->proxy_lengths == NULL) {
|
if (plcf->proxy_lengths == NULL) {
|
||||||
|
|
@ -974,7 +1050,7 @@ ngx_http_proxy_handler(ngx_http_request_t *r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_proxy_eval(ngx_http_request_t *r, ngx_http_proxy_ctx_t *ctx,
|
ngx_http_proxy_eval(ngx_http_request_t *r, ngx_http_proxy_ctx_t *ctx,
|
||||||
ngx_http_proxy_loc_conf_t *plcf)
|
ngx_http_proxy_loc_conf_t *plcf)
|
||||||
{
|
{
|
||||||
|
|
@ -1078,7 +1154,7 @@ ngx_http_proxy_eval(ngx_http_request_t *r, ngx_http_proxy_ctx_t *ctx,
|
||||||
|
|
||||||
#if (NGX_HTTP_CACHE)
|
#if (NGX_HTTP_CACHE)
|
||||||
|
|
||||||
ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_proxy_create_key(ngx_http_request_t *r)
|
ngx_http_proxy_create_key(ngx_http_request_t *r)
|
||||||
{
|
{
|
||||||
size_t len, loc_len;
|
size_t len, loc_len;
|
||||||
|
|
@ -1130,8 +1206,7 @@ ngx_http_proxy_create_key(ngx_http_request_t *r)
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
loc_len = (r->valid_location && ctx->vars.uri.len)
|
loc_len = (r->valid_location && ctx->vars.uri.len) ? plcf->location.len : 0;
|
||||||
? ngx_min(plcf->location.len, r->uri.len) : 0;
|
|
||||||
|
|
||||||
if (r->quoted_uri || r->internal) {
|
if (r->quoted_uri || r->internal) {
|
||||||
escape = 2 * ngx_escape_uri(NULL, r->uri.data + loc_len,
|
escape = 2 * ngx_escape_uri(NULL, r->uri.data + loc_len,
|
||||||
|
|
@ -1243,8 +1318,8 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
|
||||||
uri_len = r->unparsed_uri.len;
|
uri_len = r->unparsed_uri.len;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
loc_len = (r->valid_location && ctx->vars.uri.len)
|
loc_len = (r->valid_location && ctx->vars.uri.len) ?
|
||||||
? ngx_min(plcf->location.len, r->uri.len) : 0;
|
plcf->location.len : 0;
|
||||||
|
|
||||||
if (r->quoted_uri || r->internal) {
|
if (r->quoted_uri || r->internal) {
|
||||||
escape = 2 * ngx_escape_uri(NULL, r->uri.data + loc_len,
|
escape = 2 * ngx_escape_uri(NULL, r->uri.data + loc_len,
|
||||||
|
|
@ -2043,7 +2118,7 @@ ngx_http_proxy_input_filter_init(void *data)
|
||||||
/* chunked */
|
/* chunked */
|
||||||
|
|
||||||
u->pipe->input_filter = ngx_http_proxy_chunked_filter;
|
u->pipe->input_filter = ngx_http_proxy_chunked_filter;
|
||||||
u->pipe->length = 5; /* "0" CRLF CRLF */
|
u->pipe->length = 3; /* "0" LF LF */
|
||||||
|
|
||||||
u->input_filter = ngx_http_proxy_non_buffered_chunked_filter;
|
u->input_filter = ngx_http_proxy_non_buffered_chunked_filter;
|
||||||
u->length = 1;
|
u->length = 1;
|
||||||
|
|
@ -2692,11 +2767,6 @@ ngx_http_proxy_host_variable(ngx_http_request_t *r,
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data == 1 && !ctx->legacy) {
|
|
||||||
v->not_found = 1;
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
v->len = ctx->vars.host_header.len;
|
v->len = ctx->vars.host_header.len;
|
||||||
v->valid = 1;
|
v->valid = 1;
|
||||||
v->no_cacheable = 0;
|
v->no_cacheable = 0;
|
||||||
|
|
@ -2777,29 +2847,6 @@ ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
|
||||||
ngx_http_proxy_internal_connection_variable(ngx_http_request_t *r,
|
|
||||||
ngx_http_variable_value_t *v, uintptr_t data)
|
|
||||||
{
|
|
||||||
ngx_http_proxy_ctx_t *ctx;
|
|
||||||
|
|
||||||
ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
|
|
||||||
|
|
||||||
if (ctx == NULL || !ctx->legacy) {
|
|
||||||
v->not_found = 1;
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
v->valid = 1;
|
|
||||||
v->no_cacheable = 0;
|
|
||||||
v->not_found = 0;
|
|
||||||
|
|
||||||
ngx_str_set(v, "close");
|
|
||||||
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_proxy_internal_body_length_variable(ngx_http_request_t *r,
|
ngx_http_proxy_internal_body_length_variable(ngx_http_request_t *r,
|
||||||
ngx_http_variable_value_t *v, uintptr_t data)
|
ngx_http_variable_value_t *v, uintptr_t data)
|
||||||
|
|
@ -2853,7 +2900,7 @@ ngx_http_proxy_internal_chunked_variable(ngx_http_request_t *r,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r, ngx_table_elt_t *h,
|
ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||||
size_t prefix)
|
size_t prefix)
|
||||||
{
|
{
|
||||||
|
|
@ -2885,7 +2932,7 @@ ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_proxy_rewrite_cookie(ngx_http_request_t *r, ngx_table_elt_t *h)
|
ngx_http_proxy_rewrite_cookie(ngx_http_request_t *r, ngx_table_elt_t *h)
|
||||||
{
|
{
|
||||||
u_char *p;
|
u_char *p;
|
||||||
|
|
@ -3530,7 +3577,6 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
|
||||||
* conf->headers.values = NULL;
|
* conf->headers.values = NULL;
|
||||||
* conf->headers.hash = { NULL, 0 };
|
* conf->headers.hash = { NULL, 0 };
|
||||||
* conf->headers_cache.lengths = NULL;
|
* conf->headers_cache.lengths = NULL;
|
||||||
* conf->host_set = 0;
|
|
||||||
* conf->headers_cache.values = NULL;
|
* conf->headers_cache.values = NULL;
|
||||||
* conf->headers_cache.hash = { NULL, 0 };
|
* conf->headers_cache.hash = { NULL, 0 };
|
||||||
* conf->body_lengths = NULL;
|
* conf->body_lengths = NULL;
|
||||||
|
|
@ -4106,7 +4152,6 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
#if (NGX_HTTP_CACHE)
|
#if (NGX_HTTP_CACHE)
|
||||||
conf->headers_cache = prev->headers_cache;
|
conf->headers_cache = prev->headers_cache;
|
||||||
#endif
|
#endif
|
||||||
conf->host_set = prev->host_set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ngx_http_proxy_init_headers(cf, conf, &conf->headers,
|
rc = ngx_http_proxy_init_headers(cf, conf, &conf->headers,
|
||||||
|
|
@ -4139,7 +4184,6 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
#if (NGX_HTTP_CACHE)
|
#if (NGX_HTTP_CACHE)
|
||||||
prev->headers_cache = conf->headers_cache;
|
prev->headers_cache = conf->headers_cache;
|
||||||
#endif
|
#endif
|
||||||
prev->host_set = conf->host_set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
|
|
@ -4192,12 +4236,6 @@ ngx_http_proxy_init_headers(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *conf,
|
||||||
src = conf->headers_source->elts;
|
src = conf->headers_source->elts;
|
||||||
for (i = 0; i < conf->headers_source->nelts; i++) {
|
for (i = 0; i < conf->headers_source->nelts; i++) {
|
||||||
|
|
||||||
if (src[i].key.len == 4
|
|
||||||
&& ngx_strncasecmp(src[i].key.data, (u_char *) "Host", 4) == 0)
|
|
||||||
{
|
|
||||||
conf->host_set = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
s = ngx_array_push(&headers_merged);
|
s = ngx_array_push(&headers_merged);
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
|
|
|
||||||
|
|
@ -1,127 +0,0 @@
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) Igor Sysoev
|
|
||||||
* Copyright (C) Nginx, Inc.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _NGX_HTTP_PROXY_H_INCLUDED_
|
|
||||||
#define _NGX_HTTP_PROXY_H_INCLUDED_
|
|
||||||
|
|
||||||
|
|
||||||
#include <ngx_config.h>
|
|
||||||
#include <ngx_core.h>
|
|
||||||
#include <ngx_http.h>
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
ngx_array_t caches; /* ngx_http_file_cache_t * */
|
|
||||||
} ngx_http_proxy_main_conf_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
ngx_str_t key_start;
|
|
||||||
ngx_str_t schema;
|
|
||||||
ngx_str_t host_header;
|
|
||||||
ngx_str_t port;
|
|
||||||
ngx_str_t uri;
|
|
||||||
} ngx_http_proxy_vars_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
ngx_array_t *flushes;
|
|
||||||
ngx_array_t *lengths;
|
|
||||||
ngx_array_t *values;
|
|
||||||
ngx_hash_t hash;
|
|
||||||
} ngx_http_proxy_headers_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
ngx_http_upstream_conf_t upstream;
|
|
||||||
|
|
||||||
ngx_array_t *body_flushes;
|
|
||||||
ngx_array_t *body_lengths;
|
|
||||||
ngx_array_t *body_values;
|
|
||||||
ngx_str_t body_source;
|
|
||||||
|
|
||||||
ngx_http_proxy_headers_t headers;
|
|
||||||
#if (NGX_HTTP_CACHE)
|
|
||||||
ngx_http_proxy_headers_t headers_cache;
|
|
||||||
#endif
|
|
||||||
ngx_array_t *headers_source;
|
|
||||||
ngx_uint_t host_set;
|
|
||||||
|
|
||||||
ngx_array_t *proxy_lengths;
|
|
||||||
ngx_array_t *proxy_values;
|
|
||||||
|
|
||||||
ngx_array_t *redirects;
|
|
||||||
ngx_array_t *cookie_domains;
|
|
||||||
ngx_array_t *cookie_paths;
|
|
||||||
ngx_array_t *cookie_flags;
|
|
||||||
|
|
||||||
ngx_http_complex_value_t *method;
|
|
||||||
ngx_str_t location;
|
|
||||||
ngx_str_t url;
|
|
||||||
|
|
||||||
#if (NGX_HTTP_CACHE)
|
|
||||||
ngx_http_complex_value_t cache_key;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ngx_http_proxy_vars_t vars;
|
|
||||||
|
|
||||||
ngx_flag_t redirect;
|
|
||||||
|
|
||||||
ngx_uint_t http_version;
|
|
||||||
|
|
||||||
ngx_uint_t headers_hash_max_size;
|
|
||||||
ngx_uint_t headers_hash_bucket_size;
|
|
||||||
|
|
||||||
#if (NGX_HTTP_SSL || NGX_COMPAT)
|
|
||||||
ngx_uint_t ssl;
|
|
||||||
ngx_uint_t ssl_protocols;
|
|
||||||
ngx_str_t ssl_ciphers;
|
|
||||||
ngx_uint_t ssl_verify_depth;
|
|
||||||
ngx_str_t ssl_trusted_certificate;
|
|
||||||
ngx_str_t ssl_crl;
|
|
||||||
ngx_array_t *ssl_conf_commands;
|
|
||||||
#endif
|
|
||||||
} ngx_http_proxy_loc_conf_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
ngx_http_status_t status;
|
|
||||||
ngx_http_chunked_t chunked;
|
|
||||||
ngx_http_proxy_vars_t vars;
|
|
||||||
off_t internal_body_length;
|
|
||||||
|
|
||||||
ngx_chain_t *free;
|
|
||||||
ngx_chain_t *busy;
|
|
||||||
|
|
||||||
ngx_buf_t *trailers;
|
|
||||||
|
|
||||||
unsigned head:1;
|
|
||||||
unsigned internal_chunked:1;
|
|
||||||
unsigned header_sent:1;
|
|
||||||
unsigned legacy:1;
|
|
||||||
} ngx_http_proxy_ctx_t;
|
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t ngx_http_proxy_eval(ngx_http_request_t *r, ngx_http_proxy_ctx_t *ctx,
|
|
||||||
ngx_http_proxy_loc_conf_t *plcf);
|
|
||||||
#if (NGX_HTTP_CACHE)
|
|
||||||
ngx_int_t ngx_http_proxy_create_key(ngx_http_request_t *r);
|
|
||||||
#endif
|
|
||||||
ngx_int_t ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r,
|
|
||||||
ngx_table_elt_t *h, size_t prefix);
|
|
||||||
ngx_int_t ngx_http_proxy_rewrite_cookie(ngx_http_request_t *r,
|
|
||||||
ngx_table_elt_t *h);
|
|
||||||
|
|
||||||
#if (NGX_HTTP_V2)
|
|
||||||
ngx_int_t ngx_http_proxy_v2_handler(ngx_http_request_t *r);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
extern ngx_module_t ngx_http_proxy_module;
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _NGX_HTTP_PROXY_H_INCLUDED_ */
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -117,13 +117,6 @@ static ngx_command_t ngx_http_ssl_commands[] = {
|
||||||
0,
|
0,
|
||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("ssl_ech_file"),
|
|
||||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
|
||||||
ngx_conf_set_str_array_slot,
|
|
||||||
NGX_HTTP_SRV_CONF_OFFSET,
|
|
||||||
offsetof(ngx_http_ssl_srv_conf_t, ech_files),
|
|
||||||
NULL },
|
|
||||||
|
|
||||||
{ ngx_string("ssl_password_file"),
|
{ ngx_string("ssl_password_file"),
|
||||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||||
ngx_http_ssl_password_file,
|
ngx_http_ssl_password_file,
|
||||||
|
|
@ -131,13 +124,6 @@ static ngx_command_t ngx_http_ssl_commands[] = {
|
||||||
0,
|
0,
|
||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("ssl_certificate_compression"),
|
|
||||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
|
||||||
ngx_conf_set_flag_slot,
|
|
||||||
NGX_HTTP_SRV_CONF_OFFSET,
|
|
||||||
offsetof(ngx_http_ssl_srv_conf_t, certificate_compression),
|
|
||||||
NULL },
|
|
||||||
|
|
||||||
{ ngx_string("ssl_dhparam"),
|
{ ngx_string("ssl_dhparam"),
|
||||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||||
ngx_conf_set_str_slot,
|
ngx_conf_set_str_slot,
|
||||||
|
|
@ -244,7 +230,7 @@ static ngx_command_t ngx_http_ssl_commands[] = {
|
||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("ssl_ocsp"),
|
{ ngx_string("ssl_ocsp"),
|
||||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
||||||
ngx_conf_set_enum_slot,
|
ngx_conf_set_enum_slot,
|
||||||
NGX_HTTP_SRV_CONF_OFFSET,
|
NGX_HTTP_SRV_CONF_OFFSET,
|
||||||
offsetof(ngx_http_ssl_srv_conf_t, ocsp),
|
offsetof(ngx_http_ssl_srv_conf_t, ocsp),
|
||||||
|
|
@ -365,9 +351,6 @@ static ngx_http_variable_t ngx_http_ssl_vars[] = {
|
||||||
{ ngx_string("ssl_curves"), NULL, ngx_http_ssl_variable,
|
{ ngx_string("ssl_curves"), NULL, ngx_http_ssl_variable,
|
||||||
(uintptr_t) ngx_ssl_get_curves, NGX_HTTP_VAR_CHANGEABLE, 0 },
|
(uintptr_t) ngx_ssl_get_curves, NGX_HTTP_VAR_CHANGEABLE, 0 },
|
||||||
|
|
||||||
{ ngx_string("ssl_sigalg"), NULL, ngx_http_ssl_variable,
|
|
||||||
(uintptr_t) ngx_ssl_get_sigalg, NGX_HTTP_VAR_CHANGEABLE, 0 },
|
|
||||||
|
|
||||||
{ ngx_string("ssl_session_id"), NULL, ngx_http_ssl_variable,
|
{ ngx_string("ssl_session_id"), NULL, ngx_http_ssl_variable,
|
||||||
(uintptr_t) ngx_ssl_get_session_id, NGX_HTTP_VAR_CHANGEABLE, 0 },
|
(uintptr_t) ngx_ssl_get_session_id, NGX_HTTP_VAR_CHANGEABLE, 0 },
|
||||||
|
|
||||||
|
|
@ -384,13 +367,6 @@ static ngx_http_variable_t ngx_http_ssl_vars[] = {
|
||||||
{ ngx_string("ssl_alpn_protocol"), NULL, ngx_http_ssl_variable,
|
{ ngx_string("ssl_alpn_protocol"), NULL, ngx_http_ssl_variable,
|
||||||
(uintptr_t) ngx_ssl_get_alpn_protocol, NGX_HTTP_VAR_CHANGEABLE, 0 },
|
(uintptr_t) ngx_ssl_get_alpn_protocol, NGX_HTTP_VAR_CHANGEABLE, 0 },
|
||||||
|
|
||||||
{ ngx_string("ssl_ech_status"), NULL, ngx_http_ssl_variable,
|
|
||||||
(uintptr_t) ngx_ssl_get_ech_status, NGX_HTTP_VAR_CHANGEABLE, 0 },
|
|
||||||
|
|
||||||
{ ngx_string("ssl_ech_outer_server_name"), NULL, ngx_http_ssl_variable,
|
|
||||||
(uintptr_t) ngx_ssl_get_ech_outer_server_name,
|
|
||||||
NGX_HTTP_VAR_CHANGEABLE, 0 },
|
|
||||||
|
|
||||||
{ ngx_string("ssl_client_cert"), NULL, ngx_http_ssl_variable,
|
{ ngx_string("ssl_client_cert"), NULL, ngx_http_ssl_variable,
|
||||||
(uintptr_t) ngx_ssl_get_certificate, NGX_HTTP_VAR_CHANGEABLE, 0 },
|
(uintptr_t) ngx_ssl_get_certificate, NGX_HTTP_VAR_CHANGEABLE, 0 },
|
||||||
|
|
||||||
|
|
@ -432,9 +408,6 @@ static ngx_http_variable_t ngx_http_ssl_vars[] = {
|
||||||
{ ngx_string("ssl_client_v_remain"), NULL, ngx_http_ssl_variable,
|
{ ngx_string("ssl_client_v_remain"), NULL, ngx_http_ssl_variable,
|
||||||
(uintptr_t) ngx_ssl_get_client_v_remain, NGX_HTTP_VAR_CHANGEABLE, 0 },
|
(uintptr_t) ngx_ssl_get_client_v_remain, NGX_HTTP_VAR_CHANGEABLE, 0 },
|
||||||
|
|
||||||
{ ngx_string("ssl_client_sigalg"), NULL, ngx_http_ssl_variable,
|
|
||||||
(uintptr_t) ngx_ssl_get_client_sigalg, NGX_HTTP_VAR_CHANGEABLE, 0 },
|
|
||||||
|
|
||||||
ngx_http_null_variable
|
ngx_http_null_variable
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -648,7 +621,6 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sscf->prefer_server_ciphers = NGX_CONF_UNSET;
|
sscf->prefer_server_ciphers = NGX_CONF_UNSET;
|
||||||
sscf->certificate_compression = NGX_CONF_UNSET;
|
|
||||||
sscf->early_data = NGX_CONF_UNSET;
|
sscf->early_data = NGX_CONF_UNSET;
|
||||||
sscf->reject_handshake = NGX_CONF_UNSET;
|
sscf->reject_handshake = NGX_CONF_UNSET;
|
||||||
sscf->buffer_size = NGX_CONF_UNSET_SIZE;
|
sscf->buffer_size = NGX_CONF_UNSET_SIZE;
|
||||||
|
|
@ -657,7 +629,6 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
|
||||||
sscf->certificates = NGX_CONF_UNSET_PTR;
|
sscf->certificates = NGX_CONF_UNSET_PTR;
|
||||||
sscf->certificate_keys = NGX_CONF_UNSET_PTR;
|
sscf->certificate_keys = NGX_CONF_UNSET_PTR;
|
||||||
sscf->certificate_cache = NGX_CONF_UNSET_PTR;
|
sscf->certificate_cache = NGX_CONF_UNSET_PTR;
|
||||||
sscf->ech_files = NGX_CONF_UNSET_PTR;
|
|
||||||
sscf->passwords = NGX_CONF_UNSET_PTR;
|
sscf->passwords = NGX_CONF_UNSET_PTR;
|
||||||
sscf->conf_commands = NGX_CONF_UNSET_PTR;
|
sscf->conf_commands = NGX_CONF_UNSET_PTR;
|
||||||
sscf->builtin_session_cache = NGX_CONF_UNSET;
|
sscf->builtin_session_cache = NGX_CONF_UNSET;
|
||||||
|
|
@ -687,9 +658,6 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
ngx_conf_merge_value(conf->prefer_server_ciphers,
|
ngx_conf_merge_value(conf->prefer_server_ciphers,
|
||||||
prev->prefer_server_ciphers, 0);
|
prev->prefer_server_ciphers, 0);
|
||||||
|
|
||||||
ngx_conf_merge_value(conf->certificate_compression,
|
|
||||||
prev->certificate_compression, 0);
|
|
||||||
|
|
||||||
ngx_conf_merge_value(conf->early_data, prev->early_data, 0);
|
ngx_conf_merge_value(conf->early_data, prev->early_data, 0);
|
||||||
ngx_conf_merge_value(conf->reject_handshake, prev->reject_handshake, 0);
|
ngx_conf_merge_value(conf->reject_handshake, prev->reject_handshake, 0);
|
||||||
|
|
||||||
|
|
@ -709,8 +677,6 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
ngx_conf_merge_ptr_value(conf->certificate_cache, prev->certificate_cache,
|
ngx_conf_merge_ptr_value(conf->certificate_cache, prev->certificate_cache,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
ngx_conf_merge_ptr_value(conf->ech_files, prev->ech_files, NULL);
|
|
||||||
|
|
||||||
ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL);
|
ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL);
|
||||||
|
|
||||||
ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");
|
ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");
|
||||||
|
|
@ -772,12 +738,6 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
cln->data = &conf->ssl;
|
cln->data = &conf->ssl;
|
||||||
|
|
||||||
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
|
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
|
||||||
{
|
|
||||||
static ngx_ssl_client_hello_arg cb = { ngx_http_ssl_servername };
|
|
||||||
|
|
||||||
if (ngx_ssl_set_client_hello_callback(&conf->ssl, &cb) != NGX_OK) {
|
|
||||||
return NGX_CONF_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx,
|
if (SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx,
|
||||||
ngx_http_ssl_servername)
|
ngx_http_ssl_servername)
|
||||||
|
|
@ -788,7 +748,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
"dynamically to an OpenSSL library which has no tlsext support, "
|
"dynamically to an OpenSSL library which has no tlsext support, "
|
||||||
"therefore SNI is not available");
|
"therefore SNI is not available");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
|
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
|
||||||
|
|
@ -832,13 +792,6 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
{
|
{
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_ssl_certificate_compression(cf, &conf->ssl,
|
|
||||||
conf->certificate_compression)
|
|
||||||
!= NGX_OK)
|
|
||||||
{
|
|
||||||
return NGX_CONF_ERROR;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
conf->ssl.buffer_size = conf->buffer_size;
|
conf->ssl.buffer_size = conf->buffer_size;
|
||||||
|
|
@ -897,10 +850,6 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_ssl_ech_files(cf, &conf->ssl, conf->ech_files) != NGX_OK) {
|
|
||||||
return NGX_CONF_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) {
|
if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) {
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
@ -939,19 +888,13 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
|
|
||||||
if (conf->stapling) {
|
if (conf->stapling) {
|
||||||
|
|
||||||
if (conf->certificate_compression) {
|
|
||||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
|
||||||
"\"ssl_stapling\" is incompatible with "
|
|
||||||
"\"ssl_certificate_compression\"");
|
|
||||||
return NGX_CONF_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ngx_ssl_stapling(cf, &conf->ssl, &conf->stapling_file,
|
if (ngx_ssl_stapling(cf, &conf->ssl, &conf->stapling_file,
|
||||||
&conf->stapling_responder, conf->stapling_verify)
|
&conf->stapling_responder, conf->stapling_verify)
|
||||||
!= NGX_OK)
|
!= NGX_OK)
|
||||||
{
|
{
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_ssl_early_data(cf, &conf->ssl, conf->early_data) != NGX_OK) {
|
if (ngx_ssl_early_data(cf, &conf->ssl, conf->early_data) != NGX_OK) {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ typedef struct {
|
||||||
ngx_ssl_t ssl;
|
ngx_ssl_t ssl;
|
||||||
|
|
||||||
ngx_flag_t prefer_server_ciphers;
|
ngx_flag_t prefer_server_ciphers;
|
||||||
ngx_flag_t certificate_compression;
|
|
||||||
ngx_flag_t early_data;
|
ngx_flag_t early_data;
|
||||||
ngx_flag_t reject_handshake;
|
ngx_flag_t reject_handshake;
|
||||||
|
|
||||||
|
|
@ -49,7 +48,6 @@ typedef struct {
|
||||||
|
|
||||||
ngx_str_t ciphers;
|
ngx_str_t ciphers;
|
||||||
|
|
||||||
ngx_array_t *ech_files;
|
|
||||||
ngx_array_t *passwords;
|
ngx_array_t *passwords;
|
||||||
ngx_array_t *conf_commands;
|
ngx_array_t *conf_commands;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,7 @@ ngx_int_t ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
|
||||||
|
|
||||||
ngx_http_request_t *ngx_http_create_request(ngx_connection_t *c);
|
ngx_http_request_t *ngx_http_create_request(ngx_connection_t *c);
|
||||||
ngx_int_t ngx_http_process_request_uri(ngx_http_request_t *r);
|
ngx_int_t ngx_http_process_request_uri(ngx_http_request_t *r);
|
||||||
|
ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);
|
||||||
void ngx_http_process_request(ngx_http_request_t *r);
|
void ngx_http_process_request(ngx_http_request_t *r);
|
||||||
void ngx_http_update_location_config(ngx_http_request_t *r);
|
void ngx_http_update_location_config(ngx_http_request_t *r);
|
||||||
void ngx_http_handler(ngx_http_request_t *r);
|
void ngx_http_handler(ngx_http_request_t *r);
|
||||||
|
|
@ -130,8 +131,8 @@ ngx_int_t ngx_http_post_request(ngx_http_request_t *r,
|
||||||
ngx_http_posted_request_t *pr);
|
ngx_http_posted_request_t *pr);
|
||||||
ngx_int_t ngx_http_set_virtual_server(ngx_http_request_t *r,
|
ngx_int_t ngx_http_set_virtual_server(ngx_http_request_t *r,
|
||||||
ngx_str_t *host);
|
ngx_str_t *host);
|
||||||
ngx_int_t ngx_http_validate_host(ngx_str_t *host, in_port_t *port,
|
ngx_int_t ngx_http_validate_host(ngx_str_t *host, ngx_pool_t *pool,
|
||||||
ngx_pool_t *pool, ngx_uint_t alloc);
|
ngx_uint_t alloc);
|
||||||
void ngx_http_close_request(ngx_http_request_t *r, ngx_int_t rc);
|
void ngx_http_close_request(ngx_http_request_t *r, ngx_int_t rc);
|
||||||
void ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc);
|
void ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc);
|
||||||
void ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc);
|
void ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc);
|
||||||
|
|
|
||||||
|
|
@ -206,7 +206,6 @@ typedef struct {
|
||||||
#if (NGX_PCRE)
|
#if (NGX_PCRE)
|
||||||
unsigned captures:1;
|
unsigned captures:1;
|
||||||
#endif
|
#endif
|
||||||
unsigned allow_connect:1;
|
|
||||||
|
|
||||||
ngx_http_core_loc_conf_t **named_locations;
|
ngx_http_core_loc_conf_t **named_locations;
|
||||||
} ngx_http_core_srv_conf_t;
|
} ngx_http_core_srv_conf_t;
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,6 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
|
||||||
sw_schema,
|
sw_schema,
|
||||||
sw_schema_slash,
|
sw_schema_slash,
|
||||||
sw_schema_slash_slash,
|
sw_schema_slash_slash,
|
||||||
sw_spaces_before_host,
|
|
||||||
sw_host_start,
|
sw_host_start,
|
||||||
sw_host,
|
sw_host,
|
||||||
sw_host_end,
|
sw_host_end,
|
||||||
|
|
@ -159,7 +158,6 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
|
||||||
if (ch == ' ') {
|
if (ch == ' ') {
|
||||||
r->method_end = p - 1;
|
r->method_end = p - 1;
|
||||||
m = r->request_start;
|
m = r->request_start;
|
||||||
state = sw_spaces_before_uri;
|
|
||||||
|
|
||||||
switch (p - m) {
|
switch (p - m) {
|
||||||
|
|
||||||
|
|
@ -249,7 +247,6 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
|
||||||
if (ngx_str7_cmp(m, 'C', 'O', 'N', 'N', 'E', 'C', 'T', ' '))
|
if (ngx_str7_cmp(m, 'C', 'O', 'N', 'N', 'E', 'C', 'T', ' '))
|
||||||
{
|
{
|
||||||
r->method = NGX_HTTP_CONNECT;
|
r->method = NGX_HTTP_CONNECT;
|
||||||
state = sw_spaces_before_host;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -272,6 +269,7 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state = sw_spaces_before_uri;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -347,14 +345,6 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case sw_spaces_before_host:
|
|
||||||
|
|
||||||
if (ch == ' ') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fall through */
|
|
||||||
|
|
||||||
case sw_host_start:
|
case sw_host_start:
|
||||||
|
|
||||||
r->host_start = p;
|
r->host_start = p;
|
||||||
|
|
@ -383,18 +373,12 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
|
||||||
|
|
||||||
case sw_host_end:
|
case sw_host_end:
|
||||||
|
|
||||||
if (ch == ':') {
|
|
||||||
state = sw_port;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
r->host_end = p;
|
r->host_end = p;
|
||||||
|
|
||||||
if (r->method == NGX_HTTP_CONNECT) {
|
|
||||||
return NGX_HTTP_PARSE_INVALID_REQUEST;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
|
case ':':
|
||||||
|
state = sw_port;
|
||||||
|
break;
|
||||||
case '/':
|
case '/':
|
||||||
r->uri_start = p;
|
r->uri_start = p;
|
||||||
state = sw_after_slash_in_uri;
|
state = sw_after_slash_in_uri;
|
||||||
|
|
@ -465,17 +449,6 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
r->host_end = p;
|
|
||||||
|
|
||||||
if (r->method == NGX_HTTP_CONNECT) {
|
|
||||||
if (ch == ' ') {
|
|
||||||
state = sw_http_09;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NGX_HTTP_PARSE_INVALID_REQUEST;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case '/':
|
case '/':
|
||||||
r->uri_start = p;
|
r->uri_start = p;
|
||||||
|
|
@ -711,16 +684,6 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
|
||||||
case sw_http_HTTP:
|
case sw_http_HTTP:
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case '/':
|
case '/':
|
||||||
|
|
||||||
/*
|
|
||||||
* use single "/" from request line to preserve pointers,
|
|
||||||
* if request line will be copied to large client buffer
|
|
||||||
*/
|
|
||||||
if (r->method == NGX_HTTP_CONNECT) {
|
|
||||||
r->uri_start = p;
|
|
||||||
r->uri_end = p + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
state = sw_first_major_digit;
|
state = sw_first_major_digit;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -2254,6 +2217,12 @@ ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
|
||||||
case CR:
|
case CR:
|
||||||
state = sw_last_chunk_extension_almost_done;
|
state = sw_last_chunk_extension_almost_done;
|
||||||
break;
|
break;
|
||||||
|
case LF:
|
||||||
|
if (keep_trailers) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
state = sw_trailer;
|
||||||
|
break;
|
||||||
case ';':
|
case ';':
|
||||||
case ' ':
|
case ' ':
|
||||||
case '\t':
|
case '\t':
|
||||||
|
|
@ -2270,6 +2239,9 @@ ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
|
||||||
case CR:
|
case CR:
|
||||||
state = sw_chunk_extension_almost_done;
|
state = sw_chunk_extension_almost_done;
|
||||||
break;
|
break;
|
||||||
|
case LF:
|
||||||
|
state = sw_chunk_data;
|
||||||
|
break;
|
||||||
case ';':
|
case ';':
|
||||||
case ' ':
|
case ' ':
|
||||||
case '\t':
|
case '\t':
|
||||||
|
|
@ -2287,7 +2259,7 @@ ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
|
||||||
state = sw_chunk_extension_almost_done;
|
state = sw_chunk_extension_almost_done;
|
||||||
break;
|
break;
|
||||||
case LF:
|
case LF:
|
||||||
goto invalid;
|
state = sw_chunk_data;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -2307,6 +2279,9 @@ ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
|
||||||
case CR:
|
case CR:
|
||||||
state = sw_after_data_almost_done;
|
state = sw_after_data_almost_done;
|
||||||
break;
|
break;
|
||||||
|
case LF:
|
||||||
|
state = sw_chunk_start;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
goto invalid;
|
goto invalid;
|
||||||
}
|
}
|
||||||
|
|
@ -2325,7 +2300,10 @@ ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
|
||||||
state = sw_last_chunk_extension_almost_done;
|
state = sw_last_chunk_extension_almost_done;
|
||||||
break;
|
break;
|
||||||
case LF:
|
case LF:
|
||||||
goto invalid;
|
if (keep_trailers) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
state = sw_trailer;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -2345,7 +2323,7 @@ ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
|
||||||
state = sw_trailer_almost_done;
|
state = sw_trailer_almost_done;
|
||||||
break;
|
break;
|
||||||
case LF:
|
case LF:
|
||||||
goto invalid;
|
goto done;
|
||||||
default:
|
default:
|
||||||
state = sw_trailer_header;
|
state = sw_trailer_header;
|
||||||
}
|
}
|
||||||
|
|
@ -2363,7 +2341,7 @@ ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
|
||||||
state = sw_trailer_header_almost_done;
|
state = sw_trailer_header_almost_done;
|
||||||
break;
|
break;
|
||||||
case LF:
|
case LF:
|
||||||
goto invalid;
|
state = sw_trailer;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -2389,45 +2367,35 @@ data:
|
||||||
switch (state) {
|
switch (state) {
|
||||||
|
|
||||||
case sw_chunk_start:
|
case sw_chunk_start:
|
||||||
ctx->length = 5 /* "0" CRLF CRLF */;
|
ctx->length = 3 /* "0" LF LF */;
|
||||||
break;
|
break;
|
||||||
case sw_chunk_size:
|
case sw_chunk_size:
|
||||||
ctx->length = 2 /* CRLF */
|
ctx->length = 1 /* LF */
|
||||||
+ (ctx->size ? ctx->size + 7 /* CRLF "0" CRLF CRLF */
|
+ (ctx->size ? ctx->size + 4 /* LF "0" LF LF */
|
||||||
: 2 /* CRLF */);
|
: 1 /* LF */);
|
||||||
break;
|
break;
|
||||||
case sw_chunk_extension:
|
case sw_chunk_extension:
|
||||||
ctx->length = 2 /* CRLF */ + ctx->size + 7 /* CRLF "0" CRLF CRLF */;
|
|
||||||
break;
|
|
||||||
case sw_chunk_extension_almost_done:
|
case sw_chunk_extension_almost_done:
|
||||||
ctx->length = 1 /* LF */ + ctx->size + 7 /* CRLF "0" CRLF CRLF */;
|
ctx->length = 1 /* LF */ + ctx->size + 4 /* LF "0" LF LF */;
|
||||||
break;
|
break;
|
||||||
case sw_chunk_data:
|
case sw_chunk_data:
|
||||||
ctx->length = ctx->size + 7 /* CRLF "0" CRLF CRLF */;
|
ctx->length = ctx->size + 4 /* LF "0" LF LF */;
|
||||||
break;
|
break;
|
||||||
case sw_after_data:
|
case sw_after_data:
|
||||||
ctx->length = 7 /* CRLF "0" CRLF CRLF */;
|
|
||||||
break;
|
|
||||||
case sw_after_data_almost_done:
|
case sw_after_data_almost_done:
|
||||||
ctx->length = 6 /* LF "0" CRLF CRLF */;
|
ctx->length = 4 /* LF "0" LF LF */;
|
||||||
break;
|
break;
|
||||||
case sw_last_chunk_extension:
|
case sw_last_chunk_extension:
|
||||||
ctx->length = 4 /* CRLF CRLF */;
|
|
||||||
break;
|
|
||||||
case sw_last_chunk_extension_almost_done:
|
case sw_last_chunk_extension_almost_done:
|
||||||
ctx->length = 3 /* LF CRLF */;
|
ctx->length = 2 /* LF LF */;
|
||||||
break;
|
break;
|
||||||
case sw_trailer:
|
case sw_trailer:
|
||||||
ctx->length = 2 /* CRLF */;
|
|
||||||
break;
|
|
||||||
case sw_trailer_almost_done:
|
case sw_trailer_almost_done:
|
||||||
ctx->length = 1 /* LF */;
|
ctx->length = 1 /* LF */;
|
||||||
break;
|
break;
|
||||||
case sw_trailer_header:
|
case sw_trailer_header:
|
||||||
ctx->length = 4 /* CRLF CRLF */;
|
|
||||||
break;
|
|
||||||
case sw_trailer_header_almost_done:
|
case sw_trailer_header_almost_done:
|
||||||
ctx->length = 3 /* LF CRLF */;
|
ctx->length = 2 /* LF LF */;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ static ngx_int_t ngx_http_process_connection(ngx_http_request_t *r,
|
||||||
static ngx_int_t ngx_http_process_user_agent(ngx_http_request_t *r,
|
static ngx_int_t ngx_http_process_user_agent(ngx_http_request_t *r,
|
||||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||||
|
|
||||||
static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);
|
|
||||||
static ngx_int_t ngx_http_find_virtual_server(ngx_connection_t *c,
|
static ngx_int_t ngx_http_find_virtual_server(ngx_connection_t *c,
|
||||||
ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
|
ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
|
||||||
ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp);
|
ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp);
|
||||||
|
|
@ -891,27 +890,8 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
||||||
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->ssl->sni_accepted) {
|
|
||||||
return SSL_TLSEXT_ERR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c->ssl->handshake_rejected) {
|
|
||||||
*ad = SSL_AD_UNRECOGNIZED_NAME;
|
|
||||||
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
hc = c->data;
|
hc = c->data;
|
||||||
|
|
||||||
if (arg != NULL) {
|
|
||||||
host = *(ngx_str_t *) arg;
|
|
||||||
|
|
||||||
if (host.data == NULL) {
|
|
||||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
|
||||||
"SSL server name: null");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);
|
servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);
|
||||||
|
|
||||||
if (servername == NULL) {
|
if (servername == NULL) {
|
||||||
|
|
@ -920,18 +900,18 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
host.len = ngx_strlen(servername);
|
|
||||||
host.data = (u_char *) servername;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||||
"SSL server name: \"%V\"", &host);
|
"SSL server name: \"%s\"", servername);
|
||||||
|
|
||||||
|
host.len = ngx_strlen(servername);
|
||||||
|
|
||||||
if (host.len == 0) {
|
if (host.len == 0) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ngx_http_validate_host(&host, NULL, c->pool, 1);
|
host.data = (u_char *) servername;
|
||||||
|
|
||||||
|
rc = ngx_http_validate_host(&host, c->pool, 1);
|
||||||
|
|
||||||
if (rc == NGX_ERROR) {
|
if (rc == NGX_ERROR) {
|
||||||
goto error;
|
goto error;
|
||||||
|
|
@ -952,6 +932,31 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sscf = ngx_http_get_module_srv_conf(cscf->ctx, ngx_http_ssl_module);
|
||||||
|
|
||||||
|
#if (defined TLS1_3_VERSION \
|
||||||
|
&& !defined LIBRESSL_VERSION_NUMBER && !defined OPENSSL_IS_BORINGSSL)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SSL_SESSION_get0_hostname() is only available in OpenSSL 1.1.1+,
|
||||||
|
* but servername being negotiated in every TLSv1.3 handshake
|
||||||
|
* is only returned in OpenSSL 1.1.1+ as well
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (sscf->verify) {
|
||||||
|
const char *hostname;
|
||||||
|
|
||||||
|
hostname = SSL_SESSION_get0_hostname(SSL_get0_session(ssl_conn));
|
||||||
|
|
||||||
|
if (hostname != NULL && ngx_strcmp(hostname, servername) != 0) {
|
||||||
|
c->ssl->handshake_rejected = 1;
|
||||||
|
*ad = SSL_AD_ACCESS_DENIED;
|
||||||
|
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
hc->ssl_servername = ngx_palloc(c->pool, sizeof(ngx_str_t));
|
hc->ssl_servername = ngx_palloc(c->pool, sizeof(ngx_str_t));
|
||||||
if (hc->ssl_servername == NULL) {
|
if (hc->ssl_servername == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
|
|
@ -965,8 +970,6 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
||||||
|
|
||||||
ngx_set_connection_log(c, clcf->error_log);
|
ngx_set_connection_log(c, clcf->error_log);
|
||||||
|
|
||||||
sscf = ngx_http_get_module_srv_conf(cscf->ctx, ngx_http_ssl_module);
|
|
||||||
|
|
||||||
c->ssl->buffer_size = sscf->buffer_size;
|
c->ssl->buffer_size = sscf->buffer_size;
|
||||||
|
|
||||||
if (sscf->ssl.ctx) {
|
if (sscf->ssl.ctx) {
|
||||||
|
|
@ -1015,7 +1018,6 @@ done:
|
||||||
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
c->ssl->sni_accepted = 1;
|
|
||||||
return SSL_TLSEXT_ERR_OK;
|
return SSL_TLSEXT_ERR_OK;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
|
@ -1107,7 +1109,6 @@ ngx_http_process_request_line(ngx_event_t *rev)
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
ngx_int_t rc, rv;
|
ngx_int_t rc, rv;
|
||||||
ngx_str_t host;
|
ngx_str_t host;
|
||||||
in_port_t port;
|
|
||||||
ngx_connection_t *c;
|
ngx_connection_t *c;
|
||||||
ngx_http_request_t *r;
|
ngx_http_request_t *r;
|
||||||
|
|
||||||
|
|
@ -1170,7 +1171,7 @@ ngx_http_process_request_line(ngx_event_t *rev)
|
||||||
host.len = r->host_end - r->host_start;
|
host.len = r->host_end - r->host_start;
|
||||||
host.data = r->host_start;
|
host.data = r->host_start;
|
||||||
|
|
||||||
rc = ngx_http_validate_host(&host, &port, r->pool, 0);
|
rc = ngx_http_validate_host(&host, r->pool, 0);
|
||||||
|
|
||||||
if (rc == NGX_DECLINED) {
|
if (rc == NGX_DECLINED) {
|
||||||
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||||
|
|
@ -1189,7 +1190,6 @@ ngx_http_process_request_line(ngx_event_t *rev)
|
||||||
}
|
}
|
||||||
|
|
||||||
r->headers_in.server = host;
|
r->headers_in.server = host;
|
||||||
r->port = port;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r->http_version < NGX_HTTP_VERSION_10) {
|
if (r->http_version < NGX_HTTP_VERSION_10) {
|
||||||
|
|
@ -1850,7 +1850,6 @@ ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||||
{
|
{
|
||||||
ngx_int_t rc;
|
ngx_int_t rc;
|
||||||
ngx_str_t host;
|
ngx_str_t host;
|
||||||
in_port_t port;
|
|
||||||
|
|
||||||
if (r->headers_in.host) {
|
if (r->headers_in.host) {
|
||||||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||||
|
|
@ -1867,7 +1866,7 @@ ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||||
|
|
||||||
host = h->value;
|
host = h->value;
|
||||||
|
|
||||||
rc = ngx_http_validate_host(&host, &port, r->pool, 0);
|
rc = ngx_http_validate_host(&host, r->pool, 0);
|
||||||
|
|
||||||
if (rc == NGX_DECLINED) {
|
if (rc == NGX_DECLINED) {
|
||||||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||||
|
|
@ -1890,7 +1889,6 @@ ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||||
}
|
}
|
||||||
|
|
||||||
r->headers_in.server = host;
|
r->headers_in.server = host;
|
||||||
r->port = port;
|
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -1986,11 +1984,9 @@ ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
ngx_int_t
|
||||||
ngx_http_process_request_header(ngx_http_request_t *r)
|
ngx_http_process_request_header(ngx_http_request_t *r)
|
||||||
{
|
{
|
||||||
ngx_http_core_srv_conf_t *cscf;
|
|
||||||
|
|
||||||
if (r->headers_in.server.len == 0
|
if (r->headers_in.server.len == 0
|
||||||
&& ngx_http_set_virtual_server(r, &r->headers_in.server)
|
&& ngx_http_set_virtual_server(r, &r->headers_in.server)
|
||||||
== NGX_ERROR)
|
== NGX_ERROR)
|
||||||
|
|
@ -2059,11 +2055,7 @@ ngx_http_process_request_header(ngx_http_request_t *r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
if (r->method == NGX_HTTP_CONNECT) {
|
||||||
|
|
||||||
if (r->method == NGX_HTTP_CONNECT
|
|
||||||
&& (r->http_version != NGX_HTTP_VERSION_11 || !cscf->allow_connect))
|
|
||||||
{
|
|
||||||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||||
"client sent CONNECT method");
|
"client sent CONNECT method");
|
||||||
ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
|
ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
|
||||||
|
|
@ -2174,174 +2166,72 @@ ngx_http_process_request(ngx_http_request_t *r)
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t
|
ngx_int_t
|
||||||
ngx_http_validate_host(ngx_str_t *host, in_port_t *portp, ngx_pool_t *pool,
|
ngx_http_validate_host(ngx_str_t *host, ngx_pool_t *pool, ngx_uint_t alloc)
|
||||||
ngx_uint_t alloc)
|
|
||||||
{
|
{
|
||||||
u_char *h, ch;
|
u_char *h, ch;
|
||||||
size_t i, dot_pos, host_len;
|
size_t i, dot_pos, host_len;
|
||||||
ngx_int_t port;
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
sw_host_start = 0,
|
sw_usual = 0,
|
||||||
sw_host,
|
sw_literal,
|
||||||
sw_host_ip_literal,
|
sw_rest
|
||||||
sw_host_end,
|
|
||||||
sw_port,
|
|
||||||
} state;
|
} state;
|
||||||
|
|
||||||
dot_pos = host->len;
|
dot_pos = host->len;
|
||||||
host_len = host->len;
|
host_len = host->len;
|
||||||
port = 0;
|
|
||||||
|
|
||||||
h = host->data;
|
h = host->data;
|
||||||
|
|
||||||
state = sw_host_start;
|
state = sw_usual;
|
||||||
|
|
||||||
for (i = 0; i < host->len; i++) {
|
for (i = 0; i < host->len; i++) {
|
||||||
ch = h[i];
|
ch = h[i];
|
||||||
|
|
||||||
switch (state) {
|
|
||||||
|
|
||||||
case sw_host_start:
|
|
||||||
|
|
||||||
if (ch == '[') {
|
|
||||||
state = sw_host_ip_literal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
state = sw_host;
|
|
||||||
|
|
||||||
/* fall through */
|
|
||||||
|
|
||||||
case sw_host:
|
|
||||||
|
|
||||||
if (ch >= 'A' && ch <= 'Z') {
|
|
||||||
alloc = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ch >= 'a' && ch <= 'z') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ch >= '0' && ch <= '9') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
|
|
||||||
|
case '.':
|
||||||
|
if (dot_pos == i - 1) {
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
dot_pos = i;
|
||||||
|
break;
|
||||||
|
|
||||||
case ':':
|
case ':':
|
||||||
|
if (state == sw_usual) {
|
||||||
host_len = i;
|
host_len = i;
|
||||||
state = sw_port;
|
state = sw_rest;
|
||||||
break;
|
|
||||||
case '-':
|
|
||||||
break;
|
|
||||||
case '.':
|
|
||||||
if (dot_pos == i - 1) {
|
|
||||||
return NGX_DECLINED;
|
|
||||||
}
|
|
||||||
dot_pos = i;
|
|
||||||
break;
|
|
||||||
case '_':
|
|
||||||
case '~':
|
|
||||||
/* unreserved */
|
|
||||||
break;
|
|
||||||
case '!':
|
|
||||||
case '$':
|
|
||||||
case '&':
|
|
||||||
case '\'':
|
|
||||||
case '(':
|
|
||||||
case ')':
|
|
||||||
case '*':
|
|
||||||
case '+':
|
|
||||||
case ',':
|
|
||||||
case ';':
|
|
||||||
case '=':
|
|
||||||
/* sub-delims */
|
|
||||||
break;
|
|
||||||
case '%':
|
|
||||||
/* pct-encoded */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return NGX_DECLINED;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case sw_host_ip_literal:
|
case '[':
|
||||||
|
if (i == 0) {
|
||||||
|
state = sw_literal;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ']':
|
||||||
|
if (state == sw_literal) {
|
||||||
|
host_len = i + 1;
|
||||||
|
state = sw_rest;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
if (ngx_path_separator(ch)) {
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch <= 0x20 || ch == 0x7f) {
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
if (ch >= 'A' && ch <= 'Z') {
|
if (ch >= 'A' && ch <= 'Z') {
|
||||||
alloc = 1;
|
alloc = 1;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ch >= 'a' && ch <= 'z') {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ch >= '0' && ch <= '9') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (ch) {
|
|
||||||
case ':':
|
|
||||||
break;
|
|
||||||
case ']':
|
|
||||||
host_len = i + 1;
|
|
||||||
state = sw_host_end;
|
|
||||||
break;
|
|
||||||
case '-':
|
|
||||||
break;
|
|
||||||
case '.':
|
|
||||||
if (dot_pos == i - 1) {
|
|
||||||
return NGX_DECLINED;
|
|
||||||
}
|
|
||||||
dot_pos = i;
|
|
||||||
break;
|
|
||||||
case '_':
|
|
||||||
case '~':
|
|
||||||
/* unreserved */
|
|
||||||
break;
|
|
||||||
case '!':
|
|
||||||
case '$':
|
|
||||||
case '&':
|
|
||||||
case '\'':
|
|
||||||
case '(':
|
|
||||||
case ')':
|
|
||||||
case '*':
|
|
||||||
case '+':
|
|
||||||
case ',':
|
|
||||||
case ';':
|
|
||||||
case '=':
|
|
||||||
/* sub-delims */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return NGX_DECLINED;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case sw_host_end:
|
|
||||||
|
|
||||||
if (ch == ':') {
|
|
||||||
state = sw_port;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return NGX_DECLINED;
|
|
||||||
|
|
||||||
case sw_port:
|
|
||||||
|
|
||||||
if (ch >= '0' && ch <= '9') {
|
|
||||||
if (port >= 6553 && (port > 6553 || (ch - '0') > 5)) {
|
|
||||||
return NGX_DECLINED;
|
|
||||||
}
|
|
||||||
|
|
||||||
port = port * 10 + (ch - '0');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return NGX_DECLINED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state == sw_host_ip_literal) {
|
|
||||||
return NGX_DECLINED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dot_pos == host_len - 1) {
|
if (dot_pos == host_len - 1) {
|
||||||
|
|
@ -2363,10 +2253,6 @@ ngx_http_validate_host(ngx_str_t *host, in_port_t *portp, ngx_pool_t *pool,
|
||||||
|
|
||||||
host->len = host_len;
|
host->len = host_len;
|
||||||
|
|
||||||
if (portp) {
|
|
||||||
*portp = port;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -461,8 +461,6 @@ struct ngx_http_request_s {
|
||||||
|
|
||||||
ngx_http_cleanup_t *cleanup;
|
ngx_http_cleanup_t *cleanup;
|
||||||
|
|
||||||
in_port_t port;
|
|
||||||
|
|
||||||
unsigned count:16;
|
unsigned count:16;
|
||||||
unsigned subrequests:8;
|
unsigned subrequests:8;
|
||||||
unsigned blocked:8;
|
unsigned blocked:8;
|
||||||
|
|
|
||||||
|
|
@ -116,10 +116,6 @@ static ngx_int_t ngx_http_upstream_process_set_cookie(ngx_http_request_t *r,
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
|
ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
|
||||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||||
#if (NGX_HTTP_CACHE)
|
|
||||||
static ngx_int_t ngx_http_upstream_process_delta_seconds(u_char *p,
|
|
||||||
u_char *last);
|
|
||||||
#endif
|
|
||||||
static ngx_int_t ngx_http_upstream_ignore_header_line(ngx_http_request_t *r,
|
static ngx_int_t ngx_http_upstream_ignore_header_line(ngx_http_request_t *r,
|
||||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||||
static ngx_int_t ngx_http_upstream_process_expires(ngx_http_request_t *r,
|
static ngx_int_t ngx_http_upstream_process_expires(ngx_http_request_t *r,
|
||||||
|
|
@ -1771,23 +1767,6 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
|
|
||||||
|
|
||||||
if (u->ssl_alpn_protocol.len) {
|
|
||||||
if (SSL_set_alpn_protos(c->ssl->connection, u->ssl_alpn_protocol.data,
|
|
||||||
u->ssl_alpn_protocol.len)
|
|
||||||
!= 0)
|
|
||||||
{
|
|
||||||
ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
|
|
||||||
"SSL_set_alpn_protos() failed");
|
|
||||||
ngx_http_upstream_finalize_request(r, u,
|
|
||||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (u->conf->ssl_session_reuse) {
|
if (u->conf->ssl_session_reuse) {
|
||||||
c->ssl->save_session = ngx_http_upstream_ssl_save_session;
|
c->ssl->save_session = ngx_http_upstream_ssl_save_session;
|
||||||
|
|
||||||
|
|
@ -5087,9 +5066,18 @@ ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
n = ngx_http_upstream_process_delta_seconds(p + offset, last);
|
n = 0;
|
||||||
|
|
||||||
|
for (p += offset; p < last; p++) {
|
||||||
|
if (*p == ',' || *p == ';' || *p == ' ') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p >= '0' && *p <= '9') {
|
||||||
|
n = n * 10 + (*p - '0');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (n == NGX_ERROR) {
|
|
||||||
u->cacheable = 0;
|
u->cacheable = 0;
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -5099,8 +5087,7 @@ ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
r->cache->valid_sec = ngx_min((ngx_uint_t) ngx_time() + n,
|
r->cache->valid_sec = ngx_time() + n;
|
||||||
NGX_MAX_INT_T_VALUE);
|
|
||||||
u->headers_in.expired = 0;
|
u->headers_in.expired = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5110,9 +5097,18 @@ extensions:
|
||||||
23 - 1);
|
23 - 1);
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
n = ngx_http_upstream_process_delta_seconds(p + 23, last);
|
n = 0;
|
||||||
|
|
||||||
|
for (p += 23; p < last; p++) {
|
||||||
|
if (*p == ',' || *p == ';' || *p == ' ') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p >= '0' && *p <= '9') {
|
||||||
|
n = n * 10 + (*p - '0');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (n == NGX_ERROR) {
|
|
||||||
u->cacheable = 0;
|
u->cacheable = 0;
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -5124,9 +5120,18 @@ extensions:
|
||||||
p = ngx_strlcasestrn(start, last, (u_char *) "stale-if-error=", 15 - 1);
|
p = ngx_strlcasestrn(start, last, (u_char *) "stale-if-error=", 15 - 1);
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
n = ngx_http_upstream_process_delta_seconds(p + 15, last);
|
n = 0;
|
||||||
|
|
||||||
|
for (p += 15; p < last; p++) {
|
||||||
|
if (*p == ',' || *p == ';' || *p == ' ') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p >= '0' && *p <= '9') {
|
||||||
|
n = n * 10 + (*p - '0');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (n == NGX_ERROR) {
|
|
||||||
u->cacheable = 0;
|
u->cacheable = 0;
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -5140,41 +5145,6 @@ extensions:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (NGX_HTTP_CACHE)
|
|
||||||
|
|
||||||
static ngx_int_t
|
|
||||||
ngx_http_upstream_process_delta_seconds(u_char *p, u_char *last)
|
|
||||||
{
|
|
||||||
ngx_int_t n, cutoff, cutlim;
|
|
||||||
|
|
||||||
cutoff = NGX_MAX_INT_T_VALUE / 10;
|
|
||||||
cutlim = NGX_MAX_INT_T_VALUE % 10;
|
|
||||||
|
|
||||||
n = 0;
|
|
||||||
|
|
||||||
for ( /* void */ ; p < last; p++) {
|
|
||||||
if (*p == ',' || *p == ';' || *p == ' ') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*p < '0' || *p > '9') {
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n >= cutoff && (n > cutoff || *p - '0' > cutlim)) {
|
|
||||||
n = NGX_MAX_INT_T_VALUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
n = n * 10 + (*p - '0');
|
|
||||||
}
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_upstream_process_expires(ngx_http_request_t *r, ngx_table_elt_t *h,
|
ngx_http_upstream_process_expires(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||||
ngx_uint_t offset)
|
ngx_uint_t offset)
|
||||||
|
|
@ -6915,7 +6885,6 @@ ngx_http_upstream_set_local(ngx_http_request_t *r, ngx_http_upstream_t *u,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val.len == 0) {
|
if (val.len == 0) {
|
||||||
u->peer.local = NULL;
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -6932,7 +6901,6 @@ ngx_http_upstream_set_local(ngx_http_request_t *r, ngx_http_upstream_t *u,
|
||||||
if (rc != NGX_OK) {
|
if (rc != NGX_OK) {
|
||||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||||
"invalid local address \"%V\"", &val);
|
"invalid local address \"%V\"", &val);
|
||||||
u->peer.local = NULL;
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -253,7 +253,7 @@ typedef struct {
|
||||||
|
|
||||||
ngx_str_t module;
|
ngx_str_t module;
|
||||||
|
|
||||||
NGX_COMPAT_BEGIN(6)
|
NGX_COMPAT_BEGIN(2)
|
||||||
NGX_COMPAT_END
|
NGX_COMPAT_END
|
||||||
} ngx_http_upstream_conf_t;
|
} ngx_http_upstream_conf_t;
|
||||||
|
|
||||||
|
|
@ -390,7 +390,6 @@ struct ngx_http_upstream_s {
|
||||||
|
|
||||||
#if (NGX_HTTP_SSL || NGX_COMPAT)
|
#if (NGX_HTTP_SSL || NGX_COMPAT)
|
||||||
ngx_str_t ssl_name;
|
ngx_str_t ssl_name;
|
||||||
ngx_str_t ssl_alpn_protocol;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ngx_http_cleanup_pt *cleanup;
|
ngx_http_cleanup_pt *cleanup;
|
||||||
|
|
|
||||||
|
|
@ -71,10 +71,6 @@ static ngx_int_t ngx_http_variable_scheme(ngx_http_request_t *r,
|
||||||
ngx_http_variable_value_t *v, uintptr_t data);
|
ngx_http_variable_value_t *v, uintptr_t data);
|
||||||
static ngx_int_t ngx_http_variable_https(ngx_http_request_t *r,
|
static ngx_int_t ngx_http_variable_https(ngx_http_request_t *r,
|
||||||
ngx_http_variable_value_t *v, uintptr_t data);
|
ngx_http_variable_value_t *v, uintptr_t data);
|
||||||
static ngx_int_t ngx_http_variable_request_port(ngx_http_request_t *r,
|
|
||||||
ngx_http_variable_value_t *v, uintptr_t data);
|
|
||||||
static ngx_int_t ngx_http_variable_is_request_port(ngx_http_request_t *r,
|
|
||||||
ngx_http_variable_value_t *v, uintptr_t data);
|
|
||||||
static void ngx_http_variable_set_args(ngx_http_request_t *r,
|
static void ngx_http_variable_set_args(ngx_http_request_t *r,
|
||||||
ngx_http_variable_value_t *v, uintptr_t data);
|
ngx_http_variable_value_t *v, uintptr_t data);
|
||||||
static ngx_int_t ngx_http_variable_is_args(ngx_http_request_t *r,
|
static ngx_int_t ngx_http_variable_is_args(ngx_http_request_t *r,
|
||||||
|
|
@ -235,12 +231,6 @@ static ngx_http_variable_t ngx_http_core_variables[] = {
|
||||||
|
|
||||||
{ ngx_string("https"), NULL, ngx_http_variable_https, 0, 0, 0 },
|
{ ngx_string("https"), NULL, ngx_http_variable_https, 0, 0, 0 },
|
||||||
|
|
||||||
{ ngx_string("request_port"), NULL,
|
|
||||||
ngx_http_variable_request_port, 0, 0, 0 },
|
|
||||||
|
|
||||||
{ ngx_string("is_request_port"), NULL,
|
|
||||||
ngx_http_variable_is_request_port, 0, 0, 0 },
|
|
||||||
|
|
||||||
{ ngx_string("request_uri"), NULL, ngx_http_variable_request,
|
{ ngx_string("request_uri"), NULL, ngx_http_variable_request,
|
||||||
offsetof(ngx_http_request_t, unparsed_uri), 0, 0 },
|
offsetof(ngx_http_request_t, unparsed_uri), 0, 0 },
|
||||||
|
|
||||||
|
|
@ -1550,51 +1540,6 @@ ngx_http_variable_https(ngx_http_request_t *r,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
|
||||||
ngx_http_variable_request_port(ngx_http_request_t *r,
|
|
||||||
ngx_http_variable_value_t *v, uintptr_t data)
|
|
||||||
{
|
|
||||||
ngx_uint_t port;
|
|
||||||
|
|
||||||
v->len = 0;
|
|
||||||
v->valid = 1;
|
|
||||||
v->no_cacheable = 0;
|
|
||||||
v->not_found = 0;
|
|
||||||
|
|
||||||
v->data = ngx_pnalloc(r->pool, sizeof("65535") - 1);
|
|
||||||
if (v->data == NULL) {
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
port = r->port;
|
|
||||||
|
|
||||||
if (port > 0 && port < 65536) {
|
|
||||||
v->len = ngx_sprintf(v->data, "%ui", port) - v->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
|
||||||
ngx_http_variable_is_request_port(ngx_http_request_t *r,
|
|
||||||
ngx_http_variable_value_t *v, uintptr_t data)
|
|
||||||
{
|
|
||||||
if (r->port == 0) {
|
|
||||||
*v = ngx_http_variable_null_value;
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
v->len = 1;
|
|
||||||
v->valid = 1;
|
|
||||||
v->no_cacheable = 0;
|
|
||||||
v->not_found = 0;
|
|
||||||
v->data = (u_char *) ":";
|
|
||||||
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ngx_http_variable_set_args(ngx_http_request_t *r,
|
ngx_http_variable_set_args(ngx_http_request_t *r,
|
||||||
ngx_http_variable_value_t *v, uintptr_t data)
|
ngx_http_variable_value_t *v, uintptr_t data)
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,6 @@ static ngx_int_t ngx_http_v2_construct_request_line(ngx_http_request_t *r);
|
||||||
static ngx_int_t ngx_http_v2_cookie(ngx_http_request_t *r,
|
static ngx_int_t ngx_http_v2_cookie(ngx_http_request_t *r,
|
||||||
ngx_http_v2_header_t *header);
|
ngx_http_v2_header_t *header);
|
||||||
static ngx_int_t ngx_http_v2_construct_cookie_header(ngx_http_request_t *r);
|
static ngx_int_t ngx_http_v2_construct_cookie_header(ngx_http_request_t *r);
|
||||||
static ngx_int_t ngx_http_v2_construct_host_header(ngx_http_request_t *r);
|
|
||||||
static void ngx_http_v2_run_request(ngx_http_request_t *r);
|
static void ngx_http_v2_run_request(ngx_http_request_t *r);
|
||||||
static ngx_int_t ngx_http_v2_process_request_body(ngx_http_request_t *r,
|
static ngx_int_t ngx_http_v2_process_request_body(ngx_http_request_t *r,
|
||||||
u_char *pos, size_t size, ngx_uint_t last, ngx_uint_t flush);
|
u_char *pos, size_t size, ngx_uint_t last, ngx_uint_t flush);
|
||||||
|
|
@ -3518,42 +3517,44 @@ ngx_http_v2_parse_scheme(ngx_http_request_t *r, ngx_str_t *value)
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_v2_parse_authority(ngx_http_request_t *r, ngx_str_t *value)
|
ngx_http_v2_parse_authority(ngx_http_request_t *r, ngx_str_t *value)
|
||||||
{
|
{
|
||||||
ngx_int_t rc;
|
ngx_table_elt_t *h;
|
||||||
in_port_t port;
|
ngx_http_header_t *hh;
|
||||||
|
ngx_http_core_main_conf_t *cmcf;
|
||||||
|
|
||||||
if (r->host_start) {
|
static ngx_str_t host = ngx_string("host");
|
||||||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
|
||||||
"client sent duplicate \":authority\" header");
|
h = ngx_list_push(&r->headers_in.headers);
|
||||||
return NGX_DECLINED;
|
if (h == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
r->host_start = value->data;
|
h->hash = ngx_hash(ngx_hash(ngx_hash('h', 'o'), 's'), 't');
|
||||||
r->host_end = value->data + value->len;
|
|
||||||
|
|
||||||
rc = ngx_http_validate_host(value, &port, r->pool, 0);
|
h->key.len = host.len;
|
||||||
|
h->key.data = host.data;
|
||||||
|
|
||||||
if (rc == NGX_DECLINED) {
|
h->value.len = value->len;
|
||||||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
h->value.data = value->data;
|
||||||
"client sent invalid \":authority\" header");
|
|
||||||
return NGX_DECLINED;
|
h->lowcase_key = host.data;
|
||||||
|
|
||||||
|
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
|
||||||
|
|
||||||
|
hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash,
|
||||||
|
h->lowcase_key, h->key.len);
|
||||||
|
|
||||||
|
if (hh == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc == NGX_ERROR) {
|
if (hh->handler(r, h, hh->offset) != NGX_OK) {
|
||||||
ngx_http_v2_close_stream(r->stream, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
|
||||||
return NGX_ABORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ngx_http_set_virtual_server(r, value) == NGX_ERROR) {
|
|
||||||
/*
|
/*
|
||||||
* request has been finalized already
|
* request has been finalized already
|
||||||
* in ngx_http_set_virtual_server()
|
* in ngx_http_process_host()
|
||||||
*/
|
*/
|
||||||
return NGX_ABORT;
|
return NGX_ABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
r->headers_in.server = *value;
|
|
||||||
r->port = port;
|
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3724,54 +3725,7 @@ ngx_http_v2_construct_cookie_header(ngx_http_request_t *r)
|
||||||
if (hh->handler(r, h, hh->offset) != NGX_OK) {
|
if (hh->handler(r, h, hh->offset) != NGX_OK) {
|
||||||
/*
|
/*
|
||||||
* request has been finalized already
|
* request has been finalized already
|
||||||
* in ngx_http_process_header_line()
|
* in ngx_http_process_multi_header_lines()
|
||||||
*/
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
|
||||||
ngx_http_v2_construct_host_header(ngx_http_request_t *r)
|
|
||||||
{
|
|
||||||
ngx_table_elt_t *h;
|
|
||||||
ngx_http_header_t *hh;
|
|
||||||
ngx_http_core_main_conf_t *cmcf;
|
|
||||||
|
|
||||||
static ngx_str_t host = ngx_string("host");
|
|
||||||
|
|
||||||
h = ngx_list_push(&r->headers_in.headers);
|
|
||||||
if (h == NULL) {
|
|
||||||
ngx_http_v2_close_stream(r->stream, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
h->hash = ngx_hash(ngx_hash(ngx_hash('h', 'o'), 's'), 't');
|
|
||||||
|
|
||||||
h->key.len = host.len;
|
|
||||||
h->key.data = host.data;
|
|
||||||
|
|
||||||
h->value.len = r->host_end - r->host_start;
|
|
||||||
h->value.data = r->host_start;
|
|
||||||
|
|
||||||
h->lowcase_key = host.data;
|
|
||||||
|
|
||||||
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
|
|
||||||
|
|
||||||
hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash,
|
|
||||||
h->lowcase_key, h->key.len);
|
|
||||||
|
|
||||||
if (hh == NULL) {
|
|
||||||
ngx_http_v2_close_stream(r->stream, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hh->handler(r, h, hh->offset) != NGX_OK) {
|
|
||||||
/*
|
|
||||||
* request has been finalized already
|
|
||||||
* in ngx_http_process_host()
|
|
||||||
*/
|
*/
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
@ -3783,7 +3737,6 @@ ngx_http_v2_construct_host_header(ngx_http_request_t *r)
|
||||||
static void
|
static void
|
||||||
ngx_http_v2_run_request(ngx_http_request_t *r)
|
ngx_http_v2_run_request(ngx_http_request_t *r)
|
||||||
{
|
{
|
||||||
ngx_str_t host;
|
|
||||||
ngx_connection_t *fc;
|
ngx_connection_t *fc;
|
||||||
ngx_http_v2_srv_conf_t *h2scf;
|
ngx_http_v2_srv_conf_t *h2scf;
|
||||||
ngx_http_v2_connection_t *h2c;
|
ngx_http_v2_connection_t *h2c;
|
||||||
|
|
@ -3811,54 +3764,12 @@ ngx_http_v2_run_request(ngx_http_request_t *r)
|
||||||
|
|
||||||
r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE;
|
r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE;
|
||||||
|
|
||||||
if (r->headers_in.server.len == 0) {
|
if (ngx_http_process_request_header(r) != NGX_OK) {
|
||||||
ngx_log_error(NGX_LOG_INFO, fc->log, 0,
|
|
||||||
"client sent neither \":authority\" nor \"Host\" header");
|
|
||||||
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r->host_end) {
|
|
||||||
|
|
||||||
host.len = r->host_end - r->host_start;
|
|
||||||
host.data = r->host_start;
|
|
||||||
|
|
||||||
if (r->headers_in.host) {
|
|
||||||
if (r->headers_in.host->value.len != host.len
|
|
||||||
|| ngx_memcmp(r->headers_in.host->value.data, host.data,
|
|
||||||
host.len)
|
|
||||||
!= 0)
|
|
||||||
{
|
|
||||||
ngx_log_error(NGX_LOG_INFO, fc->log, 0,
|
|
||||||
"client sent \":authority\" and \"Host\" headers "
|
|
||||||
"with different values");
|
|
||||||
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
/* compatibility for $http_host */
|
|
||||||
|
|
||||||
if (ngx_http_v2_construct_host_header(r) != NGX_OK) {
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r->headers_in.content_length) {
|
|
||||||
r->headers_in.content_length_n =
|
|
||||||
ngx_atoof(r->headers_in.content_length->value.data,
|
|
||||||
r->headers_in.content_length->value.len);
|
|
||||||
|
|
||||||
if (r->headers_in.content_length_n == NGX_ERROR) {
|
|
||||||
ngx_log_error(NGX_LOG_INFO, fc->log, 0,
|
|
||||||
"client sent invalid \"Content-Length\" header");
|
|
||||||
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
|
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r->headers_in.content_length_n > 0 && r->stream->in_closed) {
|
if (r->headers_in.content_length_n > 0 && r->stream->in_closed) {
|
||||||
ngx_log_error(NGX_LOG_INFO, fc->log, 0,
|
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||||
"client prematurely closed stream");
|
"client prematurely closed stream");
|
||||||
|
|
||||||
r->stream->skip_data = 1;
|
r->stream->skip_data = 1;
|
||||||
|
|
@ -3867,22 +3778,10 @@ ngx_http_v2_run_request(ngx_http_request_t *r)
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (!r->stream->in_closed) {
|
if (r->headers_in.content_length_n == -1 && !r->stream->in_closed) {
|
||||||
r->headers_in.chunked = 1;
|
r->headers_in.chunked = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r->method == NGX_HTTP_CONNECT) {
|
|
||||||
ngx_log_error(NGX_LOG_INFO, fc->log, 0, "client sent CONNECT method");
|
|
||||||
ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r->method == NGX_HTTP_TRACE) {
|
|
||||||
ngx_log_error(NGX_LOG_INFO, fc->log, 0, "client sent TRACE method");
|
|
||||||
ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2c = r->stream->connection;
|
h2c = r->stream->connection;
|
||||||
|
|
||||||
h2c->payload_bytes += r->request_length;
|
h2c->payload_bytes += r->request_length;
|
||||||
|
|
@ -4104,14 +4003,15 @@ ngx_http_v2_process_request_body(ngx_http_request_t *r, u_char *pos,
|
||||||
n = size;
|
n = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (n > 0) {
|
||||||
|
rb->buf->last = ngx_cpymem(rb->buf->last, pos, n);
|
||||||
|
}
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
|
||||||
"http2 request body recv %uz", n);
|
"http2 request body recv %uz", n);
|
||||||
|
|
||||||
if (n > 0) {
|
|
||||||
rb->buf->last = ngx_cpymem(rb->buf->last, pos, n);
|
|
||||||
pos += n;
|
pos += n;
|
||||||
size -= n;
|
size -= n;
|
||||||
}
|
|
||||||
|
|
||||||
if (size == 0 && last) {
|
if (size == 0 && last) {
|
||||||
rb->rest = 0;
|
rb->rest = 0;
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,7 @@ static ngx_int_t ngx_http_v2_early_hints_filter(ngx_http_request_t *r);
|
||||||
static ngx_int_t ngx_http_v2_init_stream(ngx_http_request_t *r);
|
static ngx_int_t ngx_http_v2_init_stream(ngx_http_request_t *r);
|
||||||
|
|
||||||
static ngx_http_v2_out_frame_t *ngx_http_v2_create_headers_frame(
|
static ngx_http_v2_out_frame_t *ngx_http_v2_create_headers_frame(
|
||||||
ngx_http_request_t *r, u_char *pos, u_char *end, ngx_uint_t fin,
|
ngx_http_request_t *r, u_char *pos, u_char *end, ngx_uint_t fin);
|
||||||
ngx_uint_t flush);
|
|
||||||
static ngx_http_v2_out_frame_t *ngx_http_v2_create_trailers_frame(
|
static ngx_http_v2_out_frame_t *ngx_http_v2_create_trailers_frame(
|
||||||
ngx_http_request_t *r);
|
ngx_http_request_t *r);
|
||||||
|
|
||||||
|
|
@ -610,7 +609,7 @@ ngx_http_v2_header_filter(ngx_http_request_t *r)
|
||||||
fin = r->header_only
|
fin = r->header_only
|
||||||
|| (r->headers_out.content_length_n == 0 && !r->expect_trailers);
|
|| (r->headers_out.content_length_n == 0 && !r->expect_trailers);
|
||||||
|
|
||||||
frame = ngx_http_v2_create_headers_frame(r, start, pos, fin, 0);
|
frame = ngx_http_v2_create_headers_frame(r, start, pos, fin);
|
||||||
if (frame == NULL) {
|
if (frame == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
@ -775,7 +774,7 @@ ngx_http_v2_early_hints_filter(ngx_http_request_t *r)
|
||||||
header[i].value.len, tmp);
|
header[i].value.len, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame = ngx_http_v2_create_headers_frame(r, start, pos, 0, 1);
|
frame = ngx_http_v2_create_headers_frame(r, start, pos, 0);
|
||||||
if (frame == NULL) {
|
if (frame == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
@ -826,7 +825,7 @@ ngx_http_v2_init_stream(ngx_http_request_t *r)
|
||||||
|
|
||||||
static ngx_http_v2_out_frame_t *
|
static ngx_http_v2_out_frame_t *
|
||||||
ngx_http_v2_create_headers_frame(ngx_http_request_t *r, u_char *pos,
|
ngx_http_v2_create_headers_frame(ngx_http_request_t *r, u_char *pos,
|
||||||
u_char *end, ngx_uint_t fin, ngx_uint_t flush)
|
u_char *end, ngx_uint_t fin)
|
||||||
{
|
{
|
||||||
u_char type, flags;
|
u_char type, flags;
|
||||||
size_t rest, frame_size;
|
size_t rest, frame_size;
|
||||||
|
|
@ -917,7 +916,6 @@ ngx_http_v2_create_headers_frame(ngx_http_request_t *r, u_char *pos,
|
||||||
}
|
}
|
||||||
|
|
||||||
b->last_buf = fin;
|
b->last_buf = fin;
|
||||||
b->flush = flush;
|
|
||||||
cl->next = NULL;
|
cl->next = NULL;
|
||||||
frame->last = cl;
|
frame->last = cl;
|
||||||
|
|
||||||
|
|
@ -1040,7 +1038,7 @@ ngx_http_v2_create_trailers_frame(ngx_http_request_t *r)
|
||||||
header[i].value.len, tmp);
|
header[i].value.len, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ngx_http_v2_create_headers_frame(r, start, pos, 1, 0);
|
return ngx_http_v2_create_headers_frame(r, start, pos, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -623,12 +623,6 @@ ngx_http_v3_parse_literal(ngx_connection_t *c, ngx_http_v3_parse_literal_t *st,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st->huffman) {
|
if (st->huffman) {
|
||||||
if (n > NGX_MAX_INT_T_VALUE / 8) {
|
|
||||||
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
|
||||||
"client sent too large field line");
|
|
||||||
return NGX_HTTP_V3_ERR_EXCESSIVE_LOAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
n = n * 8 / 5;
|
n = n * 8 / 5;
|
||||||
st->huffstate = 0;
|
st->huffstate = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -904,7 +904,6 @@ ngx_http_v3_init_pseudo_headers(ngx_http_request_t *r)
|
||||||
u_char *p;
|
u_char *p;
|
||||||
ngx_int_t rc;
|
ngx_int_t rc;
|
||||||
ngx_str_t host;
|
ngx_str_t host;
|
||||||
in_port_t port;
|
|
||||||
|
|
||||||
if (r->request_line.len) {
|
if (r->request_line.len) {
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
|
|
@ -962,11 +961,11 @@ ngx_http_v3_init_pseudo_headers(ngx_http_request_t *r)
|
||||||
host.len = r->host_end - r->host_start;
|
host.len = r->host_end - r->host_start;
|
||||||
host.data = r->host_start;
|
host.data = r->host_start;
|
||||||
|
|
||||||
rc = ngx_http_validate_host(&host, &port, r->pool, 0);
|
rc = ngx_http_validate_host(&host, r->pool, 0);
|
||||||
|
|
||||||
if (rc == NGX_DECLINED) {
|
if (rc == NGX_DECLINED) {
|
||||||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||||
"client sent invalid \":authority\" header");
|
"client sent invalid host in request line");
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -980,7 +979,6 @@ ngx_http_v3_init_pseudo_headers(ngx_http_request_t *r)
|
||||||
}
|
}
|
||||||
|
|
||||||
r->headers_in.server = host;
|
r->headers_in.server = host;
|
||||||
r->port = port;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
|
if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
|
||||||
|
|
@ -1005,7 +1003,6 @@ ngx_http_v3_process_request_header(ngx_http_request_t *r)
|
||||||
{
|
{
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
ngx_buf_t *b;
|
ngx_buf_t *b;
|
||||||
ngx_str_t host;
|
|
||||||
ngx_connection_t *c;
|
ngx_connection_t *c;
|
||||||
ngx_http_v3_session_t *h3c;
|
ngx_http_v3_session_t *h3c;
|
||||||
ngx_http_v3_srv_conf_t *h3scf;
|
ngx_http_v3_srv_conf_t *h3scf;
|
||||||
|
|
@ -1037,13 +1034,11 @@ ngx_http_v3_process_request_header(ngx_http_request_t *r)
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r->headers_in.host && r->host_end) {
|
if (r->headers_in.host) {
|
||||||
|
if (r->headers_in.host->value.len != r->headers_in.server.len
|
||||||
host.len = r->host_end - r->host_start;
|
|| ngx_memcmp(r->headers_in.host->value.data,
|
||||||
host.data = r->host_start;
|
r->headers_in.server.data,
|
||||||
|
r->headers_in.server.len)
|
||||||
if (r->headers_in.host->value.len != host.len
|
|
||||||
|| ngx_memcmp(r->headers_in.host->value.data, host.data, host.len)
|
|
||||||
!= 0)
|
!= 0)
|
||||||
{
|
{
|
||||||
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||||
|
|
@ -1218,7 +1213,7 @@ ngx_http_v3_construct_cookie_header(ngx_http_request_t *r)
|
||||||
if (hh->handler(r, h, hh->offset) != NGX_OK) {
|
if (hh->handler(r, h, hh->offset) != NGX_OK) {
|
||||||
/*
|
/*
|
||||||
* request has been finalized already
|
* request has been finalized already
|
||||||
* in ngx_http_process_header_line()
|
* in ngx_http_process_multi_header_lines()
|
||||||
*/
|
*/
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1321,10 +1321,7 @@ ngx_mail_auth_http_create_request(ngx_mail_session_t *s, ngx_pool_t *pool,
|
||||||
b->last = ngx_copy(b->last, passwd.data, passwd.len);
|
b->last = ngx_copy(b->last, passwd.data, passwd.len);
|
||||||
*b->last++ = CR; *b->last++ = LF;
|
*b->last++ = CR; *b->last++ = LF;
|
||||||
|
|
||||||
if ((s->auth_method == NGX_MAIL_AUTH_APOP
|
if (s->auth_method != NGX_MAIL_AUTH_PLAIN && s->salt.len) {
|
||||||
|| s->auth_method == NGX_MAIL_AUTH_CRAM_MD5)
|
|
||||||
&& s->salt.len)
|
|
||||||
{
|
|
||||||
b->last = ngx_cpymem(b->last, "Auth-Salt: ", sizeof("Auth-Salt: ") - 1);
|
b->last = ngx_cpymem(b->last, "Auth-Salt: ", sizeof("Auth-Salt: ") - 1);
|
||||||
b->last = ngx_copy(b->last, s->salt.data, s->salt.len);
|
b->last = ngx_copy(b->last, s->salt.data, s->salt.len);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -523,7 +523,7 @@ ngx_mail_starttls_only(ngx_mail_session_t *s, ngx_connection_t *c)
|
||||||
ngx_int_t
|
ngx_int_t
|
||||||
ngx_mail_auth_plain(ngx_mail_session_t *s, ngx_connection_t *c, ngx_uint_t n)
|
ngx_mail_auth_plain(ngx_mail_session_t *s, ngx_connection_t *c, ngx_uint_t n)
|
||||||
{
|
{
|
||||||
u_char *p, *pos, *last;
|
u_char *p, *last;
|
||||||
ngx_str_t *arg, plain;
|
ngx_str_t *arg, plain;
|
||||||
|
|
||||||
arg = s->args.elts;
|
arg = s->args.elts;
|
||||||
|
|
@ -555,7 +555,7 @@ ngx_mail_auth_plain(ngx_mail_session_t *s, ngx_connection_t *c, ngx_uint_t n)
|
||||||
return NGX_MAIL_PARSE_INVALID_COMMAND;
|
return NGX_MAIL_PARSE_INVALID_COMMAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = p;
|
s->login.data = p;
|
||||||
|
|
||||||
while (p < last && *p) { p++; }
|
while (p < last && *p) { p++; }
|
||||||
|
|
||||||
|
|
@ -565,8 +565,7 @@ ngx_mail_auth_plain(ngx_mail_session_t *s, ngx_connection_t *c, ngx_uint_t n)
|
||||||
return NGX_MAIL_PARSE_INVALID_COMMAND;
|
return NGX_MAIL_PARSE_INVALID_COMMAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->login.len = p++ - pos;
|
s->login.len = p++ - s->login.data;
|
||||||
s->login.data = pos;
|
|
||||||
|
|
||||||
s->passwd.len = last - p;
|
s->passwd.len = last - p;
|
||||||
s->passwd.data = p;
|
s->passwd.data = p;
|
||||||
|
|
@ -584,26 +583,24 @@ ngx_int_t
|
||||||
ngx_mail_auth_login_username(ngx_mail_session_t *s, ngx_connection_t *c,
|
ngx_mail_auth_login_username(ngx_mail_session_t *s, ngx_connection_t *c,
|
||||||
ngx_uint_t n)
|
ngx_uint_t n)
|
||||||
{
|
{
|
||||||
ngx_str_t *arg, login;
|
ngx_str_t *arg;
|
||||||
|
|
||||||
arg = s->args.elts;
|
arg = s->args.elts;
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
|
||||||
"mail auth login username: \"%V\"", &arg[n]);
|
"mail auth login username: \"%V\"", &arg[n]);
|
||||||
|
|
||||||
login.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[n].len));
|
s->login.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[n].len));
|
||||||
if (login.data == NULL) {
|
if (s->login.data == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_decode_base64(&login, &arg[n]) != NGX_OK) {
|
if (ngx_decode_base64(&s->login, &arg[n]) != NGX_OK) {
|
||||||
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||||
"client sent invalid base64 encoding in AUTH LOGIN command");
|
"client sent invalid base64 encoding in AUTH LOGIN command");
|
||||||
return NGX_MAIL_PARSE_INVALID_COMMAND;
|
return NGX_MAIL_PARSE_INVALID_COMMAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->login = login;
|
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
|
||||||
"mail auth login username: \"%V\"", &s->login);
|
"mail auth login username: \"%V\"", &s->login);
|
||||||
|
|
||||||
|
|
@ -614,7 +611,7 @@ ngx_mail_auth_login_username(ngx_mail_session_t *s, ngx_connection_t *c,
|
||||||
ngx_int_t
|
ngx_int_t
|
||||||
ngx_mail_auth_login_password(ngx_mail_session_t *s, ngx_connection_t *c)
|
ngx_mail_auth_login_password(ngx_mail_session_t *s, ngx_connection_t *c)
|
||||||
{
|
{
|
||||||
ngx_str_t *arg, passwd;
|
ngx_str_t *arg;
|
||||||
|
|
||||||
arg = s->args.elts;
|
arg = s->args.elts;
|
||||||
|
|
||||||
|
|
@ -623,19 +620,18 @@ ngx_mail_auth_login_password(ngx_mail_session_t *s, ngx_connection_t *c)
|
||||||
"mail auth login password: \"%V\"", &arg[0]);
|
"mail auth login password: \"%V\"", &arg[0]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
passwd.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[0].len));
|
s->passwd.data = ngx_pnalloc(c->pool,
|
||||||
if (passwd.data == NULL) {
|
ngx_base64_decoded_length(arg[0].len));
|
||||||
|
if (s->passwd.data == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_decode_base64(&passwd, &arg[0]) != NGX_OK) {
|
if (ngx_decode_base64(&s->passwd, &arg[0]) != NGX_OK) {
|
||||||
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||||
"client sent invalid base64 encoding in AUTH LOGIN command");
|
"client sent invalid base64 encoding in AUTH LOGIN command");
|
||||||
return NGX_MAIL_PARSE_INVALID_COMMAND;
|
return NGX_MAIL_PARSE_INVALID_COMMAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->passwd = passwd;
|
|
||||||
|
|
||||||
#if (NGX_DEBUG_MAIL_PASSWD)
|
#if (NGX_DEBUG_MAIL_PASSWD)
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
|
||||||
"mail auth login password: \"%V\"", &s->passwd);
|
"mail auth login password: \"%V\"", &s->passwd);
|
||||||
|
|
@ -678,26 +674,24 @@ ngx_int_t
|
||||||
ngx_mail_auth_cram_md5(ngx_mail_session_t *s, ngx_connection_t *c)
|
ngx_mail_auth_cram_md5(ngx_mail_session_t *s, ngx_connection_t *c)
|
||||||
{
|
{
|
||||||
u_char *p, *last;
|
u_char *p, *last;
|
||||||
ngx_str_t *arg, login;
|
ngx_str_t *arg;
|
||||||
|
|
||||||
arg = s->args.elts;
|
arg = s->args.elts;
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
|
||||||
"mail auth cram-md5: \"%V\"", &arg[0]);
|
"mail auth cram-md5: \"%V\"", &arg[0]);
|
||||||
|
|
||||||
login.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[0].len));
|
s->login.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[0].len));
|
||||||
if (login.data == NULL) {
|
if (s->login.data == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_decode_base64(&login, &arg[0]) != NGX_OK) {
|
if (ngx_decode_base64(&s->login, &arg[0]) != NGX_OK) {
|
||||||
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||||
"client sent invalid base64 encoding in AUTH CRAM-MD5 command");
|
"client sent invalid base64 encoding in AUTH CRAM-MD5 command");
|
||||||
return NGX_MAIL_PARSE_INVALID_COMMAND;
|
return NGX_MAIL_PARSE_INVALID_COMMAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->login = login;
|
|
||||||
|
|
||||||
p = s->login.data;
|
p = s->login.data;
|
||||||
last = p + s->login.len;
|
last = p + s->login.len;
|
||||||
|
|
||||||
|
|
@ -1006,11 +1000,13 @@ ngx_mail_log_error(ngx_log_t *log, u_char *buf, size_t len)
|
||||||
len -= p - buf;
|
len -= p - buf;
|
||||||
buf = p;
|
buf = p;
|
||||||
|
|
||||||
if (s->login.len) {
|
if (s->login.len == 0) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
p = ngx_snprintf(buf, len, ", login: \"%V\"", &s->login);
|
p = ngx_snprintf(buf, len, ", login: \"%V\"", &s->login);
|
||||||
len -= p - buf;
|
len -= p - buf;
|
||||||
buf = p;
|
buf = p;
|
||||||
}
|
|
||||||
|
|
||||||
if (s->proxy == NULL) {
|
if (s->proxy == NULL) {
|
||||||
return p;
|
return p;
|
||||||
|
|
|
||||||
|
|
@ -531,7 +531,6 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
|
||||||
ngx_int_t rc;
|
ngx_int_t rc;
|
||||||
ngx_str_t line, auth, encoded;
|
ngx_str_t line, auth, encoded;
|
||||||
ngx_buf_t *b;
|
ngx_buf_t *b;
|
||||||
uintptr_t n;
|
|
||||||
ngx_connection_t *c;
|
ngx_connection_t *c;
|
||||||
ngx_mail_session_t *s;
|
ngx_mail_session_t *s;
|
||||||
ngx_mail_proxy_conf_t *pcf;
|
ngx_mail_proxy_conf_t *pcf;
|
||||||
|
|
@ -628,10 +627,6 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
|
||||||
CRLF) - 1
|
CRLF) - 1
|
||||||
+ s->connection->addr_text.len + s->login.len + s->host.len;
|
+ s->connection->addr_text.len + s->login.len + s->host.len;
|
||||||
|
|
||||||
n = ngx_escape_uri(NULL, s->login.data, s->login.len,
|
|
||||||
NGX_ESCAPE_MAIL_XTEXT);
|
|
||||||
line.len += n * 2;
|
|
||||||
|
|
||||||
#if (NGX_HAVE_INET6)
|
#if (NGX_HAVE_INET6)
|
||||||
if (s->connection->sockaddr->sa_family == AF_INET6) {
|
if (s->connection->sockaddr->sa_family == AF_INET6) {
|
||||||
line.len += sizeof("IPV6:") - 1;
|
line.len += sizeof("IPV6:") - 1;
|
||||||
|
|
@ -659,14 +654,7 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
|
||||||
|
|
||||||
if (s->login.len && !pcf->smtp_auth) {
|
if (s->login.len && !pcf->smtp_auth) {
|
||||||
p = ngx_cpymem(p, " LOGIN=", sizeof(" LOGIN=") - 1);
|
p = ngx_cpymem(p, " LOGIN=", sizeof(" LOGIN=") - 1);
|
||||||
|
|
||||||
if (n == 0) {
|
|
||||||
p = ngx_copy(p, s->login.data, s->login.len);
|
p = ngx_copy(p, s->login.data, s->login.len);
|
||||||
|
|
||||||
} else {
|
|
||||||
p = (u_char *) ngx_escape_uri(p, s->login.data, s->login.len,
|
|
||||||
NGX_ESCAPE_MAIL_XTEXT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p = ngx_cpymem(p, " NAME=", sizeof(" NAME=") - 1);
|
p = ngx_cpymem(p, " NAME=", sizeof(" NAME=") - 1);
|
||||||
|
|
|
||||||
|
|
@ -782,9 +782,6 @@ ngx_mail_smtp_mail(ngx_mail_session_t *s, ngx_connection_t *c)
|
||||||
|
|
||||||
ngx_str_set(&s->out, smtp_ok);
|
ngx_str_set(&s->out, smtp_ok);
|
||||||
|
|
||||||
ngx_str_null(&s->login);
|
|
||||||
ngx_str_null(&s->passwd);
|
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -97,13 +97,6 @@ static ngx_command_t ngx_mail_ssl_commands[] = {
|
||||||
0,
|
0,
|
||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("ssl_certificate_compression"),
|
|
||||||
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
|
|
||||||
ngx_conf_set_flag_slot,
|
|
||||||
NGX_MAIL_SRV_CONF_OFFSET,
|
|
||||||
offsetof(ngx_mail_ssl_conf_t, certificate_compression),
|
|
||||||
NULL },
|
|
||||||
|
|
||||||
{ ngx_string("ssl_dhparam"),
|
{ ngx_string("ssl_dhparam"),
|
||||||
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
|
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
|
||||||
ngx_conf_set_str_slot,
|
ngx_conf_set_str_slot,
|
||||||
|
|
@ -321,7 +314,6 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf)
|
||||||
scf->passwords = NGX_CONF_UNSET_PTR;
|
scf->passwords = NGX_CONF_UNSET_PTR;
|
||||||
scf->conf_commands = NGX_CONF_UNSET_PTR;
|
scf->conf_commands = NGX_CONF_UNSET_PTR;
|
||||||
scf->prefer_server_ciphers = NGX_CONF_UNSET;
|
scf->prefer_server_ciphers = NGX_CONF_UNSET;
|
||||||
scf->certificate_compression = NGX_CONF_UNSET;
|
|
||||||
scf->verify = NGX_CONF_UNSET_UINT;
|
scf->verify = NGX_CONF_UNSET_UINT;
|
||||||
scf->verify_depth = NGX_CONF_UNSET_UINT;
|
scf->verify_depth = NGX_CONF_UNSET_UINT;
|
||||||
scf->builtin_session_cache = NGX_CONF_UNSET;
|
scf->builtin_session_cache = NGX_CONF_UNSET;
|
||||||
|
|
@ -351,9 +343,6 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
ngx_conf_merge_value(conf->prefer_server_ciphers,
|
ngx_conf_merge_value(conf->prefer_server_ciphers,
|
||||||
prev->prefer_server_ciphers, 0);
|
prev->prefer_server_ciphers, 0);
|
||||||
|
|
||||||
ngx_conf_merge_value(conf->certificate_compression,
|
|
||||||
prev->certificate_compression, 0);
|
|
||||||
|
|
||||||
ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
|
ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
|
||||||
(NGX_CONF_BITMASK_SET|NGX_SSL_DEFAULT_PROTOCOLS));
|
(NGX_CONF_BITMASK_SET|NGX_SSL_DEFAULT_PROTOCOLS));
|
||||||
|
|
||||||
|
|
@ -457,13 +446,6 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_ssl_certificate_compression(cf, &conf->ssl,
|
|
||||||
conf->certificate_compression)
|
|
||||||
!= NGX_OK)
|
|
||||||
{
|
|
||||||
return NGX_CONF_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conf->verify) {
|
if (conf->verify) {
|
||||||
|
|
||||||
if (conf->verify != 3
|
if (conf->verify != 3
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_flag_t prefer_server_ciphers;
|
ngx_flag_t prefer_server_ciphers;
|
||||||
ngx_flag_t certificate_compression;
|
|
||||||
|
|
||||||
ngx_ssl_t ssl;
|
ngx_ssl_t ssl;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -476,169 +476,68 @@ ngx_stream_validate_host(ngx_str_t *host, ngx_pool_t *pool, ngx_uint_t alloc)
|
||||||
{
|
{
|
||||||
u_char *h, ch;
|
u_char *h, ch;
|
||||||
size_t i, dot_pos, host_len;
|
size_t i, dot_pos, host_len;
|
||||||
ngx_int_t port;
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
sw_host_start = 0,
|
sw_usual = 0,
|
||||||
sw_host,
|
sw_literal,
|
||||||
sw_host_ip_literal,
|
sw_rest
|
||||||
sw_host_end,
|
|
||||||
sw_port,
|
|
||||||
} state;
|
} state;
|
||||||
|
|
||||||
dot_pos = host->len;
|
dot_pos = host->len;
|
||||||
host_len = host->len;
|
host_len = host->len;
|
||||||
port = 0;
|
|
||||||
|
|
||||||
h = host->data;
|
h = host->data;
|
||||||
|
|
||||||
state = sw_host_start;
|
state = sw_usual;
|
||||||
|
|
||||||
for (i = 0; i < host->len; i++) {
|
for (i = 0; i < host->len; i++) {
|
||||||
ch = h[i];
|
ch = h[i];
|
||||||
|
|
||||||
switch (state) {
|
|
||||||
|
|
||||||
case sw_host_start:
|
|
||||||
|
|
||||||
if (ch == '[') {
|
|
||||||
state = sw_host_ip_literal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
state = sw_host;
|
|
||||||
|
|
||||||
/* fall through */
|
|
||||||
|
|
||||||
case sw_host:
|
|
||||||
|
|
||||||
if (ch >= 'A' && ch <= 'Z') {
|
|
||||||
alloc = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ch >= 'a' && ch <= 'z') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ch >= '0' && ch <= '9') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
|
|
||||||
|
case '.':
|
||||||
|
if (dot_pos == i - 1) {
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
dot_pos = i;
|
||||||
|
break;
|
||||||
|
|
||||||
case ':':
|
case ':':
|
||||||
|
if (state == sw_usual) {
|
||||||
host_len = i;
|
host_len = i;
|
||||||
state = sw_port;
|
state = sw_rest;
|
||||||
break;
|
|
||||||
case '-':
|
|
||||||
break;
|
|
||||||
case '.':
|
|
||||||
if (dot_pos == i - 1) {
|
|
||||||
return NGX_DECLINED;
|
|
||||||
}
|
|
||||||
dot_pos = i;
|
|
||||||
break;
|
|
||||||
case '_':
|
|
||||||
case '~':
|
|
||||||
/* unreserved */
|
|
||||||
break;
|
|
||||||
case '!':
|
|
||||||
case '$':
|
|
||||||
case '&':
|
|
||||||
case '\'':
|
|
||||||
case '(':
|
|
||||||
case ')':
|
|
||||||
case '*':
|
|
||||||
case '+':
|
|
||||||
case ',':
|
|
||||||
case ';':
|
|
||||||
case '=':
|
|
||||||
/* sub-delims */
|
|
||||||
break;
|
|
||||||
case '%':
|
|
||||||
/* pct-encoded */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return NGX_DECLINED;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case sw_host_ip_literal:
|
case '[':
|
||||||
|
if (i == 0) {
|
||||||
|
state = sw_literal;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ']':
|
||||||
|
if (state == sw_literal) {
|
||||||
|
host_len = i + 1;
|
||||||
|
state = sw_rest;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
if (ngx_path_separator(ch)) {
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch <= 0x20 || ch == 0x7f) {
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
if (ch >= 'A' && ch <= 'Z') {
|
if (ch >= 'A' && ch <= 'Z') {
|
||||||
alloc = 1;
|
alloc = 1;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ch >= 'a' && ch <= 'z') {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ch >= '0' && ch <= '9') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (ch) {
|
|
||||||
case ':':
|
|
||||||
break;
|
|
||||||
case ']':
|
|
||||||
host_len = i + 1;
|
|
||||||
state = sw_host_end;
|
|
||||||
break;
|
|
||||||
case '-':
|
|
||||||
break;
|
|
||||||
case '.':
|
|
||||||
if (dot_pos == i - 1) {
|
|
||||||
return NGX_DECLINED;
|
|
||||||
}
|
|
||||||
dot_pos = i;
|
|
||||||
break;
|
|
||||||
case '_':
|
|
||||||
case '~':
|
|
||||||
/* unreserved */
|
|
||||||
break;
|
|
||||||
case '!':
|
|
||||||
case '$':
|
|
||||||
case '&':
|
|
||||||
case '\'':
|
|
||||||
case '(':
|
|
||||||
case ')':
|
|
||||||
case '*':
|
|
||||||
case '+':
|
|
||||||
case ',':
|
|
||||||
case ';':
|
|
||||||
case '=':
|
|
||||||
/* sub-delims */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return NGX_DECLINED;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case sw_host_end:
|
|
||||||
|
|
||||||
if (ch == ':') {
|
|
||||||
state = sw_port;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return NGX_DECLINED;
|
|
||||||
|
|
||||||
case sw_port:
|
|
||||||
|
|
||||||
if (ch >= '0' && ch <= '9') {
|
|
||||||
if (port >= 6553 && (port > 6553 || (ch - '0') > 5)) {
|
|
||||||
return NGX_DECLINED;
|
|
||||||
}
|
|
||||||
|
|
||||||
port = port * 10 + (ch - '0');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return NGX_DECLINED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state == sw_host_ip_literal) {
|
|
||||||
return NGX_DECLINED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dot_pos == host_len - 1) {
|
if (dot_pos == host_len - 1) {
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,6 @@ typedef struct {
|
||||||
unsigned outside_entries:1;
|
unsigned outside_entries:1;
|
||||||
unsigned allow_binary_include:1;
|
unsigned allow_binary_include:1;
|
||||||
unsigned binary_include:1;
|
unsigned binary_include:1;
|
||||||
unsigned no_cacheable:1;
|
|
||||||
} ngx_stream_geo_conf_ctx_t;
|
} ngx_stream_geo_conf_ctx_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -434,7 +433,6 @@ ngx_stream_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||||
+ sizeof(ngx_stream_variable_value_t)
|
+ sizeof(ngx_stream_variable_value_t)
|
||||||
+ 0x10000 * sizeof(ngx_stream_geo_range_t *);
|
+ 0x10000 * sizeof(ngx_stream_geo_range_t *);
|
||||||
ctx.allow_binary_include = 1;
|
ctx.allow_binary_include = 1;
|
||||||
ctx.no_cacheable = 0;
|
|
||||||
|
|
||||||
save = *cf;
|
save = *cf;
|
||||||
cf->pool = pool;
|
cf->pool = pool;
|
||||||
|
|
@ -450,10 +448,6 @@ ngx_stream_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.no_cacheable) {
|
|
||||||
var->flags |= NGX_STREAM_VAR_NOCACHEABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctx.ranges) {
|
if (ctx.ranges) {
|
||||||
|
|
||||||
if (ctx.high.low && !ctx.binary_include) {
|
if (ctx.high.low && !ctx.binary_include) {
|
||||||
|
|
@ -589,12 +583,6 @@ ngx_stream_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
|
||||||
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (ngx_strcmp(value[0].data, "volatile") == 0) {
|
|
||||||
ctx->no_cacheable = 1;
|
|
||||||
rv = NGX_CONF_OK;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cf->args->nelts != 2) {
|
if (cf->args->nelts != 2) {
|
||||||
|
|
|
||||||
|
|
@ -680,7 +680,6 @@ ngx_stream_proxy_set_local(ngx_stream_session_t *s, ngx_stream_upstream_t *u,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val.len == 0) {
|
if (val.len == 0) {
|
||||||
u->peer.local = NULL;
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -697,7 +696,6 @@ ngx_stream_proxy_set_local(ngx_stream_session_t *s, ngx_stream_upstream_t *u,
|
||||||
if (rc != NGX_OK) {
|
if (rc != NGX_OK) {
|
||||||
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
||||||
"invalid local address \"%V\"", &val);
|
"invalid local address \"%V\"", &val);
|
||||||
u->peer.local = NULL;
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -126,13 +126,6 @@ static ngx_command_t ngx_stream_ssl_commands[] = {
|
||||||
0,
|
0,
|
||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("ssl_ech_file"),
|
|
||||||
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
|
|
||||||
ngx_conf_set_str_array_slot,
|
|
||||||
NGX_STREAM_SRV_CONF_OFFSET,
|
|
||||||
offsetof(ngx_stream_ssl_srv_conf_t, ech_files),
|
|
||||||
NULL },
|
|
||||||
|
|
||||||
{ ngx_string("ssl_password_file"),
|
{ ngx_string("ssl_password_file"),
|
||||||
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
|
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
|
||||||
ngx_stream_ssl_password_file,
|
ngx_stream_ssl_password_file,
|
||||||
|
|
@ -140,13 +133,6 @@ static ngx_command_t ngx_stream_ssl_commands[] = {
|
||||||
0,
|
0,
|
||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("ssl_certificate_compression"),
|
|
||||||
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
|
|
||||||
ngx_conf_set_flag_slot,
|
|
||||||
NGX_STREAM_SRV_CONF_OFFSET,
|
|
||||||
offsetof(ngx_stream_ssl_srv_conf_t, certificate_compression),
|
|
||||||
NULL },
|
|
||||||
|
|
||||||
{ ngx_string("ssl_dhparam"),
|
{ ngx_string("ssl_dhparam"),
|
||||||
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
|
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
|
||||||
ngx_conf_set_str_slot,
|
ngx_conf_set_str_slot,
|
||||||
|
|
@ -246,7 +232,7 @@ static ngx_command_t ngx_stream_ssl_commands[] = {
|
||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("ssl_ocsp"),
|
{ ngx_string("ssl_ocsp"),
|
||||||
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
|
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
|
||||||
ngx_conf_set_enum_slot,
|
ngx_conf_set_enum_slot,
|
||||||
NGX_STREAM_SRV_CONF_OFFSET,
|
NGX_STREAM_SRV_CONF_OFFSET,
|
||||||
offsetof(ngx_stream_ssl_srv_conf_t, ocsp),
|
offsetof(ngx_stream_ssl_srv_conf_t, ocsp),
|
||||||
|
|
@ -364,9 +350,6 @@ static ngx_stream_variable_t ngx_stream_ssl_vars[] = {
|
||||||
{ ngx_string("ssl_curves"), NULL, ngx_stream_ssl_variable,
|
{ ngx_string("ssl_curves"), NULL, ngx_stream_ssl_variable,
|
||||||
(uintptr_t) ngx_ssl_get_curves, NGX_STREAM_VAR_CHANGEABLE, 0 },
|
(uintptr_t) ngx_ssl_get_curves, NGX_STREAM_VAR_CHANGEABLE, 0 },
|
||||||
|
|
||||||
{ ngx_string("ssl_sigalg"), NULL, ngx_stream_ssl_variable,
|
|
||||||
(uintptr_t) ngx_ssl_get_sigalg, NGX_STREAM_VAR_CHANGEABLE, 0 },
|
|
||||||
|
|
||||||
{ ngx_string("ssl_session_id"), NULL, ngx_stream_ssl_variable,
|
{ ngx_string("ssl_session_id"), NULL, ngx_stream_ssl_variable,
|
||||||
(uintptr_t) ngx_ssl_get_session_id, NGX_STREAM_VAR_CHANGEABLE, 0 },
|
(uintptr_t) ngx_ssl_get_session_id, NGX_STREAM_VAR_CHANGEABLE, 0 },
|
||||||
|
|
||||||
|
|
@ -379,13 +362,6 @@ static ngx_stream_variable_t ngx_stream_ssl_vars[] = {
|
||||||
{ ngx_string("ssl_alpn_protocol"), NULL, ngx_stream_ssl_variable,
|
{ ngx_string("ssl_alpn_protocol"), NULL, ngx_stream_ssl_variable,
|
||||||
(uintptr_t) ngx_ssl_get_alpn_protocol, NGX_STREAM_VAR_CHANGEABLE, 0 },
|
(uintptr_t) ngx_ssl_get_alpn_protocol, NGX_STREAM_VAR_CHANGEABLE, 0 },
|
||||||
|
|
||||||
{ ngx_string("ssl_ech_status"), NULL, ngx_stream_ssl_variable,
|
|
||||||
(uintptr_t) ngx_ssl_get_ech_status, NGX_STREAM_VAR_CHANGEABLE, 0 },
|
|
||||||
|
|
||||||
{ ngx_string("ssl_ech_outer_server_name"), NULL, ngx_stream_ssl_variable,
|
|
||||||
(uintptr_t) ngx_ssl_get_ech_outer_server_name,
|
|
||||||
NGX_STREAM_VAR_CHANGEABLE, 0 },
|
|
||||||
|
|
||||||
{ ngx_string("ssl_client_cert"), NULL, ngx_stream_ssl_variable,
|
{ ngx_string("ssl_client_cert"), NULL, ngx_stream_ssl_variable,
|
||||||
(uintptr_t) ngx_ssl_get_certificate, NGX_STREAM_VAR_CHANGEABLE, 0 },
|
(uintptr_t) ngx_ssl_get_certificate, NGX_STREAM_VAR_CHANGEABLE, 0 },
|
||||||
|
|
||||||
|
|
@ -421,9 +397,6 @@ static ngx_stream_variable_t ngx_stream_ssl_vars[] = {
|
||||||
{ ngx_string("ssl_client_v_remain"), NULL, ngx_stream_ssl_variable,
|
{ ngx_string("ssl_client_v_remain"), NULL, ngx_stream_ssl_variable,
|
||||||
(uintptr_t) ngx_ssl_get_client_v_remain, NGX_STREAM_VAR_CHANGEABLE, 0 },
|
(uintptr_t) ngx_ssl_get_client_v_remain, NGX_STREAM_VAR_CHANGEABLE, 0 },
|
||||||
|
|
||||||
{ ngx_string("ssl_client_sigalg"), NULL, ngx_stream_ssl_variable,
|
|
||||||
(uintptr_t) ngx_ssl_get_client_sigalg, NGX_STREAM_VAR_CHANGEABLE, 0 },
|
|
||||||
|
|
||||||
ngx_stream_null_variable
|
ngx_stream_null_variable
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -575,27 +548,8 @@ ngx_stream_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
||||||
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->ssl->sni_accepted) {
|
|
||||||
return SSL_TLSEXT_ERR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c->ssl->handshake_rejected) {
|
|
||||||
*ad = SSL_AD_UNRECOGNIZED_NAME;
|
|
||||||
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
s = c->data;
|
s = c->data;
|
||||||
|
|
||||||
if (arg) {
|
|
||||||
host = *(ngx_str_t *) arg;
|
|
||||||
|
|
||||||
if (host.data == NULL) {
|
|
||||||
ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
|
|
||||||
"SSL server name: null");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);
|
servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);
|
||||||
|
|
||||||
if (servername == NULL) {
|
if (servername == NULL) {
|
||||||
|
|
@ -604,17 +558,17 @@ ngx_stream_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
host.len = ngx_strlen(servername);
|
|
||||||
host.data = (u_char *) servername;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
|
||||||
"SSL server name: \"%V\"", &host);
|
"SSL server name: \"%s\"", servername);
|
||||||
|
|
||||||
|
host.len = ngx_strlen(servername);
|
||||||
|
|
||||||
if (host.len == 0) {
|
if (host.len == 0) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
host.data = (u_char *) servername;
|
||||||
|
|
||||||
rc = ngx_stream_validate_host(&host, c->pool, 1);
|
rc = ngx_stream_validate_host(&host, c->pool, 1);
|
||||||
|
|
||||||
if (rc == NGX_ERROR) {
|
if (rc == NGX_ERROR) {
|
||||||
|
|
@ -635,12 +589,35 @@ ngx_stream_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sscf = ngx_stream_get_module_srv_conf(cscf->ctx, ngx_stream_ssl_module);
|
||||||
|
|
||||||
|
#if (defined TLS1_3_VERSION \
|
||||||
|
&& !defined LIBRESSL_VERSION_NUMBER && !defined OPENSSL_IS_BORINGSSL)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SSL_SESSION_get0_hostname() is only available in OpenSSL 1.1.1+,
|
||||||
|
* but servername being negotiated in every TLSv1.3 handshake
|
||||||
|
* is only returned in OpenSSL 1.1.1+ as well
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (sscf->verify) {
|
||||||
|
const char *hostname;
|
||||||
|
|
||||||
|
hostname = SSL_SESSION_get0_hostname(SSL_get0_session(ssl_conn));
|
||||||
|
|
||||||
|
if (hostname != NULL && ngx_strcmp(hostname, servername) != 0) {
|
||||||
|
c->ssl->handshake_rejected = 1;
|
||||||
|
*ad = SSL_AD_ACCESS_DENIED;
|
||||||
|
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
s->srv_conf = cscf->ctx->srv_conf;
|
s->srv_conf = cscf->ctx->srv_conf;
|
||||||
|
|
||||||
ngx_set_connection_log(c, cscf->error_log);
|
ngx_set_connection_log(c, cscf->error_log);
|
||||||
|
|
||||||
sscf = ngx_stream_get_module_srv_conf(cscf->ctx, ngx_stream_ssl_module);
|
|
||||||
|
|
||||||
if (sscf->ssl.ctx) {
|
if (sscf->ssl.ctx) {
|
||||||
if (SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx) == NULL) {
|
if (SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx) == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
|
|
@ -679,7 +656,6 @@ done:
|
||||||
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
c->ssl->sni_accepted = 1;
|
|
||||||
return SSL_TLSEXT_ERR_OK;
|
return SSL_TLSEXT_ERR_OK;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
|
@ -902,11 +878,9 @@ ngx_stream_ssl_create_srv_conf(ngx_conf_t *cf)
|
||||||
sscf->certificates = NGX_CONF_UNSET_PTR;
|
sscf->certificates = NGX_CONF_UNSET_PTR;
|
||||||
sscf->certificate_keys = NGX_CONF_UNSET_PTR;
|
sscf->certificate_keys = NGX_CONF_UNSET_PTR;
|
||||||
sscf->certificate_cache = NGX_CONF_UNSET_PTR;
|
sscf->certificate_cache = NGX_CONF_UNSET_PTR;
|
||||||
sscf->ech_files = NGX_CONF_UNSET_PTR;
|
|
||||||
sscf->passwords = NGX_CONF_UNSET_PTR;
|
sscf->passwords = NGX_CONF_UNSET_PTR;
|
||||||
sscf->conf_commands = NGX_CONF_UNSET_PTR;
|
sscf->conf_commands = NGX_CONF_UNSET_PTR;
|
||||||
sscf->prefer_server_ciphers = NGX_CONF_UNSET;
|
sscf->prefer_server_ciphers = NGX_CONF_UNSET;
|
||||||
sscf->certificate_compression = NGX_CONF_UNSET;
|
|
||||||
sscf->reject_handshake = NGX_CONF_UNSET;
|
sscf->reject_handshake = NGX_CONF_UNSET;
|
||||||
sscf->verify = NGX_CONF_UNSET_UINT;
|
sscf->verify = NGX_CONF_UNSET_UINT;
|
||||||
sscf->verify_depth = NGX_CONF_UNSET_UINT;
|
sscf->verify_depth = NGX_CONF_UNSET_UINT;
|
||||||
|
|
@ -940,9 +914,6 @@ ngx_stream_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
ngx_conf_merge_value(conf->prefer_server_ciphers,
|
ngx_conf_merge_value(conf->prefer_server_ciphers,
|
||||||
prev->prefer_server_ciphers, 0);
|
prev->prefer_server_ciphers, 0);
|
||||||
|
|
||||||
ngx_conf_merge_value(conf->certificate_compression,
|
|
||||||
prev->certificate_compression, 0);
|
|
||||||
|
|
||||||
ngx_conf_merge_value(conf->reject_handshake, prev->reject_handshake, 0);
|
ngx_conf_merge_value(conf->reject_handshake, prev->reject_handshake, 0);
|
||||||
|
|
||||||
ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
|
ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
|
||||||
|
|
@ -958,8 +929,6 @@ ngx_stream_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
ngx_conf_merge_ptr_value(conf->certificate_cache, prev->certificate_cache,
|
ngx_conf_merge_ptr_value(conf->certificate_cache, prev->certificate_cache,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
ngx_conf_merge_ptr_value(conf->ech_files, prev->ech_files, NULL);
|
|
||||||
|
|
||||||
ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL);
|
ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL);
|
||||||
|
|
||||||
ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");
|
ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");
|
||||||
|
|
@ -1022,16 +991,8 @@ ngx_stream_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
cln->data = &conf->ssl;
|
cln->data = &conf->ssl;
|
||||||
|
|
||||||
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
|
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
|
||||||
{
|
|
||||||
static ngx_ssl_client_hello_arg cb = { ngx_stream_ssl_servername };
|
|
||||||
|
|
||||||
if (ngx_ssl_set_client_hello_callback(&conf->ssl, &cb) != NGX_OK) {
|
|
||||||
return NGX_CONF_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx,
|
SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx,
|
||||||
ngx_stream_ssl_servername);
|
ngx_stream_ssl_servername);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
|
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
|
||||||
|
|
@ -1078,13 +1039,6 @@ ngx_stream_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
{
|
{
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_ssl_certificate_compression(cf, &conf->ssl,
|
|
||||||
conf->certificate_compression)
|
|
||||||
!= NGX_OK)
|
|
||||||
{
|
|
||||||
return NGX_CONF_ERROR;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conf->verify) {
|
if (conf->verify) {
|
||||||
|
|
@ -1141,10 +1095,6 @@ ngx_stream_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_ssl_ech_files(cf, &conf->ssl, conf->ech_files) != NGX_OK) {
|
|
||||||
return NGX_CONF_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) {
|
if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) {
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
@ -1184,19 +1134,13 @@ ngx_stream_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
|
|
||||||
if (conf->stapling) {
|
if (conf->stapling) {
|
||||||
|
|
||||||
if (conf->certificate_compression) {
|
|
||||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
|
||||||
"\"ssl_stapling\" is incompatible with "
|
|
||||||
"\"ssl_certificate_compression\"");
|
|
||||||
return NGX_CONF_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ngx_ssl_stapling(cf, &conf->ssl, &conf->stapling_file,
|
if (ngx_ssl_stapling(cf, &conf->ssl, &conf->stapling_file,
|
||||||
&conf->stapling_responder, conf->stapling_verify)
|
&conf->stapling_responder, conf->stapling_verify)
|
||||||
!= NGX_OK)
|
!= NGX_OK)
|
||||||
{
|
{
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_ssl_conf_commands(cf, &conf->ssl, conf->conf_commands) != NGX_OK) {
|
if (ngx_ssl_conf_commands(cf, &conf->ssl, conf->conf_commands) != NGX_OK) {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ typedef struct {
|
||||||
ngx_msec_t handshake_timeout;
|
ngx_msec_t handshake_timeout;
|
||||||
|
|
||||||
ngx_flag_t prefer_server_ciphers;
|
ngx_flag_t prefer_server_ciphers;
|
||||||
ngx_flag_t certificate_compression;
|
|
||||||
ngx_flag_t reject_handshake;
|
ngx_flag_t reject_handshake;
|
||||||
|
|
||||||
ngx_ssl_t ssl;
|
ngx_ssl_t ssl;
|
||||||
|
|
@ -49,7 +48,6 @@ typedef struct {
|
||||||
|
|
||||||
ngx_str_t ciphers;
|
ngx_str_t ciphers;
|
||||||
|
|
||||||
ngx_array_t *ech_files;
|
|
||||||
ngx_array_t *passwords;
|
ngx_array_t *passwords;
|
||||||
ngx_array_t *conf_commands;
|
ngx_array_t *conf_commands;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue