cloudflare / workerd

The JavaScript / Wasm runtime that powers Cloudflare Workers
https://blog.cloudflare.com/workerd-open-source-workers-runtime/
Apache License 2.0
6.24k stars 301 forks source link

🐛 Bug Report — Runtime APIs Pages env.ASSET.fetch rewrites html absolute paths to be relitive #1296

Open syonfox opened 1 year ago

syonfox commented 1 year ago

This is weird

Setup:

i have public/chatSAP.html

i have /functions/chat/deep/route

i call something like this

    //early out if not post method
    if(method === "GET") {
        //todo the _routes should do this i think;
        Request.url = req.url.replace("/"+path, "SAP.html" )
        //Here we are rewriting the url on get request
        return env.ASSETS.fetch(req )
    } else if(method !== "POST") {
        return errorResponse("Must POST JSON | GET PAGE")
    }

My page that renders properly and inspecting html I see my assets with absolute paths /js/script.js

gets replaced with ./js/script.js

this breaks my Pages app. I have tried forcing the new asset in a git push and also purge everything site cache

No luck THIS IS NOT A FEATURE ;)

Probably a weird one as its replacing"/some/path" at the beginning of an html path with "./some/path"

syonfox commented 1 year ago

Proof: image

after changing url to ...pages.dev/chat/some/path

image

Code that servers the catchall

/**
 * @type {PagesFunction}
 * @param  {EventContext} ctx
 * @return {Promise<Response>}
 */
export async function onRequest(ctx) {
    console.log("Hello from cloud flare request land")
    let req = ctx.request;
    let env = ctx.env
    let cf = ctx.cf;
    let url = req.url;
    let method = req.method;
    // url //"https://a43cbe91.echo-zen.pages.dev/dump/fubar",
    // "method": "GET",

    let root = '/chat';
    let folders = ctx.params.path;
    let path =folders.join("/");

    //early out if not post method
    if(method === "GET") {
        //todo the _routes should do this i think;
        Request.url = req.url.replace("/"+path, "SAP.html" )
        //Here we are rewriting the url on get request
        return env.ASSETS.fetch(req )
    } else if(method !== "POST") {
        return errorResponse("Must POST JSON | GET PAGE")
    }
}
syonfox commented 1 year ago

Heres the debug from the request

{
  "outcome": "ok",
  "scriptName": "pages-worker--1480713-production",
  "diagnosticsChannelEvents": [],
  "exceptions": [],
  "logs": [
    {
      "message": [
        "Hello from cloud flare request land"
      ],
      "level": "log",
      "timestamp": 1696969874577
    }
  ],
  "eventTimestamp": 1696969874565,
  "event": {
    "request": {
      "url": "https://25070c42.echo-zen.pages.dev/chat/SAP",
      "method": "GET",
      "headers": {
        "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
        "accept-encoding": "gzip, br",
        "accept-language": "en-US,en;q=0.5",

        "cf-ipcountry": "IN",
        "cf-ray": "8141a0340d9b8566",
        "cf-visitor": "{\"scheme\":\"https\"}",
        "connection": "Keep-Alive",
        "host": "25070c42.echo-zen.pages.dev",
        "priority": "u=1",
        "sec-fetch-dest": "document",
        "sec-fetch-mode": "navigate",
        "sec-fetch-site": "none",
        "sec-fetch-user": "?1",
        "upgrade-insecure-requests": "1",
        "user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0",
        "x-forwarded-proto": "https",

      },
      "cf": {
        "longitude": "73.82040",
        "httpProtocol": "HTTP/3",
        "tlsCipher": "AEAD-AES128-GCM-SHA256",
        "continent": "AS",
        "asn": 134053,
        "clientAcceptEncoding": "gzip, deflate, br",
        "country": "IN",
        "tlsClientAuth": {
          "certIssuerDNLegacy": "",
          "certIssuerSKI": "",
          "certSubjectDNRFC2253": "",
          "certSubjectDNLegacy": "",
          "certFingerprintSHA256": "",
          "certNotBefore": "",
          "certSKI": "",
          "certSerial": "",
          "certIssuerDN": "",
          "certVerified": "NONE",
          "certNotAfter": "",
          "certSubjectDN": "",
          "certPresented": "0",
          "certRevoked": "0",
          "certIssuerSerial": "",
          "certIssuerDNRFC2253": "",
          "certFingerprintSHA1": ""
        },
        "requestPriority": "",
        "tlsExportedAuthenticator": {
          "clientFinished": "ad1de08aa8e2c28443e8ee3fd079657ca219f828f7362f1f39aad422c0000880",
          "clientHandshake": "7215b0d2f1b6f90b91aad687414d477fe3b30815f770390d45280297f520e4fb",
          "serverHandshake": "93a63c07315885fbc47d59377bee5186cabd9ccc87399329291393e71d256fd6",
          "serverFinished": "4f918f530e17e5fb97266a9f07db30e7336ed2578d239eeef6871f3d9e6cc611"
        },
        "tlsVersion": "TLSv1.3",
        "city": "Mormugao",
        "timezone": "Asia/Kolkata",
        "verifiedBotCategory": "",
        "edgeRequestKeepAliveStatus": 1,
        "pagesHostName": "25070c42.echo-zen.pages.dev",
        "botManagement": {
          "corporateProxy": false,
          "verifiedBot": false,
          "jsDetection": {
            "passed": false
          },
          "staticResource": false,
          "detectionIds": {},
          "score": 99
        }
      }
    },
    "response": {
      "status": 200
    }
  },
  "id": 2
}
syonfox commented 1 year ago

Bug is in forwarding the request object passed in to the asset handeler.

Really we need to make a new Request Object

        let testURL = req.url.replace("/" + path, "SAP?path=")
        return env.ASSETS.fetch(new Request(testURL))