/*
 * Parse the URL and connect to a server, storing the socket in
 * out. For convenience this also takes care of asking for the remote
 * refs
 */
static int do_connect(transport_git *t, const char *url)
{
	char *host, *port;
	const char prefix[] = "git://";

	if (!git__prefixcmp(url, prefix))
		url += strlen(prefix);

	if (gitno_extract_host_and_port(&host, &port, url, GIT_DEFAULT_PORT) < 0)
		return -1;

	if (gitno_connect((git_transport *)t, host, port) < 0)
		goto on_error;

	if (send_request((git_transport *)t, NULL, url) < 0)
		goto on_error;

	git__free(host);
	git__free(port);

	return 0;

on_error:
	git__free(host);
	git__free(port);
	gitno_close(t->parent.socket);
	return -1;
}
Example #2
0
/*
 * Parse the URL and connect to a server, storing the socket in
 * out. For convenience this also takes care of asking for the remote
 * refs
 */
static int do_connect(transport_git *t, const char *url)
{
	char *host, *port;
	const char prefix[] = "git://";
	int error;

	t->socket = INVALID_SOCKET;

	if (!git__prefixcmp(url, prefix))
		url += strlen(prefix);

	if (gitno_extract_host_and_port(&host, &port, url, GIT_DEFAULT_PORT) < 0)
		return -1;

	if ((error = gitno_connect(&t->socket, host, port)) == 0) {
		error = send_request(t->socket, NULL, url);
	}

	git__free(host);
	git__free(port);

	if (error < 0 && t->socket != INVALID_SOCKET) {
		gitno_close(t->socket);
		t->socket = INVALID_SOCKET;
	}

	if (t->socket == INVALID_SOCKET) {
		giterr_set(GITERR_NET, "Failed to connect to the host");
		return -1;
	}

	return 0;
}
Example #3
0
static int http_connect(git_transport *transport, int direction)
{
	transport_http *t = (transport_http *) transport;
	int ret;
	git_buf request = GIT_BUF_INIT;
	const char *service = "upload-pack";
	const char *url = t->parent.url, *prefix_http = "http://", *prefix_https = "https://";
	const char *default_port;

	if (direction == GIT_DIR_PUSH) {
		giterr_set(GITERR_NET, "Pushing over HTTP is not implemented");
		return -1;
	}

	t->parent.direction = direction;
	if (git_vector_init(&t->refs, 16, NULL) < 0)
		return -1;

	if (!git__prefixcmp(url, prefix_http)) {
		url = t->parent.url + strlen(prefix_http);
		default_port = "80";
	}

	if (!git__prefixcmp(url, prefix_https)) {
		url += strlen(prefix_https);
		default_port = "443";
	}

	t->path = strchr(url, '/');

	if ((ret = gitno_extract_host_and_port(&t->host, &t->port, url, default_port)) < 0)
		goto cleanup;

	t->service = git__strdup(service);
	GITERR_CHECK_ALLOC(t->service);

	if ((ret = do_connect(t, t->host, t->port)) < 0)
		goto cleanup;

	/* Generate and send the HTTP request */
	if ((ret = gen_request(&request, t->path, t->host, "GET", service, 0, 1)) < 0) {
		giterr_set(GITERR_NET, "Failed to generate request");
		goto cleanup;
	}


	if (gitno_send(transport, request.ptr, request.size, 0) < 0)
		goto cleanup;

	ret = store_refs(t);

cleanup:
	git_buf_free(&request);
	git_buf_clear(&t->buf);

	return ret;
}
Example #4
0
static int git_git_uploadpack_ls(
	git_subtransport *t,
	const char *url,
	git_smart_subtransport_stream **stream)
{
	char *host, *port;
	git_stream *s;

	*stream = NULL;

	if (!git__prefixcmp(url, prefix_git))
		url += strlen(prefix_git);

	if (git_stream_alloc(t, url, cmd_uploadpack, stream) < 0)
		return -1;

	s = (git_stream *)*stream;

	if (gitno_extract_host_and_port(&host, &port, url, GIT_DEFAULT_PORT) < 0)
		goto on_error;

	if (gitno_connect(&s->socket, host, port, 0) < 0)
		goto on_error;

	t->current_stream = s;
	git__free(host);
	git__free(port);
	return 0;

on_error:
	if (*stream)
		git_stream_free(*stream);

	git__free(host);
	git__free(port);
	return -1;
}
Example #5
0
static int http_action(
	git_smart_subtransport_stream **stream,
	git_smart_subtransport *subtransport,
	const char *url,
	git_smart_service_t action)
{
	http_subtransport *t = (http_subtransport *)subtransport;
	const char *default_port = NULL;
	int flags = 0, ret;

	if (!stream)
		return -1;

	if (!t->host || !t->port || !t->path) {
		if (!git__prefixcmp(url, prefix_http)) {
			url = url + strlen(prefix_http);
			default_port = "80";
		}

		if (!git__prefixcmp(url, prefix_https)) {
			url += strlen(prefix_https);
			default_port = "443";
			t->use_ssl = 1;
		}

		if (!default_port)
			return -1;

		if ((ret = gitno_extract_host_and_port(&t->host, &t->port,
				url, default_port)) < 0)
			return ret;

		t->path = strchr(url, '/');
	}

	if (!t->connected ||
		!http_should_keep_alive(&t->parser) ||
		!http_body_is_final(&t->parser)) {

		if (t->socket.socket)
			gitno_close(&t->socket);

		if (t->use_ssl) {
			int transport_flags;

			if (t->owner->parent.read_flags(&t->owner->parent, &transport_flags) < 0)
				return -1;

			flags |= GITNO_CONNECT_SSL;

			if (GIT_TRANSPORTFLAGS_NO_CHECK_CERT & transport_flags)
				flags |= GITNO_CONNECT_SSL_NO_CHECK_CERT;
		}

		if (gitno_connect(&t->socket, t->host, t->port, flags) < 0)
			return -1;

		t->connected = 1;
	}

	switch (action)
	{
		case GIT_SERVICE_UPLOADPACK_LS:
			return http_uploadpack_ls(t, stream);

		case GIT_SERVICE_UPLOADPACK:
			return http_uploadpack(t, stream);

		case GIT_SERVICE_RECEIVEPACK_LS:
			return http_receivepack_ls(t, stream);

		case GIT_SERVICE_RECEIVEPACK:
			return http_receivepack(t, stream);
	}

	*stream = NULL;
	return -1;
}