···368 request.Header.Set("Host", siteURL.Host)
369 }
370371+ // HTTP-to-HTTPS redirects are often implemented with 301 or 302 response codes which instruct
372+ // the Go HTTP client to disregard the original request method and use GET instead. To prevent
373+ // confusion, detect such redirects and preserve the original request method.
374+ http.DefaultClient.CheckRedirect = func(req *http.Request, via []*http.Request) error {
375+ last := via[len(via)-1]
376+ newURL := req.URL.JoinPath()
377+ lastURL := last.URL.JoinPath()
378+ if lastURL.Scheme == "http" && newURL.Scheme == "https" {
379+ lastURL.Scheme = newURL.Scheme
380+ if lastURL.String() == newURL.String() {
381+ req.Method = last.Method
382+ return nil
383+ }
384+ }
385+ if req.Method != last.Method {
386+ return fmt.Errorf("unexpected redirect")
387+ }
388+ return nil
389+ }
390+391 displayServer := *verboseFlag
392 for {
393 response, err := http.DefaultClient.Do(request)
394 if err != nil {
395+ if response.StatusCode == 301 || response.StatusCode == 302 {
396+ if innerErr := errors.Unwrap(err); innerErr != nil {
397+ // If the error is due to a redirect, that means it wasn't followed, but the
398+ // original url.Error confusingly reports the new URL anyway.
399+ err = innerErr
400+ }
401+ }
402 fmt.Fprintf(os.Stderr, "error: %s\n", err)
403 os.Exit(1)
404 }