W3CWD-http-ng-interfaces-19980710

HTTP-NG Web Interfaces

W3C Working Draft 10 July 1998

This version:
http://www.w3.org/TR/1998/WD-http-ng-interfaces-19980710
Latest version:
http://www.w3.org/TR/WD-http-ng-interfaces
Editors:
Dan Larner, <larner@parc.xerox.com>

Copyright  ©  1998 W3C (MIT, INRIA, Keio ), All Rights Reserved. W3C liability, trademark, document use and software licensing rules apply.

Status of This Document

This draft specification is a work in progress representing the current consensus of the W3C HTTP-NG Protocol Design Group. This is a W3C Working Draft for review by W3C members and other interested parties. Publication as a working draft does not imply endorsement by the W3C membership.

This draft document describes an initial set of extensible formal object interfaces that allow some of the basic functionality of HTTP to be captured in the HTTP-NG framework. The draft is a result of the HTTP-NG project at the W3C and is part of a suite of documents describing the HTTP-NG design and prototype implementation:

Please send comments on this specification to <www-http-ng-comments@w3.org>.

Introduction

Part of the charter of the Protocol Design Group of the HTTP-NG project is to identify a set of formal interfaces that will allow the current functionality of the Web to be captured, as well as support future needs. Before delving into the specific interfaces, the kinds of concepts involved need to be described. The actual interface descriptions here are cast in terms of distributed object systems, the merits of which as a foundation for the Web have been discussed in "Migrating the Web toward Distributed Objects" and elsewhere. The intent is not to imply that what is presented here is complete or final, but rather to provide a starting point for how the Web should look in the future.

Concepts

