Last active
February 21, 2021 15:41
-
-
Save rfletcher/f5dd422991e6cac65c0135f9dec614f8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* A CloudFlare Worker which proxies an RSS feed, ensuring all <link/> values are secure URLs. | |
* | |
* Note: Works for my use case, but this needs more error checking before using widely. | |
* | |
* Usage: https://<yourworker>.workers.dev/https://example.com/feed.rss | |
*/ | |
addEventListener("fetch", event => { | |
event.respondWith(handleRequest(event.request)) | |
}) | |
class ElementHandler { | |
constructor() { | |
this.textBuffer = ""; | |
this.isLink = false; | |
} | |
element(element) { | |
this.isLink = element.tagName.toLowerCase() == "link"; | |
} | |
comments(comment) {} | |
text(text) { | |
if (this.isLink) { | |
this.textBuffer += text.text; | |
if (!text.lastInTextNode) { | |
text.remove(); | |
} else { | |
let url = new URL(this.textBuffer); | |
url.protocol = 'https:'; | |
text.replace(url.toString()); | |
this.textBuffer = ""; | |
} | |
} | |
} | |
} | |
// really only need to match "link" here, but the `text()` method is only called with "*". | |
const rewriter = new HTMLRewriter().on("*", new ElementHandler()); | |
async function handleRequest(request) { | |
// using a query param for input would be simpler, but my | |
// feed reader didn't like it. resort to path instead. | |
const { pathname } = new URL(request.url); | |
// strip the leading '/' | |
let url = pathname.substr(1); | |
// URL-decode if necessary | |
if (url.match(/%[a-f0-9]{2}/i)) { | |
url = decodeURIComponent(url); | |
} | |
// restore '//', which was collapsed to '/' | |
url = url.replace(/^(https?:)\/([^/])/i, "$1//$2"); | |
const response = await fetch(url); | |
return rewriter.transform(response); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment