Giter Site home page Giter Site logo

Comments (11)

misha-plus avatar misha-plus commented on July 17, 2024

Hello!
Do you use latest master version? I fixed the similar issue a few days ago. As I see this fix isn't released yet and stored only in master.

from gowebdav.

chuckwagoncomputing avatar chuckwagoncomputing commented on July 17, 2024

I set up a Radicale instance (uses Basic Auth), and I get the same error (with master). I'm currently looking into it.

from gowebdav.

chuckwagoncomputing avatar chuckwagoncomputing commented on July 17, 2024

This issue is caused by the OPTIONS request not requiring authorization. This means we'll have to check for a 401 status code at every request, or possibly try a PROPFIND / upon initial connection.

from gowebdav.

MrVine avatar MrVine commented on July 17, 2024

@misha-plus , yes, I use latest version from master

from gowebdav.

MrVine avatar MrVine commented on July 17, 2024

@chuckwagoncomputing , OPTIONS request is carrying out from options() function:

func (c *Client) options(path string) (*http.Response, error) {
	return c.req("OPTIONS", path, nil, func(rq *http.Request) {
		rq.Header.Add("Depth", "0")
	})
}

which calls c.req() function, which trying to do c.auth.Authorize(c, method, path)

from gowebdav.

chuckwagoncomputing avatar chuckwagoncomputing commented on July 17, 2024

That is correct. c.auth.Authorize will not work unless the authorization method has been set, which currently happens in Connect() in client.go, after the call to options() has succeeded. I'm moving it to req().

from gowebdav.

MrVine avatar MrVine commented on July 17, 2024

in my case c.options() returns 200 OK, and now I am trying to find the bug

from gowebdav.

MrVine avatar MrVine commented on July 17, 2024

yes, problem that authorization was not set in method c.connect()
it was not set because c.options() returns 200 OK, and in this line:

	if rs.StatusCode == 401 && c.auth.Type() == "NoAuth" {

application decided that server does not require authorization

from gowebdav.

MrVine avatar MrVine commented on July 17, 2024

I create following method:

func (c *Client) propfindTest() (*http.Response, error) {

	body :=
	`<d:propfind xmlns:d='DAV:'>
		<d:prop>
			<d:displayname/>
			<d:resourcetype/>
			<d:getcontentlength/>
			<d:getcontenttype/>
			<d:getetag/>
			<d:getlastmodified/>
		</d:prop>
	</d:propfind>`

        // "/qqq" is some existing folder on the webdav server. If folder will not exist,
        // "405 Not allowed" will be returned
	return c.req("PROPFIND", "/qqq", strings.NewReader(body), func(rq *http.Request) {
		rq.Header.Add("Depth", "0")
		rq.Header.Add("Content-Type", "text/xml;charset=UTF-8")
		rq.Header.Add("Accept", "application/xml,text/xml")
		rq.Header.Add("Accept-Charset", "utf-8")
		rq.Header.Add("Accept-Encoding", "")
	})
}

to use it instead of c.options() within c.connect, because PROPFIND requires authorization

Also, I modify c.connect() method:

func (c *Client) Connect() error {
	rs, err := c.propfindTest()
	if err != nil {
		return err
	}

	err = rs.Body.Close()
	if err != nil {
		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)
		}
		c.auth.Authorize(c, c.auth.User(), c.auth.Pass())
		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") == "")*/ {
		return newPathError("Connect", c.root, rs.StatusCode)
	}

	return nil
}

but I still get 401 Unauthorized

from gowebdav.

chuckwagoncomputing avatar chuckwagoncomputing commented on July 17, 2024

Your approach does not work because the first time propfindTest runs it is unauthorized, and returns an error. Because it returns an error, Connect() returns early and never reaches the part where it checks the return value, authorizes, and tries again.

Give the latest change a try. It works for me. If it doesn't work for you, we'll dig into this problem some more.

from gowebdav.

chripo avatar chripo commented on July 17, 2024

hello participants,
thank you for your investigations and for solving the issue.
@MrVine nice bug report! I'll use this as a template.

I'd like to improve the fix to keep the modification inside the client, because it's a client issue / improvement, and I'd love to keep the request as small as possible.
at the moment i have no clue how to do this in a nice way.

furthermore the connect call in the cmd (and client) seems to be useless. we could remove them. any concerns, what do you think?

from gowebdav.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.