Skip to content

Releases: aokazantsev/AgentProxy

AgentProxy 1.7

Choose a tag to compare

@aokazantsev aokazantsev released this 02 Nov 16:27
  • Несколько Android-устройств разделяются: device_proxy enable даёт каждому устройству свой порт на ПК (pc_port в ответе, закреплён за serial, все порты — device_ports в proxy_status; запоминаются 32 устройства, новое вытесняет то, которое включали давнее всех). Телефон по-прежнему смотрит на 127.0.0.1 и порт прокси, а adb reverse ведёт его на его порт ПК. Устройство, подключённое прежней версией, держит adb reverse на общий порт: его запросы идут без устройства, а status отвечает ready: false и pc_port: null с подсказкой, что у устройства ещё нет своего порта, — повторить enable.
  • Каждый запрос в истории несёт device — serial устройства; у запросов самого ПК и устройств, подключённых на общий порт руками, — null. Фильтр device есть у list_flows, wait_for_flow и wait_for_event; list_events и wait_for_event с device отказывают по потоку другого устройства; check_connection с serial считает трафик и отказы только этого устройства; монитор фильтрует по устройству.
  • Правило с полем device (add_rule, update_rule) подменяет ответы только этому устройству; без него — всем устройствам и ПК, как раньше. Ответ add_rule подсказывает, если у устройства ещё нет своего порта или правило без device при нескольких устройствах. Перенос правила с одного устройства на другое снимает его с уже открытых потоков и соединений, ответ, который правило cut ещё не оборвало, не обрывается; правило без device, суженное до одного устройства, действует на новые запросы, а открытые потоки и соединения остальных держит до их закрытия; снятие device открытое не трогает.
  • clear_flows с device чистит историю одного устройства, delete_rule с all: true и device удаляет только правила этого устройства (HTTP: DELETE /api/flows?device=<serial> и DELETE /api/rules?device=<serial>; другие параметры и тело у них теперь — отказ 400). Пустой device — отказ, а не «все устройства».
  • При нескольких устройствах — всегда передавать serial в device_proxy и device в чтение истории и правила: иначе видны чужие запросы, а правило меняет ответы чужому устройству (скилл, раздел «Несколько устройств»).
  • Пауза на время Charles снимает и возвращает прокси каждому устройству на его порт.
  • Совет при зависшем adb — adb -s <serial> reconnect вместо adb kill-server, который рвёт связь со всеми устройствами.
  • wait_for_flow и wait_for_event ждут не дольше 55 секунд, по умолчанию 50: клиент MCP обрывает вызов примерно через 60 секунд с ошибкой «The operation timed out», и ответ «ничего не пришло» до него не доходил. Больше 55 — отказ, он называет предел; то же у HTTP /api/flows/wait и /api/events/wait. Ждать дольше — повторить вызов с курсором из ответа timed_out: у wait_for_flow — since_seq = last_seq, у wait_for_event с flow — тот же flow и since_n; тогда запрос или событие, пришедшие между вызовами, не теряются. Без flow события между вызовами видны только в list_events.

AgentProxy 1.6

Choose a tag to compare

@aokazantsev aokazantsev released this 27 Oct 07:28
  • Новое действие правила cut (add_rule, update_rule): ответ идёт от сервера, а прокси обрывает его посреди тела, когда приложению ушло after_bytes байт тела или after_percent (1–99) от Content-Length. HTTP/1.1 — соединение закрывается без конца тела, HTTP/2 — сбрасывается только этот поток: приложение видит обрыв сети посреди загрузки, а не короткий ответ. Нужно ровно одно из двух полей; download_kbps и delay_ms работают как у остальных действий, и download_kbps в том же правиле даёт обрыв посреди медленной загрузки. times у cut считает оборванные ответы, а не запросы: HEAD и другие не оборванные ответы правило не тратят, поэтому cut с times: 1 рвёт первый ответ, дошедший до точки, а повтор или докачка с Range проходят целиком. Оборванным может оказаться и не тот запрос — проба, побочный Range медиаплеера или запрос, брошенный самим приложением (прокси успевает отдать ему больше, чем оно прочитало): после первой попытки сверить по list_flows с rule, какой запрос получил cut_after_bytes, и при промахе поменять точку через update_rule с reset_hits. Без times ответ add_rule предупреждает, что оборвётся и каждый повтор.
  • У оборванного запроса в истории rules несёт cut_after_bytes, а error записи — «AgentProxy rule … cut the response after N bytes of body», тело — дошедшая часть. Не оборванный ответ получает skipped с причиной: ответ правила respond/sse, ответ без тела, тело не длиннее точки обрыва, тело под правкой rewrite, SSE (его рвёт events с close), after_percent без Content-Length, ответ без длины клиенту HTTP/1.0, ответ, оборванный раньше точки клиентом или сервером, обрыв раньше другим правилом cut, правило исчерпано другими ответами, выключено или удалено раньше, чем ответ дошёл до точки обрыва. Ответ без длины клиенту HTTP/1.1 прокси отдаёт chunked и закрывает соединение после него: иначе закрытие соединения было бы обычным концом такого ответа.
  • Скилл agentproxy, rules.md: раздел «Обрыв cut», строки про обрыв на медленной загрузке («Скорость») и про докачку после обрыва («Порядок и сценарии»).

AgentProxy 1.5

Choose a tag to compare

@aokazantsev aokazantsev released this 26 Oct 07:17
  • Счётчики статистики использования записываются через временный файл и подменяют прежний целиком: выход программы или выключение Windows во время записи больше не обнуляют накопленное за последние дни.
  • Пакет статистики, собранный до выключения статистики в настройках, больше не уходит после него, если его отправка ещё не началась, даже если статистику тут же включили снова; ответ сервера на такой пакет не помечает новые счётчики отправленными. Выключение удаляет и временный файл счётчиков.
  • Если установщику не удалось записать выбор об отчётах о сбоях или о статистике, он называет папку и причину, а не показывает голую системную ошибку.
  • «Сохранить» в настройках меняет в settings.json только то, что изменили в окне: значения, поправленные в файле вручную, пока окно было открыто, больше не затираются тем, что окно показало при открытии. Если вместе с ручной правкой порты совпали, окно об этом говорит и ничего не пишет.
  • Разовое уведомление о статистике показывается, когда движок запустился или сообщил о проблеме, — последним из уведомлений запуска: уведомление о проблеме движка при запуске больше не вытесняет его, и щелчок по нему в Центре уведомлений открывает настройки, если после него не было других уведомлений. Выход из программы, пока движок запускается, уведомление не тратит: оно покажется при следующем запуске.

AgentProxy 1.4

Choose a tag to compare

@aokazantsev aokazantsev released this 25 Oct 12:09
  • Оборвавшаяся загрузка обновления (сбой сети или сервера, файл не удалось перенести на место) больше не оставляет в «Загрузках» недокачанный файл .part: он удаляется сразу.
  • Второй установщик, запущенный, пока идёт первый, пишет в журнал установки одну строку и больше не переносит журнал идущей установки в AgentProxy-setup.old.log и не вставляет в него свой заголовок.

AgentProxy 1.3

Choose a tag to compare

@aokazantsev aokazantsev released this 25 Oct 10:24
  • Журнал установщика (%TEMP%\AgentProxy-setup.log) больше не стирается при повторной попытке установки: каждый запуск дописывается в конец, а журнал больше 512 КБ при следующем запуске переносится в AgentProxy-setup.old.log рядом с ним. В него теперь попадают и заметки из итога установки, и отказы окна установщика (папка не подходит, идёт удаление).
  • Если установка сорвалась после того, как установщик закрыл программу, окно ошибки говорит, что программа закрыта и не запущена снова, и подсказывает исправить причину и повторить установку.
  • Окно обновления, открытое снова, пока ещё идёт загрузка, больше не качает установщик в тот же файл одновременно с первой загрузкой: оно дожидается её и берёт готовый файл, если тот совпал с контрольной суммой на GitHub. Установщик той же версии, уже лежащий в «Загрузках», не скачивается заново, если совпал с контрольной суммой на GitHub. Сбой при загрузке называется «Не удалось скачать обновление», а не «Не удалось проверить обновление».

AgentProxy 1.2

Choose a tag to compare

@aokazantsev aokazantsev released this 25 Oct 08:10
  • Установщик и деинсталлятор закрывают и копию трея, запущенную, пока шла остановка.
  • Пока идёт установка в окне, установщик не даёт Windows завершить работу без вопроса и установка не обрывается на полпути.
  • Удаление и перенос в новую папку убирают и файлы и папки с атрибутом «только чтение» (в папке программы и в папке данных), а не оставляют папку недоудалённой.
  • Неудачная проверка обновления (из меню и ежедневная) пишет в log.txt вместо полного текста сетевой ошибки её вид и код ответа сервера: имя, адрес и порт прокси больше не попадают в журнал и в отчёт о сбое.

AgentProxy 1.1

Choose a tag to compare

@aokazantsev aokazantsev released this 25 Oct 06:56
  • send_event в WebSocket отвечает после того, как сообщение прошло прокси. Если правило events оборвало соединение раньше, чем сообщение ушло, или соединение закрылось, — отказ вместо sent: true; писать в новый поток после переподключения. Прокси не передал сообщение за 5 с — тоже отказ, но сообщение может ещё уйти: перед повтором смотреть list_events.
  • Пометка closed у правила events говорит, как считается номер: before incoming event 3 (counting incoming events with data, without send_event messages; not n of list_events). Место обрыва в list_events — событие note «rule … closed the stream …»; у обрыва на исходящем сообщении WebSocket это note теперь с direction: outgoing.
  • history_matches у правила events не считает потоки, которые правило не тронет: сжатый SSE, поток правила sse, SSE с кодом ответа не 2xx; если других совпадений нет, hint называет число таких потоков и как снять сжатие.
  • Правило events с direction: outgoing и close больше не переводит хост на HTTP/1.1 (WebSocket через прокси и так HTTP/1.1) и не пишет в hint про перезапуск приложения ради HTTP/2.
  • Прокси больше не замирает, пока распаковывает сжатый ответ для истории; ответ клиенту уходит с той же задержкой, что и раньше.
  • Трей: «Перезапустить движок» и смена настроек больше не замораживают меню, пока зависший движок останавливается (до 15 с).
  • Установщик: окно и тихий режим одинаково решают, обновление это или новая установка: запись в «Приложениях» без программы в папке — новая установка, автозапуск включён.
  • Скилл agentproxy, rules.md: в разделе «Порядок и сценарии» сказано, что respond/drop/sse закрывает правила events и раньше себя по списку.

AgentProxy 1.0

Choose a tag to compare

@aokazantsev aokazantsev released this 24 Oct 20:52
  • Новое действие правила events (add_rule, update_rule): меняет события SSE и WebSocket, которые идут через прокси от настоящего сервера. Условия (host, path, method, url_regex) выбирают поток при его открытии, дальше правило смотрит каждое событие: в SSE — событие с data: (комментарии не трогаются), в WebSocket — сообщение. Поля: event_contains — только события, в данных которых есть этот текст (с учётом регистра, данные как в list_events); direction — incoming (по умолчанию, от сервера) или outgoing (от приложения, только WebSocket); replace — замены текста в данных; event_data — новые данные целиком (в SSE перевод строки даёт несколько строк data:, event: и id: остаются); close — before (событие не доставляется) или after (сначала событие): рвёт соединение приложения без кадра закрытия, приложение видит обрыв сети, дальше ничего не доставляется. Нужно хотя бы одно из replace, event_data, close; event_data и replace вместе не принимаются, delay_ms, download_kbps и upload_kbps у events тоже.
  • hits и times у events считают потоки, обычные запросы и потоки, которые правило не правит (сжатый SSE, поток правила sse, SSE для правила с direction: outgoing), их не тратят: close с times: 1 действует только на первый подходящий поток и пропускает переподключение. Правило видят потоки, открытые после него: ответ add_rule напоминает переподключить приложение, а для close без times предупреждает о цикле переподключений. history_matches у такого правила считает только записи SSE и WebSocket, у direction: outgoing — только WebSocket. update_rule и delete_rule действуют на открытые потоки сразу.
  • send_event в WebSocket, оборванный правилом events, отказывает: писать в новый поток после переподключения. send_event отвечает last_seq: реакцию приложения на событие SSE ждать wait_for_flow с since_seq = last_seq. wait_for_flow с since_seq отдаёт первый подходящий запрос после него, а не самый новый. В update_rule поля close и direction снимаются null, как и остальные; null в числовых параметрах инструментов — значение по умолчанию.
  • В истории события уже изменённые. У записи потока в rules пометки: changed — сколько событий изменено, replaced — замен всего, closed — где оборвано (before incoming event 3: счёт — события с данными этого направления, а не n из list_events), skipped — правка не применена (сжатый SSE, событие больше 1 МБ, поток правила sse, бинарное сообщение WebSocket), error — оборвать не удалось; у открытого потока пометки появляются после его конца, до того результат видно в list_events. not_found у events нет. После обрыва в событиях потока — note «rule … closed the stream …», в строке rules #seq журнала — changed и closed; недоставленное сообщение WebSocket — с note dropped. Монитор показывает эти пометки.
  • На HTTP/2 close рвёт всё соединение приложения с соседними запросами, closed об этом говорит; хосту из host правила с close прокси даёт новым соединениям только HTTP/1.1. Сжатый SSE правило не меняет: нужен rewrite с request_headers {"Accept-Encoding": "identity"}.
  • Пометка skipped у rewrite с правкой тела SSE теперь называет events.
  • Трей: выход из Windows больше не выглядит как «движок упал» и не отправляет отчёт о сбое; установщик с окном не включает снова выключенный автозапуск; окно «Журнал» не перескакивает в конец, пока журнал прокручен вверх или в нём выделен текст.
  • Скилл agentproxy: раздел «События events» в rules.md, строка в разделе потоков SKILL.md.

