1
0
mirror of https://github.com/httpie/cli.git synced 2025-08-10 22:42:05 +02:00

Add warnings when there is no incoming data from stdin (#1256)

* Add warnings when there is no incoming data from stdin

* Pass os.environ as well

* Apply suggestions
This commit is contained in:
Batuhan Taskaya
2022-01-12 17:07:34 +03:00
committed by GitHub
parent 508788ca56
commit 00c859c51d
5 changed files with 144 additions and 4 deletions

View File

@@ -1,3 +1,5 @@
import sys
import os
import zlib
import functools
from typing import Any, Callable, IO, Iterable, Optional, Tuple, Union, TYPE_CHECKING
@@ -9,7 +11,9 @@ from requests.utils import super_len
if TYPE_CHECKING:
from requests_toolbelt import MultipartEncoder
from .context import Environment
from .cli.dicts import MultipartRequestDataDict, RequestDataDict
from .compat import is_windows
class ChunkedStream:
@@ -64,13 +68,58 @@ def _wrap_function_with_callback(
return wrapped
def is_stdin(file: IO) -> bool:
try:
file_no = file.fileno()
except Exception:
return False
else:
return file_no == sys.stdin.fileno()
READ_THRESHOLD = float(os.getenv("HTTPIE_STDIN_READ_WARN_THRESHOLD", 10.0))
def observe_stdin_for_data_thread(env: Environment, file: IO) -> None:
# Windows unfortunately does not support select() operation
# on regular files, like stdin in our use case.
# https://docs.python.org/3/library/select.html#select.select
if is_windows:
return None
# If the user configures READ_THRESHOLD to be 0, then
# disable this warning.
if READ_THRESHOLD == 0:
return None
import select
import threading
def worker():
can_read, _, _ = select.select([file], [], [], READ_THRESHOLD)
if not can_read:
env.stderr.write(
f'> warning: no stdin data read in {READ_THRESHOLD}s '
f'(perhaps you want to --ignore-stdin)\n'
f'> See: https://httpie.io/docs/cli/best-practices\n'
)
thread = threading.Thread(
target=worker
)
thread.start()
def _prepare_file_for_upload(
env: Environment,
file: Union[IO, 'MultipartEncoder'],
callback: CallbackT,
chunked: bool = False,
content_length_header_value: Optional[int] = None,
) -> Union[bytes, IO, ChunkedStream]:
if not super_len(file):
if is_stdin(file):
observe_stdin_for_data_thread(env, file)
# Zero-length -> assume stdin.
if content_length_header_value is None and not chunked:
# Read the whole stdin to determine `Content-Length`.
@@ -103,6 +152,7 @@ def _prepare_file_for_upload(
def prepare_request_body(
env: Environment,
raw_body: Union[str, bytes, IO, 'MultipartEncoder', RequestDataDict],
body_read_callback: CallbackT,
offline: bool = False,
@@ -125,6 +175,7 @@ def prepare_request_body(
if is_file_like:
return _prepare_file_for_upload(
env,
body,
chunked=chunked,
callback=body_read_callback,