GetFile fetches the file from src and stores it at dst. If the server supports Accept-Range, HttpGetter will attempt a range request. This means it is the caller's responsibility to ensure that an older version of the destination file does not exist, else it will be either falsely identified as bein
(ctx context.Context, req *Request)
| 301 | // falsely identified as being replaced, or corrupted with extra bytes |
| 302 | // appended. |
| 303 | func (g *HttpGetter) GetFile(ctx context.Context, req *Request) error { |
| 304 | // Optionally enforce a maxiumum HTTP response body size. |
| 305 | if g.MaxBytes > 0 { |
| 306 | ctx = context.WithValue(ctx, httpMaxBytesValue, g.MaxBytes) |
| 307 | } |
| 308 | |
| 309 | if g.Netrc { |
| 310 | // Add auth from netrc if we can |
| 311 | if err := addAuthFromNetrc(req.u); err != nil { |
| 312 | return err |
| 313 | } |
| 314 | } |
| 315 | // Create all the parent directories if needed |
| 316 | if err := os.MkdirAll(filepath.Dir(req.Dst), req.Mode(0755)); err != nil { |
| 317 | return err |
| 318 | } |
| 319 | |
| 320 | f, err := os.OpenFile(req.Dst, os.O_RDWR|os.O_CREATE, req.Mode(0666)) |
| 321 | if err != nil { |
| 322 | return err |
| 323 | } |
| 324 | defer f.Close() |
| 325 | |
| 326 | if g.Client == nil { |
| 327 | g.Client = httpClient |
| 328 | } |
| 329 | |
| 330 | var currentFileSize int64 |
| 331 | var httpReq *http.Request |
| 332 | |
| 333 | if g.DoNotCheckHeadFirst == false { |
| 334 | headCtx := ctx |
| 335 | |
| 336 | if g.HeadFirstTimeout > 0 { |
| 337 | var cancel context.CancelFunc |
| 338 | |
| 339 | headCtx, cancel = context.WithTimeout(ctx, g.HeadFirstTimeout) |
| 340 | defer cancel() |
| 341 | } |
| 342 | |
| 343 | // We first make a HEAD request so we can check |
| 344 | // if the server supports range queries. If the server/URL doesn't |
| 345 | // support HEAD requests, we just fall back to GET. |
| 346 | httpReq, err = http.NewRequestWithContext(headCtx, "HEAD", req.u.String(), nil) |
| 347 | if err != nil { |
| 348 | return err |
| 349 | } |
| 350 | if g.Header != nil { |
| 351 | httpReq.Header = g.Header.Clone() |
| 352 | } |
| 353 | headResp, err := g.Client.Do(httpReq) |
| 354 | if err == nil { |
| 355 | headResp.Body.Close() |
| 356 | if headResp.StatusCode == 200 { |
| 357 | // If the HEAD request succeeded, then attempt to set the range |
| 358 | // query if we can. |
| 359 | if headResp.Header.Get("Accept-Ranges") == "bytes" && headResp.ContentLength >= 0 { |
| 360 | if fi, err := f.Stat(); err == nil { |
nothing calls this directly
no test coverage detected