\input texinfo   @c -*-texinfo-*-

@c %**start of header
@setfilename aws.info
@settitle Ada Web Server User's Guide
@setchapternewpage odd
@syncodeindex fn cp

@iftex
@afourpaper
@end iftex

@c ----------------------------------------- MACRO

@c Macro used for all AWS examples
@c No cartouche on HTML as this is part of the css
@macro AWSEXP{TXT}
@ifhtml
@smallexample
@group
\TXT\
@end group
@end smallexample
@end ifhtml
@ifnothtml
@cartouche
@smallexample
@group
\TXT\
@end group
@end smallexample
@end cartouche
@end ifnothtml
@end macro

@c ----------------------------------------- END MACRO

@titlepage

@title Ada Web Server User's Guide
@subtitle AWS - version @_AWS_VERSION_@
@subtitle Support for SOAP 1.1 - version @_SOAP_VERSION_@
@subtitle SMTP, POP, LDAP and Jabber protocols.
@subtitle Date: @today{}
@author AdaCore

@vskip 0pt plus 1filll

@page

Copyright @copyright{} 2000, Pascal Obry

Copyright @copyright{} 2001, Pascal Obry, Dmitriy Anisimkov

Copyright @copyright{} 2002-2010, AdaCore

@*

This document may be copied, in whole or in part, in any form or by any
means, as is or with alterations, provided that (1) alterations are clearly
marked as alterations and (2) this copyright notice is included
unmodified in any copy.

@end titlepage

@ifhtml
@c title page for the HTML documentation
@html
<font size="+2">
<p>AWS - version @_AWS_VERSION_@
<p>Support for SOAP 1.1 - version @_SOAP_VERSION_@
<p>SMTP, POP, LDAP and Jabber protocols.
<p>Document revision level $Revision: 167905 $
<p>Date: @today{}
<p>AdaCore
</font>

@page

<p>Copyright @copyright{} 2000, Pascal Obry

<p>Copyright @copyright{} 2001, Pascal Obry, Dmitriy Anisimkov

<p>Copyright @copyright{} 2002-2007, AdaCore

<p>This document may be copied, in whole or in part, in any form or by any
means, as is or with alterations, provided that (1) alterations are clearly
marked as alterations and (2) this copyright notice is included
unmodified in any copy.
@end html
@end ifhtml

@finalout

@contents

@ifinfo
@node Top
@top Ada Web Server

@menu
* Introduction::
* Building AWS::
* Using AWS::
* High level services::
* Using SOAP::
* Using WSDL::
* Working with mails::
* LDAP::
* Jabber::
* Resources::
* Status page::
* References::
* AWS API Reference::
* Index::
@end menu
@end ifinfo

@c ======================================================================

@node Introduction
@chapter Introduction

@noindent
@code{AWS} stand for @i{Ada Web Server}. It is an Ada implementation of the
@code{HTTP/1.1} protocol as defined in the RFC 2616 from June 1999.

@noindent
The goal is not to build a full Web server but more to make it possible
to use a Web browser (like Internet Explorer, or Netscape Navigator) to
control an Ada application. As we'll see later it is also possible to
have two Ada programs exchange informations via the @code{HTTP} protocol. This
is possible as @code{AWS} also implement the client side of the HTTP protocol.

@noindent
Moreover with this library it is possible to have more than one server
in a single application. It is then possible to export different kind
of services by using different @code{HTTP} ports, or to have different ports
for different services priority. Client which must be served with a
very high priority can be assigned a specific port for example.

@noindent
As designed, @code{AWS} big difference with a standard @code{CGI} server
is that there is only one executable. A @code{CGI} server has one
executable for each request or so, this becomes a pain to build and
to distribute when the project gets bigger. We will also see that it is
easier with @code{AWS} to deal with session data.

@noindent
@code{AWS} support also @code{HTTPS} (secure @code{HTTP}) using
@code{SSL}. This is based on @code{OpenSSL} a very good and Open Source SSL
implementation.

@sp 1
@noindent
Major supported features are:

@itemize @bullet

@item HTTP implementation

@item HTTPS (Secure HTTP) implementation based on SSLv3

@item Template Web pages (separate the code and the design)

@item Web Services - SOAP based

@item WSDL support (generate stub/skeleton from WSDL documents)

@item Basic and Digest authentication

@item Transparent session handling (server side)

@item HTTP state management (client side cookies)

@item File upload

@item Server push

@item SMTP / POP (client API)

@item LDAP (client API)

@item Embedded resources (full self dependant Web server)

@item Complete client API, including HTTPS

@item Web server activity log

@end itemize

@c ======================================================================

@node Building AWS
@chapter Building AWS

@menu
* Requirements::
* AWS.Net.Std::
* Building::
* Building on cross-platforms::
* Demos::
* Installing::
@end menu

@c ----------------------------------------------------------------------

@node Requirements
@section Requirements

@noindent
@code{AWS} has been mainly developed with @code{GNAT} on Windows.
It is built and tested regularly on @code{GNU/Linux} and
@code{Solaris}, it should be fairly portable across platforms. To
build @code{AWS} you need:

@itemize @bullet

@item GNU/Ada (GNAT compiler) ;
@cindex GNAT
@cindex GNU/Ada

To build this version you need at least @code{GNAT GPL 2009 Edition}
or @code{GNAT Pro 6.2} as some Ada 2005 fearures
(@code{Ada.Containers}, interfaces, overriding keyword) are used. The
code should be fairly portable but has never been tested on another
compiler than @code{GNAT}.

@item OpenSSL (@b{optional}) ;
@cindex OpenSSL

