From: Junio C Hamano Date: Sun, 9 May 2010 05:37:24 +0000 (-0700) Subject: Merge branch 'rc/maint-curl-helper' X-Git-Tag: v1.7.2-rc0~148 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/3cc9caadf738c3b2cf7aa46364be173751912a10?ds=sidebyside;hp=-c Merge branch 'rc/maint-curl-helper' * rc/maint-curl-helper: remote-curl: ensure that URLs have a trailing slash http: make end_url_with_slash() public t5541-http-push: add test for URLs with trailing slash Conflicts: remote-curl.c --- 3cc9caadf738c3b2cf7aa46364be173751912a10 diff --combined http.c index 51253e15a1,163c0e48e4..07a03fd79b --- a/http.c +++ b/http.c @@@ -204,7 -204,7 +204,7 @@@ static void init_curl_http_auth(CURL *r if (user_name) { struct strbuf up = STRBUF_INIT; if (!user_pass) - user_pass = xstrdup(getpass("Password: ")); + user_pass = xstrdup(git_getpass("Password: ")); strbuf_addf(&up, "%s:%s", user_name, user_pass); curl_easy_setopt(result, CURLOPT_USERPWD, strbuf_detach(&up, NULL)); @@@ -219,7 -219,7 +219,7 @@@ static int has_cert_password(void return 0; /* Only prompt the user once. */ ssl_cert_password_required = -1; - ssl_cert_password = getpass("Certificate Password: "); + ssl_cert_password = git_getpass("Certificate Password: "); if (ssl_cert_password != NULL) { ssl_cert_password = xstrdup(ssl_cert_password); return 1; @@@ -720,7 -720,7 +720,7 @@@ static inline int hex(int v return 'A' + v - 10; } - static void end_url_with_slash(struct strbuf *buf, const char *url) + void end_url_with_slash(struct strbuf *buf, const char *url) { strbuf_addstr(buf, url); if (buf->len && buf->buf[buf->len - 1] != '/') @@@ -815,21 -815,7 +815,21 @@@ static int http_request(const char *url ret = HTTP_OK; else if (missing_target(&results)) ret = HTTP_MISSING_TARGET; - else + else if (results.http_code == 401) { + if (user_name) { + ret = HTTP_NOAUTH; + } else { + /* + * git_getpass is needed here because its very likely stdin/stdout are + * pipes to our parent process. So we instead need to use /dev/tty, + * but that is non-portable. Using git_getpass() can at least be stubbed + * on other platforms with a different implementation if/when necessary. + */ + user_name = xstrdup(git_getpass("Username: ")); + init_curl_http_auth(slot->curl); + ret = HTTP_REAUTH; + } + } else ret = HTTP_ERROR; } else { error("Unable to start HTTP request for %s", url); @@@ -845,11 -831,7 +845,11 @@@ int http_get_strbuf(const char *url, struct strbuf *result, int options) { - return http_request(url, result, HTTP_REQUEST_STRBUF, options); + int http_ret = http_request(url, result, HTTP_REQUEST_STRBUF, options); + if (http_ret == HTTP_REAUTH) { + http_ret = http_request(url, result, HTTP_REQUEST_STRBUF, options); + } + return http_ret; } /* diff --combined http.h index 2dd03e88b7,c78cacb9c3..37a6a6a3b0 --- a/http.h +++ b/http.h @@@ -117,6 -117,7 +117,7 @@@ extern void append_remote_object_url(st int only_two_digit_prefix); extern char *get_remote_object_url(const char *url, const char *hex, int only_two_digit_prefix); + extern void end_url_with_slash(struct strbuf *buf, const char *url); /* Options for http_request_*() */ #define HTTP_NO_CACHE 1 @@@ -126,8 -127,6 +127,8 @@@ #define HTTP_MISSING_TARGET 1 #define HTTP_ERROR 2 #define HTTP_START_FAILED 3 +#define HTTP_REAUTH 4 +#define HTTP_NOAUTH 5 /* * Requests an url and stores the result in a strbuf. diff --combined remote-curl.c index 07827562b5,1fe59d6db0..24fbb9a9b9 --- a/remote-curl.c +++ b/remote-curl.c @@@ -9,7 -9,8 +9,7 @@@ #include "sideband.h" static struct remote *remote; - static const char *url; + static const char *url; /* always ends with a trailing slash */ -static struct walker *walker; struct options { int verbosity; @@@ -21,6 -22,12 +21,6 @@@ }; static struct options options; -static void init_walker(void) -{ - if (!walker) - walker = get_http_walker(url, remote); -} - static int set_option(const char *name, const char *value) { if (!strcmp(name, "verbosity")) { @@@ -101,7 -108,7 +101,7 @@@ static struct discovery* discover_refs( return last; free_discovery(last); - strbuf_addf(&buffer, "%s/info/refs", url); + strbuf_addf(&buffer, "%sinfo/refs", url); if (!prefixcmp(url, "http://") || !prefixcmp(url, "https://")) { is_http = 1; if (!strchr(url, '?')) @@@ -112,6 -119,7 +112,6 @@@ } refs_url = strbuf_detach(&buffer, NULL); - init_walker(); http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE); /* try again with "plain" url (no ? or & appended) */ @@@ -120,7 -128,7 +120,7 @@@ strbuf_reset(&buffer); proto_git_candidate = 0; - strbuf_addf(&buffer, "%s/info/refs", url); + strbuf_addf(&buffer, "%sinfo/refs", url); refs_url = strbuf_detach(&buffer, NULL); http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE); @@@ -132,8 -140,6 +132,8 @@@ case HTTP_MISSING_TARGET: die("%s not found: did you run git update-server-info on the" " server?", refs_url); + case HTTP_NOAUTH: + die("Authentication failed"); default: http_error(refs_url, http_ret); die("HTTP request failed"); @@@ -178,13 -184,13 +178,13 @@@ return last; } -static int write_discovery(int fd, void *data) +static int write_discovery(int in, int out, void *data) { struct discovery *heads = data; int err = 0; - if (write_in_full(fd, heads->buf, heads->len) != heads->len) + if (write_in_full(out, heads->buf, heads->len) != heads->len) err = 1; - close(fd); + close(out); return err; } @@@ -196,7 -202,6 +196,7 @@@ static struct ref *parse_git_refs(struc memset(&async, 0, sizeof(async)); async.proc = write_discovery; async.data = heads; + async.out = -1; if (start_async(&async)) die("cannot start thread to parse advertised refs"); @@@ -244,8 -249,9 +244,8 @@@ static struct ref *parse_info_refs(stru i++; } - init_walker(); ref = alloc_ref("HEAD"); - if (!walker->fetch_ref(walker, ref) && + if (!http_fetch_ref(url, ref) && !resolve_remote_symref(ref, refs)) { ref->next = refs; refs = ref; @@@ -495,6 -501,7 +495,6 @@@ static int rpc_service(struct rpc_stat struct child_process client; int err = 0; - init_walker(); memset(&client, 0, sizeof(client)); client.in = -1; client.out = -1; @@@ -511,7 -518,7 +511,7 @@@ rpc->out = client.out; strbuf_init(&rpc->result, 0); - strbuf_addf(&buf, "%s/%s", url, svc); + strbuf_addf(&buf, "%s%s", url, svc); rpc->service_url = strbuf_detach(&buf, NULL); strbuf_addf(&buf, "Content-Type: application/x-%s-request", svc); @@@ -546,7 -553,6 +546,7 @@@ static int fetch_dumb(int nr_heads, struct ref **to_fetch) { + struct walker *walker; char **targets = xmalloc(nr_heads * sizeof(char*)); int ret, i; @@@ -555,14 -561,13 +555,14 @@@ for (i = 0; i < nr_heads; i++) targets[i] = xstrdup(sha1_to_hex(to_fetch[i]->old_sha1)); - init_walker(); + walker = get_http_walker(url); walker->get_all = 1; walker->get_tree = 1; walker->get_history = 1; walker->get_verbosely = options.verbosity >= 3; walker->get_recover = 0; ret = walker_fetch(walker, nr_heads, targets, NULL, NULL); + walker_free(walker); for (i = 0; i < nr_heads; i++) free(targets[i]); @@@ -800,13 -805,13 +800,15 @@@ int main(int argc, const char **argv remote = remote_get(argv[1]); if (argc > 2) { - url = argv[2]; + end_url_with_slash(&buf, argv[2]); } else { - url = remote->url[0]; + end_url_with_slash(&buf, remote->url[0]); } + url = strbuf_detach(&buf, NULL); + + http_init(remote); + do { if (strbuf_getline(&buf, stdin, '\n') == EOF) break; @@@ -852,8 -857,5 +854,8 @@@ } strbuf_reset(&buf); } while (1); + + http_cleanup(); + return 0; } diff --combined t/t5541-http-push.sh index 795dc2bcdf,f0c50d3d77..17e1bdc5a8 --- a/t/t5541-http-push.sh +++ b/t/t5541-http-push.sh @@@ -34,8 -34,34 +34,34 @@@ test_expect_success 'setup remote repos mv test_repo.git "$HTTPD_DOCUMENT_ROOT_PATH" ' - test_expect_success 'clone remote repository' ' + cat >exp <act <"$HTTPD_ROOT_PATH"/access.log && + + # Clear the log, so that it does not affect the "used receive-pack + # service" test which reads the log too. + # + # We do this before the actual comparison to ensure the log is cleared. + echo > "$HTTPD_ROOT_PATH"/access.log && + + test_cmp exp act + ' + + test_expect_success 'clone remote repository' ' + rm -rf test_repo_clone && git clone $HTTPD_URL/smart/test_repo.git test_repo_clone ' @@@ -68,6 -94,7 +94,7 @@@ test_expect_success 'create and delete ' cat >exp < path2 && - git commit -a -m path2 --amend && - - HEAD=$(git rev-parse --verify HEAD) && - !(git push -v origin >output 2>&1) && - (cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git && - test $HEAD != $(git rev-parse --verify HEAD)) -' - -test_expect_success 'non-fast-forward push show ref status' ' - grep "^ ! \[rejected\][ ]*master -> master (non-fast-forward)$" output -' - -test_expect_success 'non-fast-forward push shows help message' ' - grep "To prevent you from losing history, non-fast-forward updates were rejected" \ - output -' +test_http_push_nonff "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git \ + "$ROOT_PATH"/test_repo_clone master test_expect_success 'push fails for non-fast-forward refs unmatched by remote helper' ' # create a dissimilarly-named remote ref so that git is unable to match the