@@ -909,30 +909,204 @@ to connect to both Unix and TCP sockets.
909
909
By starting a REPL from a Unix socket-based server instead of stdin, it is
910
910
possible to connect to a long-running Node.js process without restarting it.
911
911
912
- For an example of running a "full-featured" (` terminal ` ) REPL over
913
- a ` net.Server ` and ` net.Socket ` instance, see:
914
- < https://gist.github.com/TooTallNate/2209310 > .
912
+ ### Examples
915
913
916
- For an example of running a REPL instance over [ ` curl(1) ` ] [ ] , see:
917
- < https://gist.github.com/TooTallNate/2053342 > .
914
+ #### Full-featured "terminal" REPL over ` net.Server ` and ` net.Socket `
918
915
919
- This example is intended purely for educational purposes to demonstrate how
916
+ This is an example on how to run a "full-featured" (terminal) REPL using
917
+ [ ` net.Server ` ] [ ] and [ ` net.Socket ` ] [ ]
918
+
919
+ The following script starts an HTTP server on port ` 1337 ` that allows
920
+ clients to establish socket connections to its REPL instance.
921
+
922
+ ``` mjs
923
+ // repl-server.js
924
+ import repl from ' node:repl' ;
925
+ import net from ' node:net' ;
926
+
927
+ net
928
+ .createServer ((socket ) => {
929
+ const r = repl .start ({
930
+ prompt: ` socket ${ socket .remoteAddress } :${ socket .remotePort } > ` ,
931
+ input: socket,
932
+ output: socket,
933
+ terminal: true ,
934
+ useGlobal: false ,
935
+ });
936
+ r .on (' exit' , () => {
937
+ socket .end ();
938
+ });
939
+ r .context .socket = socket;
940
+ })
941
+ .listen (1337 );
942
+ ```
943
+
944
+ ``` cjs
945
+ // repl-server.js
946
+ const repl = require (' node:repl' );
947
+ const net = require (' node:net' );
948
+
949
+ net
950
+ .createServer ((socket ) => {
951
+ const r = repl .start ({
952
+ prompt: ` socket ${ socket .remoteAddress } :${ socket .remotePort } > ` ,
953
+ input: socket,
954
+ output: socket,
955
+ terminal: true ,
956
+ useGlobal: false ,
957
+ });
958
+ r .on (' exit' , () => {
959
+ socket .end ();
960
+ });
961
+ r .context .socket = socket;
962
+ })
963
+ .listen (1337 );
964
+ ```
965
+
966
+ While the following implements a client that can create a socket connection
967
+ with the above defined server over port ` 1337 ` .
968
+
969
+ ``` mjs
970
+ // repl-client.js
971
+ import net from ' node:net' ;
972
+ import process from ' node:process' ;
973
+
974
+ const sock = net .connect (1337 );
975
+
976
+ process .stdin .pipe (sock);
977
+ sock .pipe (process .stdout );
978
+
979
+ sock .on (' connect' , () => {
980
+ process .stdin .resume ();
981
+ process .stdin .setRawMode (true );
982
+ });
983
+
984
+ sock .on (' close' , () => {
985
+ process .stdin .setRawMode (false );
986
+ process .stdin .pause ();
987
+ sock .removeListener (' close' , done);
988
+ });
989
+
990
+ process .stdin .on (' end' , () => {
991
+ sock .destroy ();
992
+ console .log ();
993
+ });
994
+
995
+ process .stdin .on (' data' , (b ) => {
996
+ if (b .length === 1 && b[0 ] === 4 ) {
997
+ process .stdin .emit (' end' );
998
+ }
999
+ });
1000
+ ```
1001
+
1002
+ ``` cjs
1003
+ // repl-client.js
1004
+ const net = require (' node:net' );
1005
+
1006
+ const sock = net .connect (1337 );
1007
+
1008
+ process .stdin .pipe (sock);
1009
+ sock .pipe (process .stdout );
1010
+
1011
+ sock .on (' connect' , () => {
1012
+ process .stdin .resume ();
1013
+ process .stdin .setRawMode (true );
1014
+ });
1015
+
1016
+ sock .on (' close' , () => {
1017
+ process .stdin .setRawMode (false );
1018
+ process .stdin .pause ();
1019
+ sock .removeListener (' close' , done);
1020
+ });
1021
+
1022
+ process .stdin .on (' end' , () => {
1023
+ sock .destroy ();
1024
+ console .log ();
1025
+ });
1026
+
1027
+ process .stdin .on (' data' , (b ) => {
1028
+ if (b .length === 1 && b[0 ] === 4 ) {
1029
+ process .stdin .emit (' end' );
1030
+ }
1031
+ });
1032
+ ```
1033
+
1034
+ To run the example open two different terminals on your machine, start the server
1035
+ with ` node repl-server.js ` in one terminal and ` node repl-client.js ` on the other.
1036
+
1037
+ Original code from < https://gist.github.com/TooTallNate/2209310 > .
1038
+
1039
+ #### REPL over ` curl `
1040
+
1041
+ This is an example on how to run a REPL instance over [ ` curl() ` ] [ ]
1042
+
1043
+ The following script starts an HTTP server on port ` 8000 ` that can accept
1044
+ a connection established via [ ` curl() ` ] [ ] .
1045
+
1046
+ ``` mjs
1047
+ import http from ' node:http' ;
1048
+ import repl from ' node:repl' ;
1049
+
1050
+ const server = http .createServer ((req , res ) => {
1051
+ res .setHeader (' content-type' , ' multipart/octet-stream' );
1052
+
1053
+ repl .start ({
1054
+ prompt: ' curl repl> ' ,
1055
+ input: req,
1056
+ output: res,
1057
+ terminal: false ,
1058
+ useColors: true ,
1059
+ useGlobal: false ,
1060
+ });
1061
+ });
1062
+
1063
+ server .listen (8000 );
1064
+ ```
1065
+
1066
+ ``` cjs
1067
+ const http = require (' node:http' );
1068
+ const repl = require (' node:repl' );
1069
+
1070
+ const server = http .createServer ((req , res ) => {
1071
+ res .setHeader (' content-type' , ' multipart/octet-stream' );
1072
+
1073
+ repl .start ({
1074
+ prompt: ' curl repl> ' ,
1075
+ input: req,
1076
+ output: res,
1077
+ terminal: false ,
1078
+ useColors: true ,
1079
+ useGlobal: false ,
1080
+ });
1081
+ });
1082
+
1083
+ server .listen (8000 );
1084
+ ```
1085
+
1086
+ When the above script is running you can then use [ ` curl() ` ] [ ] to connect to
1087
+ the server and connect to its REPL instance by running ` curl --no-progress-meter -sSNT. localhost:8000 ` .
1088
+
1089
+ ** Warning** This example is intended purely for educational purposes to demonstrate how
920
1090
Node.js REPLs can be started using different I/O streams.
921
1091
It should ** not** be used in production environments or any context where security
922
1092
is a concern without additional protective measures.
923
1093
If you need to implement REPLs in a real-world application, consider alternative
924
1094
approaches that mitigate these risks, such as using secure input mechanisms and
925
1095
avoiding open network interfaces.
926
1096
1097
+ Original code from < https://gist.github.com/TooTallNate/2053342 > .
1098
+
927
1099
[ TTY keybindings ] : readline.md#tty-keybindings
928
1100
[ ZSH ] : https://en.wikipedia.org/wiki/Z_shell
929
1101
[ `'uncaughtException'` ] : process.md#event-uncaughtexception
930
1102
[ `--no-experimental-repl-await` ] : cli.md#--no-experimental-repl-await
931
1103
[ `ERR_DOMAIN_CANNOT_SET_UNCAUGHT_EXCEPTION_CAPTURE` ] : errors.md#err_domain_cannot_set_uncaught_exception_capture
932
1104
[ `ERR_INVALID_REPL_INPUT` ] : errors.md#err_invalid_repl_input
933
- [ `curl(1 )` ] : https://curl.haxx.se/docs/manpage.html
1105
+ [ `curl()` ] : https://curl.haxx.se/docs/manpage.html
934
1106
[ `domain` ] : domain.md
935
1107
[ `module.builtinModules` ] : module.md#modulebuiltinmodules
1108
+ [ `net.Server` ] : net.md#class-netserver
1109
+ [ `net.Socket` ] : net.md#class-netsocket
936
1110
[ `process.setUncaughtExceptionCaptureCallback()` ] : process.md#processsetuncaughtexceptioncapturecallbackfn
937
1111
[ `readline.InterfaceCompleter` ] : readline.md#use-of-the-completer-function
938
1112
[ `repl.ReplServer` ] : #class-replserver
0 commit comments