SWORD APP Profile 0.3

From DigiRepWiki

SWORD Home | SWORD Wiki | SWORD Project Background


This profile has been replaced by the most recent version: http://purl.org/net/sword/


Contents

SWORD Profile of the Atom Publishing Protocol

Version 0.3, created 7th June 2007

Introduction

This document is a profile of the Atom Publishing Protocol (APP). APP is an application-level protocol for publishing and editing Web resources. The APP is based on HTTP transfer of Atom-formatted representations. This Profile specifies a subset of elements from the APP for use in depositing content into information systems, such as repositories. The Profile also specifies a number of element extensions to APP, defined with reference to the extensions mechanism outlined in APP. APP and this profile also draws on the Atom Syndication Format (ATOM).

This profile has been produced to support the work of the JISC-funded SWORD project.

Conventions

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC2119 (see APP).

SWORD Profile of APP elements

The following section identifies the elements of APP which are implemented by SWORD and those which are not. It also provides additional requirements and recommendations, and identifies SWORD extensions to APP, using elements from other namespaces and elements from the sword namespace.

The section is organised according to the sections of the APP document.

5. Protocol Operations

5.1 Retrieving a Service Document

SWORD supports the use of HTTP GET requests.

GET to Service Document

In addition, SWORD uses an additional HTTP header X-Target-Owner to specify the username of a target user on whose behalf a deposit is being made.

GET to Service Document
X-Target-Owner: onBehalfOf

This facilitates the SWORD requirement to support mediated deposits. See also the notes about Authentication below (relating to APP section 14). In this case, the returned Service Document SHOULD identify only those collections to which the target user is able to deposit. If the target repository does not support mediated deposit, the returned Service Document SHOULD contain a <sword:mediation> extension element with a value of false.

5.2 Listing Collections - NOT USED

5.3 Creating a Resource

SWORD supports the use of HTTP POST

POST to URI of Collection
201 Created
Location: Member Entry URI

See further refinements to the SWORD use of HTTP POST in APP Section 9.

5.4 Editing a Resource - NOT USED

5.5 use of HTTP Response Codes

SWORD supports the use of the following HTTP response codes. Implementers should supply human-readable explanations along with HTTP response codes. Additionally, SWORD provides an APP extension point for supplying error codes within the Atom Entry Document returned with the HTTP deposit response. SEE SWORD Extensions to the APP.

  • 201 Created
  • 202 Accepted
  • 400 Bad Request
  • 401 Unauthorized
  • 403 Forbidden
  • 412 Precondition failed - level 0 implementations MAY, and level 1 implementations MUST return a 412 if the MD5 checksum does not match.
  • 415 Unsupported Media Type - level 0 implementations MAY, and level 1 implementations MUST return a 415 if the content-type supplied is not supported by the server.
  • 500 Internal Server Error - level 1 implementations SHOULD return a 500 along with one of the defined response error codes. SEE SWORD Extensions to the APP.

7. Category Documents - NOT USED

8. Service Documents

In line with APP, a service document (<app:service>) is identified with the "application/atomsvc+xml" media type.

8.1 Workspaces

The SWORD profile adheres fully to the APP definition of a Workspace.

For this profile, a Workspace is defined as an arbitrary aggregation of collections of resources.

The SWORD profile specifies that one or more <app:collection> elements SHOULD be present. The absence of any <app:collection> elements implies that the authenticated user does not have permission to deposit.

The SWORD profile recommends that the <app:accept> element is used to specify accepted media-ranges. It is anticipated that these ranges MAY include media ranges relating to accepted packaging formats, e.g. application/zip, application/xml. SWORD also specifies an extension point for supplying more detailed information about deposit formats.

The SWORD profile adheres fully to the element definitions identified at 8.3.1, 8.3.2, 8.3.2.1, 8.3.3, 8.3.3.2, 8.3.3.3, 8.3.4. SWORD defines the following extensions to the <app:collection> element:

<dcterms:accrualPolicy> - text/URI
<dcterms:abstract> - text/URI
<sword:mediation> - true|false
<sword:defaultCollection> - true|false
<sword:treatment> - text
<sword:verbose> - true|false
<sword:noOp> - true|false
<sword:checksumType> - ID
<sword:format>
	<dc:format> - ID
	<sword:formatNamespace> - URI
	<sword:formatSchema> - URI

