retriablerequest_1.8.go raw

   1  //go:build go1.8
   2  // +build go1.8
   3  
   4  // Copyright 2017 Microsoft Corporation
   5  //
   6  //  Licensed under the Apache License, Version 2.0 (the "License");
   7  //  you may not use this file except in compliance with the License.
   8  //  You may obtain a copy of the License at
   9  //
  10  //      http://www.apache.org/licenses/LICENSE-2.0
  11  //
  12  //  Unless required by applicable law or agreed to in writing, software
  13  //  distributed under the License is distributed on an "AS IS" BASIS,
  14  //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15  //  See the License for the specific language governing permissions and
  16  //  limitations under the License.
  17  
  18  package autorest
  19  
  20  import (
  21  	"bytes"
  22  	"io"
  23  	"net/http"
  24  )
  25  
  26  // RetriableRequest provides facilities for retrying an HTTP request.
  27  type RetriableRequest struct {
  28  	req *http.Request
  29  	rc  io.ReadCloser
  30  	br  *bytes.Reader
  31  }
  32  
  33  // Prepare signals that the request is about to be sent.
  34  func (rr *RetriableRequest) Prepare() (err error) {
  35  	// preserve the request body; this is to support retry logic as
  36  	// the underlying transport will always close the reqeust body
  37  	if rr.req.Body != nil && rr.req.Body != http.NoBody {
  38  		if rr.rc != nil {
  39  			rr.req.Body = rr.rc
  40  		} else if rr.br != nil {
  41  			_, err = rr.br.Seek(0, io.SeekStart)
  42  			rr.req.Body = io.NopCloser(rr.br)
  43  		}
  44  		if err != nil {
  45  			return err
  46  		}
  47  		if rr.req.GetBody != nil {
  48  			// this will allow us to preserve the body without having to
  49  			// make a copy.  note we need to do this on each iteration
  50  			rr.rc, err = rr.req.GetBody()
  51  			if err != nil {
  52  				return err
  53  			}
  54  		} else if rr.br == nil {
  55  			// fall back to making a copy (only do this once)
  56  			err = rr.prepareFromByteReader()
  57  		}
  58  	}
  59  	return err
  60  }
  61  
  62  func removeRequestBody(req *http.Request) {
  63  	req.Body = nil
  64  	req.GetBody = nil
  65  	req.ContentLength = 0
  66  }
  67