# QA 15: Proxyman — HTTPS trafikni ushlash, Map Local, Breakpoint, Scripting va Network Conditions

> **Holat:** 2026-yil oktabr. Dars macOS uchun **Proxyman 26.0.1** (2026-yil 27-sentabr) va unga biriktirilgan `proxyman-cli` asosida yozilgan. Proxyman 2026-yil sentabrda versiyalashni 6.x dan yil formatiga (26.x) o'tkazdi. Eski 6.x versiyalarda ba'zi imkoniyatlar (MCP, `proxyman-cli rules`) bo'lmasligi mumkin — ilovani yangilab oling.

> **Bu darsdan keyin siz:** mobil ilova yoki brauzer serverga aynan nima yuborayotganini o'z ko'zingiz bilan ko'rasiz va backend'ni kutmasdan chekka holatlarni o'zingiz yaratasiz.

- iPhone, iOS Simulator, Android va brauzer trafigini Proxyman orqali "ochish";
- Map Local, Map Remote, Breakpoint va Scripting bilan javob va so'rovlarni boshqarish;
- sekin tarmoq, ishlamay qolgan servis, takroriy so'rov kabi ssenariylarni daqiqalar ichida tayyorlash;
- `proxyman-cli` bilan qoidalarni terminaldan boshqarish va jamoaga ulashish;
- bug report'ga trafik dalilini maxfiy ma'lumotlarsiz biriktirish.

## Mundarija

