...
Curl (Client URL)
curl(client url) 명령어는 프로토콜들을 이용해 URL 로 데이터를 전송하여 서버에 데이터를 보내거나 가져올때 사용하기 위한 명령줄 도구 및 라이브러리이다. 쉽게말해 예를들어 자바스크립트 환경에서 REST API(http)를 테스트하고싶다면 보통 ajax, fetch 를 이용해 요청을 보내는 것과 같이, SHELL(커맨드라인 환경)에서 REST API(http) 테스트 하고 싶으면 curl 명령어를 이용하면 된다 라고 이해하면 된다.
이밖에 HTTP / HTTPS / FTP / LDAP / SCP / TELNET / SMTP / POP3 등 다양하고 주요한 프로토콜을 지원하며 Linux/Unix 계열 및 Windows 등 주요한 OS 에서 구동되므로 여러 플랫폼과 OS에서 유용하게 사용할 수 있다. 이렇게 다양하고 강력한 기능을 가진 옵션들을 제공하지만, 보통 특정 서버에서 빠르게 방화벽 예외 상태를 테스트 하거나, REST 서비스 테스트를 위해 사용되는 편이다.
Curl 설치
Linux나 Mac OS 에는 curl 명령어 패키지가 기본 탑재되어 있다. Window에서도 설치하여 사용할수 있지만 일반적으로 윈도우에는 편히라게 사용 가능한 tool이나 Postman과 같은 프로그램들이 많기 때문에 잘 사용하지 않는 편이긴 하다.
리눅스
# 우분투
$ sudo apt update
$ sudo apt install curl
# CentOS
$ sudo yum install curl
윈도우
curl 버전 확인
$ curl -V
Curl 명령어 사용법
Curl 명령어 옵션
특정 URL을 대상으로 동작하며 URL 앞에는 curl의 옵션을 사용하면 된다.
curl 명령의 옵션은 하이픈 하나(-)로 시작하는 short 형식과 하이픈 두개(--)로 시작하는 long 형식 모두 지원한다.
$ curl [options...] <url>
$ curl --help all # 전체 명령어 보기
short 형식 | long 형식 | 설명 |
-k | --insecure | https 프로토콜에서 SSL 인증서에 대한 검증없이 연결 |
-i | --head | HTTP 헤더만 보여주고 컨텐츠는 표시하지 않음 |
-D | --dump-header <file> | HTTP 헤더를 file에 기록 (덤프) |
-L | --location | HTTP 301, 302 응답을 받은 경우 리디렉션 URL로 따라간다. --max-redirs 옵션 뒤에 숫자로 몇 번의 리디렉션까지 따라갈 것인지를 적을 수 있다. 기본 값은 50이다. |
-d | --data | HTTP POST 요청 데이터 입력 |
-J | --remote-header-name | 헤더에 있는 파일 이름으로 다운로드 파일을 저장 |
-o | --output FILE | curl로 받아온 내용을 FILE 이라는 이름의 파일로 저장 |
-O | --remote-name | 파일 저장시 리모트에 저장되어 있던 이름을 그대로 가져와서 로컬에 저장 |
-s | --silent | 진행 내용이나 메시지들을 출력하지 않음 HTTP response code 만 가져오거나 할 경우 유리 |
-X | --request | 요청시 사용할 메소드의 종류 (GET, POST, PUT, PATCH, DELETE) |
-i | --include | 응답에 Content 만 출력하지 않고 서버의 Reponse 도 포함해서 출력한다. (디버깅에 유용) |
-A | --user-agent | 서버에 User-Agent <name> 보내기 |
-u | --user | 서버 사용자 및 비밀번호 |
-T | --upload-file | 로컬 FILE 을 대상으로 전송 |
-f | --fail | HTTP 오류 시 자동으로 실패 (출력 없음) |
-G | 전송할 사이트 url 및 ip 주소 | |
-H | 전송할 헤더를 지정 | |
-J | --remote-header-name | 어떤 웹서비스는 파일 다운로드시 Content-Disposition Header 를 파싱해야 정확한 파일이름을 알 수 있을 경우가 있다. -J 옵션을 주면 헤더에 있는 파일 이름으로 저장한다. |
-v | --verbose | 동작하면서 자세한 헤더 통신 옵션을 출력한다. |
-C | --continue-at | 파일 다운로드 재개 |
Curl http 메서드
GET 요청
- 터미널 창에 example.com 홈페이지의 소스 코드를 인쇄
- 프로토콜을 지정하지 않은 경우, curl은 사용할 프로토콜을 추측하려고 시도하며, 이 프로토콜은 HTTP로 기본 설정
- 아무 옵션을 적지 않은 경우 기본적으로 GET으로 동작
$ curl www.example.com
$ curl -X GET www.example.com
# GET방식은 Body 없음
# -X 요청메소드 종류 명시
POST 요청
- -d 옵션으로 body 파라미터를 앞에 쓰고, 그 뒤에 POST를 처리하는 주소를 넣는다.
- 파라미터는 무조건 먼저 인코딩 된 상태여야 한다.
- POST의 기본 Content-Type 은 application/x-www-form-urlencoded 이다.
# url 형식 데이터
$ curl -d "key1=value1&key2=value2" \
-H "Content-Type: application/x-www-form-urlencoded" \
-X POST http://localhost:8000/data
# -d 옵션으로 body 데이터를 기재
# -H 옵션으로 전송할 헤더 지정 (디폴트 : application/x-www-form-urlencoded)
# -X 옵션으로 POST 메소드 지정하고 요청할 url명시
# JSON 형식 데이터
$ curl -d '{"key1":"value1", "key2":"value2"}' \
-H "Content-Type: application/json" \
-X POST http://localhost:8000/data
# 파라미터값을 파일로 지정해서 보내기
curl -d "@data.txt" -X POST http://localhost:3000/data
curl -d "@data.json" -X POST http://localhost:3000/data
PUT 요청
$ curl -X PUT -d 'name=inpa&email=inpa@gmail.com' http://localhost:8080/user/100
$ curl -X PUT -H "Content-Type: application/json" -d '{"name":"inpa","email":"inpa@gmail.com"}' http://localhost:8080/user/100
# 파일명으로 PUT
$ curl -T filename.txt http://www.example.com/dir/
DELETE 요청
$ curl -X DELETE http://localhost:8080/user/100
Curl http 헤더
헤더 보기
- -I : 헤더만 가져오기
- -i : 헤더와 바디까지 가져오기
# 헤더정보 보기 -I
$ curl -I google.com
HTTP/1.1 302 Found
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Location: http://www.google.co.kr/?gfe_rd=cr&ei=NKoMV5TZCILD8AfCsqToCw
Content-Length: 261
Date: Tue, 12 Apr 2016 07:56:36 GMT
# 헤더 + 본문 보기 -i
$ curl -i google.com
HTTP/1.1 302 Found
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Location: http://www.google.co.kr/?gfe_rd=cr&ei=gqoMV9mPLczU8AefxoxA
Content-Length: 259
Date: Tue, 12 Apr 2016 07:57:54 GMT
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="http://www.google.co.kr/?gfe_rd=cr&ei=gqoMV9mPLczU8AefxoxA">here</A>.
</BODY></HTML>
요청/응답 진행 상황을 자세히 출력
- -v 옵션은 상세 모드를 활성화하고 세부 정보를 인쇄
- 더 자세한 정보를 필요한 경우 --trace 옵션을 사용
--trace 옵션은 주어진 파일에 대한 모든 수신/발신 데이터의 전체 추적 덤프를 활성화 - 상세 및 추적 옵션은 어떤 이유로 인해 curl 이 실패하고 원인 파악할 때 유용
$ curl -v www.example.com
Referer 지정
$ curl -e http://리퍼러주소 daniel.haxx.se
User Agent 지정
# Firefox 60을 에뮬레이트하는 경우
curl -A "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0" https://getfedora.org/
쿠키(Cookies) 보내기
- 원격 리소스에 액세스하거나 문제를 디버깅하기 위해 특정 쿠키를 사용하여 HTTP 요청을 해야 하는 경우
- 기본적으로 Curl이 있는 리소스를 요청할 때 쿠키는 전송되거나 저장되지 않는다.
- 서버로 쿠키를 보내려면 -b 스위치 다음에 쿠키 또는 문자열이 들어 있는 파일 이름을 사용
# Cookie key=value 쌍을 서버로 전송
curl -b "name=inpa" www.cookiesite.com
# headers_and_cookies 파일로 헤더 정보다 모두 저장
# 헤더 정보에는 쿠키 정보도 포함되어 있다.
$ curl -D headers_and_cookies www.cookiesite.com
# stored_cookies 파일에 저장된 쿠키 내용을 서버로 전송
$ curl -b stored_cookies www.cookiesite.com
# 서버에서 전송한 쿠키를 리다이렉트하면서 서버측에 재전송
$ curl -b "name=inpa" -L www.cookiesite.com
# -b cookies.txt 는 이미 존재하는 쿠키 파일(Mozilla 호환)을 읽어서 서버에 전송
# -c newcookies.txt 는 새로 새성된 쿠키를 파일로 저장
$ curl -b cookies.txt -c newcookies.txt www.cookiesite.com
HTTP 위치 헤더를 따르기 (Redirect)
- curl은 기본적으로 Redirect Header를 무시한다.
- -L 을 붙이면 redirect 요청을 따라서 다음 페이지로 간다.
- -d/-F 옵션을 통해 POST/PUT 요청등을 보내고 나서 redirect가 실행된다면 첫번째 요청은 POST/PUT으로 처리하고, 리다이렉트는 GET으로 처리한다.
요청된 웹 페이지가 다른 위치로 이동하면 HTTP 위치 헤더가 응답으로 전송되고 실제 웹 페이지가 있는 위치가 포함되게 된다. 예를 들어, 누군가가 한국에서 브라우저에 google.com 을 입력하면 자동으로 google.co.kr 로 리다이렉션되는데, 아래와 같이 HTTP 위치 헤더를 기반으로 수행되게 된다.
$ curl http://www.google.com
<TITLE>302 Moved</TITLE>
<H1>302 Moved</H1>
The document has moved
<A HREF="http://www.google.co.kr/">here</A>
위의 출력은 요청된 문서가 http://www.google.co.kr 로 이동되었음을 나타낸다.따라서 -L 옵션을 사용하여 리다이렉션을 따르도록 curl 을 사용할 수 있다.
$ curl -L http://www.google.com # 리다이렉트 된 google.co.kr 의 html 소스 코드를 다운로드함.
Curl http 인증
자격증명 전달
- 간혹 웹사이트는 콘텐츠를 보기 위해 사용자 이름과 비밀번호를 요구함.
- 로그인을 해야 볼수 있는 페이지를 가져올때 사용된다고 보면 됨.
- -u 옵션을 사용하여 웹서버로 자격 증명을 전달할 수 있음.
$ curl -u username:password https://example.com/protected_page
username과 password 자격 증명이 헤더를 통해 웹 서버에 전달되고, 웹 서버는 해당 정보를 인증이 완료되면 응답하여 로그인이 필요한 페이지에 접근할 수 있게 된다.
이러한 방식으로 웹 서버에서 사용자 인증을 처리하는 것이 일반적이지만, 안전한 연결을 위해 HTTPS 프로토콜이 사용을 권장된다. HTTP 프로토콜을 사용하면 자격 증명이 암호화되지 않은 상태로 전달되므로 도청 등의 위험이 있기 때문이다. 따라서 가능한 경우 HTTPS 프로토콜을 사용하여 웹 페이지를 가져올 때 자격 증명을 전달하는 것이 좋다.
프록시 인증
- 프록시 서버를 통해 데이터를 전송하려면 -x(--proxy) 옵션을 선택한 다음 프록시 URL을 사용
- 프록시의 호스트와 포트를 지정해야 함.
# 192.168.44.1 포트 8888에서 프록시를 사용하여 지정된 리소스를 다운로드
$ curl -x 192.168.44.1:8888 http://linux.com/
# 서버에 인증이 필요한 경우 -U(--proxy-user) 옵션을 사용하고 사용자 이름과 암호를 콜론(user:password)으로 구분
$ curl -U username:password -x 192.168.44.1:8888 http://linux.com/
Curl 파일 요청
파일 업로드
- -F 폼필드명=@파일명
- -F 폼필드명=폼필드값
- 기본 Content-Type 은 multipart/form-data
$ curl -F upload=@파일명 -F press=OK www.xxx.com/blog/post.cgi
출력을 파일에 저장
- -o는 미리 정의된 파일 이름을 사용하여 파일을 저장
- -O는 파일을 원래 파일 이름으로 저장
- -o 옵션과 함께 curl 명령어를 실행하면 다운로드에 대한 진행률 표시기가 표시됨.
# gettext.html 페이지가 mygettext.html 이라는 파일에 저장
$ curl -o mygettext.html http://www.gnu.org/software/gettext/manual/gettext.html
# 로컬 시스템에 gettext.html 이라는 파일 자체에 내용이 저장
$ curl -O http://www.gnu.org/software/gettext/manual/gettext.html
# 출력 재지정 연산자로 파일 저장
$ curl http://www.gnu.org/software/gettext/manual/gettext.html > mygettext.html
여러 파일 다운로드
- 여러 파일을 한 번에 다운로드하려면 여러 -O 옵션과 다운로드하려는 파일의 URL을 차례로 사용
$ curl -O URL1 -O URL2
$ curl -O http://mirrors.edge.kernel.org/archlinux/iso/2018.06.01/archlinux-2018.06.01-x86_64.iso \
-O https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-9.4.0-amd64-netinst.iso
# 범위 지정 - foo0.txt 부터 foo9.txt 파일 다운 받기
$ curl -O http://example.com/foo[0-9].txt
# []는 여러 번 조합가능하고, foo-a0 ~ foo-z9까지의 파일 다운
$ curl -O http://example.com/foo-[a-z][0-9].txt
# 중괄호 {}를 써서 foo.txt, bar.txt, baz.txt를 다운
$ curl -O http://example.com/{foo,bar,baz}.txt
for 문으로 여러 파일 다운로드
$ files="foo bar baz" # files 라는 환경변수에 파일명 할당
$ for name in $files; do
> curl -O "http://example.com/${name}.txt"
> done
# => files에 파일명 할당하고 for문으로 순회하면서 ${name}에 값 전달하여 다운
다운로드 다시 시작
- -C 옵션을 사용하여 다운로드를 재개
- 이 기능은 대용량 파일을 다운로드하는 동안 연결이 끊긴 경우 유용하며 처음부터 다운로드를 시작하는 대신 이전 파일을 계속할 수 있다.
$ curl -O http://releases.ubuntu.com/18.04/ubuntu-18.04-live-server-amd64.iso
# ... 다운로드 중
# 갑자기 인터넷이 불안정 하여 연결이 끊김
$ curl -C - -O http://releases.ubuntu.com/18.04/ubuntu-18.04-live-server-amd64.iso
# 다운로드 재개
최대 전송 속도를 지정
- --limit-rate 옵션을 사용하면 데이터 전송 속도를 제한
- 값은 바이트, k 접미사로 킬로바이트, m 접미사로 메가바이트, g 접미사로 기가바이트로 표현
- 이 옵션은 컬이 사용 가능한 모든 대역폭을 소비하는 것을 방지하는 데 유용
# 데이터 전송을 초당 1000 바이트로 제한
$ curl --limit-rate 1000B -O http://www.gnu.org/software/gettext/manual/gettext.html
# 다운로드 속도를 1MB로 제한
$ curl --limit-rate 1m -O https://dl.google.com/go/go1.10.3.linux-amd64.tar.gz
Curl 이밖의 프로토콜
SMTP로 메일 전송
- 발신자 주소, 수신자 주소 메일서버 IP 주소를 지정하고 email.txt 파일을 메일 전송
curl smtp://mail.example.com --mail-from myself@example.com --mail-rcpt \
receiver@example.com --upload-file email.txt
FTP로 파일을 전송
- FTP 서버에 액세스하려면 -u 옵션을 사용하고 아래 그림과 같이 사용자 이름과 암호를 지정
# 로그인하면 사용자의 홈 디렉토리에 있는 모든 파일과 디렉터리가 나열
$ curl -u FTP_USERNAME:FTP_PASSWORD ftp://ftp.example.com/
# FTP 서버에서 단일 파일을 다운로드
$ curl -u FTP_USERNAME:FTP_PASSWORD ftp://ftp.example.com/file.tar.gz
# -T 옵션을 사용해 파일을 FTP 서버에 업로드
$ curl -T newfile.tar.gz -u FTP_USERNAME:FTP_PASSWORD ftp://ftp.example.com/
# 범위를 사용하여 나열/다운로드. 범위가 지정되면 범위 내에서 일치하는 파일이 다운로드. 패키지 다운로드 할때 유용
$ curl ftp://ftp.uk.debian.org/debian/pool/main/[a-z]/
Curl 재밌는 명령어
내 공인 IP 조회
$ curl ifconfig.me
날씨 조회
$ curl http://wttr.in/Seou
달 상태 조회
$ curl http://wttr.in/Moon@연도-월-일
$ curl http://wttr.in/Moon@2022-06-17
wget / curl 명령어 차이점
$ curl -X GET http://127.0.0.1:8080/animal
$ curl -X POST http://127.0.0.1:8080/animal
$ curl -d 'cat,dog' -H "Content-Type: application/text" -X POST http://127.0.0.1:8080/animal
$ wget GET http://127.0.0.1:8080/animal
$ wget POST http://127.0.0.1:8080/animal
$ wget -O- --post-data='cat,dog' --header='Content-Type:application/text' 'POST http://127.0.0.1:8080/animal'
wget / curl 공통점
- HTTP, HTTPS, FTP 프로토콜을 통해 컨텐츠를 다운로드 하는 커맨트 라인 툴
- HTTP POST request 를 지원
- HTTP 쿠키를 지원
- 스크립트처럼 사용자 인터렉션없이 수행될 수 있도록 설계
- 오픈소스이며 무료90년대에 시작한 프로젝트 (wget 은 1995년, curl 은 1996년에 시작)metalink 를 지원
wget / curl 차이점
wget
- 간단하고 직관적 (만약, 별다른 옵션없이 컨텐츠를 조금 더 빠르게 다운로드하려고 한다면 wget 이 적합)
- 별도의 라이브러리를 지원하지 않음
- 재귀적으로 다운로드즉, 페이지에 있는 모든 내용이나 FTP 디렉터리에 있는 모든 파일들을 한 번에 그대로 복사
- curl 에 비하여 더 오래되었음
curl
- 복잡한 컨텐츠를 다운로드 하려고 한다면 wget 보다는 curl 이 적합
- libcurl 라이브러리로 더 강력한 기능들을 추가/사용할 수 있음
- stdin 또는 stdout 의 pipe 를 이용하는 전통적인 unix 스타일의 방식도 지원
- LDAP 이나 Samba 공유도 지원양방향 (wget 은 일반 HTTP POST request 만 지원)
- SSL 을 지원gzip 압축 및 해지를 지원
# 참고자료
https://www.tecmint.com/linux-curl-command-examples/
https://reconshell.com/curl-command-in-linux/
https://koromoon.blogspot.com/2021/12/curl.html
https://gist.github.com/moalex/4a9e5df71407d368ec4be2a6e7ca8460
https://ohgyun.com/397
https://wooono.tistory.com/279
https://hbase.tistory.com/224
이 글이 좋으셨다면 구독 & 좋아요
여러분의 구독과 좋아요는
저자에게 큰 힘이 됩니다.