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 }