1. [Debugging proxy nima va QA'ga nega kerak?](#nima-uchun)
2. [Proxyman bilan tanishuv: platformalar, versiya va litsenziya](#tanishuv)
3. [HTTPS qanday "ochiladi": SSL Proxying va root sertifikat](#ssl-proxying)
4. [O'rnatish: macOS, iOS Simulator, iPhone va Android](#ornatish)
5. [Interfeys: trafikni o'qish, filtrlash va belgilash](#interfeys)
6. [Map Local — server javobini soxtalashtirish](#map-local)
7. [Map Remote — so'rovni boshqa serverga yo'naltirish](#map-remote)
8. [Breakpoint — so'rov va javobni "jonli" tahrirlash](#breakpoint)
9. [Scripting — JavaScript bilan avtomatik qoidalar](#scripting)
10. [Network Conditions, Block List, Allow List va No Caching](#tarmoq-vositalari)
11. [Compose, Repeat, Edit & Repeat va Diff](#compose-repeat-diff)
12. [proxyman-cli: qoidalarni terminaldan boshqarish](#cli)
13. [Proxyman MCP va Atlantis](#mcp-atlantis)
14. [Muammolarni hal qilish (troubleshooting)](#troubleshooting)
15. [Bug report uchun dalil: eksport va maxfiy ma'lumotni yashirish](#dalil)
16. [Amaliy mashqlar](#mashqlar)
17. [O'zingizni tekshiring](#checklist)
18. [Xulosa](#xulosa)
19. [Manbalar](#manbalar)

---

## 1. Debugging proxy nima va QA'ga nega kerak? {#nima-uchun}

Web ilovani testlayotganda Chrome DevTools'ning **Network** tabi har bir so'rovni ko'rsatadi ([QA 9](/ios-lessons/qa-web-http-devtools)). Mobil ilovada esa bunday oyna yo'q. iPhone'dagi DemoBozor ilovasi serverga nima yuborayotganini bilish uchun trafikni o'rtada turib "eshitadigan" vosita kerak. Bu vosita — **debugging proxy**.

**Proxy** — mijoz (ilova) va server orasidagi vositachi. Ilova so'rovni to'g'ridan-to'g'ri serverga emas, proxy'ga yuboradi; proxy uni serverga uzatadi, javobni esa qaytarib beradi. Debugging proxy bu yo'lda har bir so'rovni **ko'rsatadi**, kerak bo'lsa **o'zgartiradi** yoki **o'zi javob beradi**.

Bu usulning texnik nomi — **MITM (man-in-the-middle)**. Hujumchilar ham shu texnikadan foydalanadi, lekin QA uni faqat o'z test qurilmasi va o'z jamoasining ilovasi ustida, ruxsat bilan qo'llaydi.

> **🧠 Esda tuting:** Pochta bo'limini tasavvur qiling. Har bir xat (so'rov) siz ishongan bo'lim xodimidan o'tadi. Xodim xatni ochib o'qiydi, kerak bo'lsa ichidagini almashtiradi va qayta muhrlab jo'natadi. Muhr haqiqiy ko'rinishi uchun siz oldindan bu xodimga ishonch bildirgansiz — bu **root sertifikatni o'rnatish** degani.

### QA debugging proxy bilan nima qiladi?

| QA vazifasi                                                                                | Proxyman'dagi yechim                                                      |
| ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------- |
| Ilova serverga to'g'ri ma'lumot yuboryaptimi? (`quantity`, `promoCode`, `Accept-Language`) | Flow ro'yxati va Request paneli                                           |
| Xato frontend'dami yoki backend'da?                                                        | So'rov va javobni yonma-yon ko'rish ([QA 8](/ios-lessons/qa-bug-reports)) |
| Backend hali tayyor emas yoki chekka holatni yaratish qiyin                                | Map Local, Scripting (Mock API)                                           |
| Sekin yoki uzilib qoladigan internet                                                       | Network Conditions                                                        |
| Server validatsiyasini sinash (narx, miqdor, boshqa `userId`)                              | Breakpoint, Edit & Repeat                                                 |
| Analitika eventlari to'g'ri ketyaptimi?                                                    | Filtr va JSON previewer                                                   |
| Takroriy so'rovda dublikat buyurtma paydo bo'ladimi?                                       | Repeat                                                                    |
| Bug uchun dalil kerak                                                                      | Export (HAR, Proxyman log), Copy cURL                                     |

Oddiy misol. DemoBozor'da xaridor savatchaga 3 ta "Paxta ko'ylak" qo'shdi, lekin buyurtmada 1 ta chiqdi. Proxyman'da `POST /api/v1/cart/items` so'rovini ochasiz:

- so'rovda `"quantity": 1` ketgan bo'lsa — xato **ilovada** (mobil dasturchiga);
- so'rovda `"quantity": 3` ketgan, javobda esa `1` qaytgan bo'lsa — xato **serverda** (backend dasturchiga).

Bitta qarash bilan bug to'g'ri odamga boradi va "menda ishlayapti" bahsi tugaydi.

> **🎯 Intervyuda:** "Mobil ilovaning API so'rovlarini qanday tekshirasiz?" — Proxyman yoki Charles kabi debugging proxy orqali: qurilmaga root sertifikat o'rnataman va unga ishonch beraman, domen uchun SSL Proxying'ni yoqaman, so'rov va javobni ko'raman. Kerak bo'lsa Map Local yoki Breakpoint bilan chekka holat yarataman. Ilovada SSL pinning bo'lsa, pinning'siz debug build so'rayman.

---

## 2. Proxyman bilan tanishuv: platformalar, versiya va litsenziya {#tanishuv}

**Proxyman** — HTTP/HTTPS trafikni ko'rish va boshqarish uchun debugging proxy. U macOS'da Mac'ning o'zi, iOS Simulator, iPhone/iPad va Android qurilmalar trafigini ushlaydi.

| Platforma      | Xususiyati                                                                                 |
| -------------- | ------------------------------------------------------------------------------------------ |
| macOS          | Asosiy ilova. Swift va SwiftNIO'da yozilgan native ilova; minimal talab — macOS 14         |
| Windows, Linux | ElectronJS asosidagi versiyalar                                                            |
| iOS ilova      | Mac'siz ishlaydigan alohida ilova: qurilmada lokal VPN yaratib trafikni ushlaydi (iOS 15+) |
| Android ilova  | Telefon ichida mustaqil trafik ushlash                                                     |

O'rnatish: rasmiy saytdan yuklab oling yoki Homebrew orqali:

```bash
brew install --cask proxyman
```

### 2026-yildagi muhim versiyalar

| Versiya | Sana                | QA uchun nima berdi                                                                       |
| ------- | ------------------- | ----------------------------------------------------------------------------------------- |
| 6.4.0   | 2026-yil 19-yanvar  | Proxyman MCP (AI yordamchilar bilan ishlash), Team Workspace                              |
| 6.9.0   | 2026-yil 23-aprel   | O'z Network Conditions profillaringizni saqlash, WebSocket Compose                        |
| 6.12.0  | 2026-yil 28-iyun    | Breakpoint'da Raw tab, External Proxy CLI                                                 |
| 6.14.0  | 2026-yil 23-iyul    | HTTP `QUERY` metodi; hujjatga ko'ra CLI orqali qoidalarni yaratish/o'zgartirish (`rules`) |
| 26.0.0  | 2026-yil 21-sentabr | HTTP/2 trafikni barcha vositalar bilan ushlash, Split View (Pro), Connection Log tab      |
| 26.0.1  | 2026-yil 27-sentabr | HTTP/2 bilan bog'liq crash'lar tuzatildi                                                  |

### Litsenziya: bepul va Pro

Rasmiy hujjat bo'yicha **Trial (bepul)** versiyada barcha debugging vositalari bor, lekin cheklov bilan: 2 ta pinned domen, har bir vosita uchun 2 ta qoida va yangi tab ochib bo'lmaydi. Shaxsiy maqsadda trial muddatsiz, biznes maqsadida esa 2 hafta.

**Pro** litsenziya cheklovlarni olib tashlaydi: cheksiz qoidalar, Tab View, Split View, iOS ilovaning Premium versiyasi (bir litsenziya o'rni — 2 ta iOS qurilma), 1 ta Mac va bir yillik yangilanishlar. Narxlar o'zgarib turadi, shuning uchun ularni rasmiy Pricing sahifasidan tekshiring.

> **💡 Maslahat:** O'rganish uchun bepul versiya yetadi — 2 ta Map Local qoidasi bilan ham bu darsning barcha mashqlarini bajarsa bo'ladi. Ishda foydalansangiz, litsenziyani rahbaringiz bilan hal qiling.

### Proxyman va muqobillari

| Vosita                 | Platformalar                                 | Litsenziya                           | Avtomatlashtirish              | Kimga qulay                                         |
| ---------------------- | -------------------------------------------- | ------------------------------------ | ------------------------------ | --------------------------------------------------- |
| **Proxyman**           | macOS (native), Windows, Linux, iOS, Android | Bepul trial + Pro                    | JavaScript skriptlar, CLI, MCP | macOS'da iOS/Android QA                             |
| **Charles Proxy**      | Windows, macOS, Linux                        | Pullik, 30 kunlik trial              | Rewrite qoidalari (GUI)        | Ko'p yillardan beri Charles bilan ishlagan jamoalar |
| **mitmproxy**          | Windows, macOS, Linux (CLI, mitmweb)         | Bepul, open source (MIT)             | Python addon'lar               | CI, server muhiti, chuqur avtomatlashtirish         |
| **HTTP Toolkit**       | Windows, macOS, Linux                        | Open source; ayrim imkoniyatlari Pro | Qoidalar (Modify — Pro)        | Android, Docker, Node trafigi                       |
| **Fiddler Everywhere** | Windows, macOS, Linux                        | Pullik obuna, 10 kunlik trial        | Rules (GUI)                    | Windows'da ishlovchi jamoalar                       |

Asosiy g'oyalar hammasida bir xil: sertifikat, SSL proxying, mock, breakpoint, throttling. Bitta vositani chuqur o'rgansangiz, boshqasiga o'tish bir kunlik ish.

---

## 3. HTTPS qanday "ochiladi": SSL Proxying va root sertifikat {#ssl-proxying}

HTTPS'da ilova va server o'rtasidagi trafik **TLS** bilan shifrlanadi. Ilova serverga ulanganda server o'z sertifikatini ko'rsatadi. Ilova esa bu sertifikatni qurilmadagi ishonchli **CA (Certificate Authority)** ro'yxati bo'yicha tekshiradi. Shu sabab oddiy proxy HTTPS ichini ko'ra olmaydi.

Proxyman buni quyidagicha hal qiladi:

1. Mac'ingizda **"Proxyman CA"** nomli root sertifikat yaratadi. U lokal saqlanadi: `~/Library/Application Support/com.proxyman.NSProxy/app-data/proxyman-ca.pem`.
2. Siz bu sertifikatni qurilmaga o'rnatasiz va unga **ishonch berasiz**.
3. Ilova `api.demobozor.example` ga ulanmoqchi bo'lganda, Proxyman shu host uchun sertifikatni "yo'l-yo'lakay" yasaydi va uni Proxyman CA bilan imzolaydi. Qurilma bu CA'ga ishongani uchun ulanish muvaffaqiyatli bo'ladi — bu **TLS #1**.
4. Proxyman haqiqiy server bilan alohida ulanish ochadi va serverning asl sertifikatini tekshiradi — bu **TLS #2**.
5. Ikki shifrlangan kanal orasida Proxyman ochiq matnni ko'radi.

![Proxyman MITM sxemasi: mijozlar, Proxyman CA, SSL Proxying va server orasidagi ikki TLS ulanish](/lessons/images/qa/qa_15_proxyman_mitm.svg)

### SSL Proxying List

Proxyman hamma domenni avtomatik ochmaydi. Qaysi domen yoki ilovaning trafigini ochishni **SSL Proxying List** belgilaydi:

- **Include List** — ro'yxatdagi ilova yoki domenlar ochiladi;
- **Exclude List** — bu ro'yxatdagilar e'tiborsiz qoldiriladi.

Qoidani bir necha xil yozish mumkin:

| Format         | Misol              | Ma'nosi                                    |
| -------------- | ------------------ | ------------------------------------------ |
| Ilova bo'yicha | DemoBozor (iOS)    | Shu ilovaning barcha trafigi               |
| Domen bo'yicha | `api.demobozor.example` | Faqat shu domen                            |
| Wildcard       | `*.demobozor.example`   | `api.`, `cdn.`, `staging-api.` va hokazo   |
| Hammasi        | `*`                | Barcha HTTPS trafik (shovqin ko'p bo'ladi) |

Eng tez yo'l: chap paneldagi domen ustida o'ng tugma → **Enable SSL Proxying**. SSL Proxying List oynasini **⌘⌥P** bilan ochasiz.

> **💡 Maslahat:** `*` qoidasidan qoching. Faqat o'zingiz testlayotgan domenlarni qo'shing — oyna toza bo'ladi va boshqa ilovalaringizning maxfiy trafigi ochilmaydi.

### Xavfsizlik qoidalari

> **⚠️ Diqqat:** Root sertifikat — "barcha eshiklarga mos kalit". Uni faqat o'zingizning test qurilmangizga o'rnating va ish tugagach o'chiring. Mac'da: **Certificate → Reset all Certificates**. iPhone'da: **Settings → General → VPN & Device Management** bo'limidan profilni o'chiring. Birovning telefoniga sertifikat o'rnatish yoki birovning trafigini ruxsatsiz ushlash — qonunbuzarlik.

### SSL pinning: nega ba'zi ilovalar ochilmaydi?

**SSL (certificate) pinning** — ilova faqat oldindan "yodlab olgan" sertifikat yoki kalitga ishonadi. Bunday ilova Proxyman yasagan sertifikatni rad etadi va siz `SSL Handshake Failed` xatosini ko'rasiz. Bank ilovalari va yirik ijtimoiy tarmoqlar shunday himoyalangan — bu **himoya, bug emas**.

QA uchun to'g'ri yo'l:

- dasturchilardan pinning o'chirilgan **debug/staging build** so'rang (masalan, build konfiguratsiyasidagi bayroq bilan);
- iOS'da faqat kuzatish kerak bo'lsa — [Atlantis](#mcp-atlantis) freymvorki;
- **hech qachon** release build'da pinning'ni o'chirishni so'ramang.

### Android 7+ va foydalanuvchi sertifikatlari

Android 7.0 (API 24) va undan yangi versiyalarni target qilgan ilovalar sukut bo'yicha faqat **tizim** sertifikatlariga ishonadi. Siz qo'lda o'rnatgan Proxyman CA esa **foydalanuvchi (user)** sertifikati hisoblanadi. Shuning uchun Android'da ilovaning debug build'iga `network_security_config.xml` qo'shish kerak bo'ladi — buni keyingi bo'limda ko'ramiz.

---

## 4. O'rnatish: macOS, iOS Simulator, iPhone va Android {#ornatish}

### 4.1 macOS (birinchi qadam — har doim)

1. **Certificate** menyusi → **Install Certificate on this Mac…**
2. **Automatic** rejim → Mac parolini kiriting.
3. Holat **"Installed & Trusted"** bo'lishi kerak.

Avtomatik rejim ishlamasa, **Manual** tabida **Generate & Add** tugmasini bosing. Keyin **Keychain Access** ilovasida "Proxyman CA" ni topib, **Always Trust** qilasiz.

Proxyman ishga tushganda Mac'ning tizim HTTP proksisini o'ziga yo'naltiradi. Shu sabab Safari va Chrome trafigi darhol ko'rinadi. Tizim proksisini terminaldan ham yoqib-o'chirsa bo'ladi: `proxyman-cli proxy on|off` ([12-bo'lim](#cli)).

### 4.2 iOS Simulator

1. Avval kerakli simulatorni **kamida bir marta ishga tushiring**.
2. **Certificate → Install Certificate on iOS → Simulators**.
3. Oynadagi uch qadamni bajaring: Mac'ga root sertifikat, barcha ochilgan simulatorlarga sertifikat, keyin simulatorlarni qayta ishga tushirish.

Proxyman bu ishni Xcode'dagi `simctl` orqali bajaradi. Xohlasangiz, sertifikatni o'zingiz ham qo'sha olasiz:

```bash
# Simulator ishlab turgan bo'lsin; Proxyman CA Mac'da shu yerda saqlanadi
xcrun simctl keychain booted add-root-cert \
  "$HOME/Library/Application Support/com.proxyman.NSProxy/app-data/proxyman-ca.pem"
```

Simulator Mac tarmog'idan foydalanadi, shuning uchun alohida proksi sozlash shart emas. Avtomatik usul ishlamasa: **Certificate → Export → Root Certificate as DER**, faylni simulator ekraniga sudrab tashlang, so'ng **Settings → General → About → Certificate Trust Settings** ichida Proxyman CA'ni yoqing.

### 4.3 iPhone yoki iPad (real qurilma)

1. Mac va iPhone **bitta Wi-Fi tarmog'ida** bo'lsin; VPN'larni o'chiring.
2. Mac IP manzili va portni bilib oling: **Certificate → Install Certificate on iOS → Physical Devices…** oynasi ko'rsatadi. Terminalda ham bo'ladi:

```bash
/Applications/Proxyman.app/Contents/MacOS/proxyman-cli proxy-host
# {"port":9090,"ip":"192.168.1.25"}   <- IP sizda boshqacha bo'ladi
```

3. iPhone: **Settings → Wi-Fi → (i) → Configure Proxy → Manual**. Server — Mac IP manzili, Port — `9090`, Authentication — o'chiq.
4. iPhone'dagi Safari'da (yaxshisi Private tab) `http://proxy.man/ssl` yoki `http://cert.proxyman.io` sahifasini oching va profilni yuklab oling.
5. **Settings → Profile Downloaded → Proxyman CA → Install**.
6. **Settings → General → About → Certificate Trust Settings → Proxyman CA** ni yoqing. Bu qadam majburiy: o'rnatish hali to'liq ishonch degani emas.

Test tugagach: proksini **Off** qiling va profilni o'chiring.

> **⚠️ Diqqat:** iOS 16/17 ba'zan qo'lda kiritilgan proksi sozlamasini saqlamaydi. Hujjatdagi yechim: **Forget This Network** → qayta ulaning → proksini qaytadan kiriting va **Manual** turganini tekshiring.

### 4.4 Android emulator

Eng oson yo'l — avtomatik skript: **Certificate → Install Certificate on Android → Emulators → Override All Emulators**.

- Mac'da `adb` bo'lishi kerak (`brew install android-platform-tools`).
- Emulator image **"Google APIs"** bo'lsin. "Google Play" image'lari uchun Proxyman hujjatida alohida Magisk yo'riqnomasi bor.
- Proxyman sertifikatni emulatorning **tizim** darajasiga o'rnatadi, shuning uchun `network_security_config.xml` shart emas.
- Ish tugagach **Revert All Changes** ni bosing. Aks holda Proxyman yopilgach emulator internetsiz qoladi.

### 4.5 Android real qurilma

1. Wi-Fi sozlamalarida proksi: Mac IP manzili va `9090`.
2. Chrome'da `http://proxy.man/ssl` ochib sertifikatni yuklab oling.
3. Android 11+ da qo'lda o'rnatasiz: **Settings → Security → Encryption & credentials → Install a certificate → CA certificate**. Menyu nomlari ishlab chiqaruvchiga qarab biroz farq qiladi.
4. Tekshirish: **Trusted credentials → User** tabida Proxyman CA ko'rinishi kerak.
5. Ilovaning **debug** build'iga quyidagi konfiguratsiya qo'shiladi:

```text
<!-- res/xml/network_security_config.xml -->
<network-security-config>
  <debug-overrides>
    <trust-anchors>
      <!-- Foydalanuvchi o'rnatgan CA'larga faqat debuggable build'da ishonamiz -->
      <certificates src="user" />
      <certificates src="system" />
    </trust-anchors>
  </debug-overrides>
</network-security-config>

<!-- AndroidManifest.xml -->
<application android:networkSecurityConfig="@xml/network_security_config" ... >
```

`debug-overrides` bo'limi faqat `android:debuggable="true"` bo'lganda ishlaydi. Release build'da Android uni butunlay e'tiborsiz qoldiradi.

> **⚠️ Diqqat:** Proxyman hujjatidagi to'liq namunada `base-config` bo'limida ham `<certificates src="user" />` bor — bu **barcha** build'larda foydalanuvchi sertifikatlariga ishonish degani. Hujjat ham ogohlantiradi: bunday sozlama release build'ga tushmasligi kerak. QA sifatida release build'ni tekshirganda bu xatoni qidirish — yaxshi xavfsizlik testi ([QA 24](/ios-lessons/qa-security)).

### 4.6 Brauzer, Node.js va boshqa skriptlar

- **localhost** trafigi (masalan, `http://localhost:3000`) sukut bo'yicha tizim proksisidan o'tmaydi. **Setup → Automatic Setup → Google Chrome** tugmasi maxsus Chrome oynasini ochadi va u localhost'ni ham ko'rsatadi.
- Node, Python, Ruby, cURL kabi terminal vositalari tizim proksisini hurmat qilmaydi. **Setup → Automatic Setup → Open New Terminal** maxsus terminal ochadi va unda ishga tushgan skriptlar avtomatik ushlanadi. Bu Playwright API testlaringiz trafigini ko'rish uchun ham qulay ([QA 20](/ios-lessons/qa-api-automation)).
- **Flutter** ilovalar tizim proksisini ishlatmaydi. Hujjatga ko'ra Proxyman 6.4.0+ Android emulatorda Flutter va React Native trafigini o'zining VPN ilovasi orqali kod o'zgartirmasdan ushlay oladi. Real qurilmada esa HTTP klientga proksini koddan berish kerak bo'lishi mumkin.

---

## 5. Interfeys: trafikni o'qish, filtrlash va belgilash {#interfeys}

Proxyman oynasi uch qismdan iborat:

| Panel                   | Nima bor                                                                |
| ----------------------- | ----------------------------------------------------------------------- |
| **Chap (Source List)**  | Ilovalar, domenlar, qurilmalar; tez-tez kerakli domenni **Pin** qilasiz |
| **O'rta (Flow List)**   | So'rovlar ro'yxati: metod, URL, status, hajm, vaqt                      |
| **O'ng (Flow Content)** | Tanlangan so'rov va javob tafsilotlari                                  |

Request va Response panellarida bir nechta tab bor: **Header**, **Query**, **Body**, **Cookies**, **Set-Cookie**, **Auth**, **Raw**. Body JSON bo'lsa — chiroyli formatlangan ko'rinish va **Tree View** (daraxt ko'rinishi). Katta JSON ichidan qidirish uchun **JSONPath** va **jq** filtrlari bor. 26.0.0 dan boshlab **Connection Log** tabi DNS, TLS va ulanish tafsilotlarini ko'rsatadi.

### Birinchi mashq: haqiqiy trafikni ko'rish

1. Proxyman'ni oching (macOS sertifikati o'rnatilgan bo'lsin).
2. **Setup → Automatic Setup → Open New Terminal** orqali ochilgan terminalda:

```bash
curl -s https://restful-booker.herokuapp.com/ping
curl -s "https://restful-booker.herokuapp.com/booking?firstname=Aziz"
```

3. Chap panelda `restful-booker.herokuapp.com` paydo bo'ladi → o'ng tugma → **Enable SSL Proxying** → buyruqlarni qayta ishga tushiring.
4. `GET /ping` ni tanlang: status **201** ekanini ko'rasiz. Sog'liqni tekshirish (health check) uchun bu g'alati, chunki `201 Created` yangi resurs yaratilganini bildiradi. Bu — amaliyot API'sidagi tanilgan "quirk" ([QA 10](/ios-lessons/qa-api-postman)).

### Filtrlash

- **⌘F** — filtr paneli. Asosiy filtrlar: All, HTTP, HTTPS, WebSocket, JSON, XML, Form, JS, CSS, Document, Media, Font, GraphQL.
- Status filtrlari: **1xx–5xx**. Masalan, faqat 5xx ni ko'rib, server xatolarini tez topasiz.
- Ikkilamchi filtr: URL, Query, Request/Response Header, Method, Status Code, Comment, Color; shartlar — Contains, Not Contains, Start With, End With, Equal, Regex.

### Belgilash va izoh

O'ng tugma → **Highlight** → rang (qizil, sariq, yashil, ko'k, binafsha, kulrang) va izoh. QA uchun foydali odat: muammoli so'rovni qizil qilib, izohga bug raqamini yozing (`DB-1043`). Rang va izoh Proxyman Log formatida eksport qilinadi.

### Nusxa olish

O'ng tugma → **Copy cURL**: so'rov header, cookie va body bilan birga cURL buyrug'iga aylanadi. Uni bug report'ga qo'yasiz yoki Postman/Bruno'ga import qilasiz. Shuningdek **Copy URL**, **Copy as** (Markdown jadval, CSV, Raw) bor.

> **💡 Maslahat:** Har bir test sessiyasidan oldin **Clear Session** qiling (yoki `proxyman-cli clear-session`). Ro'yxat qisqa bo'lsa, kerakli so'rovni bir zumda topasiz.

---

## 6. Map Local — server javobini soxtalashtirish {#map-local}

**Map Local** — mos keladigan so'rov uchun javobni serverdan emas, **lokal fayldan** qaytaradi. Server umuman o'zgarmaydi, lekin ilova "server shunday javob berdi" deb hisoblaydi.

QA uchun bu chekka holatlar fabrikasi. DemoBozor misolida:

| Mock                             | Ilovada nimani tekshiramiz                              |
| -------------------------------- | ------------------------------------------------------- |
| `GET /api/v1/cart` → `items: []` | Bo'sh savatcha ekrani, "Buyurtma berish" tugmasi o'chiq |
| Bitta mahsulot, `quantity: 99`   | Maksimal miqdor, "+" tugmasi o'chadi                    |
| 50 xil mahsulot                  | Uzun ro'yxat, scroll, jami summa                        |
| `imageUrl: null`                 | Placeholder rasm, crash yo'q                            |
| 200 belgili mahsulot nomi        | Matn kesilishi, layout buzilmasligi                     |
| Status `500`                     | Xato ekrani, "Qayta urinish" tugmasi                    |
| Status `401`                     | Token yangilash yoki login ekraniga qaytish             |
| Status `503` + `Retry-After`     | Texnik ishlar xabari                                    |

### Qanday yaratiladi

1. So'rov **javob bilan birga** ro'yxatda bo'lsin (SSL Proxying yoqilgan).
2. O'ng tugma → **Tools → Map Local**. Proxyman joriy javobdan nusxa olib qoida yaratadi.
3. Status, header va body'ni tahrirlang → saqlang.
4. Ilovada amalni takrorlang — endi javob sizning faylingizdan keladi.

Javob uchun alohida fayl tanlash mumkin (**Select Local File**: matn, JSON, binar, rasm). Status va header'larni ham berish kerak bo'lsa, `<FILE_URL>` belgisi qulay:

```http
HTTP/1.1 503 Service Unavailable
Content-Type: application/json
Retry-After: 120

<FILE_URL="~/qa-mocks/demobozor/maintenance.json">
```

Bo'sh savatcha uchun fayl (DemoBozor API'si xayoliy):

```json
{
  "id": "cart-7781",
  "items": [],
  "itemsTotal": 0,
  "deliveryFee": 0,
  "total": 0,
  "currency": "UZS"
}
```

Chekka holatlar to'plami uchun fayl:

```json
{
  "id": "cart-7782",
  "items": [
    {
      "productId": 42,
      "name": "Gilam (2x3 m) — qo'lda to'qilgan, tabiiy jun, klassik naqshli, Samarqand uslubidagi juda uzun nom bilan",
      "price": 2450000,
      "quantity": 99,
      "imageUrl": null
    },
    {
      "productId": 7,
      "name": "Choynak 🫖",
      "price": 0,
      "quantity": 1,
      "imageUrl": "https://cdn.demobozor.example/img/7.jpg"
    }
  ],
  "itemsTotal": 242550000,
  "deliveryFee": 0,
  "total": 242550000,
  "currency": "UZS"
}
```

Bu bitta fayl bilan uzun nom, 99 dona, `null` rasm, `0` narx, emoji va katta summani bir vaqtda tekshirasiz.

### Haqiqiy saytda sinab ko'ring

Toolshop amaliyot do'koni ([practicesoftwaretesting.com](https://practicesoftwaretesting.com)) mahsulotlarni `https://api.practicesoftwaretesting.com/products` dan oladi. Qiziq tomoni — u buning uchun yangi **`QUERY`** HTTP metodidan foydalanadi (body'li xavfsiz qidiruv so'rovi; Proxyman uni 6.14.0 dan qo'llab-quvvatlaydi). Shu so'rovga Map Local qo'ying (Method: **Any**) va body'ni quyidagicha almashtiring:

```json
{
  "current_page": 1,
  "data": [],
  "from": null,
  "last_page": 1,
  "per_page": 9,
  "to": null,
  "total": 0
}
```

Sahifani yangilasangiz, "There are no products found." degan bo'sh holat ko'rinadi. Biz bu natijani Playwright'da ham xuddi shunday mock bilan tekshirib ko'rdik.

### Map Local (Directory)

Bir nechta fayl yoki statik resurslar uchun **Map Local (Directory)**: masalan, `cdn.demobozor.example/img/*` so'rovlarini lokal papkadan berish. Lokal faylda mos fayl topilmasa, so'rov haqiqiy serverga ketadi.

> **⚠️ Diqqat:** Yoqilgan Map Local qoidasini unutish — yolg'on bug'larning eng ko'p sababi. "Savatcha bo'sh ko'rinyapti" degan bug ochishdan oldin qoidalar ro'yxatini tekshiring. Ish tugagach tool'ni o'chiring: `proxyman-cli maplocal off`.

---

## 7. Map Remote — so'rovni boshqa serverga yo'naltirish {#map-remote}

**Map Remote** (**⌘⌥R**) so'rovni boshqa manzilga yo'naltiradi va javob ilovaga shaffof qaytadi. Ilova hech narsani sezmaydi.

QA ssenariylari:

| Vazifa                                               | Qoida                                                          |
| ---------------------------------------------------- | -------------------------------------------------------------- |
| Do'kondagi prod ilovani staging API bilan sinash     | `https://api.demobozor.example/*` → host `staging-api.demobozor.example` |
| Yangi `v2` endpoint'ni eski ilova bilan sinash       | path'da `v1` → `v2`                                            |
| Backend dasturchining lokal serveri bilan tekshirish | `https://api.demobozor.example` → `http://localhost:8080`           |
| Faqat bitta endpoint'ni almashtirish                 | **Include all subpaths** belgisini olib tashlang               |

Qoida maydonlari: **Protocol, Host, Port, Path, Query**. Bo'sh qoldirilgan maydon o'zgarmaydi. Sukut bo'yicha Proxyman `Host` header'ini yangi host'ga moslaydi. Asl header kerak bo'lsa — **Preserve Host Header**. Qoida qaysi so'rovga ishlaganini **Summary → Debugging Tools → Map URL** dan ko'rasiz.

Eng tez yo'l: kerakli so'rov ustida o'ng tugma → **Tools → Map Remote**. Proxyman maydonlarni o'zi to'ldiradi.

> **⚠️ Diqqat:** Prod va staging token'lari boshqa-boshqa. Map Remote'da prod token'i staging'ga ketishi mumkin. Prod hisobingiz bilan staging'ga yoki begona hostga hech qachon map qilmang — test hisobi ishlating.

---

## 8. Breakpoint — so'rov va javobni "jonli" tahrirlash {#breakpoint}

**Breakpoint** so'rovni serverga yetmasdan, javobni esa ilovaga yetmasdan **to'xtatadi**. Siz uni tahrirlab, keyin davom ettirasiz. Tahrirlash mumkin bo'lgan narsalar: URL (scheme, host, path, port), HTTP metod, header'lar, query va form, `Authorization`/`Cookie`/`Set-Cookie`, body va javob status kodi. 6.12.0 dan **Raw** tabida butun HTTP xabarini bir joyda tahrirlaysiz.

Breakpoint oynasidagi tugmalar:

| Tugma       | Ma'nosi                                                   |
| ----------- | --------------------------------------------------------- |
| **Execute** | O'zgartirilgan so'rov/javobni yuborish                    |
| **Cancel**  | Breakpoint'ni bekor qilib, o'zgartirmasdan davom ettirish |
| **Abort**   | Ulanishni uzish va 503 qaytarish                          |

Yaratish: so'rov ustida o'ng tugma → **Tools → Breakpoint** → Request, Response yoki ikkalasini tanlang → **Add**.

### Server validatsiyasini sinash (DemoBozor, test muhiti)

Mobil ilova "miqdor 1–99" qoidasini o'zi tekshiradi va foydalanuvchiga `-1` yozdirmaydi. Lekin server ham tekshiryaptimi? Faqat ilovaga ishonish — xavfli bug: hujumchi so'rovni ilovasiz, to'g'ridan-to'g'ri yuborishi mumkin.

| Qadam                     | Breakpoint'da o'zgartirish                    | Kutilgan natija                                                                    |
| ------------------------- | --------------------------------------------- | ---------------------------------------------------------------------------------- |
| `POST /api/v1/cart/items` | `"quantity": 2` → `-1`                        | `400`/`422`, tushunarli xato matni                                                 |
| Xuddi shu                 | `"quantity": 2` → `100`                       | `400`/`422` (chegara 99)                                                           |
| `POST /api/v1/orders`     | `"promoCode": "YANGI15"` → `"yangi15"`        | Qoidaga ko'ra rad etish yoki normallashtirish                                      |
| `POST /api/v1/orders`     | body'ga `"total": 1000` qo'shish              | Server summani **o'zi hisoblaydi**, mijoz yuborgan `total`'ni e'tiborsiz qoldiradi |
| `GET /api/v1/orders/1043` | `1043` → boshqa xaridorning `1044` buyurtmasi | `403` yoki `404` — begona buyurtma ko'rinmaydi ([QA 24](/ios-lessons/qa-security)) |
| Javob                     | status `200` → `500`                          | Ilova xato ekranini ko'rsatadi, crash bo'lmaydi                                    |
| Javob                     | 60 soniya ushlab turish                       | Ilova timeout'ni to'g'ri ko'rsatadi, tugma qayta bosilmaydi                        |

Agar server `quantity: -1` ni qabul qilsa — bu **Critical** darajadagi bug: manfiy summa, ombor hisobining buzilishi va pul yo'qotish xavfi.

### Haqiqiy API'da sinab ko'ring

Restful-booker — ataylab "zaif" qilib yaratilgan amaliyot API'si. Proxyman'da `POST https://restful-booker.herokuapp.com/booking` ga breakpoint qo'yib, `totalprice` ni `-100` ga, `checkout` sanasini esa `checkin` dan oldingi kunga o'zgartiring. Biz 2026-yil oktabrda tekshirdik: server ikkalasini ham qabul qilib, `200` qaytaradi. Majburiy maydonlarni olib tashlasangiz esa `400` o'rniga `500` keladi. Ikkalasi ham bug report uchun tayyor topilma.

> **⚠️ Diqqat:** Tampering (so'rovni qasddan buzish) faqat **o'z test muhitingiz** va **o'z test hisoblaringiz** bilan qilinadi. Prod tizimda yoki birovning hisobida bunday tajriba — xavfsizlik qoidasini va qonunni buzish.

### HTTP Message Templates

Bir xil o'zgarishni tez-tez qilsangiz (masalan, "status 500 + standart xato JSON"), shablon saqlang: **Tools → Breakpoint → Breakpoint Template**, yangi shablon uchun ⌘N. Breakpoint ishlaganda **Raw → Template** orqali bir bosishda qo'llaysiz.

---

## 9. Scripting — JavaScript bilan avtomatik qoidalar {#scripting}

Breakpoint qo'lda ishlaydi: har safar oyna ochiladi. Ssenariy **takrorlanuvchi** bo'lsa (har 3-so'rovda xato, har doim 8 soniya kechikish), uni **Scripting** bilan avtomatlashtirasiz. Yo'li: **Script → Script List** (⌥⌘I) yoki so'rov ustida o'ng tugma → **Tools → Scripting**.

Har bir skript **matching rule** (qaysi URL'lar) va ikki funksiyadan iborat:

```javascript
// So'rov serverga ketishidan oldin chaqiriladi
function onRequest(context, url, request) {
  // request: method, scheme, host, path, port, queries, headers, body, bodyFilePath
  return request; // request'ni qaytarish majburiy
}

// Javob ilovaga qaytishidan oldin chaqiriladi
function onResponse(context, url, request, response) {
  // response: statusCode, headers, body, bodyFilePath
  return response; // response'ni qaytarish majburiy
}
```

`body` turi `Content-Type`'ga bog'liq: JSON va form uchun — JS obyekt, matnli turlar uchun — string, binar uchun — `Uint8Array`. Skript oynasida **Run Script on Request/Response** belgilarini yoqishni unutmang.

### 1-misol: QA sessiyasini belgilash

```javascript
// So'rovga QA belgisini qo'shamiz va jadvalda ajratib ko'rsatamiz
function onRequest(context, url, request) {
  request.headers["X-QA-Session"] = "qa-15-demo";
  request.comment = "QA: test sessiyasi";
  request.color = "purple";
  return request;
}

function onResponse(context, url, request, response) {
  return response;
}
```

### 2-misol: javobni chekka holatga aylantirish

```javascript
// GET /api/v1/cart javobini chekka holatga aylantiramiz:
// birinchi mahsulot nomi juda uzun, soni esa maksimal (99)
function onResponse(context, url, request, response) {
  var body = response.body;
  if (body && Array.isArray(body.items) && body.items.length > 0) {
    body.items[0].name = "Paxta ko'ylak ".repeat(15).trim();
    body.items[0].quantity = 99;
  }
  response.body = body;
  response.comment = "Map: uzun nom + 99 dona";
  return response;
}
```

### 3-misol: "beqaror backend" — har 3-so'rovda 500

`sharedState` — skriptlar va so'rovlar orasida umumiy obyekt. U Proxyman yopilguncha yoki `clearSharedState()` chaqirilguncha yashaydi.

```javascript
// Har 3-chi GET /api/v1/products so'roviga 500 qaytaramiz:
// ilova xatoni chiroyli ko'rsatadimi va "Qayta urinish" ishlaydimi?
function onResponse(context, url, request, response) {
  var count = (sharedState.productsCount ?? 0) + 1;
  sharedState.productsCount = count;

  if (count % 3 === 0) {
    response.statusCode = 500;
    response.headers["Content-Type"] = "application/json";
    response.body = {
      error: "INTERNAL_ERROR",
      message: "Test: soxta server xatosi",
    };
    response.color = "red";
    response.comment = "Scripting: soxta 500 (#" + count + ")";
  }
  return response;
}
```

### 4-misol: to'lov javobini kechiktirish

```javascript
// To'lov javobini 8 soniya kechiktiramiz (macOS'da sleep sinxron ishlaydi)
function onResponse(context, url, request, response) {
  sleep(8000);
  response.comment = "Scripting: 8 s kechikish";
  return response;
}
```

Windows va Linux versiyalarida `sleep` asinxron: funksiyani `async` qilib, `await sleep(8000)` yozasiz.

### 5-misol: ulanishni uzish — dublikat buyurtma testi

```javascript
// POST /api/v1/orders so'rovlarining har ikkinchisini "uzib" yuboramiz:
// ilova qayta yuborganda ikkita buyurtma yaratilmasligi kerak
function onRequest(context, url, request) {
  if (request.method !== "POST") {
    return request;
  }
  var attempt = (sharedState.orderAttempt ?? 0) + 1;
  sharedState.orderAttempt = attempt;

  if (attempt % 2 === 0) {
    abort();
    return;
  }
  return request;
}
```

Bu testda ilovaning "Qayta urinish" mantiqi va backend'ning idempotentligi tekshiriladi. To'g'ri dizaynda bitta buyurtma uchun pul ikki marta yechilmaydi.

> **💡 Maslahat:** Yuqoridagi 5 ta skriptning mantig'ini biz Node.js'da Proxyman global'larini (`sharedState`, `sleep`, `abort`) soxtalashtirib tekshirdik: 3-misol ketma-ket `200, 200, 500, 200, 200, 500` qaytaradi. Murakkab skriptni ham avval shunday kichik "harness"da sinab olish — yaxshi odat.

### Foydali qo'shimchalar

- **Addon'lar:** `require("@addons/UUID.js")` (UUID yaratish), `require("@addons/JWTDecode.js")` (token ichini o'qish) va boshqalar.
- **Muhit o'zgaruvchilari:** ruxsat berilsa, `~/.zshrc` dagi o'zgaruvchilarni `$ACCESS_TOKEN` ko'rinishida o'qiysiz. Shunda token'ni skript ichida saqlamaysiz.
- **Run as Mock API:** so'rov serverga umuman bormaydi, javobni skript yasaydi — backend hali yo'q endpoint'lar uchun qulay.
- **Debug:** `console.log(...)` natijasi skript oynasidagi konsolda chiqadi.

---

## 10. Network Conditions, Block List, Allow List va No Caching {#tarmoq-vositalari}

### Network Conditions

Yo'li: **Tools → Network Conditions** yoki so'rov ustida o'ng tugma. Qoida butun tizimga yoki faqat tanlangan domenlarga qo'llanadi. Tayyor profillar:

| Profil               | Tavsif (rasmiy hujjat)                 |
| -------------------- | -------------------------------------- |
| 100% Lost connection | Ulanish butunlay yo'q                  |
| Very Bad Network     | Download/Upload < 1 Mbps               |
| Slow Network         | 5–10 Mbps                              |
| Medium Network       | 10–20 Mbps                             |
| 2G (EDGE)            | Download < 240 kbps, Upload < 200 kbps |
| 3G                   | Download < 780 kbps, Upload < 300 kbps |
| 4G (LTE)             | Download 30–50 Mbps, Upload 5–10 Mbps  |
| Wi-Fi                | Download 25–40 Mbps, Upload 15–30 Mbps |

Haqiqiy hayotga o'xshashi uchun tezlik berilgan oraliqda tasodifiy o'zgaradi. 6.9.0 dan o'z profillaringizni ham saqlay olasiz.

DemoBozor test g'oyalari:

- katalog **3G** da: skeleton/yuklanish holati bormi, rasmlar asta-sekin chiqadimi;
- to'lov paytida **100% Lost connection**: xato xabari tushunarlimi, pul ikki marta yechilmaydimi, qayta urinish mumkinmi;
- faqat `cdn.demobozor.example` sekin: matn darhol, rasmlar keyin chiqishi kerak.

Muqobil: Apple'ning **Network Link Conditioner** vositasi ([QA 14](/ios-lessons/qa-mobile-testing)).

### Block List

So'rovlarni bloklash yoki yashirish (**⌥⌘[**). Uch rejim bor:

| Rejim                | Natija                                          |
| -------------------- | ----------------------------------------------- |
| Block & Hide Request | Bloklanadi va ro'yxatda ko'rinmaydi             |
| Block & Display      | Bloklanadi, lekin ro'yxatda ko'rinadi           |
| Hide, but not Block  | Faqat yashiriladi (shovqinni kamaytirish uchun) |

QA'dagi asosiy foydasi — **graceful degradation** testi. Analitika domeni yoki rasm CDN'i bloklanganda ham ilova ishlashi, savatcha va buyurtma bo'limlari ochilishi kerak.

### Allow List

Faqat ro'yxatdagi domenlar Proxyman'dan o'tadi, qolganlari chetlab ketadi (**⌥⌘]**). Faqat `api.demobozor.example` ni testlayotganda oynani toza saqlaydi.

### No Caching

**⌥⌘N** — so'rovlardan `If-Modified-Since`/`If-None-Match` header'larini olib tashlaydi va `Cache-Control: no-cache` qo'shadi. "Yangi narx ko'rinmayapti" turidagi bug'da muammo keshdami yoki serverdami — shu bilan aniqlaysiz.

---

## 11. Compose, Repeat, Edit & Repeat va Diff {#compose-repeat-diff}

### Compose — Proxyman ichidagi mini-Postman

**Tools → Compose** (yoki toolbar'dagi Compose tugmasi): URL, metod, header, query va body bilan yangi so'rov yasaysiz. Tayyor shablonlar bor: GET with Query, Post with JSON, Post with Form, multipart. Eng qulayi — **Import from cURL**: Chrome'dan "Copy as cURL" qilingan buyruqni URL maydoniga qo'ysangiz, Proxyman uni o'zi tahlil qiladi. 5.24.0 dan so'rovlar **History** ro'yxatida saqlanadi, 6.9.0 dan WebSocket xabarlarini ham compose qilsa bo'ladi.

### Repeat — idempotentlik testi

So'rov ustida o'ng tugma → **Repeat** (yoki **⌘⏎**). Bir nechta so'rovni birdaniga ham takrorlash mumkin.

DemoBozor'dagi muhim test: `POST /api/v1/orders` ni ikki marta **Repeat** qiling.

- Server `Idempotency-Key` header'idan foydalansa — ikkinchi so'rov **o'sha** buyurtmani qaytarishi kerak.
- Yangi buyurtma yaratilsa va pul ikki marta yechilsa — **Critical** bug.

> **⚠️ Diqqat:** Takrorlangan so'rovlar ham Breakpoint, Map Local va Scripting qoidalaridan o'tadi. Kutilmagan natija bo'lsa, avval yoqilgan qoidalarni tekshiring.

### Edit & Repeat

O'ng tugma → **Edit & Repeat**: so'rovning query, header yoki body'sini o'zgartirib, darhol qayta yuborasiz va javobni o'ng panelda ko'rasiz. Tezkor tekshiruvlar:

- `Authorization` header'ini olib tashlash → `401` kutiladi;
- `Accept-Language: ru` → xato matnlari ruscha bo'lishi kerak;
- `page=-1`, `limit=100000` → `400` yoki xavfsiz chegara ([QA 11](/ios-lessons/qa-api-advanced)).

### Diff — nima o'zgardi?

So'rovni tanlab **⌘Y** (Add to Diff pool) bosing. Diff oynasida chap va o'ng tomonni tanlaysiz. Proxyman URL, metod, status, header va body farqini **Side-by-Side** yoki **Unified** ko'rinishda ko'rsatadi.

Qachon kerak:

- yangi reliz (v2.1) va eski (v2.0) ilova bir xil so'rovga turli javob olayotganda;
- staging va prod javoblarini solishtirishda;
- bug tuzatilgandan oldin va keyin.

---

## 12. proxyman-cli: qoidalarni terminaldan boshqarish {#cli}

Proxyman bilan birga `proxyman-cli` keladi. Quyidagi buyruqlar Proxyman 26.0.1 dagi `proxyman-cli --help` natijasidan olindi (CLI versiyasi 1.11.0):

```bash
CLI=/Applications/Proxyman.app/Contents/MacOS/proxyman-cli
$CLI --help
```

| Buyruq                                                                                               | Vazifasi                                                                  |
| ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| `proxy on`, `proxy off`                                                                              | macOS tizim proksisini yoqish/o'chirish                                   |
| `proxy-host`                                                                                         | Proksi IP va portini JSON'da chiqarish                                    |
| `clear-session`                                                                                      | Joriy sessiyani tozalash                                                  |
| `breakpoint`, `maplocal`, `network-condition`                                                        | `on`, `off` yoki `open` (oynani ochish)                                   |
| `scripting`, `map-remote`, `block-list`, `allow-list`, `no-caching`, `dns-spoofing`, `reverse-proxy` | Tegishli tool'ni yoqish/o'chirish                                         |
| `export -o <fayl>`, `import -i <fayl>`                                                               | Barcha qoidalarni JSON'ga eksport/import (`-m append` yoki `-m override`) |
| `export-log`                                                                                         | Trafikni faylga eksport: `proxymansession`, `har` yoki `raw` formatida    |
| `rules <tool> ...`                                                                                   | Qoidalarni yaratish, o'qish, yangilash, o'chirish (JSON)                  |
| `mcp on`, `mcp off`                                                                                  | MCP serverini yoqish/o'chirish (kompaniya siyosati uchun)                 |
| `install-root-cert`, `custom-cert`                                                                   | Maxsus sertifikatlar                                                      |
| `external-proxy`                                                                                     | Upstream (korporativ) proksi                                              |

### QA uchun foydali retseptlar

```bash
CLI=/Applications/Proxyman.app/Contents/MacOS/proxyman-cli

# 1) Jamoaning QA qoidalarini ulashish: eksport va boshqa Mac'da import
$CLI export -o ~/qa-mocks/demobozor-rules.json
$CLI import -i ~/qa-mocks/demobozor-rules.json -m append

# 2) Bug uchun faqat API domenining trafigini HAR qilib saqlash
$CLI export-log -m domains --domains 'api.demobozor.example' -f har -o ~/Desktop/DB-1043.har

# 3) Map Local qoidasini terminaldan yaratish (Proxyman ochiq bo'lishi shart)
$CLI rules map-local create 'https://api.demobozor.example/api/v1/cart' \
  --path ~/qa-mocks/demobozor/empty-cart.json --name "Bo'sh savatcha"

# 4) Faol qoidalarni ko'rish va ish tugagach tool'ni o'chirish
$CLI rules map-local list --enabled true
$CLI maplocal off
```

`rules` buyruqlari natijani JSON'da qaytaradi. Proxyman yopiq bo'lsa, ular xato qaytaradi (biz tekshirganda shunday chiqdi):

```json
{
  "action": "list",
  "api_version": 1,
  "error": {
    "code": "app_not_running",
    "message": "Please start Proxyman app, then try again."
  },
  "ok": false,
  "tool": "map-local"
}
```

Hujjatga ko'ra kiritish xatolarida exit code `2`, boshqa xatolarda `1` bo'ladi. Shu sabab CLI'ni skriptlarda ishonchli ishlatsa bo'ladi. Har bir tool'ning `create` parametrlari uchun: `proxyman-cli help rules map-local create`.

> **⚠️ Diqqat:** `proxy on/off` Mac'ning tizim tarmoq sozlamasini o'zgartiradi. Skriptlaringiz oxirida holatni qaytarishni unutmang, aks holda keyingi ishingizda "internet yo'q" muammosiga duch kelasiz.

> **💡 Maslahat:** QA jamoasi uchun `qa-mocks/` papkasini git'da saqlang: JSON mock'lar, eksport qilingan qoidalar va `README` (qaysi mock nimani tekshiradi). Yangi QA birinchi kuniyoq `import` qilib ishga kirishadi.

---

## 13. Proxyman MCP va Atlantis {#mcp-atlantis}

### Proxyman MCP — AI yordamchi trafikni "ko'radi"

**MCP (Model Context Protocol)** orqali Claude Code, Codex yoki Cursor kabi AI yordamchilar Proxyman bilan bevosita ishlaydi: ushlangan so'rovlarni o'qiydi, xatoni tushuntiradi, cURL yasaydi, Map Local yoki Breakpoint qoidasini yaratadi. Ulash:

1. **Proxyman → Settings → MCP** → **Enable MCP Server**.
2. Shu oynada mijozni tanlab, **Copy Command** ni bosing. Claude Code uchun buyruq quyidagicha:

```bash
claude mcp add proxyman --transport stdio -- "/Applications/Proxyman.app/Contents/MacOS/mcp-server"
```

Hujjatdagi asosiy vositalar: `get_flows`, `get_flow_detail`, `filter_flows`, `export_flow_curl`, `create_map_local`, `create_breakpoint`, `create_map_remote`, `create_blacklist`, `enable_ssl_proxying`, `clear_session` va boshqalar. AI'ga beriladigan so'rov misollari:

```text
api.demobozor.example ga oxirgi 10 ta so'rovni ko'rsat va 5xx qaytganlarini tushuntir.
POST /api/v1/orders flow'ini cURL qilib ber.
GET /api/v1/cart uchun bo'sh savatcha qaytaradigan Map Local qoidasi yarat.
```

Xavfsizlik bo'yicha hujjat ma'lumotlari: server faqat `127.0.0.1` da ishlaydi, har sessiyada token ishlatiladi, javoblarda token, parol va API kalitlari avtomatik yashiriladi (redaction). Kompaniya AI'ni taqiqlagan bo'lsa, administrator `proxyman-cli mcp off` bilan MCP'ni o'chirib, sozlamani qulflaydi.

> **⚠️ Diqqat:** Trafik ichida xaridorlarning telefon raqamlari va buyurtmalari bo'lishi mumkin. AI yordamchiga trafik berishdan oldin kompaniyangizning AI siyosatini tekshiring va redaction'ni o'chirmang. AI bilan QA ishlari haqida batafsil — [QA 26](/ios-lessons/qa-ai-testing).

### Atlantis — proksisiz kuzatish (iOS)

**Atlantis** — iOS ilovaga qo'shiladigan kichik freymvork. U HTTP/HTTPS va WebSocket trafigini proksi va sertifikatsiz Mac'dagi Proxyman'ga yuboradi. VPN yoqilgan holatda ham ishlaydi — korporativ VPN'li kompaniyalarda juda qulay.

Cheklovi: Atlantis faqat **kuzatish** uchun. Map Local, Breakpoint, Map Remote, Scripting va Network Conditions ishlamaydi — buning uchun oddiy proksi kerak. Freymvorkni faqat **debug** build'ga qo'shing.

---

## 14. Muammolarni hal qilish (troubleshooting) {#troubleshooting}

| Belgisi                                     | Ehtimoliy sabab                                                                     | Yechim                                                                                                                    |
| ------------------------------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| Hech qanday trafik yo'q                     | Proksi o'rnatilmagan, VPN yoqilgan yoki ilova tizim proksisini e'tiborsiz qoldiradi | Proksi holatini tekshiring, VPN'ni o'chiring; skriptlar uchun Automatic Setup; Pro + macOS 26 da Network Extension (beta) |
| iPhone `proxy.man/ssl` ni ocholmaydi        | Boshqa tarmoq, firewall yoki 9090 porti yopiq                                       | Bitta Wi-Fi; macOS Firewall'da Proxyman'ga ruxsat; Private tab; Wi-Fi'ni "Forget" qilib qayta ulanish                     |
| `SSL Handshake Failed`                      | Sertifikat o'rnatilmagan yoki ishonch berilmagan; yoki SSL pinning                  | Avval `https://google.com` ochilishini tekshiring. U ochilsa — muammo ilovada (pinning)                                   |
| Android'da brauzer ochiladi, ilova esa yo'q | `network_security_config.xml` yo'q                                                  | Debug build'ga `debug-overrides` qo'shing yoki emulator skriptidan foydalaning                                            |
| iOS 16/17 proksi saqlanmaydi                | Apple tomonidagi xato                                                               | Forget This Network → proksini qayta kiriting                                                                             |
| `localhost` so'rovlari ko'rinmaydi          | macOS localhost'ni proksidan o'tkazmaydi                                            | Automatic Setup → Google Chrome, yoki `localhost.proxyman.io` domeni                                                      |
| Ba'zi so'rovlar umuman chiqmaydi            | Ilova javobni keshdan olyapti                                                       | No Caching (⌥⌘N) yoki URLSession keshini o'chirish                                                                        |
| Proxyman yopilgach emulatorda internet yo'q | Proksi qaytarilmagan                                                                | Revert All Changes (emulator oynasi)                                                                                      |
| Flutter ilova trafigi yo'q                  | Flutter tizim proksisini ishlatmaydi                                                | Emulatorda Proxyman VPN (6.4.0+), aks holda HTTP klientga proksini koddan berish                                          |
| Korporativ VPN bilan ishlamaydi             | VPN trafikni o'ziga tortadi                                                         | VPN sozlamasida HTTP proksini `127.0.0.1:9090` ga yo'naltirish yoki iOS'da Atlantis                                       |

---

## 15. Bug report uchun dalil: eksport va maxfiy ma'lumotni yashirish {#dalil}

"Menda ishlayapti" bahsini tugatadigan eng kuchli dalil — so'rov va javobning o'zi. Eksport usullari:

| Usul                                 | Qachon                                                                        |
| ------------------------------------ | ----------------------------------------------------------------------------- |
| O'ng tugma → **Copy cURL**           | Bitta so'rovni backend dasturchi o'zi takrorlashi uchun                       |
| O'ng tugma → **Export** → HAR        | Bir nechta so'rov; Chrome, Charles va boshqa vositalarda ochiladi             |
| **Export** → Proxyman Log            | Rang va izohlar bilan birga (faqat Proxyman'da ochiladi)                      |
| **File → Save Session As**           | Butun sessiya (ilovalar, domenlar, qurilmalar)                                |
| `proxyman-cli export-log ... -f har` | Skript yoki CI ichida                                                         |
| Postman Collection 2.0               | So'rovlarni API testlariga aylantirish ([QA 10](/ios-lessons/qa-api-postman)) |

### Maxfiy ma'lumotni yashirish

HAR fayl **hamma narsani** saqlaydi: `Authorization` token'lari, cookie'lar, telefon raqamlar, SMS kodlar. Uni Jira'ga yoki chatga qo'yishdan oldin yashirish (mask) kerak. Header'lar uchun `jq` yetadi:

```bash
# HAR fayldagi Authorization/Cookie/Set-Cookie qiymatlarini *** bilan almashtiradi
jq '.log.entries |= map(
  (.request.headers, .response.headers) |= map(
    if (.name | test("^(authorization|cookie|set-cookie)$"; "i")) then .value = "***" else . end
  )
  | .request.cookies |= map(.value = "***")
  | .response.cookies |= map(.value = "***")
)' DB-1043.har > DB-1043.masked.har
```

Body ichidagi token, SMS kod va telefon raqamlarni ham yashirish uchun kichik Node.js skript:

```javascript
// mask-har.mjs — HAR fayldagi tokenlar, cookie, telefon va SMS kodlarni yashiradi.
// Ishlatish: node mask-har.mjs DB-1043.har > DB-1043.masked.har
import { readFileSync } from "node:fs";

const SECRET_HEADERS = /^(authorization|cookie|set-cookie|x-api-key)$/i;
const SECRET_FIELDS =
  /"(accessToken|refreshToken|code|password|cardNumber)"\s*:\s*"[^"]*"/g;
const PHONE = /\+998\d{9}/g;

function maskText(text) {
  if (!text) return text;
  return text
    .replace(SECRET_FIELDS, (_m, key) => `"${key}":"***"`)
    .replace(PHONE, "+998*********");
}

const har = JSON.parse(readFileSync(process.argv[2], "utf8"));
for (const entry of har.log.entries) {
  for (const part of [entry.request, entry.response]) {
    part.headers = part.headers.map((h) =>
      SECRET_HEADERS.test(h.name) ? { ...h, value: "***" } : h,
    );
    part.cookies = (part.cookies ?? []).map((c) => ({ ...c, value: "***" }));
  }
  entry.request.url = maskText(entry.request.url);
  if (entry.request.postData)
    entry.request.postData.text = maskText(entry.request.postData.text);
  if (entry.response.content)
    entry.response.content.text = maskText(entry.response.content.text);
}
process.stdout.write(JSON.stringify(har, null, 2));
```

Biz ikkala usulni namunaviy HAR'da sinadik. `jq` faqat header va cookie'larni yashiradi. Node skripti esa body'dagi `accessToken`, SMS `code` va `+998...` raqamlarni ham yashiradi.

### Bug report'dagi namunaviy "Dalil" bo'limi

```text
Dalil:
- Proxyman: POST https://api.demobozor.example/api/v1/cart/items
  So'rov body: {"productId": 42, "quantity": -1}
  Javob: 201 Created (kutilgan: 400/422)
- Ilova: iOS 26.5, DemoBozor 2.4.0 (1287), staging
- Fayl: DB-1043.masked.har (token va telefon raqamlar yashirilgan)
- cURL: ilova qilindi (Authorization olib tashlangan)
```

> **⚠️ Diqqat:** Team Workspace'dagi "Share log online" funksiyasi qulay, lekin havola orqali trafikni kim ko'ra olishini tekshiring. Xaridorlarning shaxsiy ma'lumotlari jamoadan tashqariga chiqmasligi kerak.

---

## 16. Amaliy mashqlar {#mashqlar}

![Qaysi Proxyman vositasi qachon kerakligi: QA vazifasi va mos vosita](/lessons/images/qa/qa_15_proxyman_tools.svg)

### Mashq 1: Vositani tanlang

Har bir vazifa uchun eng mos Proxyman vositasini yozing:

1. Ilova serverdan `401` olganda login ekraniga qaytishini tekshirish (backend'ga tegmasdan).
2. Do'kondagi prod build'ni staging serverga ulash.
3. Har 5-chi `GET /api/v1/products` so'roviga `502` qaytarish.
4. Analitika SDK domeni ishlamay qolganda ilova qotib qolmasligini tekshirish.
5. Bir xil `POST /api/v1/orders` ni ikki marta yuborish.
6. v2.3 va v2.4 ilovalari bir xil `GET /api/v1/products/42` ga qanday javob olishini solishtirish.
7. Kartani tasdiqlash so'rovi 3G'da qanday ishlashini ko'rish.
8. `quantity` qiymatini bir martalik `-1` qilib yuborish.

<details>
<summary>💡 Javobni ko'rish</summary>

| #   | Vosita                                 | Izoh                                                               |
| --- | -------------------------------------- | ------------------------------------------------------------------ |
| 1   | Map Local (status 401) yoki Breakpoint | Bir martalik bo'lsa Breakpoint, takrorlanuvchi bo'lsa Map Local    |
| 2   | Map Remote                             | Host'ni `staging-api.demobozor.example` ga almashtirish                 |
| 3   | Scripting                              | `sharedState` hisoblagichi bilan har 5-so'rovda `statusCode = 502` |
| 4   | Block List                             | Analitika domenini "Block & Display" rejimida bloklash             |
| 5   | Repeat                                 | Idempotentlikni tekshirish                                         |
| 6   | Diff                                   | Ikkala javobni ⌘Y bilan Diff pool'ga qo'shish                      |
| 7   | Network Conditions                     | Faqat to'lov domeni uchun 3G profili                               |
| 8   | Breakpoint (yoki Edit & Repeat)        | Bir martalik qo'lda o'zgartirish                                   |

</details>

### Mashq 2: Texnik ishlar rejimi uchun Map Local

DemoBozor `GET /api/v1/products` uchun "texnik ishlar" javobini yozing: status `503`, `Retry-After: 300` header'i va foydalanuvchiga tushunarli o'zbekcha xabar. Ilovada nimalarni tekshirasiz?

<details>
<summary>💡 Javobni ko'rish</summary>

```http
HTTP/1.1 503 Service Unavailable
Content-Type: application/json
Retry-After: 300

{"error": "MAINTENANCE", "message": "Texnik ishlar olib borilmoqda. 5 daqiqadan so'ng qayta urinib ko'ring."}
```

Tekshiruvlar:

- ilova crash bo'lmaydi va bo'sh oq ekran ko'rsatmaydi;
- server xabari (yoki ilovaning o'z matni) tushunarli tilda chiqadi;
- "Qayta urinish" tugmasi bor, lekin u serverni sekundiga o'nlab so'rov bilan "bombardimon" qilmaydi;
- savatchadagi ma'lumotlar yo'qolmaydi;
- 503 tugagach (qoidani o'chirgach) ilova normal holatga qaytadi.

</details>

### Mashq 3: Skript yozing

Har ikkinchi `POST /api/v1/orders` javobiga `502 Bad Gateway` qaytaradigan va bunday javobni sariq rang bilan belgilaydigan Proxyman skriptini yozing.

<details>
<summary>💡 Javobni ko'rish</summary>

```javascript
function onResponse(context, url, request, response) {
  if (request.method !== "POST") {
    return response;
  }
  var n = (sharedState.orderResponses ?? 0) + 1;
  sharedState.orderResponses = n;

  if (n % 2 === 0) {
    response.statusCode = 502;
    response.headers["Content-Type"] = "application/json";
    response.body = { error: "BAD_GATEWAY" };
    response.color = "yellow";
    response.comment = "Soxta 502 (#" + n + ")";
  }
  return response;
}
```

Matching rule: `https://api.demobozor.example/api/v1/orders`. **Run Script on Response** yoqilgan bo'lsin.

E'tibor bering: bu yerda server buyurtmani **yaratgan**, lekin ilova 502 olgan. Bu juda muhim test — ilova qayta urinsa, dublikat buyurtma paydo bo'lmasligi kerak.

</details>

### Mashq 4: Tampering test rejasi

DemoBozor'ning `POST /api/v1/orders` endpoint'i uchun Breakpoint bilan bajariladigan 5 ta server validatsiyasi testini yozing (kirish o'zgarishi → kutilgan natija).

<details>
<summary>💡 Javobni ko'rish</summary>

| #   | O'zgarish                                                       | Kutilgan natija                                  |
| --- | --------------------------------------------------------------- | ------------------------------------------------ |
| 1   | `paymentMethod: "UZCARD"` → `"BITCOIN"`                         | `400`/`422`, ruxsat etilgan qiymatlar ro'yxati   |
| 2   | `promoCode` → 13 belgili kod (`ABCDEFGHIJKLM`)                  | `400`/`422` (chegara 6–12)                       |
| 3   | Bir martalik promo-kodni ikkinchi buyurtmada ishlatish          | `409` yoki `422`, "kod allaqachon ishlatilgan"   |
| 4   | Body'ga `"deliveryFee": 0` qo'shish (summa 300 000 so'mdan kam) | Server yetkazishni o'zi hisoblaydi (20 000 so'm) |
| 5   | `deliveryAddressId` → boshqa xaridorning manzil ID'si           | `403`/`404`, buyurtma yaratilmaydi               |

Har bir testni faqat staging va o'z test hisoblaringiz bilan bajaring.

</details>

### Mashq 5: iPhone "internetsiz" qoldi

QA iPhone'da proksini sozladi, lekin hech bir sayt ochilmayapti va Proxyman'da trafik yo'q. Tekshirish tartibini yozing.

<details>
<summary>💡 Javobni ko'rish</summary>

1. Proxyman Mac'da ochiqmi va qaysi IP/portda tinglayapti (`proxyman-cli proxy-host`)?
2. iPhone'dagi proksi IP'si Mac'ning **hozirgi** IP'siga mosmi (Wi-Fi qayta ulanganda IP o'zgarishi mumkin)? Port `9090`mi?
3. Mac va iPhone bitta tarmoqdami (mehmonlar tarmog'i ko'pincha qurilmalarni bir-biridan ajratadi)?
4. Ikkala qurilmada VPN o'chiqmi?
5. macOS Firewall Proxyman'ga kiruvchi ulanishlarga ruxsat beradimi?
6. Korporativ tarmoq 9090 portini bloklamaydimi?
7. Hammasi to'g'ri bo'lsa: Wi-Fi'ni "Forget" qilib, proksini qayta kiriting (iOS 16/17 xatosi).

</details>

### Mashq 6: CLI bilan dalil yig'ish

Uchta buyruq yozing: (1) sessiyani tozalash, (2) faqat `api.demobozor.example` trafigini HAR formatida `~/Desktop/DB-2001.har` ga eksport qilish, (3) Map Local tool'ini o'chirish.

<details>
<summary>💡 Javobni ko'rish</summary>

```bash
CLI=/Applications/Proxyman.app/Contents/MacOS/proxyman-cli
$CLI clear-session
# ... bug'ni qayta hosil qiling ...
$CLI export-log -m domains --domains 'api.demobozor.example' -f har -o ~/Desktop/DB-2001.har
$CLI maplocal off
```

So'ng HAR'ni `mask-har.mjs` dan o'tkazing va faqat masklangan faylni biriktiring.

</details>

### Mashq 7: Toolshop'da bo'sh holat

Toolshop'ning `QUERY https://api.practicesoftwaretesting.com/products` so'roviga Map Local qo'yib, bo'sh ro'yxat qaytaring. Ekranda nima chiqadi? Yana qaysi 3 ta chekka holatni xuddi shu usul bilan sinaysiz?

<details>
<summary>💡 Javobni ko'rish</summary>

Body: `{"current_page":1,"data":[],"from":null,"last_page":1,"per_page":9,"to":null,"total":0}` — sahifada "There are no products found." chiqadi.

Yana uchta g'oya:

1. `total: 1000`, `last_page: 112` — pagination ko'p sahifada to'g'ri ishlaydimi.
2. Mahsulot nomi 300 belgi — karta layout'i buzilmaydimi.
3. Status `500` — xato xabari chiqadimi yoki sahifa cheksiz yuklanadimi.

</details>

---

## 17. O'zingizni tekshiring {#checklist}

- [ ] Proxyman CA'ni Mac, Simulator va iPhone'ga o'rnatib, ishonch bera olaman
- [ ] SSL Proxying'ni faqat kerakli domen uchun yoqaman
- [ ] Map Local bilan bo'sh, maksimal va xato holatlarini yarata olaman
- [ ] Breakpoint bilan server validatsiyasini (test muhitida) tekshira olaman
- [ ] Takrorlanuvchi ssenariy uchun `onRequest`/`onResponse` skript yoza olaman
- [ ] Network Conditions va Block List bilan yomon tarmoq va ishlamay qolgan servisni sinay olaman
- [ ] `proxyman-cli` bilan qoidalarni eksport/import qilaman va HAR yig'aman
- [ ] Dalilni bug report'ga maxfiy ma'lumotlarsiz biriktiraman

---

## Xulosa {#xulosa}

- Debugging proxy mobil QA'ning "DevTools"i: ilova serverga nima yuborayotganini va nima olayotganini ko'rsatadi, bug'ni to'g'ri jamoaga yo'naltiradi.
- HTTPS'ni ochish uchun ikki narsa kerak: qurilmada **ishonchli Proxyman CA** va domen uchun **SSL Proxying**. Pinning'li ilova ochilmaydi — bu himoya.
- **Map Local** chekka holatlarni yaratadi, **Map Remote** serverni almashtiradi, **Breakpoint** bir martalik tahrir qiladi, **Scripting** esa takrorlanuvchi ssenariylarni avtomatlashtiradi.
- **Network Conditions**, **Block List** va **Repeat** yordamida yomon tarmoq, ishlamay qolgan servis va dublikat so'rov xatolari topiladi.
- `proxyman-cli` (26.0.1) qoidalarni ulashish, HAR eksport va skriptlar uchun; MCP esa AI yordamchilarga trafikni xavfsiz ko'rsatadi.
- Tampering faqat o'z test muhitingizda qilinadi. HAR'dagi token va shaxsiy ma'lumotlarni biriktirishdan oldin har doim yashiring.
- **Keyingi dars:** [QA 16: Test avtomatlashtirishga kirish — nimani avtomatlashtirish kerak, ROI va 2026 asboblar xaritasi](/ios-lessons/qa-automation-intro)

## Manbalar {#manbalar}

1. [Proxyman — rasmiy sayt](https://proxyman.com/)
2. [Proxyman Documentation — Overview](https://docs.proxyman.com/)
3. [Proxyman macOS Changelog](https://proxyman.com/changelog)
4. [Proxyman Docs — License (Trial va Pro)](https://docs.proxyman.com/license)
5. [Proxyman Docs — SSL Proxying](https://docs.proxyman.com/basic-features/ssl-proxying)
6. [Proxyman Docs — macOS sertifikati](https://docs.proxyman.com/debug-devices/macos)
7. [Proxyman Docs — iOS Simulator](https://docs.proxyman.com/debug-devices/ios-simulator)
8. [Proxyman Docs — iOS Device](https://docs.proxyman.com/debug-devices/ios-device)
9. [Proxyman Docs — Android Device & Emulator](https://docs.proxyman.com/debug-devices/android-device)
10. [Proxyman Docs — Automatic Script for Android Emulator](https://docs.proxyman.com/debug-devices/android-device/automatic-script-for-android-emulator)
11. [Proxyman Docs — Map Local (File)](https://docs.proxyman.com/advanced-features/map-local)
12. [Proxyman Docs — Map Remote](https://docs.proxyman.com/advanced-features/map-remote)
13. [Proxyman Docs — Breakpoint](https://docs.proxyman.com/advanced-features/breakpoint)
14. [Proxyman Docs — Scripting](https://docs.proxyman.com/scripting/script)
15. [Proxyman Docs — Snippet Code](https://docs.proxyman.com/scripting/snippet-code)
16. [Proxyman Docs — Network Conditions](https://docs.proxyman.com/advanced-features/network-throttling)
17. [Proxyman Docs — Block List](https://docs.proxyman.com/advanced-features/blacklist)
18. [Proxyman Docs — Command-line](https://docs.proxyman.com/command-line)
19. [Proxyman Docs — MCP](https://docs.proxyman.com/mcp)
20. [Proxyman Docs — Atlantis for iOS](https://docs.proxyman.com/atlantis/atlantis-for-ios)
21. [Proxyman Docs — SSL Error from HTTPS Request/Response](https://docs.proxyman.com/troubleshooting/get-ssl-error-from-https-request-and-response)
22. [Android Developers — Network security configuration](https://developer.android.com/privacy-and-security/security-config)
23. [Charles Proxy — Buy (litsenziya va trial)](https://www.charlesproxy.com/buy/)
24. [mitmproxy — rasmiy sayt](https://mitmproxy.org/)
25. [HTTP Toolkit — rasmiy sayt](https://httptoolkit.com/)
26. [Fiddler Everywhere — Telerik](https://www.telerik.com/fiddler/fiddler-everywhere)
27. [Toolshop — Practice Software Testing](https://practicesoftwaretesting.com/)
28. [Restful-booker API docs](https://restful-booker.herokuapp.com/apidoc/index.html)
