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

Define custom headers for external content requests #338

Closed
zimeon opened this issue Mar 7, 2018 · 14 comments

Comments

Projects
None yet
4 participants
@zimeon
Copy link
Contributor

commented Mar 7, 2018

After much back and forth discussion has again come around to consideration of custom headers in order to support our community-specific use-cases of creation-by-reference and proxying (replacing use of Content-type: message/external-body...). A proposal based on recent discussions:

Fedora servers SHOULD support POST or PUT requests to create or update LDP-NRs where the content not the request entity, but is instead to be retrieved from the location specified in the External-Content header. A Prefer header with value external-content-handling=MODE where MODE is one of proxy, copy, or redirect is used to specify how the content is to be handled. Thus an example request might have headers:

External-Content: <some-URI>; content-type=<some-content-type>
Prefer: external-content-handling=<copy|redirect|proxy>

Fedora servers that support External-Content requests MUST advertise the supported handling modes with the Accept-External-Content-Handling: <proxy|copy|redirect> header in response to an OPTIONS request.

Fedora servers that support External-Content requests MUST treat the content-type= parameter of the request in the same way that they would treat the Content-Type header of a similar request with content in the request entity.

Fedora servers receiving requests that would create or update an LDP-NR with External-Content and an unsupported mode MUST be reject the request with 415 (Unsupported Media Type).

Issues/points:

  • We need to define expectations for proxy, copy, and redirect handling.
  • What is expected or required behavior in response to an External-Content with no Prefer: external-content-handling=MODE header?
  • Presumably also use the same mechanism for Replacing Contents from Mementos which might then include LDP-RS as well as LDP-NR
  • We'd expect support for http(s) and file URIs for remote and local content respectively. Could a server advertise which is supported? What should response be to a request with an unsupported scheme?
  • This would be an extension of prefer headers. There is no experimental or unregistered space defined by rfc7240 or listed in the IANA registry
@zimeon

This comment has been minimized.

Copy link
Contributor Author

commented Mar 7, 2018

