Git Lfs NTLM Work
* Switched the NTLM toggle to use the same url access pattern as private batch auth * Updated the NTLM session to pull the credentials from the cred helper
This commit is contained in:
parent
21159f8baa
commit
d71daeeb04
@ -14,6 +14,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/github/git-lfs/vendor/_nuts/github.com/rubyist/tracerx"
|
"github.com/github/git-lfs/vendor/_nuts/github.com/rubyist/tracerx"
|
||||||
)
|
)
|
||||||
@ -227,10 +228,17 @@ func Batch(objects []*objectResource, operation string) ([]*objectResource, erro
|
|||||||
return nil, newRetriableError(err)
|
return nil, newRetriableError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if IsAuthError(err) {
|
tracerx.Printf("BATCH---------HEADER---: %s", res.Header["Www-Authenticate"][0][0:4])
|
||||||
Config.SetAccess("basic")
|
if IsAuthError(err){
|
||||||
tracerx.Printf("api: batch not authorized, submitting with auth")
|
if strings.ToLower(res.Header["Www-Authenticate"][0][0:4]) == "ntlm" {
|
||||||
return Batch(objects, operation)
|
Config.SetAccess("ntlm")
|
||||||
|
tracerx.Printf("api: response indicates ntlm, submitting with ntlm auth")
|
||||||
|
return Batch(objects, operation)
|
||||||
|
} else {
|
||||||
|
Config.SetAccess("basic")
|
||||||
|
tracerx.Printf("api: batch not authorized, submitting with auth")
|
||||||
|
return Batch(objects, operation)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch res.StatusCode {
|
switch res.StatusCode {
|
||||||
@ -286,9 +294,15 @@ func UploadCheck(oidPath string) (*objectResource, error) {
|
|||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if IsAuthError(err) {
|
if IsAuthError(err) {
|
||||||
Config.SetAccess("basic")
|
if strings.ToLower(res.Header["Www-Authenticate"][0][0:4]) == "ntlm" {
|
||||||
tracerx.Printf("api: upload check not authorized, submitting with auth")
|
Config.SetAccess("ntlm")
|
||||||
return UploadCheck(oidPath)
|
tracerx.Printf("api: response indicates ntlm, submitting with ntlm auth")
|
||||||
|
return UploadCheck(oidPath)
|
||||||
|
} else{
|
||||||
|
Config.SetAccess("basic")
|
||||||
|
tracerx.Printf("api: upload check not authorized, submitting with auth")
|
||||||
|
return UploadCheck(oidPath)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, newRetriableError(err)
|
return nil, newRetriableError(err)
|
||||||
@ -460,9 +474,17 @@ func doAPIRequest(req *http.Request, useCreds bool) (*http.Response, error) {
|
|||||||
// doHttpRequest runs the given HTTP request. LFS or Storage API requests should
|
// doHttpRequest runs the given HTTP request. LFS or Storage API requests should
|
||||||
// use doApiBatchRequest() or doStorageRequest() instead.
|
// use doApiBatchRequest() or doStorageRequest() instead.
|
||||||
func doHttpRequest(req *http.Request, creds Creds) (*http.Response, error) {
|
func doHttpRequest(req *http.Request, creds Creds) (*http.Response, error) {
|
||||||
res, err := Config.HttpClient().Do(req)
|
|
||||||
|
|
||||||
if Config.NTLM() {
|
|
||||||
|
tracerx.Printf("ENTER doHttpRequest")
|
||||||
|
defer tracerx.Printf("LEAVE doHttpRequest")
|
||||||
|
|
||||||
|
var(
|
||||||
|
res *http.Response
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
if Config.NtlmAccess() {
|
||||||
res, err = DoNTLMRequest(req, true)
|
res, err = DoNTLMRequest(req, true)
|
||||||
} else {
|
} else {
|
||||||
res, err = Config.HttpClient().Do(req)
|
res, err = Config.HttpClient().Do(req)
|
||||||
@ -478,7 +500,13 @@ func doHttpRequest(req *http.Request, creds Creds) (*http.Response, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = Error(err)
|
if IsAuthError(err) && res.Header["Www-Authenticate"][0][0:4] == "ntlm" {
|
||||||
|
Config.SetAccess("ntlm")
|
||||||
|
tracerx.Printf("api: response indicates ntlm, submitting with ntlm auth")
|
||||||
|
doHttpRequest(req, creds)
|
||||||
|
} else {
|
||||||
|
err = Error(err)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
err = handleResponse(res, creds)
|
err = handleResponse(res, creds)
|
||||||
}
|
}
|
||||||
@ -497,7 +525,7 @@ func doHttpRequest(req *http.Request, creds Creds) (*http.Response, error) {
|
|||||||
func doApiRequestWithRedirects(req *http.Request, via []*http.Request, useCreds bool) (*http.Response, error) {
|
func doApiRequestWithRedirects(req *http.Request, via []*http.Request, useCreds bool) (*http.Response, error) {
|
||||||
var creds Creds
|
var creds Creds
|
||||||
if useCreds {
|
if useCreds {
|
||||||
c, err := getCredsForAPI(req)
|
c, err := getCredsForAPI(req, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -724,7 +752,7 @@ func setRequestAuthFromUrl(req *http.Request, u *url.URL) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setRequestAuth(req *http.Request, user, pass string) {
|
func setRequestAuth(req *http.Request, user, pass string) {
|
||||||
if(Config.NTLM()){
|
if(Config.NtlmAccess()){
|
||||||
//no-op. The NTLM manager will handle auth headers
|
//no-op. The NTLM manager will handle auth headers
|
||||||
} else {
|
} else {
|
||||||
if len(user) == 0 && len(pass) == 0 {
|
if len(user) == 0 && len(pass) == 0 {
|
||||||
@ -758,10 +786,4 @@ func setErrorHeaderContext(err error, prefix string, head http.Header) {
|
|||||||
ErrorSetContext(err, contextKey, head.Get(key))
|
ErrorSetContext(err, contextKey, head.Get(key))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ntlmHandshake(){
|
|
||||||
if !Config.NTLM(){
|
|
||||||
panic("NTLM is not enabled but an NTLM handshake was attempted")
|
|
||||||
}
|
|
||||||
}
|
|
@ -129,34 +129,6 @@ func (c *Configuration) ConcurrentTransfers() int {
|
|||||||
return uploads
|
return uploads
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Configuration) NTLM() bool {
|
|
||||||
if v, ok := c.GitConfig("lfs.ntlm"); ok {
|
|
||||||
if v == "true" || v == "" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Any numeric value except 0 is considered true
|
|
||||||
if n, err := strconv.Atoi(v); err == nil && n != 0 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Configuration) BatchTransfer() bool {
|
|
||||||
if v, ok := c.GitConfig("lfs.batch"); ok {
|
|
||||||
if v == "true" || v == "" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Any numeric value except 0 is considered true
|
|
||||||
if n, err := strconv.Atoi(v); err == nil && n != 0 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Configuration) BatchTransfer() bool {
|
func (c *Configuration) BatchTransfer() bool {
|
||||||
value, ok := c.GitConfig("lfs.batch")
|
value, ok := c.GitConfig("lfs.batch")
|
||||||
if !ok || len(value) == 0 {
|
if !ok || len(value) == 0 {
|
||||||
@ -171,12 +143,16 @@ func (c *Configuration) BatchTransfer() bool {
|
|||||||
return useBatch
|
return useBatch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Configuration) NtlmAccess() bool {
|
||||||
|
return c.Access() == "ntlm"
|
||||||
|
}
|
||||||
|
|
||||||
// PrivateAccess will retrieve the access value and return true if
|
// PrivateAccess will retrieve the access value and return true if
|
||||||
// the value is set to private. When a repo is marked as having private
|
// the value is set to private. When a repo is marked as having private
|
||||||
// access, the http requests for the batch api will fetch the credentials
|
// access, the http requests for the batch api will fetch the credentials
|
||||||
// before running, otherwise the request will run without credentials.
|
// before running, otherwise the request will run without credentials.
|
||||||
func (c *Configuration) PrivateAccess() bool {
|
func (c *Configuration) PrivateAccess() bool {
|
||||||
return c.Access() != "none"
|
return c.Access() != "none" && c.Access() != "ntlm"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Access returns the access auth type.
|
// Access returns the access auth type.
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
"github.com/github/git-lfs/vendor/_nuts/github.com/rubyist/tracerx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// getCreds gets the credentials for the given request's URL, and sets its
|
// getCreds gets the credentials for the given request's URL, and sets its
|
||||||
@ -14,6 +15,7 @@ import (
|
|||||||
// getCredsForAPI(), but skips checking the LFS url or git remote.
|
// getCredsForAPI(), but skips checking the LFS url or git remote.
|
||||||
func getCreds(req *http.Request) (Creds, error) {
|
func getCreds(req *http.Request) (Creds, error) {
|
||||||
if skipCredsCheck(req) {
|
if skipCredsCheck(req) {
|
||||||
|
tracerx.Printf("getCreds: skipping")
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,8 +32,9 @@ func getCreds(req *http.Request) (Creds, error) {
|
|||||||
// This prefers the Git remote URL for checking credentials so that users only
|
// This prefers the Git remote URL for checking credentials so that users only
|
||||||
// have to enter their passwords once for Git and Git LFS. It uses the same
|
// have to enter their passwords once for Git and Git LFS. It uses the same
|
||||||
// URL path that Git does, in case 'useHttpPath' is enabled in the Git config.
|
// URL path that Git does, in case 'useHttpPath' is enabled in the Git config.
|
||||||
func getCredsForAPI(req *http.Request) (Creds, error) {
|
func getCredsForAPI(req *http.Request, skip bool) (Creds, error) {
|
||||||
if skipCredsCheck(req) {
|
|
||||||
|
if skip && skipCredsCheck(req) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +50,10 @@ func getCredsForAPI(req *http.Request) (Creds, error) {
|
|||||||
return fillCredentials(req, credsUrl)
|
return fillCredentials(req, credsUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getCredsForNTLM(req *http.Request) (Creds, error){
|
||||||
|
return getCredsForAPI(req, false);
|
||||||
|
}
|
||||||
|
|
||||||
func getCredURLForAPI(req *http.Request) (*url.URL, error) {
|
func getCredURLForAPI(req *http.Request) (*url.URL, error) {
|
||||||
apiUrl, err := Config.ObjectUrl("")
|
apiUrl, err := Config.ObjectUrl("")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -60,7 +67,7 @@ func getCredURLForAPI(req *http.Request) (*url.URL, error) {
|
|||||||
return req.URL, nil
|
return req.URL, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if setRequestAuthFromUrl(req, apiUrl) {
|
if !Config.NtlmAccess() && setRequestAuthFromUrl(req, apiUrl) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +82,7 @@ func getCredURLForAPI(req *http.Request) (*url.URL, error) {
|
|||||||
if gitRemoteUrl.Scheme == apiUrl.Scheme &&
|
if gitRemoteUrl.Scheme == apiUrl.Scheme &&
|
||||||
gitRemoteUrl.Host == apiUrl.Host {
|
gitRemoteUrl.Host == apiUrl.Host {
|
||||||
|
|
||||||
if setRequestAuthFromUrl(req, gitRemoteUrl) {
|
if !Config.NtlmAccess() && setRequestAuthFromUrl(req, gitRemoteUrl) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +90,6 @@ func getCredURLForAPI(req *http.Request) (*url.URL, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return credsUrl, nil
|
return credsUrl, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,7 +111,7 @@ func fillCredentials(req *http.Request, u *url.URL) (Creds, error) {
|
|||||||
|
|
||||||
creds, err := execCreds(input, "fill")
|
creds, err := execCreds(input, "fill")
|
||||||
|
|
||||||
if creds != nil && err == nil {
|
if creds != nil && err == nil && !Config.NtlmAccess() {
|
||||||
setRequestAuth(req, creds["username"], creds["password"])
|
setRequestAuth(req, creds["username"], creds["password"])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
99
lfs/ntlm.go
99
lfs/ntlm.go
@ -1,72 +1,72 @@
|
|||||||
package lfs
|
package lfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
|
||||||
//"bufio"
|
|
||||||
//"net"
|
|
||||||
"net/http"
|
|
||||||
//"encoding/xml"
|
|
||||||
"encoding/base64"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/base64"
|
||||||
|
"github.com/ThomsonReutersEikon/go-ntlm/ntlm"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"fmt"
|
"net/http"
|
||||||
//"os"
|
// "strings"
|
||||||
"github.com/ThomsonReutersEikon/go-ntlm/ntlm"
|
"github.com/github/git-lfs/vendor/_nuts/github.com/rubyist/tracerx"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (c *Configuration) NTLMSession(creds Creds) ntlm.ClientSession {
|
||||||
type myReader struct {
|
|
||||||
*bytes.Buffer
|
|
||||||
}
|
|
||||||
|
|
||||||
// So that it implements the io.ReadCloser interface
|
|
||||||
func (m myReader) Close() error { return nil }
|
|
||||||
|
|
||||||
func (c *Configuration) NTLMSession() ntlm.ClientSession {
|
|
||||||
|
|
||||||
if c.ntlmSession != nil {
|
if c.ntlmSession != nil {
|
||||||
return c.ntlmSession
|
return c.ntlmSession
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tracerx.Printf("creds---------------------")
|
||||||
|
for key, val := range creds{
|
||||||
|
tracerx.Printf("%s:%s", key, val)
|
||||||
|
}
|
||||||
|
tracerx.Printf("-------------------------creds")
|
||||||
|
|
||||||
var session, _ = ntlm.CreateClientSession(ntlm.Version2, ntlm.ConnectionOrientedMode)
|
var session, _ = ntlm.CreateClientSession(ntlm.Version2, ntlm.ConnectionOrientedMode)
|
||||||
session.SetUserInfo("user","pass","domain")
|
session.SetUserInfo(creds["username"], creds["password"], "NORTHAMERICA")
|
||||||
|
|
||||||
c.ntlmSession = session
|
c.ntlmSession = session
|
||||||
|
|
||||||
return session
|
return session
|
||||||
}
|
}
|
||||||
|
|
||||||
func DoNTLMRequest(request *http.Request, retry bool) (*http.Response, error) {
|
func DoNTLMRequest(request *http.Request, retry bool) (*http.Response, error) {
|
||||||
|
|
||||||
if !Config.NTLM() {
|
tracerx.Printf("ENTER DoNTLMRequest")
|
||||||
return nil, Error(fmt.Errorf("NTLM is not enabled"))
|
defer tracerx.Printf("LEAVE DoNTLMRequest")
|
||||||
}
|
|
||||||
|
|
||||||
handReq := cloneRequest(request)
|
handReq := cloneRequest(request)
|
||||||
res, nil := InitHandShake(handReq)
|
res, nil := InitHandShake(handReq)
|
||||||
|
|
||||||
//If the status is 401 then we need to re-authenticate, otherwise it was successful
|
//If the status is 401 then we need to re-authenticate, otherwise it was successful
|
||||||
if res.StatusCode == 401 {
|
if res.StatusCode == 401 {
|
||||||
|
|
||||||
|
creds, _ := getCredsForNTLM(request)
|
||||||
|
|
||||||
negotiateReq := cloneRequest(request)
|
negotiateReq := cloneRequest(request)
|
||||||
challengeMessage := Negotiate(negotiateReq, getNegotiateMessage())
|
challengeMessage := negotiate(negotiateReq, getNegotiateMessage())
|
||||||
|
|
||||||
challengeReq := cloneRequest(request)
|
challengeReq := cloneRequest(request)
|
||||||
res, nil := Challenge(challengeReq, challengeMessage)
|
res, _ := challenge(challengeReq, challengeMessage, creds)
|
||||||
|
|
||||||
//If the status is 401 then we need to re-authenticate
|
//If the status is 401 then we need to re-authenticate
|
||||||
if res.StatusCode == 401 && retry == true {
|
if res.StatusCode == 401 && retry == true {
|
||||||
return DoNTLMRequest(challengeReq, false)
|
return DoNTLMRequest(challengeReq, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
return res, nil
|
saveCredentials(creds, res)
|
||||||
|
|
||||||
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitHandShake(request *http.Request) (*http.Response, error){
|
func InitHandShake(request *http.Request) (*http.Response, error){
|
||||||
|
|
||||||
|
tracerx.Printf("ENTER InitHandShake")
|
||||||
|
defer tracerx.Printf("LEAVE InitHandShake")
|
||||||
|
|
||||||
var response, err = Config.HttpClient().Do(request)
|
var response, err = Config.HttpClient().Do(request)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -76,7 +76,10 @@ func InitHandShake(request *http.Request) (*http.Response, error){
|
|||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Negotiate(request *http.Request, message string) []byte{
|
func negotiate(request *http.Request, message string) []byte{
|
||||||
|
|
||||||
|
tracerx.Printf("ENTER negotiate")
|
||||||
|
defer tracerx.Printf("LEAVE negotiate")
|
||||||
|
|
||||||
request.Header.Add("Authorization", message)
|
request.Header.Add("Authorization", message)
|
||||||
var response, err = Config.HttpClient().Do(request)
|
var response, err = Config.HttpClient().Do(request)
|
||||||
@ -85,18 +88,21 @@ func Negotiate(request *http.Request, message string) []byte{
|
|||||||
panic(err.Error())
|
panic(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
ret := ParseChallengeMessage(response)
|
ret := parseChallengeResponse(response)
|
||||||
|
|
||||||
//Always close negotiate to keep the connection alive
|
//Always close negotiate to keep the connection alive
|
||||||
//We never return the response from negotiate so we
|
//We never return the response from negotiate so we
|
||||||
//can't trust decodeApiResponse to decode it
|
//can't trust decodeApiResponse to close it
|
||||||
io.Copy(ioutil.Discard, response.Body)
|
io.Copy(ioutil.Discard, response.Body)
|
||||||
response.Body.Close()
|
response.Body.Close()
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
func Challenge(request *http.Request, challengeBytes []byte) (*http.Response, error){
|
func challenge(request *http.Request, challengeBytes []byte, creds Creds) (*http.Response, error){
|
||||||
|
|
||||||
|
tracerx.Printf("ENTER challenge")
|
||||||
|
defer tracerx.Printf("LEAVE challenge")
|
||||||
|
|
||||||
challenge, err := ntlm.ParseChallengeMessage(challengeBytes)
|
challenge, err := ntlm.ParseChallengeMessage(challengeBytes)
|
||||||
|
|
||||||
@ -104,14 +110,14 @@ func Challenge(request *http.Request, challengeBytes []byte) (*http.Response, er
|
|||||||
return nil, Error(err)
|
return nil, Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
Config.NTLMSession().ProcessChallengeMessage(challenge)
|
Config.NTLMSession(creds).ProcessChallengeMessage(challenge)
|
||||||
authenticate, err := Config.NTLMSession().GenerateAuthenticateMessage()
|
authenticate, err := Config.NTLMSession(creds).GenerateAuthenticateMessage()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, Error(err)
|
return nil, Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
authenticateMessage := ConcatS("NTLM ", base64.StdEncoding.EncodeToString(authenticate.Bytes()))
|
authenticateMessage := concatS("NTLM ", base64.StdEncoding.EncodeToString(authenticate.Bytes()))
|
||||||
|
|
||||||
request.Header.Add("Authorization", authenticateMessage)
|
request.Header.Add("Authorization", authenticateMessage)
|
||||||
response, err := Config.HttpClient().Do(request)
|
response, err := Config.HttpClient().Do(request)
|
||||||
@ -119,7 +125,10 @@ func Challenge(request *http.Request, challengeBytes []byte) (*http.Response, er
|
|||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseChallengeMessage(response *http.Response) []byte{
|
func parseChallengeResponse(response *http.Response) []byte{
|
||||||
|
|
||||||
|
tracerx.Printf("ENTER parseChallengeResponse")
|
||||||
|
defer tracerx.Printf("LEAVE parseChallengeResponse")
|
||||||
|
|
||||||
if headers, ok := response.Header["Www-Authenticate"]; ok{
|
if headers, ok := response.Header["Www-Authenticate"]; ok{
|
||||||
|
|
||||||
@ -138,6 +147,9 @@ func ParseChallengeMessage(response *http.Response) []byte{
|
|||||||
|
|
||||||
func cloneRequest(request *http.Request) *http.Request {
|
func cloneRequest(request *http.Request) *http.Request {
|
||||||
|
|
||||||
|
tracerx.Printf("ENTER cloneRequest")
|
||||||
|
defer tracerx.Printf("LEAVE cloneRequest")
|
||||||
|
|
||||||
var rdr1, rdr2 myReader
|
var rdr1, rdr2 myReader
|
||||||
var clonedReq *http.Request
|
var clonedReq *http.Request
|
||||||
|
|
||||||
@ -172,7 +184,7 @@ func getNegotiateMessage() string{
|
|||||||
return "NTLM TlRMTVNTUAABAAAAB7IIogwADAAzAAAACwALACgAAAAKAAAoAAAAD1dJTExISS1NQUlOTk9SVEhBTUVSSUNB"
|
return "NTLM TlRMTVNTUAABAAAAB7IIogwADAAzAAAACwALACgAAAAKAAAoAAAAD1dJTExISS1NQUlOTk9SVEhBTUVSSUNB"
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConcatS(ar ...string) string {
|
func concatS(ar ...string) string {
|
||||||
|
|
||||||
var buffer bytes.Buffer
|
var buffer bytes.Buffer
|
||||||
|
|
||||||
@ -183,6 +195,13 @@ func ConcatS(ar ...string) string {
|
|||||||
return buffer.String()
|
return buffer.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func Concat(ar ...[]byte) []byte {
|
func concat(ar ...[]byte) []byte {
|
||||||
return bytes.Join(ar, nil)
|
return bytes.Join(ar, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type myReader struct {
|
||||||
|
*bytes.Buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
// So that myReader implements the io.ReadCloser interface
|
||||||
|
func (m myReader) Close() error { return nil }
|
@ -130,7 +130,7 @@ func (q *TransferQueue) Watch() chan string {
|
|||||||
func (q *TransferQueue) individualApiRoutine(apiWaiter chan interface{}) {
|
func (q *TransferQueue) individualApiRoutine(apiWaiter chan interface{}) {
|
||||||
for t := range q.apic {
|
for t := range q.apic {
|
||||||
obj, err := t.Check()
|
obj, err := t.Check()
|
||||||
if err != nil {`
|
if err != nil {
|
||||||
tracerx.Printf("tq-willhi: t.Check() failed %s", t.Check)
|
tracerx.Printf("tq-willhi: t.Check() failed %s", t.Check)
|
||||||
|
|
||||||
if q.canRetry(err) {
|
if q.canRetry(err) {
|
||||||
|
Loading…
Reference in New Issue
Block a user