본문 재작성

Chute는 정규식 또는 JSONPath 표현식을 사용하여 HTTP 요청 및 응답 본문의 내용을 검색하고 교체할 수 있습니다. HTTPS 트래픽의 경우 MitM 복호화가 필요합니다.

주의: 일반 HTTP 요청은 Chute의 HTTP 프록시를 거쳐 들어올 때만 처리됩니다. TUN 인터페이스를 거쳐 들어오는 일반 HTTP는 손대지 않고 그대로 전달됩니다. Chute Android는 설정에서 시스템 HTTP 프록시를 켜지 않는 한 모든 트래픽을 TUN으로 보냅니다. 이 옵션을 켜면 앱에 Chute의 HTTP 프록시가 주어집니다(Android 10 이상, 기본값은 꺼짐).

Surge의 http-request-jq 및 http-response-jq 프로그램도 지원됩니다 — Surge 구문을 참고하세요.

본문 재작성 규칙은 [Body Rewrite] 섹션에 정의됩니다. 각 방향(요청/응답)별로 하나의 메시지에는 첫 번째로 일치하는 규칙만 적용됩니다. 같은 메시지에 본문을 받는 http-request 또는 http-response 스크립트도 일치하면 규칙이 먼저 적용되고, 스크립트는 재작성된 본문을 받습니다. http-request-before-send 스크립트는 그 둘 다음에 실행됩니다.

[Body Rewrite]
^https://api\.example\.com/response.* response regex "old-text" "new-text"
^https://api\.example\.com/request.* request regex "sensitive" "[redacted]"
^https://api\.example\.com/data.* jsonpath-response jsonpath $.ads null

규칙 형식

각 규칙은 다음과 같은 일반 형식을 따릅니다:

<URL regex> [direction] <mode> <pattern> <replacement>

주의: URL 정규식은 URL 재작성과 마찬가지로 요청의 전체 URL 어느 위치에서든 일치하며, 경로만 따로 놓고도 대조됩니다. ^https://example\.com만으로 해당 호스트의 모든 경로와 쿼리 문자열이 포함되므로 끝에 .*를 붙일 필요가 없으며, ^/api는 경로가 /api로 시작하는 모든 요청과 일치합니다. 복호화된 요청의 전체 URL은 https://로 시작하므로, ^http:// 패턴은 그런 요청과 결코 일치하지 않습니다. 패턴의 대소문자는 유지되므로 \S, \D, \W, \B는 쓴 그대로의 의미를 가지며, 일치 자체는 대소문자를 구분하지 않습니다.

줄 맨 앞이나 공백 뒤에 오는 #나 //는 큰따옴표 안에 있지 않은 한 줄 끝까지 이어지는 주석을 시작합니다. ;은 주석이 되지 않습니다. 주석을 참고하세요.

Surge 구문

Surge 고유의 줄 형식도 허용됩니다. 방향을 맨 앞에 쓰고 regex 키워드는 생략합니다.

[Body Rewrite]
http-response ^https://api\.example\.com/feed "\"ads\":\s*\[.*?\]" "\"ads\":[]"
http-request ^https://api\.example\.com/submit "sensitive" "[redacted]"

Surge 형식 줄에는 여러 패턴/대체 쌍을 쓸 수 있으며, 왼쪽에서 오른쪽으로 앞선 쌍의 결과에 차례로 적용됩니다. http-request-jq와 http-response-jq는 패턴과 대체 문자열 대신 jq 프로그램을 받습니다: <type> <URL pattern> <jq program>. 프로그램에는 공백이 들어가므로 보통 따옴표로 감쌉니다. 따옴표 밖에서는 공백 뒤에 오는 //나 #가 주석을 시작하며, 프로그램은 거기서 끝납니다. 따옴표 안에서 //는 jq의 대안 연산자이므로, 이를 쓰는 프로그램은 따옴표로 감싸세요. 본문은 JSON으로 처리됩니다. 본문이 JSON이 아니거나, 프로그램이 오류를 내거나, 출력이 없으면 모두 본문을 그대로 둡니다. 프로그램 자체가 잘못된 경우에는 보고되고 그 규칙 하나만 건너뜁니다(프로필 전체가 실패하지는 않습니다). 프로그램은 파일도 환경도 읽을 수 없습니다: import와 include는 아무것도 찾지 못하고, $ENV와 env는 비어 있습니다.

