⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 util.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * util.c : serf utility routines for ra_serf * * ==================================================================== * Copyright (c) 2006 CollabNet.  All rights reserved. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution.  The terms * are also available at http://subversion.tigris.org/license-1.html. * If newer versions of this license are posted there, you may use a * newer version instead, at your option. * * This software consists of voluntary contributions made by many * individuals.  For exact contribution history, see the revision * history and logs, available at http://subversion.tigris.org/. * ==================================================================== */#define APR_WANT_STRFUNC#include <apr_want.h>#include <apr_base64.h>#include <serf.h>#include <serf_bucket_types.h>#include "svn_path.h"#include "svn_private_config.h"#include "ra_serf.h"/* Fix for older expat 1.95.x's that do not define * XML_STATUS_OK/XML_STATUS_ERROR */#ifndef XML_STATUS_OK#define XML_STATUS_OK    1#define XML_STATUS_ERROR 0#endifserf_bucket_t *svn_ra_serf__conn_setup(apr_socket_t *sock,                        void *baton,                        apr_pool_t *pool){  serf_bucket_t *bucket;  svn_ra_serf__connection_t *conn = baton;  bucket = serf_bucket_socket_create(sock, conn->bkt_alloc);  if (conn->using_ssl)    {      bucket = serf_bucket_ssl_decrypt_create(bucket, conn->ssl_context,                                              conn->bkt_alloc);      if (!conn->ssl_context)        {          conn->ssl_context = serf_bucket_ssl_decrypt_context_get(bucket);        }    }  return bucket;}serf_bucket_t*svn_ra_serf__accept_response(serf_request_t *request,                             serf_bucket_t *stream,                             void *acceptor_baton,                             apr_pool_t *pool){  serf_bucket_t *c;  serf_bucket_alloc_t *bkt_alloc;  bkt_alloc = serf_request_get_alloc(request);  c = serf_bucket_barrier_create(stream, bkt_alloc);  return serf_bucket_response_create(c, bkt_alloc);}static serf_bucket_t*accept_head(serf_request_t *request,            serf_bucket_t *stream,            void *acceptor_baton,            apr_pool_t *pool){  serf_bucket_t *response;  response = svn_ra_serf__accept_response(request, stream, acceptor_baton,                                          pool);  /* We know we shouldn't get a response body. */  serf_bucket_response_set_head(response);  return response;}voidsvn_ra_serf__conn_closed(serf_connection_t *conn,                         void *closed_baton,                         apr_status_t why,                         apr_pool_t *pool){  svn_ra_serf__connection_t *our_conn = closed_baton;  if (why)    {      abort();    }  if (our_conn->using_ssl)    {      our_conn->ssl_context = NULL;    }}apr_status_tsvn_ra_serf__cleanup_serf_session(void *data){  svn_ra_serf__session_t *serf_sess = data;  int i;  /* If we are cleaning up due to an error, don't call connection_close   * as we're already on our way out of here and we'll defer to serf's   * cleanups.   */  if (serf_sess->pending_error)    {      return APR_SUCCESS;    }  for (i = 0; i < serf_sess->num_conns; i++)    {      if (serf_sess->conns[i])        {          serf_connection_close(serf_sess->conns[i]->conn);          serf_sess->conns[i] = NULL;        }    }  return APR_SUCCESS;}voidsvn_ra_serf__setup_serf_req(serf_request_t *request,                            serf_bucket_t **req_bkt,                            serf_bucket_t **ret_hdrs_bkt,                            svn_ra_serf__connection_t *conn,                            const char *method, const char *url,                            serf_bucket_t *body_bkt, const char *content_type){  serf_bucket_t *hdrs_bkt;  *req_bkt = serf_bucket_request_create(method, url, body_bkt,                                        serf_request_get_alloc(request));  hdrs_bkt = serf_bucket_request_get_headers(*req_bkt);  serf_bucket_headers_setn(hdrs_bkt, "Host", conn->hostinfo);  serf_bucket_headers_setn(hdrs_bkt, "User-Agent", "svn/ra_serf");  if (content_type)    {      serf_bucket_headers_setn(hdrs_bkt, "Content-Type", content_type);    }  if (conn->auth_header && conn->auth_value)    {      serf_bucket_headers_setn(hdrs_bkt, conn->auth_header, conn->auth_value);    }  /* Set up SSL if we need to */  if (conn->using_ssl)    {      *req_bkt = serf_bucket_ssl_encrypt_create(*req_bkt, conn->ssl_context,                                            serf_request_get_alloc(request));      if (!conn->ssl_context)        {          conn->ssl_context = serf_bucket_ssl_encrypt_context_get(*req_bkt);        }    }  if (ret_hdrs_bkt)    {      *ret_hdrs_bkt = hdrs_bkt;    }}svn_error_t *svn_ra_serf__context_run_wait(svn_boolean_t *done,                              svn_ra_serf__session_t *sess,                              apr_pool_t *pool){  apr_status_t status;  sess->pending_error = SVN_NO_ERROR;  while (!*done)    {      int i;      status = serf_context_run(sess->context, SERF_DURATION_FOREVER, pool);      if (APR_STATUS_IS_TIMEUP(status))        {          continue;        }      if (status)        {          if (sess->pending_error)            {               return sess->pending_error;            }          return svn_error_wrap_apr(status, "Error running context");        }      /* Debugging purposes only! */      serf_debug__closed_conn(sess->bkt_alloc);      for (i = 0; i < sess->num_conns; i++)        {         serf_debug__closed_conn(sess->conns[i]->bkt_alloc);        }    }  return SVN_NO_ERROR;}apr_status_tsvn_ra_serf__is_conn_closing(serf_bucket_t *response){  serf_bucket_t *hdrs;  const char *val;  hdrs = serf_bucket_response_get_headers(response);  val = serf_bucket_headers_get(hdrs, "Connection");  if (val && strcasecmp("close", val) == 0)    {      return SERF_ERROR_CLOSING;    }  return APR_EOF;}/* * Expat callback invoked on a start element tag for an error response. */static svn_error_t *start_error(svn_ra_serf__xml_parser_t *parser,            void *userData,            svn_ra_serf__dav_props_t name,            const char **attrs){  svn_ra_serf__server_error_t *ctx = userData;  if (!ctx->in_error &&       strcmp(name.namespace, "DAV:") == 0 &&      strcmp(name.name, "error") == 0)    {      ctx->in_error = TRUE;    }  else if (ctx->in_error && strcmp(name.name, "human-readable") == 0)    {      const char *err_code;      err_code = svn_ra_serf__find_attr(attrs, "errcode");      if (err_code)        {          ctx->error->apr_err = apr_atoi64(err_code);        }      else        {          ctx->error->apr_err = APR_EGENERAL;        }      ctx->collect_message = TRUE;    }  return SVN_NO_ERROR;}/* * Expat callback invoked on an end element tag for a PROPFIND response. */static svn_error_t *end_error(svn_ra_serf__xml_parser_t *parser,          void *userData,          svn_ra_serf__dav_props_t name){  svn_ra_serf__server_error_t *ctx = userData;  if (ctx->in_error &&      strcmp(name.namespace, "DAV:") == 0 &&      strcmp(name.name, "error") == 0)    {      ctx->in_error = FALSE;    }  if (ctx->in_error && strcmp(name.name, "human-readable") == 0)    {      ctx->collect_message = FALSE;    }  return SVN_NO_ERROR;}/* * Expat callback invoked on CDATA elements in an error response. * * This callback can be called multiple times. */static svn_error_t *cdata_error(svn_ra_serf__xml_parser_t *parser,            void *userData,            const char *data,            apr_size_t len){  svn_ra_serf__server_error_t *ctx = userData;  /* Skip blank lines in the human-readable error responses. */  if (ctx->collect_message && (len != 1 || data[0] != '\n'))    {      svn_ra_serf__expand_string(&ctx->error->message, &ctx->message_len,                                 data, len, ctx->error->pool);    }  return SVN_NO_ERROR;}apr_status_tsvn_ra_serf__handle_discard_body(serf_request_t *request,                                 serf_bucket_t *response,                                 void *baton,                                 apr_pool_t *pool){  apr_status_t status;  svn_ra_serf__server_error_t *server_err = baton;  if (server_err)    {      if (!server_err->init)        {          serf_bucket_t *hdrs;          const char *val;                    server_err->init = TRUE;          hdrs = serf_bucket_response_get_headers(response);          val = serf_bucket_headers_get(hdrs, "Content-Type");          if (val && strncasecmp(val, "text/xml", sizeof("text/xml") - 1) == 0)            {              server_err->error = svn_error_create(APR_SUCCESS, NULL, NULL);              server_err->has_xml_response = TRUE;              server_err->parser.pool = server_err->error->pool;              server_err->parser.user_data = server_err;              server_err->parser.start = start_error;              server_err->parser.end = end_error;              server_err->parser.cdata = cdata_error;              server_err->parser.done = &server_err->done;              server_err->parser.ignore_errors = TRUE;            }          else            {              server_err->error = SVN_NO_ERROR;            }        }      if (server_err->has_xml_response)        {          status = svn_ra_serf__handle_xml_parser(request, response,                                                  &server_err->parser, pool);          if (server_err->done && server_err->error->apr_err == APR_SUCCESS)             {              svn_error_clear(server_err->error);              server_err->error = SVN_NO_ERROR;            }          return status;        }          }  /* Just loop through and discard the body. */  while (1)    {      const char *data;      apr_size_t len;      status = serf_bucket_read(response, SERF_READ_ALL_AVAIL, &data, &len);      if (status)        {          return status;        }      /* feed me */    }}apr_status_tsvn_ra_serf__handle_status_only(serf_request_t *request,                                serf_bucket_t *response,                                void *baton,                                apr_pool_t *pool){  apr_status_t status;  svn_ra_serf__simple_request_context_t *ctx = baton;  status = svn_ra_serf__handle_discard_body(request, response,                                            &ctx->server_error, pool);  if (APR_STATUS_IS_EOF(status))    {      serf_status_line sl;      apr_status_t rv;      rv = serf_bucket_response_status(response, &sl);            ctx->status = sl.code;      ctx->reason = sl.reason;      ctx->done = TRUE;    }  return status;}static apr_status_thandle_auth(svn_ra_serf__session_t *session,            svn_ra_serf__connection_t *conn,            serf_request_t *request,            serf_bucket_t *response,            apr_pool_t *pool){  void *creds;  svn_auth_cred_simple_t *simple_creds;  const char *tmp;  apr_size_t tmp_len, encoded_len;  svn_error_t *error;  int i;  if (!session->realm)    {      serf_bucket_t *hdrs;      char *cur, *last, *auth_hdr, *realm_name;      apr_port_t port;      hdrs = serf_bucket_response_get_headers(response);      auth_hdr = (char*)serf_bucket_headers_get(hdrs, "WWW-Authenticate");      if (!auth_hdr)        {          abort();        }      cur = apr_strtok(auth_hdr, " ", &last);      while (cur)        {          if (strcmp(cur, "Basic") == 0)            {              char *attr;              attr = apr_strtok(NULL, "=", &last);              if (strcmp(attr, "realm") == 0)                {                  realm_name = apr_strtok(NULL, "=", &last);                  if (realm_name[0] == '\"')                     {                      apr_size_t realm_len;                      realm_len = strlen(realm_name);                      if (realm_name[realm_len - 1] == '\"')                        {                          realm_name[realm_len - 1] = '\0';                          realm_name++;                        }                    }                }              else                {                  abort();                }            }          else            {              /* Support more authentication mechanisms. */              abort();            }          cur = apr_strtok(NULL, " ", &last);        }      if (!realm_name)        {          abort();        }      if (session->repos_url.port_str)        {          port = session->repos_url.port;        }      else        {          port = apr_uri_port_of_scheme(session->repos_url.scheme);        }      session->realm = apr_psprintf(session->pool, "<%s://%s:%d> %s",                                    session->repos_url.scheme,                                    session->repos_url.hostname,                                    port,                                    realm_name);      error = svn_auth_first_credentials(&creds,                                         &session->auth_state,                                         SVN_AUTH_CRED_SIMPLE,                                         session->realm,                                         session->wc_callbacks->auth_baton,                                         session->pool);    }  else    {      error = svn_auth_next_credentials(&creds,                                        session->auth_state,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -