-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
113 lines (93 loc) · 2.31 KB
/
main.go
File metadata and controls
113 lines (93 loc) · 2.31 KB
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
package main
import (
"errors"
"flag"
"fmt"
"log"
"net"
"net/http"
"os"
"syscall"
)
const version = "0.1"
var (
host, path string
port int
public bool
)
type responseWriter struct {
http.ResponseWriter
statusCode int
}
func (w *responseWriter) WriteHeader(statusCode int) {
w.statusCode = statusCode
w.ResponseWriter.WriteHeader(statusCode)
}
func logger(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
rw := &responseWriter{w, http.StatusOK}
next.ServeHTTP(rw, r)
log.Printf("- [%s] %s \"%d\" %s", r.RemoteAddr, r.Method, rw.statusCode, r.URL.String())
})
}
func init() {
var showVersion bool
flag.StringVar(&host, "host", "localhost", "host to listen on")
flag.StringVar(&host, "h", "localhost", "host to listen on")
flag.IntVar(&port, "port", 8080, "port to listen on")
flag.IntVar(&port, "p", 8080, "port to listen on")
flag.BoolVar(&public, "public", false, "make the server publicly accessible")
flag.BoolVar(&public, "P", false, "make the server publicly accessible")
flag.BoolVar(&showVersion, "version", false, "show version")
flag.BoolVar(&showVersion, "v", false, "show version")
flag.Usage = func() {
usage := `Usage: serve [options] <path>
Options:
-h, --host string
host to listen on (default "localhost")
-p, --port int
port to listen on (default 8080)
-P, --public
make the server publicly accessible
-v, --version
show version
Arguments:
<path> path to serve (default current working directory)`
fmt.Println(usage)
}
flag.Parse()
if showVersion {
fmt.Printf("v%s\n", version)
os.Exit(0)
}
if public {
host = "0.0.0.0"
}
var err error
path, err = os.Getwd()
if flag.NArg() > 0 {
path = flag.Arg(0)
} else if err != nil {
log.Fatal(err)
}
}
func main() {
fs := http.FileServer(http.Dir(path))
http.Handle("/", logger(fs))
Serve:
addr := net.JoinHostPort(host, fmt.Sprintf("%d", port))
l, err := net.Listen("tcp", addr)
if err != nil {
if operr, ok := err.(*net.OpError); ok && errors.Is(operr.Err, syscall.EADDRINUSE) {
goto ChangePort
}
log.Fatal(err)
}
defer l.Close()
fmt.Printf("Serving %s on http://%s\n", path, addr)
log.Fatal(http.Serve(l, nil))
ChangePort:
port++
fmt.Printf("WARN Address already in use, changing port to %v\n", port)
goto Serve
}