broken links now recorded as such
* Broken field in Page{} now,
* anything that fails to fetch (with http 200) or parse (should not happen) is considered broken
* tests updated appropriately
* discovered my "image.png" file was in the wrong directory because it showed up as broken. fixed!
* bug fix: only fetch if type=text/html (after HEAD response)
This commit is contained in:
1 parent
f9fd0955e8
commit
f3152b6f44
6 files changed
+38
-10
No files matched your search
@@ -39,13 +39,15 @@ func docrawl(url string) []*Page {
|
|||||||
// fetch page
|
// fetch page
|
||||||
text, err := fetchPage(dest)
|
text, err := fetchPage(dest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue // TODO handle
|
dest.Broken = true
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse links
|
// parse links
|
||||||
title, links, err := parseLinks(text)
|
title, links, err := parseLinks(text)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue // TODO handle
|
dest.Broken = true
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
dest.Title = title
|
dest.Title = title
|
||||||
for _, l := range links {
|
for _, l := range links {
|
||||||
|
|||||||
@@ -177,8 +177,8 @@ func TestHeaderFetching(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("problem creating New Page struct")
|
t.Error("problem creating New Page struct")
|
||||||
}
|
}
|
||||||
if err := fetchFiletype(page); err != nil || page.MediaType != "text/plain" {
|
if err := fetchFiletype(page); err != nil || page.MediaType != "image/png" {
|
||||||
t.Logf("got %q, wanted %q", page.MediaType, "text/plain")
|
t.Logf("got %q, wanted %q", page.MediaType, "image/png")
|
||||||
t.Error("problem fetching filetype")
|
t.Error("problem fetching filetype")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -196,14 +196,18 @@ func TestJsonOutput(t *testing.T) {
|
|||||||
if len(l[0].Links) != 1 {
|
if len(l[0].Links) != 1 {
|
||||||
t.Error("location 0 has wrong number of links")
|
t.Error("location 0 has wrong number of links")
|
||||||
}
|
}
|
||||||
if len(l[0].Assets) != 3 {
|
if len(l[0].Assets) != 2 {
|
||||||
t.Logf("got %v", len(l[0].Assets))
|
t.Logf("got %v", len(l[0].Assets))
|
||||||
t.Error("location 0 has wrong number of assets")
|
t.Error("location 0 has wrong number of assets")
|
||||||
}
|
}
|
||||||
if len(l[0].Broken) != 0 {
|
if len(l[0].Broken) != 1 {
|
||||||
t.Logf("got %v", len(l[0].Broken))
|
t.Logf("got %v", len(l[0].Broken))
|
||||||
t.Error("location 0 has wrong number of broken urls")
|
t.Error("location 0 has wrong number of broken urls")
|
||||||
}
|
}
|
||||||
|
if len(l[0].Remote) != 0 {
|
||||||
|
t.Logf("got %v", len(l[1].Remote))
|
||||||
|
t.Error("location 0 has wrong number of remote urls")
|
||||||
|
}
|
||||||
if l[1].URL != baseURL+"about.html" {
|
if l[1].URL != baseURL+"about.html" {
|
||||||
t.Error("got an incorrect location")
|
t.Error("got an incorrect location")
|
||||||
}
|
}
|
||||||
@@ -217,11 +221,15 @@ func TestJsonOutput(t *testing.T) {
|
|||||||
t.Logf("got %v", len(l[1].Broken))
|
t.Logf("got %v", len(l[1].Broken))
|
||||||
t.Error("location 1 has wrong number of broken urls")
|
t.Error("location 1 has wrong number of broken urls")
|
||||||
}
|
}
|
||||||
|
if len(l[1].Remote) != 1 {
|
||||||
|
t.Logf("got %v", len(l[1].Remote))
|
||||||
|
t.Error("location 1 has wrong number of remote urls")
|
||||||
|
}
|
||||||
|
|
||||||
// this is a cheater test because the output is from a run of the code being
|
// this is a cheater test because the output is from a run of the code being
|
||||||
// test itself. but, it's been examined and I think it's right. and, there's not
|
// test itself. but, it's been examined and I think it's right. and, there's not
|
||||||
// many other ways to test this without some significant pain
|
// many other ways to test this without some significant pain
|
||||||
cheaterTest := `[{"URL":"http://localhost:8765/","Title":"Home","Links":["http://localhost:8765/about.html"],"Assets":["http://localhost:8765/assets/image.png","http://localhost:8765/scripts/blah.js","http://localhost:8765/zzzbroken.html"],"Broken":null,"Remote":null},{"URL":"http://localhost:8765/about.html","Title":"About Test","Links":["http://localhost:8765/"],"Assets":["http://localhost:8765/assets/image.png","http://localhost:8765/scripts/blah.js"],"Broken":null,"Remote":["http://doesntexist23492387492837492374982734.com/"]}]`
|
cheaterTest := `[{"URL":"http://localhost:8765/","Title":"Home","Links":["http://localhost:8765/about.html"],"Assets":["http://localhost:8765/assets/image.png","http://localhost:8765/scripts/blah.js"],"Broken":["http://localhost:8765/zzzbroken.html"],"Remote":null},{"URL":"http://localhost:8765/about.html","Title":"About Test","Links":["http://localhost:8765/"],"Assets":["http://localhost:8765/assets/image.png","http://localhost:8765/scripts/blah.js"],"Broken":null,"Remote":["http://doesntexist23492387492837492374982734.com/"]}]`
|
||||||
j, err := locationsToJSON(l)
|
j, err := locationsToJSON(l)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("locationsToJSON failed")
|
t.Error("locationsToJSON failed")
|
||||||
@@ -229,4 +237,5 @@ func TestJsonOutput(t *testing.T) {
|
|||||||
if j != cheaterTest {
|
if j != cheaterTest {
|
||||||
t.Error("locationsToJSON text doesn't match")
|
t.Error("locationsToJSON text doesn't match")
|
||||||
}
|
}
|
||||||
|
t.Log(j)
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
errContentTypeNotFound = errors.New("no Content-Type header found")
|
errContentTypeNotFound = errors.New("no Content-Type header found")
|
||||||
|
errFetchError = errors.New("couldn't fetch page")
|
||||||
)
|
)
|
||||||
|
|
||||||
// fetchFiletype performs an http HEAD to get the media type, and sets it
|
// fetchFiletype performs an http HEAD to get the media type, and sets it
|
||||||
@@ -19,6 +20,11 @@ func fetchFiletype(page *Page) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check response code
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return errFetchError
|
||||||
|
}
|
||||||
|
|
||||||
// pull the content type out of the http header
|
// pull the content type out of the http header
|
||||||
contentType, ok := resp.Header["Content-Type"]
|
contentType, ok := resp.Header["Content-Type"]
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -45,12 +51,22 @@ func fetchPage(page *Page) (string, error) {
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we only want to fetch html
|
||||||
|
if page.MediaType != "text/html" {
|
||||||
|
return "", nil // but this isn't an error!
|
||||||
|
}
|
||||||
|
|
||||||
// GET the url
|
// GET the url
|
||||||
resp, err := http.Get(page.URL.String())
|
resp, err := http.Get(page.URL.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check response code
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return "", errFetchError
|
||||||
|
}
|
||||||
|
|
||||||
// read the body
|
// read the body
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -33,11 +33,11 @@ func sitemapToLocations(pages []*Page) []*Location {
|
|||||||
for _, c := range p.Children {
|
for _, c := range p.Children {
|
||||||
// look up this child's media type from the root list of pages
|
// look up this child's media type from the root list of pages
|
||||||
//mediaType := pageMap[c.URL.String()].MediaType
|
//mediaType := pageMap[c.URL.String()].MediaType
|
||||||
if c.Skipped == true {
|
if c.Skipped {
|
||||||
l.Remote = append(l.Remote, c.URL.String())
|
l.Remote = append(l.Remote, c.URL.String())
|
||||||
} else if c.MediaType == "text/html" {
|
} else if c.MediaType == "text/html" {
|
||||||
l.Links = append(l.Links, c.URL.String())
|
l.Links = append(l.Links, c.URL.String())
|
||||||
} else if c.MediaType == "" {
|
} else if c.Broken {
|
||||||
l.Broken = append(l.Broken, c.URL.String())
|
l.Broken = append(l.Broken, c.URL.String())
|
||||||
} else {
|
} else {
|
||||||
l.Assets = append(l.Assets, c.URL.String())
|
l.Assets = append(l.Assets, c.URL.String())
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ type Page struct {
|
|||||||
Title string
|
Title string
|
||||||
MediaType string
|
MediaType string
|
||||||
Skipped bool
|
Skipped bool
|
||||||
|
Broken bool
|
||||||
Children []*Page
|
Children []*Page
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,5 +29,5 @@ func NewPage(referrer *Page, rawurl string) (*Page, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create struct and return
|
// create struct and return
|
||||||
return &Page{URL: u, Skipped: false}, nil
|
return &Page{URL: u, Skipped: false, Broken: false}, nil
|
||||||
}
|
}
|
||||||
File renamed without changes.
Reference in new issue
Block a user