mirror of
https://github.com/makew0rld/amfora.git
synced 2024-11-03 02:37:23 -05:00
parent
8672b78d69
commit
008d713de3
@ -406,7 +406,7 @@ func handleURL(t *tab, u string, numRedirects int) (string, bool) {
|
||||
return ret(u, true)
|
||||
}
|
||||
// Not displayable
|
||||
// Could be a non 20 (or 21) status code, or a different kind of document
|
||||
// Could be a non 20 status code, or a different kind of document
|
||||
|
||||
// Handle each status code
|
||||
switch res.Status {
|
||||
@ -414,7 +414,6 @@ func handleURL(t *tab, u string, numRedirects int) (string, bool) {
|
||||
userInput, ok := Input(res.Meta)
|
||||
if ok {
|
||||
// Make another request with the query string added
|
||||
// + chars are replaced because PathEscape doesn't do that
|
||||
parsed.RawQuery = gemini.QueryEscape(userInput)
|
||||
if len(parsed.String()) > gemini.URLMaxLength {
|
||||
Error("Input Error", "URL for that input would be too long.")
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"mime"
|
||||
urlPkg "net/url"
|
||||
"os"
|
||||
"path"
|
||||
"reflect"
|
||||
@ -23,9 +24,10 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrSaving = errors.New("couldn't save JSON to disk")
|
||||
ErrNotSuccess = errors.New("status 20 not returned")
|
||||
ErrNotFeed = errors.New("not a valid feed")
|
||||
ErrSaving = errors.New("couldn't save JSON to disk")
|
||||
ErrNotSuccess = errors.New("status 20 not returned")
|
||||
ErrNotFeed = errors.New("not a valid feed")
|
||||
ErrTooManyRedirects = errors.New("redirected more than 5 times")
|
||||
)
|
||||
|
||||
var writeMu = sync.Mutex{} // Prevent concurrent writes to subscriptions.json file
|
||||
@ -115,7 +117,8 @@ func GetFeed(mediatype, filename string, r io.Reader) (*gofeed.Feed, bool) {
|
||||
// Check mediatype and filename
|
||||
if mediatype != "application/atom+xml" && mediatype != "application/rss+xml" && mediatype != "application/json+feed" &&
|
||||
filename != "atom.xml" && filename != "feed.xml" && filename != "feed.json" &&
|
||||
!strings.HasSuffix(filename, ".atom") && !strings.HasSuffix(filename, ".rss") && !strings.HasSuffix(filename, ".xml") {
|
||||
!strings.HasSuffix(filename, ".atom") && !strings.HasSuffix(filename, ".rss") &&
|
||||
!strings.HasSuffix(filename, ".xml") {
|
||||
// No part of the above is true
|
||||
return nil, false
|
||||
}
|
||||
@ -229,46 +232,133 @@ func AddPage(url string, r io.Reader) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateFeed(url string) error {
|
||||
// getResource returns a URL and Response for the given URL.
|
||||
// It will follow up to 5 redirects, and if there is a permanent
|
||||
// redirect it will return the new URL. Otherwise the URL will
|
||||
// stay the same. THe returned URL will never be empty.
|
||||
//
|
||||
// If there is over 5 redirects the error will be ErrTooManyRedirects.
|
||||
// ErrNotSuccess, as well as other fetch errors will also be returned.
|
||||
func getResource(url string) (string, *gemini.Response, error) {
|
||||
res, err := client.Fetch(url)
|
||||
if err != nil {
|
||||
if res != nil {
|
||||
res.Body.Close()
|
||||
}
|
||||
return err
|
||||
return url, nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
if res.Status != gemini.StatusSuccess {
|
||||
return ErrNotSuccess
|
||||
if res.Status == gemini.StatusSuccess {
|
||||
// No redirects
|
||||
return url, res, nil
|
||||
}
|
||||
mediatype, _, err := mime.ParseMediaType(res.Meta)
|
||||
|
||||
parsed, err := urlPkg.Parse(url)
|
||||
if err != nil {
|
||||
return err
|
||||
return url, nil, err
|
||||
}
|
||||
filename := path.Base(url)
|
||||
feed, ok := GetFeed(mediatype, filename, res.Body)
|
||||
if !ok {
|
||||
return ErrNotFeed
|
||||
|
||||
i := 0
|
||||
redirs := make([]int, 0)
|
||||
urls := make([]*urlPkg.URL, 0)
|
||||
|
||||
// Loop through redirects
|
||||
for (res.Status == gemini.StatusRedirectPermanent || res.Status == gemini.StatusRedirectTemporary) && i < 5 {
|
||||
redirs = append(redirs, res.Status)
|
||||
urls = append(urls, parsed)
|
||||
|
||||
tmp, err := parsed.Parse(res.Meta)
|
||||
if err != nil {
|
||||
// Redirect URL returned by the server is invalid
|
||||
return url, nil, err
|
||||
}
|
||||
parsed = tmp
|
||||
|
||||
// Make the new request
|
||||
res, err := client.Fetch(parsed.String())
|
||||
if err != nil {
|
||||
if res != nil {
|
||||
res.Body.Close()
|
||||
}
|
||||
return url, nil, err
|
||||
}
|
||||
|
||||
i++
|
||||
}
|
||||
return AddFeed(url, feed)
|
||||
|
||||
// Two possible options here:
|
||||
// - Never redirected, got error on start
|
||||
// - No more redirects, other status code
|
||||
// - Too many redirects
|
||||
|
||||
if i == 0 {
|
||||
// Never redirected or succeeded
|
||||
return url, res, ErrNotSuccess
|
||||
}
|
||||
|
||||
if i < 5 {
|
||||
// The server stopped redirecting after <5 redirects
|
||||
|
||||
if res.Status == gemini.StatusSuccess {
|
||||
// It ended by succeeding
|
||||
|
||||
for j := range redirs {
|
||||
if redirs[j] == gemini.StatusRedirectTemporary {
|
||||
if j == 0 {
|
||||
// First redirect is temporary
|
||||
return url, res, nil
|
||||
}
|
||||
// There were permanent redirects before this one
|
||||
// Return the URL of the latest permanent redirect
|
||||
return urls[j-1].String(), res, nil
|
||||
}
|
||||
}
|
||||
// They were all permanent redirects
|
||||
return urls[len(urls)-1].String(), res, nil
|
||||
}
|
||||
|
||||
// It stopped because there was a non-redirect, non-success response
|
||||
return url, res, ErrNotSuccess
|
||||
}
|
||||
|
||||
// Too many redirects, return original
|
||||
return url, nil, ErrTooManyRedirects
|
||||
}
|
||||
|
||||
func updatePage(url string) error {
|
||||
res, err := client.Fetch(url)
|
||||
func updateFeed(url string) {
|
||||
newURL, res, err := getResource(url)
|
||||
if err != nil {
|
||||
if res != nil {
|
||||
res.Body.Close()
|
||||
}
|
||||
return err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
if res.Status != gemini.StatusSuccess {
|
||||
return ErrNotSuccess
|
||||
return
|
||||
}
|
||||
|
||||
return AddPage(url, res.Body)
|
||||
mediatype, _, err := mime.ParseMediaType(res.Meta)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
filename := path.Base(newURL)
|
||||
feed, ok := GetFeed(mediatype, filename, res.Body)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
AddFeed(newURL, feed)
|
||||
if url != newURL {
|
||||
// URL has changed, remove old one
|
||||
Remove(url)
|
||||
}
|
||||
}
|
||||
|
||||
func updatePage(url string) {
|
||||
newURL, res, err := getResource(url)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
AddPage(newURL, res.Body)
|
||||
if url != newURL {
|
||||
// URL has changed, remove old one
|
||||
Remove(url)
|
||||
}
|
||||
}
|
||||
|
||||
// updateAll updates all subscriptions using workers.
|
||||
|
Loading…
Reference in New Issue
Block a user