Compare commits

...

4 Commits

Author SHA1 Message Date
cirospaciari
f6fee9f20a fix download + dir for proxy 2023-04-11 11:40:46 -03:00
cirospaciari
6897b5e16d experiment with export + proxy 2023-04-11 09:54:44 -03:00
cirospaciari
c3088df49f ignore when no http proxy server available on afterAll 2023-04-10 22:06:59 -03:00
cirospaciari
9029b03ab5 add http_proxy connect support on tests and fix fetch proxy behavior 2023-04-10 21:57:28 -03:00
7 changed files with 183 additions and 142 deletions

View File

@@ -182,6 +182,11 @@ jobs:
cd bun-${{matrix.tag}}
chmod +x bun
sudo mv bun /usr/local/bin/bun
mkdir -p ~/proxy/
curl -L -o ~/proxy/http_proxy https://github.com/cirospaciari/http-proxy/raw/main/bin/linux/http_proxy
chmod +x ~/proxy/http_proxy
echo -e "\nexport PATH=$PATH:~/proxy" >> ~/.bashrc
source ~/.bashrc
bun --version
- id: test
name: Test (node runner)

View File

@@ -419,6 +419,11 @@ jobs:
cd ${{matrix.tag}}
chmod +x bun
sudo mv bun /usr/local/bin/bun
mkdir -p ~/proxy/
curl -L -o ~/proxy/http_proxy https://github.com/cirospaciari/http-proxy/raw/main/bin/macos-arm64/http_proxy
chmod +x ~/proxy/http_proxy
echo -e "\nexport PATH=$PATH:~/proxy" >> ~/.zshrc
source ~/.zshrc
bun --version
- id: test
name: Test (node runner)

View File

@@ -423,6 +423,11 @@ jobs:
cd ${{matrix.tag}}
chmod +x bun
sudo mv bun /usr/local/bin/bun
mkdir -p ~/proxy/
curl -L -o ~/proxy/http_proxy https://github.com/cirospaciari/http-proxy/raw/main/bin/macos/http_proxy
chmod +x ~/proxy/http_proxy
echo -e "\nexport PATH=$PATH:~/proxy" >> ~/.zshrc
source ~/.zshrc
bun --version
- id: test
name: Test (node runner)

View File

@@ -425,6 +425,11 @@ jobs:
cd ${{matrix.tag}}
chmod +x bun
sudo mv bun /usr/local/bin/bun
mkdir -p ~/proxy/
curl -L -o ~/proxy/http_proxy https://github.com/cirospaciari/http-proxy/raw/main/bin/macos/http_proxy
chmod +x ~/proxy/http_proxy
echo -e "\nexport PATH=$PATH:~/proxy" >> ~/.zshrc
source ~/.zshrc
bun --version
- id: test
name: Test (node runner)

View File

