How can I replace request headers?


#1

I have a question about Workers.
We uses an SaaS service of Oracle.
It has privately local host name and generates the contents dynamically. The contents include many hyper-links of local host name.
But we enabled Cloudflare for the site and published as valid FQDN.
Then I maked a Workers script that replace the host name.

addEventListener(‘fetch’, event => {
event.respondWith(fetchAndReplace(event.request))
})

async function fetchAndReplace(request) {
//Fetch from origin server.

let response = await fetch(request)

// Make sure we only modify text, not images.
let type = response.headers.get(“Content-Type”) || “”
if (!type.startsWith(“text/”)) {
return response
}

// Read response body.
let text = await response.text()

// Modify it.
let modified = text.replace(/a.com/g, “b.co.jp”)

let new_headers = new Headers(response.headers)
let response_code = response.status.toString()
if (response_code.startsWith(“30”) ) {
text = new_headers.get(“Location”).replace(/a.com/g, “b.co.jp”)
new_headers.set(“Location”, text)
}

// Return modified response.
return new Response(modified, {
status: response.status,
statusText: response.statusText,
headers: new_headers
})
}

I created it based on the following article.
https://community.cloudflare.com/t/a-little-coding-and-some-usage-questions/14051

But I am facing a problem.
Application uses some custom request headers and it includes FQDN.
So we need to replace it.
The script which is enabled now replaces the responce body, but does not replace the request headers.
Q1. How can I replace “a.com” in all request headers to the “b.co.jp”?
Q2. Currently script targets specific responce header. If it can target all headers, I think it is better.


#2

I was able to solve it by myself.

addEventListener(‘fetch’, event => {
event.respondWith(fetchAndReplace(event.request))
})

async function fetchAndReplace(request) {
let newRequestHeaders = new Headers(request.headers)
for (var pair of newRequestHeaders.entries()) {
if (pair[1].includes(“b.co.jp”)) {
newRequestHeaders.set(pair[0], pair[1].replace(/b.co.jp/g, “a.com”))
}
}

//Fetch from origin server.
let response = await fetch(request, {headers: newRequestHeaders})

// Make sure we only modify text, not images.
let type = response.headers.get(“Content-Type”) || “”
if (!type.startsWith(“text/”)) {
return response
}

// Read response body.
let text = await response.text()

// Modify it.
let modified = text.replace(/a.com/g, “b.co.jp”)
let newResponseHeaders = new Headers(response.headers)

for (var pair of newResponseHeaders.entries()) {
if (pair[1].includes(“a.com”)) {
newResponseHeaders.set(pair[0], pair[1].replace(/a.com/g, “b.co.jp”))
}
}

// Return modified response.
return new Response(modified, {
status: response.status,
statusText: response.statusText,
headers: newResponseHeaders
})
}


#3

Note that you can surround code with triple backticks (```) to format code better.

https://commonmark.org/help/