When we think of the Web today, the idea of a 'resource' comes to mind. In general, a resource is an Object that has some methods (e.g. in HTTP, Get Head and Post) that can be invoked on it. Objects may be stateful in that they have some sort of opaque 'native data' that influences their behavior. The nature of this native data is unknown to the outside, unless the object explicitly makes it known somehow. [Any stateful object may or may not have some means by which it stores persistent state across activations, but that's not really part of our concern here.]

Objects which are Renderable may be asked to produce a Rendering based on a set of Preferences. This is analogous to HTTP Get. A Rendering is a transformation of the object's native data into some other form, typically a collection of bytes with an interpretation determined by a named type relative to some typespace. Common examples are illustrated by the various MIME types, e.g. text/html Rendering for viewing in a web browser, and an application/postscript Rendering for printing. When a Renderable object is asked for a Rendering of a preferred type, the implementation of the object's method for this operation transforms or maps the native data to this Rendering type. Note that this transformation may or may not be reversible. If the Rendering format happens to be the same as the native data of the document, the transformation might be identity. Objects that have no native data themselves may be able to produce a Rendering by generating it from other sources (e.g. real world state, other objects).

A Rendering may be retrieved in one of two ways. Either the Rendering is returned as a value from a synchronous call, or the Rendering is requested and then sent asynchronously, in chunks, back to some RenderingSink. The former can be thought of as a 'client-pull' technique, and the latter as a 'server-push' technique. The sink approach is to support the notion of a 'stream', to deal with Renderings that are impractically large (e.g. images), or not well bounded (e.g. live video or audio).

Renderings may also be produced by an object acting as a FormProcessor . This is analogous to HTTP Post. In this case, instead of receiving information about RenderingPreferences, the object receives a set of Name/Value pairs that are interpreted in an implementation-specific manner to produce a Rendering.

Some objects may be asked to accept a Rendering. This is analogous to HTTP Put. The intent here is that of updating the object's native data. When such a request is made on an object, if the supplied rendering is transformable by the implementation into the native data, and such an operation is semantically permissible, the rendering is transformed into the native form. If it's not possible to transform the rendering into native form (e.g. supplying GIF to an object whose implementation doesn't know how to OCR an image to translate it to an internal text representation), then an exception needs to be raised. Note that some objects could actually have multiple native data forms internally, but this is generally unknown outside the object.

Objects may have a PropertySet. These are groups of attributes that are not normally part of the native data itself, but rather more descriptive of the object as a whole. This is often referred to as Meta-Data, and may include such information as author, version, summary, etc. Properties may be static or computed [an implementation detail].

In actual implementations, the data exchanges that take place during of method invocations may pass through one or more intermediate caches. Caches often maintain a copy of some object's Rendering to improve the speed with which a Rendering can be retrieved. What can be cached and what cannot is dependent on the operation semantics, the security policies of the parties involved, contractual obligations, and other concerns. CacheControl information must accompany each request and response where the potential for caching is of concern.

Concept Composability and Extendability

The previous section attempted to expose some general concepts, or 'types' that objects may be. The key word here is may. For example, not all objects need to be Renderable, not all need to be able to process forms, and some things simply have no interesting properties to expose. What's needed is the ability to describe each of these types in isolation, and be able to combine then as needed for particular circumstances. So for example, we want to define a Renderable type to be an object that has a set of operations or Methods dealing with the retrieval of a rendering. Similarly, we define a PropertySet type for those objects that need to have that sort of functionality, and so on.

In object oriented systems, bits of functionality are combined through inheritance. To say that something 'C' inherits from 'A' and 'B', means that C objects are a derived type, and can be used as a method parameter wherever an A, B, or C is required. C also provides the methods defined for A and B objects, in addition to any that may be defined specifically for C objects. These properties are transitive with respect to inheritance. So then, using the inheritance capabilities of the distributed object system, we can define new kinds of objects that are a number of these types (and hence implement their Methods) through inheritance.

For example, to capture the functionality of a WebDocument as we think of it today, we define WebDocument as an object that inherits Renderable (supporting the equivalent of HTTP's Get), and inherits from the PropertySet object (to primarily support independent retrieval of what is currently covered by some HTTP headers).

It is also using the mechanism of inheritance that types can be extended. Note that the previous description mentioned that a type C inheriting from A and B can define its own methods in addition to the ones inherited from its parents.

For example, A WebDocument can implement its own method that allows both Rendering and Properties to be retrieved in a single call. Another example could be a new object type, MicrowaveOven, that not only is Renderable (can supply an image of what's cooking), but also adds methods to turn it on and off. Printers and Scanners could be defined as children of a WebDocument, and a Copier as a child of those. The following figure is illustrative of this sort of type evolution.

The Fit with the Current Web

This section attempts to basically describe how the components of the Web as we know them today could be cast using distributed objects with the kinds of interfaces described above, and illustrates some scenarios that would be difficult to implement with today's approach. In the descriptions, the word ObjRef is used to mean an object reference. This may either be something like a HTTP URL as we commonly see today, or it may be of a more general form that includes information about the object attributes (e.g. its type), in addition to the contact and instance identification information.

Content Retrieval

Given an ObjRef, a browser would like to contact the entity it refers to in order to receive a Rendering. If the ObjRef has the HTTP scheme, an assumption is made that the entity is a resource as we know it today and we treat it as we commonly would using HTTP1.x. [1]

If however the ObjRef has more information, (e.g. what object type it represents), the browser may take quite a different set of actions. Let's say it indicates that it's a 'WebDocument' type. The browser asks the document for a Rendering and its Properties, perhaps in a particular format. The WebDocument object receives the rendering request. It has its own implementation of the request, so how it actually processes the request may be different from other WebDocuments -- remember we're defining types here, and their intended semantics, not their actual implementations. [For example, its implementation might examine the request, and see that the requested Rendering content type is not available through local transformations of native data. It could call out to a Rendering transformation service (e.g. postscript to gif) to get the appropriate Rendering.] In the response to the browser, the WebDocument sends the Rendering, along with a set of Properties describing the document. The browser for example might notice that the document author is on the list of 'interesting people' that the browser's user has specified. The browser then decides to automatically add this ObjRef to the user's 'Favorites' folder.

In a future scenario, the browser might discover that the WebDocument had been extended with Daemon interfaces. A Daemon is basically an interface that accepts condition action pairs, and performs the action when the condition is true, typically the sending of some Event containing data to a Sink. Now, since this WebDocument's author is a user favorite, the browser decides that it would like to be notified of changes in the document so that the Rendering can be updated accordingly. It adds a Daemon (through the Daemon Interface that had been 'mixed in' with the WebDocument) to the WebDocument, whose Condition is true when the Document changes. The Daemon contains an Action that accepts Condition Results and an Event Sink (that the browser implements). This Action gets the new Rendering for the Document, packages it up in an Event and sends it to the browser's Event Sink. When the browser receives the Event, it knows that the Rendering should be updated. This might even be allowed to proceed in the background so that the browser's cache can be kept up to date. When the page is left, or when the cache entry gets dumped from the cache, the browser retracts its previously posted condition action pair from the WebDocument's Daemon interface.

Forms

If the browser sees a form method as one might today, e.g.

FORM METHOD="POST" ACTION="/cgi/wwwwais.cgi";

it treats the form just as it does today. If however, it saw a method that wasn't POST, e.g. ProcessForm, and the ACTION that wasn't the HTTP schemed URL but rather one indicating a FormProcessor object, it would invoke the named method on the specified object, passing the form parameters to the method as a property-list (a list of name-value pairs). Note here that the values in this list can be more than simple strings - any type may be passed, enabling a much richer and more compact set of inputs.

HTTP-NG Interfaces

This section contains brief descriptions of interfaces that embody the concepts mentioned previously. Actual interfaces described in ILU's Interface Specification Language (ISL) can be found in the appendix. These interfaces are certain to evolve as missing and extraneous functionality is discovered through both review and prototype implementation.

NgBasic

This interface defines a number of basic types such as strings, times, intervals, etc., as well as the NgObject object type which forms a root class from which all NG classes inherit. This is useful to be able to provide all derived objects with a standard set of methods, as well as provide a type which may be used as a handle for any kind of NG-Object. A single method, GetInterfaceDefinitionSource, which provides a means for interface discovery, is declared.

In addition, some exceptions are defined in NgBasic. Certain operations, typically Get or Put style, may return a WouldBlock exception when the operation would block for some reason. Similarly, Conflict exceptions may be returned when the operation is somehow in conflict with another operation (perhaps simultaneous Puts on a Rendering) or operational semantics (perhaps a Put based on an old version as determined through e-tag information for example). The value optionally contained in the ExceptionInformation's Pickle is operation specific. For a WouldBlock, it could contain locking information for example. Those knowledgeable about locking could attempt to extract and make use of the lock information contained in the pickle. Those not knowledgeable about locking could just disregard the value, but still have knowledge that something is currently going on with the target object that would cause them to block waiting for a result.

There may be situations where an implementation might quickly reify an object in an object creation function and later determine that this object really doesn't exist. Since this sort of 'system exception' information isn't necessarily sent across the wire, a user exception, ObjectNotExist, is defined for this sort of event.

NgStream

An object having methods intended for the asynchronous receipt of data (streaming data for example) is called a DataSink. The DataSink object type is 'abstract', in that it is meant to be subtyped, never directly instantiated. Subtypes will supply methods that are specialized to the particular type of data the the sink accepts. It methods are:

DataSinks may have a need to exert some control over the source side. The DataSource object type may be passed to a DataSink, and the DataSink can then invoke a number of 'flow-control' related methods:

Note that the methods on DataSink and DataSource are asynchronous. This avoids the return-trip time that synchronous call have. Since the states of these objects are influenced by the order in which methods are processed, these calls must take place over a communication channel that ensures that methods are processed in the order in which they are sent.

NgDocument

The object type WebDocument is primarily a combination of the Renderable and PropertySet object types, and is meant to be an NG analog to what Web documents are today. [2] The main method is GetRenderingandProperties, which is simply intended to be a combination of the GetRendering and GetProperties methods of its parents. This method mimics what we current have with HTTP Get. SendRenderingAndProperties and SendRenderingAndPropertiesSynched is similar only it allows for the return results to be sent asynchronously back to a RenderingAndPropertiesSink. The PutableWebDocument object type inherits from WebDocument, PutableRendering, and PutablePropertySet, and provides the analog to the HTTP 1.1 Put operation.

NgRendering

Rendering preferences are described through use of a RenderingPreferences record. The members of this record are briefly:

Renderings themselves are described through use of a Rendering record. The members of this record are briefly:

An object of type Renderable is able to produce a Rendering of the object. Examples are a text description, a graphic, an html page, an audio, etc. This first is Renderable itself. This type has a number of methods.

The PutableRendering object type provides the analog to the HTTP 1.1 Put operation. It adds a single method:

An object of type RenderingSink is able to asynchronously receive renderings. It inherits the RegisterSourceControl and Done methods from DataSink, and add several methods:

NgProperty

An object of type PropertySet has a method GetProperties used to retrieve name/value pairs, e.g. Authors, CreationTime, etc. A subtype of PropertySet, PutablePropertySet has a method PutProperties used to write name/value pairs.

NgFormProcessor

An object of type FormProcessor is able to process Form based input, and produce an appropriate rendering as a response. This type has two methods:

NgCache

Records are defined that may be sent along with requests and responses to provide caches and proxy relevant information. This mostly mimics the cache-related headers and Cache-Control header values found in HTTP 1.1. See the HTTP1.1 specification for the semantics. An issue that needs further thought is the crosscutting of cache-relevant information through multiple arguments - version information is a prime example.

IANA-Charsets-Registry

This interface simply contains types for identifying character sets.


Footnotes

[1] The paper "Migrating the Web toward Distributed Objects", describes how in the distributed object system ILU, Get, Head and Post methods on an object can be invoked through existing HTTP through inheritance of the iluhttp.Resource object type. Through inheritance of this type, HTTP-NG style Web objects can interoperate with existing Web browser and servers, providing a migration path to the new technology.

[2] An implementer might chose to create a new type derived from both WebDocument, and from iluhttp.Resource (part of the ILU distribution), so that it can also interact with existing Web clients and servers.



Appendix - Strawmen ISL files


NgBasic.isl

(* ************************************************************************ *)
(*
    Version 1.3 ISL for HTTP-NG, Dan Larner, 3-19-98

    This work is very preliminary - Comments welcomed and encouraged!
    'xxx' marks areas where thought is definitly needed
    Please send comments, suggestions, contributions, etc. to the http-ng
    mailing list, w3c-http-ng@w3.org and/or to larner@parc.xerox.com.

*)

(* ************************************************************************ *)
(* *************************** Basic Types ******************************** *)
(* ************************************************************************ *)

(* Defines a number of basic types used throughout HTTP-NG interfaces.      *)


Interface NgBasic Brand "NG" ;


(* ********************** String & Type related *************************** *)

Type String           = Sequence Of Short Character;

Type OptionalString   = Optional String;

Type StringSequence   = Sequence Of String;

Type ByteSequence     = Sequence Of Byte;

Type URI              = String; (* see RFC1738 and RFC 1808 *)

Type OptionalURI      = Optional URI; 

Type URISequence      = Sequence Of URI;

Type OptionalCardinal = Optional Cardinal;


(* ************************************************************************ *)
(* **************************** Time Related ****************************** *)


(* Represents a number of microseconds elapsed since midnight
   (00:00:00), January 1, 1970, coordinated universal time.
   Note that negative values indicate number of microseconds
   prior to the origin. *)
   
Type AbsoluteTime         = Long Integer;

Type OptionalAbsoluteTime = Optional AbsoluteTime;


(* Represents an relative number of microseconds *)
   
Type RelativeTime         = Long Integer;

Type OptionalRelativeTime = Optional RelativeTime;


(* ************************************************************************ *)
(* **************************** Version Related *************************** *)

Type Version = Record 
    major         :  Short Cardinal,
    minor         :  Short Cardinal
End;



(* ************************************************************************ *)
(* ***************************** Intervals ******************************** *)

(* describes an inclusive range of unsigned numbers               *)

Type UnsignedInclusiveInterval = Record
    startValue    :  Cardinal,
    endValue      :  Cardinal 
End;

Type OptionalUnsignedInclusiveInterval = Optional UnsignedInclusiveInterval;


(* ************************************************************************ *)
(* ************************ Name Value Pairs ****************************** *)

(* simply a named attribute paired with some value *)

Type NameValuePair = Record
    name    :   String,
    value   :   Pickle 
End;

    
Type NameValuePairSequence = Sequence Of NameValuePair;
Type NameSequence          = Sequence Of NgBasic.String;


(* ************************************************************************ *)
(* ***************************** Exceptions ******************************* *)

Type OptionalPickle = Optional Pickle;

Type ExceptionInformation = Record

    (* a human readable description of why the exception occurred *)
    reasonPhrase  : String,           
    
    (* if present, operation specific information on the details of why the 
       operation produced an exception *)
    specificsData : OptionalPickle   
    
End;


(* Certain operations, typically Gets or Puts, may return a WouldBlock  or
   Conflict exception when the operation would block for some reason or is
   somehow in conflict with another operation (perhaps simultaneous Puts
   on a Rendering) or operational semantics (perhaps a Put based on an
   old version as determined through e-tag information for example).
   The value optionally contained in the ExceptionInformation's Pickle is 
   operation specific. For a WouldBlock example, it could contain locking 
   information. Those knowledgeable about locking could attempt to extract 
   and make use of the lock information contained in the pickle. Those not 
   knowledgeable about locking could just disregard the value, but still have 
   knowledge that something is currently going on with the target object that 
   would cause them to block waiting for a result.
   
   There may be situations where an implementation might quickly reify an
   object in an object creation function and later determine that this object
   really doesn't exist.  There's a need to return an object doesn't exist
   exception.  Since this sort of 'system exception' information isn't
   necessarily sent across the wire, it makes sense to create a user
   exception, ObjectNotExist, for this sort of event. This is also useful if
   this were to occur as the result of an async SendRenderingCall, where the
   Report returned in the ReceiveRendering can contain an ObjectNotExist
   exception.
*)



Exception WouldBlock : ExceptionInformation "Operation would have blocked" ;

Exception Conflict   : ExceptionInformation 
                       "Conflict with another operation or semantics" ;

Exception ObjectNotExist : ExceptionInformation 
                           "Discriminator object doesn't exist" ;



(* ************************************************************************ *)
(* ***************************** NgObject ********************************* *)

(* NgObject forms a root class from which all Ng classes inherit *)

Type NgObjectSequence = Sequence Of NgObject;

Type NgObject = Object

Methods

    (* Returns a stringified object reference of an object that supports the 
       Renderable interface.  The denoted object can be asked for a Rendering
       (e.g. text/isl, text/idl, text/midl, etc.) interface in which (the most 
       specific type) the object is defined.  *)
       
    GetInterfaceDefinitionSource () : String

End;


(* ************************************************************************ *)
(* ******************************** END *********************************** *)
(* ************************************************************************ *)


NgStream.isl

(* ************************************************************************ *)
(*
    Version 1.3 ISL for HTTP-NG, Dan Larner, 3-19-98

    This work is very preliminary - Comments welcomed and encouraged!
    'xxx' marks areas where thought is definitly needed
    Please send comments, suggestions, contributions, etc. to the http-ng
    mailinglist, w3c-http-ng@w3.org and/or to larner@parc.xerox.com.

*)


(* ************************************************************************ *)
(* *********************** DataSource ************************************* *)
(* ************************************************************************ *)

Interface NgStream Brand "NG" Imports 
    NgBasic      From ngbasic.isl
End;

(* This object type may be passed in invocations of operations meant for 
   asynchronous receipt of data (such as ReceiveRendering on a RenderingSink).
   It allows the Sink side some control over the streaming operations. 
   NOTE: Methods invocations are assumed to be processed at the Source in the
   order in which they were sent.  *)

Type OptionalDataSource = Optional DataSource; 

Type DataSource = Object

    Supertypes NgBasic.NgObject End

    Methods
    
    (* Called to abort the streaming that is associated with this object *)
    Asynchronous Abort (),
    
    (* Called to pause the streaming that is associated with this object *)
    Asynchronous Pause (),
    
    (* Called to resume the streaming that is associated with this object *)
    Asynchronous Resume (),
    
    (* Called to have the streaming that is associated with this object resend 
       a range of data *)
    Asynchronous Resend ( repeatRange : NgBasic.UnsignedInclusiveInterval ),
    
    (* Called to suggest the streaming that is associated with this object
       change its chunk size *)
    Asynchronous SuggestChunkSize ( suggestedSize : Cardinal )

End;


(* This object type is used for control over a Sink.
   NOTE: Methods invocations are assumed to be processed at the Sink in the
   order in which they were sent.  *)

Type DataSink = Object

    Supertypes NgBasic.NgObject End

    Methods
    
    (* Called to tell the sink where control information can be sent *)
    Asynchronous RegisterSourceControl (thesource : DataSource),
        
    (* Called to indicate that no more data will be sent *)
    Asynchronous Done ()

End;


(* ************************************************************************ *)
(* ******************************** END *********************************** *)
(* ************************************************************************ *)


NgRendering.isl

(* ************************************************************************ *)
(*
    Version 1.3 ISL for HTTP-NG, Dan Larner, 3-19-98

    This work is very preliminary - Comments welcomed and encouraged!
    'xxx' marks areas where thought is definitly needed
    Please send comments, suggestions, contributions, etc. to the http-ng
    mailinglist, w3c-http-ng@w3.org and/or to larner@parc.xerox.com.

*)

(* ************************************************************************ *)
(* *************************** Renderings ********************************* *)
(* ************************************************************************ *)

(* An Object of type Renderable is able to produce a rendering.  
   Examples renderings are a text description, a graphic, an html 
   page, an audio, etc.

   An Object of type RenderingSink is able to asynchrounously receive 
   renderings.
*)


Interface NgRendering Brand "NG" Imports 
    NgBasic                From ngbasic.isl,
    IANA-Charsets-Registry From ianacharsets.isl,
    NgCache                From ngcache.isl,
    NgStream               From ngstream.isl
End;


(* ************************************************************************ *)
(* *************************** Rendering Types ***************************** *)

(* Note:  any URIs here which are relative paths, are by default assumed to be
relative to the IANA registry - thus for example one might use "text/html".
xxx Need specification here about what the URI actually denotes *)

Type RenderingType             = NgBasic.URI;
Type RenderingTypeSequence     = NgBasic.URISequence;
Type RenderingEncoding         = NgBasic.URI;
Type RenderingEncodingSequence = NgBasic.URISequence;


(* The requestor of a rendering may supply rendering preferences.  The 
   preferences describe what characteristics a rendering must have.
   For those members which are sequences, an empty sequence indicates no
   particular preference, else the sequence is treated as an ordered
   list of preferences.  *)


(* ************************************************************************ *)
(* ******************** Rendering Preferences ***************************** *)
  
Type RenderingPreferences = Record

    (* analogous to HTTP Accept, Accept-Charset, Accept-Encoding
       Range, and User-Agent headers *)
       
    (* Which content types are actually acceptable is obtained by, taking the 
       set of all types specified by allowContentTypes (some of which may 
       actually indicate a group of types via wildcard or other means), and 
       subtracting from it the set of all types specified by 
       disallowContentTypes.  A zero length sequence for allowContentTypes 
       means all types.  A zero length sequence for disallowContentTypes
       means no types.  Should the result allowContentTypes - 
       disallowContentTypes  be empty, a NoRenderingMatch exception should be
       raised from the receiving method. *)
    allowContentTypes    : RenderingTypeSequence,
    disallowContentTypes : RenderingTypeSequence,
    
    (* Which encodings are actually acceptable is obtained by, taking the set 
       of all types specified by allowEncodings (some of which may actually 
       indicate a group of encodings via wildcard or other means), and 
       subtracting from it the set of all types specified by disallowEncodings.
       A zero length sequence for allowEncodings means all encodings.  A zero 
       length sequence for disallowEncodings means no encodings.  Should the
       result allowEncodings - disallowEncodings be empty, a 
       NoRenderingMatch exception should be raised from the receiving 
       method. *)
    allowEncodings    : RenderingEncodingSequence,
    disallowEncodings : RenderingEncodingSequence,
     
    (* Acceptable Charsets of the rendering bytes before any encoding. A zero 
       length sequence means any charset is acceptable  *)   
    acceptCharsets     : IANA-Charsets-Registry.CharsetMIBEnumValueSequence,

    (* Acceptible Locales of the rendering bytes before any encoding. A zero 
       length sequence means any locale is acceptable  *)   
    acceptLocales     : NgBasic.StringSequence,
    
    (* If not supplied, indicates that the entire rendering is requested.
       If supplied and of non-zero size, it indicates the range of bytes 
       desired from the rendering bytes before any encoding.  If the interval 
       is supplied and is of zero size, effect is similar to Http's Head 
       method. *)
    range              : NgBasic.OptionalUnsignedInclusiveInterval,
    
    (* xxx - Need specification here about what the URI actually denotes *)
    userAgent          : NgBasic.OptionalURI
    
End;


(* ************************************************************************ *)
(* *************************** Renderings ********************************* *)

(* actual bytes of a rendering *)
Type RenderingContentBytes       = Sequence Of Byte;  


Type RenderingChunk = Record
    contentRange    : NgBasic.OptionalUnsignedInclusiveInterval, 
    renderingBytes  : RenderingContentBytes    
End;
        

Type Rendering = Record
    (* analogous to HTTP Content-Type, Content-Range, Content-Language, 
       Content-Encoding and Content-MD5 headers *)
       
    (* Type of the rendering bytes before any encoding. *)
    contentType     : RenderingType,  
    
    (* Represents an ordered sequence of transformations that were applied to 
       the original contentType to arrive at the passed renderingBytes. e.g. 
       a,b,c means a( b( c(originalBytescontent)))  A zero length sequence 
       means no transformations were applied to the original bytes.*)
    contentEncoding : RenderingEncodingSequence,  
    
    (* If rangeEncoded is False, then contentRange is the range of the 
       rendering bytes before any encoding (unsupplied meaning all the bytes).
       If rangeEncoded is True, then contentRange applies to the transformed 
       bytes, e.g. to a( b( c(originalBytescontent))).  This is to allow for 
       the situation where there are intervening caches that have some of the
       encoded bytes available, but have no ability (through design or policy)
       to decode the bytes down to their original content. contentRange is 
       required with one exception: In the case where the RenderingPreferences 
       originally received specified a range of zero size (situation
       treated similarly to HTTP Head), and the actual size is undeterminable
       (e.g. a streaming live audio for example) then contentRange may be
       unsupplied, and in this case, rangeEncoded should be ignored. *)
    contentRange    : NgBasic.OptionalUnsignedInclusiveInterval, 
    rangeEncoded    : Boolean,
    
    (* charset the rendering is in - If not supplied, default is US-ASCII *)
    contentCharSet   : IANA-Charsets-Registry.CharsetMIBEnumValue, 
    
    (* locale rendering is in e.g. en-us, de, etc. If unspecified default en *)
    contentLocale : NgBasic.OptionalString,  
    
    (* encoded bytes of the rendering *)
    renderingBytes   : RenderingContentBytes 
    
End;

Type OptionalRendering = Optional Rendering;


(* ************************************************************************ *)
(* ******************** Rendering Exceptions **************************** *)

(* Can't supply or accept any rendering meeting the preferences or input - 
   contains a RenderingPreferences (with the optional range and userAgent not
   present) describing what is acceptable *)
   
Exception NoRenderingMatch : RenderingPreferences;


(* ************************************************************************ *)
(* ********************** RenderingSink Object **************************** *)

(* a RenderingProblemReport is used to pass information to asynchronous
   callbacks that would have normally been passed back as an exception 
   from the synchronous version of the same sort of call *)
   
Type RenderingProblemReport = Union
    noMatch          : RenderingPreferences,
    wouldBlock       : NgBasic.ExceptionInformation,
    objectNotExist   : NgBasic.ExceptionInformation
End;
 

Type RenderingSink = Object

    Supertypes NgStream.DataSink End

    Methods
    
    (* Called to tell the sink information about how to do caching.  If this
       is never called, then the Sink may cache in any manner it wishes, so
       typically this will be called before any Renderings are sent.  
       Any call to this method remains in effect until a subsequent call
       to this method occurs. *)
    Asynchronous RegisterResponseCacheControl 
                 ( responseCacheInfo : NgCache.OptionalResponseCacheControl ),

    (* RenderingProblem is called when an exception would have been raised from 
       calling GetRendering (with the same args as SendRendering) on the 
       Renderable object.  This is basically to allow exceptions to be 
       passed back as the result of an async method. report is examined 
       for the same information as the exceptions that would have been raised
       from calling GetRendering on the Renderable object. The calls to 
       the sink are considered Done if this method is called. *)
    Asynchronous RenderingProblem ( report : RenderingProblemReport ),
        
    (* ReceiveRendering is called as a result of a SendRendering call on a 
       Renderable. The calls to ReceiveRendering and ReceiveRenderingChunk
       are considered complete when the Done method is called. *)
    Asynchronous ReceiveRendering ( therendering : Rendering ),
    
    (* ReceiveRenderingChunk is called to send rendering bytes that
       differ only in contentRange and renderingBytes from the 
       Rendering in the last call to ReceiveRendering *)
    Asynchronous ReceiveRenderingChunk ( thechunk : RenderingChunk ),
    
    (* Called by the DataSource when something happens to its state such 
       that it needs to know what was last received by the Sink.  If the 
       OptionalCardinal return value is supplied, it indicates (w.r.t
       rangeEncoded) the next byte expected by the sink.  If it is not 
       supplied, it indicates that the sink has not yet received any 
       rendering chunks.
       *)
    Resynchronize ( ) : NgBasic.OptionalCardinal


End;



(* ************************************************************************ *)
(* ************************* Renderable Object **************************** *)

Type Renderable = Object  

    Supertypes NgBasic.NgObject End

    Methods

    (* find out what types of renderings are available.  The returned 
    RenderingPreferences describes what can be supplied. *)
    GetAvailableRenderings () : RenderingPreferences 
        Raises NgBasic.WouldBlock, NgBasic.ObjectNotExist End, 


    (* GetRendering - The caller supplies a RenderingPreferences record
       to specify the desired characteristics of the rendering. 
       The callee's method returns the appropriate range of bytes for the 
       best match it has for the rendering Preferences.  If no match is 
       possible, the callee raises the NoRenderingMatch exception which 
       contains a  RenderingPreferences describing what can be supplied.
    *)

    GetRendering ( renderingPreferences  : RenderingPreferences, 
                   requestCacheInfo      : NgCache.OptionalRequestCacheControl,
                   out responseCacheInfo : NgCache.OptionalResponseCacheControl ) 
                 : Rendering
        Raises NoRenderingMatch, NgBasic.WouldBlock, NgBasic.ObjectNotExist End,


    (* SendRendering is just like GetRendering only instead of synchronously
       returning the Rendering, it sends it asynchronously via calls to the 
       ReceiveRendering method on the supplied RenderingSink, The number of 
       bytes in each Rendering sent is up to the caller of ReceiveRendering, 
       but should be part of the range specified in renderingPreferences.
       If present, suggestedChunkSize is a suggestion on how large to make 
       the data in the calls to ReceiveRendering.  Typically, the implementation
       of SendRendering would arrange the following sequence of calls on the
       RenderingSink.  (Where [] indicates optional and * indicates zero or more.)
       
       When things are successful:
       
           [RegisterSourceControl] 
           [RegisterResponseCacheControl]
           ReceiveRendering
           ReceiveRenderingChunk*
           Done
       
       When there's a problem:
       
           RenderingProblem
       
       See RenderingSink's ReceiveRendering method.*)

    Asynchronous SendRendering( 
        renderingPreferences : RenderingPreferences,
        requestCacheInfo     : NgCache.OptionalRequestCacheControl,
        renderSink           : RenderingSink,
        suggestedChunkSize   : NgBasic.OptionalCardinal ),

    (* A Synchronous version of SendRendering. The
      intent is to allow the caller to simply know that the
      call was received. *)
    SendRenderingSynched( 
        renderingPreferences : RenderingPreferences,
        requestCacheInfo     : NgCache.OptionalRequestCacheControl,
        renderSink           : RenderingSink,
        suggestedChunkSize   : NgBasic.OptionalCardinal )

End;


(* ************************************************************************ *)
(* ***************** Renderable that you can 'Put' to ********************* *)

Type PutableRenderable = Object  

    Supertypes NgRendering.Renderable End

    Methods
        
    (* PutRendering - The caller supplies a Rendering record describing
       the write operation to take place.  If the supplied rendering input
       is unacceptable (e.g. wrong type, etc.) the callee raises the 
       NoRenderingMatch exception which contains a RenderingPreferences 
       describing what is acceptable.
    *)

    PutRendering ( renderingInput    : Rendering )
        Raises NoRenderingMatch, NgBasic.WouldBlock, NgBasic.Conflict, 
               NgBasic.ObjectNotExist End

End;


(* ************************************************************************ *)
(* ******************************** END *********************************** *)
(* ************************************************************************ *)


NgProperty.isl

(* ************************************************************************ *)
(* ************************************************************************ *)
(*
    Version 1.3 ISL for HTTP-NG, Dan Larner, 3-19-98

    This work is very preliminary - Comments welcomed and encouraged!
    'xxx' marks areas where thought is definitly needed
    Please send comments, suggestions, contributions, etc. to the http-ng 
    mailing list, w3c-http-ng@w3.org and/or to larner@parc.xerox.com.

*)

(* ************************************************************************ *)
(* *************************** Properties ********************************* *)
(* ************************************************************************ *)

(* 
A PropertySet object contains a list of name value pairs.  
In the Web for example, a WebDocument would inherit from PropertySet
so that various attributes (e.g. last modification time, authors, etc.)
could be accessed.

*)

Interface NgProperty Brand "NG" Imports
    NgBasic From ngbasic.isl
    End;


(* ************************************************************************ *)
(* ************************ Property Value Pairs ************************** *)

(* a property is simply a named attribute paired with some value *)

Type Property = NgBasic.NameValuePair;
    
Type PropertySequence = Sequence Of Property;
Type PropertyNames    = NgBasic.NameSequence;


(* ************************************************************************ *)
(* ******************************** Exceptions **************************** *)

(* doesn't know these properties *)
Exception UnknownPropertyNames : PropertyNames ;



(* ************************************************************************ *)
(* *************************** Property Set Object ************************ *)

Type PropertySet = Object

    Supertypes NgBasic.NgObject End

    Methods

    (* GetProperties returns a Set of the requested named 'Properties' and 
       their values.  Sending an empty sequence of propertiesToGet is 
       equivalent to saying send all the properties. *)
      
    GetProperties ( propertiesToGet : PropertyNames ) : PropertySequence
        Raises UnknownPropertyNames, NgBasic.WouldBlock, 
        NgBasic.ObjectNotExist End  
                          
End;


(* ************************************************************************ *)
(* *********************** Putable Property Set Object ******************** *)


(* PropertyModification Records are used when modifying property sets *)
Type PropertyModificationKind = Enumeration Add, Remove, Change End;

Type PropertyModification = Record

    propertyName : NgBasic.String,
    
    modification : PropertyModificationKind,
    
    (* present when modification is Add or Change *)
    value        : NgBasic.OptionalPickle 
End;

Type PropertyModificationSequence = Sequence Of PropertyModification;


Type PutablePropertySet = Object

    Supertypes PropertySet End

    Methods
        
    (* PutProperties sends a Set of the requested modifications.
       Properties are added, removed and changed per the modification records.
       If an exception is raised, no modifictions will have been made to the 
       PropertySet.
       *)
      
    PutProperties ( propertiesToSet : PropertyModificationSequence )
        Raises UnknownPropertyNames, NgBasic.WouldBlock, NgBasic.Conflict,
         NgBasic.ObjectNotExist End    
                  
End;


(* ************************************************************************ *)
(* ******************************** END *********************************** *)
(* ************************************************************************ *)


NgDocument.isl

(* ************************************************************************ *)
(*
    Version 1.3 ISL for HTTP-NG, Dan Larner, 3-19-98

    This work is very preliminary - Comments welcomed and encouraged!
    'xxx' marks areas where thought is definitly needed
    Please send comments, suggestions, contributions, etc. to the http-ng
    mailing list, w3c-http-ng@w3.org and/or to larner@parc.xerox.com.

*)

(* ************************************************************************ *)
(* *************************** Web Documents ****************************** *)
(* ************************************************************************ *)

(* Defines the concept of Web Documents *)


(* Import iluhttp so that we can offer easy compatability with the existing
   web - that is, anything object inheriting from iluhttp.Resource will
   support Get, Head, Put and Post methods as we know them in the current web
*)

Interface NgDocument Brand "NG" Imports 
    iluhttp         From iluhttp.isl,
    NgRendering     From ngrendering.isl, 
    NgRendering     From ngrendering.isl, 
    NgCache         From ngcache.isl, 
    NgProperty      From ngproperty.isl,
    NgStream        From ngstream.isl
    End;


(* ************************************************************************ *)
(* ******************** RenderingAndPropertiesSink  *********************** *)

(* a RenderingProblemReport is used to pass information to asynchronous
   callbacks that would have normally been passed back as an exception 
   from the synchronous version of the same sort of call *)
   
Type PropertiesProblemReport = Union
    wouldBlock        : NgBasic.ExceptionInformation,
    unknownProperties : NgProperty.PropertyNames
End;
    

Type RenderingAndPropertiesSink = Object  

    Supertypes NgRendering.RenderingSink End

    Methods
    
    (* PropertyProblem is called when a property related exception would 
       have been raised from calling GetRenderingAndProperties (with the 
       same args as SendRenderingAndProperties)  This is basically to 
       allow exceptions to be passed back as the result of an async method. 
       report is examined for the same information as the exceptions that 
       would have been raised from calling GetProperties on the WebDocument 
       object. The calls to the sink are considered Done if this method is 
       called. *)
    Asynchronous PropertiesProblem( report : PropertiesProblemReport),
    
    
     (* ReceiveProperties is called as a result of a
        SendRenderingAndProperties call on a WebDocument. *)

    Asynchronous ReceiveProperties (theproperties : NgProperty.PropertySequence)

End;


(* ************************************************************************ *)
(* ************************** WebDocument Interface *********************** *)

(* A WebDocument is meant to be an NG version of roughly what Web documents 
   are today *)
   
Type WebDocument = Object

    Supertypes  
        NgRendering.Renderable, 
        NgProperty.PropertySet
        End
  

    (* ************
       Properties which may be accessible via the property set interface
       include 

       Authors - a NgBasic.StringSequence,  The authors of this document

       CreationTime - a NgBasic.AbsoluteTime

       Version - a NgBasic.Version,

       Summary a NgBasic.String - some (human readable) summary of what
                                  the document is
    
      Note: The next two are analogous to the lastModified and expires members
            of the ResponseCacheControl Record
       
      LastModificationTime a NgBasic.AbsoluteTime
    
      ExpectedChange an NgBasic.AbsoluteTime - when this document is expected
                                               to change
    
      ***********  *)

Methods

    (* basically a combination of the GetRendering and GetProperties methods *)
    GetRenderingAndProperties (
        renderingPreferences  : NgRendering.RenderingPreferences, 
        requestCacheInfo      : NgCache.OptionalRequestCacheControl,
        out responseCacheInfo : NgCache.OptionalResponseCacheControl,
        propertiesToGet       : NgProperty.PropertyNames, 
        Out theproperties     : NgProperty.PropertySequence
                            ) : NgRendering.Rendering
            Raises NgRendering.NoRenderingMatch,
                   NgProperty.UnknownPropertyNames, 
                   NgBasic.WouldBlock,
                   NgBasic.ObjectNotExist End,

    (* SendRenderingAndProperties is just like GetRenderingAndProperties only 
       instead of synchronusly returning the results, they are sent 
       asynchronously via calls to the ReceiveRenderingAndProperties method 
       on the supplied RenderingAndPropertiesSink. The number of bytes in each 
       Rendering sent is up to the caller of ReceiveRenderingAndProperties, but 
       should be part of the range specified in renderingPreferences. 
       If present, suggestedChunkSize is a suggestion on how large to make 
       the data in the calls to ReceiveRenderingAndProperties. Typically, the 
       implementation of SendRenderingAndProperties would arrange the following 
       sequence of calls on the RenderingAndPropertiesSink.  (Where [] indicates 
       optional and * indicates zero or more.)
       
       When things are successful:
       
           [RegisterSourceControl] 
           [RegisterResponseCacheControl]
           ReceiveProperties
           ReceiveRendering
           ReceiveRenderingChunk*
           Done
       
       When there's a problem:
       
           RenderingProblem OR PropertiesProblem

       See
       RenderingAndPropertiesSink's ReceiveRenderingAndProperties method.*)
                  
    Asynchronous SendRenderingAndProperties (
        renderingPreferences  : NgRendering.RenderingPreferences, 
        requestCacheInfo      : NgCache.OptionalRequestCacheControl,
        propertiesToGet       : NgProperty.PropertyNames,
        renderPropSink        : RenderingAndPropertiesSink,
        suggestedChunkSize    : NgBasic.OptionalCardinal ),
        
   (* A Synchronous version of SendRenderingAndProperties. The
      intent is to allow the caller to simply know that the
      call was received. *)
    SendRenderingAndPropertiesSynched( 
        renderingPreferences  : NgRendering.RenderingPreferences, 
        requestCacheInfo      : NgCache.OptionalRequestCacheControl,
        propertiesToGet       : NgProperty.PropertyNames,
        renderPropSink        : RenderingAndPropertiesSink,
        suggestedChunkSize    : NgBasic.OptionalCardinal )        
        
End;


(* ************************************************************************ *)
(* *************** WebDocument that you can 'Put' to ********************** *)

Type PutableWebDocument = Object

    Supertypes 
        NgDocument.WebDocument,
        NgRendering.PutableRenderable,
        NgProperty.PutablePropertySet
        End
  
Methods
                     
    (* basically combination of the PutRendering and PutProperties methods *)
    PutRenderingAndProperties (
        renderingInput    : NgRendering.Rendering, 
        propertiesToSet   : NgProperty.PropertyModificationSequence)
            Raises NgRendering.NoRenderingMatch,
                   NgProperty.UnknownPropertyNames, 
                   NgBasic.WouldBlock,
                   NgBasic.Conflict, NgBasic.ObjectNotExist End
        
End;



(* ************************************************************************ *)
(* ************** HTTPCompatibleWebDocument Interface ************ ******** *)

(* A HTTPCompatibleWebDocument is a WebDocument that can also be accessed via 
   HTTP 1.x Get, Head and Post calls. *)
   
Type HTTPCompatibleWebDocument = Object

    Supertypes  
        WebDocument, 
        iluhttp.Resource
        End
;
  

(* ************************************************************************ *)
(* ******************************** END *********************************** *)
(* ************************************************************************ *)


NgForm.isl

(* ************************************************************************ *)
(*
    Version 1.3 ISL for HTTP-NG, Dan Larner, 3-19-98

    This work is very preliminary - Comments welcomed and encouraged!
    'xxx' marks areas where thought is definitly needed
    Please send comments, suggestions, contributions, etc. to the http-ng
    mailing list, w3c-http-ng@w3.org and/or to larner@parc.xerox.com.

*)

(* ************************************************************************ *)
(* *************************** FormProcessors ***************************** *)
(* ************************************************************************ *)

(* An Object of type FormProcessor is able to process Form based input, and 
   produce an appropriate rendering as a response.
*)


Interface NgFormProcessor Brand "NG" Imports 
    NgBasic                From ngbasic.isl,
    IANA-Charsets-Registry From ianacharsets.isl,
    NgCache                From ngcache.isl,    
    NgRendering            From ngrendering.isl
End;



(* ************************************************************************ *)
(* ********************* Form entries  ************************************ *)

(* a Form input element is simply a named form field paired with some value *)

Type FormInputElement = NgBasic.NameValuePair;
    
Type FormInputElementSequence = Sequence Of FormInputElement;
Type FormInputElementNames    = NgBasic.NameSequence;



(* ************************************************************************ *)
(* ******************** FormProcessing Exceptions ************************* *)

(* The listed form inputs has invalid values *)
   
Exception InvalidFormEntries : FormInputElementNames;




(* ************************************************************************ *)
(* ********************** ProcessedFormSink  ****************************** *)


(* a FormProblemReport is used to pass information to asynchronous
   callbacks that would have normally been passed back as an exception 
   from the synchronous version of the same sort of call *)
   
Type FormProblemReport = Union
    invalidEntries : FormInputElementNames,
    conflict       : NgBasic.ExceptionInformation,
    objectNotExist : NgBasic.ExceptionInformation
End;

Type OptionalFormProblemReport = Optional FormProblemReport; 


(* A ProcessedFormSink is basically a NgRendering.RenderingSink
   except that there are some more problems that can be reported *)

Type ProcessedFormSink = Object  

    Supertypes NgRendering.RenderingSink End

    Methods        
        
    (* FormProblem is called when a Form related exception would have been
       raised from calling ProcessForm (with the same args as SendForm) on the 
       FormProcessor object.  This is basically to allow exceptions to be 
       passed back as the result of an async method. report is examined 
       for the same information as the exceptions that would have been raised
       from calling ProcessForm on the FormProcessor object. The calls to 
       the sink are considered Done if this method is called. *)
    Asynchronous FormProblem ( report : FormProblemReport )

End;


(* ************************************************************************ *)
(* *********************** FormProcessor Object *************************** *)

Type FormProcessor = Object  

    Supertypes NgBasic.NgObject End

    Methods
        
    (* ProcessForm - The caller supplies a FormInputElementSequence describing
       the form data.  If the supplied formEntries input is unacceptable (e.g.
       wrong type, etc.) the callee raises the InvalidFormEntries exception 
       which contains a sequence of the names of the entries which were 
       unacceptable, else a Rendering is returned.
    *)

    ProcessForm ( formEntries          : FormInputElementSequence, 
                 out responseCacheInfo : NgCache.OptionalResponseCacheControl ) 
                 : NgRendering.Rendering
        Raises InvalidFormEntries, NgBasic.WouldBlock, NgBasic.Conflict, 
               NgBasic.ObjectNotExist End,


    (* SendFormReply is just like ProcessForm only instead of synchronously 
       returning the Rendering, it sends it asynchronously via a call to the 
       ReceiveFormResult method on the supplied ProcessedFormSink *)

    Asynchronous SendFormReply ( formEntries  : FormInputElementSequence, 
                                 formSink     : ProcessedFormSink ),
                            
                            
    (* A Synchronous version of SendForm. The intent is to allow the 
    caller to simply know that the call was received. *)
    SendFormReplySynched( 
        formEntries     : FormInputElementSequence, 
        formSink        : ProcessedFormSink )                            

End;


(* ************************************************************************ *)
(* ******************************** END *********************************** *)
(* ************************************************************************ *)


NgCache.isl

(* ************************************************************************ *)
(*
    Version 1.3 ISL for HTTP-NG, Dan Larner, 3-19-98

    This work is very preliminary - Comments welcomed and encouraged!
    'xxx' marks areas where thought is definitly needed
    Please send comments, suggestions, contributions, etc. to the http-ng 
    mailing list, w3c-http-ng@w3.org and/or to larner@parc.xerox.com.

*)
(* ************************************************************************ *)

(* ************************************************************************ *)
(* *************************** Caching Control **************************** *)
(* ************************************************************************ *)

(* Caching control provides cache and proxy relevant information that
   may be sent along with requests and responses.  This mostly mimics
   the cache related headers and Cache-Control header values found in 
   HTTP 1.1.  See that specification for the semantics. 
*)



Interface NgCache Brand "NG" Imports 

    NgBasic From ngbasic.isl
    
End;


(* ************************************************************************ *)
(* *************************** Entity tags ******************************** *)

Type EntityTag             = NgBasic.String;
Type OptionalEntityTag     = Optional NgBasic.String;

Type EntityTagSequence     = Sequence Of EntityTag;

Type EntityTagOrDate = Union
    etag   : EntityTag,
    ifdate : NgBasic.AbsoluteTime
End;    


(* ************************************************************************ *)
(* ***************** Request Cache Control ******************************** *)

Type RequestCacheControl = Record

    (* analogous to HTTP Cache-Control header values *)
    noCache         : Boolean,
    noStore         : Boolean,
    noTransform     : Boolean,
    onlyIfCached    : Boolean,
    
    (* analogous to HTTP If-ModifiedSince, If-Match, If-None-Match and
       If-Range headers *)                                      
    ifModifiedSince : NgBasic.OptionalAbsoluteTime,
    ifMatch         : EntityTagSequence,
    ifNoneMatch     : EntityTagSequence,
    ifRange         : EntityTagOrDate

End;

Type OptionalRequestCacheControl = Optional RequestCacheControl;  


(* ************************************************************************ *)
(* ***************** Response Cache Control ******************************* *)

Type ResponseCacheControl = Record
   
    (* analogous to HTTP  Cache-Control header values*)
    okPublic        : Boolean,
    isPrivate       : Boolean,
    noCache         : Boolean,
    noStore         : Boolean,
    noTransform     : Boolean,
    mustRevalidate  : Boolean,
    proxyRevalidate : Boolean,
    maxAge          : NgBasic.OptionalRelativeTime,
    sMaxAge         : NgBasic.OptionalRelativeTime,
    
    (* analogous to HTTP Age, Vary, Etag, Last-Modified and Expires headers *)
    age             : NgBasic.OptionalRelativeTime,
    vary            : NgBasic.StringSequence,
    entityTag       : OptionalEntityTag,
    lastModified    : NgBasic.OptionalAbsoluteTime,
    expires         : NgBasic.OptionalAbsoluteTime
   
End;
   
Type OptionalResponseCacheControl = Optional ResponseCacheControl;


(* ************************************************************************ *)
(* ******************************** END *********************************** *)
(* ************************************************************************ *)


IANACharSets.isl

(* ************************************************************************ *)
(*
    Version 1.3 ISL for HTTP-NG, Dan Larner, 3-19-98

    This work is very preliminary - Comments welcomed and encouraged!
    'xxx' marks areas where thought is definitly needed
    Please send comments, suggestions, contributions, etc. to the http-ng 
    mailing list, w3c-http-ng@w3.org and/or to larner@parc.xerox.com.

*)

(* ************************************************************************ *)
(* *************************** IANA Charsets ****************************** *)
(* ************************************************************************ *)

(* Defines standard charsets.        *)


Interface IANA-Charsets-Registry Brand "NG" ;


Type CharsetMIBEnumValue = Short Cardinal;

Type CharsetMIBEnumValueSequence = Sequence Of CharsetMIBEnumValue;  

Type OptionalCharsetMIBEnumValue = Optional CharsetMIBEnumValue;  

Constant US-ASCII : CharsetMIBEnumValue = 3;
  
(* XXX need to complete the list *)


(* ************************************************************************ *)
(* ******************************** END *********************************** *)
(* ************************************************************************ *)