Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: rietveld.py

Issue 1683603002: Raise exceptions properly on HTTP errors from OAuthRpcServer (which is only used on bots) (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tests/rietveld_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # coding: utf-8 1 # coding: utf-8
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 """Defines class Rietveld to easily access a rietveld instance. 5 """Defines class Rietveld to easily access a rietveld instance.
6 6
7 Security implications: 7 Security implications:
8 8
9 The following hypothesis are made: 9 The following hypothesis are made:
10 - Rietveld enforces: 10 - Rietveld enforces:
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 if m: 409 if m:
410 # Fake an HTTPError exception. Cheezy. :( 410 # Fake an HTTPError exception. Cheezy. :(
411 raise urllib2.HTTPError( 411 raise urllib2.HTTPError(
412 request_path, int(m.group(1)), msg, None, None) 412 request_path, int(m.group(1)), msg, None, None)
413 old_error_exit(msg) 413 old_error_exit(msg)
414 upload.ErrorExit = trap_http_500 414 upload.ErrorExit = trap_http_500
415 415
416 for retry in xrange(self._maxtries): 416 for retry in xrange(self._maxtries):
417 try: 417 try:
418 logging.debug('%s' % request_path) 418 logging.debug('%s' % request_path)
419 result = self.rpc_server.Send(request_path, **kwargs) 419 return self.rpc_server.Send(request_path, **kwargs)
420 # Sometimes GAE returns a HTTP 200 but with HTTP 500 as the content.
421 # How nice.
422 return result
423 except urllib2.HTTPError, e: 420 except urllib2.HTTPError, e:
424 if retry >= (self._maxtries - 1): 421 if retry >= (self._maxtries - 1):
425 raise 422 raise
426 flake_codes = [500, 502, 503] 423 flake_codes = [500, 502, 503]
427 if retry_on_404: 424 if retry_on_404:
428 flake_codes.append(404) 425 flake_codes.append(404)
429 if e.code not in flake_codes: 426 if e.code not in flake_codes:
430 raise 427 raise
431 except urllib2.URLError, e: 428 except urllib2.URLError, e:
432 if retry >= (self._maxtries - 1): 429 if retry >= (self._maxtries - 1):
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 extra_headers=None, 518 extra_headers=None,
522 **kwargs): 519 **kwargs):
523 """Send a POST or GET request to the server. 520 """Send a POST or GET request to the server.
524 521
525 Args: 522 Args:
526 request_path: path on the server to hit. This is concatenated with the 523 request_path: path on the server to hit. This is concatenated with the
527 value of 'host' provided to the constructor. 524 value of 'host' provided to the constructor.
528 payload: request is a POST if not None, GET otherwise 525 payload: request is a POST if not None, GET otherwise
529 timeout: in seconds 526 timeout: in seconds
530 extra_headers: (dict) 527 extra_headers: (dict)
528
529 Returns: the HTTP response body as a string
530
531 Raises:
532 urllib2.HTTPError
531 """ 533 """
532 # This method signature should match upload.py:AbstractRpcServer.Send() 534 # This method signature should match upload.py:AbstractRpcServer.Send()
533 method = 'GET' 535 method = 'GET'
534 536
535 headers = self.extra_headers.copy() 537 headers = self.extra_headers.copy()
536 headers.update(extra_headers or {}) 538 headers.update(extra_headers or {})
537 539
538 if payload is not None: 540 if payload is not None:
539 method = 'POST' 541 method = 'POST'
540 headers['Content-Type'] = content_type 542 headers['Content-Type'] = content_type
541 543
542 prev_timeout = self._http.timeout 544 prev_timeout = self._http.timeout
543 try: 545 try:
544 if timeout: 546 if timeout:
545 self._http.timeout = timeout 547 self._http.timeout = timeout
546 # TODO(pgervais) implement some kind of retry mechanism (see upload.py).
547 url = self.host + request_path 548 url = self.host + request_path
548 if kwargs: 549 if kwargs:
549 url += "?" + urllib.urlencode(kwargs) 550 url += "?" + urllib.urlencode(kwargs)
550 551
551 # This weird loop is there to detect when the OAuth2 token has expired. 552 # This weird loop is there to detect when the OAuth2 token has expired.
552 # This is specific to appengine *and* rietveld. It relies on the 553 # This is specific to appengine *and* rietveld. It relies on the
553 # assumption that a 302 is triggered only by an expired OAuth2 token. This 554 # assumption that a 302 is triggered only by an expired OAuth2 token. This
554 # prevents any usage of redirections in pages accessed this way. 555 # prevents any usage of redirections in pages accessed this way.
555 556
556 # This variable is used to make sure the following loop runs only twice. 557 # This variable is used to make sure the following loop runs only twice.
557 redirect_caught = False 558 redirect_caught = False
558 while True: 559 while True:
559 try: 560 try:
560 ret = self._http.request(url, 561 ret = self._http.request(url,
561 method=method, 562 method=method,
562 body=payload, 563 body=payload,
563 headers=headers, 564 headers=headers,
564 redirections=0) 565 redirections=0)
565 except httplib2.RedirectLimit: 566 except httplib2.RedirectLimit:
566 if redirect_caught or method != 'GET': 567 if redirect_caught or method != 'GET':
567 logging.error('Redirection detected after logging in. Giving up.') 568 logging.error('Redirection detected after logging in. Giving up.')
568 raise 569 raise
569 redirect_caught = True 570 redirect_caught = True
570 logging.debug('Redirection detected. Trying to log in again...') 571 logging.debug('Redirection detected. Trying to log in again...')
571 self.creds.access_token = None 572 self.creds.access_token = None
572 continue 573 continue
573 break 574 break
574 575
576 if ret[0].status != 200:
577 raise urllib2.HTTPError(
578 request_path, int(ret[0]['status']), ret[1], None, None)
579
575 return ret[1] 580 return ret[1]
576 581
577 finally: 582 finally:
578 self._http.timeout = prev_timeout 583 self._http.timeout = prev_timeout
579 584
580 585
581 class JwtOAuth2Rietveld(Rietveld): 586 class JwtOAuth2Rietveld(Rietveld):
582 """Access to Rietveld using OAuth authentication. 587 """Access to Rietveld using OAuth authentication.
583 588
584 This class is supposed to be used only by bots, since this kind of 589 This class is supposed to be used only by bots, since this kind of
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 self, issue, patchset, reason, clobber, revision, builders_and_tests, 742 self, issue, patchset, reason, clobber, revision, builders_and_tests,
738 master=None, category='cq'): 743 master=None, category='cq'):
739 logging.info('ReadOnlyRietveld: triggering try jobs %r for issue %d' % 744 logging.info('ReadOnlyRietveld: triggering try jobs %r for issue %d' %
740 (builders_and_tests, issue)) 745 (builders_and_tests, issue))
741 746
742 def trigger_distributed_try_jobs( # pylint:disable=R0201 747 def trigger_distributed_try_jobs( # pylint:disable=R0201
743 self, issue, patchset, reason, clobber, revision, masters, 748 self, issue, patchset, reason, clobber, revision, masters,
744 category='cq'): 749 category='cq'):
745 logging.info('ReadOnlyRietveld: triggering try jobs %r for issue %d' % 750 logging.info('ReadOnlyRietveld: triggering try jobs %r for issue %d' %
746 (masters, issue)) 751 (masters, issue))
OLDNEW
« no previous file with comments | « no previous file | tests/rietveld_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698