Skip to content

Commit 01f9ec6

Browse files
draftcodegitster
authored andcommitted
Use packet_reader instead of packet_read_line
By using and sharing a packet_reader while handling a Git pack protocol request, the same reader option is used throughout the code. This makes it easy to set a reader option to the request parsing code. Signed-off-by: Masaya Suzuki <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b21ebb6 commit 01f9ec6

File tree

6 files changed

+129
-108
lines changed

6 files changed

+129
-108
lines changed

builtin/archive.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ static int run_remote_archiver(int argc, const char **argv,
2727
const char *remote, const char *exec,
2828
const char *name_hint)
2929
{
30-
char *buf;
3130
int fd[2], i, rv;
3231
struct transport *transport;
3332
struct remote *_remote;
33+
struct packet_reader reader;
3434

3535
_remote = remote_get(remote);
3636
if (!_remote->url[0])
@@ -53,18 +53,19 @@ static int run_remote_archiver(int argc, const char **argv,
5353
packet_write_fmt(fd[1], "argument %s\n", argv[i]);
5454
packet_flush(fd[1]);
5555

56-
buf = packet_read_line(fd[0], NULL);
57-
if (!buf)
56+
packet_reader_init(&reader, fd[0], NULL, 0, PACKET_READ_CHOMP_NEWLINE);
57+
58+
if (packet_reader_read(&reader) != PACKET_READ_NORMAL)
5859
die(_("git archive: expected ACK/NAK, got a flush packet"));
59-
if (strcmp(buf, "ACK")) {
60-
if (starts_with(buf, "NACK "))
61-
die(_("git archive: NACK %s"), buf + 5);
62-
if (starts_with(buf, "ERR "))
63-
die(_("remote error: %s"), buf + 4);
60+
if (strcmp(reader.line, "ACK")) {
61+
if (starts_with(reader.line, "NACK "))
62+
die(_("git archive: NACK %s"), reader.line + 5);
63+
if (starts_with(reader.line, "ERR "))
64+
die(_("remote error: %s"), reader.line + 4);
6465
die(_("git archive: protocol error"));
6566
}
6667

67-
if (packet_read_line(fd[0], NULL))
68+
if (packet_reader_read(&reader) != PACKET_READ_FLUSH)
6869
die(_("git archive: expected a flush"));
6970

7071
/* Now, start reading from fd[0] and spit it out to stdout */

builtin/receive-pack.c

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,30 +1569,29 @@ static void queue_commands_from_cert(struct command **tail,
15691569
}
15701570
}
15711571

1572-
static struct command *read_head_info(struct oid_array *shallow)
1572+
static struct command *read_head_info(struct packet_reader *reader,
1573+
struct oid_array *shallow)
15731574
{
15741575
struct command *commands = NULL;
15751576
struct command **p = &commands;
15761577
for (;;) {
1577-
char *line;
1578-
int len, linelen;
1578+
int linelen;
15791579

1580-
line = packet_read_line(0, &len);
1581-
if (!line)
1580+
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
15821581
break;
15831582

1584-
if (len > 8 && starts_with(line, "shallow ")) {
1583+
if (reader->pktlen > 8 && starts_with(reader->line, "shallow ")) {
15851584
struct object_id oid;
1586-
if (get_oid_hex(line + 8, &oid))
1585+
if (get_oid_hex(reader->line + 8, &oid))
15871586
die("protocol error: expected shallow sha, got '%s'",
1588-
line + 8);
1587+
reader->line + 8);
15891588
oid_array_append(shallow, &oid);
15901589
continue;
15911590
}
15921591

1593-
linelen = strlen(line);
1594-
if (linelen < len) {
1595-
const char *feature_list = line + linelen + 1;
1592+
linelen = strlen(reader->line);
1593+
if (linelen < reader->pktlen) {
1594+
const char *feature_list = reader->line + linelen + 1;
15961595
if (parse_feature_request(feature_list, "report-status"))
15971596
report_status = 1;
15981597
if (parse_feature_request(feature_list, "side-band-64k"))
@@ -1607,28 +1606,32 @@ static struct command *read_head_info(struct oid_array *shallow)
16071606
use_push_options = 1;
16081607
}
16091608

1610-
if (!strcmp(line, "push-cert")) {
1609+
if (!strcmp(reader->line, "push-cert")) {
16111610
int true_flush = 0;
1612-
char certbuf[1024];
1611+
int saved_options = reader->options;
1612+
reader->options &= ~PACKET_READ_CHOMP_NEWLINE;
16131613

16141614
for (;;) {
1615-
len = packet_read(0, NULL, NULL,
1616-
certbuf, sizeof(certbuf), 0);
1617-
if (!len) {
1615+
packet_reader_read(reader);
1616+
if (reader->status == PACKET_READ_FLUSH) {
16181617
true_flush = 1;
16191618
break;
16201619
}
1621-
if (!strcmp(certbuf, "push-cert-end\n"))
1620+
if (reader->status != PACKET_READ_NORMAL) {
1621+
die("protocol error: got an unexpected packet");
1622+
}
1623+
if (!strcmp(reader->line, "push-cert-end\n"))
16221624
break; /* end of cert */
1623-
strbuf_addstr(&push_cert, certbuf);
1625+
strbuf_addstr(&push_cert, reader->line);
16241626
}
1627+
reader->options = saved_options;
16251628

16261629
if (true_flush)
16271630
break;
16281631
continue;
16291632
}
16301633

1631-
p = queue_command(p, line, linelen);
1634+
p = queue_command(p, reader->line, linelen);
16321635
}
16331636

16341637
if (push_cert.len)
@@ -1637,18 +1640,14 @@ static struct command *read_head_info(struct oid_array *shallow)
16371640
return commands;
16381641
}
16391642

1640-
static void read_push_options(struct string_list *options)
1643+
static void read_push_options(struct packet_reader *reader,
1644+
struct string_list *options)
16411645
{
16421646
while (1) {
1643-
char *line;
1644-
int len;
1645-
1646-
line = packet_read_line(0, &len);
1647-
1648-
if (!line)
1647+
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
16491648
break;
16501649

1651-
string_list_append(options, line);
1650+
string_list_append(options, reader->line);
16521651
}
16531652
}
16541653

@@ -1924,6 +1923,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
19241923
struct oid_array shallow = OID_ARRAY_INIT;
19251924
struct oid_array ref = OID_ARRAY_INIT;
19261925
struct shallow_info si;
1926+
struct packet_reader reader;
19271927

19281928
struct option options[] = {
19291929
OPT__QUIET(&quiet, N_("quiet")),
@@ -1986,12 +1986,14 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
19861986
if (advertise_refs)
19871987
return 0;
19881988

1989-
if ((commands = read_head_info(&shallow)) != NULL) {
1989+
packet_reader_init(&reader, 0, NULL, 0, PACKET_READ_CHOMP_NEWLINE);
1990+
1991+
if ((commands = read_head_info(&reader, &shallow)) != NULL) {
19901992
const char *unpack_status = NULL;
19911993
struct string_list push_options = STRING_LIST_INIT_DUP;
19921994

19931995
if (use_push_options)
1994-
read_push_options(&push_options);
1996+
read_push_options(&reader, &push_options);
19951997
if (!check_cert_push_options(&push_options)) {
19961998
struct command *cmd;
19971999
for (cmd = commands; cmd; cmd = cmd->next)

fetch-pack.c

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -135,38 +135,42 @@ enum ack_type {
135135
ACK_ready
136136
};
137137

138-
static void consume_shallow_list(struct fetch_pack_args *args, int fd)
138+
static void consume_shallow_list(struct fetch_pack_args *args,
139+
struct packet_reader *reader)
139140
{
140141
if (args->stateless_rpc && args->deepen) {
141142
/* If we sent a depth we will get back "duplicate"
142143
* shallow and unshallow commands every time there
143144
* is a block of have lines exchanged.
144145
*/
145-
char *line;
146-
while ((line = packet_read_line(fd, NULL))) {
147-
if (starts_with(line, "shallow "))
146+
while (packet_reader_read(reader) == PACKET_READ_NORMAL) {
147+
if (starts_with(reader->line, "shallow "))
148148
continue;
149-
if (starts_with(line, "unshallow "))
149+
if (starts_with(reader->line, "unshallow "))
150150
continue;
151151
die(_("git fetch-pack: expected shallow list"));
152152
}
153+
if (reader->status != PACKET_READ_FLUSH)
154+
die(_("git fetch-pack: expected a flush packet after shallow list"));
153155
}
154156
}
155157

156-
static enum ack_type get_ack(int fd, struct object_id *result_oid)
158+
static enum ack_type get_ack(struct packet_reader *reader,
159+
struct object_id *result_oid)
157160
{
158161
int len;
159-
char *line = packet_read_line(fd, &len);
160162
const char *arg;
161163

162-
if (!line)
164+
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
163165
die(_("git fetch-pack: expected ACK/NAK, got a flush packet"));
164-
if (!strcmp(line, "NAK"))
166+
len = reader->pktlen;
167+
168+
if (!strcmp(reader->line, "NAK"))
165169
return NAK;
166-
if (skip_prefix(line, "ACK ", &arg)) {
170+
if (skip_prefix(reader->line, "ACK ", &arg)) {
167171
if (!get_oid_hex(arg, result_oid)) {
168172
arg += 40;
169-
len -= arg - line;
173+
len -= arg - reader->line;
170174
if (len < 1)
171175
return ACK;
172176
if (strstr(arg, "continue"))
@@ -178,9 +182,9 @@ static enum ack_type get_ack(int fd, struct object_id *result_oid)
178182
return ACK;
179183
}
180184
}
181-
if (skip_prefix(line, "ERR ", &arg))
185+
if (skip_prefix(reader->line, "ERR ", &arg))
182186
die(_("remote error: %s"), arg);
183-
die(_("git fetch-pack: expected ACK/NAK, got '%s'"), line);
187+
die(_("git fetch-pack: expected ACK/NAK, got '%s'"), reader->line);
184188
}
185189

186190
static void send_request(struct fetch_pack_args *args,
@@ -248,10 +252,14 @@ static int find_common(struct fetch_negotiator *negotiator,
248252
int got_ready = 0;
249253
struct strbuf req_buf = STRBUF_INIT;
250254
size_t state_len = 0;
255+
struct packet_reader reader;
251256

252257
if (args->stateless_rpc && multi_ack == 1)
253258
die(_("--stateless-rpc requires multi_ack_detailed"));
254259

260+
packet_reader_init(&reader, fd[0], NULL, 0,
261+
PACKET_READ_CHOMP_NEWLINE);
262+
255263
if (!args->no_dependents) {
256264
mark_tips(negotiator, args->negotiation_tips);
257265
for_each_cached_alternate(negotiator, insert_one_alternate_object);
@@ -336,31 +344,30 @@ static int find_common(struct fetch_negotiator *negotiator,
336344
state_len = req_buf.len;
337345

338346
if (args->deepen) {
339-
char *line;
340347
const char *arg;
341348
struct object_id oid;
342349

343350
send_request(args, fd[1], &req_buf);
344-
while ((line = packet_read_line(fd[0], NULL))) {
345-
if (skip_prefix(line, "shallow ", &arg)) {
351+
while (packet_reader_read(&reader) == PACKET_READ_NORMAL) {
352+
if (skip_prefix(reader.line, "shallow ", &arg)) {
346353
if (get_oid_hex(arg, &oid))
347-
die(_("invalid shallow line: %s"), line);
354+
die(_("invalid shallow line: %s"), reader.line);
348355
register_shallow(the_repository, &oid);
349356
continue;
350357
}
351-
if (skip_prefix(line, "unshallow ", &arg)) {
358+
if (skip_prefix(reader.line, "unshallow ", &arg)) {
352359
if (get_oid_hex(arg, &oid))
353-
die(_("invalid unshallow line: %s"), line);
360+
die(_("invalid unshallow line: %s"), reader.line);
354361
if (!lookup_object(the_repository, oid.hash))
355-
die(_("object not found: %s"), line);
362+
die(_("object not found: %s"), reader.line);
356363
/* make sure that it is parsed as shallow */
357364
if (!parse_object(the_repository, &oid))
358-
die(_("error in object: %s"), line);
365+
die(_("error in object: %s"), reader.line);
359366
if (unregister_shallow(&oid))
360-
die(_("no shallow found: %s"), line);
367+
die(_("no shallow found: %s"), reader.line);
361368
continue;
362369
}
363-
die(_("expected shallow/unshallow, got %s"), line);
370+
die(_("expected shallow/unshallow, got %s"), reader.line);
364371
}
365372
} else if (!args->stateless_rpc)
366373
send_request(args, fd[1], &req_buf);
@@ -397,9 +404,9 @@ static int find_common(struct fetch_negotiator *negotiator,
397404
if (!args->stateless_rpc && count == INITIAL_FLUSH)
398405
continue;
399406

400-
consume_shallow_list(args, fd[0]);
407+
consume_shallow_list(args, &reader);
401408
do {
402-
ack = get_ack(fd[0], result_oid);
409+
ack = get_ack(&reader, result_oid);
403410
if (ack)
404411
print_verbose(args, _("got %s %d %s"), "ack",
405412
ack, oid_to_hex(result_oid));
@@ -469,9 +476,9 @@ static int find_common(struct fetch_negotiator *negotiator,
469476
strbuf_release(&req_buf);
470477

471478
if (!got_ready || !no_done)
472-
consume_shallow_list(args, fd[0]);
479+
consume_shallow_list(args, &reader);
473480
while (flushes || multi_ack) {
474-
int ack = get_ack(fd[0], result_oid);
481+
int ack = get_ack(&reader, result_oid);
475482
if (ack) {
476483
print_verbose(args, _("got %s (%d) %s"), "ack",
477484
ack, oid_to_hex(result_oid));

remote-curl.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -409,28 +409,36 @@ static struct discovery *discover_refs(const char *service, int for_push)
409409
if (maybe_smart &&
410410
(5 <= last->len && last->buf[4] == '#') &&
411411
!strbuf_cmp(&exp, &type)) {
412-
char *line;
412+
struct packet_reader reader;
413+
packet_reader_init(&reader, -1, last->buf, last->len,
414+
PACKET_READ_CHOMP_NEWLINE);
413415

414416
/*
415417
* smart HTTP response; validate that the service
416418
* pkt-line matches our request.
417419
*/
418-
line = packet_read_line_buf(&last->buf, &last->len, NULL);
419-
if (!line)
420+
if (packet_reader_read(&reader) != PACKET_READ_NORMAL)
420421
die("invalid server response; expected service, got flush packet");
421422

422423
strbuf_reset(&exp);
423424
strbuf_addf(&exp, "# service=%s", service);
424-
if (strcmp(line, exp.buf))
425-
die("invalid server response; got '%s'", line);
425+
if (strcmp(reader.line, exp.buf))
426+
die("invalid server response; got '%s'", reader.line);
426427
strbuf_release(&exp);
427428

428429
/* The header can include additional metadata lines, up
429430
* until a packet flush marker. Ignore these now, but
430431
* in the future we might start to scan them.
431432
*/
432-
while (packet_read_line_buf(&last->buf, &last->len, NULL))
433-
;
433+
for (;;) {
434+
packet_reader_read(&reader);
435+
if (reader.pktlen <= 0) {
436+
break;
437+
}
438+
}
439+
440+
last->buf = reader.src_buffer;
441+
last->len = reader.src_len;
434442

435443
last->proto_git = 1;
436444
} else if (maybe_smart &&

0 commit comments

Comments
 (0)