-
Notifications
You must be signed in to change notification settings - Fork 16
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
Adding extension for attachments #7
base: master
Are you sure you want to change the base?
Changes from 22 commits
f02c935
b391e7c
0eced3d
e3b92e8
63b03e3
e93235b
6dda53c
c3b93a9
039d474
69a8356
c2e5850
1be8395
520087b
9a7552d
e1e5030
d0938f3
fb64e28
51c14a0
0bfb4cc
408f82c
a981729
a2c0630
6a8f54d
721d14a
e93abb5
2215c4d
f6417da
bcd8749
8fc28a1
982693c
bcc4eef
b30afd3
097cc05
638e034
226dda9
0ed24f4
ac7a3bd
b2289c0
98976f5
68a46e2
b77b683
afd4a7f
1c50b87
ced21ae
9551375
ca93e81
09f24dc
b069860
82720a7
db25065
e22accb
b74332d
96eddfc
154886b
f49e75a
9bb8c4b
06868bb
6a79d1b
3a949cd
b87e14e
4b2c6ac
a39f626
b8179bb
7446176
e054a5b
688db86
d233882
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
# Attachment extension | ||
This document outlines an extension which supports sending and receiving collection+json documents containing file attachments. This approach uses a multipart/form-data request / multipart/mixed response as a means of transfering attachments back and forth. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. drop reference to multipart/mixed. |
||
|
||
*Note*: Each of the examples below is based on the existing CJ friends [example](http://amundsen.com/media-types/collection/examples/). | ||
|
||
It is inspired by this [discussion](https://groups.google.com/forum/#!topic/collectionjson/pzdkNGx-aPE) | ||
|
||
The following RFCs form the basis of the approach in this document: | ||
|
||
* [1341] (http://www.w3.org/Protocols/rfc1341/7_2_Multipart.html) - The Multipart Content-Type | ||
* [2388] (http://tools.ietf.org/html/rfc2388) - Returning Values from Forms: multipart/form-data | ||
* [6266] (http://tools.ietf.org/html/rfc6266) - Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP) | ||
|
||
## Write template | ||
A client may receive a CollectionJson document containing a Write template which accepts attachments which the client can use to send files. | ||
|
||
### Attachment field | ||
A new _attachment_ field is introduced on the data element. For a template, this indicates that this data element is an attachment. The value of the attachment is the mime type that is expected. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @glennblock : what if more than one mime type is possible? what if any type is possible? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For multiple mime types how about accepting a delimited list? This then raises a question of ranges like "image/*". As I think more through this you should probably be allowed to pass a delimited list of media types or ranges. As for any type, if we accept ranges like "*" that would allow that. |
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. drop the above two lines as they are covered in the previous mods, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add a line defining the new value for the existing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The attachment property is only for templates so why do I need to even mention this? If there's no attachment property by default it would just be treated as a standard template prop. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. actually, it should read: "if the this is to cover future cases where there may be other values for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So you mean in the cases where contentType is present and set to On Wednesday, October 15, 2014, Mike Amundsen [email protected]
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yep, that's one case. or somehow in the future There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. content looks good to me. there are some typo/spelling nits:
there may be others. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, I'll fix that. I added these guidelines, which the RFC alone doesn't cover. Some key points to remember in the context of Collection+JSON:
On Wed, Oct 15, 2014 at 10:02 PM, Mike Amundsen [email protected]
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK just copied into Word and did a big spell/grammar check and fixed all
Also I now use Collection+JSON once at the beginning and then CJ everywhere On Wed, Oct 15, 2014 at 10:02 PM, Mike Amundsen [email protected]
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for the Write Template section[0]
If you want to talk about body parts, I think you need to identify them in for the Multipart Requests section[1]
[0] There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, I've made the edits (I think). I've added a specific reference to [1] - On Wed, Oct 15, 2014 at 11:40 PM, Mike Amundsen [email protected]
|
||
### Example | ||
```javascript | ||
{ | ||
"template" : { | ||
"data" : [ | ||
{"name" : "full-name", "value" : ""}, | ||
{"name" : "email", "value" : ""}, | ||
{"name" : "avatar", "attachment": "image/jpeg"} | ||
] | ||
} | ||
} | ||
``` | ||
## Sending attachments | ||
A client may send a request that contains attachments using the media type "multipart/form-data". It contains the data for the write template as well as attachments. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @glennblock : maybe we should add content-type or enc-type (from HTML.FORM) to the template properties instead of having the client scan the list of items to find an "attachment" property on one (or more) of the data elements. not sure of this as it opens up the possibility of other enc-types (which might be a good idea, but is out-of-scope for your extension). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm, but a template could contain multiple attachments, each one tied to a specific data element. Also things like "prompt" etc are completely relevant. |
||
|
||
### Parts | ||
* All _attachment_ fields in the data element must have a corresponding part. | ||
* The part must have a name matching the form element name. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i don't understand any of this "Parts" section. what is a Part? where is it in the example? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A multipart request consists of mulitple parts. The document is a part and the attachment is a part. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added the wording of "Body Part" to make it more explicit. Both "part" and "body part" are used in the RFC. |
||
### Example | ||
Below you can can see the request contains a write template with contact information. The template contains an avatar _attachment_ item with the value of the attachment being 'jdoe'. There is an additional part which contains the avatar image which has a _name_ of 'jdoe' | ||
``` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think the text refers to the template example above as well as the HTTP payload below, right? please move text around as needed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
content-type: multipart/form-data, boundary=AaB03x | ||
|
||
--AaB03x | ||
content-disposition: form-data; name="full-name" | ||
content-type: text/plain; charset=us-ascii | ||
John Doe | ||
--AaB03x | ||
content-disposition: form-data; name="email" | ||
content-type: text/plain; charset=us-ascii | ||
[email protected] | ||
--AaB03x | ||
content-disposition: form-data; name="avatar" | ||
content-type: image/jpeg | ||
... | ||
--AaB03x | ||
``` | ||
## Receving attachments | ||
A client may also receive a response that contains attachments. In these cases the response media type will be "multipart/mixed" containing parts for a collection+json document as well as attachments. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @glennblock: responding w/ multipart/mixed is likely to break existing Cj clients that know nothing about this extension. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, so how about this?
For the non multipart response, another option is to have a link or something at the doc level that indicates it has attachments. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think something odd is going on here. why return a collection as On Sun, Oct 12, 2014 at 2:04 PM, Glenn Block [email protected]
|
||
|
||
### Parts | ||
* The first part in the document will be a CollectionJson document. The document will contain pointers back to the attachments in the response. | ||
* All _attachment_ fields in the data element must have a value set to the name in the content-disposition header of the corresponding part. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what happens when two items have a filename w/ the same name value (but different images) e.g. each user uploads a file named "myavatar.png" into their own private folders. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a good question. One way to handle this would be to add "Name" as a property of the disposition header. This way the name can be unique, but the filenames are the same. I originally had this but removed it as it seemed redundant. Open to ideas here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. how is this handled in HTML and the RFC's you mention. surely this is On Sun, Oct 12, 2014 at 2:10 PM, Glenn Block [email protected]
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't see anything, however if we drop multipart/mixed then the issue goes away. |
||
* The document part must have a "name" of "document" as it's content-disposition header | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i don't see this in the example below. am i missing something? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is deprecated. I'll remove it. It is no longer necessary. The only thing necessary is making sure the first part is a document. |
||
* All additional parts will be attachments which relate to the document. | ||
* Each attachment must have a "name" as part of the content-disposition header. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @glennblock: i don't see this in the example below, either. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be filename. I will fix. |
||
|
||
### Attachment Data field | ||
The _attachment_ field in the response indicates that this item has an associated attachment. The _value_ of the attachment matches the filename in the content-disposition header in one of the parts. | ||
|
||
### Example | ||
Below is an example of a response containing attachments. The first part is a document which contains the list of contacts where each contact has an avatar with an _attachment_ field. Then there are additional parts which are the actual attachments. Each attachment's filename corresponds to the value of the _attachment_ field for the item in the CollectionJson document. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @glennblock When does the client make an "attachment response" request? how does it know to change the accept header to "multipart/mixed"? or even know that a multipart/mixed is coming? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we go with my suggestion that I just made, the client would know if they get a standard CJ response that has "attachment" fields. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not a fan of having to "look inside" in order to sort out content-type in fact, why are we offering up a Cj collection as a multipart at all? seems what most client would expect would be a Cj collection response with On Sun, Oct 12, 2014 at 2:12 PM, Glenn Block [email protected]
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well I as offering up multipart to allow returning attachments using the standard attachment mechanism of HTTP. However I see your point. Having a link with a render="attachment" may work fine. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another idea would be using rel="enclosure" from atom. "The value "enclosure" signifies that the IRI in the value of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe "download" is the right word for render="" in the responses. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @glennblock : this text needs to be updated to match the changes in the representation (e.g. link attachments). |
||
|
||
``` | ||
content-type: multipart/mixed, boundary=AaB03x | ||
|
||
--AaB03x | ||
content-type: application/vnd.collection+json | ||
{ "collection" : | ||
{ | ||
"version" : "1.0", | ||
"href" : "http://example.org/friends/", | ||
|
||
"items" : [ | ||
{ | ||
"href" : "http://example.org/friends/jdoe", | ||
"data" : [ | ||
{"name" : "full-name", "value" : "John Doe", "prompt" : "Full Name"}, | ||
{"name" : "email", "value" : "[email protected]", "prompt" : "Email"} | ||
{"name" : "avatar", "attachment" : "jdoe.jpg"} | ||
] | ||
}, | ||
{ | ||
"href" : "http://example.org/friends/mamund", | ||
"data" : [ | ||
{"name" : "full-name", "value" : "Mike Amundsen", "prompt" : "Full Name"}, | ||
{"name" : "email", "value" : "[email protected]", "prompt" : "Email"} | ||
{"name" : "avatar", "attachment" : "mamund.jpg"} | ||
] | ||
} | ||
} | ||
} | ||
} | ||
--AaB03x | ||
content-disposition: attachment; filename="jdoe.jpeg" | ||
content-type: image/jpeg | ||
content-transfer-encoding: binary | ||
... | ||
--AaB03x | ||
content-disposition: attachment; filename="mamund.jpeg" | ||
content-type: image/jpeg | ||
content-transfer-Encoding: binary | ||
... | ||
--AaB03x | ||
``` | ||
|
||
To see a gist with real server response with attachments go [here] (https://gist.github.com/glennblock/8db0d1facb69af67af16). You can also hit a live version [here] (http://cj-attachment.azurewebsites.net/friend) with a tool like Fiddler or using curl: `curl http://cj-attachment.azurewebsites.net/friend -v` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i'd add this to the content near the top that points to the cj thread and RFCs. a kind of "cut to the chase and look at the running code first" kind of thing. just a nit ;) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK done. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
very small nit. I'd like to use the abbreviation for collection+json as Cj, not CJ