(* $Id: nethttp.mli,v 2.1 2005/07/25 22:36:41 stolpmann Exp $ 
 * ----------------------------------------------------------------------
 * Nethttp: Basic definitions for the HTTP protocol
 *)

(** {1 Basic definitions for the HTTP protocol} *)

(** These definitions can be used by both HTTP clients and servers, and by
  * protocols in the middle, e.g. CGI.
 *)

type protocol_version = 
    int * int           (* (major,minor) number *)
      (** A pair of a major and minor version number *)

type protocol_attribute =
  [ `Secure_https
  ]

type protocol =
  [ `Http of (protocol_version * protocol_attribute list)
  | `Other
  ]
  (** The base protocol. RFC 2145 defines how to interpret major and minor numbers.
   *  In particular, we have:
   * - [`Http((0,9),_)] is the ancient HTTP version 0.9
   * - [`Http((1,n),_)] is the HTTP protocol 1.n.  It is expected that all these versions
   *   are compatible to each other except negotiable features.
   * - [`Http((m,_),_)] for m>1 is regarded as unknown protocol, incompatible to 
   *   any [`Http((1,n),_)]
   * - [`Other] is anything else (unrecognizes protocol)
   *
   *)

val string_of_protocol : protocol -> string
  (** Returns the string representation, e.g. "HTTP/1.0". Fails for [`Other] *)

val protocol_of_string : string -> protocol
  (** Parses the protocol string, e.g. "HTTP/1.0". Returns [`Other] for unrecognized
    * strings
   *)

type http_status =   (* Status codes from RFC 2616 *)
  (* 1xx: (informational) *)
  [ `Continue
  | `Switching_protocols 
  (* 2xx: (successful) *)
  | `Ok
  | `Created
  | `Accepted
  | `Non_authoritative
  | `No_content
  | `Reset_content
  | `Partial_content
  (* 3xx: (redirection) *)
  | `Multiple_choices
  | `Moved_permanently
  | `Found
  | `See_other
  | `Not_modified
  | `Use_proxy
  | `Temporary_redirect
  (* 4xx: (client error) *)
  | `Bad_request
  | `Unauthorized
  | `Payment_required
  | `Forbidden
  | `Not_found
  | `Method_not_allowed
  | `Not_acceptable
  | `Proxy_auth_required
  | `Request_timeout
  | `Conflict
  | `Gone
  | `Length_required
  | `Precondition_failed
  | `Request_entity_too_large
  | `Request_uri_too_long
  | `Unsupported_media_type
  | `Requested_range_not_satisfiable
  | `Expectation_failed
  (* 5xx: (server error) *)
  | `Internal_server_error
  | `Not_implemented
  | `Bad_gateway
  | `Service_unavailable
  | `Gateway_timeout
  | `Http_version_not_supported 
  ]
  (** HTTP response status:
   * 
   * {b Informational (1xx):}
   * - [`Continue]
   * - [`Switching_protocols]
   *
   * {b Successful (2xx):}
   * - [`Ok]
   * - [`Created]
   * - [`Accepted]
   * - [`Non_authoritative]
   * - [`No_content]
   * - [`Reset_content]
   * - [`Partial_content]
   *
   * {b Redirection (3xx):}
   * - [`Multiple_choices]
   * - [`Moved_permanently]
   * - [`Found]
   * - [`See_other]
   * - [`Not_modified]
   * - [`Use_proxy]
   * - [`Temporary_redirect]
   * 
   * {b Client error (4xx):}
   * - [`Bad_request]
   * - [`Unauthorized]
   * - [`Payment_required]
   * - [`Forbidden]
   * - [`Not_found]
   * - [`Method_not_allowed]
   * - [`Not_acceptable]
   * - [`Proxy_auth_required]
   * - [`Request_timeout]
   * - [`Conflict]
   * - [`Gone]
   * - [`Length_required]
   * - [`Precondition_failed]
   * - [`Request_entity_too_large]
   * - [`Request_uri_too_long]
   * - [`Unsupported_media_type]
   * - [`Request_range_not_satisfiable]
   * - [`Expectation_failed]
   *
   * {b Server Error (5xx):}
   * - [`Internal_server_error]
   * - [`Not_implemented]
   * - [`Bad_gateway]
   * - [`Service_unavailable]
   * - [`Gateway_timeout]
   * - [`Http_version_not_supported]
   *)


