-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathwscat.go
114 lines (102 loc) · 2.66 KB
/
wscat.go
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
/**
* wscat: WebSocket cat
* Copytright (c) 2017 Atsushi Ezura <[email protected]>
* This software is released under the MIT License, see LICENSE.md
*/
package main
import (
"bufio"
"flag"
"fmt"
"golang.org/x/net/websocket"
"net/url"
"os"
)
type wscatConfig struct {
Url string
Origin string
Conn *websocket.Conn
Reader *os.File
Writer *os.File
SendFilename string
RecvFilename string
}
func (wscat *wscatConfig) run() {
wsConn, err := websocket.Dial(wscat.Url, "tcp", wscat.Origin)
if err != nil {
pmessage := fmt.Sprintf("\x1b[31m[Fatal] cannot connect to server: %s\x1b[0m", wscat.Url)
panic(pmessage)
}
wscat.Conn = wsConn
// WebSocket packet sender.
go func() {
if wscat.Reader != os.Stdin {
defer wscat.Reader.Close()
}
scanner := bufio.NewScanner(wscat.Reader)
for scanner.Scan() {
text := scanner.Text()
websocket.Message.Send(wscat.Conn, text)
}
if err := scanner.Err(); err != nil {
panic("\x1b[31m[Fatal] send error\x1b[0m")
}
}()
// WebSocket packet receiver.
if wscat.Writer != os.Stdout {
defer wscat.Writer.Close()
}
for {
var wsMessage string
if err := websocket.Message.Receive(wscat.Conn, &wsMessage); err != nil {
panic("\x1b[31m[Fatal] receive error\x1b[0m")
}
fmt.Fprintln(wscat.Writer, "\x1b[32m"+wsMessage+"\x1b[0m")
}
}
func (wscat *wscatConfig) getOptions() {
flag.StringVar(&wscat.Url, "c", "", "specified an WebSocket URL to connect to, ex) ws://echo.websocket.org/")
flag.StringVar(&wscat.SendFilename, "i", "", "specified a filename which inputs sending data from.")
flag.StringVar(&wscat.RecvFilename, "o", "", "specified a filename which outputs receiving data to.")
flag.Parse()
}
func (wscat *wscatConfig) init() {
// If it is no specified a WebSocket URL using -c option,
// this assumes a string at the end of the command as a URL.
if wscat.Url == "" {
narg := flag.NArg()
wscat.Url = flag.Arg(narg - 1)
}
if wscat.Url == "" {
panic("\x1b[31minvalid URL\x1b[0m")
}
url, err := url.Parse(wscat.Url)
if err != nil {
panic("\x1b[31mURL parsing\x1b[0m")
}
wscat.Origin = "http://" + url.Host
if wscat.SendFilename == "" {
wscat.Reader = os.Stdin
} else {
reader, err := os.Open(wscat.SendFilename)
if err != nil {
panic(fmt.Sprintf("\x1b[31mCannot open %s\x1b[0m", wscat.SendFilename))
}
wscat.Reader = reader
}
if wscat.RecvFilename == "" {
wscat.Writer = os.Stdout
} else {
writer, err := os.Create(wscat.RecvFilename)
if err != nil {
panic(fmt.Sprintf("\x1b[31mCannot open %s\x1b[0m", wscat.RecvFilename))
}
wscat.Writer = writer
}
}
func main() {
wscat := wscatConfig{}
wscat.getOptions()
wscat.init()
wscat.run()
}