Commit ced9da54 by Vicent Martí

Merge pull request #654 from carlosmn/pkt-err

Recognize and report server-side error messages
parents 0dc8e95e 39e6af6a
......@@ -97,6 +97,25 @@ static int comment_pkt(git_pkt **out, const char *line, size_t len)
return 0;
}
static int err_pkt(git_pkt **out, const char *line, size_t len)
{
git_pkt_err *pkt;
/* Remove "ERR " from the line */
line += 4;
len -= 4;
pkt = git__malloc(sizeof(git_pkt_err) + len + 1);
GITERR_CHECK_ALLOC(pkt);
pkt->type = GIT_PKT_ERR;
memcpy(pkt->error, line, len);
pkt->error[len] = '\0';
*out = (git_pkt *) pkt;
return 0;
}
/*
* Parse an other-ref line.
*/
......@@ -234,6 +253,8 @@ int git_pkt_parse_line(
ret = ack_pkt(head, line, len);
else if (!git__prefixcmp(line, "NAK"))
ret = nak_pkt(head);
else if (!git__prefixcmp(line, "ERR "))
ret = err_pkt(head, line, len);
else if (*line == '#')
ret = comment_pkt(head, line, len);
else
......
......@@ -23,6 +23,7 @@ enum git_pkt_type {
GIT_PKT_NAK,
GIT_PKT_PACK,
GIT_PKT_COMMENT,
GIT_PKT_ERR,
};
/* Used for multi-ack */
......@@ -64,6 +65,11 @@ typedef struct {
char comment[GIT_FLEX_ARRAY];
} git_pkt_comment;
typedef struct {
enum git_pkt_type type;
char error[GIT_FLEX_ARRAY];
} git_pkt_err;
int git_pkt_parse_line(git_pkt **head, const char *line, const char **out, size_t len);
int git_pkt_buffer_flush(git_buf *buf);
int git_pkt_send_flush(GIT_SOCKET s);
......
......@@ -40,6 +40,13 @@ int git_protocol_store_refs(git_protocol *p, const char *data, size_t len)
return p->error = -1;
git_buf_consume(buf, line_end);
if (pkt->type == GIT_PKT_ERR) {
giterr_set(GITERR_NET, "Remote error: %s", ((git_pkt_err *)pkt)->error);
git__free(pkt);
return -1;
}
if (git_vector_insert(refs, pkt) < 0)
return p->error = -1;
......
......@@ -165,6 +165,12 @@ static int on_headers_complete(http_parser *parser)
transport_http *t = (transport_http *) parser->data;
git_buf *buf = &t->buf;
/* The content-type is text/plain for 404, so don't validate */
if (parser->status_code == 404) {
git_buf_clear(buf);
return 0;
}
if (t->content_type == NULL) {
t->content_type = git__strdup(git_buf_cstr(buf));
if (t->content_type == NULL)
......@@ -187,6 +193,10 @@ static int on_body_store_refs(http_parser *parser, const char *str, size_t len)
{
transport_http *t = (transport_http *) parser->data;
if (parser->status_code == 404) {
return git_buf_put(&t->buf, str, len);
}
return git_protocol_store_refs(&t->proto, str, len);
}
......@@ -195,6 +205,12 @@ static int on_message_complete(http_parser *parser)
transport_http *t = (transport_http *) parser->data;
t->transfer_finished = 1;
if (parser->status_code == 404) {
giterr_set(GITERR_NET, "Remote error: %s", git_buf_cstr(&t->buf));
t->error = -1;
}
return 0;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment