Skip to content
This repository was archived by the owner on May 29, 2018. It is now read-only.

Commit e4094f1

Browse files
committed
Add docs
1 parent baace19 commit e4094f1

File tree

2 files changed

+34
-15
lines changed

2 files changed

+34
-15
lines changed

client.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ import (
1313
"time"
1414
)
1515

16+
// Follow opens a WebSocket to the file at the given URL (which must be handled
17+
// by httpfstream's HTTP handler) and returns the file's contents. The
18+
// io.ReadCloser continues to return data (blocking as needed) if, and as long
19+
// as, there is an active writer to the file.
1620
func Follow(u *url.URL) (io.ReadCloser, error) {
1721
ws, resp, err := newClient(u, "FOLLOW")
1822
if err == websocket.ErrBadHandshake {
@@ -32,6 +36,7 @@ type webSocketReadCloser struct {
3236
ws *websocket.Conn
3337
}
3438

39+
// Read implements io.Reader.
3540
func (r *webSocketReadCloser) Read(p []byte) (n int, err error) {
3641
op, rdr, err := r.ws.NextReader()
3742
if err != nil {
@@ -48,10 +53,12 @@ func (r *webSocketReadCloser) Read(p []byte) (n int, err error) {
4853
return
4954
}
5055

56+
// Close implements io.Closer.
5157
func (r *webSocketReadCloser) Close() error {
5258
return r.ws.Close()
5359
}
5460

61+
// Append appends data from r to the file at the given URL.
5562
func Append(u *url.URL, r io.Reader) error {
5663
w, err := OpenAppend(u)
5764
if err != nil {
@@ -63,6 +70,9 @@ func Append(u *url.URL, r io.Reader) error {
6370
return err
6471
}
6572

73+
// OpenAppend opens a WebSocket to the file at the given URL (which must point
74+
// be handled by httpfstream's HTTP handler) and returns an io.WriteCloser that writes
75+
// (via the WebSocket) to that file.
6676
func OpenAppend(u *url.URL) (io.WriteCloser, error) {
6777
ws, resp, err := newClient(u, "APPEND")
6878
if err != nil {
@@ -80,6 +90,7 @@ type appendWriteCloser struct {
8090
ws *websocket.Conn
8191
}
8292

93+
// Write implements io.Writer.
8394
func (pw *appendWriteCloser) Write(p []byte) (n int, err error) {
8495
pw.ws.SetWriteDeadline(time.Now().Add(writeWait))
8596
w, err := pw.ws.NextWriter(websocket.OpText)
@@ -90,6 +101,7 @@ func (pw *appendWriteCloser) Write(p []byte) (n int, err error) {
90101
return w.Write(p)
91102
}
92103

104+
// Write implements io.Closer.
93105
func (pw *appendWriteCloser) Close() error {
94106
return pw.ws.Close()
95107
}

server.go

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,17 @@ import (
1414
"time"
1515
)
1616

17-
func New(root string) handler {
18-
return handler{
17+
// New returns a new http.Handler for httpfstream.
18+
func New(root string) Handler {
19+
return Handler{
1920
Root: root,
2021
httpFS: http.Dir(root),
2122
writers: make(map[string]struct{}),
2223
followers: make(map[string]map[*http.Request]chan []byte),
2324
}
2425
}
2526

26-
type handler struct {
27+
type Handler struct {
2728
Root string
2829
Log *log.Logger
2930

@@ -38,7 +39,8 @@ type handler struct {
3839

3940
const xVerb = "X-Verb"
4041

41-
func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
42+
// ServeHTTP implements net/http.Handler.
43+
func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
4244
verb := r.Header.Get(xVerb)
4345
if verb == "" {
4446
verb = r.URL.Query().Get("verb")
@@ -57,7 +59,7 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
5759
}
5860
}
5961

60-
func (h handler) logf(msg string, v ...interface{}) {
62+
func (h Handler) logf(msg string, v ...interface{}) {
6163
if h.Log != nil {
6264
h.Log.Printf(msg, v...)
6365
}
@@ -76,14 +78,16 @@ var (
7678
writeWait = 5 * time.Second
7779
)
7880

79-
func (h handler) resolve(path string) string {
81+
func (h Handler) resolve(path string) string {
8082
path = pathpkg.Clean("/" + path)
8183
return filepath.Join(string(h.Root), path)
8284
}
8385

86+
// ErrWriterConflict indicates that the requested path is currently being
87+
// written by another writer. A path may have at most one active writer.
8488
var ErrWriterConflict = errors.New("path already has an active writer")
8589

86-
func (h handler) addWriter(path string) error {
90+
func (h Handler) addWriter(path string) error {
8791
h.writersMu.Lock()
8892
defer h.writersMu.Unlock()
8993
if _, present := h.writers[path]; !present {
@@ -93,13 +97,13 @@ func (h handler) addWriter(path string) error {
9397
return ErrWriterConflict
9498
}
9599

96-
func (h handler) removeWriter(path string) {
100+
func (h Handler) removeWriter(path string) {
97101
h.writersMu.Lock()
98102
defer h.writersMu.Unlock()
99103
delete(h.writers, path)
100104
}
101105

102-
func (h handler) addFollower(path string, r *http.Request, c chan []byte) {
106+
func (h Handler) addFollower(path string, r *http.Request, c chan []byte) {
103107
h.followersMu.Lock()
104108
defer h.followersMu.Unlock()
105109
if _, present := h.followers[path]; !present {
@@ -108,7 +112,7 @@ func (h handler) addFollower(path string, r *http.Request, c chan []byte) {
108112
h.followers[path][r] = c
109113
}
110114

111-
func (h handler) getFollowers(path string) []chan []byte {
115+
func (h Handler) getFollowers(path string) []chan []byte {
112116
h.followersMu.Lock()
113117
defer h.followersMu.Unlock()
114118
fs := make([]chan []byte, len(h.followers[path]))
@@ -120,7 +124,7 @@ func (h handler) getFollowers(path string) []chan []byte {
120124
return fs
121125
}
122126

123-
func (h handler) removeFollower(path string, r *http.Request) {
127+
func (h Handler) removeFollower(path string, r *http.Request) {
124128
h.followersMu.Lock()
125129
defer h.followersMu.Unlock()
126130
delete(h.followers[path], r)
@@ -129,18 +133,20 @@ func (h handler) removeFollower(path string, r *http.Request) {
129133
}
130134
}
131135

132-
func (h handler) isWriting(path string) bool {
136+
func (h Handler) isWriting(path string) bool {
133137
h.writersMu.Lock()
134138
defer h.writersMu.Unlock()
135139
_, present := h.writers[path]
136140
return present
137141
}
138142

139-
func (h handler) serveFile(w http.ResponseWriter, r *http.Request) {
143+
func (h Handler) serveFile(w http.ResponseWriter, r *http.Request) {
140144
http.FileServer(h.httpFS).ServeHTTP(w, r)
141145
}
142146

143-
func (h handler) Follow(w http.ResponseWriter, r *http.Request) {
147+
// Follow handles FOLLOW requests to retrieve the contents of a file and a
148+
// real-time stream of data that is appended to the file.
149+
func (h Handler) Follow(w http.ResponseWriter, r *http.Request) {
144150
path := h.resolve(r.URL.Path)
145151
h.logf("FOLLOW %s", path)
146152

@@ -253,7 +259,8 @@ done:
253259
}
254260
}
255261

256-
func (h handler) Append(w http.ResponseWriter, r *http.Request) {
262+
// Append handles APPEND requests and appends data to a file.
263+
func (h Handler) Append(w http.ResponseWriter, r *http.Request) {
257264
path := h.resolve(r.URL.Path)
258265
h.logf("APPEND %s", path)
259266

0 commit comments

Comments
 (0)