/* * 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; }
/* * 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; }
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; }
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; }
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; }