Commit 02b4c1e2a426404ad7cad8e8a114f7f36bdb8b59

Carlos Martín Nieto 2014-11-01T16:58:20

Port the TCP transport to the new stream API

diff --git a/src/netops.c b/src/netops.c
index 23e7e9d..ab135c4 100644
--- a/src/netops.c
+++ b/src/netops.c
@@ -104,6 +104,16 @@ static int ssl_set_error(gitno_ssl *ssl, int error)
 
 int gitno_recv(gitno_buffer *buf)
 {
+	if (buf->io) {
+		int ret;
+		ret = git_stream_read(buf->io, buf->data + buf->offset, buf->len - buf->offset);
+		if (ret < 0)
+			return -1;
+
+		buf->offset += ret;
+		return ret;
+	}
+
 	return buf->recv(buf);
 }
 
@@ -168,6 +178,15 @@ void gitno_buffer_setup(gitno_socket *socket, gitno_buffer *buf, char *data, siz
 	gitno_buffer_setup_callback(socket, buf, data, len, gitno__recv, NULL);
 }
 
+void gitno_buffer_setup_fromstream(git_stream *st, gitno_buffer *buf, char *data, size_t len)
+{
+	memset(data, 0x0, len);
+	buf->data = data;
+	buf->len = len;
+	buf->offset = 0;
+	buf->io = st;
+}
+
 /* Consume up to ptr and move the rest of the buffer to the beginning */
 void gitno_consume(gitno_buffer *buf, const char *ptr)
 {
diff --git a/src/netops.h b/src/netops.h
index 8ad9153..fee6d82 100644
--- a/src/netops.h
+++ b/src/netops.h
@@ -9,6 +9,7 @@
 
 #include "posix.h"
 #include "common.h"
+#include "stream.h"
 
 #ifdef GIT_SSL
 # include <openssl/ssl.h>
@@ -32,6 +33,7 @@ typedef struct gitno_buffer {
 	char *data;
 	size_t len;
 	size_t offset;
+	git_stream *io;
 	gitno_socket *socket;
 	int (*recv)(struct gitno_buffer *buffer);
 	void *cb_data;
@@ -57,6 +59,7 @@ enum {
 int gitno__match_host(const char *pattern, const char *host);
 
 void gitno_buffer_setup(gitno_socket *t, gitno_buffer *buf, char *data, size_t len);
+void gitno_buffer_setup_fromstream(git_stream *st, gitno_buffer *buf, char *data, size_t len);
 void gitno_buffer_setup_callback(gitno_socket *t, gitno_buffer *buf, char *data, size_t len, int (*recv)(gitno_buffer *buf), void *cb_data);
 int gitno_recv(gitno_buffer *buf);
 
diff --git a/src/transports/git.c b/src/transports/git.c
index e2690fe..6f25736 100644
--- a/src/transports/git.c
+++ b/src/transports/git.c
@@ -9,6 +9,8 @@
 #include "buffer.h"
 #include "netops.h"
 #include "git2/sys/transport.h"
+#include "stream.h"
+#include "socket_stream.h"
 
 #define OWNING_SUBTRANSPORT(s) ((git_subtransport *)(s)->parent.subtransport)
 
@@ -18,16 +20,16 @@ static const char cmd_receivepack[] = "git-receive-pack";
 
 typedef struct {
 	git_smart_subtransport_stream parent;
-	gitno_socket socket;
+	git_stream *io;
 	const char *cmd;
 	char *url;
 	unsigned sent_command : 1;
-} git_stream;
+} git_proto_stream;
 
 typedef struct {
 	git_smart_subtransport parent;
 	git_transport *owner;
-	git_stream *current_stream;
+	git_proto_stream *current_stream;
 } git_subtransport;
 
 /*
@@ -67,7 +69,7 @@ static int gen_proto(git_buf *request, const char *cmd, const char *url)
 	return 0;
 }
 
-static int send_command(git_stream *s)
+static int send_command(git_proto_stream *s)
 {
 	int error;
 	git_buf request = GIT_BUF_INIT;
@@ -76,10 +78,7 @@ static int send_command(git_stream *s)
 	if (error < 0)
 		goto cleanup;
 
-	/* It looks like negative values are errors here, and positive values
-	 * are the number of bytes sent. */
-	error = gitno_send(&s->socket, request.ptr, request.size, 0);
-
+	error = git_stream_write(s->io, request.ptr, request.size, 0);
 	if (error >= 0)
 		s->sent_command = 1;
 
@@ -88,14 +87,14 @@ cleanup:
 	return error;
 }
 
-static int git_stream_read(
+static int git_proto_stream_read(
 	git_smart_subtransport_stream *stream,
 	char *buffer,
 	size_t buf_size,
 	size_t *bytes_read)
 {
 	int error;
-	git_stream *s = (git_stream *)stream;
+	git_proto_stream *s = (git_proto_stream *)stream;
 	gitno_buffer buf;
 
 	*bytes_read = 0;
@@ -103,7 +102,7 @@ static int git_stream_read(
 	if (!s->sent_command && (error = send_command(s)) < 0)
 		return error;
 
-	gitno_buffer_setup(&s->socket, &buf, buffer, buf_size);
+	gitno_buffer_setup_fromstream(s->io, &buf, buffer, buf_size);
 
 	if ((error = gitno_recv(&buf)) < 0)
 		return error;
@@ -113,23 +112,23 @@ static int git_stream_read(
 	return 0;
 }
 
-static int git_stream_write(
+static int git_proto_stream_write(
 	git_smart_subtransport_stream *stream,
 	const char *buffer,
 	size_t len)
 {
 	int error;
-	git_stream *s = (git_stream *)stream;
+	git_proto_stream *s = (git_proto_stream *)stream;
 
 	if (!s->sent_command && (error = send_command(s)) < 0)
 		return error;
 
-	return gitno_send(&s->socket, buffer, len, 0);
+	return git_stream_write(s->io, buffer, len, 0);
 }
 
-static void git_stream_free(git_smart_subtransport_stream *stream)
+static void git_proto_stream_free(git_smart_subtransport_stream *stream)
 {
-	git_stream *s = (git_stream *)stream;
+	git_proto_stream *s = (git_proto_stream *)stream;
 	git_subtransport *t = OWNING_SUBTRANSPORT(s);
 	int ret;
 
@@ -137,33 +136,31 @@ static void git_stream_free(git_smart_subtransport_stream *stream)
 
 	t->current_stream = NULL;
 
-	if (s->socket.socket) {
-		ret = gitno_close(&s->socket);
-		assert(!ret);
-	}
-
+	git_stream_free(s->io);
 	git__free(s->url);
 	git__free(s);
 }
 
-static int git_stream_alloc(
+static int git_proto_stream_alloc(
 	git_subtransport *t,
 	const char *url,
 	const char *cmd,
+	const char *host,
+	const char *port,
 	git_smart_subtransport_stream **stream)
 {
-	git_stream *s;
+	git_proto_stream *s;
 
 	if (!stream)
 		return -1;
 
-	s = git__calloc(sizeof(git_stream), 1);
+	s = git__calloc(sizeof(git_proto_stream), 1);
 	GITERR_CHECK_ALLOC(s);
 
 	s->parent.subtransport = &t->parent;
-	s->parent.read = git_stream_read;
-	s->parent.write = git_stream_write;
-	s->parent.free = git_stream_free;
+	s->parent.read = git_proto_stream_read;
+	s->parent.write = git_proto_stream_write;
+	s->parent.free = git_proto_stream_free;
 
 	s->cmd = cmd;
 	s->url = git__strdup(url);
@@ -173,6 +170,11 @@ static int git_stream_alloc(
 		return -1;
 	}
 
+	if ((git_socket_stream_new(&s->io, host, port)) < 0)
+		return -1;
+
+	GITERR_CHECK_VERSION(s->io, GIT_STREAM_VERSION, "git_stream");
+
 	*stream = &s->parent;
 	return 0;
 }
@@ -184,7 +186,7 @@ static int _git_uploadpack_ls(
 {
 	char *host=NULL, *port=NULL, *path=NULL, *user=NULL, *pass=NULL;
 	const char *stream_url = url;
-	git_stream *s;
+	git_proto_stream *s;
 	int error;
 
 	*stream = NULL;
@@ -192,26 +194,32 @@ static int _git_uploadpack_ls(
 	if (!git__prefixcmp(url, prefix_git))
 		stream_url += strlen(prefix_git);
 
-	if ((error = git_stream_alloc(t, stream_url, cmd_uploadpack, stream)) < 0)
+	if ((error = gitno_extract_url_parts(&host, &port, &path, &user, &pass, url, GIT_DEFAULT_PORT)) < 0)
 		return error;
 
-	s = (git_stream *)*stream;
+	error = git_proto_stream_alloc(t, stream_url, cmd_uploadpack, host, port, stream);
 
-	if (!(error = gitno_extract_url_parts(
-			&host, &port, &path, &user, &pass, url, GIT_DEFAULT_PORT))) {
+	git__free(host);
+	git__free(port);
+	git__free(path);
+	git__free(user);
+	git__free(pass);
 
-		if (!(error = gitno_connect(&s->socket, host, port, 0)))
-			t->current_stream = s;
 
-		git__free(host);
-		git__free(port);
-		git__free(path);
-		git__free(user);
-		git__free(pass);
-	} else if (*stream)
-		git_stream_free(*stream);
+	if (error < 0) {
+		git_proto_stream_free(*stream);
+		return error;
+	}
 
-	return error;
+	s = (git_proto_stream *) *stream;
+	if ((error = git_stream_connect(s->io)) < 0) {
+		git_proto_stream_free(*stream);
+		return error;
+	}
+
+	t->current_stream = s;
+
+	return 0;
 }
 
 static int _git_uploadpack(
@@ -237,31 +245,37 @@ static int _git_receivepack_ls(
 {
 	char *host=NULL, *port=NULL, *path=NULL, *user=NULL, *pass=NULL;
 	const char *stream_url = url;
-	git_stream *s;
+	git_proto_stream *s;
 	int error;
 
 	*stream = NULL;
 	if (!git__prefixcmp(url, prefix_git))
 		stream_url += strlen(prefix_git);
 
-	if (git_stream_alloc(t, stream_url, cmd_receivepack, stream) < 0)
-		return -1;
+	if ((error = gitno_extract_url_parts(&host, &port, &path, &user, &pass, url, GIT_DEFAULT_PORT)) < 0)
+		return error;
+
+	error = git_proto_stream_alloc(t, stream_url, cmd_receivepack, host, port, stream);
+
+	git__free(host);
+	git__free(port);
+	git__free(path);
+	git__free(user);
+	git__free(pass);
 
-	s = (git_stream *)*stream;
+	if (error < 0) {
+		git_proto_stream_free(*stream);
+		return error;
+	}
+
+	s = (git_proto_stream *) *stream;
 
-	if (!(error = gitno_extract_url_parts(&host, &port, &path, &user, &pass, url, GIT_DEFAULT_PORT))) {
-		if (!(error = gitno_connect(&s->socket, host, port, 0)))
-			t->current_stream = s;
+	if ((error = git_stream_connect(s->io)) < 0)
+		return error;
 
-		git__free(host);
-		git__free(port);
-		git__free(path);
-		git__free(user);
-		git__free(pass);
-	} else if (*stream)
-		git_stream_free(*stream);
+	t->current_stream = s;
 
-	return error;
+	return 0;
 }
 
 static int _git_receivepack(