diff options
-rw-r--r-- | .travis.yml | 21 | ||||
-rwxr-xr-x | ci/run-linux32-build.sh | 30 | ||||
-rw-r--r-- | config.mak.uname | 1 | ||||
-rw-r--r-- | http.c | 50 |
4 files changed, 97 insertions, 5 deletions
diff --git a/.travis.yml b/.travis.yml index 9c63c8c3f6..591cc57b80 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,6 +39,27 @@ env: matrix: include: + - env: Linux32 + os: linux + services: + - docker + before_install: + - docker pull daald/ubuntu32:xenial + before_script: + script: + - > + docker run + --interactive + --env DEFAULT_TEST_TARGET + --env GIT_PROVE_OPTS + --env GIT_TEST_OPTS + --env GIT_TEST_CLONE_2GB + --volume "${PWD}:/usr/src/git" + daald/ubuntu32:xenial + /usr/src/git/ci/run-linux32-build.sh $(id -u $USER) + # Use the following command to debug the docker build locally: + # $ docker run -itv "${PWD}:/usr/src/git" --entrypoint /bin/bash daald/ubuntu32:xenial + # root@container:/# /usr/src/git/ci/run-linux32-build.sh - env: Documentation os: linux compiler: clang diff --git a/ci/run-linux32-build.sh b/ci/run-linux32-build.sh new file mode 100755 index 0000000000..e30fb2cddc --- /dev/null +++ b/ci/run-linux32-build.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# +# Build and test Git in a 32-bit environment +# +# Usage: +# run-linux32-build.sh [host-user-id] +# + +# Update packages to the latest available versions +linux32 --32bit i386 sh -c ' + apt update >/dev/null && + apt install -y build-essential libcurl4-openssl-dev libssl-dev \ + libexpat-dev gettext python >/dev/null +' && + +# If this script runs inside a docker container, then all commands are +# usually executed as root. Consequently, the host user might not be +# able to access the test output files. +# If a host user id is given, then create a user "ci" with the host user +# id to make everything accessible to the host user. +HOST_UID=$1 && +CI_USER=$USER && +test -z $HOST_UID || (CI_USER="ci" && useradd -u $HOST_UID $CI_USER) && + +# Build and test +linux32 --32bit i386 su -m -l $CI_USER -c ' + cd /usr/src/git && + make --jobs=2 && + make --quiet test +' diff --git a/config.mak.uname b/config.mak.uname index 447f36ac2e..a07936da8b 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -515,7 +515,6 @@ ifneq (,$(findstring MINGW,$(uname_S))) OBJECT_CREATION_USES_RENAMES = UnfortunatelyNeedsTo NO_REGEX = YesPlease NO_PYTHON = YesPlease - BLK_SHA1 = YesPlease ETAGS_TARGET = ETAGS NO_INET_PTON = YesPlease NO_INET_NTOP = YesPlease @@ -109,7 +109,7 @@ static int curl_save_cookies; struct credential http_auth = CREDENTIAL_INIT; static int http_proactive_auth; static const char *user_agent; -static int curl_empty_auth; +static int curl_empty_auth = -1; enum http_follow_config http_follow_config = HTTP_FOLLOW_INITIAL; @@ -125,6 +125,14 @@ static struct credential cert_auth = CREDENTIAL_INIT; static int ssl_cert_password_required; #ifdef LIBCURL_CAN_HANDLE_AUTH_ANY static unsigned long http_auth_methods = CURLAUTH_ANY; +static int http_auth_methods_restricted; +/* Modes for which empty_auth cannot actually help us. */ +static unsigned long empty_auth_useless = + CURLAUTH_BASIC +#ifdef CURLAUTH_DIGEST_IE + | CURLAUTH_DIGEST_IE +#endif + | CURLAUTH_DIGEST; #endif static struct curl_slist *pragma_header; @@ -333,7 +341,10 @@ static int http_options(const char *var, const char *value, void *cb) return git_config_string(&user_agent, var, value); if (!strcmp("http.emptyauth", var)) { - curl_empty_auth = git_config_bool(var, value); + if (value && !strcmp("auto", value)) + curl_empty_auth = -1; + else + curl_empty_auth = git_config_bool(var, value); return 0; } @@ -382,10 +393,37 @@ static int http_options(const char *var, const char *value, void *cb) return git_default_config(var, value, cb); } +static int curl_empty_auth_enabled(void) +{ + if (curl_empty_auth >= 0) + return curl_empty_auth; + +#ifndef LIBCURL_CAN_HANDLE_AUTH_ANY + /* + * Our libcurl is too old to do AUTH_ANY in the first place; + * just default to turning the feature off. + */ +#else + /* + * In the automatic case, kick in the empty-auth + * hack as long as we would potentially try some + * method more exotic than "Basic" or "Digest". + * + * But only do this when this is our second or + * subsequent request, as by then we know what + * methods are available. + */ + if (http_auth_methods_restricted && + (http_auth_methods & ~empty_auth_useless)) + return 1; +#endif + return 0; +} + static void init_curl_http_auth(CURL *result) { if (!http_auth.username || !*http_auth.username) { - if (curl_empty_auth) + if (curl_empty_auth_enabled()) curl_easy_setopt(result, CURLOPT_USERPWD, ":"); return; } @@ -1079,7 +1117,7 @@ struct active_request_slot *get_active_slot(void) #ifdef LIBCURL_CAN_HANDLE_AUTH_ANY curl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH, http_auth_methods); #endif - if (http_auth.password || curl_empty_auth) + if (http_auth.password || curl_empty_auth_enabled()) init_curl_http_auth(slot->curl); return slot; @@ -1347,6 +1385,10 @@ static int handle_curl_result(struct slot_results *results) } else { #ifdef LIBCURL_CAN_HANDLE_AUTH_ANY http_auth_methods &= ~CURLAUTH_GSSNEGOTIATE; + if (results->auth_avail) { + http_auth_methods &= results->auth_avail; + http_auth_methods_restricted = 1; + } #endif return HTTP_REAUTH; } |