10 ноября 2022

Ангелы Charles:
Как сниффер поможет разработчикам мобильных приложений

Charles называют самым популярным сниффером, инструментом для мониторинга трафика и подмены данных. Он работает как промежуточное звено между вебом или мобильным приложением (в нашем случае) и сервером. Этот инструмент хорошо знают тестировщики, но разработчикам тоже полезно знать и пользоваться его возможностями. В этой статье мы сосредоточимся на основных функциях Charles для мобильных приложений.
Обложка статьи про дизайн складных экранов для Андроид
Sic! Это продолжение статьи про Charles - начало касается настройки приложения и его интерфейса.

Для начала кратко приведем примеры кейсов разработчиками:

  • Бэк еще не реализовал фичу, которую уже реализовали мы.
  • Бэк присылает не те данные.
  • Добавить или убрать элемент интерфейса, когда через код это делать дольше.
  • Получить данные, которые не заведены (например, данные о пользователе).
  • Упрощает поиск причин багов.
  • Проверка фич после реализации.

И, не откладывая в долгий ящик, перейдем к функциям Charles.
Throttling соединения
Одна из функций Charles - троттлинг соединения, который позволяет симулировать различное поведение Сети.
Инструмент позволит узнать, как приложение будет работать, например, в ситуации нестабильного интернет-соединения или его внезапного отсутствия.

Включить функцию троттлинга можно в меню Proxy, выбрав там пункт «Throttle Settings».

Давайте посмотрим на все настройки функции.

Enable Throttling — это чекбокс включения/отключения троттлинга по приложению. Можно поставить чекбокс на Only for selected hosts — это позволит проводить троттлинг только для заданных url.
Их можно добавить или удалить ниже (Add и Remove).

Далее в меню вы видите набор предустановленных настроек соединений (Throttle preset).

Bandwidth — это скорость соединения,
Utilisation — процент пропускной способности, которую можно предоставить пользователю в любой момент времени.
Round-trip latency — здесь устанавливается задержка между клиентом и сервером.
MTU — максимальный размер пакета.
Reliability, измеряемая в процентах, устанавливает вероятность, что соединение не удастся. Именно эта кнопка нужна для имитации ненадежных сетевых условий. Кнопка Stability задает вероятность нестабильного соединения и снижения качества. Это полезно для моделирования сетей, в которых периодических падает качество связи - например, мобильных.

Throttling может работать даже при установленном в приложении SSL пиннинге - достаточно настроить его и убрать Enable SSL Proxying с запросов необходимого домена.
Подмена запросов/ответов
Одна из часто используемых функций Charles - подмена запросов/ответов. Часто это самый простой вариант проверки того, как будет отображаться в приложении та или иная фича. «Чарльз» умеет менять ответ от сервера.
Есть четыре основных инструмента для подмены запросов/ответов, которые предлагаются программой:

  1. Breakpoint – позволяет поставить на паузу запрос или ответ и редактировать их в режиме реального времени.
  2. Rewrite – универсальный инструмент подмены, который по заданному правилу ищет совпадения и заменяет на необходимые нам.
  3. Map Local – подменяет целиком ответ на локальный json.
  4. Map Remote – автоматическая переадресация пользователя с одного URL-адреса на другой.

Сравнение преимуществ и недостатков методов, которое заранее может помочь определиться, какой метод выбрать для работы с вашей задачей:
А теперь подробнее о каждом из инструментов.
Breakpoint
Преимущества этого инструмента, который, как мы помним, позволяет поставить на паузу и отредактировать запрос или ответ, в легкости его применения и возможности редактирования как запроса, так и ответа. Этот инструмент идеален для быстрого изменения статуса кода, изменений небольшого числа параметров в запросе/ответе, для единичных случаев подмены.

Однако есть и несколько недостатков: слишком короткое время на редактирование запроса, кроме того, редактировать его приходится каждый раз.

Как пользоваться Breakpoint

1. Правым кликом на запрос добавляем его в список для Breakpoint

2. Редактировать список добавленного в Breakpoint можно в Proxy → Breakpoint Settings
3. В момент отправки запроса или получения ответа срабатывает Breakpoint, после чего в окне появляется соответствующая вкладка.

