Repository navigation
Releases: aokazantsev/AgentProxy
Releases · aokazantsev/AgentProxy
Release list
AgentProxy 1.7
- Несколько 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
- Новое действие правила
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
- Счётчики статистики использования записываются через временный файл и подменяют прежний целиком: выход программы или выключение Windows во время записи больше не обнуляют накопленное за последние дни.
- Пакет статистики, собранный до выключения статистики в настройках, больше не уходит после него, если его отправка ещё не началась, даже если статистику тут же включили снова; ответ сервера на такой пакет не помечает новые счётчики отправленными. Выключение удаляет и временный файл счётчиков.
- Если установщику не удалось записать выбор об отчётах о сбоях или о статистике, он называет папку и причину, а не показывает голую системную ошибку.
- «Сохранить» в настройках меняет в
settings.jsonтолько то, что изменили в окне: значения, поправленные в файле вручную, пока окно было открыто, больше не затираются тем, что окно показало при открытии. Если вместе с ручной правкой порты совпали, окно об этом говорит и ничего не пишет. - Разовое уведомление о статистике показывается, когда движок запустился или сообщил о проблеме, — последним из уведомлений запуска: уведомление о проблеме движка при запуске больше не вытесняет его, и щелчок по нему в Центре уведомлений открывает настройки, если после него не было других уведомлений. Выход из программы, пока движок запускается, уведомление не тратит: оно покажется при следующем запуске.
AgentProxy 1.4
- Оборвавшаяся загрузка обновления (сбой сети или сервера, файл не удалось перенести на место) больше не оставляет в «Загрузках» недокачанный файл
.part: он удаляется сразу. - Второй установщик, запущенный, пока идёт первый, пишет в журнал установки одну строку и больше не переносит журнал идущей установки в
AgentProxy-setup.old.logи не вставляет в него свой заголовок.
AgentProxy 1.3
- Журнал установщика (
%TEMP%\AgentProxy-setup.log) больше не стирается при повторной попытке установки: каждый запуск дописывается в конец, а журнал больше 512 КБ при следующем запуске переносится вAgentProxy-setup.old.logрядом с ним. В него теперь попадают и заметки из итога установки, и отказы окна установщика (папка не подходит, идёт удаление). - Если установка сорвалась после того, как установщик закрыл программу, окно ошибки говорит, что программа закрыта и не запущена снова, и подсказывает исправить причину и повторить установку.
- Окно обновления, открытое снова, пока ещё идёт загрузка, больше не качает установщик в тот же файл одновременно с первой загрузкой: оно дожидается её и берёт готовый файл, если тот совпал с контрольной суммой на GitHub. Установщик той же версии, уже лежащий в «Загрузках», не скачивается заново, если совпал с контрольной суммой на GitHub. Сбой при загрузке называется «Не удалось скачать обновление», а не «Не удалось проверить обновление».
AgentProxy 1.2
- Установщик и деинсталлятор закрывают и копию трея, запущенную, пока шла остановка.
- Пока идёт установка в окне, установщик не даёт Windows завершить работу без вопроса и установка не обрывается на полпути.
- Удаление и перенос в новую папку убирают и файлы и папки с атрибутом «только чтение» (в папке программы и в папке данных), а не оставляют папку недоудалённой.
- Неудачная проверка обновления (из меню и ежедневная) пишет в
log.txtвместо полного текста сетевой ошибки её вид и код ответа сервера: имя, адрес и порт прокси больше не попадают в журнал и в отчёт о сбое.
AgentProxy 1.1
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
- Новое действие правила
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 — сnotedropped. Монитор показывает эти пометки. - На 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
- Галка трея «Выключать прокси, пока запущен 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
- Ограничение скорости в правилах (
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).