From: "Aníbal Limón" <anibal.limon@linux.intel.com>
To: Ross Burton <ross.burton@intel.com>,
bitbake-devel@lists.openembedded.org
Subject: Re: [PATCH] fetch2/wget: fallback to GET if HEAD is rejected in checkstatus()
Date: Wed, 20 Jan 2016 09:48:23 -0600 [thread overview]
Message-ID: <569FAC47.4050901@linux.intel.com> (raw)
In-Reply-To: <1453295662-13333-1-git-send-email-ross.burton@intel.com>
Hi Ross,
The code looks good only two comments,
- Will be good if you add this case when HEAD isn't available to the
unittest. [1]
- I don't thinks is a good idea to log something inside fetcher (since
fetcher is a helper module) i.e. when use shared states the logic calls
checkstatus for every possible sstate available and it will show you a
lot of warnings if isn't. I have a ticket for change this behavior [2].
Cheers,
alimon
[1] http://git.openembedded.org/bitbake/tree/lib/bb/tests/fetch.py#n727
[2] https://bugzilla.yoctoproject.org/show_bug.cgi?id=8727
On 01/20/2016 07:14 AM, Ross Burton wrote:
> The core change here is to fall back to GET requests if HEAD is rejected in the
> checkstatus() method, as you can't do a HEAD on Amazon S3 (used by Github
> archives). This meant removing the monkey patch that the default method was GET
> and adding a fixed redirect handler that doesn't reset to GET.
>
> Also, change the way the opener is constructed from an if/elif cluster to a
> conditionally constructed list.
>
> Signed-off-by: Ross Burton <ross.burton@intel.com>
> ---
> bitbake/lib/bb/fetch2/wget.py | 65 ++++++++++++++++++++++++++++---------------
> 1 file changed, 42 insertions(+), 23 deletions(-)
>
> diff --git a/bitbake/lib/bb/fetch2/wget.py b/bitbake/lib/bb/fetch2/wget.py
> index c8c6d5c..dafa068 100644
> --- a/bitbake/lib/bb/fetch2/wget.py
> +++ b/bitbake/lib/bb/fetch2/wget.py
> @@ -235,38 +235,57 @@ class Wget(FetchMethod):
>
> return exported
>
> - def head_method(self):
> - return "HEAD"
> -
> + class HTTPMethodFallback(urllib2.BaseHandler):
> + """
> + Fallback to GET if HEAD is not allowed (405 HTTP error)
> + """
> + def http_error_405(self, req, fp, code, msg, headers):
> + fp.read()
> + fp.close()
> +
> + newheaders = dict((k,v) for k,v in req.headers.items()
> + if k.lower() not in ("content-length", "content-type"))
> + return self.parent.open(urllib2.Request(req.get_full_url(),
> + headers=newheaders,
> + origin_req_host=req.get_origin_req_host(),
> + unverifiable=True))
> +
> + """
> + Some servers (e.g. GitHub archives, hosted on Amazon S3) return 403
> + Forbidden when they actually mean 405 Method Not Allowed.
> + """
> + http_error_403 = http_error_405
> +
> + class FixedHTTPRedirectHandler(urllib2.HTTPRedirectHandler):
> + """
> + urllib2.HTTPRedirectHandler resets the method to GET on redirect,
> + when we want to follow redirects using the original method.
> + """
> + def redirect_request(self, req, fp, code, msg, headers, newurl):
> + newreq = urllib2.HTTPRedirectHandler.redirect_request(self, req, fp, code, msg, headers, newurl)
> + newreq.get_method = lambda: req.get_method()
> + return newreq
> exported_proxies = export_proxies(d)
>
> + handlers = [FixedHTTPRedirectHandler, HTTPMethodFallback]
> + if export_proxies:
> + handlers.append(urllib2.ProxyHandler())
> + handlers.append(CacheHTTPHandler())
> # XXX: Since Python 2.7.9 ssl cert validation is enabled by default
> # see PEP-0476, this causes verification errors on some https servers
> # so disable by default.
> import ssl
> - ssl_context = None
> if hasattr(ssl, '_create_unverified_context'):
> - ssl_context = ssl._create_unverified_context()
> -
> - if exported_proxies == True and ssl_context is not None:
> - opener = urllib2.build_opener(urllib2.ProxyHandler, CacheHTTPHandler,
> - urllib2.HTTPSHandler(context=ssl_context))
> - elif exported_proxies == False and ssl_context is not None:
> - opener = urllib2.build_opener(CacheHTTPHandler,
> - urllib2.HTTPSHandler(context=ssl_context))
> - elif exported_proxies == True and ssl_context is None:
> - opener = urllib2.build_opener(urllib2.ProxyHandler, CacheHTTPHandler)
> - else:
> - opener = urllib2.build_opener(CacheHTTPHandler)
> -
> - urllib2.Request.get_method = head_method
> - urllib2.install_opener(opener)
> -
> - uri = ud.url.split(";")[0]
> + handlers.append(urllib2.HTTPSHandler(context=ssl._create_unverified_context()))
> + opener = urllib2.build_opener(*handlers)
>
> try:
> - urllib2.urlopen(uri)
> - except:
> + uri = ud.url.split(";")[0]
> + r = urllib2.Request(uri)
> + r.get_method = lambda: "HEAD"
> + opener.open(r)
> + except urllib2.URLError as e:
> + bb.warn("checkstatus() urlopen failed: %s" % e)
> return False
> return True
>
>
prev parent reply other threads:[~2016-01-20 15:46 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-20 13:14 [PATCH] fetch2/wget: fallback to GET if HEAD is rejected in checkstatus() Ross Burton
2016-01-20 15:48 ` Aníbal Limón [this message]
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=569FAC47.4050901@linux.intel.com \
--to=anibal.limon@linux.intel.com \
--cc=bitbake-devel@lists.openembedded.org \
--cc=ross.burton@intel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.