Index: subversion/libsvn_ra_serf/serf.c =================================================================== --- subversion/libsvn_ra_serf/serf.c (revision 40357) +++ subversion/libsvn_ra_serf/serf.c (working copy) @@ -303,9 +303,11 @@ load_config(svn_ra_serf__session_t *session, else session->using_proxy = FALSE; - /* Load the list of support authn types. */ - SVN_ERR(load_http_auth_types(pool, config, server_group, - &session->authn_types)); + /* Setup authentication. */ + SVN_ERR(load_http_auth_types(pool, config, server_group, + &session->authn_types)); + /* serf_config_authn_types(session->context, session->authn_types);*/ + serf_config_credentials_callback(session->context, svn_ra_serf__credentials_callback); return SVN_NO_ERROR; } @@ -430,11 +432,15 @@ svn_ra_serf__open(svn_ra_session_t *session, serf_sess->conns[0]->useragent = USER_AGENT; /* go ahead and tell serf about the connection. */ - serf_sess->conns[0]->conn = - serf_connection_create(serf_sess->context, serf_sess->conns[0]->address, - svn_ra_serf__conn_setup, serf_sess->conns[0], - svn_ra_serf__conn_closed, serf_sess->conns[0], - serf_sess->pool); + status = + serf_connection_create2(&serf_sess->conns[0]->conn, + serf_sess->context, + url, + svn_ra_serf__conn_setup, serf_sess->conns[0], + svn_ra_serf__conn_closed, serf_sess->conns[0], + serf_sess->pool); + if (status) + return status; /* Set the progress callback. */ serf_context_set_progress_cb(serf_sess->context, svn_ra_serf__progress, Index: subversion/libsvn_ra_serf/util.c =================================================================== --- subversion/libsvn_ra_serf/util.c (revision 40357) +++ subversion/libsvn_ra_serf/util.c (working copy) @@ -504,8 +504,9 @@ svn_ra_serf__setup_serf_req(serf_request_t *reques { serf_bucket_t *hdrs_bkt; - *req_bkt = serf_bucket_request_create(method, url, body_bkt, - serf_request_get_alloc(request)); + *req_bkt = + serf_request_bucket_request_create(request, 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); @@ -1177,6 +1178,75 @@ svn_ra_serf__handle_server_error(serf_request_t *r return server_err.error; } +apr_status_t +svn_ra_serf__credentials_callback(char **username, char **password, + serf_request_t *request, void *baton, + int code, const char *authn_type, + const char *realm, + apr_pool_t *pool) +{ + svn_ra_serf__handler_t *ctx = baton; + svn_ra_serf__session_t *session = ctx->session; + void *creds; + svn_auth_cred_simple_t *simple_creds; + svn_error_t *err; + + if (code == 401) + { + /* Use svn_auth_first_credentials if this is the first time we ask for + credentials during this session OR if the last time we asked + session->auth_state wasn't set (eg. if the credentials provider was + cancelled by the user). */ + if (!session->auth_state) + { + err = svn_auth_first_credentials(&creds, + &session->auth_state, + SVN_AUTH_CRED_SIMPLE, + realm, + session->wc_callbacks->auth_baton, + session->pool); + } + else + { + err = svn_auth_next_credentials(&creds, + session->auth_state, + session->pool); + } + + if (err) + { + ctx->session->pending_error = err; + return err->apr_err; + } + + session->auth_attempts++; + + if (!creds || session->auth_attempts > 4) + { + /* No more credentials. */ + ctx->session->pending_error = + svn_error_create(SVN_ERR_AUTHN_FAILED, NULL, + "No more credentials or we tried too many times.\n" + "Authentication failed");; + return SVN_ERR_AUTHN_FAILED; + } + + simple_creds = creds; + *username = apr_pstrdup(pool, simple_creds->username); + *password = apr_pstrdup(pool, simple_creds->password); + } + else + { + *username = apr_pstrdup(pool, session->proxy_username); + *password = apr_pstrdup(pool, session->proxy_password); + } + + printf("user: %s, pass: %s\n", *username, *password); + ctx->conn->last_status_code = code; + + return APR_SUCCESS; +} + /* Implements the serf_response_handler_t interface. Wait for HTTP response status and headers, and invoke CTX->response_handler() to carry out operation-specific processing. Afterwards, check for Index: subversion/libsvn_ra_serf/update.c =================================================================== --- subversion/libsvn_ra_serf/update.c (revision 40357) +++ subversion/libsvn_ra_serf/update.c (working copy) @@ -2127,7 +2127,7 @@ link_path(void *report_baton, * if the number of ACTIVE_REQS > REQS_PER_CONN or if there currently is * only one main connection open. */ -static void +static svn_error_t * open_connection_if_needed(svn_ra_serf__session_t *sess, int active_reqs) { /* For each REQS_PER_CONN outstanding requests open a new connection, with @@ -2136,6 +2136,7 @@ open_connection_if_needed(svn_ra_serf__session_t * ((active_reqs / REQS_PER_CONN) > sess->num_conns)) { int cur = sess->num_conns; + apr_status_t status; sess->conns[cur] = apr_palloc(sess->pool, sizeof(*sess->conns[cur])); sess->conns[cur]->bkt_alloc = serf_bucket_allocator_create(sess->pool, @@ -2150,13 +2151,17 @@ open_connection_if_needed(svn_ra_serf__session_t * sess->conns[cur]->last_status_code = -1; sess->conns[cur]->ssl_context = NULL; sess->conns[cur]->session = sess; - sess->conns[cur]->conn = serf_connection_create(sess->context, - sess->conns[cur]->address, - svn_ra_serf__conn_setup, - sess->conns[cur], - svn_ra_serf__conn_closed, - sess->conns[cur], - sess->pool); + status = serf_connection_create2(&sess->conns[cur]->conn, + sess->context, + sess->repos_url, + svn_ra_serf__conn_setup, + sess->conns[cur], + svn_ra_serf__conn_closed, + sess->conns[cur], + sess->pool); + if (status) + return svn_error_wrap_apr(status, NULL); + sess->num_conns++; /* Authentication protocol specific initalization. */ @@ -2166,6 +2171,8 @@ open_connection_if_needed(svn_ra_serf__session_t * sess->proxy_auth_protocol->init_conn_func(sess, sess->conns[cur], sess->pool); } + + return SVN_NO_ERROR; } static svn_error_t * @@ -2220,7 +2227,7 @@ finish_report(void *report_baton, svn_ra_serf__request_create(handler); /* Open the first extra connection. */ - open_connection_if_needed(sess, 0); + SVN_ERR(open_connection_if_needed(sess, 0)); sess->cur_conn = 1; closed_root = FALSE; @@ -2244,8 +2251,8 @@ finish_report(void *report_baton, /* Open extra connections if we have enough requests to send. */ if (sess->num_conns < MAX_NR_OF_CONNS) - open_connection_if_needed(sess, report->active_fetches + - report->active_propfinds); + SVN_ERR(open_connection_if_needed(sess, report->active_fetches + + report->active_propfinds)); /* Switch our connection. */ if (!report->done) Index: subversion/libsvn_ra_serf/ra_serf.h =================================================================== --- subversion/libsvn_ra_serf/ra_serf.h (revision 40357) +++ subversion/libsvn_ra_serf/ra_serf.h (working copy) @@ -1402,6 +1402,16 @@ svn_ra_serf__get_deleted_rev(svn_ra_session_t *ses /*** Authentication handler declarations ***/ /** + * Callback function that loads the credentials for Basic and Digest + * authentications, both for server and proxy authentication. + */ +apr_status_t +svn_ra_serf__credentials_callback(char **username, char **password, + serf_request_t *request, void *baton, + int code, const char *authn_type, + const char *realm, + apr_pool_t *pool); +/** * For each authentication protocol we need a handler function of type * svn_serf__auth_handler_func_t. This function will be called when an * authentication challenge is received in a session.