pkt-line: share buffer/descriptor reading implementation
The packet_read function reads from a descriptor. The packet_get_line function is similar, but reads from an in-memory buffer, and uses a completely separate implementation. This patch teaches the generic packet_read function to accept either source, and we can do away with packet_get_line's implementation. There are two other differences to account for between the old and new functions. The first is that we used to read into a strbuf, but now read into a fixed size buffer. The only two callers are fine with that, and in fact it simplifies their code, since they can use the same static-buffer interface as the rest of the packet_read_line callers (and we provide a similar convenience wrapper for reading from a buffer rather than a descriptor). This is technically an externally-visible behavior change in that we used to accept arbitrary sized packets up to 65532 bytes, and now cap out at LARGE_PACKET_MAX, 65520. In practice this doesn't matter, as we use it only for parsing smart-http headers (of which there is exactly one defined, and it is small and fixed-size). And any extension headers would be breaking the protocol to go over LARGE_PACKET_MAX anyway. The other difference is that packet_get_line would return on error rather than dying. However, both callers of packet_get_line are actually improved by dying. The first caller does its own error checking, but we can drop that; as a result, we'll actually get more specific reporting about protocol breakage when packet_read dies internally. The only downside is that packet_read will not print the smart-http URL that failed, but that's not a big deal; anybody not debugging can already see the remote's URL already, and anybody debugging would want to run with GIT_CURL_VERBOSE anyway to see way more information. The second caller, which is just trying to skip past any extra smart-http headers (of which there are none defined, but which we allow to keep room for future expansion), did not error check at all. As a result, it would treat an error just like a flush packet. The resulting mess would generally cause an error later in get_remote_heads, but now we get error reporting much closer to the source of the problem. Brown-paper-bag-fixes-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
74543a0423
commit
4981fe750b
@ -138,28 +138,26 @@ static struct discovery* discover_refs(const char *service)
|
||||
if (maybe_smart &&
|
||||
(5 <= last->len && last->buf[4] == '#') &&
|
||||
!strbuf_cmp(&exp, &type)) {
|
||||
char *line;
|
||||
|
||||
/*
|
||||
* smart HTTP response; validate that the service
|
||||
* pkt-line matches our request.
|
||||
*/
|
||||
if (packet_get_line(&buffer, &last->buf, &last->len) <= 0)
|
||||
die("%s has invalid packet header", refs_url);
|
||||
if (buffer.len && buffer.buf[buffer.len - 1] == '\n')
|
||||
strbuf_setlen(&buffer, buffer.len - 1);
|
||||
line = packet_read_line_buf(&last->buf, &last->len, NULL);
|
||||
|
||||
strbuf_reset(&exp);
|
||||
strbuf_addf(&exp, "# service=%s", service);
|
||||
if (strbuf_cmp(&exp, &buffer))
|
||||
die("invalid server response; got '%s'", buffer.buf);
|
||||
if (strcmp(line, exp.buf))
|
||||
die("invalid server response; got '%s'", line);
|
||||
strbuf_release(&exp);
|
||||
|
||||
/* The header can include additional metadata lines, up
|
||||
* until a packet flush marker. Ignore these now, but
|
||||
* in the future we might start to scan them.
|
||||
*/
|
||||
strbuf_reset(&buffer);
|
||||
while (packet_get_line(&buffer, &last->buf, &last->len) > 0)
|
||||
strbuf_reset(&buffer);
|
||||
while (packet_read_line_buf(&last->buf, &last->len, NULL))
|
||||
;
|
||||
|
||||
last->proto_git = 1;
|
||||
}
|
||||
@ -308,7 +306,7 @@ static size_t rpc_out(void *ptr, size_t eltsize,
|
||||
|
||||
if (!avail) {
|
||||
rpc->initial_buffer = 0;
|
||||
avail = packet_read(rpc->out, rpc->buf, rpc->alloc, 0);
|
||||
avail = packet_read(rpc->out, NULL, NULL, rpc->buf, rpc->alloc, 0);
|
||||
if (!avail)
|
||||
return 0;
|
||||
rpc->pos = 0;
|
||||
@ -425,7 +423,7 @@ static int post_rpc(struct rpc_state *rpc)
|
||||
break;
|
||||
}
|
||||
|
||||
n = packet_read(rpc->out, buf, left, 0);
|
||||
n = packet_read(rpc->out, NULL, NULL, buf, left, 0);
|
||||
if (!n)
|
||||
break;
|
||||
rpc->len += n;
|
||||
@ -579,7 +577,7 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads)
|
||||
rpc->hdr_accept = strbuf_detach(&buf, NULL);
|
||||
|
||||
while (!err) {
|
||||
int n = packet_read(rpc->out, rpc->buf, rpc->alloc, 0);
|
||||
int n = packet_read(rpc->out, NULL, NULL, rpc->buf, rpc->alloc, 0);
|
||||
if (!n)
|
||||
break;
|
||||
rpc->pos = 0;
|
||||
|
||||
Reference in New Issue
Block a user