This PR adds the `X-Powered-By` and `Content-Type` headers to responses sent by the web server. The latter enables compression for the Edge runtime. Still, the web server doesn't have `Content-Length` and `ETag` as the response is usually dynamic.
Part of #31506.
## Bug
- [x] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
## Feature
- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
## Documentation / Examples
- [ ] Make sure the linting passes by running `yarn lint`
## Bug
Fixes#34527
- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [x] Errors have helpful link attached, see `contributing.md`
This PR brings back @Schniz awesome contribution to bring in bodies to middleware. It was reverted to leave it out of the stable release and to have some time to test it out in canary before officially releasing it. This PR is simply a `cherry-pick` of his original work.
Closes: #30953
Closes: https://github.com/vercel/next.js/pull/34490
Co-authored-by: Gal Schlezinger <2054772+Schniz@users.noreply.github.com>
This PR removes the experimental `optimizeImages` flag. This feature was designed to automatically add preload tags for images, but I was never able to get it to do a very good job of selecting the images that actually need preloading.
This feature never graduated from experimental and in fact we never even publicized it as an experimental feature for people to try.
Additionally, even if someone was using this feature, it wouldn't have a functional effect, only a performance effect (removal of some preloads).
For those reasons, I believe it is safe to remove this functionality and that it is not a breaking change.
Related to #34185, this PR reduces the size of chunk that contains web-server.ts from 1.14mb to 210.8kb, by splitting base-http and api-utils into different environments.
Only affected thing is we can't have SSG preview mode for the web runtime via `getStaticProps`.
## Bug
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
## Feature
- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
## Documentation / Examples
- [ ] Make sure the linting passes by running `yarn lint`
This allows to have a more streamlined API for rewrites.
Since middlewares are code and not static configurations, we can allow people to
delete query params and not just overwrite them.
**⚠️ Warning ⚠️** this is a breaking change in query parameter behavior with middlewares, but the API will make more sense now. Compare the following:
```diff
import {NextResponse} from 'next/server'
export default function middleware({ nextUrl }) {
- nextUrl.searchParams.set('ignored-query-param', '');
+ nextUrl.searchParams.delete('ignored-query-param'); // 🎉
return NextResponse.rewrite(nextUrl);
}
```
Since this is breaking change, we're adding a warning every time we find a query param that is missing, and eventually--the warning will be deleted.
I don't think we need to worry about older versions of Next.js as the current behavior is misleading: merging query parameters make sense for static rewrites, but not for middlewares where you have access to all the query parameters and can manipulate them freely.
Related:
* This is the opposite of #33454
* This supersedes #33574
(#31506 for context)
This PR implements the minimum viable web server on top of the Next.js base server, and integrates it into our middleware (edge) SSR runtime to handle all the requests.
This also addresses problems like missing dynamic routes support in our current handler.
Note that this is the initial implementation with the assumption that the web server is running under minimal mode. Also later we can refactor the `__server_context` environment to properly passing the context via the constructor or methods.
Subtask of #31506
* move `serverBuildDir` and getter function of `publicDir` to next-server as only used place
* simplify `getMiddlewareInfo`, remove `distDir` and other params could be accessed from web server itself
Related to #31506, this PR adds `getPrerenderManifest` and `getRoutesManifest` methods to provide manifest files to the base server. In the future, we can consider making these methods async, or provide necessary manifests from the very top.
## Bug
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
## Feature
- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
## Documentation / Examples
- [ ] Make sure the linting passes by running `yarn lint`
Part of #31506, this PR removes `loadEnvConfig` and `chalk` from the base server while keeping the same behavior for the node server.
## Bug
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
## Feature
- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
## Documentation / Examples
- [ ] Make sure the linting passes by running `yarn lint`
Part of #31506, this PR moves the code of middleware handling from the base server to the node server.
## Bug
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
## Feature
- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
## Documentation / Examples
- [ ] Make sure the linting passes by running `yarn lint`
Adds base http classes, along with Node + Web (partial) implementations
Removes usage of IncomingMessage and ServerResponse from base server
Co-authored-by: Shu Ding <3676859+shuding@users.noreply.github.com>
This PR moves `require` and `fs` usage from the base server to the node server. Closes#32322.
## Bug
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
## Feature
- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
## Documentation / Examples
- [ ] Make sure the linting passes by running `yarn lint`
Same as #32105 (closed due to conflicts):
> Explained in #32066, rename next-server as base-server and extend NextNodeServer on top of it.
>
> Note that this is just an initial PR so no method is ported.
## Bug
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
## Feature
- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
## Documentation / Examples
- [ ] Make sure the linting passes by running `yarn lint`
This reverts the type for the `conf` field in `ServerOptions` isn't changed to require all `NextConfig` values as this is a breaking change from what was previously required. We should investigate making sure this field is normalized when it is provided via a user.
## Bug
- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
Fixes: https://github.com/vercel/next.js/issues/32123
x-ref: https://github.com/vercel/next.js/pull/31858
This ensures we catch any errors in `handleRequest` so that we can respond with a 400 for invalid requests.
## Bug
- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
Fixes: https://github.com/vercel/next.js/issues/32075
Closes: https://github.com/vercel/next.js/pull/32080
This PR fixes#30398
By default Next will polyfill some fetch APIs (Request, Response, Header and fetch) only if fetch is not found in the global scope in certain entry points. If we have a custom server which is adding a global fetch (and only fetch) at the very top then the rest of APIs will not be polyfilled.
This PR adds a test on the custom server where we can add a custom polyfill for fetch with an env variable. This reproduces the issue since next-server.js will be required without having a polyfill for Response which makes it fail on requiring NextResponse. Then we remove the code that checks for subrequests to happen within the **sandbox** so that we don't need to polyfill `next-server` anymore.
The we also introduce an improvement on how we handle relative requests. Since #31858 introduced a `port` and `hostname` options for the server, we can always pass absolute URLs to the Middleware so we can always use the original `nextUrl` to pass it to fetch. This brings a lot of simplification for `NextURL` since we don't have to consider relative URLs no more.
## Bug
- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [x] Errors have helpful link attached, see `contributing.md`
Since #31939 is going to move the `Document` components, we can't rely on `DefinePlugin` to provide environment variables. This PR passes them as render opts instead. We can't just force this to be bundled like e.g. `next/dynamic`, because we use it internally.
A middleware can work as a proxy intercepting requests and then performing a `fetch` to the destination adding headers to the request / response as a "man in the middle". When using `fetch` from a middleware we are not in the context of a browser so we can't really use relative URLs, they must be always absolute.
Now consider the previous case when middleware is running in *server mode*. Typically in order to know the host where we are fetching we can use the `request.nextUrl` which is given to the middleware but in this case the invoker (which is next-server) has no context of the hostname, nor the port. To solve this use case we must make the invoker of the middleware aware of the origin hostname and port.
This PR:
- Introduces `hostname` and `port` as options for `NextServer`.
- Refactors types in `NextServer` and `NextDevServer` moving type only imports to the top of the file.
- Refactors `startServer` to do a best guess on the `hostname` and `port`, passing them down.
- Exposes `.port` and `.hostname` to be retrieved from the `app`.
In an upcoming PR we will pass the host guess to the middleware to solve the relative URL issue.
To run middleware we are using a **sandbox** that emulates the web runtime and keeps a module cache. This cache is shared for all of the modules that we run using the sandbox while there are some module-level APIs that must be scoped depending on the module we are running.
One example of this is `fetch` where we want to always inject a special header that indicate the module that is performing the fetch and use it to avoid getting into infinite loops for middleware. For those cases the cached implementation will be the first one that instantiates the module and therefore we can actually get into infinite loops. This is the reason why #31800 is failing.
With this PR we refactor the sandbox so that the module cache is scoped per module name. This means that one execution of a middleware will preserve its cache only for that module so that each execution will still have its own `fetch` implementation, fixing this issue. Also, with this refactor the code is more clear and we also provide an option to avoid using the cache.
## Bug
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
## Feature
- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
## Documentation / Examples
- [ ] Make sure the linting passes by running `yarn lint`
The order in which middleware must be invoked conditions its behaviour. Currently, this is not being taken into consideration for server since we are generating the array of middleware based on an arbitrary order of the middleware existing in the filesystem. This PR ships a change to generate the array of middleware preserving the order defined in the manifest.
## Bug
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
## Feature
- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
## Documentation / Examples
- [ ] Make sure the linting passes by running `yarn lint`
This fixes our `basePath` detection/replacing server-side as we were incorrectly considering `/docss` a match for a `basePath` of `/docs` which caused us to have an unexpected value in the `normalizeLocalePath` function.
- Fixes#22429
- Regression introduced in #17757
- Fixes: https://github.com/vercel/next.js/issues/31423
Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com>
This changes the check for whether a rewrite is internal or if it should be proxied. Currently it checks if `protocol` is unset, which is only the case for relative URLs or localhost. This means that requests where there is a hostname set, or if localhost is specified in another way such as `127.0.0.1`, then it will be proxied, which potentially causes a proxy loop or ssl error. This PR changes the test so that it also checks if the hosts match, and only proxies if they are different.
Fixes#31179
## Bug
- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
* fix(30724): clear "x-middleware-next" header when chaining middlewares
* refactor: do not accumulate "x-middleware-next" header
* test: fix grammar of test case title
* Update packages/next/server/next-server.ts
Co-authored-by: Javi Velasco <javier.velasco86@gmail.com>
This ensures the `asPath` and `req.url` values are normalized correctly for fallback pages with i18n in minimal mode. This also copies the minimal mode test suite to run against i18n as well. This also fixes an issue where rewrite params weren't passed correctly on the client when no params were already used in the destination.
The provided reproduction has been deployed against this patch [here](https://nextjs-error-repro-9zdu3sp5r-ijjk-testing.vercel.app/page/test-page) show it working.
## Bug
- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [x] Errors have helpful link attached, see `contributing.md`
Fixes: https://github.com/vercel/next.js/issues/27563
Fixes: https://github.com/vercel/next.js/issues/30203
Fixes#30897
This PR fixes the linked issue where rewrites are not being applied for locale. It adds the corresponding test but also, as it was added in debugging process, it introduces a helper to read/write into the `request` object.
We are currently writing directly into the request by casting to `any` and then using flags like `_nextRewrote`. Instead, this PR puts all of this metadata under a symbol so it is not directly accessible. This also allows to have a single place where all of this metadata is listed so we can add comments describing the purpose of each flag.
In the same way, there is metadata written in the querystring. This is adding some types for it in order to throw some visibility on where is this metadata accessed. In an upcoming PR we can move all of it to the `request` object if possible to simplify the system.
## Bug
- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [x] Errors have helpful link attached, see `contributing.md`
This ensures we handle decode failures in minimal mode as a 400 response (bad request) instead of a 500 (server error).
## Bug
- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
Co-authored-by: Tobias Koppers <sokra@users.noreply.github.com>
With this PR we are updating the way we check the usage of `eval` and other dynamic code evaluation (like `new Function`) for middleware. Now instead of simply showing a warning it will behave differently depending on if we are building or in development.
- Development: we replace the dynamic code with a wrapper so that we print a warning only when the code is used. We don't fail in this scenario as it is possible that once the application is built the code that uses `eval` is left out.
- Build: we detect with tree shaking if the code that will be bundled into the middleware includes any dynamic code and in such scenario we make the build fail as don't want to allow it for the production environment.
Closes#30674
## Bug
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
## Feature
- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
## Documentation / Examples
- [ ] Make sure the linting passes by running `yarn lint`
## Bug
- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
Fixes#30430
There's some more discussion in the issue, but in summary:
- web `Headers` implementation combines all header values with `', '`
- For `Set-Cookie` headers, you're supposed to set them as separate values, not combine them
- web `Headers` forbids the use of `Cookie`, `Set-Cookie` and some more headers, so they don't have custom implementation for those, and still joins them with `,`
- We currently just split them using `split(',')`, but this breaks when the header contains a date (expires, max-age) that also includes a `,`
I used this method to split the Set-Cookie header properly: https://www.npmjs.com/package/set-cookie-parser#splitcookiestringcombinedsetcookieheader as suggested [here](https://github.com/whatwg/fetch/issues/973#issuecomment-559678813)
I didn't add it as a dependency, since we only needed that one method and I wasn't sure what the process is for adding dependencies, so I just added the method in the middleware utils