@@ -48,6 +48,12 @@ int check_ref_type(const struct ref *ref, int flags)
4848
4949static void die_initial_contact (int unexpected )
5050{
51+ /*
52+ * A hang-up after seeing some response from the other end
53+ * means that it is unexpected, as we know the other end is
54+ * willing to talk to us. A hang-up before seeing any
55+ * response does not necessarily mean an ACL problem, though.
56+ */
5157 if (unexpected )
5258 die (_ ("The remote end hung up upon initial contact" ));
5359 else
@@ -56,6 +62,40 @@ static void die_initial_contact(int unexpected)
5662 "and the repository exists." ));
5763}
5864
65+ static enum protocol_version discover_version (struct packet_reader * reader )
66+ {
67+ enum protocol_version version = protocol_unknown_version ;
68+
69+ /*
70+ * Peek the first line of the server's response to
71+ * determine the protocol version the server is speaking.
72+ */
73+ switch (packet_reader_peek (reader )) {
74+ case PACKET_READ_EOF :
75+ die_initial_contact (0 );
76+ case PACKET_READ_FLUSH :
77+ case PACKET_READ_DELIM :
78+ version = protocol_v0 ;
79+ break ;
80+ case PACKET_READ_NORMAL :
81+ version = determine_protocol_version_client (reader -> line );
82+ break ;
83+ }
84+
85+ switch (version ) {
86+ case protocol_v1 :
87+ /* Read the peeked version line */
88+ packet_reader_read (reader );
89+ break ;
90+ case protocol_v0 :
91+ break ;
92+ case protocol_unknown_version :
93+ BUG ("unknown protocol version" );
94+ }
95+
96+ return version ;
97+ }
98+
5999static void parse_one_symref_info (struct string_list * symref , const char * val , int len )
60100{
61101 char * sym , * target ;
@@ -109,60 +149,21 @@ static void annotate_refs_with_symref_info(struct ref *ref)
109149 string_list_clear (& symref , 0 );
110150}
111151
112- /*
113- * Read one line of a server's ref advertisement into packet_buffer.
114- */
115- static int read_remote_ref (int in , char * * src_buf , size_t * src_len ,
116- int * responded )
152+ static void process_capabilities (const char * line , int * len )
117153{
118- int len = packet_read (in , src_buf , src_len ,
119- packet_buffer , sizeof (packet_buffer ),
120- PACKET_READ_GENTLE_ON_EOF |
121- PACKET_READ_CHOMP_NEWLINE );
122- const char * arg ;
123- if (len < 0 )
124- die_initial_contact (* responded );
125- if (len > 4 && skip_prefix (packet_buffer , "ERR " , & arg ))
126- die ("remote error: %s" , arg );
127-
128- * responded = 1 ;
129-
130- return len ;
131- }
132-
133- #define EXPECTING_PROTOCOL_VERSION 0
134- #define EXPECTING_FIRST_REF 1
135- #define EXPECTING_REF 2
136- #define EXPECTING_SHALLOW 3
137-
138- /* Returns 1 if packet_buffer is a protocol version pkt-line, 0 otherwise. */
139- static int process_protocol_version (void )
140- {
141- switch (determine_protocol_version_client (packet_buffer )) {
142- case protocol_v1 :
143- return 1 ;
144- case protocol_v0 :
145- return 0 ;
146- default :
147- die ("server is speaking an unknown protocol" );
148- }
149- }
150-
151- static void process_capabilities (int * len )
152- {
153- int nul_location = strlen (packet_buffer );
154+ int nul_location = strlen (line );
154155 if (nul_location == * len )
155156 return ;
156- server_capabilities = xstrdup (packet_buffer + nul_location + 1 );
157+ server_capabilities = xstrdup (line + nul_location + 1 );
157158 * len = nul_location ;
158159}
159160
160- static int process_dummy_ref (void )
161+ static int process_dummy_ref (const char * line )
161162{
162163 struct object_id oid ;
163164 const char * name ;
164165
165- if (parse_oid_hex (packet_buffer , & oid , & name ))
166+ if (parse_oid_hex (line , & oid , & name ))
166167 return 0 ;
167168 if (* name != ' ' )
168169 return 0 ;
@@ -171,20 +172,20 @@ static int process_dummy_ref(void)
171172 return !oidcmp (& null_oid , & oid ) && !strcmp (name , "capabilities^{}" );
172173}
173174
174- static void check_no_capabilities (int len )
175+ static void check_no_capabilities (const char * line , int len )
175176{
176- if (strlen (packet_buffer ) != len )
177+ if (strlen (line ) != len )
177178 warning ("Ignoring capabilities after first line '%s'" ,
178- packet_buffer + strlen (packet_buffer ));
179+ line + strlen (line ));
179180}
180181
181- static int process_ref (int len , struct ref * * * list , unsigned int flags ,
182- struct oid_array * extra_have )
182+ static int process_ref (const char * line , int len , struct ref * * * list ,
183+ unsigned int flags , struct oid_array * extra_have )
183184{
184185 struct object_id old_oid ;
185186 const char * name ;
186187
187- if (parse_oid_hex (packet_buffer , & old_oid , & name ))
188+ if (parse_oid_hex (line , & old_oid , & name ))
188189 return 0 ;
189190 if (* name != ' ' )
190191 return 0 ;
@@ -200,27 +201,35 @@ static int process_ref(int len, struct ref ***list, unsigned int flags,
200201 * * list = ref ;
201202 * list = & ref -> next ;
202203 }
203- check_no_capabilities (len );
204+ check_no_capabilities (line , len );
204205 return 1 ;
205206}
206207
207- static int process_shallow (int len , struct oid_array * shallow_points )
208+ static int process_shallow (const char * line , int len ,
209+ struct oid_array * shallow_points )
208210{
209211 const char * arg ;
210212 struct object_id old_oid ;
211213
212- if (!skip_prefix (packet_buffer , "shallow " , & arg ))
214+ if (!skip_prefix (line , "shallow " , & arg ))
213215 return 0 ;
214216
215217 if (get_oid_hex (arg , & old_oid ))
216218 die ("protocol error: expected shallow sha-1, got '%s'" , arg );
217219 if (!shallow_points )
218220 die ("repository on the other end cannot be shallow" );
219221 oid_array_append (shallow_points , & old_oid );
220- check_no_capabilities (len );
222+ check_no_capabilities (line , len );
221223 return 1 ;
222224}
223225
226+ enum get_remote_heads_state {
227+ EXPECTING_FIRST_REF = 0 ,
228+ EXPECTING_REF ,
229+ EXPECTING_SHALLOW ,
230+ EXPECTING_DONE ,
231+ };
232+
224233/*
225234 * Read all the refs from the other end
226235 */
@@ -230,47 +239,55 @@ struct ref **get_remote_heads(int in, char *src_buf, size_t src_len,
230239 struct oid_array * shallow_points )
231240{
232241 struct ref * * orig_list = list ;
242+ int len = 0 ;
243+ enum get_remote_heads_state state = EXPECTING_FIRST_REF ;
244+ struct packet_reader reader ;
245+ const char * arg ;
233246
234- /*
235- * A hang-up after seeing some response from the other end
236- * means that it is unexpected, as we know the other end is
237- * willing to talk to us. A hang-up before seeing any
238- * response does not necessarily mean an ACL problem, though.
239- */
240- int responded = 0 ;
241- int len ;
242- int state = EXPECTING_PROTOCOL_VERSION ;
247+ packet_reader_init (& reader , in , src_buf , src_len ,
248+ PACKET_READ_CHOMP_NEWLINE |
249+ PACKET_READ_GENTLE_ON_EOF );
250+
251+ discover_version (& reader );
243252
244253 * list = NULL ;
245254
246- while ((len = read_remote_ref (in , & src_buf , & src_len , & responded ))) {
255+ while (state != EXPECTING_DONE ) {
256+ switch (packet_reader_read (& reader )) {
257+ case PACKET_READ_EOF :
258+ die_initial_contact (1 );
259+ case PACKET_READ_NORMAL :
260+ len = reader .pktlen ;
261+ if (len > 4 && skip_prefix (reader .line , "ERR " , & arg ))
262+ die ("remote error: %s" , arg );
263+ break ;
264+ case PACKET_READ_FLUSH :
265+ state = EXPECTING_DONE ;
266+ break ;
267+ case PACKET_READ_DELIM :
268+ die ("invalid packet" );
269+ }
270+
247271 switch (state ) {
248- case EXPECTING_PROTOCOL_VERSION :
249- if (process_protocol_version ()) {
250- state = EXPECTING_FIRST_REF ;
251- break ;
252- }
253- state = EXPECTING_FIRST_REF ;
254- /* fallthrough */
255272 case EXPECTING_FIRST_REF :
256- process_capabilities (& len );
257- if (process_dummy_ref ()) {
273+ process_capabilities (reader . line , & len );
274+ if (process_dummy_ref (reader . line )) {
258275 state = EXPECTING_SHALLOW ;
259276 break ;
260277 }
261278 state = EXPECTING_REF ;
262279 /* fallthrough */
263280 case EXPECTING_REF :
264- if (process_ref (len , & list , flags , extra_have ))
281+ if (process_ref (reader . line , len , & list , flags , extra_have ))
265282 break ;
266283 state = EXPECTING_SHALLOW ;
267284 /* fallthrough */
268285 case EXPECTING_SHALLOW :
269- if (process_shallow (len , shallow_points ))
286+ if (process_shallow (reader . line , len , shallow_points ))
270287 break ;
271- die ("protocol error: unexpected '%s'" , packet_buffer );
272- default :
273- die ( "unexpected state %d" , state ) ;
288+ die ("protocol error: unexpected '%s'" , reader . line );
289+ case EXPECTING_DONE :
290+ break ;
274291 }
275292 }
276293
0 commit comments