Skip to content

Commit

Permalink
fix: fetch missing body and search
Browse files Browse the repository at this point in the history
  • Loading branch information
Cnily03 committed Jul 31, 2024
1 parent 511f617 commit 3f5059b
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 12 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ bun install

Other package managers can be used as well.

To start a development server, run:

```bash
bun run dev
```

Or to deploy to Cloudflare Workers, run:

```bash
bun run deploy
```

### Configuration

Create file `.dev.vars` at the root of the project and add the following content:
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"deploy:dev": "wrangler deploy -c wrangler.deploy.toml --env development",
"dev": "wrangler dev",
"start": "wrangler dev",
"tail": "wrangler tail mirrors",
"cf-typegen": "wrangler types"
},
"devDependencies": {
Expand Down
24 changes: 13 additions & 11 deletions src/mw/proxy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createMiddleware } from "hono/factory";
import type { Env, BlankEnv, MiddlewareHandler } from "hono/types";
import type { Context } from "hono";
import { parseFunctional, pathStartsWith, isContentType } from "@/utils";
import { parseFunctional, pathStartsWith, replaceContentType } from "@/utils";

type ProxyRewrite<T extends Env> = (c: Context<T>, path: string, url: string) => string

Expand Down Expand Up @@ -37,15 +37,16 @@ export function changeOrigin<T extends Env = BlankEnv>(origin: string | ProxyRew
urlobj.host = inobj.host
urlobj.port = inobj.port
urlobj.pathname = newpath
urlobj.search = urlobj.search
const resp = await fetch(urlobj, {
method: c.req.method,
headers: c.req.raw.headers,
redirect: 'follow',
body: c.req.raw.body
})
const headers = new Headers(resp.headers)
if (opts.forbidHTML && isContentType(headers, 'text/html')) {
headers.delete('Content-Type')
headers.set('Content-Type', 'text/plain')
if (opts.forbidHTML) {
replaceContentType(headers, 'text/html', 'text/plain')
}
return new Response(resp.body, {
status: resp.status,
Expand All @@ -65,11 +66,11 @@ export function rewriteURL<T extends Env = BlankEnv>(rewrite: ProxyRewrite<T>, o
method: c.req.method,
headers: c.req.raw.headers,
redirect: 'follow',
body: c.req.raw.body
})
const headers = new Headers(resp.headers)
if (opts.forbidHTML && isContentType(headers, 'text/html')) {
headers.delete('Content-Type')
headers.set('Content-Type', 'text/plain')
if (opts.forbidHTML) {
replaceContentType(headers, 'text/html', 'text/plain')
}
return new Response(resp.body, {
status: resp.status,
Expand Down Expand Up @@ -115,7 +116,8 @@ export function forwardPath<T extends Env = BlankEnv>(options?: Partial<ProxyFor
return createMiddleware<T>(async (c, next) => {
opts.forbidHTML = parseFunctional(opts.forbidHTML)
// format url to standard
let next_url = opts.forwardUrl || c.req.path.substring(1)
let search = new URL(c.req.url, "http://localhost").search
let next_url = opts.forwardUrl || c.req.path.substring(1) + search
const thisUrlObj = new URL(c.req.url, "http://localhost")
let _t = _testURLProtocol(next_url)
if (_t === "invalid") return await next()
Expand All @@ -129,14 +131,14 @@ export function forwardPath<T extends Env = BlankEnv>(options?: Partial<ProxyFor
method: c.req.method,
headers: c.req.raw.headers,
redirect: opts.redirect,
body: c.req.raw.body
})

const headers = new Headers(resp.headers)

// convert `text/html` to `text/plain`
if (opts.forbidHTML && isContentType(headers, 'text/html')) {
headers.delete('Content-Type')
headers.set('Content-Type', 'text/plain')
if (opts.forbidHTML) {
replaceContentType(headers, 'text/html', 'text/plain')
}

// redirect to the same domain
Expand Down
3 changes: 3 additions & 0 deletions src/routes/docker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ app.get('/v2/', async c => {
method: c.req.method,
headers: c.req.raw.headers,
redirect: 'follow',
body: c.req.raw.body
})
if (resp.status === 401) {
const wwwAuth = resp.headers.get('WWW-Authenticate')
Expand Down Expand Up @@ -94,6 +95,7 @@ app.on('GET', ['/token', '/v2/auth'], async c => {
// method: c.req.method,
// headers: c.req.raw.headers,
// redirect: 'follow',
// body: c.req.raw.body
// })
// if (r.status !== 401) throw new HTTPException(500, { message: 'Unknown response' })
// const wwwAuth = r.headers.get('WWW-Authenticate')
Expand Down Expand Up @@ -128,6 +130,7 @@ app.on('GET', ['/token', '/v2/auth'], async c => {
method: c.req.method,
headers: c.req.raw.headers,
redirect: 'follow',
body: c.req.raw.body
})
})

Expand Down
3 changes: 2 additions & 1 deletion src/routes/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import Proxy, { _testURLProtocol } from "@/mw/proxy";
const app = new Hono<EnvHono>();

app.use(async (c, next) => {
let path_url = c.req.path.substring(1)
let search = new URL(c.req.url, "http://localhost").search
let path_url = c.req.path.substring(1) + search
let _t = _testURLProtocol(path_url)
if (_t === "invalid") return await next()
else if (_t === "miss_protocol") {
Expand Down
13 changes: 13 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,19 @@ export function isContentType(headers: Headers, t: string): boolean {
return contentTypes.some(ct => ct.split(";")[0].trim() === t)
}

export function replaceContentType(headers: Headers, _ori: string, _new: string): Headers {
if (!headers.has("Content-Type")) return headers
let contentTypes = headers.get("Content-Type")?.split(",") || []
let newContentTypes = contentTypes.map(ct => {
let [t, ...params] = ct.split(";")
if (t.trim() === _ori.trim()) return _new.trim() + ';' + params.join(";")
return ct
})
headers.delete("Content-Type")
headers.set("Content-Type", newContentTypes.join(","))
return headers
}

export const parseFunctional = <T>(v: T | (() => T)): T => typeof v === "function" ? (v as CallableFunction)() : v

export async function hmac_sha256(key: ArrayBuffer, data: ArrayBuffer) {
Expand Down

0 comments on commit 3f5059b

Please sign in to comment.