4. Затем переходим в таб Edit Request. Здесь можно изменить Query запроса на Add/Remove.
Функционал кнопок внизу:

  • Cancel - отменяет изменения, внесенные за время работы breakpoint, и пропускает запрос/ответ дальше в оригинальном виде.
  • Abort - сбрасывает запрос/ответ и возвращает на клиент ошибку.
  • Execute - применяет внесенные изменения и пропускает запрос/ответ дальше

Редактировать данные запроса (как и ответа) удобно в табах Headers или Json Text.

Запрос:
Для продолжения нажимаем на Execute. Теперь запрос прошел и открылось окно ответа. Переходим в таб Edit Response.

Ответ (Headers):
Ответ (Json text):
Для продолжения нажимаем на Execute.
В Breakpoint Settings можно поменять настройки, при которых будет срабатывать брейкпоинт – это актуально, если надо редактировать только ответ и постоянно пропускать запрос.
FAQ
Rewrite
Этот тип подмены по заданному правилу ищет совпадения и заменяет на необходимые нам. В отличие от Breakpoint, здесь как раз довольно сложная настройка, а также есть необходимость настраивать подмену предварительно.

Однако важнее преимущества Rewrite, которые заключаются в его универсальности:
- Подмена здесь происходит автоматически,
- в наличии гибкий инструмент в параметрах подмены,
- есть возможность менять и запрос, и ответ.

Этот инструмент идеально подходит для подмены хоста, подмены определенных параметров на конкретные значения, подмен/изменений в query запроса.
Как пользоваться Rewrite

1. Переходим в меню ToolsRewriteRewrite Settings
2. С помощью кнопки Add добавляем новую вкладку подмен. Затем в Location при необходимости добавляем путь подмены.
Достаточно вставить скопированную заранее ссылку в Host, и она автоматически распарсится.
Можно оставить * в Host для подмены на всех путях. Точно так же можно поступить с полем Location, это будет равносильно * или применению ко всем путям.

3. Затем во втором блоке мы настраиваем подмену Rewrite Rule
4. Выбираем Type подмены
5. Выбираем, на что распространяется подмена Request/Response. Request включает или выключает правило подмены на запрос, Response — на ответ.
6. Заполняем поля Match поиска
Здесь Name — это имя ключа, который ищет правило для подмены, Value — значение, которое ищет правило для подмены, Regex — чекбокс для включения регулярных выражений, если они описаны в полях выше, Match whole value — чекбокс для поиска полного совпадения, Case sensitive — чекбокс для включения/отключения чувствительности к регистру.

7. После заполняем поля Replace замены
Тоже расшифруем: Name — новое имя для ключа, Value — новое значение, которое применится после замены. Replace first означает, что замена сработает только на первое совпадение, Replace all — замена сработает на все совпадения.

Настройки Rewrite.
Важнее всего обратить внимание на Enable Rewrite — это главный чекбокс включения/отключения работы Rewrite подмен в приложении.

Debug in Error Log позволяет отслеживать работу правил подмены в дебаг меню.

Посмотрим также на список подмен.
  • Чекбокс — включает/отключает конкретный пункт подмены
  • Add — добавляет новый пункт в список
  • Remove — удаляет пункт из списка
  • Import/Export — добавляет/сохраняет настройки из/в файл

Location:
  • Чекбокс — включает/отключает конкретный путь подмены
  • Add — добавляет новый путь
  • Remove — удаляет путь

Под Location список Rewrite Rule в кратком варианте отображает Type и Action правила подмены.
  • Чекбокс — включает/отключает конкретное правило подмены
  • Add — добавляет новое правило
  • Remove — удаляет правило
  • Up/Down — позволяет передвигать правила выше/ниже (чем правило выше, тем больше у него приоритет)

Теперь перейдем непосредственно к Rewrite Rule и рассмотрим типы правил подмены.
Примеры правил подмены:
1. Add / Modify / Remove Header — применяет изменения к Headers запроса/ответа. Алгоритм работы с ними во всех случаях начинается с выбора чекбоксом предмета замены (запрос или ответ). Далее, в зависимости от функции:

Add (добавляет хедер):
  • Достаточно заполнить второй блок Replace — ключ в Name, значение в Value
  • Повторяем запрос

Modify (изменяет существующий хедер):
  • Заполняем первый блок Match условием для поиска хедера под замену ("ключ":"значение", регулярные выражения)
  • Заполняем второй блок Replace новым хедером ("ключ":"значение")

Remove (удаляет существующий хедер):
Заполняем первый блок Match условием для поиска хедера для удаления ("ключ":"значение", регулярные выражения)
Пример из практики:

Для определения геопозиции используется запрос, который уже редиректит на нужный ответ в зависимости от страны. Мы подменяем в хедере ответа ссылку на редирект.
Результат:
2. Host / Path / URL — позволяет изменить путь ссылки. Во всех этих функциях важно задизейблить чекбокс выбора запроса/ответа. Далее:

Host (подмена домена):
  • в первом блоке — Match — заполните единственное доступное поле Value условием для поиска домена под замену,
  • во втором блоке — Replace — заполняем поле Value новым доменом.

Path (подмена в пути ссылки):
  • в блоке Match заполняем поле Value условием для поиска части пути под замену,
  • в блоке Replace заполняем поле Value новым путем.

URL (подмена ссылки целиком).
  • Здесь заполняем Value в блоке Match условием для поиска части ссылки под замену,
  • в блоке Replace заполняем поле Value новой частью ссылки.
Пример из практики:

Подмена тестового сервера с приходящего https://spb.test.dev.ru на необходимый в данный момент https://spb.web.test.ru
3. Add / Modify / Remove Query Param — применяет изменения к Query запроса/ответа. Во всех трех вариантах чекбокс выбора запроса/ответа задизейблен. В остальном есть небольшие различия:

  • Add — добавление квери. Здесь достаточно заполнить второй блок Replace — ключ в Name, значение в Value — и повторить запрос.
  • Modify — изменение существующего квери. Здесь первый блок Match заполняем условием для поиска квери под замену ("ключ":"значение", регулярные выражения), а второй блок Replace - новым квери ("ключ":"значение").
  • Remove — удаление существующего квери. Здесь просто заполняем первый блок Match условием для поиска квери для удаления ("ключ":"значение", регулярные выражения)
Пример из практики:

Подмена тега в приложении Sports.ru, когда легким движением руки мы получаем на экране информации игрока не Роналду, а Месси.
Результат:
4. Response Status — позволяет изменить статус-код ответа.

В этой ситуации чекбокс выбора запроса/ответа задизейблен, подмена только на ответ. Заполняем первый блок Match в единственном доступном поле Value условием для поиска статус-кода под замену, в блоке Replace заполняем поле Value новым статус-кодом.
Пример из практики:

Кейс, касающийся подмены статуса 200 на 500 для отображения ошибки сервера.
Результат:
5. Body — изменение тела запроса/ответа.

Здесь выбираем чекбоксом предмет замены (запрос/ответ), заполняем первый блок Match условием для поиска параметра под замену ("ключ":"значение", регулярные выражения), заполняем второй блок Replace новым параметром ("ключ":"значение").
Пример из практики:

Меняем на приложении «Кассир.ру» минимальную цену события с 2500 на 0.
Для правил подмены лучше брать структуру, которая находится во вкладке ответа Text. Это поможет не запутаться — нужны лишние пробелы в подмене или нет.

Пробелы чаще не нужны, их стоит убрать между парами "ключ":"значение". Но бывают и исключения. Копирование из Text поможет избежать подобных проблем.
FAQ
Map Local
Этот метод подменяет целиком ответ на локальный json. Он работает только с ответом, не касаясь запроса. Кроме того, здесь необходима предварительная настройка — получение рабочего json.

Однако есть важные преимущества:
  • возможность одновременной работы с большим количеством изменений,
  • возможность «нарисовать» выдачу, которой нет на сервере,
  • изменения подтягиваются при новом запросе сразу после сохранения в json.
