package anubis import ( "bytes" "io" "net/http" "net/url" "strings" ) // resolveRef resolves a (possibly relative) URL reference against a base URL, // preserving the base's scheme and host. Anubis's preact redir is host-relative // (e.g. "/.within.website/..."). func resolveRef(base *url.URL, ref string) *url.URL { u, err := url.Parse(ref) if err != nil { // Fall back to a copy of base; the caller's cookie check will catch it. c := *base return &c } return base.ResolveReference(u) } // maybeHTML reports whether a response could be an HTML page (and thus possibly // an Anubis interstitial). Non-HTML responses are passed through untouched. func maybeHTML(resp *http.Response) bool { ct := resp.Header.Get("Content-Type") if ct == "" { return true // unknown; be safe and inspect } return strings.Contains(strings.ToLower(ct), "text/html") } // withBody returns resp with its body replaced by an in-memory reader over b, // so the (already consumed) body can be read again by the caller. func withBody(resp *http.Response, b []byte) *http.Response { resp.Body = io.NopCloser(bytes.NewReader(b)) resp.ContentLength = int64(len(b)) resp.Header.Del("Content-Length") return resp } // applyCookies replaces the request's Cookie header with the cookies the shared // jar holds for the request URL. The replayed request goes through the base // transport directly (bypassing the client jar), so we must attach the freshly // obtained auth cookie ourselves. func (t *Transport) applyCookies(req *http.Request) { req.Header.Del("Cookie") for _, c := range t.Jar.Cookies(req.URL) { req.AddCookie(c) } }