/
main.lua
118 lines (103 loc) · 2.7 KB
/
main.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
local bundle = require('luvi').bundle
loadstring(bundle.readfile("luvit-loader.lua"), "bundle:luvit-loader.lua")()
local getenv = require('os').getenv
local isWindows = require('ffi').os == "Windows"
local uv = require('uv')
local fs = require('coro-fs')
local parseUrl = require('coro-websocket').parseUrl
local connect = require('coro-websocket').connect
local readline = require('readline')
local History = readline.History
local Editor = readline.Editor
local split = require('coro-split')
local pp = require('pretty-print')
local p = pp.prettyPrint
local meta = require('./package')
local options, url
do
local args = {...}
url = args[1]
if not url then
print(string.format("%s v%s", meta.name, meta.version))
print("usage: wscat url [subprotocol]")
print("example: wscat wss://lit.luvit.io/ lit")
return 1
end
local err
options, err = parseUrl(url)
if err then
print(err)
return -1
end
if options.pathname == "" then
options.pathname = "/"
end
options.subprotocol = args[2]
end
local getLine, history
do
local thread, editor
local prompt = ""
history = History.new()
editor = Editor.new({
stdin = pp.stdin,
stdout = pp.stdout,
history = history
})
local function onLine(err, line, reason)
local t = thread
thread = nil
return assert(coroutine.resume(t, line, err or reason))
end
function getLine()
thread = coroutine.running()
editor:readLine(prompt, onLine)
return coroutine.yield()
end
end
coroutine.wrap(function ()
local historyFile
if isWindows then
historyFile = getenv("APPDATA") .. "\\wscat_history"
else
historyFile = getenv("HOME") .. "/.wscat_history"
end
history:load(fs.readFile(historyFile) or "")
local connectMessage = "Conecting to " .. url
if options.subprotocol then
connectMessage = connectMessage .. " using " .. options.subprotocol
end
print(connectMessage)
local res, read, write = assert(connect(options))
local peer = res.socket:getpeername()
res.socket:keepalive(true, 1000)
print(string.format("Connected to %s:%s", peer.ip, peer.port))
print("(Use Control+D to send EOF)")
local done = false
local function getInput()
for line in getLine do
assert(write {
opcode = 1,
payload = line
})
fs.writeFile(historyFile, history:dump())
end
write()
done = true
end
local function logMessages()
for message in read do
if message.opcode == 1 then -- text
print(message.payload)
elseif message.opcode == 2 then -- binary
p(message.payload)
end
end
if not done then
print("Server disconnected")
os.exit(-1)
end
end
split(getInput, logMessages)
end)()
uv.run()