Этот метод идеально подойдет для работы с большим количеством изменений в структуре ответа и для моментов, когда сервер не отдает нужный ответ — бэкенд еще не готов.


Как пользоваться Map Local
1. Заранее подготовьте json с полным ответом от сервера. Проще всего его взять из готового ответа и изменить под свои требования, либо воспользоваться сваггером/документацией для того, чтобы написать ответ самостоятельно.

2. Отредактируйте данные json файла в текстовом редакторе и сохраните файл.

Рекомендуем использовать для редактирования текстовый редактор с возможностью удобной работы с JSON - например, Sublime Text.

3. Правым кликом по нужному запросу выбираем Map Local и попадаем в меню добавления/редактирования Edit Mapping.

Блоки интерфейса мобильного приложения
4. В блоке Map From уже будет заполнен запрос — и тут же его можно отредактировать.

5. В блоке Map To кнопкой Choose выбираем путь до файла json, который подготовили ранее. Затем повторяем запрос с экрана или вручную. В запросе будет приходить новый сохраненный ответ из файла.

Если есть необходимость, редактируйте json — при этом повторно путь к файлу задавать не надо, он уже добавлен.


Настройки Map Local

Переходим в меню Tools → Map Local. Map Local Settings выглядит так:
Блоки интерфейса мобильного приложения
Enable Map Local — чекбокс, который включает/отключает работу Map Local в приложении.
Список запросов с подменой содержит путь запроса и путь до файла json.
Чекбокс у подмены включает/отключает конкретно эту подмену в приложении.

Кнопки: Add — добавляет новый запрос для подмены, Remove - удаляет, а Up/Down — позволяет передвигать подмены выше/ниже, повышая или понижая их приоритет. Import/Export позволяют добавлять/сохранять настройки из файла или в файл.

Двойной клик по подмене из списка откроет меню добавления/редактирования Edit Mapping. Можно отредактировать Host или перевыбрать файл json для подмены
Блоки интерфейса мобильного приложения
FAQ
Map Remote
Мы подобрались к последнему методу подмены, который используется в Charles. Он нужен для автоматической переадресации пользователя с одного URL-адреса на другой. Это его главный недостаток и одновременно преимущество: Map Remote умеет только редиректить на новую ссылку, но это самый простой способ подменить путь ссылки, когда уже готов нужный ответ.

Как использовать метод
1. Правым кликом по нужному запросу выбираем Map Remote и попадаем в меню добавления/редактирования Edit Mapping.

2. Здесь в блоке Map From уже будет заполнен запрос, но его можно тут же отредактировать.

3. В Map To добавляем путь, на который будет настроен дальнейший редирект. После чего повторяем запрос.
Настройки Map Remote
Переходим в меню ToolsMap Remote.
layout list detail
Здесь все так же, как в настройках предыдущего метода.

Enable Map Remote — это чекбокс, который включает/отключает работу Map Remote в приложении.
Список запросов с редиректом содержит путь запроса и новый путь, на который мы ссылаемся.
Чекбокс у редиректа включит/отключит конкретно этот редирект в приложении

Кнопки: Add добавит новый запрос для редиректа, Remove удалит его из списка, Up/Down передвинет редиректы выше/ниже, меняя их приоритет. Import/Export — добавит/сохранит настройки из или в файл.

Двойной клик по редиректу из списка откроет меню добавления/редактирования Edit Mapping. Здесь можно заменить Map From и Map To.


layout supporting panel
FAQ
Итог
Мы рассмотрели функциональность Charles Proxy с упором на правила подмены, которые могут понадобиться при работе с мобильными приложениями. Скорее всего, вы столкнетесь с такими задачами.

Не стоит останавливаться на одном методе, если вы его попробовали и начали для всего использовать. Каждый метод хорош по-своему и оптимально подходит под конкретные задачи. Знакомство с каждым из них позволит оптимизировать ваш рабочий процесс и сделать его более интересным и комфортным. Например, Breakpoint лучше справляется со статус-кодами, а Map Local — с большими json-структурами. Так что не поленитесь узнать все методы — это позволит ускорить лично вашу работу и оптимизировать время.
Есть идея?