You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2012/07/11 12:26:26 UTC
svn commit: r1360103 [5/18] - in /subversion/branches/ev2-export: ./ build/
build/ac-macros/ build/generator/ build/generator/templates/ build/win32/
contrib/server-side/ notes/wc-ng/ subversion/bindings/javahl/native/
subversion/bindings/javahl/src/or...
Modified: subversion/branches/ev2-export/subversion/libsvn_fs_fs/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_fs_fs/lock.c?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_fs_fs/lock.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_fs_fs/lock.c Wed Jul 11 10:26:19 2012
@@ -655,7 +655,11 @@ walk_locks(svn_fs_t *fs,
svn_boolean_t have_write_lock,
apr_pool_t *pool)
{
- struct walk_locks_baton wlb = { get_locks_func, get_locks_baton, fs };
+ struct walk_locks_baton wlb;
+
+ wlb.get_locks_func = get_locks_func;
+ wlb.get_locks_baton = get_locks_baton;
+ wlb.fs = fs;
SVN_ERR(walk_digest_files(fs->path, digest_path, locks_walker, &wlb,
have_write_lock, pool));
return SVN_NO_ERROR;
Modified: subversion/branches/ev2-export/subversion/libsvn_fs_fs/rep-cache-db.sql
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_fs_fs/rep-cache-db.sql?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_fs_fs/rep-cache-db.sql (original)
+++ subversion/branches/ev2-export/subversion/libsvn_fs_fs/rep-cache-db.sql Wed Jul 11 10:26:19 2012
@@ -41,25 +41,19 @@ SELECT revision, offset, size, expanded_
FROM rep_cache
WHERE hash = ?1
-
-- STMT_SET_REP
INSERT OR FAIL INTO rep_cache (hash, revision, offset, size, expanded_size)
VALUES (?1, ?2, ?3, ?4, ?5)
-
-- STMT_GET_REPS_FOR_RANGE
SELECT hash, revision, offset, size, expanded_size
FROM rep_cache
WHERE revision >= ?1 AND revision <= ?2
-
-- STMT_GET_MAX_REV
SELECT MAX(revision)
FROM rep_cache
-
-- STMT_DEL_REPS_YOUNGER_THAN_REV
DELETE FROM rep_cache
WHERE revision > ?1
-
-
Modified: subversion/branches/ev2-export/subversion/libsvn_fs_fs/structure
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_fs_fs/structure?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_fs_fs/structure (original)
+++ subversion/branches/ev2-export/subversion/libsvn_fs_fs/structure Wed Jul 11 10:26:19 2012
@@ -40,6 +40,9 @@ repository) is:
revprops/ Subdirectory containing rev-props
<shard>/ Shard directory, if sharding is in use (see below)
<revnum> File containing rev-props for <revnum>
+ <shard>.pack/ Pack directory, if the repo has been packed (see below)
+ <rev>.<count> Pack file, if the repository has been packed (see below)
+ manifest Pack manifest file, if a pack file exists (see below)
revprops.db SQLite database of the packed revision properties
transactions/ Subdirectory containing transactions
<txnid>.txn/ Directory containing transaction <txnid>
@@ -134,6 +137,7 @@ The formats are:
Format 3, understood by Subversion 1.5+
Format 4, understood by Subversion 1.6+
Format 5, understood by Subversion 1.7-dev, never released
+ Format 6, understood by Subversion 1.8
The differences between the formats are:
@@ -173,6 +177,12 @@ Revision changed paths list:
Format 1-3: Does not contain the node's kind.
Format 4+: Contains the node's kind.
+Shard packing:
+ Format 4: Applied to revision data only.
+ Format 5: Revprops would be packed independently of revision data.
+ Format 6+: Applied equally to revision data and revprop data
+ (i.e. same min packed revision)
+
# Incomplete list. See SVN_FS_FS__MIN_*_FORMAT
@@ -232,6 +242,79 @@ See r1143829 of this file:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/structure?view=markup&pathrev=1143829
+Packing revision properties (format 6+)
+---------------------------
+
+Similarly to the revision data, packing will concatenate multiple
+revprops into a single file. Since they are mutable data, we put an
+upper limit to the size of these files: We will concatenate the data
+up to the limit and then use a new file for the following revisions.
+
+The limit can be set and changed at will in the configuration file.
+It is 64kB by default. Because a pack file must contain at least one
+complete property list, files containing just one revision may exceed
+that limit.
+
+Furthermore, pack files can be compressed which saves about 75% of
+disk space. A configuration file flag enables the compression; it is
+off by default and may be switched on and off at will. The pack size
+limit is always applied to the uncompressed data. For this reason,
+the default is 256kB while compression has been enabled.
+
+Files are named after their start revision as "<rev>.<counter>" where
+counter will be increased whenever we rewrite a pack file due to a
+revprop change. The manifest file contains the list of pack file
+names, one line for each revision.
+
+Many tools track repository global data in revision properties at
+revision 0. To minimize I/O overhead for those applications, we
+will never pack that revision, i.e. its data is always being kept
+in revprops/0/0.
+
+Pack file format
+
+ Top level: <length><packed container>
+
+ We always apply data compression to the pack file - using the
+ SVN_DELTA_COMPRESSION_LEVEL_NONE level if compression is disabled.
+ <length> is being encoded using the variable-length svndiff integer
+ format.
+
+ container := header '\n' (revprops)+
+ header := start_rev '\n' rev_count '\n' (size '\n')+
+
+ All numbers in the header are given as ASCII decimals. rev_count
+ is the number of revisions packed into this container. There must
+ be exactly as many "size" and serialized "revprops". The "size"
+ values in the list are the length in bytes of the serialized
+ revprops of the respective revision.
+
+Writing to packed revprops
+
+ The old pack file is being read and the new revprops serialized.
+ If they fit into the same pack file, a temp file with the new
+ content gets written and moved into place just like an non-packed
+ revprop file would. No name change or manifest update required.
+
+ If they don't fit into the same pack file, i.e. exceed the pack
+ size limit, the pack will be split into 2 or 3 new packs just
+ before and / or after the modified revision.
+
+ In the current implementation, they will never be merged again.
+ To minimize fragmentation, the initial packing process will only
+ use about 90% of the limit, i.e. leave some room for growth.
+
+ When a pack file gets split, its counter is being increased
+ creating a new file and leaving the old content in place and
+ available for concurrent readers. Only after the new manifest
+ file got moved into place, will the old pack files be deleted.
+
+ Write access to revprops is being serialized by the global
+ filesystem write lock. We only need to build a few retries into
+ the reader code to gracefully handle manifest changes and pack
+ file deletions.
+
+
Node-revision IDs
-----------------
Modified: subversion/branches/ev2-export/subversion/libsvn_fs_fs/temp_serializer.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_fs_fs/temp_serializer.c?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_fs_fs/temp_serializer.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_fs_fs/temp_serializer.c Wed Jul 11 10:26:19 2012
@@ -48,16 +48,16 @@ encode_number(apr_int64_t number, char *
if (number < 0)
{
number = -number;
- *key_buffer = (number & 63) + ' ' + 65;
+ *key_buffer = (char)((number & 63) + ' ' + 65);
}
else
- *key_buffer = (number & 63) + ' ' + 1;
+ *key_buffer = (char)((number & 63) + ' ' + 1);
number /= 64;
/* write 7 bits / byte until no significant bits are left */
while (number)
{
- *++key_buffer = (number & 127) + ' ' + 1;
+ *++key_buffer = (char)((number & 127) + ' ' + 1);
number /= 128;
}
Modified: subversion/branches/ev2-export/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_fs_fs/tree.c?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_fs_fs/tree.c Wed Jul 11 10:26:19 2012
@@ -3881,6 +3881,7 @@ svn_fs_fs__verify_root(svn_fs_root_t *ro
const svn_fs_id_t *pred_id;
dag_node_t *pred;
svn_revnum_t pred_rev;
+ svn_revnum_t delta;
/* Only r0 should have no predecessor. */
SVN_ERR(svn_fs_fs__dag_get_predecessor_id(&pred_id, frd->root_dir));
@@ -3898,10 +3899,27 @@ svn_fs_fs__verify_root(svn_fs_root_t *ro
{
SVN_ERR(svn_fs_fs__dag_get_node(&pred, root->fs, pred_id, pool));
SVN_ERR(svn_fs_fs__dag_get_revision(&pred_rev, pred, pool));
- if (pred_rev+1 != root->rev)
- /* Issue #4129. */
+
+ /* Issue #4129: bogus predecessors. */
+ /* Check 1: predecessor must be an earlier revision.
+ */
+ if (pred_rev >= root->rev)
+ return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+ "r%ld's root node's predecessor is r%ld"
+ " but must be earlier revision",
+ root->rev, pred_rev);
+
+ /* Check 2: distances must be a power of 2.
+ * Note that this condition is not defined by the FSFS format but
+ * merely a byproduct of the current implementation. Therefore,
+ * it may help to spot corruptions for the time being but might
+ * need to be removed / relaxed in later versions.
+ */
+ delta = root->rev - pred_rev;
+ if (delta & (delta - 1))
return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
- "r%ld's root node's predecessor is r%ld",
+ "r%ld's root node's predecessor is r%ld"
+ " but the delta must be a power of 2",
root->rev, pred_rev);
}
}
Modified: subversion/branches/ev2-export/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra/ra_loader.c?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra/ra_loader.c Wed Jul 11 10:26:19 2012
@@ -51,20 +51,6 @@
#include "private/svn_delta_private.h"
-/* ### This file maps URL schemes to particular RA libraries.
- ### Currently, the only pair of RA libraries which support the same
- ### protocols are neon and serf. svn_ra_open3 makes the assumption
- ### that this is the case; that their 'schemes' fields are both
- ### dav_schemes; and that "neon" is listed first.
-
- ### Users can choose which dav library to use with the http-library
- ### preference in .subversion/servers; however, it is ignored by
- ### any code which uses the pre-1.2 API svn_ra_get_ra_library
- ### instead of svn_ra_open. */
-
-#if defined(SVN_HAVE_NEON) && defined(SVN_HAVE_SERF)
-#define CHOOSABLE_DAV_MODULE
-#endif
/* These are the URI schemes that the respective libraries *may* support.
@@ -86,15 +72,6 @@ static const struct ra_lib_defn {
svn_ra_init_func_t compat_initfunc;
} ra_libraries[] = {
{
- "neon",
- dav_schemes,
-#ifdef SVN_LIBSVN_CLIENT_LINKS_RA_NEON
- svn_ra_neon__init,
- svn_ra_dav_init
-#endif
- },
-
- {
"svn",
svn_schemes,
#ifdef SVN_LIBSVN_CLIENT_LINKS_RA_SVN
@@ -414,8 +391,7 @@ svn_error_t *svn_ra_open4(svn_ra_session
SVN_CONFIG_OPTION_HTTP_LIBRARY,
DEFAULT_HTTP_LIBRARY);
- if (strcmp(http_library, "neon") != 0 &&
- strcmp(http_library, "serf") != 0)
+ if (strcmp(http_library, "serf") != 0)
return svn_error_createf(SVN_ERR_BAD_CONFIG_VALUE, NULL,
_("Invalid config: unknown HTTP library "
"'%s'"),
@@ -1282,8 +1258,7 @@ svn_ra_get_deleted_rev(svn_ra_session_t
end_revision,
revision_deleted,
pool);
- if (err && (err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE /* serf */
- || err->apr_err == SVN_ERR_RA_NOT_IMPLEMENTED)) /* neon */
+ if (err && (err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE))
{
svn_error_clear(err);
Modified: subversion/branches/ev2-export/subversion/libsvn_ra/ra_loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra/ra_loader.h?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra/ra_loader.h (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra/ra_loader.h Wed Jul 11 10:26:19 2012
@@ -353,9 +353,6 @@ svn_error_t *svn_ra_local__init(const sv
svn_error_t *svn_ra_svn__init(const svn_version_t *loader_version,
const svn_ra__vtable_t **vtable,
apr_pool_t *pool);
-svn_error_t *svn_ra_neon__init(const svn_version_t *loader_version,
- const svn_ra__vtable_t **vtable,
- apr_pool_t *pool);
svn_error_t *svn_ra_serf__init(const svn_version_t *loader_version,
const svn_ra__vtable_t **vtable,
apr_pool_t *pool);
Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/blame.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/blame.c?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/blame.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/blame.c Wed Jul 11 10:26:19 2012
@@ -46,7 +46,6 @@
* This enum represents the current state of our XML parsing for a REPORT.
*/
typedef enum blame_state_e {
- NONE = 0,
INITIAL = 0,
FILE_REVS_REPORT,
FILE_REV,
@@ -57,40 +56,6 @@ typedef enum blame_state_e {
TXDELTA
} blame_state_e;
-typedef struct blame_info_t {
- /* Current pool. */
- apr_pool_t *pool;
-
- /* our suspicious file */
- const char *path;
-
- /* the intended suspect */
- svn_revnum_t rev;
-
- /* Hashtable of revision properties */
- apr_hash_t *rev_props;
-
- /* Added and removed properties (svn_prop_t*'s) */
- apr_array_header_t *prop_diffs;
-
- /* txdelta */
- svn_txdelta_window_handler_t txdelta;
- void *txdelta_baton;
-
- /* returned txdelta stream */
- svn_stream_t *stream;
-
- /* Is this property base64-encoded? */
- svn_boolean_t prop_base64;
-
- /* The currently collected value as we build it up */
- const char *prop_name;
- svn_stringbuf_t *prop_value;
-
- /* Merged revision flag */
- svn_boolean_t merged_revision;
-
-} blame_info_t;
typedef struct blame_context_t {
/* pool passed to get_file_revs */
@@ -102,19 +67,21 @@ typedef struct blame_context_t {
svn_revnum_t end;
svn_boolean_t include_merged_revisions;
- /* are we done? */
- svn_boolean_t done;
-
/* blame handler and baton */
svn_file_rev_handler_t file_rev;
void *file_rev_baton;
-} blame_context_t;
+ /* As we parse each FILE_REV, we collect data in these variables:
+ property changes and new content. STREAM is valid when we're
+ in the TXDELTA state, processing the incoming cdata. */
+ apr_hash_t *rev_props;
+ apr_array_header_t *prop_diffs;
+ apr_pool_t *state_pool; /* put property stuff in here */
+
+ svn_stream_t *stream;
+
+} blame_context_t;
-#if 0
-/* ### we cannot use this yet since the CDATA is unbounded and cannot be
- ### collected by the parsing context. we need a streamy mechanism for
- ### this report. */
#define D_ "DAV:"
#define S_ SVN_XML_NAMESPACE
@@ -125,285 +92,188 @@ static const svn_ra_serf__xml_transition
{ FILE_REVS_REPORT, S_, "file-rev", FILE_REV,
FALSE, { "path", "rev", NULL }, TRUE },
- { FILE_REV, D_, "rev-prop", REV_PROP,
+ { FILE_REV, S_, "rev-prop", REV_PROP,
TRUE, { "name", "?encoding", NULL }, TRUE },
- { FILE_REV, D_, "set-prop", SET_PROP,
+ { FILE_REV, S_, "set-prop", SET_PROP,
TRUE, { "name", "?encoding", NULL }, TRUE },
- { FILE_REV, D_, "remove-prop", REMOVE_PROP,
- FALSE, { "name", "?encoding", NULL }, TRUE },
+ { FILE_REV, S_, "remove-prop", REMOVE_PROP,
+ FALSE, { "name", NULL }, TRUE },
- { FILE_REV, D_, "merged-revision", MERGED_REVISION,
- FALSE, { NULL }, FALSE },
+ { FILE_REV, S_, "merged-revision", MERGED_REVISION,
+ FALSE, { NULL }, TRUE },
- { FILE_REV, D_, "txdelta", TXDELTA,
- TRUE, { NULL }, TRUE },
+ { FILE_REV, S_, "txdelta", TXDELTA,
+ FALSE, { NULL }, TRUE },
{ 0 }
};
-#endif
-
-
-static blame_info_t *
-push_state(svn_ra_serf__xml_parser_t *parser,
- blame_context_t *blame_ctx,
- blame_state_e state)
+/* Conforms to svn_ra_serf__xml_opened_t */
+static svn_error_t *
+blame_opened(svn_ra_serf__xml_estate_t *xes,
+ void *baton,
+ int entered_state,
+ const svn_ra_serf__dav_props_t *tag,
+ apr_pool_t *scratch_pool)
{
- svn_ra_serf__xml_push_state(parser, state);
+ blame_context_t *blame_ctx = baton;
- if (state == FILE_REV)
+ if (entered_state == FILE_REV)
{
- blame_info_t *info;
-
- info = apr_pcalloc(parser->state->pool, sizeof(*info));
-
- info->pool = parser->state->pool;
-
- info->rev = SVN_INVALID_REVNUM;
+ apr_pool_t *state_pool = svn_ra_serf__xml_state_pool(xes);
- info->rev_props = apr_hash_make(info->pool);
- info->prop_diffs = apr_array_make(info->pool, 0, sizeof(svn_prop_t));
-
- info->prop_value = svn_stringbuf_create_empty(info->pool);
-
- parser->state->private = info;
+ /* Child elements will store properties in these structures. */
+ blame_ctx->rev_props = apr_hash_make(state_pool);
+ blame_ctx->prop_diffs = apr_array_make(state_pool,
+ 5, sizeof(svn_prop_t));
+ blame_ctx->state_pool = state_pool;
+
+ /* Clear this, so we can detect the absence of a TXDELTA. */
+ blame_ctx->stream = NULL;
+ }
+ else if (entered_state == TXDELTA)
+ {
+ apr_pool_t *state_pool = svn_ra_serf__xml_state_pool(xes);
+ apr_hash_t *gathered = svn_ra_serf__xml_gather_since(xes, FILE_REV);
+ const char *path;
+ const char *rev;
+ const char *merged_revision;
+ svn_txdelta_window_handler_t txdelta;
+ void *txdelta_baton;
+
+ path = apr_hash_get(gathered, "path", APR_HASH_KEY_STRING);
+ rev = apr_hash_get(gathered, "rev", APR_HASH_KEY_STRING);
+ merged_revision = apr_hash_get(gathered,
+ "merged-revision", APR_HASH_KEY_STRING);
+
+ SVN_ERR(blame_ctx->file_rev(blame_ctx->file_rev_baton,
+ path, SVN_STR_TO_REV(rev),
+ blame_ctx->rev_props,
+ merged_revision != NULL,
+ &txdelta, &txdelta_baton,
+ blame_ctx->prop_diffs,
+ state_pool));
+
+ blame_ctx->stream = svn_base64_decode(svn_txdelta_parse_svndiff(
+ txdelta, txdelta_baton,
+ TRUE /* error_on_early_close */,
+ state_pool),
+ state_pool);
}
- return parser->state->private;
+ return SVN_NO_ERROR;
}
-static const svn_string_t *
-create_propval(blame_info_t *info)
-{
- if (info->prop_base64)
- {
- const svn_string_t *morph;
-
- morph = svn_stringbuf__morph_into_string(info->prop_value);
-#ifdef SVN_DEBUG
- info->prop_value = NULL; /* morph killed the stringbuf. */
-#endif
- return svn_base64_decode_string(morph, info->pool);
- }
-
- return svn_string_create_from_buf(info->prop_value, info->pool);
-}
-
+/* Conforms to svn_ra_serf__xml_closed_t */
static svn_error_t *
-start_blame(svn_ra_serf__xml_parser_t *parser,
- svn_ra_serf__dav_props_t name,
- const char **attrs,
- apr_pool_t *scratch_pool)
+blame_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)
{
- blame_context_t *blame_ctx = parser->user_data;
- blame_state_e state;
+ blame_context_t *blame_ctx = baton;
+
+ if (leaving_state == FILE_REV)
+ {
+ /* Note that we test STREAM, but any pointer is currently invalid.
+ It was closed when left the TXDELTA state. */
+ if (blame_ctx->stream == NULL)
+ {
+ const char *path;
+ const char *rev;
- state = parser->state->current_state;
+ path = apr_hash_get(attrs, "path", APR_HASH_KEY_STRING);
+ rev = apr_hash_get(attrs, "rev", APR_HASH_KEY_STRING);
- if (state == NONE && strcmp(name.name, "file-revs-report") == 0)
+ /* Send a "no content" notification. */
+ SVN_ERR(blame_ctx->file_rev(blame_ctx->file_rev_baton,
+ path, SVN_STR_TO_REV(rev),
+ blame_ctx->rev_props,
+ FALSE /* result_of_merge */,
+ NULL, NULL, /* txdelta / baton */
+ blame_ctx->prop_diffs,
+ scratch_pool));
+ }
+ }
+ else if (leaving_state == MERGED_REVISION)
{
- push_state(parser, blame_ctx, FILE_REVS_REPORT);
+ svn_ra_serf__xml_note(xes, FILE_REV, "merged-revision", "*");
}
- else if (state == FILE_REVS_REPORT &&
- strcmp(name.name, "file-rev") == 0)
+ else if (leaving_state == TXDELTA)
{
- blame_info_t *info;
-
- info = push_state(parser, blame_ctx, FILE_REV);
-
- info->path = apr_pstrdup(info->pool,
- svn_xml_get_attr_value("path", attrs));
- info->rev = SVN_STR_TO_REV(svn_xml_get_attr_value("rev", attrs));
+ SVN_ERR(svn_stream_close(blame_ctx->stream));
}
- else if (state == FILE_REV)
+ else
{
- blame_info_t *info;
- const char *enc;
+ const char *name;
+ const svn_string_t *value;
- info = parser->state->private;
+ SVN_ERR_ASSERT(leaving_state == REV_PROP
+ || leaving_state == SET_PROP
+ || leaving_state == REMOVE_PROP);
- if (strcmp(name.name, "rev-prop") == 0)
- {
- push_state(parser, blame_ctx, REV_PROP);
- }
- else if (strcmp(name.name, "set-prop") == 0)
- {
- push_state(parser, blame_ctx, SET_PROP);
- }
- if (strcmp(name.name, "remove-prop") == 0)
- {
- push_state(parser, blame_ctx, REMOVE_PROP);
- }
- else if (strcmp(name.name, "merged-revision") == 0)
+ name = apr_pstrdup(blame_ctx->state_pool,
+ apr_hash_get(attrs, "name", APR_HASH_KEY_STRING));
+
+ if (leaving_state == REMOVE_PROP)
{
- push_state(parser, blame_ctx, MERGED_REVISION);
+ value = NULL;
}
- else if (strcmp(name.name, "txdelta") == 0)
+ else
{
- SVN_ERR(blame_ctx->file_rev(blame_ctx->file_rev_baton,
- info->path, info->rev,
- info->rev_props, info->merged_revision,
- &info->txdelta, &info->txdelta_baton,
- info->prop_diffs, info->pool));
-
- info->stream = svn_base64_decode
- (svn_txdelta_parse_svndiff(info->txdelta, info->txdelta_baton,
- TRUE, info->pool), info->pool);
+ const char *encoding = apr_hash_get(attrs,
+ "encoding", APR_HASH_KEY_STRING);
- push_state(parser, blame_ctx, TXDELTA);
- }
-
- state = parser->state->current_state;
-
- switch (state)
- {
- case REV_PROP:
- case SET_PROP:
- case REMOVE_PROP:
- info->prop_name = apr_pstrdup(info->pool,
- svn_xml_get_attr_value("name", attrs));
- svn_stringbuf_setempty(info->prop_value);
-
- enc = svn_xml_get_attr_value("encoding", attrs);
- if (enc && strcmp(enc, "base64") == 0)
- {
- info->prop_base64 = TRUE;
- }
+ if (encoding && strcmp(encoding, "base64") == 0)
+ value = svn_base64_decode_string(cdata, blame_ctx->state_pool);
else
- {
- info->prop_base64 = FALSE;
- }
- break;
- case MERGED_REVISION:
- info->merged_revision = TRUE;
- break;
- default:
- break;
+ value = svn_string_dup(cdata, blame_ctx->state_pool);
}
- }
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-end_blame(svn_ra_serf__xml_parser_t *parser,
- svn_ra_serf__dav_props_t name,
- apr_pool_t *scratch_pool)
-{
- blame_context_t *blame_ctx = parser->user_data;
- blame_state_e state;
- blame_info_t *info;
-
- state = parser->state->current_state;
- info = parser->state->private;
-
- if (state == NONE)
- {
- return SVN_NO_ERROR;
- }
-
- if (state == FILE_REVS_REPORT &&
- strcmp(name.name, "file-revs-report") == 0)
- {
- svn_ra_serf__xml_pop_state(parser);
- }
- else if (state == FILE_REV &&
- strcmp(name.name, "file-rev") == 0)
- {
- /* no file changes. */
- if (!info->stream)
+ if (leaving_state == REV_PROP)
{
- SVN_ERR(blame_ctx->file_rev(blame_ctx->file_rev_baton,
- info->path, info->rev,
- info->rev_props, FALSE,
- NULL, NULL,
- info->prop_diffs, info->pool));
+ apr_hash_set(blame_ctx->rev_props, name, APR_HASH_KEY_STRING, value);
}
- svn_ra_serf__xml_pop_state(parser);
- }
- else if (state == REV_PROP &&
- strcmp(name.name, "rev-prop") == 0)
- {
- apr_hash_set(info->rev_props,
- info->prop_name, APR_HASH_KEY_STRING,
- create_propval(info));
-
- svn_ra_serf__xml_pop_state(parser);
- }
- else if ((state == SET_PROP &&
- strcmp(name.name, "set-prop") == 0) ||
- (state == REMOVE_PROP &&
- strcmp(name.name, "remove-prop") == 0))
- {
- svn_prop_t *prop = apr_array_push(info->prop_diffs);
- prop->name = info->prop_name;
- prop->value = create_propval(info);
-
- svn_ra_serf__xml_pop_state(parser);
- }
- else if (state == MERGED_REVISION &&
- strcmp(name.name, "merged-revision") == 0)
- {
- svn_ra_serf__xml_pop_state(parser);
- }
- else if (state == TXDELTA &&
- strcmp(name.name, "txdelta") == 0)
- {
- SVN_ERR(svn_stream_close(info->stream));
+ else
+ {
+ svn_prop_t *prop = apr_array_push(blame_ctx->prop_diffs);
- svn_ra_serf__xml_pop_state(parser);
+ prop->name = name;
+ prop->value = value;
+ }
}
return SVN_NO_ERROR;
}
+
+/* Conforms to svn_ra_serf__xml_cdata_t */
static svn_error_t *
-cdata_blame(svn_ra_serf__xml_parser_t *parser,
+blame_cdata(svn_ra_serf__xml_estate_t *xes,
+ void *baton,
+ int current_state,
const char *data,
apr_size_t len,
apr_pool_t *scratch_pool)
{
- blame_context_t *blame_ctx = parser->user_data;
- blame_state_e state;
- blame_info_t *info;
-
- UNUSED_CTX(blame_ctx);
-
- state = parser->state->current_state;
- info = parser->state->private;
-
- if (state == NONE)
- {
- return SVN_NO_ERROR;
- }
+ blame_context_t *blame_ctx = baton;
- switch (state)
+ if (current_state == TXDELTA)
{
- case REV_PROP:
- case SET_PROP:
- svn_stringbuf_appendbytes(info->prop_value, data, len);
- break;
- case TXDELTA:
- if (info->stream)
- {
- apr_size_t ret_len;
-
- ret_len = len;
-
- SVN_ERR(svn_stream_write(info->stream, data, &ret_len));
- }
- break;
- default:
- break;
+ SVN_ERR(svn_stream_write(blame_ctx->stream, data, &len));
+ /* Ignore the returned LEN value. */
}
return SVN_NO_ERROR;
}
+
/* Implements svn_ra_serf__request_body_delegate_t */
static svn_error_t *
create_file_revs_body(serf_bucket_t **body_bkt,
@@ -460,7 +330,7 @@ svn_ra_serf__get_file_revs(svn_ra_sessio
blame_context_t *blame_ctx;
svn_ra_serf__session_t *session = ra_session->priv;
svn_ra_serf__handler_t *handler;
- svn_ra_serf__xml_parser_t *parser_ctx;
+ svn_ra_serf__xml_context_t *xmlctx;
const char *req_url;
svn_error_t *err;
@@ -472,16 +342,20 @@ svn_ra_serf__get_file_revs(svn_ra_sessio
blame_ctx->start = start;
blame_ctx->end = end;
blame_ctx->include_merged_revisions = include_merged_revisions;
- blame_ctx->done = FALSE;
SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
session, NULL /* conn */,
NULL /* url */, end,
pool, pool));
- handler = apr_pcalloc(pool, sizeof(*handler));
+ xmlctx = svn_ra_serf__xml_context_create(blame_ttable,
+ blame_opened,
+ blame_closed,
+ blame_cdata,
+ blame_ctx,
+ pool);
+ handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
- handler->handler_pool = pool;
handler->method = "REPORT";
handler->path = req_url;
handler->body_type = "text/xml";
@@ -490,21 +364,7 @@ svn_ra_serf__get_file_revs(svn_ra_sessio
handler->conn = session->conns[0];
handler->session = session;
- parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));
-
- parser_ctx->pool = pool;
- parser_ctx->user_data = blame_ctx;
- parser_ctx->start = start_blame;
- parser_ctx->end = end_blame;
- parser_ctx->cdata = cdata_blame;
- parser_ctx->done = &blame_ctx->done;
-
- handler->response_handler = svn_ra_serf__handle_xml_parser;
- handler->response_baton = parser_ctx;
-
- svn_ra_serf__request_create(handler);
-
- err = svn_ra_serf__context_run_wait(&blame_ctx->done, session, pool);
+ err = svn_ra_serf__context_run_one(handler, pool);
err = svn_error_compose_create(
svn_ra_serf__error_on_status(handler->sline.code,
Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/commit.c?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/commit.c Wed Jul 11 10:26:19 2012
@@ -42,22 +42,6 @@
#include "ra_serf.h"
#include "../libsvn_ra/ra_loader.h"
-
-/* Structure associated with a CHECKOUT request. */
-typedef struct checkout_context_t {
- /* The handler running the CHECKOUT. */
- svn_ra_serf__handler_t *handler;
-
- /* The pool for allocating RESOURCE_URL. */
- apr_pool_t *result_pool;
-
- /* The activity that will hold the checked-out resource. */
- const char *activity_url;
-
- /* The output: */
- const char *resource_url;
-
-} checkout_context_t;
/* Baton passed back with the commit editor. */
typedef struct commit_context_t {
@@ -250,7 +234,7 @@ create_checkout_body(serf_bucket_t **bkt
serf_bucket_alloc_t *alloc,
apr_pool_t *pool)
{
- checkout_context_t *ctx = baton;
+ const char *activity_url = baton;
serf_bucket_t *body_bkt;
body_bkt = serf_bucket_aggregate_create(alloc);
@@ -262,10 +246,10 @@ create_checkout_body(serf_bucket_t **bkt
svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:activity-set", NULL);
svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:href", NULL);
- SVN_ERR_ASSERT(ctx->activity_url != NULL);
+ SVN_ERR_ASSERT(activity_url != NULL);
svn_ra_serf__add_cdata_len_buckets(body_bkt, alloc,
- ctx->activity_url,
- strlen(ctx->activity_url));
+ activity_url,
+ strlen(activity_url));
svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:href");
svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:activity-set");
@@ -276,53 +260,6 @@ create_checkout_body(serf_bucket_t **bkt
return SVN_NO_ERROR;
}
-/* Implements svn_ra_serf__response_handler_t */
-static svn_error_t *
-handle_checkout(serf_request_t *request,
- serf_bucket_t *response,
- void *baton,
- apr_pool_t *pool)
-{
- checkout_context_t *ctx = baton;
- svn_ra_serf__handler_t *handler = ctx->handler;
-
- svn_error_t *err = svn_ra_serf__expect_empty_body(request, response,
- handler, pool);
-
- /* These handler functions are supposed to return an APR_EOF status
- wrapped in a svn_error_t to indicate to serf that the response was
- completely read. While we have to return this status code to our
- caller, we should treat it as the normal case for now. */
- if (err && ! APR_STATUS_IS_EOF(err->apr_err))
- return err;
-
- /* Get the resulting location. */
- if (handler->done && handler->sline.code == 201)
- {
- serf_bucket_t *hdrs;
- apr_uri_t uri;
- const char *location;
- apr_status_t status;
-
- hdrs = serf_bucket_response_get_headers(response);
- location = serf_bucket_headers_get(hdrs, "Location");
- if (!location)
- return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, err,
- _("No Location header received"));
-
- status = apr_uri_parse(pool, location, &uri);
-
- if (status)
- err = svn_error_compose_create(svn_error_wrap_apr(status, NULL), err);
-
- SVN_ERR_ASSERT(ctx->result_pool != NULL);
- ctx->resource_url = svn_urlpath__canonicalize(uri.path,
- ctx->result_pool);
- }
-
- return err;
-}
-
/* Using the HTTPv1 protocol, perform a CHECKOUT of NODE_URL within the
given COMMIT_CTX. The resulting working resource will be returned in
@@ -351,7 +288,6 @@ checkout_node(const char **working_url,
apr_pool_t *scratch_pool)
{
svn_ra_serf__handler_t handler = { 0 };
- checkout_context_t checkout_ctx = { 0 };
/* HANDLER_POOL is the scratch pool since we don't need to remember
anything from the handler. We just want the working resource. */
@@ -359,16 +295,12 @@ checkout_node(const char **working_url,
handler.session = commit_ctx->session;
handler.conn = commit_ctx->conn;
- checkout_ctx.handler = &handler;
- checkout_ctx.result_pool = result_pool;
- checkout_ctx.activity_url = commit_ctx->activity_url;
-
handler.body_delegate = create_checkout_body;
- handler.body_delegate_baton = &checkout_ctx;
+ handler.body_delegate_baton = (/* const */ void *)commit_ctx->activity_url;
handler.body_type = "text/xml";
- handler.response_handler = handle_checkout;
- handler.response_baton = &checkout_ctx;
+ handler.response_handler = svn_ra_serf__expect_empty_body;
+ handler.response_baton = &handler;
handler.method = "CHECKOUT";
handler.path = node_url;
@@ -378,8 +310,11 @@ checkout_node(const char **working_url,
if (handler.sline.code != 201)
return svn_error_trace(return_response_err(&handler));
- /* Already in the correct pool. */
- *working_url = checkout_ctx.resource_url;
+ if (handler.location == NULL)
+ return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
+ _("No Location header received"));
+
+ *working_url = apr_pstrdup(result_pool, handler.location);
return SVN_NO_ERROR;
}
Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/options.c?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/options.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/options.c Wed Jul 11 10:26:19 2012
@@ -450,9 +450,7 @@ svn_ra_serf__has_capability(svn_ra_sessi
cap_result = apr_hash_get(serf_sess->capabilities,
capability, APR_HASH_KEY_STRING);
- /* Some capabilities depend on the repository as well as the server.
- NOTE: svn_ra_neon__has_capability() has a very similar code block. If
- you change something here, check there as well. */
+ /* Some capabilities depend on the repository as well as the server. */
if (cap_result == capability_server_yes)
{
if (strcmp(capability, SVN_RA_CAPABILITY_MERGEINFO) == 0)
Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c Wed Jul 11 10:26:19 2012
@@ -41,28 +41,23 @@
/* Our current parsing state we're in for the PROPFIND response. */
typedef enum prop_state_e {
- NONE = 0,
+ INITIAL = 0,
+ MULTISTATUS,
RESPONSE,
+ HREF,
+ PROPSTAT,
+ STATUS,
PROP,
- PROPVAL
+ PROPVAL,
+ COLLECTION,
+ HREF_VALUE
} prop_state_e;
-typedef struct prop_info_t {
- apr_pool_t *pool;
-
- /* Current ns, attribute name, and value of the property we're parsing */
- const char *ns;
- const char *name;
- svn_stringbuf_t *value;
-
- const char *encoding;
-
-} prop_info_t;
/*
* This structure represents a pending PROPFIND response.
*/
-struct svn_ra_serf__propfind_context_t {
+typedef struct propfind_context_t {
/* pool to issue allocations from */
apr_pool_t *pool;
@@ -87,29 +82,273 @@ struct svn_ra_serf__propfind_context_t {
/* hash table that will be updated with the properties
*
- * This can be shared between multiple svn_ra_serf__propfind_context_t
+ * This can be shared between multiple propfind_context_t
* structures
*/
apr_hash_t *ret_props;
- /* If we're dealing with a Depth: 1 response,
- * we may be dealing with multiple paths.
+ /* hash table containing all the properties associated with the
+ * "current" <propstat> tag. These will get copied into RET_PROPS
+ * if the status code similarly associated indicates that they are
+ * "good"; otherwise, they'll get discarded.
*/
- const char *current_path;
-
- /* Are we done issuing the PROPFIND? */
- svn_boolean_t done;
-
- /* Context from XML stream */
- svn_ra_serf__xml_parser_t *parser_ctx;
+ apr_hash_t *ps_props;
/* If not-NULL, add us to this list when we're done. */
svn_ra_serf__list_t **done_list;
svn_ra_serf__list_t done_item;
+
+} propfind_context_t;
+
+
+#define D_ "DAV:"
+#define S_ SVN_XML_NAMESPACE
+static const svn_ra_serf__xml_transition_t propfind_ttable[] = {
+ { INITIAL, D_, "multistatus", MULTISTATUS,
+ FALSE, { NULL }, TRUE },
+
+ { MULTISTATUS, D_, "response", RESPONSE,
+ FALSE, { NULL }, FALSE },
+
+ { RESPONSE, D_, "href", HREF,
+ TRUE, { NULL }, TRUE },
+
+ { RESPONSE, D_, "propstat", PROPSTAT,
+ FALSE, { NULL }, TRUE },
+
+ { PROPSTAT, D_, "status", STATUS,
+ TRUE, { NULL }, TRUE },
+
+ { PROPSTAT, D_, "prop", PROP,
+ FALSE, { NULL }, FALSE },
+
+ { PROP, "*", "*", PROPVAL,
+ TRUE, { "?V:encoding", NULL }, TRUE },
+
+ { PROPVAL, D_, "collection", COLLECTION,
+ FALSE, { NULL }, TRUE },
+
+ { PROPVAL, D_, "href", HREF_VALUE,
+ TRUE, { NULL }, TRUE },
+
+ { 0 }
};
+/* Return the HTTP status code contained in STATUS_LINE, or 0 if
+ there's a problem parsing it. */
+static int parse_status_code(const char *status_line)
+{
+ /* STATUS_LINE should be of form: "HTTP/1.1 200 OK" */
+ if (status_line[0] == 'H' &&
+ status_line[1] == 'T' &&
+ status_line[2] == 'T' &&
+ status_line[3] == 'P' &&
+ status_line[4] == '/' &&
+ (status_line[5] >= '0' && status_line[5] <= '9') &&
+ status_line[6] == '.' &&
+ (status_line[7] >= '0' && status_line[7] <= '9') &&
+ status_line[8] == ' ')
+ {
+ char *reason;
+
+ return apr_strtoi64(status_line + 8, &reason, 10);
+ }
+ return 0;
+}
+
+
+/* Conforms to svn_ra_serf__path_rev_walker_t */
+static svn_error_t *
+copy_into_ret_props(void *baton,
+ const char *path, apr_ssize_t path_len,
+ const char *ns, apr_ssize_t ns_len,
+ const char *name, apr_ssize_t name_len,
+ const svn_string_t *val,
+ apr_pool_t *pool)
+{
+ propfind_context_t *ctx = baton;
+
+ svn_ra_serf__set_ver_prop(ctx->ret_props, path, ctx->rev, ns, name,
+ val, ctx->pool);
+ return SVN_NO_ERROR;
+}
+
+
+/* Conforms to svn_ra_serf__xml_opened_t */
+static svn_error_t *
+propfind_opened(svn_ra_serf__xml_estate_t *xes,
+ void *baton,
+ int entered_state,
+ const svn_ra_serf__dav_props_t *tag,
+ apr_pool_t *scratch_pool)
+{
+ propfind_context_t *ctx = baton;
+
+ if (entered_state == PROPVAL)
+ {
+ svn_ra_serf__xml_note(xes, PROPVAL, "ns", tag->namespace);
+ svn_ra_serf__xml_note(xes, PROPVAL, "name", tag->name);
+ }
+ else if (entered_state == PROPSTAT)
+ {
+ ctx->ps_props = apr_hash_make(ctx->pool);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+
+/* Conforms to svn_ra_serf__xml_closed_t */
+static svn_error_t *
+propfind_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)
+{
+ propfind_context_t *ctx = baton;
+
+ if (leaving_state == MULTISTATUS)
+ {
+ /* We've gathered all the data from the reponse. Add this item
+ onto the "done list". External callers will then know this
+ request has been completed (tho stray response bytes may still
+ arrive). */
+ if (ctx->done_list)
+ {
+ ctx->done_item.data = ctx->handler;
+ ctx->done_item.next = *ctx->done_list;
+ *ctx->done_list = &ctx->done_item;
+ }
+ }
+ else if (leaving_state == HREF)
+ {
+ const char *path;
+ const svn_string_t *val_str;
+
+ if (strcmp(ctx->depth, "1") == 0)
+ path = svn_urlpath__canonicalize(cdata->data, scratch_pool);
+ else
+ path = ctx->path;
+
+ svn_ra_serf__xml_note(xes, RESPONSE, "path", path);
+
+ /* Copy the value into the right pool, then save the HREF. */
+ val_str = svn_string_dup(cdata, ctx->pool);
+ svn_ra_serf__set_ver_prop(ctx->ret_props,
+ path, ctx->rev, D_, "href", val_str,
+ ctx->pool);
+ }
+ else if (leaving_state == COLLECTION)
+ {
+ svn_ra_serf__xml_note(xes, PROPVAL, "altvalue", "collection");
+ }
+ else if (leaving_state == HREF_VALUE)
+ {
+ svn_ra_serf__xml_note(xes, PROPVAL, "altvalue", cdata->data);
+ }
+ else if (leaving_state == STATUS)
+ {
+ /* Parse the status field, and remember if this is a property
+ that we wish to ignore. (Typically, if it's not a 200, the
+ status will be 404 to indicate that a property we
+ specifically requested from the server doesn't exist.) */
+ int status = parse_status_code(cdata->data);
+ if (status != 200)
+ svn_ra_serf__xml_note(xes, PROPSTAT, "ignore-prop", "*");
+ }
+ else if (leaving_state == PROPVAL)
+ {
+ const char *encoding = apr_hash_get(attrs, "V:encoding",
+ APR_HASH_KEY_STRING);
+ const svn_string_t *val_str;
+ apr_hash_t *gathered;
+ const char *path;
+ const char *ns;
+ const char *name;
+ const char *altvalue;
+
+ if (encoding)
+ {
+ if (strcmp(encoding, "base64") != 0)
+ return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA,
+ NULL,
+ _("Got unrecognized encoding '%s'"),
+ encoding);
+
+ /* Decode into the right pool. */
+ val_str = svn_base64_decode_string(cdata, ctx->pool);
+ }
+ else
+ {
+ /* Copy into the right pool. */
+ val_str = svn_string_dup(cdata, ctx->pool);
+ }
+
+ /* The current path sits on the RESPONSE state. Gather up all the
+ state from this PROPVAL to the (grandparent) RESPONSE state,
+ and grab the path from there.
+
+ Now, it would be nice if we could, at this point, know that
+ the status code for this property indicated a problem -- then
+ we could simply bail out here and ignore the property.
+ Sadly, though, we might get the status code *after* we get
+ the property value. So we'll carry on with our processing
+ here, setting the property and value as expected. Once we
+ know for sure the status code associate with the property,
+ we'll decide its fate. */
+ gathered = svn_ra_serf__xml_gather_since(xes, RESPONSE);
+
+ /* These will be dup'd into CTX->POOL, as necessary. */
+ path = apr_hash_get(gathered, "path", APR_HASH_KEY_STRING);
+ if (path == NULL)
+ path = ctx->path;
+
+ ns = apr_hash_get(attrs, "ns", APR_HASH_KEY_STRING);
+ name = apr_pstrdup(ctx->pool,
+ apr_hash_get(attrs, "name", APR_HASH_KEY_STRING));
+
+ altvalue = apr_hash_get(attrs, "altvalue", APR_HASH_KEY_STRING);
+ if (altvalue != NULL)
+ val_str = svn_string_create(altvalue, ctx->pool);
+
+ svn_ra_serf__set_ver_prop(ctx->ps_props,
+ path, ctx->rev, ns, name, val_str,
+ ctx->pool);
+ }
+ else
+ {
+ apr_hash_t *gathered;
+ const char *path;
+
+ SVN_ERR_ASSERT(leaving_state == PROPSTAT);
+
+ gathered = svn_ra_serf__xml_gather_since(xes, PROPSTAT);
+
+ path = apr_hash_get(gathered, "path", APR_HASH_KEY_STRING);
+ if (path == NULL)
+ path = ctx->path;
+
+ /* If we've squirreled away a note that says we want to ignore
+ these properties, we'll do so. Otherwise, we need to copy
+ them from the temporary hash into the ctx->ret_props hash. */
+ if (! apr_hash_get(gathered, "ignore-prop", APR_HASH_KEY_STRING))
+ {
+ SVN_ERR(svn_ra_serf__walk_all_paths(ctx->ps_props, ctx->rev,
+ copy_into_ret_props, ctx,
+ scratch_pool));
+ }
+
+ ctx->ps_props = NULL;
+ }
+
+ return SVN_NO_ERROR;
+}
+
+
const svn_string_t *
svn_ra_serf__get_ver_prop_string(apr_hash_t *props,
const char *path,
@@ -226,197 +465,15 @@ svn_ra_serf__set_prop(apr_hash_t *props,
val, pool);
}
-static prop_info_t *
-push_state(svn_ra_serf__xml_parser_t *parser,
- svn_ra_serf__propfind_context_t *propfind,
- prop_state_e state)
-{
- svn_ra_serf__xml_push_state(parser, state);
-
- if (state == PROPVAL)
- {
- prop_info_t *info;
-
- info = apr_pcalloc(parser->state->pool, sizeof(*info));
- info->pool = parser->state->pool;
- info->value = svn_stringbuf_create_empty(info->pool);
-
- parser->state->private = info;
- }
-
- return parser->state->private;
-}
-
-/*
- * Expat callback invoked on a start element tag for a PROPFIND response.
- */
-static svn_error_t *
-start_propfind(svn_ra_serf__xml_parser_t *parser,
- svn_ra_serf__dav_props_t name,
- const char **attrs,
- apr_pool_t *scratch_pool)
-{
- svn_ra_serf__propfind_context_t *ctx = parser->user_data;
- prop_state_e state;
- prop_info_t *info;
-
- state = parser->state->current_state;
-
- if (state == NONE && strcmp(name.name, "response") == 0)
- {
- svn_ra_serf__xml_push_state(parser, RESPONSE);
- }
- else if (state == RESPONSE && strcmp(name.name, "href") == 0)
- {
- info = push_state(parser, ctx, PROPVAL);
- info->ns = name.namespace;
- info->name = "href";
- }
- else if (state == RESPONSE && strcmp(name.name, "prop") == 0)
- {
- push_state(parser, ctx, PROP);
- }
- else if (state == PROP)
- {
- info = push_state(parser, ctx, PROPVAL);
- info->ns = name.namespace;
- info->name = apr_pstrdup(info->pool, name.name);
- info->encoding = apr_pstrdup(info->pool,
- svn_xml_get_attr_value("V:encoding", attrs));
- }
-
- return SVN_NO_ERROR;
-}
-
-/*
- * Expat callback invoked on an end element tag for a PROPFIND response.
- */
-static svn_error_t *
-end_propfind(svn_ra_serf__xml_parser_t *parser,
- svn_ra_serf__dav_props_t name,
- apr_pool_t *scratch_pool)
-{
- svn_ra_serf__propfind_context_t *ctx = parser->user_data;
- prop_state_e state;
- prop_info_t *info;
-
- state = parser->state->current_state;
- info = parser->state->private;
-
- if (state == RESPONSE && strcmp(name.name, "response") == 0)
- {
- svn_ra_serf__xml_pop_state(parser);
- }
- else if (state == PROP && strcmp(name.name, "prop") == 0)
- {
- svn_ra_serf__xml_pop_state(parser);
- }
- else if (state == PROPVAL)
- {
- const char *ns;
- const char *pname;
- const svn_string_t *val_str = NULL;
-
- /* if we didn't see a CDATA element, we may want the tag name
- * as long as it isn't equivalent to the property name.
- */
- /* ### gstein sez: I have no idea what this is about. */
- if (*info->value->data == '\0')
- {
- if (strcmp(info->name, name.name) != 0)
- val_str = svn_string_create(name.name, ctx->pool);
- else
- val_str = svn_string_create_empty(ctx->pool);
- }
-
- if (parser->state->prev->current_state == RESPONSE &&
- strcmp(name.name, "href") == 0)
- {
- if (strcmp(ctx->depth, "1") == 0)
- {
- ctx->current_path =
- svn_urlpath__canonicalize(info->value->data, ctx->pool);
- }
- else
- {
- ctx->current_path = ctx->path;
- }
- }
- else if (info->encoding)
- {
- if (strcmp(info->encoding, "base64") == 0)
- {
- const svn_string_t *morph;
-
- morph = svn_stringbuf__morph_into_string(info->value);
-#ifdef SVN_DEBUG
- info->value = NULL; /* morph killed the stringbuf. */
-#endif
- val_str = svn_base64_decode_string(morph, ctx->pool);
- }
- else
- {
- return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA,
- NULL,
- _("Got unrecognized encoding '%s'"),
- info->encoding);
- }
- }
-
- /* ### there may be better logic to ensure this is set above, but just
- ### going for the easy win here. */
- if (val_str == NULL)
- val_str = svn_string_create_from_buf(info->value, ctx->pool);
-
- ns = apr_pstrdup(ctx->pool, info->ns);
- pname = apr_pstrdup(ctx->pool, info->name);
-
- /* set the return props and update our cache too. */
- svn_ra_serf__set_ver_prop(ctx->ret_props,
- ctx->current_path, ctx->rev,
- ns, pname, val_str,
- ctx->pool);
-
- svn_ra_serf__xml_pop_state(parser);
- }
-
- return SVN_NO_ERROR;
-}
-
-/*
- * Expat callback invoked on CDATA elements in a PROPFIND response.
- *
- * This callback can be called multiple times.
- */
-static svn_error_t *
-cdata_propfind(svn_ra_serf__xml_parser_t *parser,
- const char *data,
- apr_size_t len,
- apr_pool_t *scratch_pool)
-{
- svn_ra_serf__propfind_context_t *ctx = parser->user_data;
- prop_state_e state;
- prop_info_t *info;
-
- UNUSED_CTX(ctx);
-
- state = parser->state->current_state;
- info = parser->state->private;
-
- if (state == PROPVAL)
- svn_stringbuf_appendbytes(info->value, data, len);
-
- return SVN_NO_ERROR;
-}
static svn_error_t *
setup_propfind_headers(serf_bucket_t *headers,
void *setup_baton,
apr_pool_t *pool)
{
- svn_ra_serf__propfind_context_t *ctx = setup_baton;
+ propfind_context_t *ctx = setup_baton;
- if (ctx->conn->using_compression)
+ if (ctx->sess->using_compression)
{
serf_bucket_headers_setn(headers, "Accept-Encoding", "gzip");
}
@@ -438,7 +495,7 @@ create_propfind_body(serf_bucket_t **bkt
serf_bucket_alloc_t *alloc,
apr_pool_t *pool)
{
- svn_ra_serf__propfind_context_t *ctx = setup_baton;
+ propfind_context_t *ctx = setup_baton;
serf_bucket_t *body_bkt, *tmp;
const svn_ra_serf__dav_props_t *prop;
@@ -511,7 +568,7 @@ create_propfind_body(serf_bucket_t **bkt
svn_error_t *
-svn_ra_serf__deliver_props(svn_ra_serf__propfind_context_t **prop_ctx,
+svn_ra_serf__deliver_props(svn_ra_serf__handler_t **propfind_handler,
apr_hash_t *ret_props,
svn_ra_serf__session_t *sess,
svn_ra_serf__connection_t *conn,
@@ -522,9 +579,9 @@ svn_ra_serf__deliver_props(svn_ra_serf__
svn_ra_serf__list_t **done_list,
apr_pool_t *pool)
{
- svn_ra_serf__propfind_context_t *new_prop_ctx;
+ propfind_context_t *new_prop_ctx;
svn_ra_serf__handler_t *handler;
- svn_ra_serf__xml_parser_t *parser_ctx;
+ svn_ra_serf__xml_context_t *xmlctx;
new_prop_ctx = apr_pcalloc(pool, sizeof(*new_prop_ctx));
@@ -533,7 +590,6 @@ svn_ra_serf__deliver_props(svn_ra_serf__
new_prop_ctx->find_props = find_props;
new_prop_ctx->ret_props = ret_props;
new_prop_ctx->depth = depth;
- new_prop_ctx->done = FALSE;
new_prop_ctx->sess = sess;
new_prop_ctx->conn = conn;
new_prop_ctx->rev = rev;
@@ -548,9 +604,14 @@ svn_ra_serf__deliver_props(svn_ra_serf__
new_prop_ctx->label = NULL;
}
- handler = apr_pcalloc(pool, sizeof(*handler));
+ xmlctx = svn_ra_serf__xml_context_create(propfind_ttable,
+ propfind_opened,
+ propfind_closed,
+ NULL,
+ new_prop_ctx,
+ pool);
+ handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
- handler->handler_pool = pool;
handler->method = "PROPFIND";
handler->path = path;
handler->body_delegate = create_propfind_body;
@@ -564,51 +625,28 @@ svn_ra_serf__deliver_props(svn_ra_serf__
new_prop_ctx->handler = handler;
- parser_ctx = apr_pcalloc(pool, sizeof(*new_prop_ctx->parser_ctx));
- parser_ctx->pool = pool;
- parser_ctx->user_data = new_prop_ctx;
- parser_ctx->start = start_propfind;
- parser_ctx->end = end_propfind;
- parser_ctx->cdata = cdata_propfind;
- parser_ctx->done = &new_prop_ctx->done;
- parser_ctx->done_list = new_prop_ctx->done_list;
- parser_ctx->done_item = &new_prop_ctx->done_item;
-
- new_prop_ctx->parser_ctx = parser_ctx;
-
- handler->response_handler = svn_ra_serf__handle_xml_parser;
- handler->response_baton = parser_ctx;
-
- /* create request */
- svn_ra_serf__request_create(new_prop_ctx->handler);
-
- *prop_ctx = new_prop_ctx;
+ *propfind_handler = handler;
return SVN_NO_ERROR;
}
-svn_boolean_t
-svn_ra_serf__propfind_is_done(svn_ra_serf__propfind_context_t *ctx)
-{
- return ctx->done;
-}
-
/*
* This helper function will block until the PROP_CTX indicates that is done
* or another error is returned.
*/
svn_error_t *
-svn_ra_serf__wait_for_props(svn_ra_serf__propfind_context_t *prop_ctx,
- svn_ra_serf__session_t *sess,
- apr_pool_t *pool)
+svn_ra_serf__wait_for_props(svn_ra_serf__handler_t *handler,
+ apr_pool_t *scratch_pool)
{
- svn_error_t *err, *err2;
+ svn_error_t *err;
+ svn_error_t *err2;
- err = svn_ra_serf__context_run_wait(&prop_ctx->done, sess, pool);
+ err = svn_ra_serf__context_run_one(handler, scratch_pool);
- err2 = svn_ra_serf__error_on_status(prop_ctx->handler->sline.code,
- prop_ctx->path, NULL);
+ err2 = svn_ra_serf__error_on_status(handler->sline.code,
+ handler->path,
+ NULL);
if (err2)
{
svn_error_clear(err);
@@ -632,13 +670,13 @@ svn_ra_serf__retrieve_props(apr_hash_t *
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- svn_ra_serf__propfind_context_t *prop_ctx;
+ svn_ra_serf__handler_t *handler;
*results = apr_hash_make(result_pool);
- SVN_ERR(svn_ra_serf__deliver_props(&prop_ctx, *results, sess, conn, url,
+ SVN_ERR(svn_ra_serf__deliver_props(&handler, *results, sess, conn, url,
rev, depth, props, NULL, result_pool));
- SVN_ERR(svn_ra_serf__wait_for_props(prop_ctx, sess, result_pool));
+ SVN_ERR(svn_ra_serf__wait_for_props(handler, scratch_pool));
return SVN_NO_ERROR;
}
Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h Wed Jul 11 10:26:19 2012
@@ -71,22 +71,11 @@ typedef struct svn_ra_serf__connection_t
/* Our connection to a server. */
serf_connection_t *conn;
- /* The server is not Apache/mod_dav_svn (directly) and only supports
- HTTP/1.0. Thus, we cannot send chunked requests. */
- svn_boolean_t http10;
-
/* Bucket allocator for this connection. */
serf_bucket_alloc_t *bkt_alloc;
- /* Host name */
- const char *hostname;
-
- /* Are we using ssl */
- svn_boolean_t using_ssl;
- int server_cert_failures; /* Collected cert failures in chain */
-
- /* Should we ask for compressed responses? */
- svn_boolean_t using_compression;
+ /* Collected cert failures in chain. */
+ int server_cert_failures;
/* What was the last HTTP status code we got on this connection? */
int last_status_code;
@@ -98,11 +87,11 @@ typedef struct svn_ra_serf__connection_t
svn_ra_serf__session_t *session;
- /* user agent string */
- const char *useragent;
-
} svn_ra_serf__connection_t;
+/** Max. number of connctions we'll open to the server. */
+#define MAX_NR_OF_CONNS 4
+
/*
* The master serf RA session.
*
@@ -121,8 +110,11 @@ struct svn_ra_serf__session_t {
/* Should we ask for compressed responses? */
svn_boolean_t using_compression;
+ /* The user agent string */
+ const char *useragent;
+
/* The current connection */
- svn_ra_serf__connection_t **conns;
+ svn_ra_serf__connection_t *conns[MAX_NR_OF_CONNS];
int num_conns;
int cur_conn;
@@ -134,6 +126,10 @@ struct svn_ra_serf__session_t {
apr_uri_t repos_root;
const char *repos_root_str;
+ /* The server is not Apache/mod_dav_svn (directly) and only supports
+ HTTP/1.0. Thus, we cannot send chunked requests. */
+ svn_boolean_t http10;
+
/* Our Version-Controlled-Configuration; may be NULL until we know it. */
const char *vcc_url;
@@ -186,7 +182,7 @@ struct svn_ra_serf__session_t {
const char *uuid;
/* Connection timeout value */
- long timeout;
+ apr_short_interval_time_t timeout;
/* HTTPv1 flags */
svn_tristate_t supports_deadprop_count;
@@ -286,6 +282,13 @@ static const svn_ra_serf__dav_props_t ch
{ NULL }
};
+static const svn_ra_serf__dav_props_t type_and_checksum_props[] =
+{
+ { "DAV:", "resourcetype" },
+ { SVN_DAV_PROP_NS_DAV, "sha1-checksum" },
+ { NULL }
+};
+
/* WC props compatibility with ra_neon. */
#define SVN_RA_SERF__WC_CHECKED_IN_URL SVN_PROP_WC_PREFIX "ra_dav:version-url"
@@ -659,13 +662,18 @@ typedef svn_error_t *
apr_pool_t *scratch_pool);
-/* ### TBD */
+/* Called for all states that are not using the builtin cdata collection.
+ This callback is (only) appropriate for unbounded-size cdata content.
+
+ CURRENT_STATE may be used to decide what to do with the data.
+
+ Temporary allocations may be made in SCRATCH_POOL. */
typedef svn_error_t *
(*svn_ra_serf__xml_cdata_t)(svn_ra_serf__xml_estate_t *xes,
void *baton,
int current_state,
const char *data,
- apr_size_t *len,
+ apr_size_t len,
apr_pool_t *scratch_pool);
@@ -708,7 +716,22 @@ typedef struct svn_ra_serf__xml_transiti
} svn_ra_serf__xml_transition_t;
-/* ### docco */
+/* Construct an XML parsing context, based on the TTABLE transition table.
+ As content is parsed, the CLOSED_CB callback will be invoked according
+ to the definition in the table.
+
+ If OPENED_CB is not NULL, then it will be invoked for *every* tag-open
+ event. The callback will need to use the ENTERED_STATE and TAG parameters
+ to decide what it would like to do.
+
+ If CDATA_CB is not NULL, then it will be called for all cdata that is
+ not be automatically collected (based on the transition table record's
+ COLLECT_CDATA flag). It will be called in every state, so the callback
+ must examine the CURRENT_STATE parameter to decide what to do.
+
+ The same BATON value will be passed to all three callbacks.
+
+ The context will be created within RESULT_POOL. */
svn_ra_serf__xml_context_t *
svn_ra_serf__xml_context_create(
const svn_ra_serf__xml_transition_t *ttable,
@@ -718,6 +741,10 @@ svn_ra_serf__xml_context_create(
void *baton,
apr_pool_t *result_pool);
+/* Destroy all subpools for this structure. */
+void
+svn_ra_serf__xml_context_destroy(
+ svn_ra_serf__xml_context_t *xmlctx);
/* Construct a handler with the response function/baton set up to parse
a response body using the given XML context. The handler and its
@@ -729,8 +756,8 @@ svn_ra_serf__create_expat_handler(svn_ra
apr_pool_t *result_pool);
-/* Allocated within XES->STATE_POOL. Changes are not allowd. Make a deep
- copy, as appropriate.
+/* Allocated within XES->STATE_POOL. Changes are not allowd (callers
+ should make a deep copy if they need to make changes).
The resulting hash maps char* names to char* values. */
apr_hash_t *
@@ -757,7 +784,10 @@ svn_ra_serf__xml_note(svn_ra_serf__xml_e
/* Returns XES->STATE_POOL for allocating structures that should live
- as long as the state identified by XES. */
+ as long as the state identified by XES.
+
+ Note: a state pool is created upon demand, so only use this function
+ when memory is required for a given state. */
apr_pool_t *
svn_ra_serf__xml_state_pool(svn_ra_serf__xml_estate_t *xes);
@@ -894,12 +924,6 @@ svn_ra_serf__response_discard_handler(se
void *baton,
apr_pool_t *pool);
-/* Return the value of the RESPONSE's Location header if any, or NULL
- * otherwise. All allocations will be made in POOL.
- */
-const char *
-svn_ra_serf__response_get_location(serf_bucket_t *response,
- apr_pool_t *pool);
/** XML helper functions. **/
@@ -1007,16 +1031,6 @@ svn_ra_serf__expand_ns(svn_ra_serf__dav_
/** PROPFIND-related functions **/
-/* Opaque structure representing PROPFINDs. */
-typedef struct svn_ra_serf__propfind_context_t svn_ra_serf__propfind_context_t;
-
-/*
- * Returns a flag representing whether the PROPFIND @a ctx is completed.
- */
-svn_boolean_t
-svn_ra_serf__propfind_is_done(svn_ra_serf__propfind_context_t *ctx);
-
-
/*
* This function will deliver a PROP_CTX PROPFIND request in the SESS
* serf context for the properties listed in LOOKUP_PROPS at URL for
@@ -1026,7 +1040,7 @@ svn_ra_serf__propfind_is_done(svn_ra_ser
* expected to call svn_ra_serf__wait_for_props().
*/
svn_error_t *
-svn_ra_serf__deliver_props(svn_ra_serf__propfind_context_t **prop_ctx,
+svn_ra_serf__deliver_props(svn_ra_serf__handler_t **propfind_handler,
apr_hash_t *prop_vals,
svn_ra_serf__session_t *sess,
svn_ra_serf__connection_t *conn,
@@ -1038,13 +1052,12 @@ svn_ra_serf__deliver_props(svn_ra_serf__
apr_pool_t *pool);
/*
- * This helper function will block until the PROP_CTX indicates that is done
- * or another error is returned.
+ * This helper function will block until PROPFIND_HANDLER indicates that is
+ * done or another error is returned.
*/
svn_error_t *
-svn_ra_serf__wait_for_props(svn_ra_serf__propfind_context_t *prop_ctx,
- svn_ra_serf__session_t *sess,
- apr_pool_t *pool);
+svn_ra_serf__wait_for_props(svn_ra_serf__handler_t *handler,
+ apr_pool_t *scratch_pool);
/* This is a blocking version of deliver_props.
Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/replay.c?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/replay.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/replay.c Wed Jul 11 10:26:19 2012
@@ -129,7 +129,7 @@ typedef struct replay_context_t {
svn_ra_serf__xml_parser_t *parser_ctx;
/* The propfind for the revision properties of the current revision */
- svn_ra_serf__propfind_context_t *prop_ctx;
+ svn_ra_serf__handler_t *propfind_handler;
} replay_context_t;
@@ -188,8 +188,7 @@ start_replay(svn_ra_serf__xml_parser_t *
push_state(parser, ctx, REPORT);
/* Before we can continue, we need the revision properties. */
- SVN_ERR_ASSERT(!ctx->prop_ctx
- || svn_ra_serf__propfind_is_done(ctx->prop_ctx));
+ SVN_ERR_ASSERT(!ctx->propfind_handler || ctx->propfind_handler->done);
/* Create a pool for the commit editor. */
ctx->dst_rev_pool = svn_pool_create(ctx->src_rev_pool);
@@ -781,7 +780,7 @@ svn_ra_serf__replay_range(svn_ra_session
replay_ctx->revprop_rev = rev;
}
- SVN_ERR(svn_ra_serf__deliver_props(&replay_ctx->prop_ctx,
+ SVN_ERR(svn_ra_serf__deliver_props(&replay_ctx->propfind_handler,
replay_ctx->revs_props, session,
session->conns[0],
replay_ctx->revprop_target,
@@ -790,6 +789,9 @@ svn_ra_serf__replay_range(svn_ra_session
NULL,
replay_ctx->src_rev_pool));
+ /* Spin up the serf request for the PROPFIND. */
+ svn_ra_serf__request_create(replay_ctx->propfind_handler);
+
/* Send the replay report request. */
handler = apr_pcalloc(replay_ctx->src_rev_pool, sizeof(*handler));
Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c Wed Jul 11 10:26:19 2012
@@ -270,6 +270,11 @@ load_config(svn_ra_serf__session_t *sess
else
session->timeout = apr_time_from_sec(DEFAULT_HTTP_TIMEOUT);
+ if (session->timeout < 0) /* Always true for DEFAULT_HTTP_TIMEOUT */
+ session->timeout = apr_time_from_sec(600); /* 10 min */
+
+ SVN_ERR_ASSERT(session->timeout > 0);
+
/* Convert the proxy port value, if any. */
if (port_str)
{
@@ -392,33 +397,27 @@ svn_ra_serf__open(svn_ra_session_t *sess
serf_sess->capabilities = apr_hash_make(serf_sess->pool);
- SVN_ERR(load_config(serf_sess, config, serf_sess->pool));
-
+ serf_sess->http10 = TRUE; /* until we confirm HTTP/1.1 */
+ serf_sess->http10 = FALSE; /* ### don't change behavior yet */
- serf_sess->conns = apr_palloc(serf_sess->pool, sizeof(*serf_sess->conns) * 4);
+ SVN_ERR(load_config(serf_sess, config, serf_sess->pool));
serf_sess->conns[0] = apr_pcalloc(serf_sess->pool,
sizeof(*serf_sess->conns[0]));
- serf_sess->conns[0]->http10 = TRUE; /* until we confirm HTTP/1.1 */
- serf_sess->conns[0]->http10 = FALSE; /* ### don't change behavior yet */
serf_sess->conns[0]->bkt_alloc =
serf_bucket_allocator_create(serf_sess->pool, NULL, NULL);
serf_sess->conns[0]->session = serf_sess;
serf_sess->conns[0]->last_status_code = -1;
- serf_sess->conns[0]->using_ssl = serf_sess->using_ssl;
- serf_sess->conns[0]->using_compression = serf_sess->using_compression;
- serf_sess->conns[0]->hostname = url.hostname;
-
/* create the user agent string */
if (callbacks->get_client_string)
callbacks->get_client_string(callback_baton, &client_string, pool);
if (client_string)
- serf_sess->conns[0]->useragent = apr_pstrcat(pool, USER_AGENT, "/",
- client_string, (char *)NULL);
+ serf_sess->useragent = apr_pstrcat(pool, USER_AGENT, "/",
+ client_string, (char *)NULL);
else
- serf_sess->conns[0]->useragent = USER_AGENT;
+ serf_sess->useragent = USER_AGENT;
/* go ahead and tell serf about the connection. */
status =