cURL (client URL) 은 오픈소스 커맨드 라인 툴로, 서버간에 데이터를 전송할 때 사용합니다. 저는 주로 웹 서비스의 method들을 테스트 할 때나 웹에서 간단하게 파일을 다운로드 받을 때 많이 사용했었는데, 실제로는 HTTP, HTTPS 프로토콜 이외에도 FTP, SCP, SMB, LDAP, IMAP, SMTP 등을 포함한 상당수의 인터넷 프로토콜을 지원한다고 합니다.
기본 사용법
cURL은 대부분의 리눅스와 윈도우(10 이후), MacOS에도 기본으로 설치가 되어 있기 때문에 범용적으로 사용이 가능합니다. 터미널을 열어서 "curl --help"를 입력해보면, 주로 사용하는 옵션에 대한 설명이 나옵니다. 전체 옵션을 보고 싶다면 "curl --help all" 을 입력하면 됩니다. 참고로 Windows Powershell에서는 커맨드를 wrapping 하기 때문에 조금 사용법이 다릅니다. 다음 섹션부터 기본적인 http(s) 요청을 테스트하는 방법에 대해서 알아보겠습니다.
GET
cURL에서 아무런 옵션없이 URL을 입력하면 GET 방식의 요청으로 인식됩니다.
아래 요청은 www.google.com 에 GET 방식으로 해당 URL의 데이터를 가지고 옵니다.
> curl https://www.google.com
실제로 실행을 해보면, google.com 의 html 소스 코드가 화면에 텍스트 형태로 출력됩니다.
POST
POST 방식으로 데이터를 요청하기 위해서는 -X 옵션을 사용합니다.
ex)
> curl -X POST http://localhost:3000/data
보통 POST 방식으로 데이터를 요청할 때는, header나 request body (payload) 등의 데이터를 같이 전송하게 됩니다. 각각 -H, -d 옵션으로 추가할 수 있습니다.
ex)
> curl -X POST -d "param1=value1¶m2=value2" -H "Content-Type: application/x-www-form-urlencoded" http://localhost:3000/data
데이터 (-d) 옵션은 여러 개로 나눠서 쓸 수 있습니다. 이 때 전송되는 데이터는 "&" 로 연결이 되어서 전송됩니다. 즉, 아래 요청과 바로 위에서 사용한 -d "param1=value1¶m2=value2" 요청은 같은 데이터로 요청이 됩니다.
> curl -X POST -d "param1=value1" -d "param2=value2" -H "Content-Type: application/x-www-form-urlencoded" http://localhost:3000/data
request body 가 json 형태인 경우 아래와 같이 사용하면 됩니다.
ex)
> curl -X POST -d "{\"key1\": \"value1\", \"key2\": \"value2\"}" -H "Content-Type: application/json" http://localhost:3000/data
request body를 파일에서 읽어서 전송할 수도 있습니다. -d 옵션 혹은 -T 옵션을 사용할 수 있습니다.
ex)
> curl -X POST -d "@data.json" -H "Content-Type: application/json" http://localhost:3000/data
> curl -X POST -T data.json -H "Content-Type: application/json" http://localhost:3000/data
웹 페이지에서 폼 전송하는 것을 테스트하고 싶다면, -F 옵션을 사용합니다. 폼 데이터를 전송하게 되면 default 헤더는 multipart/form-data 로 변경이 됩니다.
> curl -F "username=testuser" -F "password=1234" -X POST http://localhost:3000/form
폼 전송으로 파일도 업로드 할 수 있습니다.
> curl -F "file1=@data.json" -X POST http://localhost:3000/form
그 외의 옵션들
cURL 옵션은 상당히 많기도 하고, 조합해서 사용할 수 있기 때문에 모두 기술하는 것은 시간낭비가 될 것 같아서, 자주 쓰이거나 유용한 옵션에 대해서 이야기 해 보겠습니다.
Option | Option (long) | 기능 |
-k | --insecure | https 프로토콜 사용시 안전하지 않은 연결도 허용 |
-I | --head | 화면 출력시 헤더만 출력 |
-i | --include | 화면 출력시 헤더 및 내용 출력 |
-O | --remote-name | 내용을 remote file 이름으로 저장 |
-o | --output <file> | 내용을 지정한 파일 이름으로 저장 |
-v | --verbose | 전송 내용을 상세히 출력 |
-V | --version | cURL 버전 내용 출력 |
-u | --user <user:password> | 유저 / 패스워드 전송 |
-s | --silent | Slient 모드, 다운로드시 전송 정보를 화면에 출력하지 않음 |
-L | --location | redirect 추적 - L 옵션이 없으면 서버에서 redirect 되는 경우 컨텐츠를 받아오지 않음 |
-b | --cookie <data|filename> | 쿠키 정보 전송 |
-C | --continue-at <offset> | 특정 위치에서부터 이어서 전송 |
파일 다운로드 하기
웹 서버의 URL에서 파일을 다운로드 받아야 한다면 다음과 같이 쓸 수 있습니다. (옵션은 연결가능..)
> curl -LOk http://localhost:3000/filename
원하는 경로에 원하는 이름으로 파일을 지정해서 저장하고 싶다면 -o 옵션을 사용합니다. (파일 이름만 지정해도 됨)
> curl -Lk -o filefullpath http://localhost:3000/filename
서버에서 redirect 하지 않는 경우에는 L 옵션을 생략 가능하지만, 갑자기 컨텐츠 다운로드가 안되서 당황하는 경우를 피하고 싶다면 그냥 LOk 옵션을 기억해 두는 편이 나을 듯 합니다.
SFTP / SCP 프로토콜 이용하기
cURL은 sftp 나 scp 등의 프로토콜도 지원하는데요, 이 섹션에서 어떻게 사용하는 지 간단히 알아보겠습니다.
ssh 서비스가 활성화되어 있다고 가정하고 아래와 같이 접속해 봅니다. 참고로 sftp와 scp 는 ssh 기반의 프로토콜이기 때문에, ssh 서비스가 활성화되어 있으면 사용이 가능합니다.
> curl sftp://localhost -u <username>
접속을 시도하면 password를 입력하는 프롬프트가 나오고, password를 입력하면 다음 단계로 넘어갑니다.
만약 localhost에 ssh로 접속한 적이 없다면.. 아래와 같은 에러 메시지를 보게 될 것입니다.
remote 서버가 known_hosts에 등록되어 있지 않아서 생기는 문제인데요.. 시스템 정책상 ssh, scp 등에서만 ~/.ssh/known_hosts 파일을 편집할 수 있는 권한이 있어서 그렇다고 합니다.
해결책 방법은 ssh 로 한번 접속해서 remote 서버를 등록해주면 됩니다.
> ssh localhost
아마 아래와 비슷한 메시지가 나올거고, yes를 입력하면 remote 서버가 known_hosts 에 등록됩니다.
remote 서버를 등록할 수 없는 상황이라면.. -k 옵션을 사용하면 됩니다. 위에서 설명한 -k 옵션은 insecure 를 의미하기 때문에 등록되지 않아 신뢰할 수 없는 서버도 그냥 접속하겠다라는 의미입니다.
> curl sftp://localhost -ku <username>
기본적으로 curl sftp 로 접속을 하게 되면 sftp 루트의 파일 리스트를 출력해 줍니다. 만약 특정 경로의 파일 리스트를 보고 싶다면 아래와 같이 입력하면 되는데, 끝에 "/"를 붙여 주셔야 합니다.
> curl sftp://localhost/home/<username>/ -ku <username>
그리고 해당 경로에 있는 파일을 다운로드 하려면 파일 경로를 지정해 주면 되고, 파일로 저장할 경우 -o (파일 경로를 지정 해서 저장) 혹은 -O (remote 서버의 파일이름으로 저장) 옵션을 사용하면 됩니다.
> curl sftp://localhost/home/<username>/test.txt -kOu <username>
마지막으로 보안상 좋지는 않지만.. 꼭 필요하다면 아래와 같이 password를 붙여서 전송할 수 있습니다. 그러면 password를 물어보는 프롬프트가 나오지 않습니다.
> curl sftp://localhost/home/<username>/test.txt -kOu <username>:<password>