forked from raviqqe/liche
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathurl_checker.go
90 lines (70 loc) · 1.51 KB
/
url_checker.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
package main
import (
"errors"
"net/url"
"os"
"path"
"path/filepath"
"regexp"
"sync"
"time"
"github.com/valyala/fasthttp"
)
type urlChecker struct {
timeout time.Duration
documentRoot string
excludedPattern *regexp.Regexp
semaphore semaphore
}
func newURLChecker(t time.Duration, d string, r *regexp.Regexp, s semaphore) urlChecker {
return urlChecker{t, d, r, s}
}
func (c urlChecker) Check(u string, f string) error {
u, local, err := c.resolveURL(u, f)
if err != nil {
return err
}
if c.excludedPattern != nil && c.excludedPattern.MatchString(u) {
return nil
}
if local {
_, err := os.Stat(u)
return err
}
c.semaphore.Request()
defer c.semaphore.Release()
if c.timeout == 0 {
_, _, err := fasthttp.Get(nil, u)
return err
}
_, _, err = fasthttp.GetTimeout(nil, u, c.timeout)
return err
}
func (c urlChecker) CheckMany(us []string, f string, rc chan<- urlResult) {
wg := sync.WaitGroup{}
for _, s := range us {
wg.Add(1)
go func(s string) {
rc <- urlResult{s, c.Check(s, f)}
wg.Done()
}(s)
}
wg.Wait()
close(rc)
}
func (c urlChecker) resolveURL(u string, f string) (string, bool, error) {
uu, err := url.Parse(u)
if err != nil {
return "", false, err
}
if uu.Scheme != "" {
return u, false, nil
}
if !path.IsAbs(uu.Path) {
return path.Join(filepath.Dir(f), uu.Path), true, nil
}
if c.documentRoot == "" {
return "", false, errors.New("document root directory is not specified")
}
return path.Join(c.documentRoot, uu.Path), true, nil
}