주의: Chute Android는 jq 프로그램을 jackson-jq로 실행합니다. 출력은 결과 4096개 또는 4 MB로 제한되며 — 그보다 많이 출력하는 프로그램은 본문을 그대로 둡니다 — jq 1.7의 일부 내장 함수가 없습니다. now, todateiso8601, fromdateiso8601을 제외한 날짜 함수(strftime, strptime, mktime, gmtime, todate 등), @base32와 @base32d, abs, toarray, trim, ltrim과 rtrim, IN, INDEX와 JOIN, tostream과 fromstream이 그 예입니다. 이 중 하나를 호출하는 프로그램은 실행 중에 오류를 내므로 본문은 그대로 남습니다.

방향

키워드 설명
response 응답 본문에 적용 (생략 시 기본값)
request 요청 본문에 적용

모드

모드 설명
regex 정규식 검색 및 교체
jsonpath-response / jsonpath-request / body-jsonpath-response / body-jsonpath-request JSONPath 기반 수정

정규식 모드

디코딩된 본문 텍스트에 대해 표준 정규식 찾기 및 바꾸기를 수행합니다. NSRegularExpression(ICU)을 사용하며, 대소문자를 구분하지 않고 일치시킵니다. 교체 문자열은 캡처 그룹 참조($1, $2 등)를 지원합니다.

<URL regex> [response|request] regex <pattern> <replacement>

예 — JSON 응답에서 광고 제거:

[Body Rewrite]
^https://api\.example\.com/feed.* response regex "\"ads\":\s*\[.*?\]" "\"ads\":[]"

예 — 요청 본문 정리:

[Body Rewrite]
^https://api\.example\.com/submit.* request regex "\"password\":\s*\".*?\"" "\"password\":\"[FILTERED]\""

예 — 캡처 그룹을 사용하여 데이터 재형식화:

[Body Rewrite]
// "last, first"를 "first last"로 변환
^https://api\.example\.com/users.* response regex "\"name\":\s*\"(\w+),\s*(\w+)\"" "\"name\":\"$2 $1\""

예 — 응답 본문에 포함된 URL 재작성:

[Body Rewrite]
^https://api\.example\.com.* response regex "https://old-cdn\.example\.com" "https://new-cdn.example.com"

공백이 포함된 토큰은 큰따옴표로 묶어야 합니다:

[Body Rewrite]
^https://example\.com.* response regex "old value with spaces" "new value"

따옴표로 묶인 토큰 안에 리터럴 큰따옴표를 포함하려면 백슬래시로 이스케이프합니다: \".


JSONPath 모드

JSONPath 표현식을 사용하여 JSON 본문을 수정합니다. 특정 경로에서 값 읽기, 설정 및 삭제를 지원합니다.

<URL regex> jsonpath-response|jsonpath-request jsonpath <jsonpath-expression> [value]

지원되는 JSONPath 구문

표현식 설명
$.key 객체 속성 접근
$.key.subkey 중첩 속성 접근
$[0] 인덱스로 배열 요소 접근
$.key[0].subkey 객체와 배열 혼합 접근
$.items[*].name 와일드카드: 배열의 모든 항목
$.*.value 와일드카드: 모든 속성

.*는 객체의 모든 멤버와 배열의 모든 요소를 가져오므로, $.items.*.name은 각 항목의 이름에 도달합니다. 배열에 대한 마지막 단계로 쓰면 아무것도 바꾸지 않습니다. 요소 자체를 교체하려면 [*]를 쓰세요.

값 유형

값 결과
string 문자열 값으로 설정 — 아래 형식 어디에도 해당하지 않는 값은 모두 문자열이므로 example.com, 1.0.0-beta, 12abc는 문자열로 남습니다
42 정수로 설정 — 토큰 전체가 JSON 숫자이고 소수부와 지수가 없는 경우
3.14 실수로 설정 — 소수부나 지수가 있는 JSON 숫자(1e3 등), 또는 64비트를 넘는 정수
true 불리언 true로 설정
false 불리언 false로 설정
[…] 또는 {…} 따옴표 없이 쓰면 JSON으로 파싱되어 그 배열이나 객체로 설정됩니다. 마지막 필드이므로 줄의 나머지가 쓰인 그대로 값이 되며 공백이 들어가도 됩니다. 따옴표로 묶거나 올바른 JSON이 아니면 문자열로 남습니다.
null, nil 또는 생략 경로 삭제

주의: 값을 따옴표로 묶어도 문자열 유형으로 강제되지 않습니다. 따옴표는 토큰화 과정에서 제거되고 남은 내용으로 유형이 추론되므로, "42"는 숫자 42가 되고 "true"는 불리언 true가 되며 "null"은 경로를 삭제합니다. 따옴표가 영향을 주는 것은 […]와 {…}뿐이며, 따옴표로 묶으면 이들은 문자열로 남습니다. 키워드는 대소문자까지 정확히 일치해야 하므로 True와 NULL은 문자열입니다. 숫자는 토큰 전체가 JSON 표기대로 숫자일 때만 인정됩니다. +1, .5, 1., 007은 문자열로 남고, 실수로도 나타낼 수 없을 만큼 큰 수(1e400 등)도 마찬가지입니다. "42"나 "true" 같은 문자열을 설정하는 표기법은 없으니 그럴 때는 regex 규칙을 쓰세요.

예 — JSON 필드 설정:

[Body Rewrite]
^https://api\.example\.com/profile.* jsonpath-response jsonpath $.user.name "Anonymous"

예 — JSON 필드 삭제:

[Body Rewrite]
^https://api\.example\.com/data.* jsonpath-response jsonpath $.tracking null

예 — 와일드카드 수정:

[Body Rewrite]
^https://api\.example\.com/list.* jsonpath-response jsonpath $.items[*].hidden true

실용 예제

JSON 응답에서 추적 매개변수 제거

모든 API 응답에서 trackingId 필드를 제거합니다. 각 방향별로 첫 번째로 일치하는 규칙만 적용되므로, URL 패턴당 하나의 규칙을 사용하세요:

[Body Rewrite]
^https://api\.example\.com/.* jsonpath-response jsonpath $.trackingId null

HTML 응답에 스크립트 태그 삽입

모든 HTML 페이지에서 </body> 앞에 사용자 정의 <script> 태그를 추가합니다:

[Body Rewrite]
^https://www\.example\.com/.* response regex "</body>" "<script>console.log('injected')</script></body>"

요청 로그에서 민감한 필드 마스킹

서버에 도달하기 전에 나가는 요청 본문에서 API 키와 토큰을 교체합니다. 각 방향별로 첫 번째로 일치하는 규칙만 적용되므로, 두 필드를 하나의 규칙으로 결합하세요:

[Body Rewrite]
^https://api\.example\.com/.* request regex "\"(apiKey|token)\":\s*\"[^\"]+\"" "\"$1\":\"[REDACTED]\""

응답에서 날짜 형식 정규화

ISO 날짜를 더 짧은 형식으로 교체합니다:

[Body Rewrite]
^https://api\.example\.com/.* response regex "(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z" "$1/$2/$3 $4:$5"

앱 설정에서 기능 플래그 비활성화

설정 엔드포인트에서 모든 기능 플래그를 false로 강제 설정합니다:

[Body Rewrite]
^https://api\.example\.com/config.* jsonpath-response jsonpath $.features[*].enabled false

캐시된 응답에서 CDN URL 재작성

이전 CDN에 대한 모든 참조를 새 CDN으로 교체합니다:

[Body Rewrite]
^https://www\.example\.com/.* response regex "https://old-cdn\.example\.com" "https://new-cdn.example.com"

처리 파이프라인

본문 재작성은 다음을 자동으로 처리합니다:

  1. Content-Encoding: gzip 및 deflate를 지원합니다. 지원되지 않는 인코딩은 건너뜁니다.
  2. Transfer-Encoding: 처리 전에 청크 전송 인코딩을 디청킹합니다.
  3. 디코딩: 재작성 규칙을 적용하기 전에 본문의 압축을 해제합니다.
  4. 재인코딩: 본문을 다시 압축하고 Content-Length를 업데이트합니다. Transfer-Encoding 헤더를 제거합니다.
  5. Accept-Encoding: 응답 규칙이 요청의 URL과 일치하면, 응답이 디코딩 가능한 인코딩으로 유지되도록 요청의 Accept-Encoding 헤더가 gzip, deflate, identity로 재작성됩니다.

재작성 처리를 위한 최대 본문 크기는 HTTP/1.x(일반 HTTP와 복호화된 HTTP/1.1)에서 128KB이며, 이보다 큰 본문은 수정 없이 통과됩니다. 복호화된 HTTP/2 메시지는 크기와 관계없이 통째로 버퍼링되어 재작성됩니다.

HTTP/1.x에서 응답 본문은 전부 도착한 뒤에 재작성됩니다. 그 전에 서버가 연결을 닫으면, Content-Length도 청크 인코딩도 없는 본문은 연결이 끝나는 곳이 본문의 끝이므로 완전한 것으로 보고 평소대로 재작성합니다. Content-Length나 청크 인코딩으로 구획되는데 연결 종료로 잘린 본문은 받은 그대로 클라이언트에 전달되며, 재작성되지 않고 Content-Length도 바뀌지 않습니다. 그런 다음 연결이 닫히므로 클라이언트는 응답이 불완전하다는 것을 알 수 있습니다.


참고

  • HTTPS 트래픽의 경우, 일치하는 호스트명에 대해 MitM 복호화가 활성화되어야 합니다.
  • 정규식 일치는 대소문자를 구분하지 않습니다. 교체 템플릿은 ICU 캡처 그룹 참조를 지원합니다: $0(전체 일치), $1(첫 번째 그룹), $2(두 번째 그룹) 등.
  • URL 패턴이나 본문 패턴이 유효한 정규식이 아니면 regex 줄이나 JSONPath 줄은 구성 오류가 되어 규칙이 로드되지 않습니다. jq 줄은 대신 경고와 함께 건너뜁니다. 첫 번째 쌍 뒤의 쌍에서는 유효하지 않은 패턴이 그 쌍만 버리며, 로그에 경고가 남습니다.
  • JSONPath 모드는 본문이 유효한 JSON인 경우에만 적용됩니다.
  • 본문 재작성 규칙은 디코딩된(UTF-8) 본문 텍스트에 적용됩니다.
  • 각 방향(요청/응답)별로 하나의 메시지에는 첫 번째로 일치하는 규칙만 적용됩니다. 여러 수정이 필요하면 하나의 통합 규칙으로 정의하세요.
  • 존재하지 않는 JSONPath를 삭제하면 본문은 변경되지 않습니다. 값을 설정할 때 부모 객체가 존재하면 키가 생성되며, 중간 경로가 없으면 아무 일도 일어나지 않습니다.
S. Smart Rabbit LLC © All Rights Reserved            updated 2026-09-29 21:57:05

이 페이지는 영어판의 번역본입니다. 내용이 다를 경우 영어판이 우선합니다.

results matching ""

    No results matching ""