https://bz.apache.org/bugzilla/show_bug.cgi?id=61616
--- Comment #48 from Mohamed El Housseine <[email protected]> --- After driving many tests with the data provided by Carsten, I was able to figure out, where the unsent-but-read data sits during the stall. For simplification I will reduce the proxy flow to the following steps: 1- proxy_connect_handler calls ap_proxy_transfer_between_connections after every succesfull POLLIN. The flow of ap_proxy_transfer_between_connections consists of: 2- call ap_get_brigade to read the incoming data from the backend connection into bb_i 3- call ap_proxy_buckets_lifetime_transform to copy bb_i into bb_o 4- call ap_pass_brigade to write the data of bb_o to the client connection 5- repeat the steps 2:4 as long as step 2 and step 4 return APR_SUCCESS During this flow following situtations may occur: #a: the ap_core_input_filter is called from ap_get_brigade in step2. It takes as last parameter the readbytes (the max amount of data to read) and it tries to read the requested amount of data from the socket by calling the apr function socket_bucket_read through apr_bucket_read in a loop (http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/server/core_filters.c?annotate=1734391#l235 and http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/server/core_filters.c?annotate=1734391#l284). #b: socket_bucket_read allocates a new bucket and _overwrites_ the requested len with APR_BUCKET_BUFF_SIZE, before passing it to apr_socket_recv. #c: Because of this, it is possible that socket_bucket_read reads more data from the socket into the bucket than ap_core_input_filter was instructed to get. #d: In this case the read data will be split into several buckets by ap_core_input_filter. Tthe first one will be returned through bb_i and the rest will be kept in in_ctx->b. (http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/server/core_filters.c?annotate=1734391#l305 ff.) #e: the ap_pass_brigade in step 4 then tries to write the data from bb_i to the target connection. If that write comes back incomplete, the flag data_in_output_filters will be set to true, in which case the loop in step 5 ends. #f: if this all happens at the very end of the data transfer, and the socket doesn't receive any more data to cause a POLLIN, step 1 will never happen again and the data in in_ctx->b will not get sent before rsync decides to send an (application-level) keepalive (after minutes). -- You are receiving this mail because: You are the assignee for the bug. --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