Consult the SWORD extensions to the APP for further definitions and usage guidelines.

8.3.5 - NOT USED

9. Creating and Editing Resources

9.1 Member URIs

SWORD adheres to APP on Member URIs.

9.2 Creating resources with POST

SWORD is allied to APP and uses a simple 'POST to URI of collection' as outlined by APP in section 9.6. Additionally SWORD uses a set of SWORD-defined HTTP headers to supply additional parameters with the POST. The following headers are defined:

  X-Target-Owner: on-behalf-of
  X-Verbose: true|false
  X-No-Op: true|false
  X-Format: agreed-format-id
  X-Deposit-ID: deposit-id 
  X-Content-Checksum-Type: checksum-type
  X-Content-Checksum: checksum

Consult the SWORD extensions to the APP for further definitions and usage guidelines.

9.3 Updating Resources with PUT - NOT USED

9.4 Deleting Resources with DELETE - NOT USED

9.5 Caching and entity tags - NOT USED

9.6 Media Resources and Media Link Entries

SWORD uses this mechanism for posting media types other than appliation/atom+xml to a Collection. SWORD recommends that the returned Media Link Entry adheres to the APP protocol, with the following additional recommendations:

The Location: element of the HTTP header MUST contain a URI for the Media Link Entry. This SHOULD be a unique identifier for an Atom Entry Document created for the deposit and returned with the response.

This Media Link Entry MUST contain an <atom:content> element with a src attribute containing a URI for the deposited Media Resource. It is recommended that this URI derefrences to the location of the deposited package.

An <atom:link> element SHOULD be supplied with a rel="edit-media" attribute and a href containing a URI for the Media Resource. This MAY be the same as the URI supplied with the <atom:content> element. It is recommended that this URI derefrences to the location of the deposited package.

An <atom:link> element SHOULD be supplied with a rel="edit" attribute and a href containing a URI for the deposit. This SHOULD be a public splash page or jump-off page, or a users private metadata or workflow management page. It MAY give users future access to an 'unpacked' deposit. If records are queued in a 'pending' workflow, this URI may not yet dereference.

URIs SHOULD be unique and wherever possible SHOULD persist, but this is not a requirement.

The ATOM Entry returned with the HTTP Response MAY contain the following extensions:

<atom:contributor> - mediator name
<atom:source>
       <atom:generator> - id of the source repository
<sword:treatment> - text
<sword:verboseDescription> - text
<sword:noOp> - true/false (true = no action has been taken; false = deposit has been made as requested)
<sword:checksumType> - id
<sword:checksum> - checksum
<sword:format>
	<dc:format> - id

Consult the SWORD extensions to the APP for further definitions and usage guidelines.

9.7 The Slug: Header

The SWORD Profile does not require the use of The Slug header. The Slug header MAY be used, but servers MAY choose to ignore the header or alter its value.

10. Listing Collections - Not Used

  • APP states that "Collection Resources MUST provide representations in the form of Atom Feed couments whose Entries contain the IRIs of Members in the Collection".
  • The SWORD profile does not require Collection lists, but implementers MAY wish to support this feature in order to be APP compliant.

10.1 Collection partial lists - NOT USED

  • see notes above - implementers MAY wish to use Collection partial lists.

10.2 The "app:edited" Element - NOT USED

11. Atom Format

The SWORD Profile uses the "edit" and "edit-media" link relations. The SWORD profile does not currently support edits or modification of deposited items, therefore a URI with an edit or edit-media link relation points to a Member Entry which MAY be editable, but is not required to be.

The edit link URI SHOULD point to the location of a workflow management page, or jump-off page.

The edit-media link URI SHOULD point to the location of the deposited file or package.

12. The Atom Format Type Parameter

The SWORD Profile uses the "entry" type parameter.

13. Publishing Controls - NOT USED

14. Securing the Atom Publishing Protocol

The SWORD Profile adheres to the statement: "At a minimum, client and server implementations MUST be capable of being configured to use HTTP Basic Authentication [RFC2617] in conjunction with a TLS connection as specified by [RFC2818]."

It is the responsibility of implementers to integrate existing authentication solutions.

15. Security Considerations

