
                                                                 -*- text -*-

Contents
========

 * Sessions and requests
 * Passing errors back from neon callbacks
 * Library specific conventions
 * Error sources when dispatching a request



Sessions and requests
=====================

Both Neon and ra_neon have concepts known as 'session' and 'request'.
The request concept in ra_neon parallels the one in Neon, except that
ra_neon stores request-related info for the RA layer.  The session
concept in ra_neon differs from the one in Neon: while the one in Neon
is mainly meant to track / maintain a socket connection, the ra_neon
session is the RA session opened by an RA consumer.  An ra_neon session
(currently) contains 2 Neon sessions.

Only one request can be dispatched on a Neon session at a time; this
is why there is a second Neon session, which is used by ra_neon
implementations of Neon callbacks which want to retrieve information
from the server concurrently with an active Neon session.  Allocation
to either Neon session happens automatically.



Passing errors back from neon callbacks
=======================================

The general Neon request sequence is:

 1. Create a session
 2. Create a request
 3. Add an in-memory or callback-provided request body, if applicable
 4. Add custom headers, if any
 5. Register one or more content consumers for the response body
    (ra_neon usually creates xml parsers for this purpose)
 6. Dispatch the request
    (send it to the server and process the response)

While in any of the registered callbacks (be it xml parser,
body consumer or body provider), Subversion function calls can return
their usual errors.  The Neon APIs have been wrapped to catch these
and marshall them through the Neon layer, so that the dispatch routine
can raise the error for normal processing.



Library specific conventions
============================

 * When a specific variable name is used frequently both to refer to
   ra_neon and Neon resources, the Neon resource variable is prefixed
   with 'ne_'.

 * Don't use Neon functions which construct and destroy
   their own requests (ie: ne_simple_request, ne_lock, ne_propfind etc.).

 * Create wrapper functions for callbacks, creating an ra_neon callback
   which returns an svn_error_t *, storing the returned error
   in the request structure.

 * When storing an error in the request structure 'err' field,
   use the SVN_RA_NEON__REQ_ERR() macro.

 * Make Neon resources which need explicit destruction live as short
   as possible, or register a pool cleanup to ensure destruction.
   Preferrably, copy the results into a pool with the necessary lifetime.



Error sources when dispatching a request
========================================

There are a number of different error sources which all come
together in svn_ra_neon__request_dispatch(), which tries to
sort them out and generate the most important error.

 1. Neon encounters a network or authentication error
    (all Neon errors except NE_ERROR and NE_OK)
 2. Neon didn't encounter an error (returns NE_OK),
    but the response sent contains an HTTP error (ie 404 Not found, or alike)
    In this situation, there are 2 possibilities:
    a) The response contains extended error explanation from mod_dav,
       which will sometimes be marked as Subversion internal error
    b) The response contains only the error status code.
 3. A callback requested cancelation because the routine it wrapped
    [see 'Passing back errors from Neon' about wrapping] returned an error
    (request body provider or response consumer, the latter
     are xml parser errors, most of the time).

In order to make callers as simple as possible, svn_ra_neon__request_dispatch()
condenses all these error sources into 1 returned svn_error_t, while trying
to keep the errors returned human-readable.

When condensing errors, these rules are used:

 - Local errors take priority over ones received from the server
 - Authentication problems, network problems and other unknown
   errors are transformed into a generic error code + message
 - Locally generated errors in the callbacks are returned as is
 - Subversion server errors are returned when available
 - Protocol statuses unexpectedly returned (including 2xx codes!)
   result in a general error message including the status number
   and description

