From: Jeff King <peff@peff.net>
To: "Kyle J. McKay" <mackyle@gmail.com>
Cc: git@vger.kernel.org, "David Aguilar" <davvid@gmail.com>,
"Petr Baudis" <pasky@ucw.cz>,
"Richard Hartmann" <richih.mailinglist@gmail.com>,
"Daniel Knittl-Frank" <knittl89@googlemail.com>,
"Jan Krüger" <jk@jk.gs>, "Alejandro Mery" <amery@geeks.cl>
Subject: Re: [PATCH v3] config: add support for http.<url>.* settings
Date: Fri, 12 Jul 2013 05:59:23 -0400 [thread overview]
Message-ID: <20130712095923.GA4695@sigill.intra.peff.net> (raw)
In-Reply-To: <9e7edfbc83a7284615af4ca0de39c1b@f74d39fa044aa309eaea14b9f57fe79>
On Thu, Jul 11, 2013 at 02:50:03PM -0700, Kyle J. McKay wrote:
> The <url> value is considered a match to a url if the <url> value
> is either an exact match or a prefix of the url which ends on a
> path component boundary ('/'). So "https://example.com/test" will
> match "https://example.com/test" and "https://example.com/test/too"
> but not "https://example.com/testextra".
>
> Longer matches take precedence over shorter matches with
> environment variable settings taking precedence over all.
>
> With this configuration:
>
> [http]
> useragent = other-agent
> noEPSV = true
> [http "https://example.com"]
> useragent = example-agent
> sslVerify = false
> [http "https://example.com/path"]
> useragent = path-agent
I like the general direction you are going, and especially the path
prefix matching is something I had always meant to implement for the
credential code.
A few comments on the implementation:
> +enum http_option_type {
> + opt_post_buffer = 0,
> + opt_min_sessions,
> +#ifdef USE_CURL_MULTI
> + opt_max_requests,
> +#endif
> + opt_ssl_verify,
> + opt_ssl_try,
> + opt_ssl_cert,
> +#if LIBCURL_VERSION_NUM >= 0x070903
> + opt_ssl_key,
> +#endif
> +#if LIBCURL_VERSION_NUM >= 0x070908
> + opt_ssl_capath,
> +#endif
> + opt_ssl_cainfo,
> + opt_low_speed,
> + opt_low_time,
> + opt_no_epsv,
> + opt_http_proxy,
> + opt_cookie_file,
> + opt_user_agent,
> + opt_passwd_req,
> + opt_max
> +};
We usually put enum fields in ALL_CAPS to mark them as constants (though
you can find few exceptions in the code).
> +static size_t http_options_url_match_prefix(const char *url,
> + const char *url_prefix,
> + size_t url_prefix_len)
> +{
It looks like you're matching the URLs as raw strings, and I don't see
any canonicalization going on. What happens if I have
"https://example.com/foo+bar" in my config, but then I visit
"https://example.comfoo%20bar"?
Or what about optional components? If I have "https://example.com" in my
config, but I am visiting "https://peff@example.com/", shouldn't it
match? The config spec is more general than my specific URL; you would
not want it to match in the opposite direction, though.
I think you would want to break down the URL into fields, canonicalize
each field by undoing any encoding, and then compare the broken-down
URLs, as credential_match does (adding in your prefix/boundary matching to
the path instead of a straight string comparison).
I think you could mostly reuse the code there by doing:
1. Create a "struct url" that contains the broken-down form; "struct
credential" would contain a url.
2. Pull out credential_from_url into "int url_parse(struct url *,
const char *)".
3. Pull out credential_match into "int url_match(struct url *, struct
url *)".
4. Parse and compare URLs from "http.$URL.*" during the config read
(similar to credential_config_callback).
That does make your by-length ordering impossible, but I don't think you
can do it in the general case. If I have:
[http "http://peff@example.com"] foo = 1
[http "http://example.com:8080"] foo = 2
and I visit "http://peff@example.com:8080", which one is the winner? I
don't think there is an unambiguous definition. I'd suggest instead just
using the usual "last one wins" strategy that our config uses. It has
the unfortunate case that:
[http "http://example.com"]
foo = 1
[http]
foo = 2
will always choose http.foo=2, but I don't think that is a big problem
in practice. You often only set one or the other, and in the cases where
you want to have a non-standard default and then override it with
another host-specific case, the "last one wins" rule makes it simple to
explain that you need to specify keys in most-general to most-specific
order.
> static int http_options(const char *var, const char *value, void *cb)
> {
> - if (!strcmp("http.sslverify", var)) {
> + const char *url = (const char *)cb;
No need to cast from void, this isn't C++. :)
The rest of the http_options() changes look like what I'd expect.
> @@ -344,7 +479,7 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)
>
> http_is_verbose = 0;
>
> - git_config(http_options, NULL);
> + git_config(http_options, (void *)url);
No need to cast again. :)
So this is the URL that we got on the command line. Which means that if
we get a redirect, we will not re-examine the options. I think that's
OK; we do not even _see_ the redirect, as it happens internally within
curl. The credential code has the same problem, but it is not a security
issue because curl clears the credentials on redirect.
However, it may be worth mentioning in the documentation that the config
options operate on the URL you give git, _not_ necessarily on the actual
URL you are hitting at any given moment (the gitcredentials(7) page
should probably make the same distinction).
-Peff
next prev parent reply other threads:[~2013-07-12 9:59 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-07-11 21:50 [PATCH v3] config: add support for http.<url>.* settings Kyle J. McKay
2013-07-11 23:12 ` Junio C Hamano
[not found] ` <455666C5-7663-4361-BF34-378D3EAE2891@gmail.com>
[not found] ` <7vsizjn390.fsf@alter.siamese.dyndns.org>
[not found] ` <7v4nbyic57.fsf@alter.siamese.dyndns.org>
2013-07-13 19:46 ` Kyle J. McKay
2013-07-15 4:02 ` Junio C Hamano
2013-07-15 5:12 ` Jeff King
2013-07-15 9:50 ` Kyle J. McKay
2013-07-15 5:06 ` Jeff King
2013-07-12 9:59 ` Jeff King [this message]
2013-07-12 13:07 ` Kyle J. McKay
2013-07-12 20:58 ` Aaron Schrab
2013-07-15 4:43 ` Jeff King
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130712095923.GA4695@sigill.intra.peff.net \
--to=peff@peff.net \
--cc=amery@geeks.cl \
--cc=davvid@gmail.com \
--cc=git@vger.kernel.org \
--cc=jk@jk.gs \
--cc=knittl89@googlemail.com \
--cc=mackyle@gmail.com \
--cc=pasky@ucw.cz \
--cc=richih.mailinglist@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).