github.com/sap/cf-mta-plugin@v2.6.3+incompatible/clients/csrf/transport.go (about)

     1  package csrf
     2  
     3  import (
     4  	"net/http"
     5  	"strconv"
     6  
     7  	"github.com/cloudfoundry-incubator/multiapps-cli-plugin/log"
     8  	"github.com/jinzhu/copier"
     9  )
    10  
    11  type Csrf struct {
    12  	Header              string
    13  	Token               string
    14  	IsInitialized       bool
    15  	NonProtectedMethods map[string]bool
    16  }
    17  
    18  type Cookies struct {
    19  	Cookies []*http.Cookie
    20  }
    21  
    22  type Transport struct {
    23  	OriginalTransport http.RoundTripper
    24  	Csrf              *Csrf
    25  	Cookies           *Cookies
    26  }
    27  
    28  func (t Transport) RoundTrip(req *http.Request) (*http.Response, error) {
    29  	req2 := http.Request{}
    30  	copier.Copy(&req2, req)
    31  
    32  	UpdateCookiesIfNeeded(t.Cookies.Cookies, &req2)
    33  
    34  	csrfTokenManager := NewDefaultCsrfTokenManager(&t, &req2)
    35  	err := csrfTokenManager.updateToken()
    36  	if err != nil {
    37  		return nil, err
    38  	}
    39  
    40  	log.Tracef("Sending a request with CSRF '" + req2.Header.Get("X-Csrf-Header") + " : " + req2.Header.Get("X-Csrf-Token") + "'\n")
    41  	log.Tracef("Cookies used are: " + prettyPrintCookies(req2.Cookies()) + "\n")
    42  	res, err := t.OriginalTransport.RoundTrip(&req2)
    43  	if err != nil {
    44  		return nil, err
    45  	}
    46  	tokenWasRefreshed, err := csrfTokenManager.refreshTokenIfNeeded(res)
    47  	if err != nil {
    48  		return nil, err
    49  	}
    50  
    51  	if tokenWasRefreshed {
    52  		log.Tracef("Response code '" + strconv.Itoa(res.StatusCode) + "' from bad token. Must Retry.\n")
    53  		return nil, &ForbiddenError{}
    54  	}
    55  
    56  	return res, err
    57  }
    58  
    59  func UpdateCookiesIfNeeded(cookies []*http.Cookie, request *http.Request) {
    60  	if len(cookies) == 0 {
    61  		return
    62  	}
    63  
    64  	request.Header.Del(CookieHeader)
    65  	for _, cookie := range cookies {
    66  		request.AddCookie(cookie)
    67  	}
    68  }
    69  
    70  func prettyPrintCookies(cookies []*http.Cookie) string {
    71  	result := ""
    72  	for _, cookie := range cookies {
    73  		result = result + cookie.String() + " "
    74  	}
    75  	return result
    76  }