OpenSSL is an Open Source toolkit implementing the @i{Secure Sockets Layer}
(SSL v2 and v3) and much more. You'll find libraries for Win32 into this
distribution. For other platforms just download the OpenSSL source
distribution from @url{http://www.openssl.org} and build it.

@item OpenLDAP (@b{optional}) ;
@cindex OpenLDAP

OpenLDAP is an Open Source toolkit implementing the
@i{Lightweight Directory Access Protocol}.
If you want to use the @code{AWS/LDAP} API
on UNIX based systems, you need to install properly the @code{OpenLDAP}
package. On Windows you don't need to install it as the
@file{libldap.a} library will be built by @code{AWS} and will use the
standard Windows @code{LDAP DLL} @file{wldap32.dll}.

You can download OpenLDAP from @url{http://www.openldap.org}.

@end itemize

@c ----------------------------------------------------------------------

@node AWS.Net.Std
@section AWS.Net.Std
@cindex AWS.Net.Std

@noindent
This package is the standard (non-SSL) socket implementation. It exists
different implementations of this package:

@table @b

@item IPv4

Version based on @code{GNAT.Sockets}. This is the @b{default implementation}
used.

@item IPv6

As above but supporting IPv6 protocol. To select this implementation
just do when building (see below):

@AWSEXP {$ make IPv6=true}

@end table

@c ----------------------------------------------------------------------

@node Building
@section Building
@cindex Building

@noindent
Before building be sure to edit @file{makefile.conf}, this file
contains many settings important for the build. Note that it is
important to run @code{make setup} each time you edit this file.

@noindent
When you have built and configured all external libraries you must set the
@var{ADA_PROJECT_PATH} variable to point to the GNAT Project files for
the different packages. For @code{XML/Ada} support, you also need to set
@var{XMLADA} to @var{true} in @file{makefile.conf}.

@noindent
At this point you can build @code{AWS} with:

@AWSEXP {$ make setup build}

@noindent
Note that some demos require that @code{AWS} be built with @code{SSL}
support. If you want to activate @code{SSL} on UNIX (in
this case you must have @file{libssl.a} and @file{libcrypto.a}
available on your platform), open @file{makefile.conf} and set the
@var{SOCKET} variable to @code{openssl}. Then rebuild with:
@cindex libssl.a
@cindex libcrypto.a

@AWSEXP {$ make setup build}

@noindent
It is is possible to build @code{AWS} in debug mode by setting
@var{DEBUG} make's variable in @file{makefile.conf}, or just:

@AWSEXP {$ make DEBUG=true setup build}

@noindent
Note that by default @code{AWS} is configured to use the @code{GNAT}
compiler. So, if you use @code{GNAT} you can build @code{AWS} just with:

@AWSEXP {$ make setup build}

@noindent
If you want to build only the @code{AWS} libraries and tools and do not want
to build the demos you can set @code{DEMOS} to "false" as in:

@AWSEXP {$ make DEMOS=false setup}

@c ----------------------------------------------------------------------

@node Building on cross-platforms
@section Building on cross-platforms
@cindex Building
@cindex cross-platforms

@noindent
To build for a cross platform the TARGET makefile variable must be set
with the cross toolchain to be used. The value must be the triplet of
the toolchain to use.

@noindent
For example, to build on VxWorks:

@AWSEXP {$ make TARGET=powerpc-wrs-vxworks setup build}

@c ----------------------------------------------------------------------

@node Demos
@section Demos

@noindent
@code{AWS} comes with some ready to use demos. The demos are a good
way to learn how to use @code{AWS}.

@noindent
Here are a short description of them:

@table @file

@item agent

A program using the @code{AWS} client interface. This simple tool can be used
to retrieve Web page content. It supports passing through a proxy with
authentication and basic authentication on the Web site.

@item auth

A simple program to test the Web Basic and Digest authentication feature.

@item com

Two simples program that uses the @code{AWS} communication service.

@item dispatch

A simple demo using the dispatcher facility. @pxref{URI dispatcher}.

@item hello_world

The famous Hello World program. This is a server that will always
return a Web page saying ``Hello World!''.

@item hotplug

A simple test for the hotplug feature.

@item interoplab

A WSDL based demo that test most of the @code{SOAP} features.

@item jabber_demo

A simple Jabber command line client to check the presence of a JID
(Jabber ID). This uses the Jabber API, @pxref{AWS.Jabber}.

@item multiple_sessions

A demo of two embedded servers using different sessions.

@item res_demo

A demo using the resource feature. This Web Server embedded a @code{PNG}
image and an @code{HTML} page. The executable is self contained.

@item runme

An example that test many @code{AWS} features.

@item soap_demo

A simple client/server program to test the @code{SOAP} protocol.

@item soap_disp

Like above but use a @code{SOAP} dispatcher.

@item soap_vs

A client and server that implement seven @code{SOAP} procedures for
testing purpose.

@item split

A demo for the transient pages and page splitter @code{AWS}'s
feature. Here a very big table is split on multiple pages. A set of
links can be used to navigate to the next or previous page or to
access directly to a given page.

@item test_ldap

A simple @code{LDAP} demo which access a public @code{LDAP} server and
display some information.

@item test_mail

A simple application that send a set of @code{SMTP} messages with
different kind of attachments.

@item text_input

A simple demo which handle textarea and display the content.

@item vh_demo

Two servers on the same machine... virtual hosting demo.
@pxref{Virtual host dispatcher}.

@item web_block

A simple Web Bock based counter.

@item web_block_ajax

As above but using also @code{Ajax}.

@item web_block_ajax_templates

As above but using also the @code{templates2ada} tool which create a
tight coupling between the web templates and the @code{Ada} code.

@item web_elements

A driver to browse the Web Elements library and see some examples.

@item web_mail

A simple Web Mail implementation that works on a @code{POP} mailbox.

@item wps

A very simple static Web page server based on @code{AWS.Services.Page_Server}.
@pxref{Static Page server}.

@item ws

A static Web page server and push enabled server.

@item zdemo

A simple demo of the Gzip content encoding feature.

@end table

@noindent
For build instructions see @file{demos/README}.

@c ----------------------------------------------------------------------

@node Installing
@section Installing
@cindex Installing

@noindent
When the build is done you must install @code{AWS} at a specific
location. The target directory is defined with the @var{prefix}
@file{makefile.conf} variable. The default value is set to the
compiler root directory. Note that the previously installed version is
automatically removed before installing the new one. To install:

@AWSEXP {$ make install}

@noindent
To install @code{AWS} into another directory you can either edit
@file{makefile.conf} and set @var{prefix} to the directory you like
to install @code{AWS} or just force the make @var{prefix} variable:

@AWSEXP {$ make prefix=/opt install}

@noindent
Alternatively, with @code{GNAT} 5.03 and above it is possible to
install @code{AWS} into the GNAT Standard Library location. In this
case @code{AWS} is ready-to-use as there is no need to set
@var{ADA_PROJECT_PATH}, just set @var{prefix} to point to @code{GNAT} root
directory:

@AWSEXP {$ make prefix=/opt/gnatpro/6.1.1 install}

@noindent
Now you are ready to use @code{AWS} !

@c ======================================================================

@node Using AWS
@chapter Using AWS

@menu
* Setting up environment::
* Basic notions::
* Building answers::
* Configuration options::
* Session handling::
* HTTP state management::
* Authentication::
* File upload::
* Communication::
* Hotplug module::
* Server Push::
* Working with Server sockets::
* Server Log::
* Secure server::
* Unexpected exception handler::
* Socket log::
* Client side::
@end menu

@c ----------------------------------------------------------------------

@node Setting up environment
@section Setting up environment

@menu
* Using environment variables::
* Using GNAT Project Files::
@end menu

@node Using environment variables
@subsection Using environment variables

@noindent
After installing @code{AWS} you must set the build environment to
point the compiler to the right libraries. First let's say that
@code{AWS} has been installed in @file{awsroot} directory.

Following are the instructions to set the environment yourself. Note
that the preferred solution is to use project files. In this case there
is no manual configuration.

@table @b

@item spec files

The spec files are installed in @file{<awsroot>/include/aws}. Add this
path into @var{ADA_INCLUDE_PATH} or put it on the command line
@code{-aI<awsroot>/include/aws}.

@item components

@code{AWS} uses some components they are installed in
@file{<awsroot>/include/aws/components}. Add this path into ADA_INCLUDE_PATH
or put it on the command line @code{-I<awsroot>/include/aws/components}.

@item libraries

The GNAT library files (@file{.ali}) and the @code{AWS} libraries
(@file{libaws.a}) are installed into @file{<awsroot>/lib/aws/static}. Add this
path into @var{ADA_OBJECTS_PATH} or put it on the command line
@code{-aO<awsroot>/lib/aws/static}. Furthermore for @code{gnatlink} to find the
libraries you must add the following library path option on the
@code{gnatmake} command line @code{-largs -L<awsroot>/lib/aws/static -laws}.

Note that to build SSL applications you need to add @code{-lssl -lcrypto} on
gnatmake's @code{-largs} section.

@item external libraries

You must do the same thing (setting @var{ADA_INCLUDE_PATH} and
@var{ADA_OBJECTS_PATH}) for all external libraries that you will
be using.

@end table

@node Using GNAT Project Files
@subsection Using GNAT Project Files

@noindent
The best solution is to use the installed GNAT Project File
@file{aws.gpr}. This is supported only for @code{GNAT 5.01} or
above. You must have installed @code{XML/Ada} with project file
support too.

If this is the case just set the @var{ADA_PROJECT_PATH} variable to
point to the @code{AWS} and @code{XML/Ada} install directories. From
there you just have to with the @code{AWS} project file in your GNAT
Project file, nothing else to set.

@AWSEXP {@b{with} "aws";

@b{project} Simple @b{is}

   @b{for} Main @b{use} ("prog.adb");

   @b{for} Source_Dirs @b{use} ("src");

   @b{for} Object_Dir @b{use} "obj";

@b{end} Simple;}

@noindent
See the @i{GNAT User's Guide} for more information about GNAT Project Files.

@c ----------------------------------------------------------------------

@node Basic notions
@section Basic notions

@noindent
@code{AWS} is not a Web Server like @i{IIS} or @i{Apache}, it is a component
to embedded HTTP protocol in an application. It means that it is possible
to build an application which can also answer to a standard browser like
@i{Internet Explorer} or @i{Netscape Navigator}. Since @code{AWS} provides
support client and server HTTP protocol, applications can communicate
through the HTTP channel. This give a way to build distributed
applications, @xref{AWS.Client}.

@noindent
An application using @code{AWS} can open many @code{HTTP} channels. Each
channel will use a specific port. For example, it is possible to
embedded many @code{HTTP} and/or many @code{HTTPS} channels in the
same application.

@menu
* Building an AWS server::
* Callback procedure::
* Form parameters::
* Distribution of an AWS server::
@end menu

@node Building an AWS server
@subsection Building an AWS server

@noindent
To build a server you must:

@enumerate

@item declare the HTTP Web Server
@cindex HTTP declaration

@AWSEXP {WS  : AWS.Server.HTTP;}

@item Start the server
@cindex starting server

@noindent
You need to start the server before using it. This is done by calling
@code{AWS.Server.Start} (@xref{AWS.Server}.)

@AWSEXP {@b{procedure} Start
  (Web_Server                : @b{in out} HTTP;
   Name                      : @b{in}     String;
   Callback                  : @b{in}     Response.Callback;
   Max_Connection            : @b{in}     Positive     := Def_Max_Connect;
   Admin_URI                 : @b{in}     String       := Def_Admin_URI;
   Port                      : @b{in}     Positive     := Def_Port;
   Security                  : @b{in}     Boolean      := False;
   Session                   : @b{in}     Boolean      := False;
   Case_Sensitive_Parameters : @b{in}     Boolean      := True;
   Upload_Directory          : @b{in}     String       := Def_Upload_Dir);
@i{--  Start the Web server. It initialize the Max_Connection connections}
@i{--  lines. Name is just a string used to identify the server. This is used}
@i{--  for example in the administrative page. Admin_URI must be set to enable}
@i{--  the administrative status page. Callback is the procedure to call for}
@i{--  each resource requested. Port is the Web server port. If Security is}
@i{--  set to True the server will use an HTTPS/SSL connection. If Session is}
@i{--  set to True the server will be able to get a status for each client}
@i{--  connected. A session ID is used for that, on the client side it is a}
@i{--  cookie. Case_Sensitive_Parameters if set to False it means that the CGI}
@i{--  parameters name will be handled without case sensitivity. Upload}
@i{--  directory point to a directory where uploaded files will be stored.}}

@noindent
@code{Start} takes many parameters:

@table @b

@item Web_Server
@cindex Web_Server

this is the Web server to start.

@item Name

This is a string to identify the server. This name will be used for
example in the administrative status page.

@item Callback
@cindex Callback

This is the procedure to call for each requested resources. In this
procedure you must handle all the possible URI that you want to support.
(see below).

@item Max_Connection
@cindex Max_Connection

This is the maximum number of simultaneous connections. It means that
Max_Connection client's browsers can gets answer at the same
time. This parameter must be changed to match your needs. A medium Web
server will certainly need something like 20 or 30 simultaneous
connections.

@item Admin_URI
@cindex Admin_URI

This is a special URI recognized internally by the server. If this URI
is requested the server will return the administrative page. This page
is built using a specific template page (default is
@file{@_STATUS_PAGE_@}) @pxref{Status page}.

The administrative page returns many information about the server. It is
possible to configure the server via two configuration files
@xref{Configuration options}.

@item Port
@cindex Port

This is the port to use for the Web server. You can use any free port on
your computer. Note that on some OS specific range could be reserved
or needs specials privileges (port 80 on Linux for example).

@item Security
@cindex Security

If Security is set to True the server will use an HTTPS/SSL
connection. This part uses the @code{OpenSSL} library.

@item Session
@cindex Session

If Session is set to true the server will keep a session ID for each
client. The client will be able to save and get variables associated
with this session ID.

@item Case_Sensitive_Parameters
@cindex Case_Sensitive_Parameters

If set to True the CGI name parameters will be handled without using the
case.

@end table

@noindent
Note that there is other @code{Start} routines which support other features.
For example there is a @code{Start} routine which use a dispatcher routine
instead of the simple callback procedure. @pxref{AWS.Server}. And
there is also the version using a @code{Config.Object} which is the most
generic one.

@item provides a callback procedure

@noindent
The callback procedure has the following prototype:

@AWSEXP {@b{function} Service (Request : @b{in} AWS.Status.Data) @b{return} AWS.Response.Data;}

@noindent
This procedure receive the request status. It is possible to retrieve
information about the request through the @code{AWS.Status} API
(@xref{AWS.Status}.).

@noindent
For example, to know what URI has been asked:

@AWSEXP {URI : @b{constant} String := AWS.Status.URI (Request);

@b{if} URI = "/whatever" @b{then}
   ...
@b{end if};}

@noindent
Then this function should return an answer using one of the constructors
in @code{AWS.Response} (@xref{AWS.Response}.). For example, to return an
@code{HTML} message:

@AWSEXP {AWS.Response.Build (Content_Type => "text/html",
                    Message_Body => "<p>just a demo");}

@noindent
It is also possible to return a file. For example, here is the way to
return a PNG image:

@AWSEXP {AWS.Response.File (Content_Type => "image/png",
                   Filename     => "adains.png");}

@end enumerate

@noindent
Note that the main procedure should exit only when the server is terminated.
For this you can use the @code{AWS.Server.Wait} service.

@noindent
A better solution is to use a template engine like Templates_Parser to
build the @code{HTML} Web Server answer. Templates_Parser module is
distributed with this version of AWS.

@node Callback procedure
@subsection Callback procedure
@cindex Callback
@cindex Callback procedure

@noindent
The callback procedure is the user's code that will be called by the AWS
component to get the right answer for the requested resource. In fact
AWS just open the HTTP message, parsing the HTTP header and it builds
an object of type @code{AWS.Status.Data}. At this point it calls the
user's callback procedure, passing the object. The callback procedure
must returns the right response for the requested resources. Now AWS
will just build up the HTTP response message and send it back to
user's browser.

@noindent
@b{But what is the resource ?}
@cindex resources

@noindent
Indeed in a standard Web development a resource is either a static
object - an @code{HTML} page, an @code{XML} or @code{XSL} document -
or a @code{CGI} script. With @code{AWS} a resource is @i{just a
string} to identify the resource, it does not represent the name of a
static object or @code{CGI} script.

@noindent
So this string is just an internal representation for the
resource. The callback procedure must be implemented to handle each
internal resource and return the right response.

@noindent
Let's have a small example. For example we want to build a Web server
that will answer ``Hello World'' if we ask for the internal resource
@b{/hello}, and must answer ``Hum...'' otherwise.

@cindex Hello world
@AWSEXP {@b{with} AWS.Response;
@b{with} AWS.Server;
@b{with} AWS.Status;

@b{procedure} Hello_World @b{is}

   WS : AWS.Server.HTTP;

   @b{function} HW_CB (Request : @b{in} AWS.Status.Data)
     @b{return} AWS.Response.Data
   @b{is}
      URI : @b{constant} String := AWS.Status.URI (Request);
   @b{begin}
      @b{if} URI = "/hello" @b{then}
         @b{return} AWS.Response.Build ("text/html", "<p>Hello world !");
      @b{else}
         @b{return} AWS.Response.Build ("text/html", "<p>Hum...");
      @b{end if};
   @b{end} HW_CB;

@b{begin}
   AWS.Server.Start
      (WS, "Hello World", Callback => HW_CB'Unrestricted_Access);
   @b{delay} 30.0;
@b{end} Hello_World;}

@noindent
Now of course the resource internal name can represent a file on
disk. It is not mandatory but it is possible. For example it is
perfectly possible to build with @code{AWS} a simple page server.

@cindex Page server
@cindex Simple server
@noindent
As an example, let's build a simple page server. This server will
returns files in the current directory. Resources internal name
represent an @code{HTML} page or a @code{GIF} or @code{PNG} image for
example. This server will return a 404 message (Web Page Not Found) if
the file does not exist. Here is the callback procedure that implements
such simple page server:

@AWSEXP {@b{function} Get (Request : @b{in} AWS.Status.Data) @b{return} AWS.Response.Data @b{is}
   URI      : @b{constant} String := AWS.Status.URI (Request);
   Filename : @b{constant} String := URI (2 .. URI'Last);
@b{begin}
   @b{if} Utils.Is_Regular_File (Filename) @b{then}
      @b{return} AWS.Response.File
        (Content_Type => AWS.MIME.Content_Type (Filename),
         Filename     => Filename);

   @b{else}
      return AWS.Response.Acknowledge
        (Messages.S404,
         "<p>Page '" & URI & "' Not found.");
   @b{end if};
@b{end} Get;}

@node Form parameters
@subsection Form parameters
@cindex Form parameters
@cindex Parameters

@noindent
Form parameters are stored into a table of key/value pair. The key is the form
input tag name and the value is the content of the input field as filled by
the user.

@AWSEXP {Enter your name

<FORM METHOD=GET ACTION=/get-form>"
<INPUT TYPE=TEXT NAME=name VALUE="<default>" size=15>
<INPUT TYPE=SUBMIT NAME=go VALUE="Ok">
</FORM>}

@noindent
Note that as explained above @pxref{Callback procedure}, the resource
described in @code{ACTION} is just an internal string representation
for the resource.

@noindent
In this example there is two form parameters:

@table @b
@item name
The value is the content of this text field as filled by the client.

@item go
The value is "Ok".
@end table

@noindent
There is many functions (in @code{AWS.Parameters}) to retrieve the tag name
or value and the number of parameters. Here are some examples:

@AWSEXP {@b{function} Service (Request : @b{in} AWS.Status.Data)
  @b{return} AWS.Response.Data
@b{is}
   P : @b{constant} AWS.Parameters.List := AWS.Status.Parameters (Request);
   ...}


@table @code
@item AWS.Parameters.Get (P, "name")
@cindex Parameters Get
Returns the value for parameter named @b{name}

@item AWS.Parameters.Get_Name (P, 1)
@cindex Parameters Get_Name
Returns the string "name".

@item AWS.Parameters.Get (P, 1)
Returns the value for parameter named @b{name}

@item AWS.Parameters.Get (P, "go")
Returns the string "Ok".

@item AWS.Parameters.Get_Name (P, 2)
Returns the string "go".

@item AWS.Parameters.Get (P, 2)
Returns the string "Ok".
@end table

@noindent
@code{Request} is the @code{AWS} current connection status passed to the
callback procedure. And @code{P} is the parameters list retrieved from the
connection status data. For a discussion about the callback procedure
@xref{Building an AWS server}.

@node Distribution of an AWS server
@subsection Distribution of an AWS server
@cindex Distributing

@noindent
The directory containing the server program must contain the following
files if you plan to use a status page @xref{Status page}.

@table @file
@item @_STATUS_PAGE_@

The template @code{HTML} file for the @code{AWS} status page.

@item @_LOGO_IMAGE_@

The @code{AWS} logo displayed on the status page.

@item @_UP_IMAGE_@

The @code{AWS} hotplug table up arrow.

@item @_DOWN_IMAGE_@

The @code{AWS} hotplug table down arrow.

@end table

@noindent
Note that these filenames are the current @code{AWS} default. But it is
possible to change those defaults using the configuration files
@pxref{Configuration options}.

@c ----------------------------------------------------------------------

@node Building answers
@section Building answers

@noindent
We have already seen, in simple examples, how to build basic answers using
@code{AWS.Response} API. In this section we present all ways to build
answers from basic support to the more advanced support like the
compressed memory stream response.

@menu
* Redirection::
* New location for a page::
* Authentication required::
* Sending back an error message::
* Response from a string::
* Response from a Stream_Element_Array::
* Response from a file::
* Response from a stream::
* Response from a on-disk stream::
* Response from a on-disk once stream::
* Response from a memory stream::
* Response from a compressed memory stream::
* Response from a pipe stream::
* Split page::
@end menu

@node Redirection
@subsection Redirection

@noindent
A redirection is a way to redirect the client's browser to another
URL. Client's won't notice that a redirection has occurs. As soon as
the browser has received the response from the server it will retrieve
the page as pointed by the redirection.

@AWSEXP {@b{return} Response.URL (Location => "/use-this-one");}

@node New location for a page
@subsection New location for a page

@noindent
User will receive a Web page saying that this page has moved and
eventually pointing to the new location.

@AWSEXP {@b{return} Response.Moved
  (Location => "/use-this-one";
   Message  => "This page has moved, please update your reference");}

@node Authentication required
@subsection Authentication required

@noindent
For protected pages you need to ask user to enter a password.
@pxref{Authentication}.

@node Sending back an error message
@subsection Sending back an error message

@noindent
@code{Acknowledge} can be used to send back error messages. There is
many kind of status code, see @code{Message.Status_Code}
definition. Together with the status code it is possible to pass
textual error message in @code{Message_Body} parameter.

@AWSEXP {@b{return} Response.Acknowledge
  (Status_Code  => Messages.S503,
   Message_Body => "Can't connect to the database, please retry later.",
   Content_Type => MIME.Text_Plain);}

@node Response from a string
@subsection Response from a string

@noindent
This is the simplest way to build a response object. There is two
constructors in @code{AWS.Response}, one based on a standard string
and one for Unbounded_String.

@AWSEXP {@b{return} Response.Build (MIME.Text_HTML, "My answer");}

@noindent
The Build routine takes also a status code parameter to handle
errors. By default this code is @code{Messages.S200} which is the
standard HTTP status (no error encountered). The other parameter can
be used to control caches. @pxref{AWS.Response}.

@node Response from a Stream_Element_Array
@subsection Response from a Stream_Element_Array

@noindent
This is exactly as above but the Build routine takes a
@code{Stream_Element_Array} instead of a string.

@node Response from a file
@subsection Response from a file

@noindent
To build a @code{File} response there is a single constructor named
@code{File}. This routine is very similar to the one above except that
we specify a filename as the response.

@AWSEXP {@b{return} Response.File (MIME.Text_HTML, "index.html");}

@noindent
Again there parameters to control the status code and cache. No check
on the filename is done at this point, so if @file{index.html} does
not exit no exception is raised. The server is responsible to check
for the file and to properly send back the 404 message if necessary.

@noindent
Note that this routine takes an optional parameter named @code{Once}
that is to be used for temporary files created on the server side for
the client. With @code{Once} set to @code{True} the file will be
deleted by the server after sending it (this includes the case where
the download is suspended).

@node Response from a stream
@subsection Response from a stream

@noindent
Sometimes it is not possible (or convenient) to build the response in
memory as a string object for example. Streams can be used to
workaround this. The constructor for such response is again very
similar to the ones above except that instead of the data we pass an
handle to a @code{Resources.Streams.Stream_Type} object.

@noindent
The first step is to build the stream object. This is done by deriving
a new type from @code{Resources.Streams.Stream_Type} and implementing
three abstract procedures.

@table @code
@item Read

Must return the next chunk of data from the stream. Note that
initialization if needed are to be done there during the first call to
read.

@item End_Of_File

Must return True when there is no more data on the stream.

@item Close

Must close the stream and for example release all memory used by the
implementation.
@end table

@noindent
The second step is to build the response object:

@AWSEXP {@b{type} SQL_Stream @b{is new} Resources.Streams.Stream_Type;

Stream_Object : SQL_Stream;

@b{procedure} Read (...) @b{is} ...
@b{function} End_Of_File (...) @b{return} Boolean @b{is} ...
@b{procedure} Close (...) @b{is}

...

@b{return} Response.Stream (MIME.Text_HTML, Stream_Object);}

@noindent
Note that in some cases it is needed to create a file containing the
data for the client (for example a tar.gz or a zip archive). But there
is no way to properly remove this file from the file system as we
really don't know when the upload is terminated when using the
@code{AWS.Response.File} constructor. To solve this problem it is
possible to use a stream as the procedure @code{Close} is called by
the server when all data have been read. In this procedure it is
trivial to do the necessary clean-up.

@node Response from a on-disk stream
@subsection Response from a on-disk stream

@noindent
An ready-to-use implementation of the stream API described above where
the stream content is read from an on-disk file.

@node Response from a on-disk once stream
@subsection Response from a on-disk once stream

@noindent
An ready-to-use implementation of the stream API described above where
the stream content is read from an on-disk file. When the transfer is
completed the file is removed from the file system.

@node Response from a memory stream
@subsection Response from a memory stream

@noindent
This is an implementation of the standard stream support described
above. In this case the stream is in memory and built by adding data
to it.

@noindent
To create a memory stream just declare an object of type
@code{AWS.Resources.Streams.Memory.Stream_Type}. When created, this
memory stream is empty, using the @code{Streams.Memory.Append}
routines it is possible to add chunk of data to it. It is of course
possible to call @code{Append} as many times as needed. When done just
return this object to the server.

@AWSEXP {Data : AWS.Resources.Streams.Memory.Stream_Type;

Append (Data, Translator.To_Stream_Element_Array ("First chunk"));
Append (Data, Translator.To_Stream_Element_Array ("Second chunk..."));

...

@b{return} Response.Stream (MIME.Text_HTML, Data);}

@noindent
Note that you do not have to take care of releasing the allocated
memory, the default @code{Close} routine will do just that.

@node Response from a compressed memory stream
@subsection Response from a compressed memory stream

@noindent
This is a slight variant of the standard memory stream described
above. In this case the stream object must be declared as a
@code{AWS.Resources.Streams.Memory.ZLib.Stream_Type}.

@noindent
The ZLib stream object must be initialized to enable the
compression and select the right parameters. This is done using the
@code{AWS.Resources.Streams.Memory.ZLib.Deflate_Initialize} routine which
takes many parameters to select the right options for the compression
algorithm, all of them have good default values. When initialized the
compressed stream object is used exactly as a standard stream.

@AWSEXP {Data : AWS.Resources.Streams.Memory.ZLib.Stream_Type;

Deflate_Initialize (Data);

Append (Data, Translator.To_Stream_Element_Array ("First chunk"));
Append (Data, Translator.To_Stream_Element_Array ("Second chunk..."));

...

@b{return} Response.Stream (MIME.Text_HTML, Data);}

@noindent
Note that there is the reverse implementation to decompress a
stream. @pxref{AWS.Resources.Streams.Memory.ZLib}. It's usage
is identical.

@node Split page
@subsection Split page

@code{AWS} has a specific high level service to split a large response
into a set of pages. For more information @pxref{Split pages}.

@node Response from a pipe stream
@subsection Response a from pipe stream

@noindent
The response sent to the server is read from the output of an external
application. This kind of stream can be used to avoid writing a temporary
file into the hard disk. For example it is possible to return an archive
created with the @code{tar} tool without writting the intermediate tar
achive on the disk.

@c ----------------------------------------------------------------------

@node Configuration options
@section Configuration options
@cindex Configuration options

@noindent
To configure an @code{AWS} server it is possible to use a
configuration object. This object can be set using the @code{AWS.Config.Set}
API or initialized using a configuration file.

@noindent
Configuration files are a way to configure the server without
recompiling it. Each application can be configured using two
configurations files:

@table @file

@item aws.ini
@cindex aws.ini
@cindex ini file

This file is parsed first and corresponds to the configuration for all
AWS server runs in the same directory.

@item <program_name>.ini
@cindex program_name.ini

This file is parsed after @file{aws.ini}. It is possible with this
initialization file to have specific settings for some servers.
@file{program_name.ini} is looked first in the application's directory
and then in the current working directory. This is only supported on
platforms where @code{Ada.Command_Line} is implemented. So, on @b{VxWorks}
only @file{aws.ini} is parsed.

@end table

@noindent
Furthermore, it is possible to read a specific configuration file
using the @code{AWS.Config.Ini.Read} routine. @pxref{AWS.Config.Ini}.

@noindent
Current supported options are:

@table @code

@item Accept_Queue_Size (positive)
@cindex Accept_Queue_Size
This is the size of the queue for the incoming requests. Higher this
value will be and less "@i{connection refused}" will be reported to the
client. The default value is @_QUEUE_SIZE_@.

@item Admin_Password (string)
@cindex Admin_Password
This is the password used to call the administrative page. The
password can be generated with @file{aws_password} (the module name
must be @var{admin})

@AWSEXP {$ aws_password admin <password>}

@item Admin_URI (string)
@cindex Admin_URI
This is the URI to call the administrative page. This can be used when
calling @code{AWS.Server.Start}. The default is @file{@_ADMIN_URI_@}.

@item Certificate (string)
@cindex Certificate (string)
Set the certificate file to be used with the secure servers. The
default is @file{@_DEFAULT_CERTIFICATE_@}. A single certificate or a
certificate chain is supported. The certificates must be in @code{PEM} format
and the chain must be sorted starting with the subject's certificate, followed
by intermediate CA certificates if applicable and ending at the highest
level (root) CA certificate. If the file contains only a single
certificate, it can be followed by a private key. In this case the Key
parameter (see below) must empty.

@item Case_Sensitive_Parameters (boolean)
@cindex Case_Sensitive_Parameters
If set to @code{True} the @code{HTTP} parameters are case
sensitive. The default value is @_CASE_SENSITIVE_PARAMETERS_@.

@item Check_URL_Validity (boolean)
@cindex Check_URL_Validity
Server have to check URI for validity. For example it checks that an
URL does not reference a resource above the Web root. The default
is @_CHECK_URL_VALIDITY_@.

@item Cleaner_Wait_For_Client_Timeout (duration)
@cindex Cleaner_Wait_For_Client_Timeout
Number of seconds to timeout on waiting for a client request. This is a
timeout for regular cleaning task. The default is
@_CT_WAIT_FOR_CLIENT_@ seconds.

@item Cleaner_Client_Header_Timeout (duration)
@cindex Cleaner_Client_Header_Timeout
Number of seconds to timeout on waiting for client header. This is a
timeout for regular cleaning task. The default is @_CT_CLIENT_HEADER_@ seconds.

@item Cleaner_Client_Data_Timeout (duration)
@cindex Cleaner_Client_Data_Timeout
Number of seconds to timeout on waiting for client message body. This
is a timeout for regular cleaning task. The default is
@_CT_CLIENT_DATA_@ seconds.

@item Cleaner_Server_Response_Timeout (duration)
@cindex Cleaner_Server_Response_Timeout
Number of seconds to timeout on waiting for client to accept
answer. This is a timeout for regular cleaning task. The default is
@_CT_SERVER_RESPONSE_@ seconds.

@item Directory_Browser_Page (string)
@cindex Directory_Browser_Page
Specify the filename for the directory browser template page. The
default value is @file{@_DIRECTORY_BROWSER_PAGE_@}.

@item Down_Image (string).
@cindex Down_Image
The name of the down arrow image to use in the status page. The default is
@file{@_DOWN_IMAGE_@}.

@item Error_Log_Filename_Prefix (string)
@cindex Log_Filename_Prefix
This is to set the filename prefix for the log file. By default the
log filename prefix is the program name (without extension) followed
by "_error".

@item Error_Log_Split_Mode [None/Each_Run/Daily/Monthly]
@cindex Log_Split_Mode
It indicates how to split the error logs. Each_Run means that a new log file
is used each time the process is started. Daily and Monthly will use a
new log file each day or month. The default is @_ERROR_LOG_SPLIT_MODE_@.

@item Exchange_Certificate (boolean)
@cindex Exchange_Certificate
If set to True it means that the client will be asked to send its
certificate to the server. The default value is @_EXCHANGE_CERTIFICATE_@.

@item Force_Wait_For_Client_Timeout (duration)
@cindex Force_Wait_For_Client_Timeout
Number of seconds to timeout on waiting for a client request. This is a
timeout for urgent request when resources are missing. The default is
@_FT_WAIT_FOR_CLIENT_@ seconds.

@item Force_Client_Header_Timeout (duration)
@cindex Force_Client_Header_Timeout
Number of seconds to timeout on waiting for client header. This is a
timeout for urgent request when resources are missing. The default is
@_FT_CLIENT_HEADER_@ seconds.

@item Force_Client_Data_Timeout (duration)
@cindex Force_Client_Data_Timeout
Number of seconds to timeout on waiting for client message body. This
is a timeout for urgent request when resources are missing. The default is
@_FT_CLIENT_DATA_@ seconds.

@item Force_Server_Response_Timeout (duration)
@cindex Force_Server_Response_Timeout
Number of seconds to timeout on waiting for client to accept answer. This
is a timeout for urgent request when resources are missing. The default is
@_FT_SERVER_RESPONSE_@ seconds.

@item Free_Slots_Keep_Alive_Limit (positive)
@cindex Free_Slots_Keep_Alive_Limit
This is the minimum number of remaining free slots to enable keep-alive HTTP
connections. For heavy-loaded HTTP servers, the Max_Connection parameter
should be big enough, and Free_Slots_Keep_Alive_Limit should be about 1-10%
of the Max_Connection parameter depending on the duration of the
average server response. Longer is the average time to send back a
response bigger Free_Slots_Keep_Alive_Limit should be.
The default is @_KEEP_ALIVE_LIMIT_@.

@item Hotplug_Port (positive)
@cindex Hotplug_Port
This is the hotplug communication port needed to register and
un-register an hotplug module. The default value is @_HOTPLUG_PORT_@.

@item Key (string)
@cindex Key
Set the RSA key file to be used with the secure servers. The
default file is @file{@_DEFAULT_KEY_@}.

@item Line_Stack_Size (positive)
@cindex Line_Stack_Size
The HTTP lines stack size. The stack size must be adjusted for each
applications depending on the use of the stack done by the callback
procedures. The default is @_LINE_STACK_SIZE_@.

@item Log_Extended_Fields (string list)
@cindex Log_Extended_Fields
Comma separated list of the extended log field names. If this parameter
is empty, the HTTP log would be in the apache compartible format, otherwise
log file would be in Extended format. For more information @pxref{Server Log}.

@item Log_File_Directory (string)
@cindex Log_File_Directory
This is to set the directory where log file must be written. This
parameter will be used automatically by @code{AWS.Log} if logging
facility is enabled. By default log files are written in the current
directory. The default is @file{@_LOG_FILE_DIR_@}.

@item Log_Filename_Prefix (string)
@cindex Log_Filename_Prefix
This is to set the filename prefix for the log file. By default the
log filename prefix is the program name (without extension).

@item Log_Split_Mode [None/Each_Run/Daily/Monthly]
@cindex Log_Split_Mode
It indicates how to split the logs. Each_Run means that a new log file
is used each time the process is started. Daily and Monthly will use a
new log file each day or month. The default is @_LOG_SPLIT_MODE_@.

@item Logo_Image (string).
@cindex Logo_Image
The name of the logo image to use in the status page. The default is
@file{@_LOGO_IMAGE_@}.

@item Max_Concurrent_Download (positive)
@cindex Max_Concurrent_Download
Control the maximum number of parallel downloads accepted by the download
manager. The default value is @_MAX_CONCURRENT_DOWNLOAD_@.

@item Max_Connection (positive)
@cindex Max_Connection
This is the maximum number of simultaneous connections for the
server. This can be used when calling the @code{AWS.Server.Start}. The
default is @_MAX_CONNECT_@.

Note that the total number of threads used by a server is:

@AWSEXP {N = <main server thread> + <max connections> [+ <session>]

  Note: [...] means optional value
        Add 1 only if the session feature is activated. This is
        due to the session cleaner task.}

@item MIME_Types (string)
@cindex MIME_Types
The name of the file containing the MIME types associations. The default file
name is @file{@_MIME_TYPES_@}.

@item Receive_Timeout (duration)
@cindex Receive_Timeout
Number of seconds to timeout when receiving chunk of data. The
default is @_RECEIVE_TIMEOUT_@ seconds.

@item Reuse_Address (boolean)
@cindex Reuse_Address
Set the socket reuse address policy. If set to True the server will be
able to bind to a socket that has just been released without the need of
waiting. Enabling this feature is not secure and should probably used
only for debugging purpose. The default is @_REUSE_ADDRESS_@.

@item Security_Mode (string)
@cindex Security_Mode
Set the security mode to use for the secure connections. The default
mode is "@b{@_SECURITY_MODE_@}". @pxref{AWS.Net.SSL}.

@item Send_Timeout (duration)
@cindex Send_Timeout
Number of seconds to timeout when sending chunk of data. The default is
@_SEND_TIMEOUT_@ seconds.

@item Server_Host (string)
@cindex Server_Host
The name of the host machine. This can be used if a computer has more
than one IP address, it is possible to have two servers at the same
port on the same machine, both being binded on different IP addresses.

@item Server_Name (string)
@cindex Server_Name
The name of the server. This can be used when calling
@code{AWS.Server.Start}. The default is "@b{@_SERVER_NAME_@}".

@item Server_Port (integer)
@cindex Server_Port
The port where server will wait for incoming connections requests. This
can be used when calling @code{AWS.Server.Start}. The default is
@_SERVER_PORT_@.

@item Session (boolean)
@cindex Session
Whether the session support must be activated or not. The default is
@_SESSION_@.

@item Session_Name (string)
@cindex Session_Name
The name of the cookie session. This can be used to support sessions
for multiple servers embedded into the same executable. The default is
"@_SESSION_NAME_@".

@item Session_Lifetime (duration)
@cindex Session_Lifetime (duration)
Number of seconds to keep session information. After this period a
session is obsoleted and will be removed at next cleanup. The default
is @_SESSION_LIFETIME_@ seconds.

@item Session_Cleanup_Interval (duration)
@cindex Session_Cleanup_Interval (duration)
Number of seconds between each run of the session cleanup task. This
task will remove all session data that have been obsoleted. The
default is @_SESSION_CLEANUP_INTERVAL_@ seconds.

@item Status_Page (string)
@cindex Status_Page
The name of the status page to used. The default is
@file{@_STATUS_PAGE_@}.

@item Transient_Cleanup_Interval (positive)
@cindex Transient_Cleanup_Interval
Specify the number of seconds between each run of the cleaner task to remove
transient pages. The default value is @_TRANSIENT_CLEANUP_INTERVAL_@ seconds.

@item Transient_Lifetime
@cindex Transient_Lifetime
Specify the number of seconds to keep a transient page. After this
period the transient page is obsoleted and will be removed during next
cleanup. The default value is @_TRANSIENT_LIFETIME_@ seconds.

@item Up_Image (string)
@cindex Up_Image
The name of the up arrow image to use in the status page. The default is
@file{@_UP_IMAGE_@}.

@item Upload_Directory (string)
@cindex Upload_Directory
This is to set the directory where upload files must be stored. By
default uploaded files are written in the current directory. The
default is @file{@_UPLOAD_DIR_@}.

@item WWW_Root (string)
@cindex WWW_Root
This option sets the Web Server root directory. All Web resources are
referenced from this root directory. The default value is "@_WWW_ROOT_@".
@end table

@noindent
Each option value can be retrieved using the @code{AWS.Config} unit or
set using @code{AWS.Config.Set}.

@noindent
For example to build a server where the @i{port} and the maximum number of
@i{connection} can be changed via a configuration file (either
@file{aws.ini} or @file{<program_name>.ini}):

@AWSEXP {WS   : AWS.Server.HTTP;

Conf : @b{constant} AWS.Config.Object := AWS.Config.Get_Current;

Server.Start (WS, Service'Access, Conf);}

@c ----------------------------------------------------------------------

@node Session handling
@section Session handling
@cindex Session

@noindent
@code{AWS} provides a way to keep session data while users are
browsing. It works by creating transparently a session ID where it
is possible to insert, delete and retrieve session data using a standard
Ada API (@xref{AWS.Session}.). Session data are key/value pair each of
them being strings. These sessions data are kept on the server, for
client side state management see @xref{HTTP state management}.

@itemize @bullet

@item First you declare and start an HTTP channel with session enabled:

@AWSEXP {WS : AWS.Server.HTTP;

Server.Start (WS,
              Port     => 1234,
              Callback => Service'Access,
              Session  => True);}

@noindent
Here we have built an HTTP channel with a maximum of 3 simultaneous
connections using the port 1234. A session ID will be created and sent
inside a cookie to the client's browser at the first request. This
session ID will be sent back to the server each time the client will ask
for a resource to the server.

@item Next, in the Service callback procedure that you have provided you
must retrieve the Session ID. As we have seen, the callback procedure
has the following prototype:

@AWSEXP {@b{function} Service (Request : @b{in} AWS.Status.Data) @b{return} AWS.Response.Data;}

@noindent
The Session ID is kept in the Request object and can be retrieved using:

@AWSEXP {Session_ID  : @b{constant} AWS.Session.ID := AWS.Status.Session (Request);}

@item From there it is quite easy to get or set some session data using
the provided API. For example:

@AWSEXP {@b{declare}
   C : Integer;
@b{begin}
   C := AWS.Session.Get (Session_ID, "counter");
   C := C + 1;
   AWS.Session.Set (Session_ID, "counter", C);
@b{end};}

@noindent
This example first get the value (as an Integer) for session data whose
key is "@code{counter}", increment this counter and then set it back to
the new value.

@end itemize

@noindent
It is also possible to save and restore all session data. It means that the
server can be shutdown and launched some time after and all client data are
restored as they were at shutdown time. Client will just see nothing. With this
feature it is possible to shutdown a server to update its look or because a
bug has been fixed for example. It is then possible to restart it
keeping the complete Web server context.

@c ----------------------------------------------------------------------

@node HTTP state management
@section HTTP state management
@cindex HTTP state
@cindex Cookies

@noindent
@code{AWS} provides a full implementation of RFC 2109 via the @code{AWS.Cookie}
package. Using this package you set, get and expire client-side HTTP cookies.

@noindent
First we set a cookie:

@AWSEXP {@b{declare}
   Content : AWS.Response.Data;
@b{begin}
   AWS.Cookie.Set (Content,
                   Key      => "hello",
                   Value    => "world",
                   Max_Age  => 86400);
@b{end};}

@noindent
Here we set the cookie @code{hello} with the value @code{world}, and we tell
the client to expire the cookie 86400 seconds into the future.

@noindent
Getting the cookie value back is equally simple:

@AWSEXP {@b{declare}
   Request : AWS.Status.Data
   --  Assume that this object contain an actual HTTP request.
@b{begin}
   Put_Line (AWS.Cookie.Get (Request, "hello"));
   --  Output 'world'
@b{end};}

@noindent
Had the cookie @code{hello} not existed, an empty @code{String} would've been
returned.

@noindent
In some cases it might be of value to know if a given cookie exists, and for
that we have the @code{Exists} function available.

@AWSEXP {@b{declare}
   Request : AWS.Status.Data
   --  Assume that this object contain an actual HTTP request
@b{begin}
   @b{if} AWS.Cookie.Exists ("hello") @b{then}
      Put_Line ("The 'hello' cookie exists!");
   @b{end if};
@b{end};}

Note that @code{Exists} doesn't care if the cookie contains an actual value or
not. If a cookie with no value exists, @code{Exists} will return
@code{True}.

@noindent
And finally we might wish to tell the client to expire a cookie:

@AWSEXP {@b{declare}
   Content : AWS.Response.Data;
@b{begin}
   AWS.Cookie.Expire (Content,
                      Key  => "hello");
@b{end};}

@noindent
The Cookie package provide @code{Get} functions and @code{Set} procedures for
@code{String}, @code{Integer}, @code{Float} and @code{Boolean} types, but since
cookies are inherently strings, it's important to understand what happens when
the cookie @code{String} value can't be converted properly to either
@code{Integer}, @code{Float} or @code{Boolean}.

@noindent
So if either conversion fails or the cookie simply doesn't exist, the following
happens:

@itemize @bullet

@item For @code{Integer}, the value 0 is returned

@item For @code{Float}, the value 0.0 is returned.

@item For @code{Boolean}, the value @code{False} is returned. Note that only
the string ``True'' is @code{True}. Everything else is @code{False}.

@end itemize

For more information, @xref{AWS.Cookie}.

@c ----------------------------------------------------------------------

@node Authentication
@section Authentication
@cindex authentication
@cindex basic
@cindex digest

@noindent
@code{AWS} supports @b{Basic} and @b{Digest} authentication. The
authentication request can be sent at any time from the callback
procedure. For this the @code{AWS.Response.Authenticate} message must
be returned.

@noindent
The authentication process is as follow:

@enumerate

@item Send authentication request

From the callback routine return an authentication request when
needed.

@AWSEXP {@b{function} Service (Request : @b{in} Status.Data) @b{return} Response.Data @b{is}
   URI  : @b{constant} String := Status.URI (Request);
   User : @b{constant} String := Status.Authorization_Name (Request);
@b{begin}
   @i{--  URI starting with "/prot/" are protected}
   @b{if} URI (URI'First .. URI'First + 5) = "/prot/"
     @b{and then} User = ""
   @b{then}
      @b{return} Response.Authenticate ("AWS", Response.Basic);}

The first parameter is the @b{Realm}, it is just a string that will be
displayed (on the authentication dialog box) by the browser to
indicate for which resource the authentication is needed.

@item Check authentication

When an authentication as been done the callback's request data
contain the user and password. Checks the values against an ACL for
each protected resources.

@AWSEXP {@b{function} Protected_Service
  (Request : @b{in} AWS.Status.Data)
   @b{return} AWS.Response.Data
@b{is}
   User : @b{constant} String := Status.Authorization_Name (Request);
   Pwd  : @b{constant} String := Status.Authorization_Password (Request);
@b{begin}
   @b{if} User = "xyz" @b{and then} Pwd = "azerty" @b{then}
      @b{return} ...;}

@end enumerate

@noindent
Note that the @b{Basic} authentication is not secure at all. The password
is sent unencoded by the browser to the server. If security is an
issue it is better to use the @b{Digest} authentication and/or an
@b{SSL} server.

@c ----------------------------------------------------------------------

@node File upload
@section File upload
@cindex File upload
@cindex upload, server

@noindent
File upload is the way to send a file from the client to the server. To
enable file upload on the client side the Web page must contain a @b{FORM}
with an @b{INPUT} tag of type @b{FILE}. The @b{FORM} must also contain
the @b{enctype} attribute set to @i{multipart/form-data}.

@AWSEXP {<FORM enctype="multipart/form-data" ACTION=/whatever METHOD=POST>
File to process: <INPUT NAME=filename TYPE=FILE>
<INPUT TYPE=SUBMIT NAME=go VALUE="Send File">
</FORM>}

@noindent
On the server side, @code{AWS} will retrieve the file and put it into the
upload directory. @code{AWS} add a prefix to the file to ensure that the
filename will be unique on the server side. The upload directory can be
changed using the configuration options. @xref{Configuration options}.

@noindent
The uploaded files are removed after the user's callback. This is done
for security reasons, if files were not removed it would be possible
to fill the server hard disk by uploading large files to the
server. This means that uploaded files must be specifically handled by
the users by either copying or renaming them.

@noindent
@code{AWS} will also setup the form parameters as usual. In the above example
there is two parameters (@xref{Form parameters}.)

@table @b
@item filename
This variable contains two values, one with the client side name and
one with the server side name.

@table @i
@item First value : Parameters.Get (P, "filename")

The value is the full pathname of the file on the server. (i.e. the
upload directory catenated with the prefix and filename).

@item Second value : Parameters.Get (P, "filename", 2)

The value is the simple filename (no path information) of the file on
the client side.
@end table

@item go
The value is "Send File"
@end table

@c ----------------------------------------------------------------------

@node Communication
@section Communication
@cindex Communication
@cindex Sending message

@noindent
This API is used to do communication between programs using the HTTP
GET protocol. It is a very simple API not to be compared with @code{GLADE}
or @code{SOAP}. This communication facility is to be used for simple
request or when a light communication support is needed. For more
complex communications or to achieve inter-operability with other
modules it is certainly a good idea to have a look at the
@code{AWS/SOAP} support, @pxref{SOAP}.

@noindent
In a communication there is a Client and a Server. Here is what is to be
done on both sides to have programs talking together.

@menu
* Communication - client side::
* Communication - server side::
@end menu

@node Communication - client side
@subsection Communication - client side
@cindex Communication, Client

@noindent
On the client side it is quite simple. You just have to send a message
using @code{AWS.Communication.Client.Send_Message}.

@AWSEXP {@b{function} Send_Message
  (Server     : @b{in} String;
   Port       : @b{in} Positive;
   Name       : @b{in} String;
   Parameters : @b{in} Parameter_Set := Null_Parameter_Set)
   @b{return} Response.Data;}

@noindent
The message is sent to the specified server using the given port. A
message is composed of a name which is a string and a set of
parameters. There is a parameter set constructor in
@code{AWS.Communication}. This function return a response as for any
callback procedure.

@node Communication - server side
@subsection Communication - server side
@cindex Communication, Server

@noindent
On the server side things are a bit more complex but not that
difficult. You must instantiate the @code{AWS.Communication.Server}
generic package by providing a callback procedure. This callback
procedure will must handle all kind of message that a client will send.

@noindent
During instantiation you must also pass a context for the communication
server. This context will be passed back to the callback procedure.

@AWSEXP {@b{generic}

   @b{type} T (<>) @b{is limited private};
   @b{type} T_Access @b{is access} T;

   @b{with function} Callback
     (Server     : @b{in} String;
      Name       : @b{in} String;
      Context    : @b{in} T_Access;
      Parameters : @b{in} Parameter_Set := Null_Parameter_Set)
      @b{return} Response.Data;

@b{package} AWS.Communication.Server @b{is}
   ...}

@*

@AWSEXP {A complete example can be found in the demos directory. Look for
@file{com_1.adb} and @file{com_2.adb}.}

@noindent
Note that this communication API is used by the Hotplug module facility
@xref{Hotplug module}.

@c ----------------------------------------------------------------------

@node Hotplug module
@section Hotplug module
@cindex hotplug

@noindent
An @b{Hotplug module} is a module that can by dynamically binded to a
running server. It is a Web server and the development process is very
similar to what we have seen until now @xref{Building an AWS server}.
The Hotplug module will register itself into a Web server by
sending a message using the communication API. The Hotplug module send
to the server a regular expression and an URL. The main server will
redirect all URL matching the regular expression to the Hotplug module.

@noindent
Note that the main server will redirect the URL to the first matching
regular expression.

@menu
* Hotplug module - server activation::
* Hotplug module - creation::
@end menu

@node Hotplug module - server activation
@subsection Hotplug module - server activation

@noindent
The first step is to properly create the main server hotplug module
registration file. This file must list all hotplug modules that can
register into the main server. Each line have the following format:

@AWSEXP {hotplug_module_name:password:server:port}

@table @b

@item hotplug_module_name

The name of the hotplug module. You can choose any name you want. This
name will be use during the registration process and to generate the
password.

@item password

The MD5 password, see below.

@item server

The name of the server where the redirection will be made. This is for
security reasons, main server will not permit to redirect requests to
any other server.

@item port

The port to use for the redirection on @code{server}.

@end table

@noindent
You must create a password for each hotplug modules. The generated
password depends on the hotplug module name. A tool named
@code{aws_password} is provided with @code{AWS} to generate such
password. Usage is simple:

@AWSEXP {$ aws_password <hotplug_module_name> <password>}

@noindent
Then, after starting the main server you must activate the Hotplug feature:

@AWSEXP {AWS.Server.Hotplug.Activate (WS'Unchecked_Access, 2222, "hotplug_conf.ini");}

@noindent
@file{hotplug_conf.ini} is the hotplug module registration file
described above.

@node Hotplug module - creation
@subsection Hotplug module - creation

@noindent
Here is how to create an Hotplug module:

@enumerate 1

@item First you create a standard Web server @xref{Building an AWS server}.

@AWSEXP {WS : AWS.Server.HTTP
  (3, 1235, False, Hotplug_CB.Hotplug'Access, False);}

Here we have a server listening to the port 1235. This server can be
used alone if needed as any Server developed with AWS.

@item Then you register the Hotplug module to the main server
@xref{AWS.Client.Hotplug}.

@AWSEXP {Response := AWS.Client.Hotplug.Register
  (Name     => "Hotplug_Module_Demo",
   Password => "my_password",
   Server   => "http://dieppe:2222",
   Regexp   => ".*AWS.*",
   URL      => "http://omsk:1235/");}

@noindent
The hotplug module @code{Hotplug_Module_Demo} must have been declared
on the main server, the password and redirection must have been
properly recorded too for security reasons
@pxref{Hotplug module - server activation}.
This command register @code{Hotplug_Module_Demo} into the server running
on the machine @code{dieppe} and ask it to redirect all @code{URL}
containing @code{AWS} to the server running on machine @code{omsk} on
port @code{1235}.

@item When the Hotplug module is stopped, you must unregister it

@AWSEXP {Response := AWS.Client.Hotplug.Unregister
  (Name     => "Hotplug_Module_Demo",
   Password => "my_password",
   Server   => "http://dieppe:2222",
   Regexp   => ".*AWS.*");}

Here we ask to unregister @code{Hotplug_Module_Demo} from server
@code{dieppe}. As for the registration process a proper password must
be specified @pxref{Hotplug module - server activation}.

@end enumerate

@AWSEXP {A complete example can be found in the demos directory. Look for
@file{main.adb} and @file{hotplug.adb}.}

@c ----------------------------------------------------------------------

@node Server Push
@section Server Push
@cindex Server Push
@cindex Push

@noindent
Server Push is a feature that let the Web Server send continuously
data to client's  Web Browser or client applications. The client does
not have to reload at periodic time (which is what is called client
pull) to have the data updated, each time the server send a piece of
data it gets displayed on the client.

@noindent
To build a push server you need to build an instance of the
@code{AWS.Server.Push} package. This package takes a set of formal
parameters. Here are the step-by-step instructions to build a Push
Server:

@enumerate

@item The data to be sent

First you must create a type that will contains the data to be sent to
client's browser except if it is a standard Ada type. See
@code{Client_Output_Type} formal parameter.

@item The data that will be streamed

This is the representation of the data that will be sent to client's
browser. This will be either a @code{String} for Web pages or
@code{Stream_Element_Array} for binary data like pictures. See
@code{Stream_Output_Type} formal parameter.

@item The context

It is often nice to be able to configure each client with different
parameters if needed. This can be achieved with the Context data type
that will be passed as parameter of the conversion function described
below. See @code{Client_Environment} formal parameter.

@item Provides a function to convert from the data type to be sent to
the data that will be streamed.

This is a function that will transform the data described on point 1
above to the form described on point 2 above. See
@code{To_Stream_Output} formal parameter.

@item Build the Push Server

To do so you just need to instantiate @code{AWS.Server.Push} with the
above declarations.

@item Registering new clients

In the standard @code{AWS} procedure callback it is possible to register a
client if requested. This is done by calling
@code{AWS.Server.Push.Register}. It is possible to unregister a
client using @code{AWS.Server.Push.Unregister}. Each client must be
identified with a unique client ID. After registering a new client
from the callback procedure you must return the
@code{AWS.Response.Socket_Taken} message. This is very important, it
tells the server to not close this socket.

@item Sending the data

At this point it is possible to send data to clients. To do so
two routines are available.

@table @code
@item AWS.Server.Push.Send_To
@cindex Send_To
To send a piece of data to a specific client identified by its client ID.

@item AWS.Server.Push.Send
@cindex Send
To send a piece of data to all clients registered on this server.

@end table

@end enumerate

@noindent
Very large Internet applications should use this feature carefully. A
push server keeps a socket reserved for each registered clients and
the number of available sockets per process is limited by the OS.

@c ----------------------------------------------------------------------

@node Working with Server sockets
@section Working with Server sockets
@cindex Working with Server sockets

@noindent
With @code{AWS} is is possible to take out a socket from the server and give
it back later. This feature must be used carefully but it gives a lot
of flexibility. As the socket is taken away, the connection line (or slot)
is released, @code{AWS} can then use it to handle other requests.

@noindent
This can be used to better support heavy loaded servers when some
requests need a long time to complete. Long time here means longer
than most of the other requests which should be mostly interractives
for a Web server. Of course in such a case a keep-alive connection is
kept open.

@noindent
The usage in such a case is to take out the socket and put it in a
waiting line. This releases the connection for the server. When the
data to prepare the answer is ready you give back the socket to the
server.

@itemize @bullet

@item Take a socket from the server

This first step is done form the callback function. A user instead of
replying immediatly decides to take away the socket from the
server. The first step is to record the connection socket socket by
calling @code{AWS.Status.Socket}. The second step is to tell the
server to not release this socket by returning @code{AWS.Response.Socket_Taken}
from the callback function. At this point the server will continue to
serve other clients.

@noindent
Note that this feature is used by the server push implementation
@pxref{Server Push}.

@item Give back the socket to the server

Calling @code{AWS.Sever.Give_Back_Socket} will register the socket for
reuse. This socket will be placed into a spool, next time the server
will check for incoming requests it will be picked up.

@end itemize

@c ----------------------------------------------------------------------

@node Server Log
@section Server Log
@cindex logs
@cindex Log.Start
@cindex Log.Stop
@cindex Log.Start_Error
@cindex Log.Stop_Error
@cindex Log.Flush

@noindent
It is possible to have the server activity logged into the file
@file{<progname>-Y-M-D.log}. To activate the logging you must call the
@code{AWS.Server.Log.Start}, and it is possible to stop logging by calling
@code{AWS.Server.Log.Stop}. Note that @code{AWS.Server.Log.Start} have
a parameter named @code{Auto_Flush} to control output buffering. This
parameter is False by default. If set to True, the log file will be
automatically flushed after each data. If the server logging is not
buffered, i.e. Auto_Flush is False, the log can still be flushed by
calling the @code{AWS.Server.Log.Flush} routine. @xref{AWS.Log}, for
more information especially about the way rotating logs can be
setup. Using this feature it is possible to have automatic split of
the log file each day, each month or at every run. See @code{AWS.Log}
spec. This is very useful to avoid having very big log files.

@noindent
The log format depend on Log_Extended_Fields configuration parameter.
If this parameter is empty, the HTTP log would have fixed apache compartible format:

@AWSEXP {<client IP> - <auth name> - [<date and time>] "<request>" <status code> <size>

For example:

100.99.12.1 -  - [22/Nov/2000:11:44:14] "GET /whatever HTTP/1.1" 200 1789}

If the extended fields list is not empty, the log file format would have
user defined fields set:

@AWSEXP {#Version: 1.0
#Date: 2006-01-09 00:00:01
#Fields: date time c-ip cs-method cs-uri cs-version sc-status sc-bytes
2006-01-09 00:34:23 100.99.12.1 GET /foo/bar.html HTTP/1.1 200 30}

Fields in the comma separated Log_Extended_Fields list could be:
@table @i
@item date
Date at which transaction completed
@item time
Time at which transaction completed
@item time-taken
Time taken for transaction to complete in seconds
@item c-ip
Client side connected IP address
@item c-port
Client side connected port
@item s-ip
Server side connected IP address
@item s-port
Server side connected port
@item cs-method
HTTP request method
@item cs-username
Client authentication username
@item cs-version
Client supported HTTP version
@item cs-uri
Request URI
@item cs-uri-stem
Stem portion alone of URI (omitting query)
@item cs-uri-query
Query portion alone of URI
@item sc-status
Responce status code
@item sc-bytes
Length of response message body
@item cs(<header>)
Any header field name sent from client to server
@item sc(<header>)
Any header field name sent from server to client
@item x-<appfield>
Any application defined field name
@end table

@noindent
@code{AWS} also support error log files. If activated every internal error
detected by @code{AWS} will gets logged into this special file.
Log file for errors would be in simple apache compartible format.
See @code{AWS.Server.Log.Start_Error} and @code{AWS.Server.Log.Stop_Error}.

@noindent
For the full set of routines supporting the log facility
@pxref{AWS.Server.Log} .

@c ----------------------------------------------------------------------

@node Secure server
@section Secure server
@cindex Secure server
@cindex HTTPS

@noindent
It is not much difficult to use a secure server (@code{HTTPS}) than a
standard one. Here we describe only what is specific to an HTTPS
server.

@noindent
Before going further you must check that @code{AWS} has been
configured with @code{SSL} support. @pxref{Building}. You must also
have installed the @code{OpenSSL} library on your system. If this is
done, you can continue reading this section.

@menu
* Initialization::
* Creating a test certificate::
* Protocol::
@end menu

@node Initialization
@subsection Initialization
@cindex certificate

@noindent
A server is configured as using the HTTPS protocol at the time it is
started. The only thing to do is to set the Start's Security parameter
to True. This will start a server and activate the @code{SSL} layer by
default. A secure server must use a valid certificate, the default one
is @file{@_DEFAULT_CERTIFICATE_@}. This certificate has been
created by the openssl tool and is valid until year 2008. Yet, this
certificate has not been signed. To build a secure server user's can
rely on, you must have a valid certificate signed by one of the
@b{Certificate Authorities}.

@noindent
The certificate to be used must be specified before starting the
secure server with @code{AWS.Server.Set_Security}.

@AWSEXP {AWS.Server.Set_Security (WS, Certificate_Filename => "/xyz/aws.pem");}

@node Creating a test certificate
@subsection Creating a test certificate
@cindex certificate

@noindent
The goal here is not to replace the @code{OpenSSL} documentation but
just to present one way to create a certificate for an @code{HTTPS}
test server.

@table @b

@item The RSA key

@AWSEXP {$ openssl genrsa -rand <filename> -out ca-key.pem}

@noindent
Filename must be point to any file, this is used to initialized the
random seed.

@item The Certificate

@AWSEXP {$ openssl req -new -x509 -days 730 -key ca-key.pem -out ca-cert.pem}

@item Create a single self contained file

@AWSEXP {$ cat ca-key.pem ca-cert.pem > aws.pem}

@end table

@noindent
A this point you can use @file{aws.pem} with your server.

@node Protocol
@subsection Protocol
@cindex SSL
@cindex TLS

@noindent
There are different security options, either @code{SSLv2}, @code{SSLv3} or
@code{TLSv1}. @code{SSLv2} and @code{SSLv3} are supported by most if
not all Web browsers. These are the default protocol used by
@code{AWS}.

@noindent
@code{TLSv1} is not supported at this point.

@c ----------------------------------------------------------------------

@node Unexpected exception handler
@section Unexpected exception handler
@cindex exception handler

@noindent
When @code{AWS} detects an internal problem, it calls a specific
handler. This handler can be used to log the error, send an alert
message or build the answer to be sent back to the client's browser.

@noindent
Here is the spec for this handler:

@AWSEXP {@b{type} Unexpected_Exception_Handler @b{is access}
  @b{procedure} (E      : @b{in}     Ada.Exceptions.Exception_Occurrence;
             Log    : @b{in out} AWS.Log.Object;
             Error  : @b{in}     Data;
             Answer : @b{in out} Response.Data);}

@noindent
The handler can be called in two modes:

@table @b

@item Non fatal error (Error.Fatal is False)

In this case @code{AWS} will continue working without problem. A
bug has been detected but it was not fatal to the thread (slot in
@code{AWS}'s terminology) handling. In this case it is possible to
send back an application level message to the client's browser. For
that you just have to fill the unexpected handler's @var{Answer} parameter
with the right response message. The @var{Error} parameter receive
information about the problem, @pxref{AWS.Exceptions}.

@item Fatal error (Error.Fatal is True)

In this case @code{AWS} will continue working but a thread (slot number
@var{Error.Slot} in @code{AWS}'s terminology) will be killed. It means
that @code{AWS} will have lost one the simultaneous connection
handler. The server will continue working unless it was the last slot handler
available. Note that a Fatal error means an @code{AWS} internal bug
and it should be reported if possible. In this mode there is no way to
send back an answer to the client's browser and @var{Error} value must
be ignored.

@end table

@noindent
The default handler for unexpected exceptions send a message to
standard error for fatal errors. For non fatal errors it log a message
(if the error log is activated for the server) and send back a message
back to the client. The message is either a built-in one or, if present
in the server's directory, the content of the @file{500.tmplt} file.
This templates can used the following tags:

@table @b
@item AUTH_MODE
The authorization mode (Either NONE, BASIC or DIGEST).

@item EXCEPTION
Exception information with traceback if activated.

@item HTTP_VERSION
Either HTTP/1.0 or HTTP/1.1

@item METHOD
The request method (Either GET, HEAD, POST or PUT)

@item PAYLOAD
The full @code{XML} payload for @code{SOAP} request.

@item PEERNAME
The IP address of the client

@item SOAP_ACTION
Either True or False. Set to True for a @code{SOAP} request.

@item URI
The complete URI
@end table

@noindent
For more information @pxref{AWS.Server} and @pxref{AWS.Exceptions}.

@c ----------------------------------------------------------------------

@node Socket log
@section Socket log
@cindex Socket log

@noindent
To ease @code{AWS} applications debugging it is possible to log all data
sent/received to/from the sockets. For this you need to call the
@code{AWS.Net.Log.Start} routine by passing a write procedure
callback. You have to create such procedure or use one read-to-use
provided in @code{AWS.Net.Log.Callbacks} package.

For more information @pxref{AWS.Net.Log} and @pxref{AWS.Net.Log.Callbacks}.

@c ----------------------------------------------------------------------

@node Client side
@section Client side
@cindex Client protocol
@cindex client HTTP

@noindent
@code{AWS} is not only a server it also implement the HTTP and HTTPS
protocol from the client side. For example with @code{AWS} it is
possible to get a Web page content using the @code{AWS.Client} API,
@xref{AWS.Client}.

@noindent
It also support client @b{Keep-Alive} connections. It is then possible to
request many URI from the same server using the same connection
(i.e. the same sockets).

@noindent
@code{AWS} client API also support proxy, proxy authentication and Web server
authentication. Only basic (and not digest) authentication is
supported at this time.

@noindent
Let's say that you want to retrieve the @code{contrib.html} Web page from
Pascal Obry's homepage which is @url{http://perso.wanadoo.fr/pascal.obry}. The
code to do so is:

@AWSEXP {Data := Client.Get
  (URL => "http://perso.wanadoo.fr/pascal.obry/contrib.html");}

@noindent
From there you can ask for the result's content type:

@AWSEXP {@b{if} Response.Content_Type (Data) = "text/html" @b{then}
   ...
@b{end if};}

@noindent
Or using the MIME types defined in @code{AWS.MIME} unit:

@AWSEXP {@b{if} Response.Content_Type (Data) = MIME.Text_HTML @b{then}
   ...
@b{end if};}

@noindent
And display the content if it is some kind of text data:

@AWSEXP {Text_IO.Put_Line (Response.Message_Body (Data));}

@noindent
If the content is some kind of binary data (executable, PNG image, Zip
archive...), then it is possible to write the result to a file for
example. Look at the @code{agent} program in the @code{demos}
directory.

@noindent
If the Web page is protected and you must pass the request through an
authenticating proxy, the call will becomes:

@AWSEXP {Data := Client.Get
  (URL        => "http://www.mydomain.net/protected/index.html"
   User       => "me",
   Pwd        => "mypwd",
   Proxy      => "192.168.67.1",
   Proxy_User => "puser",
   Proxy_Pwd  => "ppwd");}

@noindent
@cindex upload, client
The client upload protocol is implemented. Using @code{AWS.Client.Upload} it
is possible to send a file to a server which support the file upload protocol.

@c ======================================================================

@node High level services
@chapter High level services

@noindent
Here you will find a description of high level services. These services are
ready to use with AWS and can be used together with user's callbacks.

@noindent
Refer to the Ada spec for a complete API and usage description.

@menu
* Directory browser::
* Dispatchers::
* Static Page server::
* Transient Pages::
* Split pages::
* Download Manager::
* Web Elements::
* Web Blocks::
* Web Cross-References::
@end menu

@c ----------------------------------------------------------------------

@node Directory browser
@section Directory browser
@cindex Directory browser

@noindent
This service will help building a Web directory browser. It has a lot
of options to sort directory entries and is based on the templates
interface @pxref{AWS.Templates}. This means that you can use the
default directory template or provide your own.

@pxref{AWS.Services.Directory} for complete spec and services descriptions.

@c ----------------------------------------------------------------------

@node Dispatchers
@section Dispatchers
@cindex Dispatchers

@noindent
In many AWS applications it is needed to check the URI to give the
right answer. This means that part of the application is a big
@b{if/elsif} procedure. Also, in standard callback it is not possible
to have user data. Both of these restrictions are addressed with the
Dispatchers facilities.

@noindent
Working with a dispatcher is quite easy:

@enumerate
@item Create a new dispatcher by inheriting from the service you want
to build.
@item Register a set of action based on rules (strings, regular
expressions depending on the service)
@end enumerate

@menu
* Callback dispatcher::
* Method dispatcher::
* URI dispatcher::
* Virtual host dispatcher::
* Transient pages dispatcher::
* Timer dispatcher::
* Linker dispatcher::
* SOAP dispatcher::
@end menu

@node Callback dispatcher
@subsection Callback dispatcher
@cindex Dispatchers callback
@cindex Callback, dispatcher

@noindent
This is a wrapper around the standard callback procedure. It is needed
to mix dispatcher based callback and access to procedure
callback. Note that it is not in the @code{AWS.Services.Dispatchers}
hierarchy but in @code{AWS.Dispatchers.Callback} because this is a
basic service needed for the server itself. It is referenced here for
documentation purpose but an AWS server can be built with using it.

@pxref{AWS.Dispatchers.Callback} for complete spec description.

@node Method dispatcher
@subsection Method dispatcher
@cindex Dispatchers method
@cindex method, dispatcher

@noindent
This is a dispatcher based on the request method. A different callback
procedure can be registered for the supported request methods: GET,
POST, PUT, HEAD.

@pxref{AWS.Services.Dispatchers.Method} for complete spec description.

@node URI dispatcher
@subsection URI dispatcher
@cindex Dispatchers URI
@cindex URI, dispatcher

@noindent
This is a dispatcher based on the request resource. A different callback
procedure can be registered for specific resources. The resource is
described either by its full name (string) or a regular expression.

@pxref{AWS.Services.Dispatchers.URI} for complete spec description.

@node Virtual host dispatcher
@subsection Virtual host dispatcher
@cindex Dispatchers virtual host
@cindex virtual host, dispatcher

@noindent
This is a dispatcher based on the host name. A different callback
procedure can be registered for specific host. This is also known as
virtual hosting.

@noindent
The same computer can be registered into the DNS with different
names. So all names point to the same machine. But in fact you want
each name to be seen as a different Web server. This is called virtual
hosting. This service will just do that, call different @b{callback}
procedures or redirect to some @b{machine/port} based on the host name
in the client's request.

@pxref{AWS.Services.Dispatchers.Virtual_Host} for complete spec description.

@node Transient pages dispatcher
@subsection Transient pages dispatcher
@cindex Dispatchers Transient pages
@cindex transient pages, dispatcher

@noindent
This is a dispatcher that calls a user's callback and if the resource
requested is not found (i.e. the user's callback returns status code
404) it checks if this resource is known as a transient
page. @pxref{Transient Pages}.

@node Timer dispatcher
@subsection Timer dispatcher
@cindex Dispatchers Timer
@cindex timer, dispatcher

@noindent
A timer dispatcher can be used to call different callback routines
depending on the current date and time. Such dispatcher is composed of
a set of @code{Period} activated. When the current date and time is
inside a @code{Period} the corresponding callback is called. A
@code{Period} can eventually be repeated. Here are the different kind
of @code{Period} supported by @code{AWS}:

@table @b

@item Once

A unique period in time. The boundaries are fully described using a
year, month, day, hour, minute and second.

@item Yearly

A period that repeats each year. The boundaries are described using a
month, day, hour, minute and second.

@item Monthly

A period that repeats each month. The boundaries are described using a
day, hour, minute and second.

@item Weekly

A period that repeats each week. The boundaries are described using a
day name, hour, minute and second.

@item Daily

A period that repeats each day. The boundaries are described using an
hour, minute and second.

@item Hourly

A period that repeats each hour. The boundaries are described using a
minute and second.

@item Minutely

A period that repeats each minute. The boundaries are described using
a second.

@end table

@node Linker dispatcher
@subsection Linker dispatcher
@cindex Dispatchers Linker
@cindex linker, dispatcher

@noindent
A dispatcher that can be used to chain two dispatchers. The response
of the first dispatcher is returned except if it is a 404 (Not Found)
error. In this case, the response of the second dispatcher is returned.

@node SOAP dispatcher
@subsection SOAP dispatcher
@cindex Dispatchers SOAP
@cindex SOAP, dispatcher

@noindent
@code{AWS} provides also a @code{SOAP} specific dispatcher. This is a way to
automatically route HTTP requests or @code{SOAP} requests to different
callback routines.

@pxref{SOAP helpers} for more information.

@pxref{SOAP.Dispatchers.Callback} for complete spec description.

@c ----------------------------------------------------------------------

@node Static Page server
@section Static Page server
@cindex Static Page server
@cindex Simple Page server
@cindex Page server

@noindent
This service is a ready to use static page server callback. Using it
is possible to build a simple static page server, as simple as:

@AWSEXP {@b{with} AWS.Server;
@b{with} AWS.Services.Page_Server;

@b{procedure} WPS @b{is}
   WS : AWS.Server.HTTP;
@b{begin}
   AWS.Server.Start
     (WS, "Simple Page Server demo",
      Port           => 8080,
      Callback       => AWS.Services.Page_Server.Callback'Access,
      Max_Connection => 5);

   AWS.Server.Wait (AWS.Server.Q_Key_Pressed);

   AWS.Server.Shutdown (WS);
@b{end} WPS;}

@noindent
Build this program and launch it, it will server @code{HTML} pages and images
in the current directory.

@noindent
It is possible to activate the directory browsing facility of this
simple page server. This is not activated by default. This feature
is based on the directory browsing service @pxref{Directory browser}.

@noindent
Note that this service uses two template files:

@table @b
@item aws_directory.thtml

The template page used for directory browsing. See
@pxref{AWS.Services.Directory} for a full description of this template usage.

@item 404.thtml

The Web page returned if the requested page is not found. This is a
template with a single tag variable named PAGE. It will be replaced by
the ressource which was not found.

@i{Note that on Microsoft IE this page will be displayed only if the
total page size is bigger than 512 bytes or it includes at least one image.}

@end table

@pxref{AWS.Services.Page_Server} for a complete spec description.

@c ----------------------------------------------------------------------

@node Transient Pages
@section Transient Pages
@cindex transient pages
@cindex pages, transient

@noindent
A transient page is a resource that has a certain life time on the
server. After this time the resource will be released and will not be
accessible anymore.

@noindent
Sometimes you want to reference, in a Web page, a resource that is built
in memory by the server. This resource can be requested by the client (by
clicking on the corresponding link) or not, in both cases the page must
be released after a certain amount of time to free the associated memory.

@noindent
This is exactly what the transient pages high level service do
automatically. Each transient page must be registered into the
service, a specific routine named @code{Get_URI} can be used to create
a unique @code{URI} on this server. @pxref{AWS.Services.Transient_Pages}.

@noindent
A transient pages dispatcher can be used to build a transient pages
aware server. @pxref{Transient pages dispatcher}.

@c ----------------------------------------------------------------------

@node Split pages
@section Split pages
@cindex split pages
@cindex pages, split

@noindent
It not not very convenient to send back a Web page with a large
table. In such a case it is better to split the table in chunks (20
lines or so) and to send only the first page. This page reference the
next pages and can also contains an index of the pages.

@noindent
The @code{AWS}'s split page feature can automatically do that for
you. Given template @code{Translate_Table} or @code{Translate_Set} and the
max line per page it returns the first page and create a set of
transient pages for all other pages. A set of template tags are used
to reference the previous and next page and also to build the page index.

@noindent
There is different ways to split a set of pages and ready-to-use
splitters are available:

@table @b
@item Alpha
Split in (at most) 28 pages, one for empty fields, one for all fields
that start with a digit, and one for each different initial letter.
@pxref{AWS.Services.Split_Pages.Alpha}.

@item Alpha.Bounded
Same as the alpha splitter, but pages larger than a Max_Per_Page value
are further splitted.
A secondary index is generated that gives the various pages for a given
letter. @pxref{AWS.Services.Split_Pages.Alpha.Bounded}.

@item Uniform
Split in pages of length Max_Per_Page (except the last one). This
corresponds to the default service in Split_Pages package.
@pxref{AWS.Services.Split_Pages.Uniform}.

@item Uniform.Alpha
Same as the uniform splitter, but builds in addition an alphabetical
secondary index from a key field.
@pxref{AWS.Services.Split_Pages.Uniform.Alpha}.

@item Uniform.Overlapping
Same as the uniform splitter, but pages (except the first one)
repeat Overlap lines from the previous page in addition to the
Max_Per_Page lines. @pxref{AWS.Services.Split_Pages.Uniform.Overlapping}.
@end table

@noindent
Using the spliter abstract interface it is possible to build a
customized splitter algorithm. @pxref{AWS.Services.Split_Pages}.

@c ----------------------------------------------------------------------

@node Download Manager
@section Download Manager
@cindex Download Manager

@noindent
A server that need to handle lot of large downloads can run out of
connection to answer the standard Web pages. A solution is to increase the
number of simultaneous connections, but this is not really efficient
as a task is created for each connection and does not ensure that all
the connections will be used for the downloads anyway.

@noindent
The download manager can be used for that, and provides the following
feature:

@itemize
@item use a single task for all downloads
@item can be configured to limit the number of simultaneous connections
@item downloads past this limit are queued
@item send messages to the client with the position in the waiting line
@item send messages to the client when the download is about to start
@end itemize

@noindent
The server must be configured to use dispatchers (standard callbacks
are not supported, note that it is possible to create a dispatcher for
standard callbacks. @pxref{AWS.Dispatchers.Callback}).

@noindent
To start the download manager you need to pass the main server
dispatcher object. The start routine will return a new dispatcher,
linked with the download server specific dispatcher, that must be used
to start the standard Web server. See comment in
@pxref{AWS.Services.Download}.

@noindent
To queue a download request in the download manager you just need to
create a stream object (can be any kind of stream, see
@code{AWS.Resources.Streams.*}) for the resource to download.

@noindent
The download manager needs two templates files:

@table @code

@item aws_download_manager_waiting.thtml

This template is used for sending a message to the client when the
request is on the waiting line. The tags defined in this template file
are:

@table @b
@item NAME
the name of the resource to download (the filename), this is the
default filename used for the client side save dialog.

@item RES_URI
the URI used to access the resource.

@item POSITION
the position in the waiting line (not counting the current served clients).
@end table

@item aws_download_manager_start.thtml

This template is used for sending a message to the client when the
download is about to start (the request is out of the waiting
line). The tags defined in this template file are:

@table @b
@item NAME
as above

@item RES_URI
as above
@end table
@end table

@noindent
It is important to note that those templates must be reloaded
periodically. The best way to do that in the context of an @code{HTML}
document is to use a meta-tag. For example to refresh the page every
two seconds:

@AWSEXP{<meta http-equiv="refresh" content="2">}

@noindent
The templates could look like:

@table @code
@item aws_download_manager_waiting.thtml

@AWSEXP{<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
        "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
  <meta http-equiv="refresh" content="2">
  <title>Download Manager - waiting</title>
</head>
<body>
  <p>Waiting for downloading @@_NAME_@@
  <p>Position in the waiting line @@_POSITION_@@
</body>
</html>
}

@item aws_download_manager_start.thtml

@AWSEXP{<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
        "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
  <meta http-equiv="refresh" content="2">
  <title>Download Manager - waiting</title>
</head>
<body>
  <p>Waiting for downloading @@_NAME_@@
  <p>The download will start in a moment
</body>
</html>
}

@end table

@c ----------------------------------------------------------------------

@node Web Elements
@section Web Elements
@cindex Web Elements

@menu
* Ajax::
* Installation and requirements::
@end menu

@noindent
@code{AWS} provides some components to help creating nice looking Web
interfaces. It is possible to browse those Web Elements using the
@code{web_elements} demo. Just launch this Web application from the
demos directory and turn your Web browser to
@url{http://localhost:2400}.

Currently @code{AWS} provides:

@itemize
@item Notebooks (based on CSS)
@item CSS Menu
@item Rounded boxes
@item Ajax
@end itemize

@noindent
All of them are based on templates to be easily reused in other
applications. The three first are best described by the Web Elements
demos as they are 100% design. The @code{Ajax} one is a bit more complex, we
will present its use in the following section.

@node Installation and requirements
@subsection Installation
@cindex we_icons
@cindex we_js

To ease integration we have used the following design:

@itemize

@item Sub-directories found in the @code{AWS}'s web_elements directory
are self contained. The content must be copied into the project. Note
that the icons and javascripts directories contain the
icons and javascripts code shared by all web elements and must also be
copied, see below.

@item Each graphic elements (icons) is referenced into the templates with the
alias @code{/we_icons/<icon_name>}. So users must provide the right alias
("@code{/we_icons/}") in the  Web server.

@item Each JavaScripts code is referenced into the templates with the
alias @code{/we_js/<script>}. So users must provide the right alias
(@code{"/we_js/"}) in the  Web server.
@end itemize

@node Ajax
@subsection Ajax
@cindex Ajax
@cindex aws_action_replace.tjs
@cindex aws_action_clear.tjs

@menu
* Steps to do Ajax::
* Basic Ajax support::
* XML based Ajax::
* Advanced Ajax::
@end menu

@noindent
First of all, @code{Ajax} stand for
@i{Asynchronous JavaScript language and XML}, and is not well defined
at the moment. @code{Ajax} is on one side able to send HTTP requests
to the Web server and on the other side able to manipulate directly the Web
browser's @code{DOM} tree. On the @code{DOM} it can add, remove or
replace @code{XML} nodes. So, it is possible to change the content of
a Web page without reloading it from the server.

@noindent
Most importantly, @code{Ajax} changes the way Web applications are
thought from @b{page} based to @b{event} based.

@noindent
As implemented into @code{AWS}, @code{Ajax} support comes as a set of
@code{JavaScript} templates. Using those templates there is no need to
know @code{JavaScript} (except for the @code{JavaScript} event names) and it
makes @code{Ajax} programming lot easier. Two actions are provided,
one for replacing another for clearing part of the web page content.

@node Steps to do Ajax
@subsubsection Steps to do Ajax

@noindent
What are the steps to do @code{Ajax} ?

@noindent
Remember, do not think about the Web page but about a specific widget
(@code{HTML} fragments) with the associated event and action.

@enumerate
@item Include the AWS/Ajax support file

This is the @code{AWS/Ajax} runtime, it contains @code{JavaScript}
code needed for the @code{AWS/Ajax} support.

@item Create the Web widgets/forms

There is nothing special here, use your favorite Web designer tool.

@item Create Web area

Using some @code{HTML} <div> tags we create areas where we will place
@code{HTML} fragments later. For example when clicking on a button
(described above) in our Web interface we want to display a new form
in this area.

@item Name the widgets/forms/area using id="name" attribute

Give a different name to the widgets using id="name". This name will
be later used to identify the widgets on which the envent and
corresponding action must be placed. We do not want to clutter the Web
design with @code{JavaScript} code like @code{onclick="dothis()"} or
@code{onchange="dothat()"}.

@item Add the proper event/action to the widgets using the AWS/Ajax templates

This is the interresting part. At this point we link events/actions
to the widgets and specify in which area the results sent by the
server will be placed.

@end enumerate

@noindent
This is not the only way to do @code{Ajax}, we just presented here a simple
approach that works well with the @code{AWS/Ajax} templates.

@node Basic Ajax support
@subsubsection Basic Ajax support

@noindent
This section describes the @code{AWS/Ajax} support where the answer from the
server is an @code{HTML} fragment. This basic support is designed to
be used for migration of a Web server to @code{Ajax}. For new
applications, it is worth considering using the XML based Ajax support,
@pxref{XML based Ajax}.

@noindent
Let's have a very simple example:

@itemize @bullet
@item The AWS/Ajax runtime support

@AWSEXP{@@@@INCLUDE@@@@@ aws.tjs}

Must be included in every Web pages into the @code{<head>} tag.

@item The widget: a button

@AWSEXP{<input @b{id="clickme"} type="button" value="Clik Me">}

@item The result area: a div

@AWSEXP{<div @b{id="placeholder"}>... result here ...</div>}

@item The AWS/Ajax

@AWSEXP{@@@@INCLUDE@@@@ aws_action_replace.tjs onclick @b{clickme} @b{placeholder}}

Basically it places an @b{onclick} attribute (the event) in the @code{HTML}
@code{<input>} identified as @b{clickme} (the action) above. Here is
what happen when the button is clicked:

@itemize
@item send the "/onclick$clickme" HTTP request to the server
@item asynchronously wait for the answer, when received place the
message body into the @code{<div>} @b{placeholder}.
@end itemize

@end itemize

@noindent
On the server side the code would look like this:

@AWSEXP{@b{function} Callback (Request : @b{in} Status.Data) @b{return} Response.Data @b{is}
   URI : @b{constant} String := Status.URI (Request);
begin
   @b{if} URI = "/clickme" @b{then}
      @b{return} Response.Build (MIME.Text_HTML, "you click me!");
   ...
}

@noindent
So when the button is clicked the string @b{"you click me!"} will replace
the @b{"... result here ..."} string of the place holder div above.

@noindent
This is a simple and very limited example as there is no parameter
passed to the @code{HTTP} request. In real Web applications it is necessary
to send a context with the request. This can be either the value of
other widgets or all values of widgets' form.

@noindent
References to widgets or forms can be passed to the
@file{aws_action_replace.tjs} template starting with the 5th
parameter.

@AWSEXP{<input @b{id="field"} type="text" value="default value">

...

@@@@INCLUDE@@@@ aws_action_replace.tjs (onclick @b{clickme} @b{placeholder} 5=>@b{field})
}

or

@AWSEXP{<form @b{id="small_form"} name="small_form">
...
</form>

@@@@INCLUDE@@@@ aws_action_replace.tjs (onclick @b{clickme} @b{placeholder} 5=>@b{small_form})
}

@noindent
Note that the @code{onclick} event is only one of the possible
@code{JavaScript} event on a @code{button}. It is possible to used
any supported event, for example on an @code{HTML} @code{<select>} widget
it is common to map the action to the @code{onchange} event.

@noindent
@code{AWS} also provides support for clearing an area or a widget
content (like an input).

@AWSEXP{@@@@INCLUDE@@@@ aws_action_clear.tjs (onclick, clear, field)}

@noindent
This simple action adds the @b{onclick} event to the @b{clear} button
to erase the content of the @b{field} widget.

@node XML based Ajax
@subsubsection XML based Ajax

@noindent
In many cases you'll like to update and/or clear multiple areas in your
Web interface. With the templates above only a single action is
possible. @code{AWS} provides support for @code{XML} based answers. In
this @code{XML} documents it is possible to:

@itemize @bullet
@item replace an area with a new content

@AWSEXP{<replace id="@b{item_id}">@i{new text}</replace>}

@item clear an area

@AWSEXP{<clear id="@b{item_id}"/>}

@item add an item into a select widget

@AWSEXP{<select action="@b{add}" id="@b{item_id}"
option_value="value" option_content="content"/>}

@item remove an item from a select widget

@AWSEXP{<select action="@b{delete}" id="@b{item_id}" option_value="value"/>}

@item select a specific item in a select widget

@AWSEXP{<select action="@b{select}" id="@b{item_id}" option_value="value"/>}

@item clear a select widget (remove all items)

@AWSEXP{<select action="@b{clear}" id="@b{item_id}"/>}

@item select a radio button

@AWSEXP{<radio action="@b{select}" id="@b{item_id}"/>}

@item check a checkbox

@AWSEXP{<check action="@b{select}" id="@b{item_id}"/>}

@item clear a checkbox

@AWSEXP{<check action="@b{clear}" id="@b{item_id}"/>}

@item call another URL

@AWSEXP{<get url="http://thishost/action">
   <parameters value="name=Ajax"/>
   <field id="input1"/>
</get>
}

This will send the following request:

@AWSEXP{http://thishost/action?name=Ajax&input1=<val_input1>}

Where @b{val_input1} is the current value of the @b{input1} input
widget. The result must be an @code{XML/Ajax} document that will be parsed.

@item make a list sortable

@AWSEXP{<make_sortable>
   <list id="@b{firstlist}"/>
   <list id="@b{secondlist}"/>
</make_sortable>
}

Here @b{firstlist} and @b{secondlist} are @b{id} of @code{UL} elements. It is
possible to specified as many list id as needed. A drag and drop is
then possible for all elements in those lists. It is then possible to
reference such list by passing the list id as a field to the
template. Items on those list will be serialized and passed to the @code{AWS}
callback. Note that for the serialization to work properly, each
@code{LI} elements must be given the id of the list and then the value
we want to pass.

@AWSEXP{<ul id="@b{firstlist}">
   <li id="@b{firstlist_red}">Red</li>
   <li id="@b{firstlist_green}">Green</li>
   <li id="@b{firstlist_blue}">Blue</li>
</ul>
}

The serialization will send each value on this list using a
multi-valued parameter named @b{firstlist[]}.

@AWSEXP{http://server?firstlist[]=red&firstlist[]=green&firstlist[]=blue}

@item make a list not sortable

@AWSEXP{<destroy_sortable>
   <list id="@b{firstlist}"/>
   <list id="@b{secondlist}"/>
</destroy_sortable>
}

Remove the sortable properly from the specified lists.

@item redirect to another URL

@AWSEXP{<location url="http://thishost/go_there"/>}

Redirect the browser to the specified URL.

@item refresh the current page

@AWSEXP{<refresh/>}

Refresh the current page as if the Web Browser refresh button was pressed.

@item add a CSS style to a given node

@AWSEXP{<apply_style id="@b{node_id}">
   <attribute id="display" value="none"/>
</apply_style>
}

Add the CSS style @code{display:none} to the @b{node_id} element. It
is possible to specify multiple attributes if needed.

@item make an entry disabled or enabled

@AWSEXP{<disabled id="@b{item_id}" value="@b{true/false}"/>}

@item make an entry read-only or writable

@AWSEXP{<read_only id="@b{item_id}" value="@b{true/false}"/>}

@item reset a form

@AWSEXP{<reset id="@b{form_id}"/>}

@end itemize

@noindent
Here is an example of such XML document:

@AWSEXP{<response>
   <replace id="xml_status_bar">Fill Widgets...</replace>
   <replace id="text1">Response from XML</replace>
   <replace id="text2">Another response for text2</replace>
   <replace id="input1">tag is input1</replace>
   <replace id="input2">tag is input2</replace>
   <select action="add" id="xmlsel" option_value="one" option_content="1"/>
   <select action="add" id="xmlsel" option_value="two" option_content="2"/>
   <select action="add" id="xmlsel" option_value="three" option_content="3"/>
   <select action="select" id="xmlsel" option_value="two"/>
   <radio action="select" id="radio1"/>
   <check action="select" id="check1"/>
   <check action="select" id="check3"/>
   <check action="clear" id="check2"/>
</response>
}

@noindent
To register an @code{Ajax} action to a specific tag id a macro can be
used. It is named @code{JS_ACTION} and defined in @file{ajax_api.tjs}.
The usage is similar to what is described in the previous section
(@pxref{Basic Ajax support}) except that in this case we use a macron
instead of an include file and we do not have to pass the placeholder.

@noindent
Let's revisit the first example above to use the @code{XML}
@code{Ajax} support.

@itemize @bullet
@item The AWS/Ajax runtime support

@AWSEXP{@@@@INCLUDE@@@@@ aws.tjs}

Must be included in every Web pages into the @code{<head>} tag.

@item The AWS/Ajax API

@AWSEXP{@@@@INCLUDE@@@@@ ajax_api.tjs}

Must be included at least once during an application life-time. It
gives access to the @code{JS_ACTION} macro.

@item The widget: a button

@AWSEXP{<input @b{id="clickme"} type="button" value="Clik Me">}

@item The result area: a div

@AWSEXP{<div @b{id="placeholder"}>... result here ...</div>}

@item The AWS/Ajax

@AWSEXP{@@_JS_ACTION(onclick, @b{clickme})_@@}

Basically it places an @b{onclick} attribute (the event) in the @code{HTML}
@code{<input>} identified as @b{clickme} (the action) above. Here is
what happen when the button is clicked:

@itemize
@item send the "/onclick$clickme" HTTP request to the server
@item asynchronously wait for the XML answer, when received parse the
answer and perform the actions according to the @code{XML} content.
@end itemize

@end itemize

@noindent
To set the placeholder with "@b{new text}", the @code{XML} document
returned by the server must be:

@AWSEXP{<response>
   <replace id="@b{placeholder}">@b{new text}</replace>
</response>
}

@noindent
If we want also to clear the input field named @b{field} and to select the
radio button named @b{radio1} we must return:

@AWSEXP{<response>
   <replace id="@b{placeholder}">@b{new text}</replace>
   <clear id="@b{field}"/>
   <radio action="select" id="@b{radio1}"/>
</response>
}

@noindent
This is by far the most flexible solution as it is possible to return, from the
server, a structured answer.

@noindent
A final comment, if the text returned by the server to replace a
specific area is an @code{HTML} fragment, the content must be placed into a
@code{CDATA} tag:

@AWSEXP{<response>
   <replace id="item_id">
      <![CDATA[ @i{HTML CODE HERE} ]]>
   </replace>
</response>
}

@node Advanced Ajax
@subsubsection Advanced Ajax

@noindent
Finally, if this is not enough because you need to use some specific
@code{JavaScript} code, @code{AWS} provides a macro named
@code{BIND_JS} to add an event to a specific widget, the action being
the name of a @code{JavaScript} routine.

@noindent
This macro together with the @file{aws_func_replace.tjs},
@file{aws_func_clear.tjs} templates and the @file{JS_ACTION} macro can
be used to chain multiple actions. Those templates are the function
body used by the corresponding templates @file{aws_action_replace.tjs},
@file{aws_action_clear.tjs}.

@noindent
Let say you want to clear a widget, change the content of another one
and calling one of your specific @code{JavaScript} routine when clicking on
a button. It is not possible to have mutiple @code{onclick} events on
the same widget, the solution is the following:

@itemize
@item Create the JavaScript routine to do the job

For this in the the body of the @code{clear_replace()} JavaScript
routine we place:

function clear_replace() @*
@{
@AWSEXP{@@@@INCLUDE@@@@ aws_func_replace.tjs (@b{clickme} @b{placeholder} 4=>@b{field})
@@@@INCLUDE@@@@ aws_func_clear.tjs (@b{area})
call_this_routine();
}
@}

Then to add the event on the widget:

@AWSEXP{@@_BIND_JS(@b{onclick}, @b{clickme} @b{clear_replace})_@@}

@end itemize

@noindent
Furthermore, it is possible to pass (as the parameter number 20) a
routine to call after a specific action to all templates and to the
@code{JS_ACTION} macro. This is another way to chain multiple actions
for a single event.

@noindent
Note that all @code{AWS/Ajax} templates and the @file{ajax_api.tjs}
file have a set of comments at the start explaining in details the
usage of each parameter.

@c ----------------------------------------------------------------------

@node Web Blocks
@section Web Blocks
@cindex Web Blocks

@menu
* Web Block example::
* Web Block and Ajax::
* Web Block and templates2ada::
@end menu

@noindent
The @code{AWS.Services.Web_Block} hierarchy contains an API useful for
keeping context on Web pages. It has been designed to be able to split
a Web application into a set of independent blocks that can be put
together in the same Web page. The context is then useful as it is
passed and known by each individual block. Note that this is different
than the session as a session is global to the current Web browser
whereas the context can be different for each individual web pages
opened.

@noindent
Instead of parsing a whole page using @code{AWS.Templates} API the web blocks
are registered independently using @code{AWS.Services.Web_Block.Registry}.
The block is registered together with its templates and a callback to use
to get user's data for this specific block with the given context.

@noindent
So using this API, instead of having a set of callbacks returning an
@code{AWS.Response.Data} and where the final rendering is to be done
by the client code, we have a set of callbacks that returns a
@code{Translate_Set}. The client just have to fill the set with the
data corresponding to the actual request and possibly using the
context. The final rendering is done by the provided services in
@code{Web_Block.Registry}.

@noindent
Note that all Web pages must also be registered into the registry
to ensure that the context identification is properly kept. The context
identification is injected into the Web pages transparently for the
end-user when using @code{Ajax}.

@node Web Block example
@subsection Web Block example

@noindent
Let's have a simple example, a page containing a single block with a
tag (@@_COUNTER_@@) which is incremented by one each time it is
used. The code can be found in @file{demos/web_block}.

@noindent
First create the following HTML fragment and place it into
@file{counter.thtml}.

@AWSEXP{<p>@@_COUNTER_@@</p>}

@noindent
Then create the main page and place it into @file{page.thtml}. The
important part is the @@_CTX_WB_@@ tag which is passed to the link. This
tag is the context identifier, it must be passed to each request. Note
that this is automatically done when using the @code{Ajax} framework
(@pxref{Web Block and Ajax}).

@AWSEXP{<html>
   <head>
      <title>Main Page</title>
   </head>
   <body>
      <p>This is the main page, bellow is a simple counter</p>
      <p>@@_COUNTER_@@</p>
      <a href="/?CTX_WB=@@_CTX_WB_@@>Next</a>
   </body>
</html>
}

@noindent
The @code{Web_Callbacks} package contains the application callbacks.

@AWSEXP{@b{with} AWS.Response;
@b{with} AWS.Status;
@b{with} AWS.Templates;
@b{with} AWS.Services.Web_Block.Context;

@b{package} Web_Callbacks @b{is}

   @b{use} AWS;
   @b{use} AWS.Services;

   @b{function} Main (Request : @b{in} Status.Data) @b{return} Response.Data;
   --  Main callback which handle the home page

   @b{procedure} Counter
     (Request      : @b{in}              Status.Data;
      Context      : @b{not null access} Web_Block.Context.Object;
      Translations : @b{in out}          Templates.Translate_Set);
   --  The callback handling the counter web block

@b{end} Web_Callbacks;}

@noindent
Last part is to actually implement the @code{Counter} callback. Here
is a possible implementation making use of the context to keep the
counter state.

@AWSEXP{@b{with} AWS.Utils;
@b{with} AWS.Messages;
@b{with} AWS.MIME;
@b{with} AWS.Services.Web_Block.Registry;

@b{package body} Web_Callbacks @b{is}

   -------------
   -- Counter --
   -------------

   @b{procedure} Counter
     (Request      : @b{in}              Status.Data;
      Context      : @b{not null access} Web_Block.Context.Object;
      Translations : @b{in out}          Templates.Translate_Set)
   @b{is}
      N : Natural := 0;
   @b{begin}
      @b{if} Context.Exist ("N") @b{then}
         N := Natural'Value (Context.Get_Value ("N"));
      @b{end if};

      N := N + 1;
      Context.Set_Value ("N", Utils.Image (N));

      Templates.Insert
        (Translations,
         AWS.Templates.Assoc ("COUNTER", N));
   @b{end} Counter;

   ----------
   -- Main --
   ----------

   @b{function} Main (Request : @b{in} Status.Data) @b{return} Response.Data @b{is}
      URI : constant String := Status.URI (Request);
   @b{begin}
      return Web_Block.Registry.Build
        (Key          => URI,
         Request      => Request,
         Translations => Set);
   @b{end} Main;

@b{end} Web_Callbacks;}

@noindent
Finally, we write the main procedure:

@AWSEXP{@b{with} Ada.Text_IO;

@b{with} AWS.Server;
@b{with} AWS.Services.Web_Block.Registry;

@b{with} Web_Callbacks;

@b{procedure} Web_Block @b{is}

   @b{use} Ada;
   @b{use} AWS;
   @b{use} AWS.Services;

   HTTP : AWS.Server.HTTP;

@b{begin}
   --  First we register the main page and the counter block

   Services.Web_Block.Registry.Register
     ("/", "page.thtml", null);

   Services.Web_Block.Registry.Register
     ("COUNTER", "counter.thtml",
      Web_Callbacks.Counter'Access, Context_Required => True);

   --  Then we just start the server

   Server.Start (HTTP, "web_block", Web_Callbacks.Main'Access);

   Text_IO.Put_Line ("Press Q to terminate.");

   Server.Wait (Server.Q_Key_Pressed);

   Server.Shutdown (HTTP);
@b{end} Web_Block;}

@noindent
Compile and run the server. Then connect to the server and click on
next. The counter will be incremented by one each time.

@node Web Block and Ajax
@subsection Web Block and Ajax

@noindent
The Web Block framework has really been designed to be used with
@code{Ajax}. It is the only way to gain the full power of the Web Block
framework.

@noindent
For the complete code, see @code{demos/web_block_ajax}.

@noindent
When using @code{Ajax} it is not needed to explicitly pass the context
identification to every link. This is done automatically by the
framework. So the main page will look like this:

@AWSEXP{@@@@INCLUDE@@@@ ../../web_elements/javascripts/ajax_api.tjs
<html>
   <head>
      <title>Main Page</title>
      @@@@INCLUDE@@@@ ../../web_elements/javascripts/aws.tjs
   </head>
   <body>
      <p>This is the main page, bellow is a simple counter</p>
      @@_WIDGET_COUNTER_@@
   </body>
</html>}

@noindent
The counter widget is on @file{widget_counter.thtml}:

@AWSEXP{<!-- implementation of a simple counter widget -->
<p><div id="counter">@@_COUNTER_@@</div></p>
<a id="next" href="/">Next</a>
@@_JS_ACTION(onclick, next)_@@}

For the @code{Ajax} part, @pxref{Ajax}.

@noindent
We now have one more register call for registering the @code{next} button
@code{Ajax} callback, and a callback named @code{Widget_Counter} for
displaying the block:

@AWSEXP{Services.Web_Block.Registry.Register
  ("WIDGET_COUNTER", "widget_counter.thtml",
   Web_Callbacks.Widget_Counter'Access);

Services.Web_Block.Registry.Register
  ("/onclick$next", "r_widget_counter.txml",
   Web_Callbacks.Onclick_Next'Access,
   Content_Type     => MIME.Text_XML,
   Context_Required => True);}

@noindent
The @code{next} @code{Ajax} button is using an XML based response which
is defined in @file{r_widget_counter.txml}:

@AWSEXP{<response>
   <replace id="counter">@@_COUNTER_@@</replace>
</response>}

@noindent
The @code{Widget_Counter} callbacks just have to set the
@code{COUNTER} tag variable to the corresponding value. This is used to
display the block. The @code{Ajax} callback @code{Onclick_Next} has to
increment the counter and set the @code{COUNTER} tag variable, a simple
implementation is:

@AWSEXP{@b{procedure} Onclick_Next
  (Request      : @b{in}              Status.Data;
   Context      : @b{not null access} Web_Block.Context.Object;
   Translations : @b{in out}          Templates.Translate_Set)
@b{is}
   N : Natural := 0;
@b{begin}
   @b{if} Context.Exist ("N") @b{then}
      N := Natural'Value (Context.Get_Value ("N"));
   @b{end if};

   N := N + 1;

   Context.Set_Value ("N", Utils.Image (N));

   Templates.Insert
     (Translations, Templates.Assoc ("COUNTER", N));
@b{end} Onclick_Next;}

@noindent
The framework will then call @code{Onclick_Next} when pressing the
@code{Next} button. This routine increments N by one sending back a
response based on @code{r_widget_counter.txml}. Finally, the client
browser will parse this XML response and do the corresponding actions.

@node Web Block and templates2ada
@subsection Web Block and templates2ada

@noindent
For the complete code, see @code{demos/web_block_ajax_templates}.

@noindent
It is possible to use the @code{Templates_Parser's templates2ada} tool for
generating the callbacks register calls. This ensures that all tags on the
application Web Pages have a corresponding callback.

@noindent
The code is almost identical to the standard @code{Ajax} example above. The
main difference is that we need to use a naming convention for the
blocks. This way we can generate automatically the corresponding
callbacks using a template. A common convention is to add @code{LAZY_} as
prefix for the name of the blocks. With this convention the main page
template is:

@AWSEXP{@@@@INCLUDE@@@@ ../../web_elements/javascripts/ajax_api.tjs
<html>
   <head>
      <title>Main Page</title>
      @@@@INCLUDE@@@@ ../../web_elements/javascripts/aws.tjs
   </head>
   <body>
      <p>This is the main page, bellow is a simple counter</p>
      @@_LAZY_WIDGET_COUNTER_@@
   </body>
</html>}

@noindent
We need also modify the standard @file{templates.tads} as distributed
with the @code{Templates_Parser}. Here is the interesting part:

@AWSEXP{@@@@SET@@@@ PACKAGE = WBlocks

...

@b{with} AWS.MIME;
@b{with} AWS.Services.Web_Block.Registry;
@b{with} Web_Callbacks;

@@@@TABLE@@@@
@b{with} @@_PACKAGE_@@.@@_CAPITALIZE:REPLACE_ALL(\./_):BASENAME_@@;
@@@@END_TABLE@@@@

@b{package body} @@_PACKAGE_@@ @b{is}

   @b{use} AWS;

   @b{package body} Lazy @b{is}

      --------------
      -- Register --
      --------------

      @b{procedure} Register @b{is}
         @b{use} AWS.Services;
      @b{begin}
         --  Register blocks
@@@@TABLE@@@@
   @@@@IF@@@@ @@_UPPER:SLICE(1..5):VARIABLE_LIST_@@ = "LAZY_"
         Web_Block.Registry.Register
           ("@@_VARIABLE_LIST_@@",
            "@@_LOWER:REPLACE_ALL(LAZY_/):VARIABLE_LIST_@@.thtml",
            Web_Callbacks.@@_CAPITALIZE:REPLACE_ALL(LAZY_/):VARIABLE_LIST_@@'Access);
   @@@@END_IF@@@@
@@@@END_TABLE@@@@
         --  Register Ajax
@@@@TABLE@@@@
   @@@@TABLE@@@@
      @@@@IF@@@@ not @@_IS_EMPTY:AJAX_EVENT_@@
         Services.Web_Block.Registry.Register
            ("/@@_AJAX_EVENT_@@$@@_AJAX_ACTION_@@",
             @@_PACKAGE_@@.R_@@_CAPITALIZE:REPLACE_ALL(\./_):AJAX_FILE_@@.Template,
             Web_Callbacks.@@_CAPITALIZE:AJAX_EVENT_@@@_UNDERSCORE_@@@_CAPITALIZE:AJAX_ACTION_@@'Access,
             Content_Type     => MIME.Text_XML,
             Context_Required => True);
      @@@@END_IF@@@@
   @@@@END_TABLE@@@@
@@@@END_TABLE@@@@
      @b{end} Register;
   @b{end} Lazy;

@b{end} @@_PACKAGE_@@;}

@noindent
Basically this is to write a register call for every template's
tag starting with @code{LAZY_}. The second section is to write a
register call for every @code{Ajax} event. All callbacks are expected to be in
a package named @code{Web_Callbacks}. It is of course possible to change
this template to reference callbacks for blocks and @code{Ajax} in separate
packages. The use of a template here is very flexible.

@noindent
Now let's parse the application HTML and XML templates and create the
corresponding Ada specs and register calls:

@AWSEXP{$ templates2ada -d . -o code.ada -t templates.tada -e .thtml -e .txml
$ gnatchop code.ada}

@noindent
Look at the generated code below, it properly register the
@code{Widget_Counter} callback to be used for rendering
@code{LAZY_WIDGET_COUNTER} using the @file{widget_counter.thtml}. So
we have a tight coupling between the code and the template file. If
the tag is renamed in the template file the application will not
compile anymore. The same is true for @code{Ajax} callbacks, every
@code{Ajax} action put in a template file needs a corresponding
callback in Ada. This greatly helps keeping the application code
synchronized.

@AWSEXP{@b{procedure} Register @b{is}
   @b{use} AWS.Services;
@b{begin}
   Web_Block.Registry.Register
      ("LAZY_WIDGET_COUNTER",
       "widget_counter.thtml",
       Web_Callbacks.Widget_Counter'Access);
   Services.Web_Block.Registry.Register
      ("/onclick$next",
       WBlocks.R_Widget_Counter.Template,
       Web_Callbacks.Onclick_Next'Access,
       Content_Type     => MIME.Text_XML,
       Context_Required => True);
@b{end} Register;}

@noindent
In the main, it is just now required to register the Web pages and to
call the generated @code{Register} procedure:

@AWSEXP{Services.Web_Block.Registry.Register ("/", "page.thtml", null);

WBlocks.Lazy.Register;
}

@noindent
Moreover, an Ada spec containing reference for the tag names is
generated for every HTML and XML template file. All tags can be
referenced using those specs, it is not needed to use string
literal in the application. Again, this ensures that a tag which is
renamed or deleted is detected at compilation time. For example the
@code{Widget_Counter} callback can be rewritten as follow:

@AWSEXP{@b{procedure} Widget_Counter
  (Request      : @b{in}              Status.Data;
   Context      : @b{not null access} Web_Block.Context.Object;
   Translations : @b{in out}          Templates.Translate_Set)
@b{is}
   N : Natural := 0;
@b{begin}
   @b{if} Context.Exist ("N") @b{then}
      N := Natural'Value (Context.Get_Value ("N"));
   @b{end if};

   Templates.Insert
     (Translations, Templates.Assoc (WBlocks.Widget_Counter.COUNTER, N));
@b{end} Widget_Counter;}

@c ======================================================================

@node Web Cross-References
@section Web Cross-References
@cindex webxref
@cindex web cross-references

@noindent
When building an @code{Ajax} Web applications it is required to give ids to
web elements to be able to reference them. It is also quite common to
use CSS to give such and such item a specific style. After some time
it is quite difficult to keep track of all those ids. Are they all
used ? Don't we reference an id that does not exist anymore ?

@noindent
@code{webxref} has been designed to help finding such problems.

@noindent
The files kinds handled are:

@table @file

@item .css
@item .tcss

A CSS (or template CSS file). Ids and classes inside are recorded as
CSS definitions.

@item .xml
@item .html
@item .thtml

A meta-language document. Ids and classes inside are recorded as
referencing a CSS definition and meta-language definition.

@item .txml

An @code{Ajax} response file. Ids declared inside are recorded as referencing
a meta-language definition.

@end table

@noindent
The features are:

@table @b

@item cross-references

By default @code{webxref} output all the references to ids and classes.

@item finding unused items

Output the ids/classes that are defined but not used. For example an
id declared in a CSS but never referenced into an HTML document or an
HTML id never referenced in an @code{Ajax} response file @file{.txml} document.

@item finding undeclared items

Output ids/classes that are referenced but never defined. This is for
example an id inside an @code{Ajax} response file which is never defined into
an HTML document.

@item enforcing a naming scheme for ids and classes

It can enforce a specific prefix for ids and classes. The id prefix
can be based on the filename (using filename's first character and all
character before an underscore). This make it less likely to find the
same id on multiple files.

@end table

@noindent
Note that all references are in a format recognized by tools like @code{GPS}
and @code{Emacs}. It is then possible to navigate inside them easily.

@noindent
All @code{webxref} options are listed using the @code{-h} option.

@c ======================================================================

@node Using SOAP
@chapter Using SOAP
@cindex SOAP
@cindex Simple Object Access Protocol

@noindent
@code{SOAP} can be used to implements Web Services. The @code{SOAP}
implementation uses @code{AWS HTTP} as the transport layer. @code{SOAP} is
platforms and languages independent, to ensure a good
inter-operability, @code{AWS/SOAP} implementation has been validated through
@url{http://validator.soapware.org/}, the version number listed on
this server corresponds to the AWS version string
(@code{AWS.Version}) catenated with the @code{SOAP} version string
(@code{SOAP.Version}).

@noindent
This @code{SOAP} implementation is certainly one with the higher level
of abstraction. No need to mess with a serializer, to know what is a
payload or be an @code{XML} expert. All the low level stuffs are
completely hidden as the @code{SOAP} type system has been binded as
much as possible to the Ada type system.

@noindent
@cindex WSDL
@cindex Web Service Definition Language
The @code{SOAP} type system has been relaxed to be compatible with
@code{WSDL} based @code{SOAP} implementation. In these implementations, types
are generally (as in the Microsoft implementation) not part of the
payload and should be taken from the @code{WSDL} (Web Services Description
Language). @code{AWS/SOAP} is not @code{WSDL} compliant at this stage, all
such types are binded into the Ada type system as strings. It is up to
the programer to convert such strings to the desired type.

@menu
* SOAP Client::
* SOAP Server::
@end menu

@c ----------------------------------------------------------------------

@node SOAP Client
@section SOAP Client
@cindex SOAP Client

@noindent
The @code{SOAP} client interface is quite simple. Here are the step-by-step
instructions to call a @code{SOAP} Web Service:

@enumerate

@item Build the @code{SOAP} parameters

@noindent
As for the @code{SOAP} servers, the @code{SOAP} parameters are built using a
@code{SOAP.Parameters.List} object.

@AWSEXP {Params : @b{constant} Parameters.List
  := +I (10, "v1") & I (32, "v2");}

@item Build the @code{SOAP} Payload

@noindent
The Payload object is the procedure name and the associated parameters.

@AWSEXP {@b{declare}
   Payload : Message.Payload.Object;
@b{begin}
   Payload := Message.Payload.Build ("Add", Params);}

@item Call the @code{SOAP} Web Service

@noindent
Here we send the above Payload to the Web Server which handles the Web
Service. Let's say that this server is named @code{myserver}, it is
listening on port @code{8082} and the @code{SOAPAction} is @code{soapdemo}.

@AWSEXP {Resp : @b{constant} Message.Response.Object'Class :=
   SOAP.Client.Call ("http://myserver:8082/soapdemo", Payload);}

@item Retrieve the result

@noindent
Let's say that the answer is sent back into the parameter named
"myres", to get it:

@AWSEXP {My_Res : @b{constant} Integer := SOAP.Parameters.Get (Params, "myres");}

@end enumerate

@noindent
In the above example we have called a Web Service whose spec could be
described in Ada as follow:

@AWSEXP {@b{function} Add (V1, V2 : @b{in} Integer) @b{return} Integer;
@i{--  Add V1 and V2 and returns the result. In SOAP the result is named "myres"}}

@c ----------------------------------------------------------------------

@node SOAP Server
@section SOAP Server
@cindex SOAP Server
@cindex SOAPAction

@noindent
A @code{SOAP} server implementation must provides a callback procedure as for
standard Web server @pxref{Callback procedure}. This callback must
checks for the @code{SOAP} Action URI to handle both standard Web requests
and @code{SOAP} ones. The @code{SOAPAction} is sent with the HTTP headers and
can be retrieved using @code{AWS.Status.SOAPAction}.

@menu
* Step by step instructions::
* SOAP helpers::
@end menu

@node Step by step instructions
@subsection Step by step instructions

@noindent
Here are the step-by-step instructions to be followed in the @code{SOAP}
callback procedure:

@enumerate

@item Retrieve the @code{SOAP} Payload
@cindex Payload

@noindent
The @code{SOAP} Payload is the @code{XML} message, it contains the
procedure name to be called and the associated parameters.

@AWSEXP {@b{function} SOAP_CB (Request : @b{in} AWS.Status.Data)
  @b{return} AWS.Response.Data
@b{is}
   @b{use} SOAP.Types;
   @b{use} SOAP.Parameters;

   Payload : @b{constant} SOAP.Message.Payload.Object
     := SOAP.Message.XML.Load_Payload (AWS.Status.Payload (Request));}

@noindent
@code{AWS.Status.Payload} returns the @code{XML} Payload as sent by
the @code{SOAP} Client. This @code{XML} Payload is then parsed using
@code{SOAP.Message.XML.Load_Payload} which returns a
@code{SOAP.Message.Payload.Object} object.

@item Retrieve the @code{SOAP} Parameters

The @code{SOAP} procedure's parameters.

@AWSEXP {Params  : @b{constant} SOAP.Parameters.List
  := SOAP.Message.Parameters (Payload);}

@code{SOAP.Parameters.List} is a structure which holds the @code{SOAP}
parameters. Each parameter can be retrieved using a
@code{SOAP.Parameters} API, @pxref{SOAP.Parameters}. For example to
get the parameter named @code{myStruc} which is a @code{SOAP} struct:

@AWSEXP {My_Struct : @b{constant} SOAP_Record
  := SOAP.Parameters.Get (Params, "myStruct");}

Another example, to get the parameter named @code{myInt} which is a
@code{SOAP} integer:

@AWSEXP {My_Int : @b{constant} Integer := SOAP.Parameters.Get (Params, "myInt");}

@item Implements the Web Service

@noindent
This is the real job, as for any procedure you can do whatever is
needed to compute the result.

@item Build the @code{SOAP} answer

@noindent
This is the procedure answer. A @code{SOAP} answer is built from the
@code{SOAP} Payload and by setting the returned parameters.

@AWSEXP {@b{declare}
   Resp        : SOAP.Message.Response.Object;
   Resp_Params : SOAP.Parameters.List;
@b{begin}
   Resp := SOAP.Message.Response.From (Payload);

   Resp_Params := +I (My_Int * 2, "answer");

   SOAP.Message.Set_Parameters (Resp, Resp_Params);}

This build a response which is a single integer value named
@code{answer} with the value @code{My_Int * 2}.

@item Returns the answer back to the client

@noindent
This last step will encode the response object in @code{XML} and will
returns it as the body of an @code{HTTP} message.

@AWSEXP {@b{return} SOAP.Message.Response.Build (Resp);}

@end enumerate

@node SOAP helpers
@subsection SOAP helpers

@noindent
There is two ways to help building the @code{SOAP}
callbacks. @code{AWS} provides a @code{SOAP} specific callback, the spec is :

@AWSEXP {@b{function} SOAP_Callback
  (SOAPAction : @b{in} String;
   Payload    : @b{in} Message.Payload.Object;
   Request    : @b{in} AWS.Status.Data)
   @b{return} AWS.Response.Data;}

@noindent
With both solutions exposed below, @code{AWS} retrieve the
@code{SOAPAction} and the Payload from the @code{SOAP} request. This
is transparent to the user.

@enumerate

@item Using Utils.SOAP_Wrapper
@cindex Utils.SOAP_Wrapper

@noindent
It is possible to dispatch to such callback by using the
@code{SOAP.Utils.SOAP_Wrapper} generic routine.

@AWSEXP {@b{generic}
   @b{with function} SOAP_CB
     (SOAPAction : @b{in} String;
      Payload    : @b{in} Message.Payload.Object;
      Request    : @b{in} AWS.Status.Data)
      @b{return} AWS.Response.Data;
@b{function} SOAP_Wrapper
  (Request : @b{in} AWS.Status.Data)
   @b{return} AWS.Response.Data;
@i{--  From a standard HTTP callback call the SOAP callback passed as generic}
@i{--  formal procedure. Raise Constraint_Error if Request is not a SOAP}
@i{--  request.}}

For example, from the standard HTTP callback @code{CB} we want to call
@code{SOAP_CB} for all @code{SOAP} requests:

@AWSEXP {@b{function} SOAP_CB
  (SOAPAction : @b{in} String;
   Payload    : @b{in} Message.Payload.Object;
   Request    : @b{in} AWS.Status.Data)
   @b{return} AWS.Response.Data
@b{is}
@b{begin}
   @i{--  Code here}
@b{end} SOAP_CB;

@b{procedure} SOAP_Wrapper @b{is new} SOAP.Utils.SOAP_Wrapper (SOAP_CB);

@b{function} CB (Request : @b{in} AWS.Status.Data)
  @b{return} AWS.Response.Data
@b{is}
   SOAPAction : @b{constant} String := Status.SOAPAction (Request);
@b{begin}
   @b{if} SOAPAction /= "" @b{then}
      SOAP_Wrapper (Request);
   @b{else}
      ...}

@item Using a SOAP Dispatcher
@cindex SOAP Dispatcher

@noindent
@code{AWS} provides also a @code{SOAP} specific dispatcher. This
dispatcher will automatically calls a standard @code{HTTP} or
@code{SOAP} callback depending on the request. If @code{SOAPAction} is
specified (i.e. it is a @code{SOAP} request), the dispatcher will call
the @code{SOAP} callback otherwise it will call the standard @code{HTTP}
callback. This is by far the easiest integration procedure. Using
dispatcher the above code will be written:

@AWSEXP {@b{function} SOAP_CB
  (SOAPAction : @b{in} String;
   Payload    : @b{in} Message.Payload.Object;
   Request    : @b{in} AWS.Status.Data)
   @b{return} AWS.Response.Data
@b{is}
@b{begin}
   @i{--  Code here}
@b{end} SOAP_CB;

@b{function} CB (Request : @b{in} AWS.Status.Data)
  @b{return} AWS.Response.Data
@b{is}
   SOAPAction : @b{constant} String := Status.SOAPAction (Request);
@b{begin}
   @i{--  Code here}
@b{end} CB;

@i{--  In the main procedure}

@b{begin}
   AWS.Server.Start
     (WS,
      Dispatcher =>
        SOAP.Dispatchers.Callback.Create (CB'Access, SOAP_CB'Access),
      Config     =>
        AWS.Config.Default_Config);}

@noindent
@cindex SOAP.Dispatchers.Callback
The dispacther is created using @code{SOAP.Dispatchers.Callback.Create}.
This routine takes two parameters, one is the standard HTTP
callback procedure and the other is the @code{SOAP} callback procedure.
@end enumerate

@c ======================================================================

@node Using WSDL
@chapter Using WSDL
@cindex WSDL
@cindex Web Service Definition Language

@menu
* Creating WSDL documents::
* Working with WSDL documents::
* Using ada2wsdl and wsdl2aws together::
@end menu

@noindent
@code{WSDL} (Web Service Definition Language) is an @code{XML} based document
which described a set of Web Services either based on @code{SOAP} or
@code{XML/RPC}.
By using a @code{WSDL} document it is possible to describe, in a formal way,
the interface to any Web Services. The @code{WSDL} document contains the
end-point (URL to the server offering the service), the @code{SOAPAction}
(needed to call the right routine), the procedure names and a
description of the input and output parameters.

@noindent
@code{AWS} provides two tools to work with @code{WSDL} documents:

@table @file
@item ada2wsdl
@cindex ada2wsdl
which creates a @code{WSDL} document from an Ada package spec.

@item wsdl2aws
@cindex wsdl2aws
which create the interfaces
to use a Web Service or to implement Web Services. With this tool the
@code{SOAP} interface is completely abstracted out, users will deal only
with @code{Ada} API. All the @code{SOAP} marshaling will be created
automatically.
@end table

@c ----------------------------------------------------------------------

@node Creating WSDL documents
@section Creating WSDL documents
@cindex ada2wsdl

@menu
* Using ada2wsdl::
* Ada mapping to WSDL::
* ada2wsdl::
* ada2wsdl limitations::
@end menu

@noindent
Note that this tool is based on @code{ASIS}.

@node Using ada2wsdl
@subsection Using ada2wsdl

@noindent
@code{ada2wsdl} can be used on any Ada spec file to generated a
@code{WSDL} document. The Ada spec is parsed using @code{ASIS}.

@noindent
The simplest way to use it is:

@AWSEXP {$ ada2wsdl simple.ads}

@noindent
Given the following Ada spec file:

@AWSEXP {@b{package} Simple @b{is}
   @b{function} Plus (Value : @b{in} Natural) @b{return} Natural;
@b{end} Simple;}

@noindent
It will generate the following @code{WSDL} document:

@AWSEXP {<?xml version="1.0" encoding="UTF-8"?>
<definitions @b{name="Simple"}
   targetNamespace="urn:aws:Simple"
   xmlns:tns="urn:aws:Simple"
   xmlns="http://schemas.xmlsoap.org/wsdl/"
   xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
   xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/"
   xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
   xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema">

   <message name="Plus_Request">
      <part @b{name="Value" type="xsd:int"}/>
   </message>

   <message name="Plus_Response">
      <part @b{name="Result" type="xsd:int"}/>
   </message>

   <portType name="Simple_PortType">
      <operation @b{name="Plus"}>
         <input message="tns:Plus_Request"/>
         <output message="tns:Plus_Response"/>
      </operation>
   </portType>

   <binding name="Simple_Binding" type="tns:Simple_PortType">
      <soap:binding style="rpc"
         transport="http://schemas.xmlsoap.org/soap/http"/>

      <operation name="Plus">
         <soap:operation soapAction="Plus"/>
         <input>
            <soap:body
               encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
               namespace="urn:aws:Simple"
               use="encoded"/>
         </input>
         <output>
            <soap:body
               encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
               namespace="urn:aws:Simple"
               use="encoded"/>
         </output>
      </operation>
   </binding>

   <service name="Simple_Service">
      <port name="Simple_Port" binding="tns:Simple_Binding">
         <soap:address location="http://.../"/>
      </port>
   </service>
</definitions>}

@noindent
In bold are marked the important parts from a spec point of view. The
first item is the name of the @code{WSDL} document (the name of the
Ada spec package). On the @code{portType} section we have the
description of the Ada @b{Plus} function. Something important to note
is that in Ada a function does not have a named return parameter,
@file{ada2wsdl} use @b{Result} for the response. Both the input and
output parameter are mapped to @code{SOAP} @code{xsd:int} type.

@noindent
Note that the @code{SOAP} address generated by default (http://.../)
must be edited manually or specified using @file{ada2wsdl}'s -a
option.

@noindent
This is of course a very simple example. @code{ada2wsdl} does support lot
more complex specs and will map Ada records, arrays, enumerations,
derived types to a corresponding @code{XML} schema definition. See
section below for a description of the mapping.

@node Ada mapping to WSDL
@subsection Ada mapping to WSDL

@code{ada2wsdl} parse Ada records, arrays, derived types, enumerations,
procedures and functions and generate the corresponding @code{WSDL}
document. In this section we describe the mapping between Ada and
@code{WSDL}.

@table @b
@item Integer
Mapped to @b{xsd:int}.

@item Float
Mapped to @b{xsd:float}.

@item Long_Float
Mapped to @b{xsd:double}

@item Long_Long_Float
Mapped to @b{xsd:double}, not supported by SOAP, mapped
for convenience but precision cannot be guaranteed.

@item Boolean
Mapped to @b{xsd:boolean}

@item String
Mapped to @b{xsd:string}

@item Unbounded_String
Mapped to @b{xsd:string}, note that Unbounded_String should be used
only inside a record for full interoperability. This is a current limitation.

@item Character
Mapped to a Character schema definition.

@AWSEXP {<simpleType name="Character">
   <restriction base="xsd:string">
      <length value="1"/>
   </restriction>
</simpleType>}

@item SOAP.Utils.SOAP_Base64
Mapped to @b{xsd:base64Binary}. @code{SOAP.Utils.SOAP_Base64} is a
subtype of string which is is recognized by @code{ada2wsdl} to
generate the proper SOAP type.

@item SOAP.Types.Byte
Mapped to @b{xsd:byte}. @code{SOAP.Types.Byte} is a type which is
recognized by @code{ada2wsdl} to generate the proper SOAP type.

@item SOAP.Types.Short
Mapped to @b{xsd:short}. @code{SOAP.Types.Short} is a type which is
recognized by @code{ada2wsdl} to generate the proper SOAP type.

@item SOAP.Types.Long
Mapped to @b{xsd:long}. @code{SOAP.Types.Long} is a type which is
recognized by @code{ada2wsdl} to generate the proper SOAP type.

@item SOAP.Types.Unsigned_Byte
Mapped to @b{xsd:unsignedByte}. @code{SOAP.Types.Unsigned_Byte} is a
type which is recognized by @code{ada2wsdl} to generate the proper SOAP type.

@item SOAP.Types.Unsigned_Short
Mapped to @b{xsd:unsignedShort}. @code{SOAP.Types.Unsigned_Short} is a
type which is recognized by @code{ada2wsdl} to generate the proper SOAP type.

@item SOAP.Types.Unsigned_Int
Mapped to @b{xsd:unsignedInt}. @code{SOAP.Types.Unsigned_Int} is a
type which is recognized by @code{ada2wsdl} to generate the proper SOAP type.

@item SOAP.Types.Unsigned_Long
Mapped to @b{xsd:unsignedLong}. @code{SOAP.Types.Unsigned_Long} is a
type which is recognized by @code{ada2wsdl} to generate the proper SOAP type.

@item Derived types
Mapped to a type schema definition.

@AWSEXP {@b{type} Number @b{is new} Integer;}

is defined as:

@AWSEXP {<simpleType name="Number"
        targetNamespace="http://soapaws/WSDL_C_pkg/">
   <restriction base="xsd:int"/>
</simpleType>}

@item User's types
Mapped to a type schema definition.

@AWSEXP {@b{type} Small @b{is range} 1 .. 10;}

is defined as:

@AWSEXP {<simpleType name="Small"
        targetNamespace="http://soapaws/WSDL_C_pkg/">
   <restriction base="xsd:byte"/>
</simpleType>}

@item Enumerations
Mapped to an enumeration schema definition. For example:

@AWSEXP {@b{type} Color @b{is} (Red, Green, Blue);}

is defined as:

@AWSEXP {<simpleType name="Color">
   <restriction base="xsd:string">
      <enumeration value="Red"/>
      <enumeration value="Green"/>
      <enumeration value="Blue"/>
   </restriction>
</simpleType>}

@item Records
Mapped to a struct schema definition. For example:

@AWSEXP {@b{type} Rec @b{is record}
   A : Integer;
   B : Float;
   C : Long_Float;
   D : Character;
   E : Unbounded_String;
   F : Boolean;
@b{end record};}

is defined as:

@AWSEXP {<complexType name="Rec">
   <all>
      <element name="A" type="xsd:int"/>
      <element name="B" type="xsd:float"/>
      <element name="C" type="xsd:double"/>
      <element name="D" type="tns:Character"/>
      <element name="E" type="xsd:string"/>
      <element name="F" type="xsd:boolean"/>
   </all>
</complexType>}

@item Arrays
Mapped to an array schema definition. For example:

@AWSEXP {@b{type} Set_Of_Rec @b{is array} (Positive @b{range} <>) @b{of} Rec;}

is defined as:

@AWSEXP {<complexType name="Set_Of_Rec">
   <complexContent>
      <restriction base="soap-enc:Array">
         <attribute ref="soap-enc:arrayType" wsdl:arrayType="tns:Rec[]"/>
      </restriction>
   </complexContent>
</complexType>}

@item Array inside a record
This part is a bit delicate. A record field must be constrained but a
@code{SOAP} arrays is most of the time not constrained at all. To
support this @code{AWS} use a safe access array component. Such a type
is built using a generic runtime support package named
@code{SOAP.Utils.Safe_Pointers}. This package implements a reference
counter for the array access and will release automatically the memory
when no more reference exists for a given object.

For example, let's say that we have an array of integer that we want
to put inside a record:

@AWSEXP {@b{type} Set_Of_Int @b{is array} (Positive @b{range} <>) @b{of} Integer;}

The first step is to create the safe array access support:

@AWSEXP {@b{type} Set_Of_Int_Access @b{is access} Set_Of_Int;

@b{package} Set_Of_Int_Safe_Pointer @b{is}
   @b{new} SOAP.Utils.Safe_Pointers (Set_Of_Int, Set_Of_Int_Access);}

Note that the name @code{Set_Of_Int_Safe_Pointer} (@i{<type>_Safe_Pointer})
is mandatory (and checked by @file{ada2wsdl}) to achieve
interoperability with @file{wsdl2aws}. @pxref{Working with WSDL documents}.

From there the safe array access can be placed into the record:

@AWSEXP {@b{type} Complex_Rec @b{is record}
   SI : Set_Of_Int_Safe_Pointer.Safe_Pointer;
@b{end record};}

To create a Safe_Pointer given a @code{Set_Of_Int} one must use
@code{Set_Of_Int_Safe_Pointer.To_Safe_Pointer} routine. Accessing
individual items is done with @code{SI.Item (K)}.

These Ada definitions are fully recognized by @file{ada2wsdl} and will
generate standard array and record @code{WSDL} definitions as seen above.

@AWSEXP {<complexType name="Set_Of_Int">
   <complexContent>
      <restriction base="soap-enc:Array">
         <attribute ref="soap-enc:arrayType" wsdl:arrayType="xsd:int[]"/>
      </restriction>
   </complexContent>
</complexType>

<complexType name="Complex_Rec">
   <all>
      <element name="SI" type="tns:Set_Of_Int"/>
   </all>
</complexType>}

@end table

@node ada2wsdl
@subsection ada2wsdl

@AWSEXP{Usage: ada2wsdl [options] ada_spec}

@noindent
@code{ada2wsdl} options are:

@table @b
@item -a url
Specify the @code{URL} for the Web Server address. Web Services will be
available at this address. A port can be specified on the @code{URL},
@code{http://server[:port]}. The default value is @code{http://.../}.

@item -f
Force creation of the @code{WSDL} file. Overwrite exiting file
with the same name.

@item -I path
Add path option for the @code{ASIS} compilation step. This option can
appear any number of time on the command line.

@item -noenum
Do not generate @code{WSDL} representation for Ada enumerations, map
them to standard string. @pxref{Ada mapping to WSDL}.

@item -o file
Generate the @code{WSDL} document into file.

@item -q
Quiet mode (no output)

@item -s name
Specify the Web Service name for the @code{WSDL} document, by default
the spec package's name is used.

@item -v
Verbose mode, display the parsed spec.

@end table

@node ada2wsdl limitations
@subsection @file{ada2wsdl} limitations
@cindex ada2wsdl limitations

@itemize @bullet

@item Do not handle constraint arrays into a records.

@item Unbounded_String are supported with full interoperability only inside a record.

@item Only unconstraint arrays are supported

@item Arrays with multiple dimentions not supported
@end itemize

@c ----------------------------------------------------------------------

@node Working with WSDL documents
@section Working with WSDL documents

@menu
* Client side (stub)::
* Server side (skeleton)::
* wsdl2aws::
* wsdl2aws behind the scene::
* wsdl2aws limitations::
@end menu

@node Client side (stub)
@subsection Client side (stub)
@cindex WSDL, Client

@noindent
This section describe how to use a Web Service. Let's say that we want
to use the Barnes & Noble Price Quote service. The WSDL document for
this service can be found at
@url{http://www.xmethods.net/sd/2001/BNQuoteService.wsdl}. In summary
this document says that there is a service named @code{getPrice}
taking as input a string representing the ISBN number and returning
the price as floating point.

The first step is to generate the client interface (stub):

@AWSEXP {$ wsdl2aws -noskel http://www.xmethods.net/sd/2001/BNQuoteService.wsdl}

@noindent
This will create many files, the interesting one at this point is
@file{bnquoteservice-client.ads}, inside we have:

@AWSEXP {@b{function} getPrice
  (isbn : @b{in} String)
   @b{return} Float;
--  @i{Raises SOAP.SOAP_Error if the procedure fails}}

@noindent
Let's call this service to find out the price for
@i{The Sword of Shannara Trilogy} book.

@AWSEXP {@b{with} Ada.Text_IO;
@b{with} BNQuoteService.Client;

@b{procedure} Price @b{is}
   @b{use} Ada;

   ISBN : @b{constant} String := "0345453751";
   --  @i{The Sword of Shannara Trilogy ISBN}

   @b{package} LFIO @b{is new} Text_IO.Float_IO (Float);

@b{begin}
   Text_IO.Put_Line ("B&N Price for The Sword of Shannara Trilogy");
   LFIO.Put (BNQuoteService.Client.getPrice (ISBN), Aft => 2, Exp => 0);
@b{end} Price;}

@noindent
That's all is needed to use this Web Service. This program is fully
functional, It is possible to build it and to run it to get the answer.

@node Server side (skeleton)
@subsection Server side (skeleton)
@cindex WSDL, Server

@noindent
Building a Web Service can also be done from a @code{WSDL} document. Let's
say that you are Barnes & Noble and that you want to build Web Service
@code{getPrice} as described in the previous section.

@noindent
You have created the @code{WSDL} document to specify the service spec.
From there you can create the skeleton:

@AWSEXP {$ wsdl2aws -nostub http://www.xmethods.net/sd/2001/BNQuoteService.wsdl}

@noindent
This will create many files, the interesting one here is
@file{bnquoteservice-server.ads}, inside we have:

@AWSEXP {Port : @b{constant} := 80;

@b{generic}
  @b{with function} getPrice
  (isbn : @b{in} String)
   @b{return} Float;
@b{function} getPrice_CB
  (SOAPAction : @b{in} String;
   Payload    : @b{in} SOAP.Message.Payload.Object;
   Request    : @b{in} AWS.Status.Data)
   @b{return} AWS.Response.Data;}

@noindent
This is a @code{SOAP AWS}'s callback routine that can be instantiated
with the right routine to retrieve the price of a book given its ISBN
number. A possible implementation of such routine could be:

@AWSEXP {@b{function} getPrice
  (isbn : @b{in} String)
   @b{return} Float @b{is}
@b{begin}
   @b{if} isbn = "0987654321" @b{then}
      return 45.0;
   @b{elsif} ...
@b{end} getPrice;

@b{function} SOAP_getPrice @b{is new} BNQuoteService.Server.getPrice_CB (getPrice);}

@noindent
@code{SOAP_getPrice} is a @code{SOAP AWS}'s callback routine (i.e. it is not
a standard callback). To use it there is different solutions:

@table @b

@item Using SOAP.Utils.SOAP_Wrapper
This generic function can be used to translate a standard callback
based on @code{AWS.Status.Data} into a @code{SOAP} callback routine.

@AWSEXP {@b{function} getPrice_Wrapper @b{is new} SOAP.Utils.SOAP_Wrapper (SOAP_getPrice);}

@noindent
The routine @code{getPrice_Wrapper} can be used as any other AWS's
callback routines. Note that inside this wrapper the @code{XML} payload is
parsed to check the routine name and to retrieve the @code{SOAP}
parameters. To call this routine the payload needs to be parsed (we
need to know which routine has be invoked). In this case we have
parsed the @code{XML} payload twice, this is not efficient.

@item Building the wrapper yourself

@noindent
This solution is more efficient if there is many @code{SOAP}
procedures as the payload is parsed only once.

@AWSEXP {@b{function} CB (Request : @b{in} Status.Data) @b{return} Response.Data @b{is}
   SOAPAction : @b{constant} String := Status.SOAPAction (Request);
   Payload    : @b{constant} SOAP.Message.Payload.Object
     := SOAP.Message.XML.Load_Payload (AWS.Status.Payload (Request));
   Proc       : @b{constant} String
     := SOAP.Message.Payload.Procedure_Name (Payload);
@b{begin}
   @b{if} SOAPAction = "..." @b{then}

      @b{if} Proc = "getPrice" @b{then}
         @b{return} SOAP_getPrice (SOAPAction, Payload, Request);
      @b{elsif} ...
         ...
      @b{end if};

   @b{else}
      ...
   @b{end if};}

@end table

@noindent
Note that the port to be used by the AWS server is described into the
server spec.

@node wsdl2aws
@subsection wsdl2aws
@cindex wsdl2aws

@smallexample
Usage: wsdl2aws [options] <file|URL>
@end smallexample

It is possible to pass a @code{WSDL} file or direct @file{wsdl2aws} to
a @code{WSDL} document on the Web by passing it's @code{URL}.

@noindent
@code{wsdl2aws} options are:

@table @b
@item -q
Quiet mode (no output)

@item -d
Generate debug code. Will output some information about the payload to
help debug a Web Service.

@item -a
Generate using Ada style names. For example @code{getPrice} will be converted
to @code{Get_Price}. This formatting is done for packages, routines and formal
parameters.

@item -f
Force creation of the file. Overwrite any exiting files with the same
name.

@item -e
Specify the default endpoint to use instead of the one found in the
WSDL document.

@item -s
Skip non supported @code{SOAP} routines. If @code{-s} is not used,
@code{wsdl2aws} will exit with an error when a problem is found while
parsing the @code{WSDL} document. This option is useful to skip
routines using non supported types and still be able to compile the
generated files.

@item -o name
Specify the name of the local @code{WSDL} document. This option can be used
only when using a Web @code{WSDL} document (i.e. passing an URL to
@code{wsdl2aws}).

@item -doc
Handle document style binding as RPC ones. This is sometimes needed
because some @code{WSDL} document specify a document style binding even
though it is really an RPC one.

@item -v
Verbose mode, display the parsed spec.

@item -v -v
Verbose mode, display the parsed spec and lot of information while
parsing the @code{WSDL} document tree.

@item -wsdl
Add @code{WSDL} document as comment into the generated root unit.

@item -cvs
Add CVS Îd tag in every generated file.

@item -nostub
Do not generated stubs, only skeletons are generated.

@item -noskel
Do not generated skeletons, only stubs are generated.

@item -cb
Generate a @code{SOAP} dispatcher callback routine for the
server. This dispatcher routine contains the code to handle all the
operations as described in the @code{WSDL} document. You need also to
specify the @code{-spec} and/or @code{-types} options, see below.

@item -x operation
Add @code{operation} to the list of @code{SOAP} operations to skip during the
code generation. It is possible to specify multiple @code{-x} options on the
command line.

@item -spec spec
Specify the name of the spec containing the Ada implementation of the
@code{SOAP} routines. This is used for example by the @code{-cb} option above
to instantiate all the server side @code{SOAP} callbacks used by the main
@code{SOAP} dispatcher routine. If @code{-types} is not specified, the
type definitions are also used from this spec.

@item -types spec
Specify the name of the spec containing the Ada types (record, array) used by
@code{SOAP} routines specified with option @code{-spec}. If @code{-spec} is
not specified, the spec definitions are also used from this spec.

@item -main filename
Specify the name of the server's procedure main to generate. If
file @file{<filename>.amt} (Ada Main Template) is present, it uses this
template file to generate the main procedure. The template can
reference the following variable tags:

@table @b
@item SOAP_SERVICE
The name of the service as described into the @code{WSDL}
document. This tag can be used to include the right units

@AWSEXP {@b{with} @@_SOAP_SERVICE_@@.Client;
@b{with} @@_SOAP_SERVICE_@@.CB;}

@item SOAP_VERSION
The AWS's SOAP version.

@item AWS_VERSION
The AWS's version.

@item UNIT_NAME
The name of the generated unit. This is the name of the procedure that
will be created.

@AWSEXP {@b{procedure} @@_UNIT_NAME_@@ @b{is}
@b{begin}
   ...}

@end table

@item -proxy name|IP
Use this proxy to access the @code{WSDL} document and generate code to access
to these Web Services via this proxy. The proxy can be specified by
its DNS name or IP address.

@item -pu name
User name for the proxy if proxy authentication required.

@item -pp password
User password for the proxy if proxy authentication required.

@item -timeouts [timeouts | connect_timeout,send_timeout,receive_timeout ]
Set the timeouts for the SOAP connection. The timeouts is either a
single value used for the connect, send and receive timeouts or three
values separated by a colon to set each timeout independently.
@end table

@node wsdl2aws behind the scene
@subsection wsdl2aws behind the scene

@noindent
The @code{wsdl2aws} tool read a @code{WSDL} document and creates a root
package and a set of child packages as described below:

@table @b
@item <root>
This is the main package, it contains eventually the full @code{WSDL} in
comment and the description of the services as read from the @code{WSDL}
document.

@item <root>.Types
This package contains the definitions of the types which are not @code{SOAP}
base types. We find here the definitions of the @code{SOAP} structs
and arrays with routines to convert them between the Ada and @code{SOAP} type
model. A subtype definition is also created for every routine's returned type.
In fact, all definitions here are only alias or renaming of types
and/or routines generated in other packages. The real definitions for
structs, arrays, enumerations and derived types are generated into a
package whose name depends on the name space used for these
entities. This package act as a container for all definitions and it
is the only one used in the other generated packages.

@item <root>.Client
All spec to call Web Services.

@item <root>.Server
All spec to build Web Services. These specs are all generic and must
be instantiated with the right routine to create the web services.

@item <root>.CB
The @code{SOAP} dispatcher callback routine.
@end table

@node wsdl2aws limitations
@subsection wsdl2aws limitations
@cindex wsdl2aws limitations

@noindent
It is hard to know all current limitations as the @code{WSDL} and
@code{SOAP} world is quite complex. We list there all known limitations:

@itemize @bullet

@item Some @code{SOAP} base types are not supported : @i{date, time, xsd:hexBinary, decimal}. All these are easy to add (except decimal), it is just not
supported with the current version.

@item Multi-dimension arrays are not supported.

@item abstract types are not supported.

@item SOAP MIME attachments are not supported.

@item WSDL type inheritance not supported.

@item Only the RPC/Encoded SOAP messages' style is supported (the
Document/Literal is not)

@end itemize

@c ----------------------------------------------------------------------

@node Using ada2wsdl and wsdl2aws together
@section Using ada2wsdl and wsdl2aws together

@noindent
Using both tools together is an effective way to build rapidely a @code{SOAP}
server. It can be said that doing so is quite trivial in fact. Let's
take the following spec:

@AWSEXP {@b{package} Graphics @b{is}

   @b{type} Point @b{is} record
      X, Y : Float;
   @b{end} record;

   @b{function} Distance (P1, P2 : @b{in} Point) @b{return} Float;
   --  @i{Returns the distance between points P1 and P2}

@b{end} Graphics;}

@noindent
We do not show the body here but we suppose it is implemented. To
build a server for this service it is as easy as:

@AWSEXP {$ ada2wsdl -a http://localhost:8787 -o graphics.wsdl graphics.ads}

@noindent
The server will be available on localhost at port 8787.

@AWSEXP {$ wsdl2aws -cb -main server -types graphics graphics.wsdl
$ gnatmake server -largs ...}

@noindent
Options

@table @code
@item -cb
is to create the @code{SOAP} dispatcher callback routine,

@item -main server
to generate the main server procedure in @file{server.adb},

@item -types graphics
to use @file{graphics.ads} to get references from user's spec (reference to
@code{Graphics.Point} for example).
@end table

@c ======================================================================

@node Working with mails
@chapter Working with mails

@menu
* Sending e-mail::
* Retrieving e-mail::
@end menu

@c ----------------------------------------------------------------------

@node Sending e-mail
@section Sending e-mail
@cindex Sending e-mail
@cindex SMTP
@cindex Simple Mail Transfer Protocol

@noindent
@code{AWS} provides a complete API to send e-mail using @code{SMTP}
protocol. You need to have access to an SMTP server to use this
feature. The API covers sending simple mail with text message and/or
with @code{MIME} attachments (base64 encoded). Here are the steps to
send a simple e-mail:

@itemize @bullet

@item Initialize the SMTP server

@AWSEXP {SMTP_Server : SMTP.Receiver
   := SMTP.Client.Initialize ("smtp.hostname");}

Here @code{AWS} uses the default SMTP port to create an SMTP mail server but
it is possible to specify a different one. The hostname specified
must be a valid SMTP server.

@item Send the e-mail

To send an e-mail there is many different API. Let's send a simple text mail.

@AWSEXP {Status : SMTP.Status;

SMTP.Client.Send
  (SMTP_Server,
   From    => SMTP.E_Mail ("Pascal Obry", "p.obry@@wanadoo.fr"),
   To      => SMTP.E_Mail ("John Doe", "john.doe@@here.com"),
   Subject => "About AWS SMTP protocol",
   Message => "AWS can now send mails",
   Status  => Status);}

@noindent
Here Status will contain the SMTP returned status.

@item Check that everything is ok

@noindent
Using above status data it is possible to check that the message was
sent or not by the server. The status contain a code and an error
message, both of them can be retrieved using specific routines,
@xref{AWS.SMTP}. It is also possible to check that the call was
successful with @code{SMTP.Is_Ok} routine.

@AWSEXP {@b{if not} SMTP.Is_Ok (Status) @b{then}
   Put_Line ("Can't send message: " & SMTP.Status_Message (Status));
@b{end if};}

@end itemize

@noindent
In the above example, the message content was given as a string but it
is possible to specify a disk file. @code{AWS} can also send MIME messages
either from disk files or with in memory base64 encoded binary
data. The API provides also a way to send messages to multiple
recipients at the same time and to send messages with alternative
contents (text and HTML for example). These features are not described here,
complete documentation can be found on the spec @pxref{AWS.SMTP} and
@pxref{AWS.SMTP.Client}.

@c ----------------------------------------------------------------------

@node Retrieving e-mail
@section Retrieving e-mail
@cindex Retrieving e-mail
@cindex POP
@cindex Post Office Protocol

@noindent
@code{AWS} provides an API to retrieve e-mails from a @code{POP}
mailbox. @code{POP} stands for @i{Post Office Protocol} and is the main
protocol used by Internet Service Providers around the
world. @code{IMAP} is another well known protocol in this area but it
is not supported by @code{AWS}.

@noindent
We describes here the @code{POP} API. For a complete description see
@pxref{AWS.POP}.

@itemize @bullet

@item Opening the mailbox

@noindent
The first step is to authenticate using a user name and
password. @code{AWS} supports two methods one called @code{Clear_Text}
which is the most used and another one @code{APOP} which is more secure but
almost not supported by @code{ISP} for the moment (and will probably
never be supported as a more secure protocol named @code{SPA} -Secure
Password Authentication- could be used instead).

@AWSEXP {Mailbox : POP.Mailbox
   := POP.Initialize ("pop.hostname", "john.does", "mysuperpwd");}

@noindent
The default Authentication method is @code{Clear_Text}.

@item Getting mailbox information

@noindent
When the connection is opened it is possible to get information about
the mailbox like the number of messages or the total number of bytes
in the mailbox.

@AWSEXP {N     : @b{constant} Natural := POP.Message_Count (Mailbox);

Bytes : @b{constant} Natural := POP.Size (Mailbox);}

@item Retreiving individual e-mail

@noindent
Each message is numbered starting from 1. A function named @code{Get}
will return a message given its mailbox's number.

@AWSEXP {Message : @b{constant} POP.Message := POP.Get (Mailbox, 2, Remove => True);}

@noindent
Remove can be set to @code{False} for the message to stay on the
mailbox. The default value is @code{False}.

@item Iterating through the mailbox content

@noindent
Another way to retreive message is by using an iterator.

@AWSEXP {@b{procedure} Print_Subject
  (Message : @b{in}     POP.Message
   Index   : @b{in}     Positive;
   Quit    : @b{in out} Boolean) @b{is}
@b{begin}
   Text_IO.Put_Line (POP.Subject (Message));
@b{end} Print_Message;

@b{procedure} Print_All_Subjects @b{is new} POP.For_Every_Message (Print_Subject);

...

Print_All_Subjects (Mailbox, Remove => True);}

@noindent
It exists a set of routines on a @code{POP.Message} object to get the subject
the content, the date or any headers. It is also possible to work with
attachments. See point below.

@item Working with attachments

@noindent
A message can have a set of @code{MIME} attachments. The number of
attachments can be retrieved using @code{Attachment_Count}.

@AWSEXP {Message : @b{constant} POP.Message := ...;

A_Count : @b{constant} Natural := POP.Attachment_Count (Message);}

@noindent
As for messages it is possible to get a single attachment using its
index in the message or by using an iterator.

@AWSEXP {First_Attachment : @b{constant} POP.Attachment := POP.Get (Message, 1);

@b{procedure} Write_Attachment
  (Attachment : @b{in}     POP.Attachment
   Index      : @b{in}     Positive;
   Quit       : @b{in out} Boolean) @b{is}
@b{begin}
   POP.Write (Attachment, Directory => ".");
@b{end} Print_Message;

@b{procedure} Write_All_Attachments @b{is new} POP.For_Every_Attachment (Write_Attachment);

...

Write_All_Attachments (Message);}

@noindent
It is also possible to retrieve the attachment's filename, the content
as a memory stream. @pxref{AWS.POP}.

@item Closing the connection

@AWSEXP {POP.Close (POP_Server);}

@end itemize

@c ======================================================================

@node LDAP
@chapter LDAP
@cindex LDAP
@cindex LDAP Directory
@cindex Lightweight Directory Access Protocol

@noindent
@code{AWS} provides a complete API to retrieve information from LDAP servers.
Note that there is no support for updating, modifying or deleting
information only to read information from the server.

@noindent
The @code{AWS/LDAP} implementation is based on @code{OpenLDAP}. To
build an LDAP application you need to link with the @file{libldap.a}
library. This library is built by @code{AWS} on Windows based system
and will use the @file{wldap32.dll} as provided with Windows
NT/2000/XP. On UNIX based systems, you must install properly the
@code{OpenLDAP} package.

@noindent
The steps required to read information from an LDAP server are:

@table @b

@item Initialize the LDAP directory

@AWSEXP {@b{declare}
   Directory : LDAP.Client.Directory;
@b{begin}
   Directory := LDAP.Client.Init (Host);}

Host is the hostname where the LDAP directory is running. It is
possible to specify the port if the LDAP server does not use the
default one.

@item Bind to the LDAP server

This step is the way to pass a login/password if the LDAP server
required an authentication. If not, the login/password must be empty strings.

@AWSEXP {LDAP.Client.Bind (Directory, "", "");}

@item Do the search

@noindent
For the search you must specify the base name, a filter, the scope and
a set of attributes to retrieve.

@AWSEXP {Response_Set := LDAP.Client.Search
  (Directory, Base_DN, Filter, LDAP.Client.LDAP_Scope_Subtree,
   LDAP.Client.Attributes
     ("cn", "sn", "telephonenumber"));}

@table @b
@item Attributes
The set of attributes to retrieve from the directory.
@item Filter
A set of values for some attributes. A filter is <attribute_name>=<value>
where value can contain '*' at the end. For example "(cn=DUPON*)" will
look for all entries where the common name is starting by the string "DUPON".
@item Scope
Define how far in the hierarchical directory the search will
operate. It is either one level, all subtrees or on the base of the tree.
@end table

@noindent
For more information @pxref{AWS.LDAP.Client}.

@item Iterate through the response set

@noindent
For this there is two iterators. @code{First_Entry}/@code{Next_Entry} or the
generic high level iterator @code{For_Every_Entry}.

@AWSEXP {@b{declare}
   Message : LDAP.Client.LDAP_Message;
@b{begin}
   Message := LDAP.Client.First_Entry (Directory, Response_Set);

   @b{while} Message /= LDAP.Client.Null_LDAP_Message @b{loop}

      Do_Job (Message);

      Message := LDAP.Client.Next_Entry (Directory, Message);
   @b{end loop};
@b{end};}

@item Read attributes for each entry

@noindent
Each entry has an associated set of attributes. To retrieve attributes
values there is two iterators. @code{First_Attribute} / @code{Next_Attribute}
or the generic high level iterator @code{For_Every_Attribute}.

@AWSEXP {@b{declare}
   BER : @b{aliased} LDAP.Client.BER_Element;

   Attr : @b{constant} String := LDAP.Client.First_Attribute
     (Directory, Message, BER'Unchecked_Access);
@b{begin}
   Do_Job (Attr);

   @b{loop}
      @b{declare}
         Attr : @b{constant} String := LDAP.Client.Next_Attribute
          (Directory, Message, BER);
      @b{begin}
         @b{exit when} Attr = "";
         Do_Job (Attr);
      @b{end};
  @b{end loop};
@b{end};}

@item Cleanup

@noindent
At the end of the processing it is important to release memory
associated with LDAP objects.

@AWSEXP {LDAP.Client.Free (Message);
LDAP.Client.Unbind (Directory);}

@end table

@noindent
@pxref{AWS.LDAP.Client} for all high level supported API and documentation.

@noindent
Note that for complete information about @code{AWS/LDAP} you you should read
an LDAP API description. @code{AWS/LDAP} is only a binding and follow the
LDAP API closely.

@c ======================================================================

@node Jabber
@chapter Jabber
@cindex Jabber

@noindent
@code{AWS} support part of the Jabber protocol. At this stage only two kind
of messages are supported:

@enumerate

@item Presence

To check the presence status of a specific JID (Jabber ID)

@item Message

To send messages to a specific JID (Jabber ID)

@end enumerate

@noindent
Note that if you want an application to check the presence or send
message to users it is recommended to create a specific Jabber ID on the
server for this application and ask users to accept this specific user
to check their presence status.

@menu
* Jabber presence::
* Jabber message::
@end menu

@c ----------------------------------------------------------------------

@node Jabber presence
@section Jabber presence
@cindex Jabber presence

@noindent
To check for the presence of another JID you must first have the right
to do so. The jabber server won't let you see presence of another JID
unless the JID have permitted you to see its presence.

@itemize @bullet

@item First declare the server and status objects

@AWSEXP {Server : AWS.Jabber.Server;
Status : AWS.Jabber.Presence_Status;}

@item Connect to the server, you must have an account created and must
know the login and password

@AWSEXP {AWS.Jabber.Connect
  (Server, "jabber.domain.org", "joe", "mysuperpwd");}

@item Then, to check the presence of user "john"

@AWSEXP {AWS.Jabber.Check_Presence
  (Server, "john@@jabber.domain.org", Status);}

@item Then, you just have to close the server

@AWSEXP {AWS.Jabber.Close (Server);}

@end itemize

@c ----------------------------------------------------------------------

@node Jabber message
@section Jabber message
@cindex Jabber message

@noindent
To send a message to a specific JID, you must connect to
the server as above and close the server when you don't need to
communicate with it anymore. The only different part is to send the
message, here is an example:

@AWSEXP {Send_Message
   (Server,
    JID     => "john@@jabber.domain.org",
    Subject => "Hello there!",
    Content => "Are you using AWS ?");}

@noindent
It is as simple as that !

@c ======================================================================

@node Resources
@chapter Resources
@cindex Resources
@cindex Self dependant

@noindent
@code{AWS} support embedded resources. It means that it is possible to build
a fully self dependent executable. This is useful when distributing a
server. The server program contains the code but also the images (@code{PNG},
@code{JPEG}, @code{GIF}), the templates, the @code{HTML} pages... more
generally any file the Web Server must serve to clients.

@menu
* Building resources::
* Using resources::
* Stream resources::
* awsres tool::
@end menu

@c ----------------------------------------------------------------------

@node Building resources
@section Building resources
@cindex Building resources

@noindent
To embbed the files into the executable you must build a resource
tree. This task is greatly simplified using @file{AWSRes} tool. For
example let's say that you want to build a simple server with a single
page containing some text and one PNG image. The text is handled
directly in the callback procedure and contain a reference to the
image @file{logo.png}. To build the resource tree:

@AWSEXP {$ awsres logo.png}

@noindent
This will create a set of packages whose root is the unit @code{res} by
default. The resource tree is created. @pxref{awsres tool} for the complete
AWS's usage description.

@noindent
@code{awsres} can also compress the resource files. This can be done
by using @code{awsres}'s @code{-z} option. Compressed resources are
handled transparently. If the Web client supports compression the
resource is sent as-is otherwise a decompression stream will be
created for the resource to be decompressed on-the-fly while sending it.

@c ----------------------------------------------------------------------

@node Using resources
@section Using resources
@cindex Using resources

@noindent
This is really the simplest step. The resource tree must be linked
with your executable, to do so you just have to ``with'' the
resource tree root into one of your program unit. This will ensure
that the resource tree will be compiled and linked into the
executable. @code{AWS} and @code{Templates_Parser know} about resource
files and will pick them up if available.

@noindent
Note that this is transparent to users. It is possible to build the
very same server based on standard files or resources files. The only
change in the code is to ``with'' or not the resource tree.

@noindent
Note that @code{AWS} supports only a single resource tree. If more
than one resource tree is included into a program only one will be
seen.

@c ----------------------------------------------------------------------

@node Stream resources
@section Stream resources
@cindex Stream resources

@noindent
Users can build a response directly from a stream. In this case the
callback answer is built using @code{AWS.Response.Stream}. It creates a
resource object whose operations have been inherited from
@code{AWS.Resource.Stream.Stream_Type} and redefined by the user. So
the @code{Read} operation can dynamically create the result stream
data, the @code{End_Of_File} operation must returns @code{True} when the
stream data is out and so on. This feature is useful to let users completely
create and control dynamically @code{AWS}'s response content.

@pxref{AWS.Resources.Streams}.

@c ----------------------------------------------------------------------

@node awsres tool
@section awsres tool
@cindex awsres

@noindent
@code{AWSRes} is a tool to build resource files. It creates a root package
named @file{res} by default and a child package for each resource
file.

@noindent
Usage: awsres [-hrquz] file1 [-uz] [file2...]

@table @code

@item -h
Display help message.

@item -q
Quiet mode.

@item -r name
Set the root unit name. Default is @code{res}.

@item -u
Add following files as uncompressed resources.

@item -z
Add following files as compressed resources.

@end table

@c ======================================================================

@node Status page
@chapter Status page
@cindex Status

@noindent
The status page gives information about the @code{AWS} internal status. For
example it returns the server socket ID, the number of simultaneous
connection, the number of time a connection has been used...

@noindent
To display the information @code{AWS} use a template file. The
template file (default is @file{@_STATUS_PAGE_@}) is an @code{HTML} file with
some specific tags recognized by the parser. For more information
about how the template parser works, please look for the template
parser documentation distributed with @code{AWS}.

@noindent
Here are the tag variables recognized by @code{AWS} status page:

@table @b

@item ABORTABLE_V (vector tag)
@cindex ABORTABLE_V

A list of boolean. One for each connection. True means that this
connection can be aborted if none is available. This is to be inserted
in a template table.

@item ACCEPT_QUEUE_SIZE
@cindex ACCEPT_QUEUE_SIZE

@pxref{Configuration options}.

@item ACCEPTOR_LENGTH
@cindex ACCEPTOR_LENGTH

Number of sockets in the internal socket set.

@item ACTIVITY_COUNTER_V (vector tag)
@cindex ACTIVITY_COUNTER_V

A list of natural. One for each connection. This is the number of
request the connection has answered. This counter is reset each time the
connection is closed. In other word this is the number of request a
keep-alive connection has processed.

@item ACTIVITY_TIME_STAMP_V (vector tag)
@cindex ACTIVITY_TIME_STAMP_V

A list of date. One for each connection. This is the time of the latest
request answered.

@item ADMIN
@cindex ADMIN

URI to the administrative page.

@item CASE_SENSITIVE_PARAMETERS
@cindex CASE_SENSITIVE_PARAMETERS

@pxref{Configuration options}.

@item CHECK_URL_VALIDITY
@cindex CHECK_URL_VALIDITY

@pxref{Configuration options}.

@item CLEANER_CLIENT_DATA_TIMEOUT
@cindex CLEANER_CLIENT_DATA_TIMEOUT

@pxref{Configuration options}.

@item CLEANER_CLIENT_HEADER_TIMEOUT
@cindex CLEANER_CLIENT_HEADER_TIMEOUT

@pxref{Configuration options}.

@item CLEANER_SERVER_RESPONSE_TIMEOUT
@cindex CLEANER_SERVER_RESPONSE_TIMEOUT

@pxref{Configuration options}.

@item CLEANER_WAIT_FOR_CLIENT_TIMEOUT
@cindex CLEANER_WAIT_FOR_CLIENT_TIMEOUT

@pxref{Configuration options}.

@item CURRENT_CONNECTIONS
@cindex CURRENT_CONNECTIONS

Number of current connections to the server.

@item ERROR_LOG (boolean tag)
@cindex ERROR_LOG

This is set to true if error logging is active.

@item ERROR_LOG_FILE
@cindex ERROR_LOG_FILE

The error log file full pathname.

@item ERROR_LOG_FILENAME_PREFIX
@cindex ERROR_LOG_FILENAME_PREFIX

@pxref{Configuration options}.

@item ERROR_LOG_SPLIT_MODE
@cindex ERROR_LOG_SPLIT_MODE

@pxref{Configuration options}.

@item FORCE_CLIENT_DATA_TIMEOUT
@cindex FORCE_CLIENT_DATA_TIMEOUT

@pxref{Configuration options}.

@item FORCE_CLIENT_HEADER_TIMEOUT
@cindex FORCE_CLIENT_HEADER_TIMEOUT

@pxref{Configuration options}.

@item FORCE_SERVER_RESPONSE_TIMEOUT
@cindex FORCE_SERVER_RESPONSE_TIMEOUT

@pxref{Configuration options}.

@item FORCE_WAIT_FOR_CLIENT_TIMEOUT
@cindex FORCE_WAIT_FOR_CLIENT_TIMEOUT

@pxref{Configuration options}.

@item FREE_SLOTS_KEEP_ALIVE_LIMIT
@cindex FREE_SLOTS_KEEP_ALIVE_LIMIT

@pxref{Configuration options}.

@item LINE_STACK_SIZE
@cindex LINE_STACK_SIZE

@pxref{Configuration options}.

@item KEYS_M (matrix tag)
@cindex KEYS_M

A list of set of keys (for each key correspond a value in the tag
VALUES_L, see below). Each key in the vector tag start with an @code{HTML}
"<td>" tag. This is to be able to display the key/value in column.

@item LOG (boolean tag)
@cindex LOG

This is set to true if logging is active.

@item LOG_FILE
@cindex LOG_FILE

The log file full pathname.

@item LOG_FILENAME_PREFIX
@cindex LOG_FILENAME_PREFIX

@pxref{Configuration options}.

@item LOG_FILE_DIRECTORY
@cindex LOG_FILE_DIRECTORY

@pxref{Configuration options}.

@item LOG_MODE
@cindex LOG_MODE

The rotating log mode, this is either @code{NONE}, @code{DAILY},
@code{MONTHLY} or @code{EACH_RUN}.

@item LOGO
@cindex LOGO

A string to be placed in an img @code{HTML} tag. This is the name of
the @code{AWS} logo image.

@item MAX_CONCURRENT_DOWNLOAD
@cindex MAX_CONCURRENT_DOWNLOAD

@pxref{Configuration options}.

@item MAX_CONNECTION
@cindex MAX_CONNECTION

@pxref{Configuration options}.

@item PEER_NAME_V (vector tag)
@cindex PEER_NAME_V

A list of peer name. One for each connection. This is the name of the last
peer connected to the slot.

@item PHASE_V (vector tag)
@cindex PHASE_V

What is the slot currently doing, for example Server_Processing or Closed.

@item RECEIVE_TIMEOUT
@cindex RECEIVE_TIMEOUT

@pxref{Configuration options}.

@item REUSE_ADDRESS
@cindex REUSE_ADDRESS

@pxref{Configuration options}.

@item SECURITY
@cindex SECURITY

A boolean set to True if this is a secure socket (HTTPS/SSL).

@item SECURITY_MODE
@cindex SECURITY_MODE

@pxref{Configuration options}.

@item SEND_TIMEOUT
@cindex SEND_TIMEOUT

@pxref{Configuration options}.

@item SERVER_HOST
@cindex SERVER_HOST

@pxref{Configuration options}.

@item SERVER_NAME
@cindex SERVER_NAME

@pxref{Configuration options}.

@item SERVER_PORT
@cindex SERVER_PORT

@pxref{Configuration options}.

@item SERVER_SOCK
@cindex SERVER_SOCK

Server socket ID.

@item SESSION
@cindex SESSION

@pxref{Configuration options}.

@item SESSION_CLEANUP_INTERVAL
@cindex SESSION_CLEANUP_INTERVAL

Number of seconds between each run of the session cleanup task. This
task will remove all session data that have been obsoleted.

@item SESSION_LIFETIME
@cindex SESSION_LIFETIME

Number of seconds to keep session information. After this period a
session is obsoleted and will be removed at next cleanup.

@item SESSION_NAME
@cindex SESSION_NAME

@pxref{Configuration options}.

@item SESSIONS_TERMINATE_V (vector tag)
@cindex SESSIONS_TERMINATE_V

A list of time. Each item correspond to the time when the session will
be obsoleted.

@item SESSIONS_TS_V (vector tag)
@cindex SESSIONS_TS_V

A list of time stamp. Each item correspond to a session last access time.

@item SESSIONS_V (vector tag)
@cindex SESSIONS_V

A list of session ID.

@item SLOT_ACTIVITY_COUNTER_V (vector tag)
@cindex SLOT_ACTIVITY_COUNTER_V

A list of natural. One for each connection. This is the total number of
requests the slot has answered. This counter is never reseted.

@item SOCK_V (vector tag)
@cindex SOCK_V

A list of sockets ID. One for each connection.

@item STATUS_PAGE
@cindex STATUS_PAGE

@pxref{Configuration options}.

@item START_TIME
@cindex START_TIME

A timestamp in YYYY-MM-DD HH:MM:SS format. When the server was started.

@item TRANSIENT_CLEANUP_INTERVAL
@cindex TRANSIENT_CLEANUP_INTERVAL

@pxref{Configuration options}.

@item TRANSIENT_LIFETIME
@cindex TRANSIENT_LIFETIME

@pxref{Configuration options}.

@item UPLOAD_DIRECTORY
@cindex UPLOAD_DIRECTORY

@pxref{Configuration options}.

@item UPLOAD_SIZE_LIMIT
@cindex UPLOAD_SIZE_LIMIT

@pxref{Configuration options}.

@item VALUES_M (matrix tag)
@cindex VALUES_M

A list of set of values (for each value correspond a key in the vector tag
KEYS_L, see above). Each key in the vector tag start with an @code{HTML}
"<td>" tag. This is to be able to display the key/value in column.

@item VERSION
@cindex VERSION

@code{AWS} version string.

@item WWW_ROOT
@cindex WWW_ROOT

@pxref{Configuration options}.

@end table

@noindent
There is also all @code{Templates_Parser} specific tags. This is not listed
here please have a look at the @code{Templates_Parser} documentation
distributed with @code{AWS}.

@c ======================================================================

@node References
@appendix References
@cindex References

@noindent
Here is a list of documents used to implement @code{AWS}, the
@code{SOAP} support and associated services:

@table @b

@item RFC 0821
@cindex RFC 0821
@cindex SMTP

@smallexample
                     SIMPLE MAIL TRANSFER PROTOCOL

                           Jonathan B. Postel
                              August 1982

                     Information Sciences Institute
                   University of Southern California
                           4676 Admiralty Way
                   Marina del Rey, California  90291
@end smallexample

@item RFC 1867
@cindex RFC 1867
@cindex HTML File Upload

@smallexample
Network Working Group                                           E. Nebel
Request For Comments: 1867                                   L. Masinter
Category: Experimental                                 Xerox Corporation
                                                           November 1995


                     Form-based File Upload in HTML
@end smallexample

@item RFC 1939
@cindex RFC 1939
@cindex POP

@smallexample
Network Working Group                                           J. Myers
Request for Comments: 1939                               Carnegie Mellon
STD: 53                                                          M. Rose
Obsoletes: 1725                             Dover Beach Consulting, Inc.
Category: Standards Track                                       May 1996


                    Post Office Protocol - Version 3
@end smallexample

@item RFC 1945
@cindex RFC 1945
@cindex HTTP/1.0

@smallexample
Network Working Group                                     T. Berners-Lee
Request for Comments: 1945                                       MIT/LCS
Category: Informational                                      R. Fielding
                                                               UC Irvine
                                                              H. Frystyk
                                                                 MIT/LCS
                                                                May 1996


                Hypertext Transfer Protocol -- HTTP/1.0
@end smallexample

@item RFC 2049
@cindex RFC 2049
@cindex MIME

@smallexample
Network Working Group                                          N. Freed
Request for Comments: 2049                                     Innosoft
Obsoletes: 1521, 1522, 1590                               N. Borenstein
Category: Standards Track                                 First Virtual
                                                          November 1996


                 Multipurpose Internet Mail Extensions
                           (MIME) Part Five:
                   Conformance Criteria and Examples
@end smallexample

@item RFC 2109
@cindex RFC 2109

@smallexample
Network Working Group                                         D. Kristol
Request for Comments: 2109        Bell Laboratories, Lucent Technologies
Category: Standards Track                                    L. Montulli
                                                 Netscape Communications
                                                           February 1997


                    HTTP State Management Mechanism
@end smallexample

@item RFC 2195
@cindex RFC 2195
@cindex IMAP/POP

@smallexample
Network Working Group                                       J. Klensin
Request for Comments: 2195                                    R. Catoe
Category: Standards Track                                 P. Krumviede
Obsoletes: 2095                                                    MCI
                                                        September 1997


       IMAP/POP AUTHorize Extension for Simple Challenge/Response
@end smallexample

@item RFC 2554
@cindex RFC 2554
@cindex SMTP Authentication

@smallexample
Network Working Group                                           J. Myers
Request for Comments: 2554                       Netscape Communications
Category: Standards Track                                     March 1999


                         SMTP Service Extension
                           for Authentication
@end smallexample

@item RFC 2616
@cindex RFC 2616
@cindex HTTP/1.1

@smallexample
Network Working Group                                      R. Fielding
Request for Comments: 2616                                   UC Irvine
Obsoletes: 2068                                              J. Gettys
Category: Standards Track                                   Compaq/W3C
                                                              J. Mogul
                                                                Compaq
                                                            H. Frystyk
                                                               W3C/MIT
                                                           L. Masinter
                                                                 Xerox
                                                              P. Leach
                                                             Microsoft
                                                        T. Berners-Lee
                                                               W3C/MIT
                                                             June 1999


                Hypertext Transfer Protocol -- HTTP/1.1
@end smallexample

@item RFC 2617
@cindex RFC 2617
@cindex HTTP Authentication

@smallexample
Network Working Group                                          J. Franks
Request for Comments: 2617                       Northwestern University
Obsoletes: 2069                                          P. Hallam-Baker
Category: Standards Track                                 Verisign, Inc.
                                                            J. Hostetler
                                                         AbiSource, Inc.
                                                             S. Lawrence
                                                   Agranat Systems, Inc.
                                                                P. Leach
                                                   Microsoft Corporation
                                                             A. Luotonen
                                     Netscape Communications Corporation
                                                              L. Stewart
                                                       Open Market, Inc.
                                                               June 1999


      HTTP Authentication: Basic and Digest Access Authentication
@end smallexample

@item draft 302
@cindex draft 302
@cindex SSL

@smallexample
Transport Layer Security Working Group                  Alan O. Freier
INTERNET-DRAFT                                 Netscape Communications
Expire in six months                                    Philip Karlton
                                               Netscape Communications
                                                        Paul C. Kocher
                                                Independent Consultant
                                                     November 18, 1996


                          The SSL Protocol
                            Version 3.0
@end smallexample

@item SOAP (W3C Note 08 May 2000)
@cindex SOAP 1.1

@smallexample
Simple Object Access Protocol (SOAP) 1.1

W3C Note 08 May 2000

This version:
   http://www.w3.org/TR/2000/NOTE-SOAP-20000508

Latest version:
   http://www.w3.org/TR/SOAP

Authors (alphabetically):
   Don Box, DevelopMentor
   David Ehnebuske, IBM
   Gopal Kakivaya, Microsoft
   Andrew Layman, Microsoft
   Noah Mendelsohn, Lotus Development Corp.
   Henrik Frystyk Nielsen, Microsoft
   Satish Thatte, Microsoft
   Dave Winer, UserLand Software, Inc.

Copyright© 2000 DevelopMentor, International Business Machines Corporation,
Lotus Development Corporation, Microsoft, UserLand Software
@end smallexample

@url{http://www.w3.org/TR/SOAP/}
@sp 1

@item A Busy Developer's Guide to SOAP 1.1
@cindex SOAP 1.1

@smallexample
By Dave Winer, Jake Savin, UserLand Software, 4/2/01.
@end smallexample

@url{http://www.soapware.org/bdg}

@end table

@c ======================================================================

@node AWS API Reference
@appendix AWS API Reference

@menu
AWS User's API:

* AWS::
* AWS.Attachments::
* AWS.Client::
* AWS.Client.Hotplug::
* AWS.Communication::
* AWS.Communication.Client::
* AWS.Communication.Server::
* AWS.Config::
* AWS.Config.Ini::
* AWS.Config.Set::
* AWS.Containers.Tables::
* AWS.Cookie::
* AWS.Default::
* AWS.Dispatchers::
* AWS.Dispatchers.Callback::
* AWS.Exceptions::
* AWS.Headers::
* AWS.Headers.Values::
* AWS.Jabber::
* AWS.LDAP.Client::
* AWS.Log::
* AWS.Messages::
* AWS.MIME::
* AWS.Net::
* AWS.Net.Buffered::
* AWS.Net.Log::
* AWS.Net.Log.Callbacks::
* AWS.Net.SSL::
* AWS.Net.SSL.Certificate::
* AWS.Parameters::
* AWS.POP::
* AWS.Resources::
* AWS.Resources.Embedded::
* AWS.Resources.Files::
* AWS.Resources.Streams::
* AWS.Resources.Streams.Disk::
* AWS.Resources.Streams.Disk.Once::
* AWS.Resources.Streams.Memory::
* AWS.Resources.Streams.Memory.ZLib::
* AWS.Resources.Streams.Pipe::
* AWS.Response::
* AWS.Server::
* AWS.Server.Hotplug::
* AWS.Server.Log::
* AWS.Server.Push::
* AWS.Server.Status::
* AWS.Services.Callbacks::
* AWS.Services.Directory::
* AWS.Services.Dispatchers::
* AWS.Services.Dispatchers.Linker::
* AWS.Services.Dispatchers.Method::
* AWS.Services.Dispatchers.URI::
* AWS.Services.Dispatchers.Virtual_Host::
* AWS.Services.Download::
* AWS.Services.Page_Server::
* AWS.Services.Split_Pages::
* AWS.Services.Split_Pages.Alpha::
* AWS.Services.Split_Pages.Alpha.Bounded::
* AWS.Services.Split_Pages.Uniform::
* AWS.Services.Split_Pages.Uniform.Alpha::
* AWS.Services.Split_Pages.Uniform.Overlapping::
* AWS.Services.Transient_Pages::
* AWS.Services.Web_Block::
* AWS.Services.Web_Block.Context::
* AWS.Services.Web_Block.Registry::
* AWS.Session::
* AWS.SMTP::
* AWS.SMTP.Client::
* AWS.Status::
* AWS.Templates::
* AWS.Translator::
* AWS.URL::
@end menu

@menu
SOAP User's API:

* SOAP::
* SOAP.Client::
* SOAP.Dispatchers::
* SOAP.Dispatchers.Callback::
* SOAP.Message::
* SOAP.Message.XML::
* SOAP.Parameters::
* SOAP.Types::
@end menu

@node AWS
@appendixsec AWS
@cindex AWS

@include aws.ads.texi

@page
@node AWS.Attachments
@appendixsec AWS.Attachments
@cindex AWS.Attachments

@include aws-attachments.ads.texi

@page
@node AWS.Client
@appendixsec AWS.Client
@cindex AWS.Client

@include aws-client.ads.texi

@page
@node AWS.Client.Hotplug
@appendixsec AWS.Client.Hotplug
@cindex AWS.Client.Hotplug

@include aws-client-hotplug.ads.texi

@page
@node AWS.Communication
@appendixsec AWS.Communication
@cindex AWS.Communication

@include aws-communication.ads.texi

@page
@node AWS.Communication.Client
@appendixsec AWS.Communication.Client
@cindex AWS.Communication.Client

@include aws-communication-client.ads.texi

@page
@node AWS.Communication.Server
@appendixsec AWS.Communication.Server
@cindex AWS.Communication.Server

@include aws-communication-server.ads.texi

@page
@node AWS.Config
@appendixsec AWS.Config
@cindex AWS.Config

@include aws-config.ads.texi

@page
@node AWS.Config.Ini
@appendixsec AWS.Config.Ini
@cindex AWS.Config.Ini

@include aws-config-ini.ads.texi

@page
@node AWS.Config.Set
@appendixsec AWS.Config.Set
@cindex AWS.Config.Set

@include aws-config-set.ads.texi

@page
@node AWS.Containers.Tables
@appendixsec AWS.Containers.Tables
@cindex AWS.Containers.Tables

@include aws-containers-tables.ads.texi

@page
@node AWS.Cookie
@appendixsec AWS.Cookie
@cindex AWS.Cookie

@include aws-cookie.ads.texi

@page
@node AWS.Default
@appendixsec AWS.Default
@cindex AWS.Default

@include aws-default.ads.texi

@page
@node AWS.Dispatchers
@appendixsec AWS.Dispatchers
@cindex AWS.Dispatchers

@include aws-dispatchers.ads.texi

@page
@node AWS.Dispatchers.Callback
@appendixsec AWS.Dispatchers.Callback
@cindex AWS.Dispatchers.Callback
@cindex Callback, dispatcher API

@include aws-dispatchers-callback.ads.texi

@page
@node AWS.Exceptions
@appendixsec AWS.Exceptions
@cindex AWS.Exceptions
@cindex Exceptions, Unexpected exceptions, Exceptions handler

@include aws-exceptions.ads.texi

@page
@node AWS.Headers
@appendixsec AWS.Headers
@cindex AWS.Headers

@include aws-headers.ads.texi

@page
@node AWS.Headers.Values
@appendixsec AWS.Headers.Values
@cindex AWS.Headers.Values

@include aws-headers-values.ads.texi

@page
@node AWS.Jabber
@appendixsec AWS.Jabber
@cindex AWS.Jabber
@cindex Jabber Binding

@include aws-jabber.ads.texi

@page
@node AWS.LDAP.Client
@appendixsec AWS.LDAP.Client
@cindex AWS.LDAP.Client
@cindex LDAP Binding

@include aws-ldap-client.ads.texi

@page
@node AWS.Log
@appendixsec AWS.Log
@cindex AWS.Log

@include aws-log.ads.texi

@page
@node AWS.Messages
@appendixsec AWS.Messages
@cindex AWS.Messages

@include aws-messages.ads.texi

@page
@node AWS.MIME
@appendixsec AWS.MIME
@cindex AWS.MIME

@include aws-mime.ads.texi

@page
@node AWS.Net
@appendixsec AWS.Net
@cindex AWS.Net

@include aws-net.ads.texi

@page
@node AWS.Net.Buffered
@appendixsec AWS.Net.Buffered
@cindex AWS.Net.Buffered

@include aws-net-buffered.ads.texi

@page
@node AWS.Net.Log
@appendixsec AWS.Net.Log
@cindex AWS.Net.Log

@include aws-net-log.ads.texi

@page
@node AWS.Net.Log.Callbacks
@appendixsec AWS.Net.Log.Callbacks
@cindex AWS.Net.Log.Callbacks

@include aws-net-log-callbacks.ads.texi

@page
@node AWS.Net.SSL
@appendixsec AWS.Net.SSL
@cindex AWS.Net.SSL

@include aws-net-ssl.ads.texi

@page
@node AWS.Net.SSL.Certificate
@appendixsec AWS.Net.SSL.Certificate
@cindex AWS.Net.SSL.Certificate

@include aws-net-ssl-certificate.ads.texi

@page
@node AWS.Parameters
@appendixsec AWS.Parameters
@cindex AWS.Parameters

@include aws-parameters.ads.texi

@page
@node AWS.POP
@appendixsec AWS.POP
@cindex AWS.POP

@include aws-pop.ads.texi

@page
@node AWS.Resources
@appendixsec AWS.Resources
@cindex AWS.Resources

@include aws-resources.ads.texi

@page
@node AWS.Resources.Embedded
@appendixsec AWS.Resources.Embedded
@cindex AWS.Resources.Embedded

@include aws-resources-embedded.ads.texi

@page
@node AWS.Resources.Files
@appendixsec AWS.Resources.Files
@cindex AWS.Resources.Files

@include aws-resources-files.ads.texi

@page
@node AWS.Resources.Streams
@appendixsec AWS.Resources.Streams
@cindex AWS.Resources.Streams

@include aws-resources-streams.ads.texi

@page
@node AWS.Resources.Streams.Disk
@appendixsec AWS.Resources.Streams.Disk
@cindex AWS.Resources.Streams.Disk

@include aws-resources-streams-disk.ads.texi

@page
@node AWS.Resources.Streams.Disk.Once
@appendixsec AWS.Resources.Streams.Disk.Once
@cindex AWS.Resources.Streams.Disk.Once

@include aws-resources-streams-disk-once.ads.texi

@page
@node AWS.Resources.Streams.Memory
@appendixsec AWS.Resources.Streams.Memory
@cindex AWS.Resources.Streams.Memory

@include aws-resources-streams-memory.ads.texi

@page
@node AWS.Resources.Streams.Memory.ZLib
@appendixsec AWS.Resources.Streams.Memory.ZLib
@cindex AWS.Resources.Streams.Memory.ZLib

@include aws-resources-streams-memory-zlib.ads.texi

@page
@node AWS.Resources.Streams.Pipe
@appendixsec AWS.Resources.Streams.Pipe
@cindex AWS.Resources.Streams.Pipe

@include aws-resources-streams-pipe.ads.texi

@page
@node AWS.Response
@appendixsec AWS.Response
@cindex AWS.Response

@include aws-response.ads.texi

@page
@node AWS.Server
@appendixsec AWS.Server
@cindex AWS.Server

@include aws-server.ads.texi

@page
@node AWS.Server.Hotplug
@appendixsec AWS.Server.Hotplug
@cindex AWS.Server.Hotplug

@include aws-server-hotplug.ads.texi

@page
@node AWS.Server.Log
@appendixsec AWS.Server.Log
@cindex AWS.Server.Log

@include aws-server-log.ads.texi

@page
@node AWS.Server.Push
@appendixsec AWS.Server.Push
@cindex AWS.Server.Push

@include aws-server-push.ads.texi

@page
@node AWS.Server.Status
@appendixsec AWS.Server.Status
@cindex AWS.Server.Status

@include aws-server-status.ads.texi

@page
@node AWS.Services.Callbacks
@appendixsec AWS.Services.Callbacks
@cindex AWS.Services.Callbacks

@include aws-services-callbacks.ads.texi

@page
@node AWS.Services.Directory
@appendixsec AWS.Services.Directory
@cindex AWS.Services.Directory

@include aws-services-directory.ads.texi

@page
@node AWS.Services.Dispatchers
@appendixsec AWS.Services.Dispatchers
@cindex AWS.Services.Dispatchers

@include aws-services-dispatchers.ads.texi

@page
@node AWS.Services.Dispatchers.Linker
@appendixsec AWS.Services.Dispatchers.Linker
@cindex AWS.Services.Dispatchers.Linker

@include aws-services-dispatchers-linker.ads.texi

@page
@node AWS.Services.Dispatchers.Method
@appendixsec AWS.Services.Dispatchers.Method
@cindex AWS.Services.Dispatchers.Method

@include aws-services-dispatchers-method.ads.texi

@page
@node AWS.Services.Dispatchers.URI
@appendixsec AWS.Services.Dispatchers.URI
@cindex AWS.Services.Dispatchers.URI

@include aws-services-dispatchers-uri.ads.texi

@page
@node AWS.Services.Dispatchers.Virtual_Host
@appendixsec AWS.Services.Dispatchers.Virtual_Host
@cindex AWS.Services.Dispatchers.Virtual_Host

@include aws-services-dispatchers-virtual_host.ads.texi

@page
@node AWS.Services.Download
@appendixsec AWS.Services.Download
@cindex AWS.Services.Download

@include aws-services-download.ads.texi

@page
@node AWS.Services.Page_Server
@appendixsec AWS.Services.Page_Server
@cindex AWS.Services.Page_Server

@include aws-services-page_server.ads.texi

@page
@node AWS.Services.Split_Pages
@appendixsec AWS.Services.Split_Pages
@cindex AWS.Services.Split_Pages

@include aws-services-split_pages.ads.texi

@page
@node AWS.Services.Split_Pages.Alpha
@appendixsec AWS.Services.Split_Pages.Alpha
@cindex AWS.Services.Split_Pages.Alpha

@include aws-services-split_pages-alpha.ads.texi

@page
@node AWS.Services.Split_Pages.Alpha.Bounded
@appendixsec AWS.Services.Split_Pages.Alpha.Bounded
@cindex AWS.Services.Split_Pages.Alpha.Bounded

@include aws-services-split_pages-alpha-bounded.ads.texi

@page
@node AWS.Services.Split_Pages.Uniform
@appendixsec AWS.Services.Split_Pages.Uniform
@cindex AWS.Services.Split_Pages.Alpha.Uniform

@include aws-services-split_pages-uniform.ads.texi

@page
@node AWS.Services.Split_Pages.Uniform.Alpha
@appendixsec AWS.Services.Split_Pages.Uniform.Alpha
@cindex AWS.Services.Split_Pages.Alpha.Uniform.Alpha

@include aws-services-split_pages-uniform-alpha.ads.texi

@page
@node AWS.Services.Split_Pages.Uniform.Overlapping
@appendixsec AWS.Services.Split_Pages.Uniform.Overlapping
@cindex AWS.Services.Split_Pages.Alpha.Uniform.Overlapping

@include aws-services-split_pages-uniform-overlapping.ads.texi

@page
@node AWS.Services.Transient_Pages
@appendixsec AWS.Services.Transient_Pages
@cindex AWS.Services.Transient_Pages

@include aws-services-transient_pages.ads.texi

@page
@node AWS.Services.Web_Block
@appendixsec AWS.Services.Web_Block
@cindex AWS.Services.Web_Block

@include aws-services-web_block.ads.texi

@page
@node AWS.Services.Web_Block.Context
@appendixsec AWS.Services.Web_Block.Context
@cindex AWS.Services.Web_Block.Context

@include aws-services-web_block-context.ads.texi

@page
@node AWS.Services.Web_Block.Registry
@appendixsec AWS.Services.Web_Block.Registry
@cindex AWS.Services.Web_Block.Registry

@include aws-services-web_block-registry.ads.texi

@page
@node AWS.Session
@appendixsec AWS.Session
@cindex AWS.Session

@include aws-session.ads.texi

@page
@node AWS.SMTP
@appendixsec AWS.SMTP
@cindex AWS.SMTP

@include aws-smtp.ads.texi

@page
@node AWS.SMTP.Client
@appendixsec AWS.SMTP.Client
@cindex AWS.SMTP.Client

@include aws-smtp-client.ads.texi

@page
@node AWS.Status
@appendixsec AWS.Status
@cindex AWS.Status

@include aws-status.ads.texi

@page
@node AWS.Templates
@appendixsec AWS.Templates
@cindex AWS.Templates

@include aws-templates.ads.texi

@page
@node AWS.Translator
@appendixsec AWS.Translator
@cindex AWS.Translator

@include aws-translator.ads.texi

@page
@node AWS.URL
@appendixsec AWS.URL
@cindex AWS.URL

@include aws-url.ads.texi

@page
@node SOAP
@appendixsec SOAP
@cindex SOAP (API)

@include soap.ads.texi

@page
@node SOAP.Client
@appendixsec SOAP.Client
@cindex SOAP.Client

@include soap-client.ads.texi

@page
@node SOAP.Dispatchers
@appendixsec SOAP.Dispatchers
@cindex SOAP.Dispatchers

@include soap-dispatchers.ads.texi

@page
@node SOAP.Dispatchers.Callback
@appendixsec SOAP.Dispatchers.Callback
@cindex SOAP.Dispatchers.Callback

@include soap-dispatchers-callback.ads.texi

@page
@node SOAP.Message
@appendixsec SOAP.Message
@cindex SOAP.Message

@include soap-message.ads.texi

@page
@node SOAP.Message.XML
@appendixsec SOAP.Message.XML
@cindex SOAP.Message.XML

@include soap-message-xml.ads.texi

@page
@node SOAP.Parameters
@appendixsec SOAP.Parameters
@cindex SOAP.Parameters

@include soap-parameters.ads.texi

@page
@node SOAP.Types
@appendixsec SOAP.Types
@cindex SOAP.Types

@include soap-types.ads.texi

@c ======================================================================

@node Index
@unnumbered Index

@printindex cp

@bye
