Alien-SVN

 view release on metacpan or  search on metacpan

src/subversion/subversion/libsvn_ra_serf/options.c  view on Meta::CPAN

#include "private/svn_fspath.h"

#include "ra_serf.h"


/* In a debug build, setting this environment variable to "yes" will force
   the client to speak v1, even if the server is capable of speaking v2. */
#define SVN_IGNORE_V2_ENV_VAR "SVN_I_LIKE_LATENCY_SO_IGNORE_HTTPV2"


/*
 * This enum represents the current state of our XML parsing for an OPTIONS.
 */
enum options_state_e {
  INITIAL = 0,
  OPTIONS,
  ACTIVITY_COLLECTION,
  HREF
};

typedef struct options_context_t {
  /* pool to allocate memory from */
  apr_pool_t *pool;

  /* Have we extracted options values from the headers already?  */
  svn_boolean_t headers_processed;

  svn_ra_serf__session_t *session;
  svn_ra_serf__connection_t *conn;
  svn_ra_serf__handler_t *handler;

  svn_ra_serf__response_handler_t inner_handler;
  void *inner_baton;

  const char *activity_collection;
  svn_revnum_t youngest_rev;

} options_context_t;

#define D_ "DAV:"
#define S_ SVN_XML_NAMESPACE
static const svn_ra_serf__xml_transition_t options_ttable[] = {
  { INITIAL, D_, "options-response", OPTIONS,
    FALSE, { NULL }, FALSE },

  { OPTIONS, D_, "activity-collection-set", ACTIVITY_COLLECTION,
    FALSE, { NULL }, FALSE },

  { ACTIVITY_COLLECTION, D_, "href", HREF,
    TRUE, { NULL }, TRUE },

  { 0 }
};


/* Conforms to svn_ra_serf__xml_closed_t  */
static svn_error_t *
options_closed(svn_ra_serf__xml_estate_t *xes,
               void *baton,
               int leaving_state,
               const svn_string_t *cdata,
               apr_hash_t *attrs,
               apr_pool_t *scratch_pool)
{
  options_context_t *opt_ctx = baton;

  SVN_ERR_ASSERT(leaving_state == HREF);
  SVN_ERR_ASSERT(cdata != NULL);

  opt_ctx->activity_collection = svn_urlpath__canonicalize(cdata->data,
                                                           opt_ctx->pool);

  return SVN_NO_ERROR;
}


static svn_error_t *
create_options_body(serf_bucket_t **body_bkt,
                    void *baton,
                    serf_bucket_alloc_t *alloc,
                    apr_pool_t *pool)
{
  serf_bucket_t *body;
  body = serf_bucket_aggregate_create(alloc);
  svn_ra_serf__add_xml_header_buckets(body, alloc);
  svn_ra_serf__add_open_tag_buckets(body, alloc, "D:options",
                                    "xmlns:D", "DAV:",
                                    NULL);
  svn_ra_serf__add_tag_buckets(body, "D:activity-collection-set", NULL, alloc);
  svn_ra_serf__add_close_tag_buckets(body, alloc, "D:options");

  *body_bkt = body;
  return SVN_NO_ERROR;
}


/* We use these static pointers so we can employ pointer comparison
 * of our capabilities hash members instead of strcmp()ing all over
 * the place.
 */
/* Both server and repository support the capability. */
static const char *const capability_yes = "yes";
/* Either server or repository does not support the capability. */
static const char *const capability_no = "no";
/* Server supports the capability, but don't yet know if repository does. */
static const char *const capability_server_yes = "server-yes";


/* This implements serf_bucket_headers_do_callback_fn_t.
 */
static int
capabilities_headers_iterator_callback(void *baton,
                                       const char *key,
                                       const char *val)
{
  options_context_t *opt_ctx = baton;
  svn_ra_serf__session_t *session = opt_ctx->session;

  if (svn_cstring_casecmp(key, "dav") == 0)
    {
      /* Each header may contain multiple values, separated by commas, e.g.:
           DAV: version-control,checkout,working-resource
           DAV: merge,baseline,activity,version-controlled-collection
           DAV: http://subversion.tigris.org/xmlns/dav/svn/depth */
      apr_array_header_t *vals = svn_cstring_split(val, ",", TRUE,
                                                   opt_ctx->pool);

      /* Right now we only have a few capabilities to detect, so just
         seek for them directly.  This could be written slightly more
         efficiently, but that wouldn't be worth it until we have many



( run in 1.117 second using v1.01-cache-2.11-cpan-2ed5026b665 )