AgentProxy 0.15

Choose a tag to compare

@aokazantsev aokazantsev released this 24 Oct 13:45
  • Галка трея «Выключать прокси, пока запущен Charles» («Настройки…», по умолчанию выключена, ключ yield_to_charles в settings.json). Пока запущен Charles.exe, прокси не слушает порт, а устройства, у которых прокси равен адресу AgentProxy, снимаются с него (http_proxy :0, adb reverse --remove). Когда Charles закроют, прокси включается сам и возвращает прокси снятым устройствам, если они подключены и прокси на них никто не задал.
  • Уже открытые соединения клиентов (WebSocket, SSE, keep-alive) пауза не рвёт: они доживают через AgentProxy, чтобы всё ушло в Charles — перезапустить приложение. agentproxy.cmd status на паузе отвечает кодом 0 с "paused": "charles".
  • На паузе работают MCP, HTTP API, монитор и история. proxy_status и check_connection отдают proxy.paused: "charles" (иначе null), proxy_status — ещё proxy.yield_to_charles (галка включена), у check_connection новый вердикт paused_for_charles с подсказкой, device_proxy enable отказывает с объяснением. Хук старта сессии пишет «выключен, пока запущен Charles».
  • Скилл agentproxy: строка про паузу на время Charles в «Почему не видно трафика».

AgentProxy 0.14

Choose a tag to compare

@aokazantsev aokazantsev released this 24 Oct 05:18
  • Ограничение скорости в правилах (add_rule, update_rule): новые поля download_kbps (скорость ответа клиенту) и upload_kbps (скорость чтения тела запроса от клиента), кбит/с, 1..1000000, у любого действия. Действие delay теперь «только замедлить»: нужен delay_ms, download_kbps или upload_kbps. Скорость правила общая на все запросы и соединения, которые оно замедляет, как одна медленная сеть; запрос под несколькими правилами идёт по самому медленному, и его байты учитываются только в нём. Работает и для ответов сервера, и для respond и sse. Таймаут чтения приложения срабатывает только на паузе без данных: по HTTPS запись TLS в 16 КБ идёт не меньше 131 / download_kbps секунд и дольше, пока правило замедляет несколько передач сразу; по HTTP паузы короткие.
  • Замедляется соединение клиента, пока по нему идёт подходящий запрос. На HTTP/1.1 это ровно этот запрос; хосту из условия host такого правила прокси даёт новым соединениям только HTTP/1.1. На HTTP/2 (нет host, соединение открыто до правила, клиент только HTTP/2) соединение замедляется целиком до закрытия. У запроса в поле rules пометка limited: request или connection; соединения не TCP — skipped. Ответ add_rule/update_rule подсказывает про перезапуск приложения и про host. Новая скорость в update_rule действует сразу, и на идущий ответ; удаление и выключение правила снимают ограничение сразу.
  • Скилл agentproxy: раздел «Скорость» в rules.md.
  • Известные ограничения скорости: WebSocket, открытый запросом под правилом, замедлен до закрытия (пометка у него limited: request); хост по IP-адресу без SNI на HTTP/1.1 не переводится; upload_kbps на соединении HTTP/2 замедляет и служебные кадры клиента; на HTTP/2 лимит правила держится и после исчерпания times; пометка skipped «not TCP» бывает и при сбое обёртки соединения (причина — в read_log).