Abstract
Remove all but Atom Collections. Simplify everything by introducing a simple search via URI template.
Status
Open (JoeGregorio)
Rationale
Introducing Search into the APP, and mandating that the results of the search requests be Atom Feeds allows the APP to be vastly simplified. This Pace does that simplification.
The Pace drops the Introspection document, leaving that for another specification.
The Pace simplfies the protocol by only supporting one Collection type, one that allows only Atom Entries. Collections that allow a certain type of Entry, 'generic' to create Generic Resources, which gives us the same functionality as Generic Collections. This mechanism has several advantages:
-
It allows setting meta-data for a non-Entry resource. (title, summary, etc. for pictures)
-
It allows setting pub:control properties for a non-Entry resource. (Now that picture can be marked as 'draft').
-
The initial POST to create an entry for a non-Entry resource such as a video or image is much smaller. Sure we still have the problem of a POST failing and not knowing if the Entry was really created, but at least that doesn't happen after we have uploaded 99% of a 57MB video file.
-
The server returns in the Entry a URI for the client to PUT the video or image to. PUT is idempotent so that if the upload fails then the client can just try again. We avoid the ambiguity of doing a POST and not knowing if the request succeeded and whether or not to do another POST.
The 'types' of entries that can be used in a collection is extensible and tracked in a IANA registry. That list isn't necessarily fixed and I am open to dropping/modifying 'text', 'html' and 'xhtml', and 'src', though the 'generic' type needs to be there to enable the equivalent functionality of Generic Collections.
The registry of 'types' is also useful for creating more specific collections in the future. For example, an 'hcalendar' type could be registered and the could mean that the collection is expecting Atom Entries that have only XHTML content that contains an hCalendar formatted microformat.
The Pace adds Search Resources which implement A9 OpenSearch style parametrized search URIs. The search parameters are restricted to date ranges and index ranges. The current spec has date queries but they are buried in a header and are not extensible. The use of the 'next' attribute in the current spec almost forces the server to implement indexes which I found out when implementing. Again, the search interface just takes that functionality, puts it in a common mechanism with date queries, and allows for future extensions.
Changes since first proposal
Extended Section 7.3 to clarify how to DELETE Generic Resources.
Used a 'special' URI in atom:content@src to indicate the request to create a Generic Resource. That's because src="" would conflict with xml:base handling.
Fixed examples to use the correct format for daterange.
Proposal
Add the following definitions to Section 3.
Entry Resource - A resource whose representation is an Atom Entry. Generic Resource - A resource whose representation is not an Atom Entry, such as an image (image/png).
The Atom Publishing Protocol operates on collections of Web resources. All collections support the same basic interactions, as do the resources within the collections. The patterns of interaction are based on the common HTTP verbs. * GET is used to retrieve a representation of a resource or perform a read-only query. * POST is used to create a new, dynamically-named resource. * PUT is used to update a known resource. * DELETE is used to remove a resource. 4.1 Editable Resources An Editable resource is a resouce that can be edited via the HTTP methods GET, PUT and DELETE. 4.1.1 Read Client Server | | | 1.) GET or HEAD to Editable Resource URI | |------------------------------------------>| | | | 2.) 200 OK | |<------------------------------------------| | | 1. The client sends a GET (or HEAD) request to the member's URI. 2. The server responds with the represenation of the resource. 4.1.2 Update Client Server | | | 1.) PUT to Editable Resource URI | |------------------------------------------>| | | | 2.) 200 OK | |<------------------------------------------| 1. The client PUTs an updated representation to the member's URI. 2. The server MAY respond with an updated representation of the member's new state. 4.1.3 Delete Client Server | | | 1.) DELETE to Editable Resource URI | |------------------------------------------>| | | | 2.) 200 Ok | |<------------------------------------------| | | 1. The client sends a DELETE request to the member's URI. 2. The server responds with successful status code. 4.2 Collections The APP groups Editable Resources with representations in Atom Entry Format into "Collections", which are analogous to the "folders" or "directories" found in many file systems. All Editable Resources that are members of a Collection have representations as Atom Entries. 4.3 Introspection To discover the capabilities of a Collection Resource, the client GET's the Collection Document from the Collection. Client Server | | | 1.) GET to Collection Resource | |--------------------------------->| | | | 2.) Collection Document | |<---------------------------------| | | 1. The client sends a GET request to the Collection Resource. 2. The server responds with an Collection Document containing a description of the capabilities of the collection. The content of this document can vary based on aspects of the client request, including, but not limited to, authentication credentials. 4.4 Listing Clients can request a listing of the collection's membership. Enumerating the Editable Resources that are members of a collection is done using one of the Search Resources listing in the Introspection Document. The Search Resource returns Atom Feed Documents with all the Entries that match the search criteria. Client Server | | | 1.) GET to Search Resource | |------------------------------->| | | | 2.) 200 OK, Atom Feed Doc | |<-------------------------------| | | 1. The client sends a GET request to the Collection's URI. 2. The server responds with an Atom Feed Document containing a full or partial listing of the collection's membership. 4.5 Authoring A client can add new Entries to a Collection by sending a request to the collection; other changes are accomplished by sending HTTP requests to the Editable Member resources. 4.5.1 Create Client Server | | | 1.) POST to Collection URI | |------------------------------->| | | | 2.) 201 Created @ Location | |<-------------------------------| | | 1. The client sends an Atom Entry Document to the server via HTTP POST. The Request URI is that of the Collection Resource. 2. The server responds with a response of "201 Created" and a "Location" header containing the URI of the newly-created resource. 4.5.2 Editing Member Resources Members of Collections are Editable Resources and are edited following the patterns in Section 4.1.
Section 4.5 "Success and Failure" Remains unchanged. (Except it is now Section 4.6)
Section 5 Collection Document The Collection Document describes the capabilites of a Collection, the types of Entries that it will accept, the types of searching it supports, etc. The Collection Document has the media-type 'application/atomcoll+xml', see Section 11 <collection xmlns="http://purl.org/atom/app"> <member-type>text</member-type> <member-type>html</member-type> <member-type>xhtml</member-type> <member-type>src</member-type> <member-type>generic</member-type> <search-template>http://example.org/{index}</search-template> <search-template>http://example.org/d/{daterange}</search-template> </collection> 5.1 The 'app:collection' Element The "collection" element is the document element of an Collection Document, acting as a container for service data associated with one Collection. appService = element app:collection { ( appMemberType* appSearchTemplate & anyElement* ) } The following child elements are defined by this specification: * app:collection elements MAY contain any number of app:member-type elements. * app:collection elements MAY contain any number of app:search-template elements. 5.2 The 'app:member-type' Element The 'member-type' element element contains information elements about the types of Entries that the Collection may contain. appMemberType = element app:member-type { appTypeValue } The value of appTypeValue MUST be a string that is non-empty, and matches either the "isegment-nz-nc" or the "IRI" production in [RFC3987]. Note that use of a relative reference other than a simple name is not allowed. If a name is given, implementations MUST consider the link relation type to be equivalent to the same name registered within the IANA Registry of Link Relations Section 12, and thus the IRI that would be obtained by appending the value of the rel attribute to the string "http://www.iana.org/assignments/entrytype/". The value of appTypeValue specifies constraints on the Entries that may appear in the Collection. The app:collection element may have multiple app:member-type elements. An Entry POSTed to a Collection MUST meet the constaints of at least one of the app:member-type constraints. It MAY meet more than one, but the mimimum requirement is at least one. This specification defines four initial values for app:member-type IANA registry: "text" - All Text Constructs and app:content in the entry must have a type of 'text'. "html" - All Text Constructs and app:content in the entry must have a type of 'html'. "xhtml" - All Text Constructs and app:content in the entry must have a type of 'xhtml'. "src" - The atom:content element must have a non-empty src attribute. "generic" - The Text Constructs in the entry must have a type of 'text'. The atom:content MUST be empty and MUST include a src="" attribute. See Section 7.3 for the special processing requirements of "generic" type Entries. 5.3 The 'app:search-template' Element The 'app:search-template' element describes searching capabilites. The content of the app:search-template element is a URI Template of a Search Resource (See Section 6). Every search resource, whose URI is determined by filling in the variables in a URI Template, MUST return an Atom Feed as it's representation. The Atom Feed MUST be filled with entries that match the search critera. Section 6 Search Resources Search resources are resources that are identified by URI Templates. They MUST return Atom Feed Documents as their representation, and unless otherwise stated the entries in the document must be ordered by their atom:updated property, with the most recently updated entries coming first in the document. Section 6.1 URI Templates URI Templates are a mechanisms for allowing queries using HTTP URIs. By itself a URI Template is not a valid URI. Instead there are multiple parameters embedded in the URI and distinguised by closing braces. For example: htpp://example.org/blog/edit/{index} or http://example.org/blog/{daterange} The value of each app:search-template element is a template of the URI for a Search Resource. 1. The variables in the template are enclosed in unescaped braces '{' and '}'. 1. With the exception of the variable names and their enclosing braces, the template URI MUST be properly escaped. 1. The character encoding of the template URI, and of the URI after the template is filled in, MUST be utf-8. Each URI template has one or more variables that must be substituted with the values of the named variables to construct a valid URI. 1. Substitute the brace-delimited variable, and the surrounding braces, for the desired value of that variable, ensuring that the value is also properly percent-encoded utf-8. For example, given the URI template: htpp://example.org/blog/edit/{index} and if the client wants the first 15 entries in the collection it would substitute '1-15' for {index} giving: htpp://example.org/blog/edit/1-15 Note that the template can appear at any place in the URI template: URI Template | Value of index | Expanded URI ----------------------------------------+------------------+-------------------------------------- http://example.org/{index}/search | 3-27 | http://example.org/3-27/search http://example.org/search?index={index} | 3-27 | http://example.org/search?index=3-27 Section 6.2 URI Template Variables This specification defines two variables that can be used in app:search-template values, called URI Templates. Other specifications MAY define new variables used in URI templates. An Introspection Document MUST contain at least two app:search-template elements. One of those URI Templates MUST contain only a single variable whose name is {index}. The other of the two required URI Templates MUST contain only a single variable whose name is {daterange}. There may be any number of app:search-template elements that contain URI Templates that do not match the two required by this specification. Section 6.2.1 URI Template Variable 'index' A URI Template with the variable 'index' allows querying for entries in a collection using their index when ordered by their 'updated' property. The value of the index variable should be a pair of indices separated by a dash character; either index may be optionally omitted, in which case the range is understood as stretching to infinity on that end. index-specifier = [indexnum] "-" [indexnum] The response to such a search request MUST be an Atom Feed where all the entries fall within the requested range. The request range is considered a closed set, that is, if an entry matches one end of the range exactly it MUST be included in the response. If no members fall in the requested range, the server MUST respond with an Atom Feed containing no entries. Section 6.2.2 URI Template Variable 'daterange' A URI Template with the variable 'daterange' allows querying for entries in a collection using their 'updated' property. The value of the 'daterange' variable should be a pair of iso formatted dates separated by a dash character; either index may be optionally omitted, in which case the range is understood as stretching to infinity on that end. daterange-specifier = [iso-date] "/" [iso-date] The 'iso-date' MUST conform to the "date-time" production in [RFC3339]. In addition, an uppercase "T" character MUST be used to separate date and time, and an uppercase "Z" character MUST be present in the absence of a numeric time zone offset. The response to such a search request MUST be an Atom Feed where all the entries fall within the requested range. The request range is considered a closed set, that is, if an entry matches one end of the range exactly it MUST be included in the response. If no members fall in the requested range, the server MUST respond with an Atom Feed containing no entries. Section 7 Collection Resources This specification defines two HTTP methods for use with collection resources: GET and POST. 7.1 GET Get to a Collection Resource returns a Collection Document. 7.2 POST In addition to GET, a Collection Resource also accepts POST requests. The client POSTs an Atom Entry to the Collection Resource. Note that some collections may impose constraints on the Entries that are created in a Collection. A POST MAY generate a response with a status code of 400 ("Bad Request"). In the case of a successful creation, the status code MUST be 201 ("Created"). Example Request, Create a resource in a collection. POST /collection HTTP/1.1 Host: example.org User-Agent: Cosimo/1.0 Accept: application/atom+xml Content-Type: application/atom+xml Content-Length: nnnn <entry .... ...</entry> Here, the client is adding a new Entry to a collection. Example Response, resource created successfully. HTTP/1.1 201 Created Date: Fri, 25 Mar 2005 17:17:11 GMT Content-Length: nnnn Content-Type: application/atom+xml; charset="utf-8" Location: http://example.org/edit/first-post.atom <?xml version="1.0" encoding="UTF-8"?> <entry ... </entry> Section 7.3 Creation of Generic Resources Even though the protocol only manages collections of Atom Entries, it still has allowances for uploading non-Entry content, for example video and images. The uploading of such content is done by first creating a new Entry in a Collection that allows Entries of type 'generic'. The creation of Entries of type 'generic' has some special handling. The inclusion of a 'src' attribute that is set to 'http://purl.org/atom/app/generic/' indicates to the server that the client is requesting the creation of an Editable Resource for the media that the atom:content refers to. The Editable Resource MUST be of the same mime-type as that the 'type' attribute of atom:content. The URI of the Editable Resource is returned in the Atom Entry in a link element with a rel attribute with a value of 'srcedit' See Section 8.1. Once the Entry is created the non-Atom Entry can be PUT to the URI of the Editable Resource the server just created. Note that this process creates two Editable Resources, the Atom Entry that describes the Generic Resource, and the Generic Resource itself. Both resources are Editable, but only the Atom Entry supports DELETE. That is, the only way to DELETE a Generic Resource is to DELETE it's associated Atom Entry. The Generic Resource MUST NOT support DELETE. The associated Atom Entry MUST support DELETE and deleting it MUST remove the Generic Resource. Section 8 Member Resources Section 8.1 Atom Entry Extensions This specification adds three new values to the Registry of Link Relations. The value of 'collection' signifies that the IRI in the value of the href is the Collection that this Entry belongs to. The value of 'edit' signifies that the IRI in the value of the href attribute identifies the resource that is used to edit the entry. That is, it is the URI of the Entry as an Editable Resource. The value of 'srcedit' signifies that the IRI in the value of the href attribute identifies the resource that is used to edit the resource pointed to by the 'src' attribute of the atom:content element. That is, it is the URI of the atom:content@src as an Editable Resource. If the "srcedit" attribute is not given, it's value defaults to the "src" attribute of the content element. If the "srcedit" link is present, and it's value is an empty string, then there is no URI that can be treated in the way such a value would be treated. Clients SHOULD use the "srcedit" value to manipulate the resource within the context of the APP itself. Clients SHOULD prefer the "atom:content@src" value in any other context. For example, if the resource is an image, a client may replace the image data using a PUT on the "srcedit" value, and may even display a preview of the image by fetching the "srcedit" URI. But when creating a public, read-only reference to the same image resource, the client should use the "atom:content@src" value. Section 8.2 Role of Atom Entry Elements During Editing The elements of an Atom Entry Document are either a 'Writable Element' or a 'Round Trip Element'. Writable Element - An element of an Atom Entry whose value is editable by the client and not enforced by the server. Round Trip Element - An element of an Atom Entry whose value is enforced by the server and not editable by the client. That categorization will determine the elements' disposition during editing. +--------------------+------------+ | Atom Entry Element | Property | +--------------------+------------+ | atom:author | Writable | | | | | atom:category | Writable | | | | | atom:content | Writable | | | | | atom:contributor | Writable | | | | | atom:id | Round Trip | | | | | atom:link | *See Below | | | | | atom:published | Writable | | | | | atom:source | Writable | | | | | atom:summary | Writable | | | | | atom:title | Writable | | | | | atom:updated | Round Trip | +--------------------+------------+ The atom:link elements are Writable unless they have the link relation of 'edit' or 'srcedit'. For the values of 'edit' and 'srcedit' the atom:link elements are of type Round Trip. Section 9 Examples Section 9.1 Simple Create Here is an example of creating a simple entry. In this example the client begins with only the URI of the Collection Resource, which is: http://example.org/app/ The Entry that we wish to use to create a new resource with is: <?xml version="1.0" encoding="utf-8"?> <entry xmlns="http://www.w3.org/2005/Atom"> <title>Atom-Powered Robots Run Amok</title> <updated>2003-12-13T18:30:02Z</updated> <summary>Some text.</summary> <content type="xhtml" xml:lang="en" xml:base="http://example.org/"> <div xmlns="http://www.w3.org/1999/xhtml"> <p><i>Film at eleven.</i></p> </div> </content> </entry> As you can see this Entry has a atom:content@type of 'xhtml'. First the client retrieves the Collection Document finds out if the Collection can support this type of Entry. To retrieve the Collection Document it does a GET on the Collection Resource URI: GET /app/ HTTP/1.1 Host: example.org User-Agent: Agent/1.0 Accept: application/atomcoll+xml The Collection returns a representation the enumerates it's capabilities. HTTP/1.1 200 OK Date: Fri, 25 Mar 2005 17:15:33 GMT Last-Modified: Mon, 04 Oct 2004 18:31:45 GMT ETag: "2b3f6-a4-5b572640" Content-Type: application/atomcoll+xml; charset="utf-8" <?xml version="1.0" encoding="utf-8"?> <collection xmlns="http://purl.org/atom/app/"> <member-type>text</member-type> <member-type>html</member-type> <member-type>xhtml</member-type> <search-template>http://example.org/si/{index}</search-template> <search-template>http://example.org/bydate.cgi?{daterange}</search-template> </collection> The client finds an app:member-type element with a value of 'xhtml' so it knows that the Collection can indeed support the type of Entry it is trying to create. The client POSTs the Entry to the Collection Resource URI: POST /app/ HTTP/1.1 Host: example.org User-Agent: Cosimo/1.0 Accept: application/atom+xml Content-Type: application/atom+xml Content-Length: nnnn <?xml version="1.0" encoding="utf-8"?> <entry xmlns="http://www.w3.org/2005/Atom"> <title>Atom-Powered Robots Run Amok</title> <updated>2003-12-13T18:30:02Z</updated> <summary>Some text.</summary> <content type="xhtml" xml:lang="en" xml:base="http://example.org/"> <div xmlns="http://www.w3.org/1999/xhtml"> <p><i>Film at eleven.</i></p> </div> </content> </entry> If the resource is created successfully the response might be: HTTP/1.1 201 Created Date: Fri, 25 Mar 2005 17:17:11 GMT Content-Length: nnnn Content-Type: application/atom+xml; charset="utf-8" Location: http://example.org/app/876 <?xml version="1.0" encoding="utf-8"?> <entry xmlns="http://www.w3.org/2005/Atom"> <title>Atom-Powered Robots Run Amok</title> <link href="http://example.org/2003/12/13/atom-powered-robots-run-amok.html"/> <link rel="edit" href="http://example.org/app/876"/> <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id> <updated>2003-12-13T18:30:02Z</updated> <summary>Some text.</summary> <content type="xhtml" xml:lang="en" xml:base="http://example.org/"> <div xmlns="http://www.w3.org/1999/xhtml"> <p><i>Film at eleven.</i></p> </div> </content> </entry> Note that the Location: header gives the same value as the link element with a relation of 'edit'. Also note that the server has created an unique atom:id for the entry. Section 9.2 Resynchronization Here is an example of a client requesting all the Entries that have changed since the last time the client synchronized with the server. The last time the client resynchronized from the server was 2003-12-13T18:30:02Z. The client wishes to get all the entries that have been updated since that time. The server returns the following representation for it's Collection Resource: <?xml version="1.0" encoding="utf-8"?> <collection xmlns="http://purl.org/atom/app/"> <member-type>text</member-type> <member-type>html</member-type> <member-type>xhtml</member-type> <search-template>http://example.org/si/{index}</search-template> <search-template>http://example.org/bydate.cgi?{daterange}</search-template> </collection> We are guaranteed to find at least one 'search-template' that allows us to search by the 'updated' time. That URI in this case is: http://example.org/bydate.cgi?{daterange} We expand the URI Template with our search criteria, which is a query for all entries modified from 2003-12-13T18:30:02Z to now. The URI of that Search Resource is: http://example.org/bydate.cgi?/2003-12-13T18:30:02Z Remember that the first date in the date range is left empty if we want all entries modified until now. The response will be an Atom Feed of all the Entries that meet our criteria: HTTP/1.1 200 OK Date: Fri, 25 Mar 2005 17:15:33 GMT Last-Modified: Sun, 28 Aug 2005 18:31:45 GMT ETag: "23094-2349239-29348" Content-Type: application/atom+xml; charset="utf-8" <?xml version="1.0" encoding="utf-8"?> <feed xmlns="http://www.w3.org/2005/Atom"> <title>Example Feed</title> <link href="http://example.org/"/> <updated>2005-08-28T18:30:02Z</updated> <author> <name>John Doe</name> </author> <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id> ... <entry> <title>False Alarm on the Atom-Powered Robots Thing</title> <link href="http://example.org/2003/12/13/atom-powered-robot-retraction.html"/> <link rel="edit" href="http://example.org/app/877"/> <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-498593458954</id> <updated>2003-12-14T07:59:34Z</updated> <summary>Ooops</summary> <content type="xhtml" xml:lang="en" xml:base="http://example.org/"> <div xmlns="http://www.w3.org/1999/xhtml"> <p><i>What can I say, the Atom menace never materialized.</i></p> </div> </content> </entry> <entry> <title>Atom-Powered Robots Run Amok</title> <link href="http://example.org/2003/12/13/atom-powered-robots-run-amok.html"/> <link rel="edit" href="http://example.org/app/876"/> <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id> <updated>2003-12-13T18:30:02Z</updated> <summary>Some text.</summary> <content type="xhtml" xml:lang="en" xml:base="http://example.org/"> <div xmlns="http://www.w3.org/1999/xhtml"> <p><i>Film at eleven.</i></p> </div> </content> </entry> </feed> Section 9.3 Compound Entry An example of creating a new entry with an inline image. That is, the client has an image it must publish and an entry that includes an HTML 'img' element that uses that image. In this scenario we consider a client that has URIs of two Collection Resources. The first collection handles only 'text', 'html' and 'xhtml' entries. The URI of the first collection is: http://example.net/blog/edit/ and it has a Collection representation of: <?xml version="1.0" encoding="utf-8"?> <collection xmlns="http://purl.org/atom/app/"> <member-type>text</member-type> <member-type>html</member-type> <member-type>xhtml</member-type> <search-template>http://example.net/blog/edit/{index}</search-template> <search-template>http://example.net/blog/edit/{daterange}</search-template> </collection> The second collection only handles 'generic' Entries. It has a URI: http://example.net/binary/edit and has a Collection representation of: <?xml version="1.0" encoding="utf-8"?> <collection xmlns="http://purl.org/atom/app/"> <member-type>generic</member-type> <search-template>http://example.net/binary/edit/{index}</search-template> <search-template>http://example.net/binary/edit/{daterange}</search-template> </collection> First the client requests that the server create an Editable Resource for the image by POSTing an entry with an empty atom:content@src attribute to the second collection URI: POST /binary/edit HTTP/1.1 Host: example.net User-Agent: Thingio/1.0 Accept: application/atom+xml Content-Type: application/atom+xml Content-Length: nnnn <?xml version="1.0" encoding="utf-8"?> <entry xmlns="http://www.w3.org/2005/Atom"> <title>A picture of the beach.</title> <updated>2005-09-02T10:30:00Z</updated> <summary>Waves</summary> <content type="image/png" src="http://purl.org/atom/app/generic"/> </entry> If the resource is created successfully the response might be: HTTP/1.1 201 Created Date: Fri, 25 Mar 2005 17:17:11 GMT Content-Length: nnnn Content-Type: application/atom+xml; charset="utf-8" Location: http://example.net/binary/edit/129 <?xml version="1.0" encoding="utf-8"?> <entry xmlns="http://www.w3.org/2005/Atom"> <title>A picture of the beach.</title> <link rel="edit" href="http://example.net/binary/edit/129"/> <link rel="srcedit" href="http://example.net/binary/edit/b/129.png"/> <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-568596895695</id> <updated>2005-09-02T10:30:00Z</updated> <summary>Waves</summary> <content type="image/png" src="http://example.net/binary/readonly/129.png"/> </entry> The URI with a relationship of 'edit' is the Editable Resource used to edit the Atom formatted meta-data about the image. The URI with a relationship of 'srcedit' is the Editable Resource used to edit the actual image. The URI in atom:content@src is the URI of the image that is to be used for publication. The client uses the URI returned in the link with a relationship of 'srcedit' to upload the image to the server: POST /binary/edit/b/129.png HTTP/1.1 Host: example.net User-Agent: Thingio/1.0 Content-Type: image/png Content-Length: nnnn ...binary data... Which returns a 200 on success HTTP/1.1 200 Ok Date: Fri, 25 Mar 2005 18:17:11 GMT Now the last step for the client is to POST the Atom Entry that refers to the newly created image resource to the first Collection Resource. Note that the client takes the URI http://example.net/binary/readonly/129.png and uses it in the 'img' element in the Entry: POST /blog/edit/ HTTP/1.1 Host: example.net User-Agent: Thingio/1.0 Accept: application/atom+xml Content-Type: application/atom+xml Content-Length: nnnn <?xml version="1.0" encoding="utf-8"?> <entry xmlns="http://www.w3.org/2005/Atom"> <title>What I did on my summer vacation</title> <updated>2005-09-02T10:30:00Z</updated> <summary>Beach!</summary> <content type="xhtml" xml:lang="en" xml:base="http://example.org/"> <div xmlns="http://www.w3.org/1999/xhtml"> <p>We went to the beach for summer vacation. Here is a picture of the waves rolling in: <img src="http://example.net/binary/readonly/129.png" alt="A picture of the beach." /> </p> </div> </content> </entry>
Section 9 becomes Section 10 and so on.
Section 11 IANA Considerations becomes Section 12 IANA Considerations. Also remove the registration of the application/atomserv+xml media-type.