tusd icon indicating copy to clipboard operation
tusd copied to clipboard

Add callback to UnroutedHandler to remove restriction on upload URIs.

Open innovate-invent opened this issue 4 years ago • 8 comments

Fixes #340

innovate-invent avatar Jan 03 '20 01:01 innovate-invent

Interesting approach, thanks for opening this PR. I understand the need for this feature but I disagree with the API design. Instead of the GetID and GetURL functions, I would advocate for this design:

DeserializeUploadURL func(url string) (uploadId string, err error)
SerializeUploadURL func(uploadId string) (url string, err error)

In particular, I am not a fan of:

  • the names GetID and GetURL, which are not very descriptive
  • the http.Request argument is not need IMO (Could you explain why you added it?)
  • the url.URL return value. Using a string in our situation is enough and makes it easier to handle

What do you think?

Acconut avatar Jan 06 '20 18:01 Acconut

* the names GetID and GetURL, which are not very descriptive

I am ok with whatever name you want, although deserialize is not the best word to use given my response to the next point.

* the http.Request argument is not need IMO (Could you explain why you added it?)

tus does not specify how the ID is transmitted and could be influenced by extra header information (possibly added by a proxy). It is better to provide to the library user the entire request so as to not be unnecessarily restrictive.

* the url.URL return value. Using a string in our situation is enough and makes it easier to handle

URLs should be managed by the appropriate type, only converting to strings when strings are needed.

You will see most implementations do something along the lines of

u := url.Parse(request.url)
paths := u.Path.split("/")
paths = append(paths, id)
u.Path = paths.join("/")
return u // Why discard information here by converting back to a string?

This is more for the sake of the interface, why make it restrictive?

I should also add that the current implementation, building urls via string concatenation, needs to be reworked to use the appropriate url.URL type.

innovate-invent avatar Jan 06 '20 19:01 innovate-invent

Good points! The names GetID and GetUpload are too broad, so they must be changed to express their purpose more explicitly.

A bit different topic: Can you provide an example of what your URLs look like which cannot be used with the current tusd version?

Acconut avatar Jan 09 '20 11:01 Acconut

Good points! The names GetID and GetUpload are too broad, so they must be changed to express their purpose more explicitly.

How about RequestToID and IDToURL or BuildID and BuildURL or MapID and MapURL. The argument signature is revealing to the purpose and can take some of the burden of the name.

A bit different topic: Can you provide an example of what your URLs look like which cannot be used with the current tusd version?

My application lets the end user define the url path hierarchy so I can't provide a real example. Here are some examples of possible hierarchy schemes:

Automatically routed based on user credential: Request: POST /upload Response: Location: /user/data/filename

A url scheme for concatenated uploads: Request: POST /user/data/ Response: Location: /user/data/filename/1 Request: POST /user/data/ Response: Location: /user/data/filename/2

A 1:1 filesystem to url mapping that handles many many uploads: Request POST /uploads/ Response: Location: /uploads/fi/le/filename

innovate-invent avatar Jan 09 '20 17:01 innovate-invent

@Acconut Do you mind providing some more feedback on the proposed method names?

innovate-invent avatar Apr 09 '20 16:04 innovate-invent

Thanks for reminding me about this PR, @innovate-invent!

How about RequestToID and IDToURL or BuildID and BuildURL or MapID and MapURL. The argument signature is revealing to the purpose and can take some of the burden of the name.

I am a fan of descriptive method name and don't shy away from long names if necessary ;) What about ExtractID and GenerateUploadURL?

My application lets the end user define the url path hierarchy so I can't provide a real example. Here are some examples of possible hierarchy schemes:

Thanks for the example. However, in that case wouldn't it be better to add a middleware in front of the tusd handler tor rewrite URL? This has the benefit that you could possibly extract user information etc from the URL. With your proposed configurations, it would not be possible to forward this information to the end application, would it?

Acconut avatar May 01 '20 14:05 Acconut

Thanks for the example. However, in that case wouldn't it be better to add a middleware in front of the tusd handler tor rewrite URL? This has the benefit that you could possibly extract user information etc from the URL. With your proposed configurations, it would not be possible to forward this information to the end application, would it?

The end user provides the ExtractID and GenerateUploadURL callbacks, giving them full control over the urls. Using middleware could be a solution, although I feel it is a good idea to retain these callbacks. Hardcoded paths (or path schemes) are never a good idea, even if they are internal.

I will try and update the function names this weekend.

innovate-invent avatar May 01 '20 17:05 innovate-invent

Since this PR was opened, a few things have changed which might make this PR not needed anymore:

  • With tusd v2, hooks have the ability to change the upload ID.
  • With https://github.com/tus/tusd/pull/1020, upload IDs will be able to contain slashes.
  • In a future PR, we want to decouple the upload ID from the file path in the destination store.

Combining these changes should allow users to freely modify the upload URL however they like without the need for callback to translate between the URL and upload IDs. Let me know if there is still a need for this.

Acconut avatar Jan 25 '24 11:01 Acconut