func (pf *PacmanFetcher) httpDownload(url *http.URL) (string, os.Error) { req, err := http.NewRequest("GET", url.String(), nil) if err != nil { return "", err } req.UserAgent = MAW_USERAGENT resp, err := http.DefaultClient.Do(req) if err != nil { return "", err } defer resp.Body.Close() if resp.StatusCode != 200 { return "", os.NewError("Download of " + url.String() + " failed: HTTP " + resp.Status) } _, filename := path.Split(url.Path) destpath := path.Join(pf.pkgdest, filename) destfile, err := os.Create(destpath) if err != nil { return "", err } defer destfile.Close() if resp.ContentLength < 0 { _, err = io.Copy(destfile, resp.Body) } else { _, err = io.Copyn(destfile, resp.Body, resp.ContentLength) } if err != nil { return "", err } return destpath, nil }
// Forward a request to another domain // By design Go doesn't let you define new methods on non-local types func (this *HttpClient) Forward(req *http.Request, newDomain string) (resp *http.Response, err os.Error) { log.Printf("req host: %v\n", req.Host) // TODO change the the domain back for _, cookie := range req.Cookie { log.Printf("req cookie: %v\n", cookie) } var base *http.URL /*var r *http.Response*/ url := (newDomain + req.URL.RawPath) log.Printf("forwarding to: " + url) redirectChecker := this.client.CheckRedirect if redirectChecker == nil { redirectChecker = defaultCheckRedirect } var via []*http.Request for redirect := 0; ; redirect++ { var nReq = http.Request{} nReq.Method = req.Method //log.Printf("HTTP method: " + nReq.Method) nReq.Header = req.Header //log.Printf("Headers: %v\n", nReq.Header) if base == nil { nReq.URL, err = http.ParseURL(url) } else { nReq.URL, err = base.ParseURL(url) } if err != nil { break } // Set the redirection referer headers if len(via) > 0 { // Add the Referer header. lastReq := via[len(via)-1] if lastReq.URL.Scheme != "https" { nReq.Referer = lastReq.URL.String() } err = redirectChecker(&nReq, via) if err != nil { break } } // TODO support for content in the body if we aren't // dealing with GET/HEAD requests. url = nReq.URL.String() // Wrapped the client so I could do that ...sigh... // Also, #Do i a wrapper around #send if resp, err = this.client.Do(&nReq); err != nil { break } if shouldRedirect(resp.StatusCode) { resp.Body.Close() if url = resp.Header.Get("Location"); url == "" { err = os.ErrorString(fmt.Sprintf("%d response missing Location header", resp.StatusCode)) break } base = req.URL via = append(via, &nReq) continue } // log.Printf("final URL: " + url) return } err = &http.URLError{req.Method, url, err} return }