diff --git a/tools/deno_http_proxy.ts b/tools/deno_http_proxy.ts new file mode 100644 index 0000000000..a2e5352aaa --- /dev/null +++ b/tools/deno_http_proxy.ts @@ -0,0 +1,27 @@ +// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +import { + serve, + ServerRequest +} from "../js/deps/https/deno.land/std/http/server.ts"; + +const addr = Deno.args[1] || "127.0.0.1:4500"; +const originAddr = Deno.args[2] || "127.0.0.1:4501"; +const server = serve(addr); + +async function main(): Promise { + console.log(`http://${addr}/`); + for await (const req of server) { + proxyRequest(req); + } +} + +async function proxyRequest(req: ServerRequest) { + const url = `http://${originAddr}${req.url}`; + const resp = await fetch(url, { + method: req.method, + headers: req.headers + }); + req.respond(resp); +} + +main(); diff --git a/tools/http_benchmark.py b/tools/http_benchmark.py index c7c7a83b12..7348b6b5ab 100755 --- a/tools/http_benchmark.py +++ b/tools/http_benchmark.py @@ -13,6 +13,7 @@ import subprocess # "deno_http" was once called "deno_net_http" ADDR = "127.0.0.1:4544" +ORIGIN_ADDR = "127.0.0.1:4545" DURATION = "10s" @@ -36,6 +37,18 @@ def deno_http(deno_exe): }) +def deno_http_proxy(deno_exe, hyper_hello_exe): + deno_cmd = [ + deno_exe, "run", "--allow-net", "tools/deno_http_proxy.ts", ADDR, + ORIGIN_ADDR + ] + print "http_proxy_benchmark testing DENO using net/http." + return run( + deno_cmd, + merge_env={"DENO_DIR": os.path.join(util.root_path, "js")}, + origin_cmd=http_proxy_origin(hyper_hello_exe)) + + def deno_core_single(exe): print "http_benchmark testing deno_core_single" return run([exe, "--single-thread"]) @@ -52,12 +65,22 @@ def node_http(): return run(node_cmd) +def node_http_proxy(hyper_hello_exe): + node_cmd = ["node", "tools/node_http_proxy.js", ADDR.split(":")[1]] + print "http_proxy_benchmark testing NODE." + return run(node_cmd, None, http_proxy_origin(hyper_hello_exe)) + + def node_tcp(): node_cmd = ["node", "tools/node_tcp.js", ADDR.split(":")[1]] print "http_benchmark testing node_tcp.js" return run(node_cmd) +def http_proxy_origin(hyper_hello_exe): + return [hyper_hello_exe, ORIGIN_ADDR.split(":")[1]] + + def hyper_http(hyper_hello_exe): hyper_cmd = [hyper_hello_exe, ADDR.split(":")[1]] print "http_benchmark testing RUST hyper." @@ -73,16 +96,18 @@ def http_benchmark(build_dir): "deno_tcp": deno_tcp(deno_exe), # "deno_http" was once called "deno_net_http" "deno_http": deno_http(deno_exe), + "deno_proxy": deno_http_proxy(deno_exe, hyper_hello_exe), "deno_core_single": deno_core_single(core_http_bench_exe), "deno_core_multi": deno_core_multi(core_http_bench_exe), # "node_http" was once called "node" "node_http": node_http(), + "node_proxy": node_http_proxy(hyper_hello_exe), "node_tcp": node_tcp(), "hyper": hyper_http(hyper_hello_exe) } -def run(server_cmd, merge_env=None): +def run(server_cmd, merge_env=None, origin_cmd=None): # Run deno echo server in the background. if merge_env is None: env = None @@ -95,6 +120,11 @@ def run(server_cmd, merge_env=None): # TODO Need to use SO_REUSEPORT with tokio::net::TcpListener. time.sleep(5) + origin = None + if origin_cmd is not None: + print "Starting origin server" + origin = subprocess.Popen(origin_cmd, env=env) + server = subprocess.Popen(server_cmd, env=env) time.sleep(5) # wait for server to wake up. TODO racy. @@ -109,6 +139,9 @@ def run(server_cmd, merge_env=None): return stats finally: server.kill() + if origin is not None: + print "Stopping origin server" + origin.kill() if __name__ == '__main__': diff --git a/tools/node_http_proxy.js b/tools/node_http_proxy.js new file mode 100644 index 0000000000..75dd5a3715 --- /dev/null +++ b/tools/node_http_proxy.js @@ -0,0 +1,28 @@ +// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +const http = require("http"); +const port = process.argv[2] || "4544"; +const originPort = process.argv[3] || "4545"; +console.log("port", port); +http + .Server((req, res) => { + const options = { + port: originPort, + path: req.url, + method: req.method, + headers: req.headers + }; + + const proxy = http.request(options, proxyRes => { + res.writeHead(proxyRes.statusCode, proxyRes.headers); + proxyRes.pipe( + res, + { end: true } + ); + }); + + req.pipe( + proxy, + { end: true } + ); + }) + .listen(port);