📄 session.c
字号:
ne_ssl_trust_default_ca(sess2); } } neonprogress_baton->pool = pool; neonprogress_baton->progress_baton = callbacks->progress_baton; neonprogress_baton->progress_func = callbacks->progress_func; ne_set_progress(sess, ra_dav_neonprogress, neonprogress_baton); ne_set_progress(sess2, ra_dav_neonprogress, neonprogress_baton); session->priv = ras; return SVN_NO_ERROR;}static svn_error_t *svn_ra_dav__reparent(svn_ra_session_t *session, const char *url, apr_pool_t *pool){ svn_ra_dav__session_t *ras = session->priv; ne_uri uri = { 0 }; SVN_ERR(parse_url(&uri, url)); ne_uri_free(&ras->root); ras->root = uri; svn_stringbuf_set(ras->url, url); return SVN_NO_ERROR;}static svn_error_t *svn_ra_dav__get_repos_root(svn_ra_session_t *session, const char **url, apr_pool_t *pool){ svn_ra_dav__session_t *ras = session->priv; if (! ras->repos_root) { svn_string_t bc_relative; svn_stringbuf_t *url_buf; SVN_ERR(svn_ra_dav__get_baseline_info(NULL, NULL, &bc_relative, NULL, ras->sess, ras->url->data, SVN_INVALID_REVNUM, pool)); /* Remove as many path components from the URL as there are components in bc_relative. */ url_buf = svn_stringbuf_dup(ras->url, pool); svn_path_remove_components (url_buf, svn_path_component_count(bc_relative.data)); ras->repos_root = apr_pstrdup(ras->pool, url_buf->data); } *url = ras->repos_root; return SVN_NO_ERROR; }static svn_error_t *svn_ra_dav__do_get_uuid(svn_ra_session_t *session, const char **uuid, apr_pool_t *pool){ svn_ra_dav__session_t *ras = session->priv; if (! ras->uuid) { svn_ra_dav_resource_t *rsrc; const char *lopped_path; const svn_string_t *uuid_propval; SVN_ERR(svn_ra_dav__search_for_starting_props(&rsrc, &lopped_path, ras->sess, ras->url->data, pool)); SVN_ERR(svn_ra_dav__maybe_store_auth_info(ras, pool)); uuid_propval = apr_hash_get(rsrc->propset, SVN_RA_DAV__PROP_REPOSITORY_UUID, APR_HASH_KEY_STRING); if (uuid_propval == NULL) /* ### better error reporting... */ return svn_error_create(APR_EGENERAL, NULL, _("The UUID property was not found on the " "resource or any of its parents")); if (uuid_propval && (uuid_propval->len > 0)) ras->uuid = apr_pstrdup(ras->pool, uuid_propval->data); /* cache */ else return svn_error_create (SVN_ERR_RA_NO_REPOS_UUID, NULL, _("Please upgrade the server to 0.19 or later")); } *uuid = ras->uuid; return SVN_NO_ERROR; }#ifndef SVN_NEON_0_25/* A callback of type ne_header_handler, invoked when neon encounters mod_dav_svn's custom 'creationdate' header in a LOCK response. */static voidhandle_creationdate_header(void *userdata, const char *value){ struct lock_request_baton *lrb = userdata; svn_error_t *err; if (! value) return; err = svn_time_from_cstring(&(lrb->creation_date), value, lrb->pool); if (err) { svn_error_clear(err); lrb->creation_date = 0; }}/* A callback of type ne_header_handler, invoked when neon encounters mod_dav_svn's custom 'lock owner' header in a LOCK response. */static voidhandle_lock_owner_header(void *userdata, const char *value){ struct lock_request_baton *lrb = userdata; if (! value) return; lrb->lock_owner = apr_pstrdup(lrb->pool, value);}#endif /* ! SVN_NEON_0_25 *//* A callback of type ne_create_request_fn; called whenever neon creates a request. */static void create_request_hook(ne_request *req, void *userdata, const char *method, const char *requri){ struct lock_request_baton *lrb = userdata; /* If a LOCK, UNLOCK, or PROPFIND is happening, then remember the http method. */ if ((strcmp(method, "LOCK") == 0) || (strcmp(method, "UNLOCK") == 0) || (strcmp(method, "PROPFIND") == 0)) { lrb->method = apr_pstrdup(lrb->pool, method); lrb->request = req; }}/* A callback of type ne_pre_send_fn; called whenever neon is just about to send a request. */static voidpre_send_hook(ne_request *req, void *userdata, ne_buffer *header){ struct lock_request_baton *lrb = userdata; if (! lrb->method) return; /* Possibly attach some custom headers to the request. */ if ((strcmp(lrb->method, "LOCK") == 0) || (strcmp(lrb->method, "PROPFIND") == 0)) { /* Possibly add an X-SVN-Option: header indicating that the lock is being stolen. */ if (lrb->force) { char *hdr = apr_psprintf(lrb->pool, "%s: %s\r\n", SVN_DAV_OPTIONS_HEADER, SVN_DAV_OPTION_LOCK_STEAL); ne_buffer_zappend(header, hdr); } /* If we have a working-revision of the file, send it so that svn_fs_lock() can do an out-of-dateness check. */ if (SVN_IS_VALID_REVNUM(lrb->current_rev)) { char *buf = apr_psprintf(lrb->pool, "%s: %ld\r\n", SVN_DAV_VERSION_NAME_HEADER, lrb->current_rev); ne_buffer_zappend(header, buf); }#ifndef SVN_NEON_0_25 /* Register callbacks to read any custom 'creationdate' and 'lock owner' response headers sent by mod_dav_svn. */ ne_add_response_header_handler(req, SVN_DAV_CREATIONDATE_HEADER, handle_creationdate_header, lrb); ne_add_response_header_handler(req, SVN_DAV_LOCK_OWNER_HEADER, handle_lock_owner_header, lrb);#endif /* ! SVN_NEON_0_25 */ } if (strcmp(lrb->method, "UNLOCK") == 0) { if (lrb->force) { char *buf = apr_psprintf(lrb->pool, "%s: %s\r\n", SVN_DAV_OPTIONS_HEADER, SVN_DAV_OPTION_LOCK_BREAK); ne_buffer_zappend(header, buf); } } /* Register a response handler capable of parsing <D:error> */ lrb->error_parser = ne_xml_create(); svn_ra_dav__add_error_handler(req, lrb->error_parser, &(lrb->err), lrb->pool);}#ifdef SVN_NEON_0_25/* A callback of type ne_post_send_fn; called after neon has sent a request and received a response header back. */static intpost_send_hook(ne_request *req, void *userdata, const ne_status *status){ struct lock_request_baton *lrb = userdata; if (! lrb->method) return NE_OK; if ((strcmp(lrb->method, "LOCK") == 0) || (strcmp(lrb->method, "PROPFIND") == 0)) { const char *val; val = ne_get_response_header(req, SVN_DAV_CREATIONDATE_HEADER); if (val) { svn_error_t *err = svn_time_from_cstring(&(lrb->creation_date), val, lrb->pool); NE_DEBUG(NE_DBG_HTTP, "got cdate %s for %s request...\n", val, lrb->method); if (err) { svn_error_clear(err); lrb->creation_date = 0; /* ### Should we return NE_RETRY in this case? And if ### we were to do that, would we also set *status ### and call ne_set_error? */ } } val = ne_get_response_header(req, SVN_DAV_LOCK_OWNER_HEADER); if (val) lrb->lock_owner = apr_pstrdup(lrb->pool, val); } return NE_OK;}#endif /* SVN_NEON_0_25 */static voidsetup_neon_request_hook(svn_ra_dav__session_t *ras){ /* We need to set up the lock callback once and only once per neon session creation. */ if (! ras->lrb) { struct lock_request_baton *lrb; /* Build context for neon callbacks and then register them. */ lrb = apr_pcalloc(ras->pool, sizeof(*lrb)); ne_hook_create_request(ras->sess, create_request_hook, lrb); ne_hook_pre_send(ras->sess, pre_send_hook, lrb);#ifdef SVN_NEON_0_25 ne_hook_post_send(ras->sess, post_send_hook, lrb);#endif /* SVN_NEON_0_25 */ lrb->pool = ras->pool; ras->lrb = lrb; }}/* (Note: *LOCK is an output parameter.) *//* ### TODO for 1.3: Send all locks to the server at once. */static svn_error_t *shim_svn_ra_dav__lock(svn_ra_session_t *session, svn_lock_t **lock, const char *path, const char *comment, svn_boolean_t force, svn_revnum_t current_rev, apr_pool_t *pool){ svn_ra_dav__session_t *ras = session->priv; int rv; const char *url; svn_string_t fs_path; struct ne_lock *nlock; svn_lock_t *slock; /* To begin, we convert the incoming path into an absolute fs-path. */ url = svn_path_url_add_component(ras->url->data, path, pool); SVN_ERR(svn_ra_dav__get_baseline_info(NULL, NULL, &fs_path, NULL, ras->sess, url, SVN_INVALID_REVNUM, pool)); /* Clear out the lrb... */ memset((ras->lrb), 0, sizeof(*ras->lrb)); /* ...and load it up again. */ ras->lrb->pool = pool; ras->lrb->current_rev = current_rev; ras->lrb->force = force; /* Make a neon lock structure. */ nlock = ne_lock_create(); nlock->owner = comment ? ne_strdup(apr_xml_quote_string(pool, comment, 1)) : NULL; if ((rv = ne_uri_parse(url, &(nlock->uri)))) { ne_lock_destroy(nlock); return svn_ra_dav__convert_error(ras->sess, _("Failed to parse URI"), rv, pool); } /* Issue LOCK request. */ rv = ne_lock(ras->sess, nlock); /* Did we get a <D:error> response? */ if (ras->lrb->err) { ne_lock_destroy(nlock); if (ras->lrb->error_parser) ne_xml_destroy(ras->lrb->error_parser); return ras->lrb->err; } /* Did we get some other sort of neon error? */ if (rv) { ne_lock_destroy(nlock); if (ras->lrb->error_parser) ne_xml_destroy(ras->lrb->error_parser); return svn_ra_dav__convert_error(ras->sess, _("Lock request failed"), rv, pool); } if (!ras->lrb->lock_owner || !ras->lrb->creation_date) return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL, _("Incomplete lock data returned")); /* Build an svn_lock_t based on the returned ne_lock. */ slock = svn_lock_create(pool); slock->path = fs_path.data; slock->token = apr_pstrdup(pool, nlock->token); if (nlock->owner) slock->comment = apr_pstrdup(pool, nlock->owner); slock->owner = apr_pstrdup(pool, ras->lrb->lock_owner); slock->creation_date = ras->lrb->creation_date; if (nlock->timeout == NE_TIMEOUT_INFINITE) slock->expiration_date = 0; else if (nlock->timeout > 0) slock->expiration_date = slock->creation_date + apr_time_from_sec(nlock->timeout); /* Free neon things. */ ne_lock_destroy(nlock); if (ras->lrb->error_parser) ne_xml_destroy(ras->lrb->error_parser); *lock = slock; return SVN_NO_ERROR;}static svn_error_t *svn_ra_dav__lock(svn_ra_session_t *session, apr_hash_t *path_revs, const char *comment, svn_boolean_t force, svn_ra_lock_callback_t lock_func, void *lock_baton, apr_pool_t *pool){ apr_hash_index_t *hi; apr_pool_t *iterpool = svn_pool_create(pool); svn_ra_dav__session_t *ras = session->priv; svn_error_t *ret_err = NULL; setup_neon_request_hook(ras); /* ### TODO for 1.3: Send all the locks over the wire at once. This loop is just a temporary shim. */ for (hi = apr_hash_first(pool, path_revs); hi; hi = apr_hash_next(hi)) { svn_lock_t *lock; const void *key; const char *path; void *val; svn_revnum_t *revnum; svn_error_t *err, *callback_err = NULL; svn_pool_clear(iterpool); apr_hash_this(hi, &key, NULL, &val); path = key; revnum = val;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -