-
Notifications
You must be signed in to change notification settings - Fork 9
/
kite-http.go
119 lines (97 loc) · 2.32 KB
/
kite-http.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
115
116
117
118
119
// USAGE
//
// kite-http [--header name=value] [--debug] [-] <url>
//
// Use a hyphen to read data from stdin and POST it.
//
// Sets a default content-type of "application/x-www-form-urlencoded" for POSTs.
//
// Writes the http response (including header's protocol and status) to stdout.
//
// Use the --debug flag to write data from stdin to stderr.
package main
import (
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"strings"
"time"
)
type headers map[string]string
var myHeaders headers
func (i *headers) String() string {
return fmt.Sprint(*i)
}
func (i *headers) Set(value string) error {
header := strings.SplitN(value, "=", 2)
myHeaders[header[0]] = header[1]
return nil
}
func main() {
myHeaders = make(map[string]string)
flag.Var(&myHeaders, "header", "HTTP header as name=value")
debug := flag.Bool("debug", false, "write data from stdin to stderr")
timeout := flag.Duration("timeout", time.Second, "timeout for receiving a response from the HTTP server")
flag.Parse()
var stdin = false
var url string
switch flag.NArg() {
case 0:
log.Fatal("missing url")
case 1:
url = flag.Arg(0)
case 2:
if flag.Arg(0) == "-" {
stdin = true
} else {
log.Fatal("unrecognised argument: " + flag.Arg(0))
}
url = flag.Arg(1)
}
var data []byte
var err error
if stdin {
data, err = ioutil.ReadAll(os.Stdin)
if err != nil {
log.Fatal(err)
}
}
if *debug {
io.WriteString(os.Stderr, string(data)+"\n")
}
var req *http.Request
var resp *http.Response
client := &http.Client{
Timeout: *timeout,
}
if len(data) > 0 {
req, err = http.NewRequest("POST", url, strings.NewReader(string(data)))
} else {
req, err = http.NewRequest("GET", url, nil)
}
for k, v := range myHeaders {
req.Header.Set(k, v)
}
if len(data) > 0 {
if _, ok := myHeaders["Content-Type"]; !ok {
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
}
}
resp, err = client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
// We want to write to stdout the dechunked response. However
// httputil.DumpResponse() writes the chunked response.
//
// So we write the status part of the header, which is the only
// part we care about, ourselves and then the body.
fmt.Print(resp.Proto + " " + resp.Status + "\r\n")
fmt.Print("\r\n")
io.Copy(os.Stdout, resp.Body)
}