📄 util.c
字号:
session->pool); } session->auth_attempts++; if (error) { abort(); } if (!creds || session->auth_attempts > 4) { /* No more credentials. */ printf("No more credentials or we tried too many times. Sorry.\n"); return APR_EGENERAL; } simple_creds = creds; tmp = apr_pstrcat(session->pool, simple_creds->username, ":", simple_creds->password, NULL); tmp_len = strlen(tmp); encoded_len = apr_base64_encode_len(tmp_len); session->auth_value = apr_palloc(session->pool, encoded_len + 6); apr_cpystrn(session->auth_value, "Basic ", 7); apr_base64_encode(&session->auth_value[6], tmp, tmp_len); session->auth_header = "Authorization"; /* FIXME Come up with a cleaner way of changing the connection auth. */ for (i = 0; i < session->num_conns; i++) { session->conns[i]->auth_header = session->auth_header; session->conns[i]->auth_value = session->auth_value; } return APR_SUCCESS;}static voidstart_xml(void *userData, const char *raw_name, const char **attrs){ svn_ra_serf__xml_parser_t *parser = userData; svn_ra_serf__dav_props_t name; if (parser->error) return; if (!parser->state) svn_ra_serf__xml_push_state(parser, 0); svn_ra_serf__define_ns(&parser->state->ns_list, attrs, parser->state->pool); name = svn_ra_serf__expand_ns(parser->state->ns_list, raw_name); parser->error = parser->start(parser, parser->user_data, name, attrs);}static voidend_xml(void *userData, const char *raw_name){ svn_ra_serf__xml_parser_t *parser = userData; svn_ra_serf__dav_props_t name; if (parser->error) return; name = svn_ra_serf__expand_ns(parser->state->ns_list, raw_name); parser->error = parser->end(parser, parser->user_data, name);}static voidcdata_xml(void *userData, const char *data, int len){ svn_ra_serf__xml_parser_t *parser = userData; if (parser->error) return; if (!parser->state) svn_ra_serf__xml_push_state(parser, 0); parser->error = parser->cdata(parser, parser->user_data, data, len);}apr_status_tsvn_ra_serf__handle_xml_parser(serf_request_t *request, serf_bucket_t *response, void *baton, apr_pool_t *pool){ const char *data; apr_size_t len; serf_status_line sl; apr_status_t status; int xml_status; svn_ra_serf__xml_parser_t *ctx = baton; serf_bucket_response_status(response, &sl); if (ctx->status_code) { *ctx->status_code = sl.code; } /* Woo-hoo. Nothing here to see. */ if (sl.code == 404 && ctx->ignore_errors == FALSE) { /* If our caller won't know about the 404, abort() for now. */ if (!ctx->status_code) { abort(); } if (*ctx->done == FALSE) { *ctx->done = TRUE; if (ctx->done_list) { ctx->done_item->data = ctx->user_data; ctx->done_item->next = *ctx->done_list; *ctx->done_list = ctx->done_item; } } return svn_ra_serf__handle_discard_body(request, response, NULL, pool); } if (!ctx->xmlp) { ctx->xmlp = XML_ParserCreate(NULL); XML_SetUserData(ctx->xmlp, ctx); XML_SetElementHandler(ctx->xmlp, start_xml, end_xml); if (ctx->cdata) { XML_SetCharacterDataHandler(ctx->xmlp, cdata_xml); } } while (1) { status = serf_bucket_read(response, 8000, &data, &len); if (SERF_BUCKET_READ_ERROR(status)) { return status; } xml_status = XML_Parse(ctx->xmlp, data, len, 0); if (xml_status == XML_STATUS_ERROR && ctx->ignore_errors == FALSE) { XML_ParserFree(ctx->xmlp); if (!ctx->status_code) { abort(); } if (*ctx->done == FALSE) { *ctx->done = TRUE; if (ctx->done_list) { ctx->done_item->data = ctx->user_data; ctx->done_item->next = *ctx->done_list; *ctx->done_list = ctx->done_item; } } ctx->error = svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL, "XML parsing failed: (%d %s)", sl.code, sl.reason); return ctx->error->apr_err; } if (ctx->error && ctx->ignore_errors == FALSE) { XML_ParserFree(ctx->xmlp); status = ctx->error->apr_err; svn_error_clear(ctx->error); return status; } if (APR_STATUS_IS_EAGAIN(status)) { return status; } if (APR_STATUS_IS_EOF(status)) { xml_status = XML_Parse(ctx->xmlp, NULL, 0, 1); if (xml_status == XML_STATUS_ERROR && ctx->ignore_errors == FALSE) { abort(); } XML_ParserFree(ctx->xmlp); *ctx->done = TRUE; if (ctx->done_list) { ctx->done_item->data = ctx->user_data; ctx->done_item->next = *ctx->done_list; *ctx->done_list = ctx->done_item; } return status; } /* feed me! */ } /* not reached */}svn_error_t *svn_ra_serf__handle_server_error(serf_request_t *request, serf_bucket_t *response, apr_pool_t *pool){ svn_ra_serf__server_error_t server_err; apr_status_t status; memset(&server_err, 0, sizeof(server_err)); status = svn_ra_serf__handle_discard_body(request, response, &server_err, pool); if (APR_STATUS_IS_EOF(status)) { status = svn_ra_serf__is_conn_closing(response); if (status == SERF_ERROR_CLOSING) { serf_connection_reset(serf_request_get_conn(request)); } } SVN_ERR(server_err.error); return svn_error_create(APR_EGENERAL, NULL, _("Unspecified error message"));}/* 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 connection close. */static apr_status_thandle_response(serf_request_t *request, serf_bucket_t *response, void *baton, apr_pool_t *pool){ svn_ra_serf__handler_t *ctx = baton; serf_status_line sl; apr_status_t status; if (!response) { /* Uh-oh. Our connection died. Requeue. */ if (ctx->response_error) { status = ctx->response_error(request, response, 0, ctx->response_error_baton); if (status) { return status; } } svn_ra_serf__request_create(ctx); return APR_SUCCESS; } status = serf_bucket_response_status(response, &sl); if (SERF_BUCKET_READ_ERROR(status)) { return status; } status = serf_bucket_response_wait_for_headers(response); if (status) { if (!APR_STATUS_IS_EOF(status)) { return status; } /* Cases where a lack of a response body (via EOF) is okay: * - A HEAD request * - 204/304 response * * Otherwise, if we get an EOF here, something went really wrong: either * the server closed on us early or we're reading too much. Either way, * scream loudly. */ if (strcmp(ctx->method, "HEAD") != 0 && sl.code != 204 && sl.code != 304) { ctx->session->pending_error = svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL, _("Premature EOF seen from server")); return ctx->session->pending_error->apr_err; } } if (ctx->conn->last_status_code == 401 && sl.code < 400) { svn_auth_save_credentials(ctx->session->auth_state, ctx->session->pool); ctx->session->auth_attempts = 0; ctx->session->auth_state = NULL; } ctx->conn->last_status_code = sl.code; if (sl.code == 401) { handle_auth(ctx->session, ctx->conn, request, response, pool); svn_ra_serf__request_create(ctx); status = svn_ra_serf__handle_discard_body(request, response, NULL, pool); } else if (sl.code >= 500) { ctx->session->pending_error = svn_ra_serf__handle_server_error(request, response, pool); return ctx->session->pending_error->apr_err; } else { status = ctx->response_handler(request, response, ctx->response_baton, pool); } if (APR_STATUS_IS_EOF(status)) { status = svn_ra_serf__is_conn_closing(response); } return status;}/* Implements the serf_request_setup_t interface (which sets up both a request and its response handler callback). If the CTX->delegate() callback is non-NULL, invoke it to carry out the majority of the serf_request_setup_t implementation. Otherwise, perform default setup, with special handling for HEAD requests, and finer-grained callbacks invoked (if non-NULL) to produce the request headers and body. */static apr_status_tsetup_request(serf_request_t *request, void *setup_baton, serf_bucket_t **req_bkt, serf_response_acceptor_t *acceptor, void **acceptor_baton, serf_response_handler_t *handler, void **handler_baton, apr_pool_t *pool){ svn_ra_serf__handler_t *ctx = setup_baton; serf_bucket_t *headers_bkt; *acceptor = svn_ra_serf__accept_response; *acceptor_baton = ctx->session; if (ctx->delegate) { apr_status_t status; status = ctx->delegate(request, ctx->delegate_baton, req_bkt, acceptor, acceptor_baton, handler, handler_baton, pool); if (status) { return status; } ctx->response_handler = *handler; ctx->response_baton = *handler_baton; } else { if (strcmp(ctx->method, "HEAD") == 0) { *acceptor = accept_head; } if (ctx->body_delegate) { ctx->body_buckets = ctx->body_delegate(ctx->body_delegate_baton, serf_request_get_alloc(request), pool); } svn_ra_serf__setup_serf_req(request, req_bkt, &headers_bkt, ctx->conn, ctx->method, ctx->path, ctx->body_buckets, ctx->body_type); if (ctx->header_delegate) { ctx->header_delegate(headers_bkt, ctx->header_delegate_baton, pool); } } *handler = handle_response; *handler_baton = ctx; return APR_SUCCESS;}serf_request_t *svn_ra_serf__request_create(svn_ra_serf__handler_t *handler){ return serf_connection_request_create(handler->conn->conn, setup_request, handler);}svn_error_t *svn_ra_serf__discover_root(const char **vcc_url, const char **rel_path, svn_ra_serf__session_t *session, svn_ra_serf__connection_t *conn, const char *orig_path, apr_pool_t *pool){ apr_hash_t *props; const char *path, *relative_path, *present_path = ""; /* If we're only interested in our VCC, just return it. */ if (session->vcc_url && !rel_path) { *vcc_url = session->vcc_url; return SVN_NO_ERROR; } props = apr_hash_make(pool); path = orig_path; *vcc_url = NULL; do { SVN_ERR(svn_ra_serf__retrieve_props(props, session, conn, path, SVN_INVALID_REVNUM, "0", base_props, pool)); *vcc_url = svn_ra_serf__get_ver_prop(props, path, SVN_INVALID_REVNUM, "DAV:", "version-controlled-configuration"); if (*vcc_url) { relative_path = svn_ra_serf__get_ver_prop(props, path, SVN_INVALID_REVNUM, SVN_DAV_PROP_NS_DAV, "baseline-relative-path"); break; } /* This happens when the file is missing in HEAD. */ /* Okay, strip off. */ present_path = svn_path_join(svn_path_basename(path, pool), present_path, pool); path = svn_path_dirname(path, pool); } while (!svn_path_is_empty(path)); if (!*vcc_url) { abort(); } /* Store our VCC in our cache. */ if (!session->vcc_url) { session->vcc_url = apr_pstrdup(session->pool, *vcc_url); } /* Update our cached repository root URL. */ if (!session->repos_root_str) { svn_stringbuf_t *url_buf; url_buf = svn_stringbuf_create(path, pool); svn_path_remove_components(url_buf, svn_path_component_count(relative_path)); /* Now recreate the root_url. */ session->repos_root = session->repos_url; session->repos_root.path = apr_pstrdup(session->pool, url_buf->data); session->repos_root_str = apr_uri_unparse(session->pool, &session->repos_root, 0); } if (rel_path) { if (present_path[0] != '\0') { *rel_path = svn_path_url_add_component(relative_path, present_path, pool); } else { *rel_path = relative_path; } } return SVN_NO_ERROR;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -