mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-09 09:09:33 +00:00
net: move the reference storage to common code
This commit is contained in:
parent
e4c93a3927
commit
40a40e8e9d
50
src/protocol.c
Normal file
50
src/protocol.c
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2011 the libgit2 contributors
|
||||
*
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
#include "common.h"
|
||||
#include "protocol.h"
|
||||
#include "pkt.h"
|
||||
#include "buffer.h"
|
||||
|
||||
int git_protocol_store_refs(git_protocol *p, const char *data, size_t len)
|
||||
{
|
||||
git_buf *buf = &p->buf;
|
||||
git_vector *refs = p->refs;
|
||||
int error;
|
||||
const char *line_end, *ptr;
|
||||
|
||||
if (len == 0) { /* EOF */
|
||||
if (buf->size != 0)
|
||||
return p->error = git__throw(GIT_ERROR, "EOF and unprocessed data");
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
git_buf_put(buf, data, len);
|
||||
ptr = buf->ptr;
|
||||
while (1) {
|
||||
git_pkt *pkt;
|
||||
|
||||
if (buf->size == 0)
|
||||
return 0;
|
||||
|
||||
error = git_pkt_parse_line(&pkt, ptr, &line_end, buf->size);
|
||||
if (error == GIT_ESHORTBUFFER)
|
||||
return 0; /* Ask for more */
|
||||
if (error < GIT_SUCCESS)
|
||||
return p->error = git__rethrow(error, "Failed to parse pkt-line");
|
||||
|
||||
git_buf_consume(buf, line_end);
|
||||
error = git_vector_insert(refs, pkt);
|
||||
if (error < GIT_SUCCESS)
|
||||
return p->error = git__rethrow(error, "Failed to add pkt to list");
|
||||
|
||||
if (pkt->type == GIT_PKT_FLUSH)
|
||||
p->flush = 1;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
23
src/protocol.h
Normal file
23
src/protocol.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2011 the libgit2 contributors
|
||||
*
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
#ifndef INCLUDE_protocol_h__
|
||||
#define INCLUDE_protocol_h__
|
||||
|
||||
#include "transport.h"
|
||||
#include "buffer.h"
|
||||
|
||||
typedef struct {
|
||||
git_transport *transport;
|
||||
git_vector *refs;
|
||||
git_buf buf;
|
||||
int error;
|
||||
unsigned int flush :1;
|
||||
} git_protocol;
|
||||
|
||||
int git_protocol_store_refs(git_protocol *p, const char *data, size_t len);
|
||||
|
||||
#endif
|
@ -20,9 +20,11 @@
|
||||
#include "filebuf.h"
|
||||
#include "repository.h"
|
||||
#include "fetch.h"
|
||||
#include "protocol.h"
|
||||
|
||||
typedef struct {
|
||||
git_transport parent;
|
||||
git_protocol proto;
|
||||
GIT_SOCKET socket;
|
||||
git_vector refs;
|
||||
git_remote_head **heads;
|
||||
@ -126,11 +128,7 @@ static int do_connect(transport_git *t, const char *url)
|
||||
static int store_refs(transport_git *t)
|
||||
{
|
||||
gitno_buffer *buf = &t->buf;
|
||||
git_vector *refs = &t->refs;
|
||||
int error = GIT_SUCCESS;
|
||||
const char *line_end, *ptr;
|
||||
git_pkt *pkt;
|
||||
|
||||
|
||||
while (1) {
|
||||
error = gitno_recv(buf);
|
||||
@ -139,34 +137,20 @@ static int store_refs(transport_git *t)
|
||||
if (error == GIT_SUCCESS) /* Orderly shutdown, so exit */
|
||||
return GIT_SUCCESS;
|
||||
|
||||
ptr = buf->data;
|
||||
while (1) {
|
||||
if (buf->offset == 0)
|
||||
break;
|
||||
error = git_pkt_parse_line(&pkt, ptr, &line_end, buf->offset);
|
||||
/*
|
||||
* If the error is GIT_ESHORTBUFFER, it means the buffer
|
||||
* isn't long enough to satisfy the request. Break out and
|
||||
* wait for more input.
|
||||
* On any other error, fail.
|
||||
*/
|
||||
if (error == GIT_ESHORTBUFFER) {
|
||||
break;
|
||||
}
|
||||
if (error < GIT_SUCCESS) {
|
||||
return error;
|
||||
}
|
||||
error = git_protocol_store_refs(&t->proto, buf->data, buf->offset);
|
||||
if (error == GIT_ESHORTBUFFER) {
|
||||
gitno_consume_n(buf, buf->len);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get rid of the part we've used already */
|
||||
gitno_consume(buf, line_end);
|
||||
if (error < GIT_SUCCESS)
|
||||
return git__rethrow(error, "Failed to store refs");
|
||||
|
||||
error = git_vector_insert(refs, pkt);
|
||||
if (error < GIT_SUCCESS)
|
||||
return error;
|
||||
|
||||
if (pkt->type == GIT_PKT_FLUSH)
|
||||
return GIT_SUCCESS;
|
||||
gitno_consume_n(buf, buf->offset);
|
||||
|
||||
if (t->proto.flush) { /* No more refs */
|
||||
t->proto.flush = 0;
|
||||
return GIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
@ -476,6 +460,7 @@ static void git_free(git_transport *transport)
|
||||
|
||||
git_vector_free(refs);
|
||||
git__free(t->heads);
|
||||
git_buf_free(&t->proto.buf);
|
||||
git__free(t->parent.url);
|
||||
git__free(t);
|
||||
}
|
||||
@ -501,6 +486,8 @@ int git_transport_git(git_transport **out)
|
||||
t->parent.download_pack = git_download_pack;
|
||||
t->parent.close = git_close;
|
||||
t->parent.free = git_free;
|
||||
t->proto.refs = &t->refs;
|
||||
t->proto.transport = (git_transport *) t;
|
||||
|
||||
*out = (git_transport *) t;
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "fetch.h"
|
||||
#include "filebuf.h"
|
||||
#include "repository.h"
|
||||
#include "protocol.h"
|
||||
|
||||
enum last_cb {
|
||||
NONE,
|
||||
@ -28,6 +29,7 @@ enum last_cb {
|
||||
|
||||
typedef struct {
|
||||
git_transport parent;
|
||||
git_protocol proto;
|
||||
git_vector refs;
|
||||
git_vector common;
|
||||
int socket;
|
||||
@ -186,47 +188,8 @@ static int on_headers_complete(http_parser *parser)
|
||||
static int on_body_store_refs(http_parser *parser, const char *str, size_t len)
|
||||
{
|
||||
transport_http *t = (transport_http *) parser->data;
|
||||
git_buf *buf = &t->buf;
|
||||
git_vector *refs = &t->refs;
|
||||
int error;
|
||||
const char *line_end, *ptr;
|
||||
static int first_pkt = 1;
|
||||
|
||||
if (len == 0) { /* EOF */
|
||||
if (buf->size != 0)
|
||||
return t->error = git__throw(GIT_ERROR, "EOF and unprocessed data");
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
git_buf_put(buf, str, len);
|
||||
ptr = buf->ptr;
|
||||
while (1) {
|
||||
git_pkt *pkt;
|
||||
|
||||
if (buf->size == 0)
|
||||
return 0;
|
||||
|
||||
error = git_pkt_parse_line(&pkt, ptr, &line_end, buf->size);
|
||||
if (error == GIT_ESHORTBUFFER)
|
||||
return 0; /* Ask for more */
|
||||
if (error < GIT_SUCCESS)
|
||||
return t->error = git__rethrow(error, "Failed to parse pkt-line");
|
||||
|
||||
git_buf_consume(buf, line_end);
|
||||
|
||||
if (first_pkt) {
|
||||
first_pkt = 0;
|
||||
if (pkt->type != GIT_PKT_COMMENT)
|
||||
return t->error = git__throw(GIT_EOBJCORRUPTED, "Not a valid smart HTTP response");
|
||||
}
|
||||
|
||||
error = git_vector_insert(refs, pkt);
|
||||
if (error < GIT_SUCCESS)
|
||||
return t->error = git__rethrow(error, "Failed to add pkt to list");
|
||||
}
|
||||
|
||||
return error;
|
||||
return git_protocol_store_refs(&t->proto, str, len);
|
||||
}
|
||||
|
||||
static int on_message_complete(http_parser *parser)
|
||||
@ -243,6 +206,7 @@ static int store_refs(transport_http *t)
|
||||
http_parser_settings settings;
|
||||
char buffer[1024];
|
||||
gitno_buffer buf;
|
||||
git_pkt *pkt;
|
||||
|
||||
http_parser_init(&t->parser, HTTP_RESPONSE);
|
||||
t->parser.data = t;
|
||||
@ -273,6 +237,12 @@ static int store_refs(transport_http *t)
|
||||
return GIT_SUCCESS;
|
||||
}
|
||||
|
||||
pkt = git_vector_get(&t->refs, 0);
|
||||
if (pkt == NULL || pkt->type != GIT_PKT_COMMENT)
|
||||
return t->error = git__throw(GIT_EOBJCORRUPTED, "Not a valid smart HTTP response");
|
||||
else
|
||||
git_vector_remove(&t->refs, 0);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -750,6 +720,7 @@ static void http_free(git_transport *transport)
|
||||
}
|
||||
git_vector_free(common);
|
||||
git_buf_free(&t->buf);
|
||||
git_buf_free(&t->proto.buf);
|
||||
git__free(t->heads);
|
||||
git__free(t->content_type);
|
||||
git__free(t->host);
|
||||
@ -775,6 +746,8 @@ int git_transport_http(git_transport **out)
|
||||
t->parent.download_pack = http_download_pack;
|
||||
t->parent.close = http_close;
|
||||
t->parent.free = http_free;
|
||||
t->proto.refs = &t->refs;
|
||||
t->proto.transport = (git_transport *) t;
|
||||
|
||||
#ifdef GIT_WIN32
|
||||
/* on win32, the WSA context needs to be initialized
|
||||
|
Loading…
Reference in New Issue
Block a user