The SWORD Profile recommends implementers refer to this section of APP.

Compliance

SWORD identifies two levels of compliance.

Level 0 requires implementation of a minimal set of mandatory elements as defined [below].

Full level 1 compliance REQUIRES implementation of the full set of extension elements and compliance with APP as indicated by the [SWORD profile of APP] specified in this document.

Partial level 1 compliance REQUIRES implementation of some optional elements specified [below]. This may depend on local requirements. Partial level 1 compliance is identified as 1-part.

Level 0 compliance

Mandatory elements for Level 0 compliance are:

SWORD parameter APP element In
Collection ID <app:collection href=""> (atom uri) Service Document
Deposit Status HTTP Status Code HTTP Response
Error Code HTTP Status Code HTTP Response
Error Description in HTTP Response HTTP Response
Treatment Description <sword:treatment> extension in Service Document and ATOM Entry Service Document

and

ATOM Media Entry

Level 1 compliance

These elements are mandatory for full level 1 compliance and optional for partial compliance.

SWORD parameter APP element / HTTP header Extension APP / HTTP header In
onBehalfOf TargetOwner X-Target-Owner HTTP Header (POST) and HTTP Header (GET)
Repository / Collection Name

<collection>
<atom:title>

Service Document
Repository / Collection Policy

<dcterms:accrualPolicy>

Service Document
Collection Description

<dcterms:abstract>

Service Document
Default Collection

<sword:defaultCollection>

ServiceDocument
Format ID Content-Type X-Format-ID HTTP header (POST)
HTTP header (response)
Format Accepted Content-Type <dc:format> Service Document
Atom Entry Document (response)
Format Description
Format Namespace

<sword:namespace>

Service Document
Format Schema

<sword:schema>

Service Document
Treatment Description

<sword:treatment>

Service Description
Atom Entry Document (response)
Verbose Supported

<sword:verbose>
X-Verbose

Service Description
NoOp Supported

<sword:noOp>

Service Description
Mediation Allowed

<sword:mediation>

Service Document
Source Repository

<atom:source>
<atom:generator>

Target Collection POST to URI of Collection
Transaction ID <atom:id> X-Deposit-ID HTTP header (POST)

HTTP header (response)

Atom Entry Document (response)
Verbose

<sword:verbose>

Service Document

HTTP header (POST)

Verbose Description

<sword:verboseDescription>

Atom Entry Document (response)
NoOp

<sword:noOp>
X-No-Op

Service Document

HTTP header (POST)

Atom Entry Document (response)
Checksum Type Content-MD5

<sword:checksumType&gt
X-Content-Checksum-Type

HTTP header (POST)

HTTP header (response)

Atom Entry Document (response)
Checksum Content-MD5: md5-digest

<sword:checksum>
X-Content-Checksum

HTTP header (POST)

HTTP header (response)

Atom Entry Document (response)
Target Owner <atom:author> X-Target-Owner Deposit POST
Identifier (URI)

<atom:content type="" src="">
Location

