Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Path replacement of endpoint in Drive /upload operation #2623

Open
denisazevedo opened this issue Jun 4, 2024 · 2 comments
Open

Path replacement of endpoint in Drive /upload operation #2623

denisazevedo opened this issue Jun 4, 2024 · 2 comments
Assignees
Labels
priority: p3 Desirable enhancement or fix. May not be included in next release. type: question Request for information or clarification. Not an issue.

Comments

@denisazevedo
Copy link

When we create a service with endpoint (option#WithEndpoint) using host and path, ie:
https://myhost.com/connections/google/

	service, err := drive.NewService(ctx, option.WithHTTPClient(client))
	...
	tokenSource := option.WithTokenSource(oauth2.StaticTokenSource(&oauth2.Token{AccessToken: *token}))
	endpointOptions := option.WithEndpoint("https://myhost.com/connections/google/")
	options := []option.ClientOption{
		tokenSource,
		endpointOptions,
	}

it works well for operations like folder creation, as the URL will replaced by:
https://myhost.com/connections/google/files
Replaced by:

urls := googleapi.ResolveRelative(c.s.BasePath, "files")

But for media upload operations, like file creation, it is removing our endpoint path here:

urls = googleapi.ResolveRelative(c.s.BasePath, "/upload/drive/v3/files")

Instead of calling this:
https://myhost.com/connections/google/upload/drive/v3/files
it's calling:
https://myhost.com/upload/drive/v3/files

The reason is the slash / at the beggining of the relstr during the googleapi.ResolveRelative func call.
This is the only operation that starts with slash, all others (like files, comments, etc) are appended to our custom endpoint.

Is it an issue or intentional?

@denisazevedo denisazevedo added priority: p3 Desirable enhancement or fix. May not be included in next release. type: question Request for information or clarification. Not an issue. labels Jun 4, 2024
@codyoss codyoss assigned noahdietz and unassigned codyoss Jun 4, 2024
@noahdietz
Copy link
Contributor

noahdietz commented Jun 4, 2024

Interesting, thanks for the detailed report. I kind of think you've been depending on some emergent behavior.

ResolveRelative is documented saying it strips path segments trailing the host:
image.

I reproduced the behavior you've observed here: https://go.dev/play/p/CQFiZZgSsy8

func main() {
	e := "https://foo.googleapis.com/bar/baz/"
	p1 := "v1/fooer"
	p2 := "/v1/fooer"
	p3 := "fooer"

	fmt.Println("resolved endpoint:", googleapi.ResolveRelative(e, ""))
	fmt.Println("resolved p1:", googleapi.ResolveRelative(e, p1))
	fmt.Println("resolved p2:", googleapi.ResolveRelative(e, p2))
	fmt.Println("resolved p3:", googleapi.ResolveRelative(e, p3))
}
resolved endpoint: https://foo.googleapis.com/bar/baz/
resolved p1: https://foo.googleapis.com/bar/baz/v1/fooer
resolved p2: https://foo.googleapis.com/v1/fooer
resolved p3: https://foo.googleapis.com/bar/baz/fooer

You are right that it seems that when the relstr (second argument to ResolveRelative) starts with a /, it strips the path following the host completely. It gets weirder though...

When I take the trailing slash off of the endpoint it starts trimming differently:

resolved endpoint: https://foo.googleapis.com/bar/baz
resolved p1: https://foo.googleapis.com/bar/v1/fooer // different - baz is dropped
resolved p2: https://foo.googleapis.com/v1/fooer // same - both dropped
resolved p3: https://foo.googleapis.com/bar/fooer // different - baz is dropped

This will take a bit of investigating - I am worried about changing ResolveRelative behavior at this point b.c it's used so broadly, and even the "basePaths" in the generated code have path segments following the host name. There are also a few different ways that the endpoint assigned to the client BasePath property could be derived from the environment, which further confuses the potential current usage.

Edit: fix formatting

@denisazevedo
Copy link
Author

denisazevedo commented Jun 5, 2024

Thanks for your attention on this @noahdietz
I see, it really needs a deeper investigation. In our case, it's working broadly because all operations we're using is "appending" the endpoint's path and not replacing it.

About things getting weirder, check this out:
If you run this grep command at root level:

grep --include=\*.go -rn -e 'ResolveRelative(.*, "'

It returns 20k+ occurrences, yes, a lot of them.

But when you run:

grep --include=\*.go -rn -e 'ResolveRelative(.*, "/'

Only 74 starts with a /, and guess what, all of them is /upload/..., for instance:
./checks/v1alpha/checks-gen.go:3096: urls = googleapi.ResolveRelative(c.s.BasePath, "/upload/v1alpha/{+parent}/reports:analyzeUpload")

This commit replaced the old code for the ResolveRelative. I believe it may was a minor mistake when the / was forgotten in the replaced path.

Edit:
Actually, I found this thread where Chris Broadfoot and Seth Hollyman discussed about this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority: p3 Desirable enhancement or fix. May not be included in next release. type: question Request for information or clarification. Not an issue.
Projects
None yet
Development

No branches or pull requests

3 participants