This repository has been archived by the owner on Feb 21, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
http.go
98 lines (83 loc) · 2.15 KB
/
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
package loader
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"time"
)
// NewHTTPTemplateFetcher creates a new struct. `urls` must give us the
// base HTTP urls for us to look the templates in (note: do not use trailing slashes)
func NewHTTPTemplateFetcher(urls []string) (*HTTPTemplateFetcher, error) {
f := &HTTPTemplateFetcher{
URLs: make([]string, len(urls)),
}
for k, v := range urls {
u, err := url.Parse(v)
if err != nil {
return nil, err
}
if !u.IsAbs() {
return nil, fmt.Errorf("url %s is not an absolute url", v)
}
f.URLs[k] = u.String()
}
return f, nil
}
// FetchTemplate returns a TemplateSource representing the template at path
// `path`. Paths are searched relative to the urls given to NewHTTPTemplateFetcher()
func (l *HTTPTemplateFetcher) FetchTemplate(path string) (TemplateSource, error) {
u, err := url.Parse(path)
if err != nil {
return nil, fmt.Errorf("error parsing given path as url: %s", err)
}
if u.IsAbs() {
return nil, ErrAbsolutePathNotAllowed
}
// XXX Consider caching!
for _, base := range l.URLs {
u := base + "/" + path
res, err := http.Get(u)
if err != nil {
continue
}
return NewHTTPSource(res)
}
return nil, ErrTemplateNotFound
}
// NewHTTPSource creates a new HTTPSource instance
func NewHTTPSource(r *http.Response) (*HTTPSource, error) {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
return nil, err
}
s := &HTTPSource{
bytes.NewBuffer(body),
time.Time{},
}
if lastmodStr := r.Header.Get("Last-Modified"); lastmodStr != "" {
t, err := time.Parse(http.TimeFormat, lastmodStr)
if err != nil {
fmt.Printf("failed to parse: %s\n", err)
t = time.Now()
}
s.LastModifiedTime = t
} else {
s.LastModifiedTime = time.Now()
}
return s, nil
}
// LastModified returns the last modified date of this template
func (s *HTTPSource) LastModified() (time.Time, error) {
return s.LastModifiedTime, nil
}
// Reader returns the io.Reader for the template
func (s *HTTPSource) Reader() (io.Reader, error) {
return s.Buffer, nil
}
// Bytes returns the bytes in the template file
func (s *HTTPSource) Bytes() ([]byte, error) {
return s.Buffer.Bytes(), nil
}