val int_of_http_status : http_status -> int
  (** Returns the integer code for a status value *)

val http_status_of_int : int -> http_status
  (** Returns the status value for an integer code, or raises [Not_found] *)

val string_of_http_status : http_status -> string
  (** Returns the informational text for a status value *)
  (* See also Netcgi.status_line *)

type http_method = string * string
  (** Method name, URI *)

type cache_control_token =
    [ `No_store
    | `Max_age of int
    | `Max_stale of int option
    | `Min_fresh of int
    | `No_transform
    | `Only_if_cached
    | `Public
    | `Private of string list
    | `No_cache of string list
    | `Must_revalidate
    | `Proxy_revalidate
    | `S_maxage of int
    | `Extension of string * string option
    ]
    (** The cache control token for the [Cache-control] header *)

type etag =
    [ `Weak of string
    | `Strong of string
    ]
   (** Entity tags can be weak or strong *)

val weak_validator_match : etag -> etag -> bool
  (** Whether the tags match weakly (see RFC 2616 for definition) *)

val strong_validator_match : etag -> etag -> bool
  (** Whether the tags match strongly (see RFC 2616 for definition) *)

exception Bad_header_field of string
  (** Raised when a header field cannot be parsed. The string argument is the
    * name of the failing function
   *)

class type http_header = Netmime.mime_header
  (** The HTTP header is represented as MIME header *)

class type http_trailer = Netmime.mime_header
  (** The HTTP trailer is represented as MIME header *)

val status_of_cgi_header : http_header -> (int * string)
  (** Returns the status code and the status text corresponding to the [Status]
    * header
   *)

type cookie = (* Cgi.cookie =  *)
    { cookie_name : string;
        (** The name of the cookie *)
      cookie_value : string;
        (** The value of the cookie. There are no restrictions on the
	 * value of the cookie
	 *)
      cookie_expires : float option;
        (** Expiration:
	 *  - [None]: the cookie expires when the browser session ends.
         *  - [Some t]: the cookie expires at the time [t] (seconds since
	 *    the epoch)
         *) 
      cookie_domain : string option;
        (** Cookies are bound to a certain domain, i.e. the browser sends
	 * them only when web pages of the domain are requested:
	 *
	 *  - [None]: the domain is the hostname of the server
         *  - [Some domain]: the domain is [domain]
         *)
      cookie_path : string option;
        (** Cookies are also bound to certain path prefixes, i.e. the browser
	 * sends them only when web pages at the path or below are requested.
	 *
	 * - [None]: the path is script name + path_info
         * - [Some p]: the path is [p]. With [Some "/"] you can disable the
	 *   path restriction completely.
         *)
      cookie_secure : bool;
        (** Cookies are also bound to the type of the web server: 
	 * [false] means servers without SSL, [true] means servers with
	 * activated SSL ("https").
	 *)
    }

val decode_query : string -> (string * string)
  (** Splits the URI into a "script name" and a "query string" *)

val split_host_port : string -> (string * int option)
  (** Splits the [Host] header in hostname and optional port number.
    * Fails on syntax error
   *)

val uripath_encode : string -> string
  (** Encodes unsafe characters in URI paths. The slash character is not encoded.
    * This function should only be applied to the part before '?'.
   *)

val uripath_decode : string -> string
  (** Decodes %XX sequences in URI paths. %2F is forbidden (failure).
    * This function should only be applied to the part before '?'.
   *)


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

(** {2 Parsing and Printing of Headers} *)

module Header : sig
  (** This module is a parser/printer for the header fields used in HTTP/1.1.
    * The [get_*] functions generally raise [Not_found] when the queried header
    * is not present. If the syntax of the field is a comma-separated list of
    * multiple values, the [get_*] functions generally merge all headers of 
    * the same type. The order is preserved in this case. The list [[]] means
    * that the header exists, but only with empty value. For example,
    *
    * {[
    * Accept: text/html
    * Accept: text/plain
    * ]}
    *
    * would be returned as [["text/html",[],[]; "text/plain", [],[]]] by [get_accept].
    * The header
    *
    * {[Accept:]}
    *
    * would be returned as [[]].
    *
    * The [set_*] functions generally produce only a single header with comma-
    * separated values. Existing header are overwritten/removed.
    *
    * To remove a header, simply use the [delete_field] method of [http_header].
    *
    * Error behaviour: The [get_*] functions raise [Bad_header_field] when they
    * cannot parse a header field. The [set_*] functions raise [Invalid_argument]
    * when an invalid value is passed to them (only very few functions do that).
    * The argument of both exceptions is the function name.
   *)

  val get_accept : #http_header -> (string *
		                 (string * string) list *
			        (string * string) list) list
    (** Returns the [Accept] header as list of triples 
      * [(media_range, media_range_params, accept_params)].
      * If there are [accept_params], the first such parameter is always ["q"].
      *
      * All present [Accept] headers are merged. The function returns [[]] when
      * there is at least one [Accept] header, but none of the headers has a
      * non-empty value. The function raises [Not_found] if there no such headers
      * at all (which should be interpreted as [ ["*/*",[],[] ] ]).
     *)

  val best_media_type : #http_header -> string list -> ( string * (string * string) list )
    (** Returns the best media type for a header and a list of supported types.
      * If any type is acceptable, "*/*" will be returned. If no type is acceptable,
      * "" will be returned.
      * The supported media types should be sorted such that the best type
      * is mentioned first.
      *
      * Known bug: The rule that media ranges are sorted by degree of "specificness"
      * is not implemented, e.g. that "text/html" is preferred over other "text/*"
      * when both have the same "q" value. 
     *)

  val set_accept : #http_header -> (string *
		                 (string * string) list *
			        (string * string) list) list -> unit
    (** Sets the [Accept] header *)

  val get_accept_charset : #http_header -> (string *
					 (string * string) list) list
    (** Returns the [Accept-charset] header as list of pairs [(charset,params)].
      * The only mentioned parameter in RFC 2616 is ["q"].
      *
      * All present [Accept-charset] headers are merged. The function raises [Not_found]
      * when there is no [Accept-charset] header (which should be interpreted as
      * [ ["*",[]] ]).
     *)

  val best_charset : #http_header -> string list -> string
    (** Returns the best charset for a header and a list of supported charsets.
      * If any charset is acceptable, "*" will be returned.
      * The supported charsets should be sorted such that the best charset
      * is mentioned first.
      *
      * This function already implements the special handling of ISO-8859-1
      * mentioned in RFC 2616.
     *)

  val set_accept_charset : #http_header -> (string *
					 (string * string) list) list -> unit
    (** Sets the [Accept-charset] header *)

  val get_accept_encoding : #http_header -> (string *
					(string * string) list) list
    (** Returns the [Accept-encoding] header as list of pairs [(coding,params)].
      * The only mentioned parameter in RFC 2616 is ["q"]. The RFC describes
      * compatibility problems with the "q" parameter.
      *
      * All present [Accept-encoding] headers are merged. The function raises [Not_found]
      * when there is no [Accept-encoding] header (which should be interpreted as
      * [ ["identity",[]] ]). The return value [[]] must be interpreted as
      * [ ["identity",[]] ].
     *)

  val best_encoding : #http_header -> string list -> string
    (** Returns the best encoding for a header and a list of supported encodings.
      * If anything else fails, "identity" will be returned.
      * The supported encodings should be sorted such that the best encoding
      * is mentioned first.
     *)

  val set_accept_encoding : #http_header -> (string *
					(string * string) list) list -> unit
    (** Sets the [Accept-encoding] header *)

  val get_accept_language : #http_header -> (string *
					(string * string) list) list
    (** Returns the [Accept-language] header as list of pairs [(lang_range,params)].
      * The only mentioned parameter in RFC 2616 is ["q"].
      *
      * All present [Accept-language] headers are merged. The function raises [Not_found]
      * when there is no [Accept-language] header (which should be interpreted as
      * [ ["*",[]] ]). 
     *)

  val set_accept_language : #http_header -> (string *
					(string * string) list) list -> unit
    (** Sets the [Accept-language] header *)

  val get_accept_ranges : #http_header -> string list
    (** Returns the [Accept-ranges] header as list of tokens.
      * 
      * All present [Accept-ranges] headers are merged. The function raises [Not_found]
      * when there is no [Accept-ranges] header. The RFC leaves it open how this is
      * to be interpreted in general.
     *)

  val set_accept_ranges : #http_header -> string list -> unit
    (** Sets the [Accept-ranges] header *)

  val get_age : #http_header -> float
    (** Returns the [Age] header as number
     *)

  val set_age : #http_header -> float -> unit
    (** Sets the [Age] header *)

  val get_allow : #http_header -> string list
    (** Returns the [Allow] header as list of tokens.
      *
      * All present [Allow] headers are merged. The function raises [Not_found]
      * when there is no [Allow] header. The RFC leaves it open how this is
      * to be interpreted in general.
     *)

  val set_allow : #http_header -> string list -> unit
    (** Sets the [Allow] header *)

  val get_authorization : #http_header -> (string * (string * string) list)
    (** Returns the [Authorization] header as pair [(auth_scheme,auth_params)],
      * or raises [Not_found] if not present.
      *
      * The "Basic" authentication scheme is represented specially as
      * [("basic", [ "credentials", creds ])] where [creds] are the
      * Base64-encoded credentials.
     *)

  val set_authorization : #http_header -> 
                               (string * (string * string) list) -> unit
    (** Sets the [Authorization] header.
      * The "Basic" authentication scheme is represented as explained for
      * [get_authorization].
     *)

  val get_cache_control : #http_header -> cache_control_token list
    (** Returns the [Cache-control] header as list of tokens.
      *
      * All present [Cache-control] headers are merged. The function raises [Not_found]
      * when there is no [Cache-control] header. 
     *)

  val set_cache_control : #http_header -> cache_control_token list -> unit
    (** Sets the [Cache-control] header *)

  val get_connection : #http_header -> string list
    (** Returns the [Connection] header as list of tokens.
      *
      * All present [Connection] headers are merged. The function raises [Not_found]
      * when there is no [Connection] header. 
      *
      * The Connection header must be ignored when received from a HTTP/1.0 client.
     *)

  val set_connection : #http_header -> string list -> unit
    (** Sets the [Connection] header *)

  val get_content_encoding : #http_header -> string list
    (** Returns the [Content-encoding] header as list of tokens.
      *
      * All present [Content-encoding] headers are merged. The function raises [Not_found]
      * when there is no [Content-encoding] header. 
     *)

  val set_content_encoding : #http_header -> string list -> unit
    (** Sets the [Content-encoding] header *)

  val get_content_language : #http_header -> string list
    (** Returns the [Content-language] header as list of tokens.
      *
      * All present [Content-language] headers are merged. The function raises [Not_found]
      * when there is no [Content-language] header. 
     *)

  val set_content_language : #http_header -> string list -> unit
    (** Sets the [Content-language] header *)

  val get_content_length : #http_header -> int64
    (** Returns the [Content-length] header as number. If the number is too big for
      * int64, the exception [Bad_header_field "Content-length"] will be raised.
      * Raises [Not_found] when the header is missing.
     *)

  val set_content_length : #http_header -> int64 -> unit
    (** Sets the [Content-length] header *)

  val get_content_location : #http_header -> string
    (** Returns the [Content-location] header as string.  Raises [Not_found] when the 
      * header is missing.
     *)

  val set_content_location : #http_header -> string -> unit
    (** Sets the [Content-location] header *)

  val get_content_md5 : #http_header -> string
    (** Returns the [Content-MD5] header as string. The Base64 encoding has not been
      * touched. Raises [Not_found] when the header is missing.
     *)

  val set_content_md5 : #http_header -> string -> unit
    (** Sets the [Content-MD5] header *)

  val get_content_range : #http_header -> [ `Bytes of (int64*int64) option * int64 option ]
    (** Returns the [Content-range] header as 
      * [`Bytes(byte_range_resp_spec, instance_length)]. The option value [None]
      * corresponds to "*" in the RFC.
      * Raises [Not_found] when the header is missing.
     *)

  val set_content_range : #http_header -> 
                          [ `Bytes of (int64*int64) option * int64 option ] -> unit
    (** Sets the [Content-range] header *)

  val get_content_type : #http_header -> string * (string * string) list
    (** Returns the [Content-type] header as pair [(media_type, params)].
      * Raises [Not_found] when the header is missing.
     *)

  val set_content_type : #http_header -> string * (string * string) list -> unit
    (** Sets the [Content-type] header *)

  val get_date : #http_header -> float
    (** Returns the [Date] header as number (seconds since the Epoch).
      * Raises [Not_found] when the header is missing.
     *)

  val set_date : #http_header -> float -> unit
    (** Sets the [Date] header *)

  val get_etag : #http_header -> etag
    (** Returns the [Etag] header.
      * Raises [Not_found] when the header is missing.
     *)

  val set_etag : #http_header -> etag -> unit
    (** Sets the [Etag] header *)

  val get_expect : #http_header -> (string * string option * (string * string) list) list
    (** Returns the [Expect] header as list of triples [(token,value,params)].
      *
      * All present [Expect] headers are merged. The function raises [Not_found]
      * when there is no [Expect] header. 
     *)

  val set_expect : #http_header -> 
                   (string * string option * (string * string) list) list -> unit
    (** Sets the [Expect] header *)

  val get_expires : #http_header -> float
    (** Returns the [Expires] header as number (seconds since the Epoch).
      * Raises [Not_found] when the header is missing.
     *)

  val set_expires : #http_header -> float -> unit
    (** Sets the [Expires] header *)

  val get_from : #http_header -> string
    (** Returns the [From] header as string.
      * Raises [Not_found] when the header is missing.
     *)

  val set_from : #http_header -> string -> unit
    (** Sets the [From] header *)

  val get_host : #http_header -> string * int option
    (** Returns the [Host] header as pair [(host,port)].
      * Raises [Not_found] when the header is missing.
     *)

  val set_host : #http_header -> string * int option -> unit
    (** Sets the [Host] header *)

  val get_if_match : #http_header -> etag list option
    (** Returns the [If-match] header. The value [None] means "*".
      * Raises [Not_found] when the header is missing.
     *)

  val set_if_match : #http_header -> etag list option -> unit
    (** Sets the [If-match] header *)
  val get_if_modified_since : #http_header -> float
    (** Returns the [If-modified-since] header as number (seconds since the Epoch).
      * Raises [Not_found] when the header is missing.
     *)

  val set_if_modified_since : #http_header -> float -> unit
    (** Sets the [If-modified-since] header *)

  val get_if_none_match : #http_header -> etag list option
    (** Returns the [If-none-match] header. The value [None] means "*".
      * Raises [Not_found] when the header is missing.
     *)

  val set_if_none_match : #http_header -> etag list option -> unit
    (** Sets the [If-none-match] header *)

  val get_if_range : #http_header -> [ `Etag of etag | `Date of float ]
    (** Returns the [If-range] header. 
      * Raises [Not_found] when the header is missing.
     *)
  val set_if_range : #http_header -> [ `Etag of etag | `Date of float ] -> unit
    (** Sets the [If-range] header *)

  val get_if_unmodified_since : #http_header -> float
    (** Returns the [If-unmodified-since] header as number (seconds since the Epoch).
      * Raises [Not_found] when the header is missing.
     *)

  val set_if_unmodified_since : #http_header -> float -> unit
    (** Sets the [If-unmodified-since] header *)

  val get_last_modified : #http_header -> float
    (** Returns the [Last-modified] header as number (seconds since the Epoch).
      * Raises [Not_found] when the header is missing.
     *)

  val set_last_modified : #http_header -> float -> unit
    (** Sets the [Last-modified] header *)

  val get_location : #http_header -> string
    (** Returns the [Location] header as string.
      * Raises [Not_found] when the header is missing.
     *)
  val set_location : #http_header -> string -> unit
    (** Sets the [Location] header *)

  val get_max_forwards : #http_header -> int
    (** Returns the [Max-forwards] header as number.
      * Raises [Not_found] when the header is missing.
     *)

  val set_max_forwards : #http_header -> int -> unit
    (** Sets the [Max-forwards] header *)

  val get_pragma : #http_header -> (string * string option) list
    (** Returns the [Pragma] header as list of pairs [(token,value)].
      *
      * All present [Pragma] headers are merged. The function raises [Not_found]
      * when there is no [Pragma] header. 
     *)

  val set_pragma : #http_header -> (string * string option) list -> unit
    (** Sets the [Pragma] header *)

  val get_proxy_authenticate : #http_header -> 
                                 (string * (string * string) list) list
    (** Returns the [Proxy-authenticate] header as list of challenges
      * [(auth_scheme,auth_params)].
      *
      * All present [Proxy-authenticate] headers are merged. The function raises [Not_found]
      * when there is no [Proxy-authenticate] header. 
     *)

  val set_proxy_authenticate : #http_header -> 
                                 (string * (string * string) list) list -> unit
    (** Sets the [Proxy-authenticate] header *)

  val get_proxy_authorization : #http_header -> (string * (string * string) list)
    (** Returns the [Proxy-authorization] header as pair 
      * [(auth_scheme,auth_params)].Raises [Not_found] when the header is
      * missing.
      *
      * The "Basic" authentication scheme is represented specially as
      * [("basic", [ "credentials", creds ])] where [creds] are the
      * Base64-encoded credentials.
     *)

  val set_proxy_authorization : #http_header -> 
                                   (string * (string * string) list)-> unit
    (** Sets the [Proxy-authorization] header 
      * The "Basic" authentication scheme is represented as explained for
      * [get_proxy_authorization].
      *)

  val get_range : #http_header -> [`Bytes of (int64 option * int64 option) list ]
    (** Returns the [Range] header as [`Bytes ranges], where the list [ranges]
      * has elements of the form [(Some first_pos, Some last_pos)],
      * [(Some first_pos, None)] (prefix range), or [(None, Some last_pos)] (suffix
      * range).
      * Raises [Not_found] when the header is missing.
     *)

  val set_range : #http_header -> [`Bytes of (int64 option * int64 option) list ] -> unit
    (** Sets the [Range] header *)

  val get_referer : #http_header -> string
    (** Returns the [Referer] header as string.
      * Raises [Not_found] when the header is missing.
     *)

  val get_referrer : #http_header -> string
    (** Same, for addicts of correct orthography *)

  val set_referer : #http_header -> string -> unit
    (** Sets the [Referer] header *)

  val set_referrer : #http_header -> string -> unit
    (** Same, for addicts of correct orthography *)

  val get_retry_after : #http_header -> [ `Date of float | `Seconds of int ]
    (** Returns the [Retry-after] header.
      * Raises [Not_found] when the header is missing.
     *)

  val set_retry_after : #http_header -> [ `Date of float | `Seconds of int ] -> unit
    (** Sets the [Retry-after] header *)

  val get_server : #http_header -> string
    (** Returns the [Server] header as uninterpreted string (including comments).
      * Raises [Not_found] when the header is missing.
     *)

  val set_server : #http_header -> string -> unit
    (** Sets the [Server] header *)

  val get_te : #http_header -> (string *
		              (string * string) list *
		              (string * string) list) list
    (** Returns the [TE] header as list of triples 
      * [(te_token, te_params, accept_params)].
      * If there are [accept_params], the first such parameter is always ["q"].
      *
      * All present [TE] headers are merged. The function returns [[]] when
      * there is at least one [TE] header, but none of the headers has a
      * non-empty value. The function raises [Not_found] if there no such headers
      * at all.
     *)

  val set_te : #http_header -> (string *
		              (string * string) list *
		              (string * string) list) list -> unit
    (** Sets the [TE] header *)

  val get_trailer : #http_header -> string list
    (** Returns the [Trailer] header as list of field names.
      *
      * All present [Trailer] headers are merged. The function returns [[]] when
      * there is at least one [Trailer] header, but none of the headers has a
      * non-empty value. The function raises [Not_found] if there no such headers
      * at all.
     *)

  val set_trailer : #http_header -> string list -> unit
    (** Sets the [Trailer] header *)

  val get_transfer_encoding : #http_header -> (string * (string * string) list) list
    (** Returns the [Transfer-encoding] header as list of pairs
      * [(token, params)].
      *
      * All present [Transfer-encoding] headers are merged. The function returns [[]] when
      * there is at least one [Transfer-encoding] header, but none of the headers has a
      * non-empty value. The function raises [Not_found] if there no such headers
      * at all.
     *)

  val set_transfer_encoding : #http_header -> (string * (string * string) list) list -> unit
    (** Sets the [Transfer-encoding] header *)

  val get_upgrade : #http_header -> string list
    (** Returns the [Upgrade] header as list of products.
      * 
      * All present [Upgrade] headers are merged. The function returns [[]] when
      * there is at least one [Upgrade] header, but none of the headers has a
      * non-empty value. The function raises [Not_found] if there no such headers
      * at all.
     *)

  val set_upgrade : #http_header -> string list -> unit
    (** Sets the [Upgrade] header *)

  val get_user_agent : #http_header -> string
    (** Returns the [User-agent] header as uninterpreted string (including comments).
      * Raises [Not_found] if the header is missing.
     *)

  val set_user_agent : #http_header -> string -> unit
    (** Sets the [User-agent] header *)

  val get_vary : #http_header -> [ `Star | `Fields of string list ]
    (** Returns the [Vary] header.
      * Raises [Not_found] if the header is missing.
     *)

  val set_vary : #http_header -> [ `Star | `Fields of string list ] -> unit
    (** Sets the [Vary] header *)
