diff options
-rw-r--r-- | fetcher.go | 63 |
1 files changed, 54 insertions, 9 deletions
@@ -29,6 +29,7 @@ import ( "github.com/golang-basic/go-curl" "io/ioutil" "mime" + "net/http" "net/url" "os" "path" @@ -36,6 +37,11 @@ import ( "strings" ) +type FetchResult struct { + ResponseCode int + ErrorString string +} + type FetcherCurlCBData struct { basepath string filename string @@ -83,7 +89,7 @@ func curlWriteCallback(ptr []byte, userdata interface{}) bool { return true } -func FetchFileCurl(ctx *ImportContext, uri *url.URL) (err error) { +func FetchFileCurl(ctx *ImportContext, res *FetchResult, uri *url.URL) (err error) { rhl.Printf("curl-based fetcher called for '%s'", ctx.SourceUri) easy := curl.EasyInit() @@ -116,7 +122,7 @@ func FetchFileCurl(ctx *ImportContext, uri *url.URL) (err error) { easy.Setopt(curl.OPT_PROGRESSDATA, ctx) if err = easy.Perform(); err != nil { - err = fmt.Errorf("fetcher('%s'): %s", ctx.SourceUri, err) + err = fmt.Errorf("curl-fetcher('%s'): %s", ctx.SourceUri, err) return } @@ -130,7 +136,7 @@ func FetchFileCurl(ctx *ImportContext, uri *url.URL) (err error) { return } -func FetchFileLocal(ctx *ImportContext, uri *url.URL) (err error) { +func FetchFileLocal(ctx *ImportContext, res *FetchResult, uri *url.URL) (err error) { rhl.Printf("Local fetcher called for '%s'", ctx.SourceUri) if ctx.ProgressCallBack != nil { ctx.ProgressCallBack(1, "fetching", 1.0, ctx.ProgressCallBackData) @@ -139,15 +145,17 @@ func FetchFileLocal(ctx *ImportContext, uri *url.URL) (err error) { ctx.SourceFile = filepath.Join(ctx.Config.LocalFetchDir, path.Clean("/"+uri.Path)) var src *os.File if src, err = os.Open(ctx.SourceFile); err != nil { - return + res.ResponseCode = http.StatusBadRequest + res.ErrorString = fmt.Sprintf("local-file open(): %s", err) + return nil } - defer src.Close() + src.Close() ctx.DeleteSourceFile = false ctx.DeleteSourceDir = false return } -type FetchFunc func(*ImportContext, *url.URL) (err error) +type FetchFunc func(*ImportContext, *FetchResult, *url.URL) (err error) // TODO: implement fetchers for: // archiv:// @@ -182,15 +190,52 @@ func fetcher_init() { } } -func FetchFile(ctx *ImportContext) (err error) { +func checkPassword(ctx *ImportContext, result *FetchResult) (err error) { + cached := true + + for { + req := getPasswordRequest{} + req.username = ctx.UserName + req.cached = cached + req.response = make(chan getPasswordResult) + ctx.RdDb.getPasswordChan <- req + + res := <-req.response + if res.err != nil { + return res.err + } + if ctx.Password == res.password { + return nil + } + if cached { + cached = false + } else { + break + } + } + result.ResponseCode = http.StatusUnauthorized + result.ErrorString = "invalid username and/or password" + return +} + +func FetchFile(ctx *ImportContext) (res *FetchResult, err error) { + res = &FetchResult{ResponseCode: http.StatusOK} var uri *url.URL if uri, err = url.Parse(ctx.SourceUri); err != nil { - return + res.ResponseCode = http.StatusBadRequest + res.ErrorString = fmt.Sprintf("parsing uri: %s", err) + return res, nil + } + + if !ctx.Trusted { + if err = checkPassword(ctx, res); err != nil || res.ResponseCode != http.StatusOK { + return + } } if fetcher, ok := fetchers[uri.Scheme]; ok { - err = fetcher(ctx, uri) + err = fetcher(ctx, res, uri) } else { err = fmt.Errorf("No fetcher for uri scheme '%s' found.", uri.Scheme) } |