Atom Entry Document (response)
HTTP header (response>
Object URI

<atom:link rel="edit-media" href"">

Atom Entry Document (response)
Display URI <atom:link rel="edit" href""> Atom Entry Document (response)

SWORD Extensions to the APP

This section defines SWORD extensions to the APP, as used in this document.

APP Element extensions

SWORD defines the use of additional elements, as follows:

Element Namespace APP / ATOM extension point Usage notes
<dcterms:accrualPolicy>
http://purl.org/dc/terms/ <app:collection> (Service Document) Use for a human-readable repository or collection policy.  Include either a text description or a URI.
<dcterms:abstract> http://purl.org/dc/terms/ <app:collection> (Service Document) Use for a human-readable repository or collection description.  Include either a text description or a URI.
<sword:mediation>

http://purl.org/sword/

<app:collection> (Service Document) Use to indicate if mediated deposit is allowed on the defined collection.
Value=true|false
<sword:defaultCollection>

http://purl.org/sword/

<app:collection> (Service Document) Use to indicate a default collection where multiple collections are listed.  If only one collection is specified in the Service Document, this is assumed to be the default collection.
Value=true|false
<sword:treatment>

http://purl.org/sword/

<app:collection> (Service Document) Use for a human-readable statement about what treatment the deposited resource will receive. Include either a text description or a URI.
<sword:treatment>

http://purl.org/sword/

<atom:entry> (Atom Entry Document (response)) Use for a human-readable statement about what treatment the deposited resource has received. Include either a text description or a URI.
<sword:verbose>

http://purl.org/sword/

<app:collection> (Service Document) Use to indicate if verbose descriptions are supported. This extension is intended for use by developers for testing implementation.
Value=true|false
<sword:verboseDescription>

http://purl.org/sword/

<atom:entry> (Atom Entry

Document

(response))
Use to supply a verbose descriptions are supported. This extension is intended for use by developers for testing implementation Include either a text description or a URI.
Value=true|false
<sword:noOp>

http://purl.org/sword/

<app:collection> (Service Document) Use 'true' to indicate if the server supports the noOp facility. This extension is intended for use by developers for testing implementation.
Value=true|false
<sword:noOp>

http://purl.org/sword/

<atom:entry> (Atom Entry Document (response)) Use 'true' to indicate that the server has taken no action on receipt of this deposit. This extension is intended for use by developers for testing implementation.
Value=true|false
<sword:checksumType>

http://purl.org/sword/

<app:collection> (Service Document) Use to supply an identifier for the checksum type supported by the server. Absence of a checksumType indicates that checksums are not supported.
<sword:checksumType>

http://purl.org/sword/

Atom Entry Document (response) Use to supply an identifier for the checksum type handled by the server.
<sword:checksum>

http://purl.org/sword/

<atom:entry> Atom Entry Document (response)) Use to supply the checksum handled by the server in the response.
<sword:format>

http://purl.org/sword/

<app:collection> (Service Document)
<atom:entry> (Atom Entry Document (response))
Wrapper for additional format elements.
<dc:format> http://purl.org/dc/terms/ <app:collection> (Service Document)
<atom:entry> (Atom Entry Document (response))
Used for an identifier for the particular packaging format supported or handled.
<sword:formatNamespace>

http://purl.org/sword/

<app:collection> (Service Document) Used to supply a URI for the format namespace.
<sword:formatSchema>

http://purl.org/sword/

<app:collection> (Service Document) Used to supply& a URI for the format schema.
<sword:level> http://purl.org/sword/ <app:service> (Service Document) Used to indicate the compliance level supported by the server.
Value=0|1|1-part
<sword:error> http://purl.org/sword/ <atom:entry> (Atom Entry Document (response)) Used to provide an error code to further refine the HTTP code supplied with the response.
The following error codes MAY be used
  • ErrorContent
  • ErrorParse
  • ErrorChecksumMismatch - required if a checksum is sent
  • ErrorUnknownChecksumAlgorithm - required if a checksum is sent
  • ErrorBadRequest - where parameters are not understood
  • TargetOwnerUnknown - where the server cannot identify the specified TargetOwner
  • MediationNotAllowed - where a client has attempted a mediated deposit, but this is not supported by the server

HTTP Header extensions

Header Usage Usage notes
Content-MD5 HTTP Header (POST) Used to supply a MD5 checksum.
X-Content-Checksum-Type HTTP Header (POST) Use where an Md5 checksum in NOT available, to provide an identifier for the checksum type supplied with the deposit.
X-Content-Checksum HTTP Header (POST) Use where an Md5 checksum in NOT available, to supply a checksum with the deposit.
X-Format-ID HTTP Header (POST) Used for an identifier for the particular packaging format supplied.
X-Verbose HTTP Header (POST) Use to request a verbose description with the response. This header

is intended for use by developers for testing implementation.

Value=true|false
X-No-Op HTTP Header (POST) Use 'true' to indicate if the server should take no action on receipt of this deposit.  This extension is intended for use by developers for testing implementation.
Value=true|false

Examples

Retrieve Service Document

GET to Service Document (simple user)

GET /atom/servicedocument HTTP/1.1
Host: www.myrepository.ac.uk

GET to Service Document onBehalfOf TargetUser (mediated user)

GET /atom/servicedocument HTTP/1.1
Host: www.myrepository.ac.uk
X-Target-Owner: lcarr

Service Document

Example 1: level 0

