Ограничение 64 КБ для данных JSON для урлопена - PullRequest
0 голосов
/ 24 октября 2018

Ударяю головой о проблему.Я заранее предупрежу, что это невозможно воспроизвести, поскольку я не могу поделиться своей конечной точкой.Кроме того, я работаю специалистом по данным, поэтому мои знания о веб-технологиях ограничены.

from urllib.request import Request, urlopen

url = "https://www.some_endpoint.com/"
req = Request(
    url, headers={"API-TOKEN": "some_token"})
json_string = "{"object": "XYZ".....}"

response = urlopen(req, json_string.encode("utf-8"))

Я получаю необычное поведение на урлопене.Когда мой JSON меньше 65536 байт, как показывает оценка len(json_string.encode('utf-8')), этот вызов urlopen работает нормально.Когда он превышает этот предел, я получаю ошибку HTTP 500.

Это чисто ограничение на стороне сервера при определении размера?Что необычно, так это то, что когда большие данные передаются через графический интерфейс в конечную точку, они работают нормально.Или я могу сделать что-то, чтобы разделить мои данные на 64-байтовые байты на urlopen?Существуют ли отраслевые стандарты для этого?

1 Ответ

0 голосов
/ 24 октября 2018

Ошибка HTTP 500 указывает на «внутреннюю ошибку сервера».Теоретически это означает, что с вашим кодом нет проблем, есть проблема с сервером.

На практике ошибка HTTP 500 может означать почти все, потому что многие серверы будут использовать HTTP 500 каккод ошибки по умолчанию, когда более конкретный код ошибки не предоставляется программистом.К сожалению, это означает, что вы вынуждены гадать, как работает чей-то код.

Вот несколько возможных подходов:

  • Возможно, у сервера есть максимальный запросразмер 64 КиБ.Вы можете уменьшить размер запроса, используя более компактный JSON (убрать пробелы между разделителями) или Content-Encoding: gzip.

    import gzip
    import json
    
    # Remove whitespace from JSON
    json_string = json.dumps(
        json.loads(json_string),
        separators=(',', ':'))
    # Encode as Gzip
    json_data = gzip.compress(
        json_string.encode('UTF-8'))
    
    req = Request(
        url, headers={"API-TOKEN": "some_token",
                      "Content-Encoding": "gzip"})
    response = urlopen(req, json_data)
    
  • Возможно, существует какой-либо способ разделения или разбиения на частизапрос на несколько меньших запросов.Для этого потребуется знание точного API, который вы используете.

  • Возможно, на сервере или в прокси-сервере есть какая-то ошибка, которая не позволяет вам отправлять запрос в письменном виде.Вы можете попробовать использовать Transfer-Encoding: chunked, если Content-Length не работает для> 64 КиБ.Возможно, сервер ожидает использовать 100 Continue, но urllib не поддерживает это.

Если вы используете MITM для своего клиента GUI с помощью таких инструментов, как Charles, вы можете увидеть точный форматзапрос, и вы можете сделать свой собственный запрос, используя тот же формат.

...