Merge branch 'jt/tighten-fetch-proto-v2-response'
"git fetch" was a bit loose in parsing resposes from the other side when talking over the protocol v2. * jt/tighten-fetch-proto-v2-response: fetch-pack: be more precise in parsing v2 responsemaint
						commit
						67cf2fa3d5
					
				
							
								
								
									
										12
									
								
								fetch-pack.c
								
								
								
								
							
							
						
						
									
										12
									
								
								fetch-pack.c
								
								
								
								
							| 
						 | 
				
			
			@ -1248,6 +1248,18 @@ static int process_acks(struct fetch_negotiator *negotiator,
 | 
			
		|||
	    reader->status != PACKET_READ_DELIM)
 | 
			
		||||
		die(_("error processing acks: %d"), reader->status);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * If an "acknowledgments" section is sent, a packfile is sent if and
 | 
			
		||||
	 * only if "ready" was sent in this section. The other sections
 | 
			
		||||
	 * ("shallow-info" and "wanted-refs") are sent only if a packfile is
 | 
			
		||||
	 * sent. Therefore, a DELIM is expected if "ready" is sent, and a FLUSH
 | 
			
		||||
	 * otherwise.
 | 
			
		||||
	 */
 | 
			
		||||
	if (received_ready && reader->status != PACKET_READ_DELIM)
 | 
			
		||||
		die(_("expected packfile to be sent after 'ready'"));
 | 
			
		||||
	if (!received_ready && reader->status != PACKET_READ_FLUSH)
 | 
			
		||||
		die(_("expected no other sections to be sent after no 'ready'"));
 | 
			
		||||
 | 
			
		||||
	/* return 0 if no common, 1 if there are common, or 2 if ready */
 | 
			
		||||
	return received_ready ? 2 : (received_ack ? 1 : 0);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -537,6 +537,56 @@ test_expect_success 'push with http:// and a config of v2 does not request v2' '
 | 
			
		|||
	! grep "git< version 2" log
 | 
			
		||||
'
 | 
			
		||||
 | 
			
		||||
test_expect_success 'when server sends "ready", expect DELIM' '
 | 
			
		||||
	rm -rf "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" http_child &&
 | 
			
		||||
 | 
			
		||||
	git init "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" &&
 | 
			
		||||
	test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" one &&
 | 
			
		||||
 | 
			
		||||
	git clone "$HTTPD_URL/smart/http_parent" http_child &&
 | 
			
		||||
 | 
			
		||||
	test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" two &&
 | 
			
		||||
 | 
			
		||||
	# After "ready" in the acknowledgments section, pretend that a FLUSH
 | 
			
		||||
	# (0000) was sent instead of a DELIM (0001).
 | 
			
		||||
	printf "/ready/,$ s/0001/0000/" \
 | 
			
		||||
		>"$HTTPD_ROOT_PATH/one-time-sed" &&
 | 
			
		||||
 | 
			
		||||
	test_must_fail git -C http_child -c protocol.version=2 \
 | 
			
		||||
		fetch "$HTTPD_URL/one_time_sed/http_parent" 2> err &&
 | 
			
		||||
	test_i18ngrep "expected packfile to be sent after .ready." err
 | 
			
		||||
'
 | 
			
		||||
 | 
			
		||||
test_expect_success 'when server does not send "ready", expect FLUSH' '
 | 
			
		||||
	rm -rf "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" http_child log &&
 | 
			
		||||
 | 
			
		||||
	git init "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" &&
 | 
			
		||||
	test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" one &&
 | 
			
		||||
 | 
			
		||||
	git clone "$HTTPD_URL/smart/http_parent" http_child &&
 | 
			
		||||
 | 
			
		||||
	test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" two &&
 | 
			
		||||
 | 
			
		||||
	# Create many commits to extend the negotiation phase across multiple
 | 
			
		||||
	# requests, so that the server does not send "ready" in the first
 | 
			
		||||
	# request.
 | 
			
		||||
	for i in $(test_seq 1 32)
 | 
			
		||||
	do
 | 
			
		||||
		test_commit -C http_child c$i
 | 
			
		||||
	done &&
 | 
			
		||||
 | 
			
		||||
	# After the acknowledgments section, pretend that a DELIM
 | 
			
		||||
	# (0001) was sent instead of a FLUSH (0000).
 | 
			
		||||
	printf "/acknowledgments/,$ s/0000/0001/" \
 | 
			
		||||
		>"$HTTPD_ROOT_PATH/one-time-sed" &&
 | 
			
		||||
 | 
			
		||||
	test_must_fail env GIT_TRACE_PACKET="$(pwd)/log" git -C http_child \
 | 
			
		||||
		-c protocol.version=2 \
 | 
			
		||||
		fetch "$HTTPD_URL/one_time_sed/http_parent" 2> err &&
 | 
			
		||||
	grep "fetch< acknowledgments" log &&
 | 
			
		||||
	! grep "fetch< ready" log &&
 | 
			
		||||
	test_i18ngrep "expected no other sections to be sent after no .ready." err
 | 
			
		||||
'
 | 
			
		||||
 | 
			
		||||
stop_httpd
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue