빌드노트
명령에 없는 curl 헤더가 붙을 때: -q는 맨 앞에 둔다
명령에 없는 사용자 정의 헤더가 curl 요청에 붙을 때 기본 설정 파일을 판별한다. 같은 실행 파일과 loopback 요청에서 기본 실행, 첫 -q, 뒤쪽 -q를 비교하고 명시적 --config가 계속 적용되는 차이를 확인한다.
curl 스크립트에 -H로 넣은 적 없는 사용자 정의 헤더가 요청에서 보인다면 기본 설정 파일을 의심할 수 있다. curl은 명령행 인자 외에 기본 curlrc 파일에서도 옵션을 읽는다. 같은 요청을 비교할 때 실행 파일 바로 다음의 첫 인자로 -q를 두면 이 파일의 개입을 가려낼 수 있다. 다른 옵션 뒤에 붙인 -q는 같은 대조가 아니다. curl의 -q 설명 (새 탭에서 열림)
같은 실행 파일로 -q 위치만 바꾼다
먼저 문제가 생긴 스크립트와 같은 환경에서 어떤 curl을 실행하는지 확인한다. 다음은 Windows PowerShell용 조회다. 실행 파일을 하나 선택해 이후 요청에서도 같은 경로를 사용한다.
Get-Command curl -All | Select-Object Name, CommandType, Source | Format-List
$curlExe = (Get-Command curl.exe -CommandType Application | Select-Object -First 1).Source
& $curlExe -q --version
실제 비교에 사용한 Windows PowerShell 5.1에서는 curl이라는 별칭과 curl.exe 실행 파일이 함께 보였다. 따라서 이름이 curl이라는 이유만으로 실행 파일의 옵션이 적용됐다고 판단하지 않았다. 버전 출력은 curl 8.21.0 (Windows) libcurl/8.21.0으로 시작했다. 버전 조회에도 첫 인자에 -q를 넣었다.
다음 세 명령은 같은 URL에 같은 GET을 보내면서 -q의 유무와 위치만 바꾼다. 자신이 관리하는 로컬 서버의 읽기 전용 경로가 준비돼 있어야 한다. 8080/health를 그 포트와 경로로 바꾸고, 문제가 된 헤더를 확인하던 서버 로그 등에서 세 요청의 헤더를 비교한다. 아래 명령 자체가 요청 헤더를 출력하는 것은 아니다.
$url = 'http://127.0.0.1:8080/health'
& $curlExe -sS --noproxy '*' --connect-timeout 1 --max-time 3 $url
& $curlExe -q -sS --noproxy '*' --connect-timeout 1 --max-time 3 $url
& $curlExe -sS -q --noproxy '*' --connect-timeout 1 --max-time 3 $url
이 비교의 --noproxy '*'는 로컬 요청이 프록시를 거치지 않게 하는 조건이다. 시간 제한은 응답을 계속 기다리지 않게 한다. 기존 스크립트에 적용할 때도 -q는 공통 옵션 배열의 끝에 추가하지 말고 실행 파일 다음에 별도 인자로 둔다.
이 차이를 확인하기 위해 Windows 11에서 개인 설정과 분리한 실험도 했다. 자식 curl의 CURL_HOME을 새 소유 폴더로 지정하고, 그 안의 .curlrc에는 다음 한 줄만 넣었다. 긴 옵션의 이름, 등호, 인자를 한 줄에 적은 curl 설정 파일 문법이다. 공식 설정 파일 문법 (새 탭에서 열림)
header = "X-Lab: default"
다른 홈 관련 변수도 모두 새 폴더로 지정했고, 실행 파일 폴더로 탐색이 이어져도 개인 설정을 만나지 않도록 시스템 curl의 복사본을 사용했다. 수신기는 127.0.0.1에만 열었다. 위 세 요청과 같은 옵션을 이 수신기의 동일한 /headers 경로로 보내자 다음 응답을 받았다. 이 한 줄은 수신기가 받은 X-Lab 값을 돌려준 응답 본문이며 curl 자체의 진단 문구가 아니다.
- 기본 실행:
X-Lab=default - 첫 인자에
-q:X-Lab=<absent> -sS다음에-q:X-Lab=default
세 요청 모두 curl 종료 코드는 0이었다. 서버에서 받은 헤더도 각각 default, 없음, default로 일치했다. 성공 여부만으로는 기본 설정을 읽었는지 구분할 수 없었다. 첫 -q에서만 사용자 정의 헤더가 사라지는 것이 이 실험의 판별 근거다. curl 8.21.0의 해당 버전 문서 (새 탭에서 열림)도 첫 인자라는 조건을 명시한다.
자신의 비교에서도 첫 -q에서만 차이가 사라지면 기본 설정 파일의 옵션을 조사할 근거가 생긴다. 그대로라면 먼저 실제 인자 순서와 뒤에서 설명할 명시적 --config를 확인한다. -q 하나로 모든 설정 원인을 배제했다고 볼 수는 없다. 연결 자체가 실패했다면 헤더가 없다는 결과로 세지 말고 URL과 서버의 수신 상태부터 확인한다.
설정 파일은 현재 폴더만 찾지 않는다
어느 파일이 적용됐는지는 curl을 실행한 프로세스의 환경에서 확인한다. IDE나 작업 실행기가 호출했다면 그 실행 환경을 대상으로 봐야 한다. 다음 조회는 파일 내용을 열지 않고 탐색에 쓰이는 환경 변수 값을 보여 준다.
'CURL_HOME', 'XDG_CONFIG_HOME', 'HOME', 'USERPROFILE', 'APPDATA' |
ForEach-Object { Get-Item "Env:$_" -ErrorAction SilentlyContinue } |
Format-List Name, Value | Out-String -Width 4096
curl 8.21.0의 공식 문서에 나온 Windows 기본 파일 탐색 순서는 다음과 같다. 변수 값이 없으면 그 항목은 건너뛴다. 아래는 문서의 규칙이며, 이번 실험에서 각 위치의 우선순위를 모두 재검증한 것은 아니다.
CURL_HOME아래.curlrcXDG_CONFIG_HOME아래curlrc— 이 위치 지원은 7.73.0부터다.HOME아래.curlrcUSERPROFILE아래.curlrcAPPDATA아래.curlrcUSERPROFILE아래Application Data폴더의.curlrc- 앞선 위치에서 찾지 못하면 curl 실행 파일과 같은 폴더
Windows에서는 .curlrc 외에 _curlrc라는 이름도 확인하며 .curlrc를 우선한다. 따라서 현재 작업 폴더에 설정 파일이 없거나, 자신이 예상한 홈에 파일이 없다는 것만으로 기본 설정을 배제할 수 없다. curl 8.21.0의 설정 파일 탐색 규칙 (새 탭에서 열림)
첫 -q로 차이를 확인한 뒤에는 이 경로들과 파일의 관련 옵션을 대조해 출처를 좁힌다. 비교 결과만으로 특정 파일 이름까지 알아낸 것은 아니다. 반복 실행할 스크립트는 첫 인자 -q를 고정하고 필요한 옵션을 명령이나 의도적으로 지정한 설정 파일에 적으면, 사용자별 기본 파일의 영향을 줄일 수 있다.
-q를 써도 명시한 --config는 읽는다
-q는 기본 curlrc의 자동 로드를 막는 옵션이다. --config 또는 -K로 직접 지정한 파일까지 무시하게 만들지는 않는다. 반대로 --config를 쓴다고 기본 파일을 자동으로 대체하는 것도 아니다. curl의 --config 설명 (새 탭에서 열림)
같은 실험에서 별도 파일 explicit.cfg에 다음 한 줄을 저장했다. 기본 파일의 X-Lab: default는 그대로 두었다.
header = "X-Lab: explicit"
이 파일이 있는 작업 폴더에서, 같은 $url에 아래 두 요청을 보냈다. 직접 확인할 때도 ./explicit.cfg가 실제로 존재해야 하며 $curlExe와 $url은 앞에서 정한 값을 사용한다.
& $curlExe -q -sS --config './explicit.cfg' --noproxy '*' --connect-timeout 1 --max-time 3 $url
& $curlExe -sS --config './explicit.cfg' --noproxy '*' --connect-timeout 1 --max-time 3 $url
첫 요청은 X-Lab=explicit, 두 번째는 X-Lab=default,explicit를 반환했다. 두 요청 모두 종료 코드는 0이었다. 두 번째 응답의 쉼표는 수신기가 두 X-Lab 헤더 값을 이어서 보여 준 표기다. 실제 요청에는 같은 이름의 헤더가 두 줄 있었다.
즉, 첫 -q는 자동으로 들어오던 default를 제외했지만 명시적으로 요청한 explicit는 남겼다. 스크립트에 이미 --config가 있다면 그 파일도 확인해야 한다. 이번에 실행한 범위는 Windows curl 8.21.0의 합성 헤더와 loopback HTTP 요청이다. 개인 curlrc나 자격 증명은 읽지 않았으며, Linux·macOS의 실제 파일 탐색은 실행하지 않았다.