Open philipwalton opened 4 months ago
Hello Philip Walton!
You encountered this issue because you need to:
fetch
method follows redirects correctly by setting the redirect
option to manual or handling it in a different way.fetch
options to prevent automatic following of redirects to handle them explicitly if needed.Let's go through the solution step by step. First, modify your code as follows:
worker.js should look like this (your code is ok):
export default {
async fetch(request) {
const url = new URL(request.url);
console.log('incoming request') // to see in console
if (url.pathname === '/needs-redirect') {
url.pathname = '/redirected';
return Response.redirect(url.href, 301);
}
return new Response('Hello!');
},
};
Next, update your index.js:
import { unstable_dev } from 'wrangler';
const worker = await unstable_dev('./worker.js', {
experimental: { disableExperimentalWarning: true },
});
const response = await worker.fetch('/needs-redirect', { redirect: 'manual' }) // prevent automatic following by option redirect: 'manual'
if (response.status === 301)
console.log('Redirected to:', response.headers.get('Location'));
else
console.log('Response status:', response.status);
Open two terminals in your project directory.
In the first terminal, run your worker locally on localhost with port 3000:
$ wrangler dev --host=localhost --port=3000 ./worker.js
In the second terminal, run your index.js with the following command:
node index.js
You should see the following outputs:
In the first terminal:
>wrangler dev --host=localhost --port=3000 ./worker.js
⛅️ wrangler 3.56.0
-------------------------------------------------------
⎔ Starting local server...
[wrangler:inf] Ready on http://127.0.0.1:3000
In the second terminal:
>node index.js
Redirected to: http://placeholder/redirected
Cheers, Adnan
You encountered this issue because you need to:
- Ensure the
fetch
method follows redirects correctly by setting theredirect
option to manual or handling it in a different way.- Use
fetch
options to prevent automatic following of redirects to handle them explicitly if needed.
Hi @rameardo, I appreciate the suggestion for how to work around this error via setting redirect: 'manual'
in the fetch options, but I believe there is still a bug here because Cloudflare workers can definitely follow redirects, and so the local testing environment should be able to as well.
Also, you didn't comment on the second issue I reported, starting with the text:
In addition to the error shown above when using
unstable_dev
, I'm also seeing errors for the same worker file when running wrangler dev locally with a local host specified:
Do you have any idea as to what's causing the redirect URL to contain multiple ports: http://localhost:8787:8787:3000/redirected
?
Hello Philip Walton!
You are right; usually, Cloudflare Workers follow redirects. However, in local testing, I believe there are two types of execution: the first one is remote as local, and the second one is fully local.
For example, this is fully local:
$ wrangler dev
And this is remote:
wrangler dev -r
-r
flag runs directly from Cloudflare infrastructure, as far as I know.Sorry, I forgot to answer this part:
In addition to the error shown above when using unstable_dev, I'm also seeing errors for the same worker file when running wrangler dev locally with a local host specified:
I think you are right; this is a bug. After investigating the issue, I think your command is incorrect (correct and not correct) let me explain why. (BUT GENERALY, YES THIS IS A BUG)
Example 1: If you are executing your worker like this:
wrangler dev --host=localhost:3000 ./index.js
Here, we have the following (why @CloudflareTeam?) localhost:8787:3000
And yes, you are right; this is a bug! Wrangler should split the host localhost:3000 and replace it with port 8787.
You don't need to specify the port in this manner. According to the Wrangler help page, the correct way is to use the --port
flag. For example:
wrangler dev --host=localhost --port 3000 ./index.js
Here, we have the following: localhost:3000
But the issue you mentioned still exists. The reason is a hostname mismatch. Your worker is hosted on 127.0.0.1, which is the same as localhost. However, it seems Wrangler does not treat localhost exactly like 127.0.0.1. (@CloudflareTeam ??)
To fix this issue, you need to serve directly from 127.0.0.1. Use the following command:
wrangler dev --host=127.0.0.1 --port=3000 ./index.js
This command should fix the issue!
curl -i http://localhost:3000/needs-redirect
Now, the output should be as you want:
HTTP/1.1 301 Moved Permanently
Content-Length: 0
Location: http://localhost:3000/redirected
But generally, you are right; this is indeed a bug. However, the above is the solution for your case if you need an immediate fix.
You don't need to specify the port in this manner. According to the Wrangler help page, the correct way is to use the
--port
flag. For example:wrangler dev --host=localhost --port 3000 ./index.js
Your example is actually different from mine, and I should clarify that in my real application code I'm setting both "host" and "port" to different port values. Here's what I have in my wrangler.toml
file:
host = "localhost:3001" # Origin server
port = 3000 # Port the worker should listen on
Notice how I have a different port set under "host" then I do under "port". The reason I'm doing this is because I have an application server running on port "3001", and I have my Cloudflare worker running on port "3000", which acts as a proxy for my application server.
According to the wrangler documentation, the "port" configuration should not be the port of the application server but rather the port of the worker, which is how I have it configured.
I assume running a local application server during development time is very common, so if there's a better way to configure my worker to support that use case, please let me know.
You are right; usually, Cloudflare Workers follow redirects. However, in local testing, I believe there are two types of execution: the first one is remote as local, and the second one is fully local.
By the way, in my case I actually need to test the 'follow redirects' behavior because I have a redirect chain scenario that I want to make sure redirects to completion.
Also, to emphasize something I said above, this behavior worked in wrangler version 2, so this is a regression in version 3.
Wrangler 2 defaulted to remote mode dev, while Wrangler 3 defaults to local mode dev. I think the --local-upstream
flag should preserve the behaviour you're expecting (wrangler dev --local-upstream=localhost:3000 ./worker.js
). Arguably --host
should do this too (tracked in https://github.com/cloudflare/workers-sdk/issues/5125).
https://github.com/cloudflare/workers-sdk/issues/5221 tracks the issue with redirect URLs containing too many ports.
Could you confirm whether --local-upstream
works for you?
Could you confirm whether
--local-upstream
works for you?
--local-upstream
does not work for me, i.e. it does not solve either of the issues I've raised here:
fetch()
via unstable_dev
, andunstable_dev
)The --local-upstream
option does allow me to run wranger dev
and use my local application server as an upstream, but --host
actually already did that, and since host is a supported config option that seems like a better option to use, correct?
Wrangler 2 defaulted to remote mode dev, while Wrangler 3 defaults to local mode dev.
I understand, but to clarify, wrangler 2 (when using the --local
flag) did not have either of the redirect issues I've raised here, so the issue it's just a change in defaults. The behavior has also changed.
Which Cloudflare product(s) does this pertain to?
Wrangler core
What version(s) of the tool(s) are you using?
3.56.0 [Wrangler]
What version of Node are you using?
v20.11.0
What operating system and version are you using?
macOS sonoma 14.4.1 (23E224)
Describe the Bug
Observed behavior
When calling
return Response.redirect(url.href, 301)
from within Worker code, I'm getting errors, both when using theunstable_dev
API as well as when usingwrangler dev
with a custom local host specified.Expected behavior
My redirect code fully worked with v2 of wrangler, but after upgrading to v3 I'm getting errors in both my tests and my local dev environment.
Steps to reproduce
node index.js
(if it doesn't happen automatically)Here is the contents of the worker file in the repro:
In addition to the error shown above when using
unstable_dev
, I'm also seeing errors for the same worker file when runningwrangler dev
locally with a local host specified:Then, if I use
curl
to test the redirect, I get an invalidLocation
header returned with the response. See the following screenshot:Notice how path was property updated by the redirect logic in the worker, but the URL in the
Location
header is invalid, as it now includes port 3000 appended to the existing port (which is also repeated for some reason). This also did not happen when using wrangler v2.Please provide a link to a minimal reproduction
https://stackblitz.com/edit/stackblitz-starters-vjsh9a?file=index.js
Please provide any relevant error logs
Error when using
unstable_dev
:Invalid response when running wrangler with host
localhost:3000
specified: