def maybe_add_slashes(request_path, GET, *args, **kwargs): ''' Redirect with trailing slashes if necessary. ''' # Look for a missing trailing slash at the repository root. split_req = request_path.lstrip('/').split('/', 2) if len(split_req) == 2 and split_req[-1] != '': # There are two full components in the path: owner and repo, req_owner, req_repo = split_req if repo_exists(req_owner, req_repo, GET): # Missing a trailing slash for the branch listing. return redirect( absolute_url(request, '{}/'.format(request_path)), 302) if len(split_req) == 3 and split_req[-1] != '': # There are three full components in the path: owner, repo, and ref. req_owner, req_repo, req_ref_path = split_req req_ref, req_path = split_branch_path(req_owner, req_repo, req_ref_path, GET) if req_path == '' and not req_ref_path.endswith('/'): # Missing a trailing slash at the root of the repository. return redirect( absolute_url(request, '{}/'.format(request_path)), 302) return untouched_route(*args, **kwargs)
def repo_ref_path(account, repo, ref_path): access_token = get_token().get('access_token') GET = Getter((access_token, 'x-oauth-basic'), throws4XX=True).get template_args = dict(account=account, repo=repo) if not repo_exists(account, repo, GET): return make_404_response('no-such-repo.html', template_args) ref, path = split_branch_path(account, repo, ref_path, GET) if ref is None: return make_404_response('no-such-ref.html', dict(ref=ref_path, **template_args)) try: artifacts = get_circle_artifacts(account, repo, ref, GET) artifact_url = artifacts.get(select_path(artifacts, path)) except RuntimeError as err: vars = dict(error=err, codes=err_codes, git_ref=ref) if err.args[0] == ERR_TESTS_PENDING: return make_response( render_template('error-pending.html', refresh=request.path, **vars), 200) elif err.args[0] == ERR_TESTS_FAILED: return make_response(render_template('error-failed.html', **vars), 200) else: return make_response(render_template('error-runtime.html', **vars), 400) if artifact_url is None: return make_404_response('error-404.html', dict(ref=ref, path=path, **template_args)) try: if urlparse(artifact_url).scheme == 'file': mimetype, _ = guess_type(artifact_url) with open(urlparse(artifact_url).path) as file: content = file.read() else: artifact_resp = GET(artifact_url, _LONGTIME) if artifact_resp.status_code != 200: raise IOError('Bad response from CircleCI: HTTP {}'.format( artifact_resp.status_code)) content = artifact_resp.content mimetype = artifact_resp.headers.get('Content-Type', '') except IOError as err: return make_response( render_template('error-runtime.html', error=err, codes=err_codes), 500) return Response(content, headers={ 'Content-Type': mimetype, 'Cache-Control': 'no-store private' })
def wrapper(*args, **kwargs): ''' Redirect under repository root based on referer if necessary. ''' GET = Getter((get_token().get('access_token'), 'x-oauth-basic')).get # See if the OK hand sign (U+1F44C) was given. if request.args.get('go') == u'\U0001f44c': return untouched_route(*args, **kwargs) # See if there's a referer at all. referer_url = request.headers.get('Referer') if not referer_url: # No referer, no redirect. return maybe_add_slashes(request.path, GET, *args, **kwargs) # See if the referer path is long enough to suggest a redirect. referer_path = urlparse(referer_url).path split_path = referer_path.lstrip('/').split('/', 2) if len(split_path) != 3: # Not long enough. return maybe_add_slashes(request.path, GET, *args, **kwargs) # Talk to Github about the path and find a ref name. path_owner, path_repo, path_ref = split_path if not repo_exists(path_owner, path_repo, GET): # No repo by this name, no redirect. return maybe_add_slashes(request.path, GET, *args, **kwargs) ref, _ = split_branch_path(path_owner, path_repo, path_ref, GET) if ref is None: # No ref identified, no redirect. return maybe_add_slashes(request.path, GET, *args, **kwargs) # Usually 3, but maybe more? slash_count = 2 + len(ref.split('/')) # See if a redirect is necessary. if needs_redirect(request.host, request.path, referer_url, slash_count): return make_redirect(slash_count) # Otherwise, proceed as normal. return maybe_add_slashes(request.path, GET, *args, **kwargs)
def repo_ref_path(account, repo, ref_path): access_token = get_token().get('access_token') GET = Getter((access_token, 'x-oauth-basic'), throws4XX=True).get template_args = dict(account=account, repo=repo) if not repo_exists(account, repo, GET): return make_404_response('no-such-repo.html', template_args) ref, path = split_branch_path(account, repo, ref_path, GET) if ref is None: return make_404_response('no-such-ref.html', dict(ref=ref_path, **template_args)) try: artifacts = get_circle_artifacts(account, repo, ref, GET) artifact_url = artifacts.get(select_path(artifacts, path)) except RuntimeError as err: vars = dict(error=err, codes=err_codes, git_ref=ref) if err.args[0] == ERR_TESTS_PENDING: return make_response(render_template('error-pending.html', refresh=request.path, **vars), 200) elif err.args[0] == ERR_TESTS_FAILED: return make_response(render_template('error-failed.html', **vars), 200) else: return make_response(render_template('error-runtime.html', **vars), 400) if artifact_url is None: return make_404_response('error-404.html', dict(ref=ref, path=path, **template_args)) try: if urlparse(artifact_url).scheme == 'file': mimetype, _ = guess_type(artifact_url) with open(urlparse(artifact_url).path) as file: content = file.read() else: artifact_resp = GET(artifact_url, _LONGTIME) if artifact_resp.status_code != 200: raise IOError('Bad response from CircleCI: HTTP {}'.format(artifact_resp.status_code)) content = artifact_resp.content mimetype = artifact_resp.headers.get('Content-Type', '') except IOError as err: return make_response(render_template('error-runtime.html', error=err, codes=err_codes), 500) return Response(content, headers={'Content-Type': mimetype, 'Cache-Control': 'no-store private'})
def maybe_add_slashes(request_path, GET, *args, **kwargs): ''' Redirect with trailing slashes if necessary. ''' # Look for a missing trailing slash at the repository root. split_req = request_path.lstrip('/').split('/', 2) if len(split_req) == 2 and split_req[-1] != '': # There are two full components in the path: owner and repo, req_owner, req_repo = split_req if repo_exists(req_owner, req_repo, GET): # Missing a trailing slash for the branch listing. return redirect(absolute_url(request, '{}/'.format(request_path)), 302) if len(split_req) == 3 and split_req[-1] != '': # There are three full components in the path: owner, repo, and ref. req_owner, req_repo, req_ref_path = split_req req_ref, req_path = split_branch_path(req_owner, req_repo, req_ref_path, GET) if req_path == '' and not req_ref_path.endswith('/'): # Missing a trailing slash at the root of the repository. return redirect(absolute_url(request, '{}/'.format(request_path)), 302) return untouched_route(*args, **kwargs)
def repo_ref(account, repo, ref): ''' Redirect to add trailing slash. ''' access_token = get_token().get('access_token') GET = Getter((access_token, 'x-oauth-basic'), throws4XX=True).get return str(repo_exists(account, repo, GET))
def repo_only(account, repo): ''' Add a slash. ''' access_token = get_token().get('access_token') GET = Getter((access_token, 'x-oauth-basic'), throws4XX=True).get return str(repo_exists(account, repo, GET))