@@ -2702,13 +2702,12 @@ pub fn handleResponseMetadata(
}
if (this.proxy_tunneling and this.proxy_tunnel == null) {
//proxy denied connection
if (this.state.pending_response.status_code != 200) {
return error.ConnectionRefused;
if (this.state.pending_response.status_code == 200) {
//signal to continue the proxing
return true;
}
//signal to continue the proxing
return true;
//proxy denied connection so return proxy result (407, 403 etc)
this.proxy_tunneling = false;
}
const is_redirect = this.state.pending_response.status_code >= 300 and this.state.pending_response.status_code <= 399;

View File

@@ -1,136 +0,0 @@
import { afterAll, beforeAll, describe, expect, it } from "bun:test";
import { gc } from "harness";
let proxy, auth_proxy, server;
// TODO: Proxy with TLS requests
beforeAll(() => {
proxy = Bun.serve({
port: 0,
async fetch(request) {
// if is not an proxy connection just drop it
if (!request.headers.has("proxy-connection")) {
return new Response("Bad Request", { status: 400 });
}
// simple http proxy
if (request.url.startsWith("http://")) {
return await fetch(request.url, {
method: request.method,
body: await request.text(),
});
}
// no TLS support here
return new Response("Bad Request", { status: 400 });
},
});
auth_proxy = Bun.serve({
port: 0,
async fetch(request) {
// if is not an proxy connection just drop it
if (!request.headers.has("proxy-connection")) {
return new Response("Bad Request", { status: 400 });
}
if (!request.headers.has("proxy-authorization")) {
return new Response("Proxy Authentication Required", { status: 407 });
}
const auth = Buffer.from(
request.headers.get("proxy-authorization").replace("Basic ", "").trim(),
"base64",
).toString("utf8");
if (auth !== "squid_user:ASD123@123asd") {
return new Response("Forbidden", { status: 403 });
}
// simple http proxy
if (request.url.startsWith("http://")) {
return await fetch(request.url, {
method: request.method,
body: await request.text(),
});
}
// no TLS support here
return new Response("Bad Request", { status: 400 });
},
});
server = Bun.serve({
port: 0,
async fetch(request) {
if (request.method === "POST") {
const text = await request.text();
return new Response(text, { status: 200 });
}
return new Response("Hello, World", { status: 200 });
},
});
});
afterAll(() => {
server.stop();
proxy.stop();
auth_proxy.stop();
});
it("proxy non-TLS", async () => {
const url = `http://localhost:${server.port}`;
const auth_proxy_url = `http://squid_user:ASD123%40123asd@localhost:${auth_proxy.port}`;
const proxy_url = `localhost:${proxy.port}`;
const requests = [
[new Request(url), auth_proxy_url],
[
new Request(url, {
method: "POST",
body: "Hello, World",
}),
auth_proxy_url,
],
[url, auth_proxy_url],
[new Request(url), proxy_url],
[
new Request(url, {
method: "POST",
body: "Hello, World",
}),
proxy_url,
],
[url, proxy_url],
];
for (let [request, proxy] of requests) {
gc();
const response = await fetch(request, { verbose: true, proxy });
gc();
const text = await response.text();
gc();
expect(text).toBe("Hello, World");
}
});
it("proxy non-TLS auth can fail", async () => {
const url = `http://localhost:${server.port}`;
{
try {
const response = await fetch(url, { verbose: true, proxy: `http://localhost:${auth_proxy.port}` });
expect(response.statusText).toBe("Proxy Authentication Required");
} catch (err) {
expect(err).toBe("Proxy Authentication Required");
}
}
{
try {
const response = await fetch(url, {
verbose: true,
proxy: `http://squid_user:asdf123@localhost:${auth_proxy.port}`,
});
expect(response.statusText).toBe("Forbidden");
} catch (err) {
expect(err).toBe("Forbidden");
}
}
});

View File

@@ -0,0 +1,158 @@
import { which } from "bun";
import { afterAll, beforeAll, describe, expect, it } from "bun:test";
import { gc } from "harness";
import { spawn } from "node:child_process";
import { readFileSync } from "node:fs";
import { join } from "node:path";
type ProxyServer = { port: number | null; stop(): void };
let proxy: ProxyServer, auth_proxy: ProxyServer, server: ProxyServer, server_tls: ProxyServer;
const HTTP_PROXY_PATH = which("http_proxy");
const test = HTTP_PROXY_PATH ? it : it.skip;
const rawKeyFile = join(import.meta.dir, "../../node/tls", "fixtures", "rsa_private.pem");
const certFile = join(import.meta.dir, "../../node/tls", "fixtures", "rsa_cert.crt");
beforeAll(async () => {
if (!HTTP_PROXY_PATH) return;
function startProxyServer(options: Array<string>): Promise<ProxyServer> {
return new Promise((resolve, reject) => {
const proxy = spawn(HTTP_PROXY_PATH, options);
proxy.stdout.on("data", data => {
const [type, value] = data.toString().split(" ");
switch (type) {
case "[LISTEN]":
let port = value?.trim()?.split(":")[1];
if (port) {
port = parseInt(port, 10);
}
resolve({
port,
stop() {
proxy.kill();
},
});
case "[LISTEN-FAILURE]":
reject({ port: null, stop: () => {} });
break;
default:
console.log("Unknown type", data.toString());
}
});
if (proxy.exitCode) {
reject({ port: null, stop: () => {} });
}
});
}
proxy = await startProxyServer(["--port", "0"]);
auth_proxy = await startProxyServer(["--port", "0", "--auth", "squid_user:ASD@123asd"]);
server = Bun.serve({
port: 0,
async fetch(request) {
if (request.method === "POST") {
const text = await request.text();
return new Response(text, { status: 200 });
}
return new Response("Hello, World", { status: 200 });
},
});
server_tls = Bun.serve({
port: 0,
certFile: certFile,
keyFile: rawKeyFile,
async fetch(request) {
if (request.method === "POST") {
const text = await request.text();
return new Response(text, { status: 200 });
}
return new Response("Hello, World", { status: 200 });
},
});
});
afterAll(() => {
if (!HTTP_PROXY_PATH) return;
server.stop();
proxy.stop();
auth_proxy.stop();
server_tls.stop();
});
for (let is_tls of [false, true]) {
describe(`server ${is_tls ? "TLS" : "non-TLS"}`, () => {
test("fetch proxy", async done => {
const url = `${is_tls ? "https" : "http"}://127.0.0.1:${is_tls ? server_tls.port : server.port}`;
const auth_proxy_url = `http://squid_user:ASD%40123asd@127.0.0.1:${auth_proxy.port}`;
const proxy_url = `http://127.0.0.1:${proxy.port}`;
const requests: Array<[Request | string, string]> = [
[new Request(url), auth_proxy_url],
[
new Request(url, {
method: "POST",
body: "Hello, World",
}),
auth_proxy_url,
],
[url, auth_proxy_url],
[new Request(url), proxy_url],
[
new Request(url, {
method: "POST",
body: "Hello, World",
}),
proxy_url,
],
[url, proxy_url],
];
for (let [request, proxy] of requests) {
try {
gc();
const response = await fetch(request, { keepalive: false, verbose: true, proxy });
gc();
expect(response.status).toBe(200);
} catch (err) {
console.error(err);
expect(true).toBeFalsy();
}
}
done();
});
test("fetch proxy auth can fail", async done => {
const url = `${is_tls ? "https" : "http"}://localhost:${is_tls ? server_tls.port : server.port}`;
{
try {
const response = await fetch(url, {
keepalive: false,
verbose: true,
proxy: `http://localhost:${auth_proxy.port}`,
});
expect(response.status).toBe(407);
} catch (err) {
console.error(err);
expect(true).toBeFalsy();
}
}
{
try {
const response = await fetch(url, {
keepalive: false,
verbose: true,
proxy: `http://squid_user:asdf123@localhost:${auth_proxy.port}`,
});
expect(response.status).toBe(403);
} catch (err) {
console.error(err);
expect(true).toBeFalsy();
}
}
done();
});
});
}