2019-08-31 15:17:10 +02:00
|
|
|
"""Parsing and processing of CLI input (args, auth credentials, files, stdin).
|
|
|
|
|
|
|
|
"""
|
2020-09-25 14:44:22 +02:00
|
|
|
import enum
|
2019-08-31 15:17:10 +02:00
|
|
|
import re
|
|
|
|
|
|
|
|
|
|
|
|
URL_SCHEME_RE = re.compile(r'^[a-z][a-z0-9.+-]*://', re.IGNORECASE)
|
|
|
|
|
|
|
|
HTTP_POST = 'POST'
|
|
|
|
HTTP_GET = 'GET'
|
|
|
|
|
|
|
|
# Various separators used in args
|
|
|
|
SEPARATOR_HEADER = ':'
|
|
|
|
SEPARATOR_HEADER_EMPTY = ';'
|
|
|
|
SEPARATOR_CREDENTIALS = ':'
|
|
|
|
SEPARATOR_PROXY = ':'
|
2021-12-23 20:06:35 +01:00
|
|
|
SEPARATOR_HEADER_EMBED = ':@'
|
2019-08-31 15:17:10 +02:00
|
|
|
SEPARATOR_DATA_STRING = '='
|
|
|
|
SEPARATOR_DATA_RAW_JSON = ':='
|
|
|
|
SEPARATOR_FILE_UPLOAD = '@'
|
2020-06-08 17:59:41 +02:00
|
|
|
SEPARATOR_FILE_UPLOAD_TYPE = ';type=' # in already parsed file upload path only
|
2019-08-31 15:17:10 +02:00
|
|
|
SEPARATOR_DATA_EMBED_FILE_CONTENTS = '=@'
|
|
|
|
SEPARATOR_DATA_EMBED_RAW_JSON_FILE = ':=@'
|
|
|
|
SEPARATOR_QUERY_PARAM = '=='
|
2021-12-01 19:09:39 +01:00
|
|
|
SEPARATOR_QUERY_EMBED_FILE = '==@'
|
2019-08-31 15:17:10 +02:00
|
|
|
|
|
|
|
# Separators that become request data
|
|
|
|
SEPARATOR_GROUP_DATA_ITEMS = frozenset({
|
|
|
|
SEPARATOR_DATA_STRING,
|
|
|
|
SEPARATOR_DATA_RAW_JSON,
|
|
|
|
SEPARATOR_FILE_UPLOAD,
|
|
|
|
SEPARATOR_DATA_EMBED_FILE_CONTENTS,
|
|
|
|
SEPARATOR_DATA_EMBED_RAW_JSON_FILE
|
|
|
|
})
|
|
|
|
|
2020-09-28 12:16:57 +02:00
|
|
|
SEPARATORS_GROUP_MULTIPART = frozenset({
|
|
|
|
SEPARATOR_DATA_STRING,
|
|
|
|
SEPARATOR_DATA_EMBED_FILE_CONTENTS,
|
|
|
|
SEPARATOR_FILE_UPLOAD,
|
|
|
|
})
|
|
|
|
|
2019-08-31 15:17:10 +02:00
|
|
|
# Separators for items whose value is a filename to be embedded
|
|
|
|
SEPARATOR_GROUP_DATA_EMBED_ITEMS = frozenset({
|
2021-12-23 20:06:35 +01:00
|
|
|
SEPARATOR_HEADER_EMBED,
|
2021-12-01 19:09:39 +01:00
|
|
|
SEPARATOR_QUERY_EMBED_FILE,
|
2019-08-31 15:17:10 +02:00
|
|
|
SEPARATOR_DATA_EMBED_FILE_CONTENTS,
|
|
|
|
SEPARATOR_DATA_EMBED_RAW_JSON_FILE,
|
|
|
|
})
|
|
|
|
|
2021-12-03 11:17:45 +01:00
|
|
|
# Separators for nested JSON items
|
|
|
|
SEPARATOR_GROUP_NESTED_JSON_ITEMS = frozenset([
|
|
|
|
SEPARATOR_DATA_STRING,
|
2019-08-31 15:17:10 +02:00
|
|
|
SEPARATOR_DATA_RAW_JSON,
|
2022-01-04 10:04:20 +01:00
|
|
|
SEPARATOR_DATA_EMBED_FILE_CONTENTS,
|
|
|
|
SEPARATOR_DATA_EMBED_RAW_JSON_FILE,
|
2019-08-31 15:17:10 +02:00
|
|
|
])
|
|
|
|
|
|
|
|
# Separators allowed in ITEM arguments
|
|
|
|
SEPARATOR_GROUP_ALL_ITEMS = frozenset({
|
|
|
|
SEPARATOR_HEADER,
|
|
|
|
SEPARATOR_HEADER_EMPTY,
|
2021-12-23 20:06:35 +01:00
|
|
|
SEPARATOR_HEADER_EMBED,
|
2019-08-31 15:17:10 +02:00
|
|
|
SEPARATOR_QUERY_PARAM,
|
2021-12-01 19:09:39 +01:00
|
|
|
SEPARATOR_QUERY_EMBED_FILE,
|
2019-08-31 15:17:10 +02:00
|
|
|
SEPARATOR_DATA_STRING,
|
|
|
|
SEPARATOR_DATA_RAW_JSON,
|
|
|
|
SEPARATOR_FILE_UPLOAD,
|
|
|
|
SEPARATOR_DATA_EMBED_FILE_CONTENTS,
|
|
|
|
SEPARATOR_DATA_EMBED_RAW_JSON_FILE,
|
|
|
|
})
|
|
|
|
|
|
|
|
# Output options
|
|
|
|
OUT_REQ_HEAD = 'H'
|
|
|
|
OUT_REQ_BODY = 'B'
|
|
|
|
OUT_RESP_HEAD = 'h'
|
|
|
|
OUT_RESP_BODY = 'b'
|
2021-12-23 21:13:25 +01:00
|
|
|
OUT_RESP_META = 'm'
|
2019-08-31 15:17:10 +02:00
|
|
|
|
2021-12-23 21:13:25 +01:00
|
|
|
BASE_OUTPUT_OPTIONS = frozenset({
|
2019-08-31 15:17:10 +02:00
|
|
|
OUT_REQ_HEAD,
|
|
|
|
OUT_REQ_BODY,
|
|
|
|
OUT_RESP_HEAD,
|
2021-12-23 21:13:25 +01:00
|
|
|
OUT_RESP_BODY,
|
|
|
|
})
|
|
|
|
|
|
|
|
OUTPUT_OPTIONS = frozenset({
|
|
|
|
*BASE_OUTPUT_OPTIONS,
|
|
|
|
OUT_RESP_META,
|
2019-08-31 15:17:10 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
# Pretty
|
|
|
|
PRETTY_MAP = {
|
|
|
|
'all': ['format', 'colors'],
|
|
|
|
'colors': ['colors'],
|
|
|
|
'format': ['format'],
|
|
|
|
'none': []
|
|
|
|
}
|
|
|
|
PRETTY_STDOUT_TTY_ONLY = object()
|
|
|
|
|
2020-05-27 15:58:15 +02:00
|
|
|
|
|
|
|
DEFAULT_FORMAT_OPTIONS = [
|
2020-05-28 12:26:06 +02:00
|
|
|
'headers.sort:true',
|
|
|
|
'json.format:true',
|
|
|
|
'json.indent:4',
|
|
|
|
'json.sort_keys:true',
|
2021-08-31 22:49:53 +02:00
|
|
|
'xml.format:true',
|
2021-08-31 22:52:16 +02:00
|
|
|
'xml.indent:2',
|
2020-05-27 15:58:15 +02:00
|
|
|
]
|
2020-06-16 12:54:50 +02:00
|
|
|
SORTED_FORMAT_OPTIONS = [
|
|
|
|
'headers.sort:true',
|
|
|
|
'json.sort_keys:true',
|
2020-06-16 12:20:13 +02:00
|
|
|
]
|
2020-06-16 12:54:50 +02:00
|
|
|
SORTED_FORMAT_OPTIONS_STRING = ','.join(SORTED_FORMAT_OPTIONS)
|
|
|
|
UNSORTED_FORMAT_OPTIONS_STRING = ','.join(
|
|
|
|
option.replace('true', 'false') for option in SORTED_FORMAT_OPTIONS)
|
2020-05-27 15:58:15 +02:00
|
|
|
|
2019-08-31 15:17:10 +02:00
|
|
|
# Defaults
|
|
|
|
OUTPUT_OPTIONS_DEFAULT = OUT_RESP_HEAD + OUT_RESP_BODY
|
|
|
|
OUTPUT_OPTIONS_DEFAULT_STDOUT_REDIRECTED = OUT_RESP_BODY
|
2019-09-03 17:14:39 +02:00
|
|
|
OUTPUT_OPTIONS_DEFAULT_OFFLINE = OUT_REQ_HEAD + OUT_REQ_BODY
|
2020-09-25 14:44:22 +02:00
|
|
|
|
|
|
|
|
2020-09-28 12:16:57 +02:00
|
|
|
class RequestType(enum.Enum):
|
2020-09-25 14:44:22 +02:00
|
|
|
FORM = enum.auto()
|
|
|
|
MULTIPART = enum.auto()
|
|
|
|
JSON = enum.auto()
|