diff --git a/default.go b/default.go index 47481c7..23f6a48 100644 --- a/default.go +++ b/default.go @@ -19,7 +19,7 @@ const ( maxBodySizeBytes = 20971520 ) -func defaultLinkHandler(link string) (*LinkInfo, error) { +func (api *LinkInfoApi) DefaultLinkHandler(link string) (*LinkInfo, error) { redirects := make([]string, 0) u, err := url.Parse(link) @@ -31,7 +31,7 @@ func defaultLinkHandler(link string) (*LinkInfo, error) { var res *http.Response for i := 0; i < 10; i++ { - res, err = Client.Head(link) + res, err = api.Client.Head(link) if err != nil { return nil, err @@ -52,7 +52,7 @@ func defaultLinkHandler(link string) (*LinkInfo, error) { contentType := res.Header.Get("Content-Type") if contentType == "" { - contentType = detectContentType(link, "application/octet-stream") + contentType = api.detectContentType(link, "application/octet-stream") } if idx := strings.Index(contentType, ";"); idx != -1 { @@ -73,7 +73,7 @@ func defaultLinkHandler(link string) (*LinkInfo, error) { switch contentType { case contentTypeHtml: if contentLength > 0 && contentLength < maxBodySizeBytes { - err = retrieveHtmlLinkTitle(ret, link) + err = api.retrieveHtmlLinkTitle(ret, link) break } fallthrough @@ -84,7 +84,7 @@ func defaultLinkHandler(link string) (*LinkInfo, error) { return ret, err } -func detectContentType(link, defaultType string) string { +func (api *LinkInfoApi) detectContentType(link, defaultType string) string { req, err := http.NewRequest("GET", link, nil) if err != nil { @@ -93,7 +93,7 @@ func detectContentType(link, defaultType string) string { req.Header.Set("Range", "bytes=0-512") - res, err := Client.Do(req) + res, err := api.Client.Do(req) if err != nil { return defaultType @@ -120,8 +120,8 @@ var ( attrKeys = []string{"property", "name", "itemprop"} ) -func retrieveHtmlLinkTitle(i *LinkInfo, link string) error { - res, err := Client.Get(link) +func (api *LinkInfoApi) retrieveHtmlLinkTitle(i *LinkInfo, link string) error { + res, err := api.Client.Get(link) if err != nil { return err diff --git a/default_test.go b/default_test.go index e2e7420..e7c047d 100644 --- a/default_test.go +++ b/default_test.go @@ -5,8 +5,10 @@ import ( "testing" ) -func Test_detectContentType(t *testing.T) { - contentType := detectContentType("http://example.com", "") +func Test_LinkInfoApi_detectContentType(t *testing.T) { + api := &LinkInfoApi{} + + contentType := api.detectContentType("http://example.com", "") if contentType == "" { t.Fatal("Unable to test example.com, returned empty type") @@ -21,7 +23,7 @@ func Test_detectContentType(t *testing.T) { } } -func Test_defaultLinkHandler(t *testing.T) { +func Test_LinkInfoApi_defaultLinkHandler(t *testing.T) { type expectedData struct { Link string Title string @@ -33,8 +35,10 @@ func Test_defaultLinkHandler(t *testing.T) { {"http://techslides.com/demos/sample-videos/small.mp4", "", "video/mp4"}, } + api := &LinkInfoApi{} + for _, link := range testLinks { - l, err := defaultLinkHandler(link.Link) + l, err := api.DefaultLinkHandler(link.Link) if err != nil { t.Fatal("Unable to retrieve link info:", err) @@ -50,10 +54,12 @@ func Test_defaultLinkHandler(t *testing.T) { } } -func Test_retrieveHtmlLinkTitle(t *testing.T) { +func Test_LinkInfoApi_retrieveHtmlLinkTitle(t *testing.T) { ret := &LinkInfo{} - if err := retrieveHtmlLinkTitle(ret, "http://example.com"); err != nil { + api := &LinkInfoApi{} + + if err := api.retrieveHtmlLinkTitle(ret, "http://example.com"); err != nil { t.Fatal("Unable to retrieve html link title:", err) } diff --git a/imgur.go b/imgur.go new file mode 100644 index 0000000..cee442b --- /dev/null +++ b/imgur.go @@ -0,0 +1,9 @@ +package linkinfo + +var ( + imgurHosts = []string{"imgur.com", "i.imgur.com"} +) + +func (i *LinkInfoApi) ImgurLinkHandler(link string) (*LinkInfo, error) { + return nil, nil +} diff --git a/linkinfo.go b/linkinfo.go index fa4268f..816784d 100644 --- a/linkinfo.go +++ b/linkinfo.go @@ -5,14 +5,14 @@ import ( "net/url" ) -type linkHandler struct { - hosts []string - handler func(link string) (*LinkInfo, error) +type LinkHandler struct { + Hosts []string + Handler func(link string) (*LinkInfo, error) } type LinkInfoApi struct { - client *http.Client - ImgurId string + Client *http.Client + linkHandlers []*LinkHandler } type LinkInfo struct { @@ -24,14 +24,20 @@ type LinkInfo struct { Redirects []string `json:"redirects,omitempty"` } -var ( - linkHandlers = []*linkHandler{ - {hosts: []string{"youtube.com", "youtu.be"}, handler: youtubeLinkHandler}, - } -) - func New() *LinkInfoApi { - return &LinkInfoApi{} + api := &LinkInfoApi{} + + api.registerDefaultHandlers() + + return api +} + +func (i *LinkInfoApi) registerDefaultHandlers() { + i.linkHandlers = []*LinkHandler{ + {Hosts: youtubeHosts, Handler: i.YoutubeLinkHandler}, + {Hosts: imgurHosts, Handler: i.ImgurLinkHandler}, + {Hosts: twitterHosts, Handler: i.TwitterLinkHandler}, + } } func (i *LinkInfoApi) Retrieve(link string) (*LinkInfo, error) { @@ -41,13 +47,13 @@ func (i *LinkInfoApi) Retrieve(link string) (*LinkInfo, error) { return nil, err } - for _, handler := range linkHandlers { - for _, host := range handler.hosts { + for _, handler := range i.linkHandlers { + for _, host := range handler.Hosts { if host == u.Hostname() { - return handler.handler(link) + return handler.Handler(link) } } } - return defaultLinkHandler(link) + return i.DefaultLinkHandler(link) } diff --git a/twitter.go b/twitter.go new file mode 100644 index 0000000..8b93ccd --- /dev/null +++ b/twitter.go @@ -0,0 +1,9 @@ +package linkinfo + +var ( + twitterHosts = []string{"twitter.com"} +) + +func (i *LinkInfoApi) TwitterLinkHandler(link string) (*LinkInfo, error) { + return nil, nil +} diff --git a/youtube.go b/youtube.go index 2dbe336..bf16a3d 100644 --- a/youtube.go +++ b/youtube.go @@ -1,5 +1,9 @@ package linkinfo -func youtubeLinkHandler(link string) (*LinkInfo, error) { +var ( + youtubeHosts = []string{"youtube.com", "youtu.be"} +) + +func (i *LinkInfoApi) YoutubeLinkHandler(link string) (*LinkInfo, error) { return nil, nil }