-
-
Save TooTallNate/2053342 to your computer and use it in GitHub Desktop.
/** | |
* Requires node v0.7.7 or greater. | |
* | |
* To connect: $ curl -sSNT. localhost:8000 | |
*/ | |
var http = require('http') | |
, repl = require('repl') | |
, buf0 = new Buffer([0]) | |
var server = http.createServer(function (req, res) { | |
res.setHeader('content-type', 'multipart/octet-stream') | |
res.write('Welcome to the Fun House\r\n') | |
repl.start({ | |
prompt: 'curl repl> ' | |
, input: req | |
, output: res | |
, terminal: false | |
, useColors: true | |
, useGlobal: false | |
}) | |
// log | |
console.log(req.headers['user-agent']) | |
// hack to thread stdin and stdout | |
// simultaneously in curl's single thread | |
var iv = setInterval(function () { | |
res.write(buf0) | |
}, 100) | |
res.connection.on('end', function () { | |
clearInterval(iv) | |
}) | |
}) | |
server.listen(8000) |
☮ ~ (master) ⚡ curl -sSNT. localhost:8000 | |
Welcome to the Fun House | |
curl repl> process.platform | |
'darwin' | |
curl repl> process.arch | |
'x64' | |
curl repl> process.cwd() | |
'/Users/nrajlich' | |
curl repl> path | |
{ resolve: [Function], | |
normalize: [Function], | |
join: [Function], | |
relative: [Function], | |
dirname: [Function], | |
basename: [Function], | |
extname: [Function], | |
_makeLong: [Function] } | |
curl repl> ^C | |
☮ ~ (master) ⚡ |
@SamB You're welcome! :-)
interesting, it works fine when running with the http-module.
However, when running as express middleware, the null-byte(s) in setInterval are printed as spaces in curl output.
Any idea what express might be adding here?
Sounds like express, indeed, sends null bytes. Or maybe you're using a different terminal, or different settings so that now they're rendered as space, rather than ignored. Anyway, you can use stdbuf -i0 -o0 -e0 tr -d '\000'
to filter them out.
ah thanks, that makes sense.
In the meantime I've also discovered polka, an express alternative which doesn't abstracts the native http req & res away.
I've quickly put this together for re-use:
https://github.com/coderofsalvation/middleware-remoteshell
Hopefully this allows me and others to route all stderr/stdout into a tmux mega-dashboard :)
With nginx as a proxy, I can't connect to my repl service using curl command. It hangs if I use -T option with stdin:
$ curl -sSNT . https://dev.mysite.com/api/job-item/replhttp
curl: (56) OpenSSL SSL_read: Connection reset by peer, errno 104
$ curl -vsSNT. https://dev.mysite.com/api/job-item/replhttp -I
* Trying 123.456.78.9:443...
* Connected to dev.mysite.com (123.456.78.9) port 443 (#0)
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /home/mostafa/anaconda3/ssl/cacert.pem
CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: CN=dev.mysite.com
* start date: Feb 16 12:05:49 2022 GMT
* expire date: May 17 12:05:48 2022 GMT
* subjectAltName: host "dev.mysite.com" matched cert's "dev.mysite.com"
* issuer: C=US; O=Let's Encrypt; CN=R3
* SSL certificate verify ok.
> PUT /api/job-item/replhttp HTTP/1.1
> Host: dev.mysite.com
> User-Agent: curl/7.71.1
> Accept: */*
> Transfer-Encoding: chunked
> Expect: 100-continue
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* Mark bundle as not supporting multiuse
< HTTP/1.1 100 Continue
HTTP/1.1 100 Continue
* OpenSSL SSL_read: Connection reset by peer, errno 104
* Closing connection 0
curl: (56) OpenSSL SSL_read: Connection reset by peer, errno 104
Any idea?
nginx will ensure it will behave itself, as in, it will strictly speak standard HTTP to your web app. This is a protective feature. The idea in this thread uses a non-standard protocol and disguises it as HTTP, very thinly. The disguise breaks as soon as you insert a component that expects real HTTP.
Edit: You might get away with HTTP UPGRADE somehow, but it will probably be a bit more complicated.
Do you have any idea about how to UPGRADE it?
On Ubuntu 20.04, curl takes a lot of CPU resources (more then 25%) to run this example.
@mk-pmb Now you tell me, after I already looked that all those up!