(*
  val get_via : #http_header -> (string option * string * string * string option) list
    (** Returns the [Via] header as list of tuples
      * [(proto_name, proto_version, received_by, comment)].
      *
      * All present [Via] headers are merged. 
      * Raises [Not_found] if the header is missing.
     *)
 *)
(*
  val set_via : #http_header -> (string option * string * string * string option) list -> unit
    (** Sets the [Via] header *)
 *)
(*
  val get_warning : #http_header -> (int * string * string * float option) list
    (** Returns the [Warning] header as list of tuples
      * [(code, agent, text, date)].
      *
      * All present [Warning] headers are merged. 
      * Raises [Not_found] if the header is missing.
     *)
 *)
(*
  val set_warning : #http_header -> (int * string * string * float option) list -> unit
    (** Sets the [Warning] header *)
 *)

  val get_www_authenticate : #http_header -> 
                                 (string * (string * string) list) list
    (** Returns the [WWW-Authenticate] header as list of challenges
      * [(auth_scheme,auth_params)].
      *
      * All present [WWW-Authenticate] headers are merged. 
      * Raises [Not_found] if the header is missing.
     *)

  val set_www_authenticate : #http_header -> 
                               (string * (string * string) list) list -> unit
    (** Sets the [WWW-Authenticate] header *)

  val get_cookie : #http_header -> (string * string) list
    (** Get the cookies as (name,value) pairs (or Not_found) *)

  val set_cookie : #http_header -> (string * string) list -> unit
    (** Set the [Cookie] header. Note: This does not set cookies in the client, use 
      * [set_set_cookie] instead!
     *)

(*
  val get_set_cookie : #http_header -> cookie list
 *)

  val set_set_cookie : #http_header -> cookie list -> unit
    (** Set the [Set-Cookie] header
     *)


end
