Den mån 8 sep. 2025 kl 00:58 skrev Branko Čibej <[email protected]>:
> On 7. 9. 25 22:38, Daniel Sahlberg wrote: > > Den ons 20 aug. 2025 kl 16:43 skrev Branko Čibej <[email protected]>: > >> [moved here from users@] >> >> On 20. 8. 25 14:29, sebb wrote: >> >> svn co --depth=empty https://svn.apache.org/repos/asf/incubator >> >> >> >> Traced this to svn_ra_serf__expect_empty_body() line 1154; the value >> returned from serf_bucket_response_get_headers() is 0xf0, clearly wrong, >> and then serf_bucket_headers_get() crashes. This happens with both serf-1 >> and serf-2 (trunk), could be a bug in Serf, could be something else. Also >> happens over http://, so it's not something related to OpenSSL (which >> makes sense). >> >> -- Brane >> >> > Hi, > > I've spent some time this weekend trying to figure this out. It seems like > we end up in Subversion's libsvn_ra_serf/update.c in process_buffer with > at_eof = 0, thus creating an EAGAIN bucket which doesn't have any header, > thus causing an error later on (as described by Brane above). Thus I'm > leaning towards a Subversion error rather than an error in Serf. > > The call originates in update_delay_handler and it seems that function has > the proper headers in the request bucket. But it creates a new bucket in > process_buffer, without attaching the headers. This in turn causes the > issues in serf_bucket_response_get_headers() since there are no headers to > get. > > I'm a bit at loss here, but it would be fun to be able to follow this to > the very end so if I may ask the graybeards here to not "just solve it" but > bear with me and maybe just give me a few pointers on where to look next. > Even if it is a Doh! moment for someone... > > > > Never been in that code. If it's a 301, Subversion should handle it, I'm > almost certain Serf doesn't (which is ... another kind of problem). You're > sure it behaves as if it received EAGAIN instead of a redirect? I know > there's code in Subversion that handles redirects, but it's IIRC at a > higher level where we connect to the repository; not in the edit drive. > Well... We end up here (ignore the line numbers, I've added quite a bit of printf() debug code). [[[ (gdb) bt #0 update_delay_handler (request=0x7ffff638a038, response=0x7ffff6392738, handler_baton=0x7ffff63ad2a0, scratch_pool=0x7ffff6381028) at subversion/libsvn_ra_serf/update.c:2258 #1 0x00007ffff79b6c36 in handle_response (request=0x7ffff638a038, response=0x7ffff6392738, handler=0x7ffff63ad1c0, serf_status=0x7fffffffcbe0, scratch_pool=0x7ffff6381028) at subversion/libsvn_ra_serf/util.c:1489 #2 0x00007ffff79b6d48 in handle_response_cb (request=0x7ffff638a038, response=0x7ffff6392738, baton=0x7ffff63ad1c0, response_pool=0x7ffff6381028) at subversion/libsvn_ra_serf/util.c:1523 #3 0x00007ffff765c94e in serf.process_connection () from /home/dsg/bin/lib/libserf-1.so.1 #4 0x00007ffff765b21e in serf_event_trigger () from /home/dsg/bin/lib/libserf-1.so.1 #5 0x00007ffff765b369 in serf_context_run () from /home/dsg/bin/lib/libserf-1.so.1 #6 0x00007ffff79b599c in svn_ra_serf__context_run (sess=0x7ffff63af250, waittime_left=0x7fffffffcdd8, scratch_pool=0x7ffff6386028) at subversion/libsvn_ra_serf/util.c:913 #7 0x00007ffff79b2f55 in process_editor_report (ctx=0x7ffff639c660, handler=0x7ffff63ad1c0, scratch_pool=0x7ffff63ad028) at subversion/libsvn_ra_serf/update.c:2434 #8 0x00007ffff79b33e6 in finish_report (report_baton=0x7ffff639c660, pool=0x7ffff63b1028) at subversion/libsvn_ra_serf/update.c:2509 #9 0x00007ffff7de8da0 in svn_wc_crawl_revisions6 (wc_ctx=0x7ffff63c48a8, local_abspath=0x7ffff63b1168 "/home/dsg/bin/bin/incubator", reporter=0x7ffff79cd660 <ra_serf_reporter>, report_baton=0x7ffff639c660, restore_files=1, depth=svn_depth_unknown, honor_depth_exclude=1, depth_compatibility_trick=0, use_commit_times=0, cancel_func=0x7ffff7ceb065 <check_cancel>, cancel_baton=0x0, notify_func=0x5555555877a5 <svn_cl__check_externals_failed_notify_wrapper>, notify_baton=0x7fffffffd700, scratch_pool=0x7ffff63b1028) at subversion/libsvn_wc/adm_crawler.c:868 #10 0x00007ffff7f9924d in update_internal (result_rev=0x0, timestamp_sleep=0x7fffffffd5dc, conflicted_paths=0x0, ra_session_p=0x7fffffffd2d0, local_abspath=0x7ffff63b1168 "/home/dsg/bin/bin/incubator", anchor_abspath=0x7ffff63b2f50 "/home/dsg/bin/bin/incubator", revision=0x7fffffffd360, depth=svn_depth_unknown, depth_is_sticky=0, ignore_externals=0, allow_unver_obstructions=0, adds_as_modification=1, notify_summary=1, ctx=0x7ffff63c47d8, result_pool=0x7ffff63b1028, scratch_pool=0x7ffff63b1028) at subversion/libsvn_client/update.c:563 #11 0x00007ffff7f99884 in svn_client__update_internal (result_rev=0x0, timestamp_sleep=0x7fffffffd5dc, local_abspath=0x7ffff63b1168 "/home/dsg/bin/bin/incubator", revision=0x7fffffffd4e0, depth=svn_depth_unknown, depth_is_sticky=1, ignore_externals=0, allow_unver_obstructions=0, adds_as_modification=1, make_parents=0, innerupdate=0, ra_session=0x7ffff63af228, ctx=0x7ffff63c47d8, pool=0x7ffff63b1028) at subversion/libsvn_client/update.c:702 #12 0x00007ffff7efaf6f in svn_client__checkout_internal (result_rev=0x0, timestamp_sleep=0x7fffffffd5dc, url=0x7ffff63b34a8 " http://svn.apache.org/repos/asf/incubator", local_abspath=0x7ffff63b1168 "/home/dsg/bin/bin/incubator", peg_revision=0x7fffffffd6f0, revision=0x7fffffffd6e0, depth=svn_depth_unknown, ignore_externals=0, allow_unver_obstructions=0, settings_from_context=0, wc_format_version=0x0, store_pristine=svn_tristate_unknown, ra_session=0x7ffff63af228, ctx=0x7ffff63c47d8, scratch_pool=0x7ffff63b1028) at subversion/libsvn_client/checkout.c:274 #13 0x00007ffff7efb091 in svn_client_checkout4 (result_rev=0x0, URL=0x7ffff63b34a8 "http://svn.apache.org/repos/asf/incubator", path=0x7ffff63b34f8 "incubator", peg_revision=0x7fffffffd6f0, revision=0x7fffffffd6e0, depth=svn_depth_unknown, ignore_externals=0, allow_unver_obstructions=0, wc_format_version=0x0, store_pristine=svn_tristate_unknown, ctx=0x7ffff63c47d8, pool=0x7ffff63b1028) at subversion/libsvn_client/checkout.c:305 #14 0x0000555555567db1 in svn_cl__checkout (os=0x7ffff63c3520, baton=0x7fffffffd9d0, pool=0x7ffff63c3028) at subversion/svn/checkout-cmd.c:168 #15 0x000055555559c2c2 in sub_main (exit_code=0x7fffffffdd04, argc=3, cmdline_argv=0x7fffffffde48, pool=0x7ffff63c3028) at subversion/svn/svn.c:3365 #16 0x000055555559c64c in main (argc=3, argv=0x7fffffffde48) at subversion/svn/svn.c:3450 ]]] update_delay_handler has an argument response, a bucket of type RESPONSE, and I can call serf_bucket_response_get_headers(response) to get a headers bucket which I can pass to serf_bucket_headers_get and get the headers. We then get the response (serf_bucket_read) and pass on to process_buffer which creates a new bucket using svn_ra_serf__create_bucket_with_eagain. (I think the eagain is a red herring. We seem to read from the response_body_bucket which is returning 0, ie not APR_STATUS_IS_EOF, so the udb->report->report_received and at_eof flags are not set to TRUE. But even if I hard code these to TRUE, process_buffer creates a new bucket with serf_bucket_simple_create and this STILL doesn't have a request header so we fail in the same place as before. It seems Subversion is looking for a redirect on svn_ra_serf__exchange_capabilities(), which is called really early, in svn_ra_serf__open(). The server, at that time, isn't sending a 301 (the actual request is OPTIONS /repos/asf/incubator) so we proceed. Then (much) later the server sends a 301 on REPORT /repos/asf/!svn/me which we are not able to handle. One way to solve this is to check if serf_bucket_response_get_headers find any header, something like this: [[[ Index: subversion/libsvn_ra_serf/util.c =================================================================== --- subversion/libsvn_ra_serf/util.c (revision 1926872) +++ subversion/libsvn_ra_serf/util.c (working copy) @@ -1139,7 +1139,7 @@ svn_ra_serf__expect_empty_body(serf_request_t *req { svn_ra_serf__handler_t *handler = baton; serf_bucket_t *hdrs; - const char *val; + const char *val = 0; /* This function is just like handle_multistatus_only() except for the XML parsing callbacks. We want to look for the -readable element. */ @@ -1151,7 +1151,8 @@ svn_ra_serf__expect_empty_body(serf_request_t *req SVN_ERR_ASSERT(handler->server_error == NULL); hdrs = serf_bucket_response_get_headers(response); - val = serf_bucket_headers_get(hdrs, "Content-Type"); + if (hdrs) + val = serf_bucket_headers_get(hdrs, "Content-Type"); if (val && (handler->sline.code < 200 || handler->sline.code >= 300) && strncasecmp(val, "text/xml", sizeof("text/xml") - 1) == 0) ]]] The server did actually return Content-Type: text/xml, so technically this is probably wrong, but the reply body is HTML and I have a feeling it wouldn't pass XML parsing a little later in the code above. With the change above we fail with the following error message: [[[ svn: E175011: Repository moved permanently to ' http://svn.apache.org/repos/asf' ]]] We should probably come back to OP with a question why they configured the redirect this way in the first place.. Cheers, Daniel

