def application(environ, start_response): # The WSGI server puts content length and type in the environment # even when not provided with the request. Drop them if they are empty. if environ.get('CONTENT_LENGTH') == '': del environ['CONTENT_LENGTH'] if environ.get('CONTENT_TYPE') == '': del environ['CONTENT_TYPE'] wrequest = WerkzeugRequest(environ) data = wrequest.get_data() request = Request( method=wrequest.method, url=wrequest.url, headers=wrequest.headers, data=data, ) prepared = request.prepare() stream = streams.build_output_stream( args, env, prepared, response=None, output_options=args.output_options) streams.write_stream(stream, env.stdout, env.stdout_isatty) # When there is data in the request, give the next one breathing room. if data: print("\n", file=env.stdout) # Make dreams come true. response = Response(headers={'Server': server}) return response(environ, start_response)
def main(args=sys.argv[1:], env=Environment(), error=None): """Run the main program and write the output to ``env.stdout``. Return exit status code. """ args = decode_args(args, env.stdin_encoding) plugin_manager.load_installed_plugins() from httpie.cli import parser if env.config.default_options: args = env.config.default_options + args def _error(msg, *args, **kwargs): msg = msg % args level = kwargs.get('level', 'error') env.stderr.write('\nhttp: %s: %s\n' % (level, msg)) if error is None: error = _error debug = '--debug' in args traceback = debug or '--traceback' in args exit_status = ExitStatus.OK if debug: print_debug_info(env) if args == ['--debug']: return exit_status downloader = None try: args = parser.parse_args(args=args, env=env) if args.download: args.follow = True # --download implies --follow. downloader = Downloader( output_file=args.output_file, progress_file=env.stderr, resume=args.download_resume ) downloader.pre_request(args.headers) last_response = get_response(args, config_dir=env.config.directory) if args.show_redirects: responses = last_response.history + [last_response] else: responses = [last_response] for response in responses: if args.check_status or downloader: exit_status = get_exit_status( http_status=response.status_code, follow=args.follow ) if not env.stdout_isatty and exit_status != ExitStatus.OK: error('HTTP %s %s', response.raw.status, response.raw.reason, level='warning') write_stream_kwargs = { 'stream': build_output_stream( args=args, env=env, request=response.request, response=response, ), # NOTE: `env.stdout` will in fact be `stderr` with `--download` 'outfile': env.stdout, 'flush': env.stdout_isatty or args.stream } try: if env.is_windows and is_py3 and 'colors' in args.prettify: write_stream_with_colors_win_py3(**write_stream_kwargs) else: write_stream(**write_stream_kwargs) except IOError as e: if not traceback and e.errno == errno.EPIPE: # Ignore broken pipes unless --traceback. env.stderr.write('\n') else: raise if downloader and exit_status == ExitStatus.OK: # Last response body download. download_stream, download_to = downloader.start(last_response) write_stream( stream=download_stream, outfile=download_to, flush=False, ) downloader.finish() if downloader.interrupted: exit_status = ExitStatus.ERROR error('Incomplete download: size=%d; downloaded=%d' % ( downloader.status.total_size, downloader.status.downloaded )) except KeyboardInterrupt: if traceback: raise env.stderr.write('\n') exit_status = ExitStatus.ERROR except SystemExit as e: if e.code != ExitStatus.OK: if traceback: raise env.stderr.write('\n') exit_status = ExitStatus.ERROR except requests.Timeout: exit_status = ExitStatus.ERROR_TIMEOUT error('Request timed out (%ss).', args.timeout) except requests.TooManyRedirects: exit_status = ExitStatus.ERROR_TOO_MANY_REDIRECTS error('Too many redirects (--max-redirects=%s).', args.max_redirects) except Exception as e: # TODO: Better distinction between expected and unexpected errors. if traceback: raise msg = str(e) if hasattr(e, 'request'): request = e.request if hasattr(request, 'url'): msg += ' while doing %s request to URL: %s' % ( request.method, request.url) error('%s: %s', type(e).__name__, msg) exit_status = ExitStatus.ERROR finally: if downloader and not downloader.finished: downloader.failed() return exit_status
def program(args, env, log_error): """ The main program without error handling :param args: parsed args (argparse.Namespace) :type env: Environment :param log_error: error log function :return: status code """ exit_status = ExitStatus.OK downloader = None show_traceback = args.debug or args.traceback try: if args.download: args.follow = True # --download implies --follow. downloader = Downloader(output_file=args.output_file, progress_file=env.stderr, resume=args.download_resume) downloader.pre_request(args.headers) final_response = get_response(args, config_dir=env.config.directory) if args.all: responses = final_response.history + [final_response] else: responses = [final_response] for response in responses: if args.check_status or downloader: exit_status = get_exit_status(http_status=response.status_code, follow=args.follow) if not env.stdout_isatty and exit_status != ExitStatus.OK: log_error('HTTP %s %s', response.raw.status, response.raw.reason, level='warning') write_stream_kwargs = { 'stream': build_output_stream( args=args, env=env, request=response.request, response=response, output_options=(args.output_options if response is final_response else args.output_options_others)), # NOTE: `env.stdout` will in fact be `stderr` with `--download` 'outfile': env.stdout, 'flush': env.stdout_isatty or args.stream } try: if env.is_windows and is_py3 and 'colors' in args.prettify: write_stream_with_colors_win_py3(**write_stream_kwargs) else: write_stream(**write_stream_kwargs) except IOError as e: if not show_traceback and e.errno == errno.EPIPE: # Ignore broken pipes unless --traceback. env.stderr.write('\n') else: raise if downloader and exit_status == ExitStatus.OK: # Last response body download. download_stream, download_to = downloader.start(final_response) write_stream( stream=download_stream, outfile=download_to, flush=False, ) downloader.finish() if downloader.interrupted: exit_status = ExitStatus.ERROR log_error('Incomplete download: size=%d; downloaded=%d' % (downloader.status.total_size, downloader.status.downloaded)) return exit_status finally: if downloader and not downloader.finished: downloader.failed() if (not isinstance(args, list) and args.output_file and args.output_file_specified): args.output_file.close()
def program(args, env, log_error): """ The main program without error handling :param args: parsed args (argparse.Namespace) :type env: Environment :param log_error: error log function :return: status code """ exit_status = ExitStatus.OK downloader = None show_traceback = args.debug or args.traceback try: if args.download: args.follow = True # --download implies --follow. downloader = Downloader( output_file=args.output_file, progress_file=env.stderr, resume=args.download_resume ) downloader.pre_request(args.headers) final_response = get_response(args, config_dir=env.config.directory) if args.all: responses = final_response.history + [final_response] else: responses = [final_response] for response in responses: if args.check_status or downloader: exit_status = get_exit_status( http_status=response.status_code, follow=args.follow ) if not env.stdout_isatty and exit_status != ExitStatus.OK: log_error( 'HTTP %s %s', response.raw.status, response.raw.reason, level='warning' ) write_stream_kwargs = { 'stream': build_output_stream( args=args, env=env, request=response.request, response=response, output_options=( args.output_options if response is final_response else args.output_options_history ) ), # NOTE: `env.stdout` will in fact be `stderr` with `--download` 'outfile': env.stdout, 'flush': env.stdout_isatty or args.stream } try: if env.is_windows and is_py3 and 'colors' in args.prettify: write_stream_with_colors_win_py3(**write_stream_kwargs) else: write_stream(**write_stream_kwargs) except IOError as e: if not show_traceback and e.errno == errno.EPIPE: # Ignore broken pipes unless --traceback. env.stderr.write('\n') else: raise if downloader and exit_status == ExitStatus.OK: # Last response body download. download_stream, download_to = downloader.start(final_response) write_stream( stream=download_stream, outfile=download_to, flush=False, ) downloader.finish() if downloader.interrupted: exit_status = ExitStatus.ERROR log_error('Incomplete download: size=%d; downloaded=%d' % ( downloader.status.total_size, downloader.status.downloaded )) return exit_status finally: if downloader and not downloader.finished: downloader.failed() if (not isinstance(args, list) and args.output_file and args.output_file_specified): args.output_file.close()