@@ -331,9 +331,63 @@ static int get_protocol_http_header(enum protocol_version version,
331
331
return 0 ;
332
332
}
333
333
334
+ static void check_smart_http (struct discovery * d , const char * service ,
335
+ struct strbuf * type )
336
+ {
337
+ const char * p ;
338
+ struct packet_reader reader ;
339
+
340
+ /*
341
+ * If we don't see x-$service-advertisement, then it's not smart-http.
342
+ * But once we do, we commit to it and assume any other protocol
343
+ * violations are hard errors.
344
+ */
345
+ if (!skip_prefix (type -> buf , "application/x-" , & p ) ||
346
+ !skip_prefix (p , service , & p ) ||
347
+ strcmp (p , "-advertisement" ))
348
+ return ;
349
+
350
+ packet_reader_init (& reader , -1 , d -> buf , d -> len ,
351
+ PACKET_READ_CHOMP_NEWLINE |
352
+ PACKET_READ_DIE_ON_ERR_PACKET );
353
+ if (packet_reader_read (& reader ) != PACKET_READ_NORMAL )
354
+ die ("invalid server response; expected service, got flush packet" );
355
+
356
+ if (skip_prefix (reader .line , "# service=" , & p ) && !strcmp (p , service )) {
357
+ /*
358
+ * The header can include additional metadata lines, up
359
+ * until a packet flush marker. Ignore these now, but
360
+ * in the future we might start to scan them.
361
+ */
362
+ for (;;) {
363
+ packet_reader_read (& reader );
364
+ if (reader .pktlen <= 0 ) {
365
+ break ;
366
+ }
367
+ }
368
+
369
+ /*
370
+ * v0 smart http; callers expect us to soak up the
371
+ * service and header packets
372
+ */
373
+ d -> buf = reader .src_buffer ;
374
+ d -> len = reader .src_len ;
375
+ d -> proto_git = 1 ;
376
+
377
+ } else if (!strcmp (reader .line , "version 2" )) {
378
+ /*
379
+ * v2 smart http; do not consume version packet, which will
380
+ * be handled elsewhere.
381
+ */
382
+ d -> proto_git = 1 ;
383
+
384
+ } else {
385
+ die ("invalid server response; got '%s'" , reader .line );
386
+ }
387
+ }
388
+
334
389
static struct discovery * discover_refs (const char * service , int for_push )
335
390
{
336
- struct strbuf exp = STRBUF_INIT ;
337
391
struct strbuf type = STRBUF_INIT ;
338
392
struct strbuf charset = STRBUF_INIT ;
339
393
struct strbuf buffer = STRBUF_INIT ;
@@ -405,55 +459,15 @@ static struct discovery *discover_refs(const char *service, int for_push)
405
459
last -> buf_alloc = strbuf_detach (& buffer , & last -> len );
406
460
last -> buf = last -> buf_alloc ;
407
461
408
- strbuf_addf (& exp , "application/x-%s-advertisement" , service );
409
- if (maybe_smart &&
410
- (5 <= last -> len && last -> buf [4 ] == '#' ) &&
411
- !strbuf_cmp (& exp , & type )) {
412
- struct packet_reader reader ;
413
- packet_reader_init (& reader , -1 , last -> buf , last -> len ,
414
- PACKET_READ_CHOMP_NEWLINE |
415
- PACKET_READ_DIE_ON_ERR_PACKET );
416
-
417
- /*
418
- * smart HTTP response; validate that the service
419
- * pkt-line matches our request.
420
- */
421
- if (packet_reader_read (& reader ) != PACKET_READ_NORMAL )
422
- die ("invalid server response; expected service, got flush packet" );
423
-
424
- strbuf_reset (& exp );
425
- strbuf_addf (& exp , "# service=%s" , service );
426
- if (strcmp (reader .line , exp .buf ))
427
- die ("invalid server response; got '%s'" , reader .line );
428
- strbuf_release (& exp );
429
-
430
- /* The header can include additional metadata lines, up
431
- * until a packet flush marker. Ignore these now, but
432
- * in the future we might start to scan them.
433
- */
434
- for (;;) {
435
- packet_reader_read (& reader );
436
- if (reader .pktlen <= 0 ) {
437
- break ;
438
- }
439
- }
440
-
441
- last -> buf = reader .src_buffer ;
442
- last -> len = reader .src_len ;
443
-
444
- last -> proto_git = 1 ;
445
- } else if (maybe_smart &&
446
- last -> len > 5 && starts_with (last -> buf + 4 , "version 2" )) {
447
- last -> proto_git = 1 ;
448
- }
462
+ if (maybe_smart )
463
+ check_smart_http (last , service , & type );
449
464
450
465
if (last -> proto_git )
451
466
last -> refs = parse_git_refs (last , for_push );
452
467
else
453
468
last -> refs = parse_info_refs (last );
454
469
455
470
strbuf_release (& refs_url );
456
- strbuf_release (& exp );
457
471
strbuf_release (& type );
458
472
strbuf_release (& charset );
459
473
strbuf_release (& effective_url );
0 commit comments