<?xml version="1.0" encoding='utf-8'?>
<service xmlns="http://purl.org/atom/app#"
         xmlns:atom="http://www.w3.org/2005/Atom"
	 xmlns:sword="http://purl.org/sword/">
 <sword:level>0</sword:level>
 <workspace>
   <atom:title>Main Site</atom:title>
   <collection
       href="http://www.myrepository.ac.uk/atom/geography-collection" >
     <atom:title>My Repository : Geography Collection</atom:title>
   </collection>
 </workspace>
</service>


Example 2: level 1

<?xml version="1.0" encoding='utf-8'?>
<service xmlns="http://purl.org/atom/app#"
         xmlns:atom="http://www.w3.org/2005/Atom"
	 xmlns:sword="http://purl.org/sword/"
	 xmlns:dcterms="http://purl.org/dc/terms/">
 <sword:level>1</sword:level>
 <workspace>
   <atom:title>Main Site</atom:title>
   <collection
       href="http://www.myrepository.ac.uk/atom/geography-collection" >
     <atom:title>My Repository : Geography Collection</atom:title>
     <app:accept>application/xml, application/zip, application/atom+xml, Multipart/Related;type=application/atom+xml</app:accept> 
     <dcterms:accrualPolicy>Collection Policy</dcterms:accrualPolicy>
     <dcterms:abstract>Collection description</dcterms:abstract>
     <sword:mediation>true</sword:mediation>
     <sword:defaultCollection>true</sword:defaultcollection>
     <sword:treatment>Treatment description</sword:treatment>
     <sword:format>
	   <dc:format>agreed format identifier</dc:format>
	   <sword:schema>uri</sword:schema>
	   <sword:namespace>uri</sword:namespace>
     </sword:format>
     <sword:verbose>true</sword:verboseSupport>
     <sword:noOp>true</sword:noOpSupport>  
     <sword:checksumType>mD5</sword:checksumType>
   </collection>
 </workspace>
</service>

Deposit

Example 1: POST binary (level 0)

http://www.myrepository.ac.uk/atom/geography-collection
   POST /geography-collection/ HTTP/1.1
   Host: www.myrepository.ac.uk/atom
   Content-Type: application/zip
   Content-Length: nnn
  
   ...binary data...

Example 2: POST binary (level 1-part, mediated user)

  POST /geography-collection HTTP/1.1
  Host: www.myrepository.ac.uk/atom
  Content-Type: application/zip
  Slug: My Deposit
  Authorization: Basic ZGFmZnk6c2VjZXJldA==
  Content-Length: nnn
  X-Target-Owner: lcarr
   
  ...binary data...

Alternatives to X-Target-Owner:

Target Owner (as parameter) - http://www.myrepository.ac.uk/atom/geography-collection?onBehalfOf=lcarr
Target Owner (as collection) - http://www.myrepository.ac.uk/atom/geography-collection/lcarr
Target Owner (as collection) - http://www.myrepository.ac.uk/atom/users/lcarr/geography-collection

Example 3: POST (level 1, mediated user)

  POST /geography-collection HTTP/1.1
  Host: www.myrepository.ac.uk/atom
  Content-Type: application/zip
  Slug: My Deposit
  Authorization: Basic ZGFmZnk6c2VjZXJldA==
  Content-Length: nnn
  Content-MD5: md5-digest
  X-Target-Owner: lcarr
  X-Verbose: true
  X-No-Op: true
  X-Format: agreed-format-id   
  X-Deposit-ID: deposit-id

Response

Example 1: level 0 response

  HTTP/1.1 201 Created
  Date: Mon, 14 May 2007 14:27:11 GMT
  Content-Length: nnn
  Content-Type: application/atom+xml; charset="utf-8"
  Location: http://www.myrepository.ac.uk/collection/edit/my_deposit.atom
  <?xml version="1.0"?>
   <entry xmlns:atom="http://www.w3.org/2005/Atom"
	 xmlns:sword="http://purl.org/sword/"
	 xmlns:dcterms="http://purl.org/dc/terms/">
     <title>My Deposit</title>
     <id>deposit-id</id>
     <updated>2007-05-14T14:27:08Z</updated>
     <author><name>Les Carr</name></author>
     <summary type="text" />
     <content type="application/zip"
        src="http://www.myrepository.ac.uk/my_deposit.zip"/>
     <link rel="edit-media"
        href="http://www.myrepository.ac.uk/my_deposit.zip" />
     <link rel="edit"
        href="http://www.myrepository.ac.uk/lcarr/workflow/my_deposit.atom" />
     <sword:treatment>Treatment description</sword:treatment>
  </entry>