Input was taken from https://docs.google.com/document/d/1tGIX3XxU3km2kshgvrU5BOcLomwDKt5Oi0vPZJRB1Vc/edit and there were several comments in support of using a custom header (though not necessarily the proposal above):

  • Mike Durbin, 1:52 PM Mar 1: This whole controversy seems to be around using and "misusing" other standards. Forgive my ignorance here, but if there's no standard that unambiguously supports functionality we want, why not use our own custom header?
  • Jared Whiklo,1:56 PM Mar 1: that's too easy?
  • Aaron Birkland, 2:09 PM Mar 1: LOL, I'd see a custom header acceptable and straightforward.
  • Bethany Seeger, 2:10 PM Mar 1: +1 to that
  • Benjamin Pennell, 3:28 PM Mar: yes, I agree
  • Andrew Woods, 6:57 PM Mar 1: Since there is almost zero chance that a non-Fedora-aware client would use any of the headers defined below in a way that Fedora is specifying... using a simpler, Fedora-defined header could be reasonable.
  • Simeon Warner, 7:50 PM Mar 1: Having today been writing objections to the use of Accept-Post with these faux "media types" (#308), I'm open to considering a custom header
  • Danny Lamb, 10:27 AM Yesterday: +1 Custom header sounds better than pushing a square peg through a round hole.

@zimeon zimeon added this to the Recommendation milestone Mar 7, 2018

@escowles

This comment has been minimized.

Copy link
Contributor

commented Mar 8, 2018

What is expected or required behavior in response to an External-Content with no Prefer: external-content-handling=MODE header?

Since Prefer headers do not need to be honored, I would expect the response to include a Preference-Applied header indicating the mode, either to confirm that the preference was applied successfully, or to indicate that the server chose to do something else (including its default mode if none was requested).

@zimeon

This comment has been minimized.

Copy link
Contributor Author

commented Mar 8, 2018

My assumption would be that a server never sends a Preference-Applied header unless it has followed a Prefer header in the request. Thus I would not expect to see any Preference-Applied in the response to a request without a Prefer, nor would I expect to see a Preference-Applied in the case that a requested Prefer was not honored. This is how I read RFC7240:

The Preference-Applied response header MAY be included within a response message as an indication as to which Prefer tokens were honored by the server and applied to the processing of a request.

@escowles

This comment has been minimized.

Copy link
Contributor

commented Mar 8, 2018

If the impl. doesn't send a Preference-Applied header, I'm not sure how the client would know what happened. Maybe a HEAD request would include Link headers or something that indicated which mode was used?

@zimeon

This comment has been minimized.

Copy link
Contributor Author

commented Mar 8, 2018

Well, we could specify that if an implementation does anything other than normal creation/update, it MUST send the appropriate Preference-Applied in the response -- but I think we'd have to be explicit about that as it isn't what RFC7240 says.

We might also want to specify an ongoing "proxy mode" indication in a Link header in HEAD/GET that should be present for anything that is proxied (redirect would be obvious, copied makes no lasting difference).

@birkland

This comment has been minimized.

Copy link
Contributor

commented Mar 8, 2018

What is the motivation of embedding Content-Type in the External-Content header? To me, it would be most clear to introduce something like External-Content-Location header, whose sole purpose and semantics are to indicate the location of external content. Then we have other orthogonal concerns handled by other headers: Content-Type for conveying the content type of the (external) content, and Prefer for specifying behavior.

Something like this would express external content, with a redirect preference:

POST /path/to/Resource
Content-Type:  image/jpeg
External-Content-Location:  http://uri/of/external/content
Prefer: external-content-handling=redirect

Something like this would not express a preference of handling, but does specify an external content location. The server can do whatever it wants, but probably SHOULD copy, behaving "as if the external content had instead been provided in the entity body"

POST /path/to/Resource
Content-Type: image/jpeg
External-Content-Location:  http://uri/of//external/content

Requiring the server to always respond with a Preference-Applied with regard to external content would be fine, and rather explicit/clear

@birkland

This comment has been minimized.

Copy link
Contributor

commented Mar 8, 2018

Just updating with some discussion on the fedora tech call. @dannylamb relayed some of the concerns with Content-Type, and mentioned the alternative of using Link headers to External-Content-Location. The folks who stuck around after the call liked:

For specifying location and Content-Type:

Link: <some-URI>; rel=external-content; type=image/jpeg

For specifying that the client wants the server to process the request as external content in the first place, and how:

Prefer: external-content-handling=<copy|redirect|proxy>

There is some confusion about Content-Type, since seemingly there are two places a client could put it. (as a header vs link. must they leave the header blank?). It was recommended that the spec define an order of preference. On the table at the tech call was that the server:

  1. MUST use the type from the external-content link, if provided
  2. MUST use the Content-Type header if provided if none has been provided in the external content link
  3. MAY try to use the Content-Type implied from the source URI and associated protocols (e.g. look at http headers sent by the remote header, for http)
  4. MAY reject the request, or use a default if it can't be determined otherwise.
@whikloj

This comment has been minimized.

Copy link
Contributor

commented Mar 8, 2018

I like the Link header suggestion.

To not narrow our implementation base too much I would suggest that we change the MUST to MAY in 2 above.

  1. MAY use the Content-type header if provided if none has been provided in the external-content link.

Basically if you get the Link header with the rel=external-content it should provide the type parameter, otherwise the server has the right to reject your request.

@zimeon

This comment has been minimized.

Copy link
Contributor Author

commented Mar 8, 2018

@birkland - A reason for not using Content-Type is the worry that it is worse to repurpose an existing header (changing meaning from "this is the media type of the content of this message") leading to a great erchance of odd/unexpected behavior in case of client/server mismatch. If folks think this is OK then it is very tidy to reuse Content-Type. We can use words as you've suggested above to clarify the new meaning.

@birkland @whikloj - I think that using Link would be a very odd twist on the established semantics of Link. To me the idea of "here is a link to something related to this resource or content in this request" just seems too different from "the content is over here rather than in the request". I do appreciate that syntactically one can stuff everything we need in there, but semantically it seems awkward or bad.

@whikloj

This comment has been minimized.

Copy link
Contributor

commented Mar 8, 2018

@zimeon When I went to look at RFC 5988 (which I hope is the right one) and read the sentence.

A link can be viewed as a statement of the form "{context IRI} has a
{relation type} resource at {target IRI}, which has {target
attributes}".

under 3. Links I felt that:

"<this object> has a <external-content> resource at <some-external-URI>, which has <type=mime-type>"

I thought that was workable.

@whikloj

This comment has been minimized.

Copy link
Contributor

commented Mar 8, 2018

@zimeon But I'd be okay with the custom header too.

@zimeon

This comment has been minimized.

Copy link
Contributor Author

commented Mar 8, 2018

Thank you @whikloj for your patience and restatement... I've come round to your viewpoint. I think I have been too hung up on the copy semantics. If I think more in terms of proxy|redirect, where the <some-external-URI> content remains in play after the request is complete, Link makes more sense. I can see in parallel:

<this-object> has a <semantic-type> resource at <LDP-NR-class>
<this-object> has a <semantic-type> resource at <Memento-Original-Resource-class>
<this-object> has a <external-content> resource at <some-external-URI>, which has <type=mime-type>

Per RFC8288 (with replaces RFC 5988) the link relation should be a URI unless we intend to register it will IANA, so then we'd have:

Link: <some-URI>; rel="http://fedora.info/definitions/fcrepo#external-content"; type="image/jpeg"
Prefer: external-content-handling=<copy|redirect|proxy>

(there is no extension mechanism specified for Prefer except for IANA registration, and a URI is not allowed as the token in Prefer: token because, per RFC7230, token MUST NOT include delimiters such as / and :)

@escowles

This comment has been minimized.

Copy link
Contributor

commented Mar 14, 2018

Summary of today's editors' discussion:

  • We don't think that Prefer is the right fit, because clients typically know what handling they want and would rather have a failure than e.g., copying the remote content
  • Advertising the handling modes supported in OPTIONS responses gives the client enough information to know what the options are and plan accordingly
  • So adding a required handling parameter to the Link header allows the client to specify the handling, and get a 4xx response if the server cannot support it
@zimeon

This comment has been minimized.

Copy link
Contributor Author

commented Mar 14, 2018

Current PR to address this issue is #343 (was closed accidentally)

@zimeon zimeon reopened this Mar 14, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.