diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..269643f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,27 @@ +--- +name: Bug report +about: Create a report to help us improve + +--- + +Hello Collaborators, + +**Describe the bug** +A short description of what you think the bug is. + +**Software** + - OS: + - Golang: + - Version: + +**To Reproduce** +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected** +A short description of what you expected to happen. + +**Additional context** +Add any other context about the problem here. diff --git a/README.md b/README.md index 248b626..7c5b921 100644 --- a/README.md +++ b/README.md @@ -253,55 +253,55 @@ func (c *Client) Connect() error ``` Connect connects to our dav server -#### func (\*Client) [Copy](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=6960:7028#L314) +#### func (\*Client) [Copy](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=6438:6506#L303) ``` go func (c *Client) Copy(oldpath, newpath string, overwrite bool) error ``` Copy copies a file from A to B -#### func (\*Client) [Mkdir](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=6051:6107#L273) +#### func (\*Client) [Mkdir](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=5529:5585#L262) ``` go func (c *Client) Mkdir(path string, _ os.FileMode) error ``` Mkdir makes a directory -#### func (\*Client) [MkdirAll](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=6286:6345#L284) +#### func (\*Client) [MkdirAll](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=5764:5823#L273) ``` go func (c *Client) MkdirAll(path string, _ os.FileMode) error ``` MkdirAll like mkdir -p, but for webdav -#### func (\*Client) [Read](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=7134:7184#L319) +#### func (\*Client) [Read](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=6612:6662#L308) ``` go func (c *Client) Read(path string) ([]byte, error) ``` Read reads the contents of a remote file -#### func (\*Client) [ReadDir](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=3126:3186#L131) +#### func (\*Client) [ReadDir](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=2604:2664#L120) ``` go func (c *Client) ReadDir(path string) ([]os.FileInfo, error) ``` ReadDir reads the contents of a remote directory -#### func (\*Client) [ReadStream](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=7495:7558#L337) +#### func (\*Client) [ReadStream](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=6973:7036#L326) ``` go func (c *Client) ReadStream(path string) (io.ReadCloser, error) ``` ReadStream reads the stream for a given path -#### func (\*Client) [Remove](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=5557:5599#L250) +#### func (\*Client) [Remove](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=5035:5077#L239) ``` go func (c *Client) Remove(path string) error ``` Remove removes a remote file -#### func (\*Client) [RemoveAll](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=5665:5710#L255) +#### func (\*Client) [RemoveAll](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=5143:5188#L244) ``` go func (c *Client) RemoveAll(path string) error ``` RemoveAll removes remote files -#### func (\*Client) [Rename](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=6794:6864#L309) +#### func (\*Client) [Rename](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=6272:6342#L298) ``` go func (c *Client) Rename(oldpath, newpath string, overwrite bool) error ``` @@ -325,19 +325,19 @@ func (c *Client) SetTransport(transport http.RoundTripper) ``` SetTransport exposes the ability to define custom transports -#### func (\*Client) [Stat](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=4513:4568#L198) +#### func (\*Client) [Stat](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=3991:4046#L187) ``` go func (c *Client) Stat(path string) (os.FileInfo, error) ``` Stat returns the file stats for a specified path -#### func (\*Client) [Write](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=7849:7918#L352) +#### func (\*Client) [Write](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=7327:7396#L341) ``` go func (c *Client) Write(path string, data []byte, _ os.FileMode) error ``` Write writes data to a given path -#### func (\*Client) [WriteStream](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=8320:8400#L374) +#### func (\*Client) [WriteStream](https://github.com/studio-b12/gowebdav/blob/master/client.go?s=7798:7878#L363) ``` go func (c *Client) WriteStream(path string, stream io.Reader, _ os.FileMode) error ``` diff --git a/client.go b/client.go index 9bdbf21..c91529f 100644 --- a/client.go +++ b/client.go @@ -85,18 +85,7 @@ func (c *Client) Connect() error { return err } - if rs.StatusCode == 401 && c.auth.Type() == "NoAuth" { - if strings.Index(rs.Header.Get("Www-Authenticate"), "Digest") > -1 { - c.auth = &DigestAuth{c.auth.User(), c.auth.Pass(), digestParts(rs)} - } else if strings.Index(rs.Header.Get("Www-Authenticate"), "Basic") > -1 { - c.auth = &BasicAuth{c.auth.User(), c.auth.Pass()} - } else { - return newPathError("Authorize", c.root, rs.StatusCode) - } - return c.Connect() - } else if rs.StatusCode == 401 { - return newPathError("Authorize", c.root, rs.StatusCode) - } else if rs.StatusCode != 200 || (rs.Header.Get("Dav") == "" && rs.Header.Get("DAV") == "") { + if rs.StatusCode != 200 { return newPathError("Connect", c.root, rs.StatusCode) } diff --git a/cmd/gowebdav/main.go b/cmd/gowebdav/main.go index c5fe1ec..c96c836 100644 --- a/cmd/gowebdav/main.go +++ b/cmd/gowebdav/main.go @@ -4,7 +4,7 @@ import ( "errors" "flag" "fmt" - d "github.com/studio-b12/gowebdav" + d "github.com/mrvine/gowebdav" "io" "os" "os/user" diff --git a/digestAuth.go b/digestAuth.go index 868a2c6..dbf8660 100644 --- a/digestAuth.go +++ b/digestAuth.go @@ -77,7 +77,12 @@ func getDigestAuthorization(digestParts map[string]string) string { nonceCount := 00000001 cnonce := getCnonce() response := getMD5(fmt.Sprintf("%s:%s:%v:%s:%s:%s", ha1, d["nonce"], nonceCount, cnonce, d["qop"], ha2)) - authorization := fmt.Sprintf(`Digest username="%s", realm="%s", nonce="%s", uri="%s", cnonce="%s", nc="%v", qop="%s", response="%s", opaque="%s"`, - d["username"], d["realm"], d["nonce"], d["uri"], cnonce, nonceCount, d["qop"], response, d["opaque"]) + authorization := fmt.Sprintf(`Digest username="%s", realm="%s", nonce="%s", uri="%s", qop=%s, nc=%v, cnonce="%s", response="%s"`, + d["username"], d["realm"], d["nonce"], d["uri"], d["qop"], nonceCount, cnonce, response) + + if d["opaque"] != "" { + authorization += fmt.Sprintf(`, opaque="%s"`, d["opaque"]) + } + return authorization } diff --git a/requests.go b/requests.go index 17b5515..5e047e8 100644 --- a/requests.go +++ b/requests.go @@ -1,6 +1,7 @@ package gowebdav import ( + "bytes" "fmt" "io" "net/http" @@ -8,13 +9,17 @@ import ( ) func (c *Client) req(method, path string, body io.Reader, intercept func(*http.Request)) (req *http.Response, err error) { - r, err := http.NewRequest(method, PathEscape(Join(c.root, path)), body) + // Tee the body, because if authorization fails we will need to read from it again. + var ba bytes.Buffer + bb := io.TeeReader(body, &ba) + + r, err := http.NewRequest(method, PathEscape(Join(c.root, path)), &ba) if err != nil { return nil, err } c.auth.Authorize(c, method, path) - + for k, vals := range c.headers { for _, v := range vals { r.Header.Add(k, v) @@ -25,7 +30,22 @@ func (c *Client) req(method, path string, body io.Reader, intercept func(*http.R intercept(r) } - return c.c.Do(r) + rs, err := c.c.Do(r) + + if rs.StatusCode == 401 && c.auth.Type() == "NoAuth" { + if strings.Index(rs.Header.Get("Www-Authenticate"), "Digest") > -1 { + c.auth = &DigestAuth{c.auth.User(), c.auth.Pass(), digestParts(rs)} + } else if strings.Index(rs.Header.Get("Www-Authenticate"), "Basic") > -1 { + c.auth = &BasicAuth{c.auth.User(), c.auth.Pass()} + } else { + return rs, newPathError("Authorize", c.root, rs.StatusCode) + } + return c.req(method, path, bb, intercept) + } else if rs.StatusCode == 401 { + return rs, newPathError("Authorize", c.root, rs.StatusCode) + } + + return rs, err } func (c *Client) mkcol(path string) int {