A bug on CF? —Having trouble with Cloudflare Workers showing secondary pages on a /subdirectory

I am able to show the contents of blog.some-site.com on mysite.com/blog by using the following script from workers’ examples:

/**
 * Example someHost at URL is set up to respond with HTML
 * Replace URL with the host you wish to send requests to
 */
const someHost = 'https://blog.some-site.com';
const url = someHost;

/**
 * gatherResponse awaits and returns a response body as a string.
 * Use await gatherResponse(..) in an async function to get the response body
 * @param {Response} response
 */
async function gatherResponse(response) {
  const { headers } = response;
  const contentType = headers.get('content-type') || '';
  if (contentType.includes('application/json')) {
    return JSON.stringify(await response.json());
  } else if (contentType.includes('application/text')) {
    return response.text();
  } else if (contentType.includes('text/html')) {
    return response.text();
  } else {
    return response.text();
  }
}

async function handleRequest() {
  const init = {
    headers: {
      'content-type': 'text/html;charset=UTF-8',
    },
  };
  const response = await fetch(url, init);
  const results = await gatherResponse(response);
  return new Response(results, init);
}

addEventListener('fetch', event => {
  return event.respondWith(handleRequest());
});

However, if I visit a secondary page mysite.com/blog/some-post it still shows the homepage of blog.some-site.com and not the actual post page I am requesting via the URL blog.some-site.com/some-post.

Also, assets (images, etc) are not showing up either.

For my routes I have:
mysite.com/blog*
mysite.com/assets*

Before posting this request for help, I have searched here on the CF community, SO, and overall on the web.

Others seem to be able to do this with ease. I am not sure what the missing piece is on mine. I’m starting to doubt CF is not able to handle it correctly.

This helps with getting assets to work Issue from subdomains to subdirectory

However, can’t still get secondary pages to show.

Unless you’ve changed it since, there is no bug - it’s doing exactly what you tell it to.

You’re always sending users to https://blog.some-site.com, regardless of the original URL.

export default {
  fetch(req) {
    const url = new URL(req.url);
    url.hostname = "blog.site.com";
    return fetch(url.toString(), req);
  }
}

Hi @KianNH

I have actually replaced the code with this one Issue from subdomains to subdirectory - #3 by user9096

Which works for assets.

But, subdirectories are still not showing.

Where in this new code I would tell it to fetch secondary pages as well?

Sorry, I am a total noob to this :frowning:

Hi @valsopi! Sorry you’re having trouble setting this up.

Generally, if you want Workers to act as a proxy for some other service, you need three things:

  • Deploy a Worker on a catch-all (*) rule where you want to run the thing.
  • Code which transforms an incoming request into a request for the original host.
  • [optional] Code which transforms a response from the original host, which re-writes all the links (e.g. img src, a href, etc.) to point to your proxy.

That last point can be the most thorny, but can be accomplished with HTMLRewriter. I saw some examples of that being shared on your Twitter thread, but lemme know if you need additional help with this piece.

The other two should hopefully be relatively simple. Deploy your Worker on example.com/blog*. And then, with code like this, you can formulate the URL you want to actually fetch:

https://cloudflareworkers.com/#13369b873ce239e28296822162562d03:https://example.com/blog/xyz

Here, we accept requests on https://example.com/blog/xyz and this gets transformed into https://bbc.com/xyz.

Finally, we just need to fetch it:

https://cloudflareworkers.com/#a158f8af336ac0a4a063d69ecf881bcf:https://example.com/blog/

Again, this page would need its URLs rewritten with HTMLRewriter.

Very quickly, that might look something like this: Cloudflare Workers

2 Likes

Thank you for this elegant solution @gbrimble. Works perfectly!

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.