Example 2: level 1-part response

  HTTP/1.1 201 Created
  Date: Mon, 14 May 2007 14:27:11 GMT
  Content-Length: nnn
  Content-Type: application/atom+xml; charset="utf-8"
  Location: http://www.myrepository.ac.uk/collection/edit/my_deposit.atom
  <?xml version="1.0"?>
   <entry xmlns:atom="http://www.w3.org/2005/Atom"
	 xmlns:sword="http://purl.org/sword/">
     <title>My Deposit</title>
     <id>deposit-id</id>
     <updated>2007-05-14T14:27:08Z</updated>
     <author><name>Les Carr</name></author>
     <summary type="text" />
     <content type="application/zip"
        src="http://www.myrepository.ac.uk/my_deposit.zip"/>
     <link rel="edit-media"
        href="http://www.myrepository.ac.uk/my_deposit.zip" />
     <link rel="edit"
        href="http://www.myrepository.ac.uk/lcarr/workflow/my_deposit.atom" />
     <contributor><name>Martin Morrey</name></contributor>
     <source>
          <generator>Repository id</generator>
     </source>
     <sword:treatment>Treatment description</sword:treatment>
  </entry>

Example 3: level 1 response

  HTTP/1.1 201 Created
  Date: Mon, 14 May 2007 14:27:11 GMT
  Content-Length: nnn
  Content-Type: application/atom+xml; charset="utf-8"
  Content-MD5: md5-digest
  X-Target-Owner: lcarr
  X-Verbose: true
  X-No-Op: true
  X-Format: agreed-format-id   
  X-Deposit-ID: deposit-id
  Location: http://www.myrepository.ac.uk/collection/edit/my_deposit.atom
  <?xml version="1.0"?>
   <entry xmlns:atom="http://www.w3.org/2005/Atom"
	 xmlns:sword="http://purl.org/sword/"
	 xmlns:dcterms="http://purl.org/dc/terms/">
     <title>My Deposit</title>
     <id>deposit-id</id>
     <updated>2007-05-14T14:27:08Z</updated>
     <author><name>Les Carr</name></author>
     <summary type="text" />
     <content type="application/zip"
        src="http://www.myrepository.ac.uk/my_deposit.zip"/>
     <link rel="edit-media"
        href="http://www.myrepository.ac.uk/my_deposit.zip" />
     <link rel="edit"
        href="http://www.myrepository.ac.uk/lcarr/workflow/my_deposit.atom" />
     <contributor><name>Martin Morrey</name></contributor>
     <source>
          <generator>Repository id</generator>
     </source>
     <sword:treatment>Treatment description</sword:treatment>
     <sword:verboseDescription>description</sword:verboseDescription>
     <sword:noOp>true</<sword:noOp>
     <sword:checksumType>MD5</sword:checksumType>
     <sword:checksum>md5-digest<sword:checksum>
     <sword:format>
	 <dc:format>Format ID</dc:format>
     </sword:format>
  </entry>

References

Nottingham, M. and R. Sayre, "The Atom Syndication Format", RFC 4287, December 2005. [RFC4287]. http://www.ietf.org/rfc/rfc4287.txt (see also non-normative html version at http://atompub.org/rfc4287.html)

Gregario, J. and B. de hOra, "The Atom Publishing Protocol", Internet Draft, March 2007. http://www.ietf.org/internet-drafts/draft-ietf-atompub-protocol-14.txt (see also non-normative html version at http://bitworking.org/projects/atom/draft-ietf-atompub-protocol-14.html)

Fielding et al, "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, June 1999 http://www.w3.org/Protocols/rfc2616/rfc2616.html

"HTTP/1.1: Status Code Definitions", part of "Hypertext Transfer Protocol -- HTTP/1.1" RFC 2616 Fielding, et al. http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

Klyne, G., Nottingham, M. and Mogul, J. "Registration Procedures for Message Header Fields", RFC 3864, September 2004 http://www.rfc-editor.org/rfc/rfc3864.txt