curl 설치 및 사용법 - HTTP GET/POST, REST API 연계등

이 페이지 내용이 너무 많아져서 curl 주요 사용법 요약 에 주요 내용만 축약했습니다. 

Web 에서 파일을 다운받을 경우 wget 이 더 사용이 간편합니다.


개요

curl 은 command line 용 data transfer tool 이다. download/upload 모두 가능하며 HTTP/HTTPS/FTP/LDAP/SCP/TELNET/SMTP/POP3 등 주요한 프로토콜을 지원하며 Linux/Unix 계열 및 Windows 등 주요한 OS 에서 구동되므로

여러 플랫폼과 OS에서 유용하게 사용할 수 있다. 또 libcurl 이라는 C 기반의 library 가 제공되므로 C/C++ 프로그램 개발시 위의 protocol 과 연계가 필요하다면 libcurl 을 사용하여 손쉽게 연계할 수 있다.

libcurl은 PHP, ruby, PERL 및 여러 언어에 바인딩되어 있으므로 사용하는 언어나 개발환경에 맞게 libcurl 을 사용할 수 있다.
 

설치

Linux나 Mac OS X 에는 기본 탑재되어 있다. Windows는 build 된 바이너리를 설치해도 되고 compiler 가 있다면 소스를 받아서 직접 빌드해도 된다.(curl windows 에서 빌드하기 참조)

Windows 버전은 cygwin나 MinGW 로 빌드한거 보다는 VIsual Studio 로 빌드한 버전을 다운받는게 좋다. (Win32-Generic, Win64 - Generic 항목에서 받으면 되며 추천하는 링크는 https://winampplugins.co.uk/curl/ 이다.) 

CentOS/RHEL 계열에서 최신 버전 설치는 RHEL/CentOS 6 에서 curl 최신 버전 설치 문서를 참고하자.


주요 옵션

curl [options...] <url> 형식으로 사용하면 된다.

option 처리는 GNU getopt 를 사용하므로 하이픈 하나를 붙이는 short 형식의 옵션과 하이픈 두개로 시작되는 long 형식의 options 이 있다. 

주요 options (http/https 관련 옵션만 정리)

shortlong설명비고
-k--insecurehttps 사이트를 SSL certificate 검증없이 연결한다.wget 의 --no-check-certificate 과 비슷한 역할 수행
-l--headHTTP header 만 보여주고 content 는 표시하지 않는다
-D--dump-header <file><file> 에 HTTP header 를 기록한다.
-L--location

서버에서 HTTP 301 이나 HTTP 302 응답이 왔을 경우 redirection URL 로 따라간다.

--max-redirs 뒤에 숫자로 redirection 을 몇 번 따라갈지 지정할 수 있다. 기본 값은 50이다

curl -v daum.net 을 실행하면 결과값으로 다음과 같이 HTTP 302 가 리턴된다.

< HTTP/1.1 302 Object Moved
< Location: http://www.daum.net/

-L 옵션을 추가하면 www.daum.net 으로 재접속하여 결과를 받아오게 된다.

-d--dataHTTP Post dataFORM 을 POST 하는 HTTP나 JSON 으로 데이타를 주고받는 REST 기반의 웹서비스 디버깅시 유용한 옵션이다
-v--verbose 동작하면서 자세한 옵션을 출력한다.
-J--remote-header-name어떤 웹서비스는 파일 다운로드시 Content-Disposition Header 를 파싱해야 정확한 파일이름을 알 수 있을 경우가 있다. -J 옵션을 주면 헤더에 있는 파일 이름으로 저장한다.curl 7.20 이상부터 추가된 옵션
-o--output FILEcurl 은 remote 에서 받아온 데이타를 기본적으로는 콘솔에 출력한다. -o 옵션 뒤에 FILE 을 적어주면 해당 FILE 로 저장한다. (download 시 유용)
-O--remote-namefile 저장시 remote 의 file 이름으로 저장한다. -o 옵션보다 편리하다.
-s--silent정숙 모드. 진행 내역이나 메시지등을 출력하지 않는다. -o 옵션으로 remote data 도 /dev/null 로 보내면 결과물도 출력되지 않는다HTTP response code 만 가져오거나 할 경우 유리
-X--request

Request 시 사용할 method 종류(GET, POST, PUT, PATCH, DELETE) 를 기술한다.


-i--include응답에 Content 만 출력하지 않고 서버의 Reponse 도 포함해서 출력한다. (디버깅에 유용)

HTTP/HTTPS Download(GET Method)

HTTP로 다운로드

다운로드 받은 파일을 콘솔로 출력
curl http://www.gnu.org/software/bash/manual/html_node/index.html
지정한 이름으로 저장
curl -o index.html http://www.gnu.org/software/bash/manual/html_node/index.html
서버의 filename 으로 저장
curl -O  http://www.gnu.org/software/bash/manual/html_node/index.html
여러 url 에서 동시에 다운로드
curl -O  http://www.gnu.org/software/bash/manual/html_node/index.html -O http://www.gnu.org/savannah-checkouts/gnu/libiconv/documentation/libiconv-1.13/iconv.1.html

이어받기

-C/--continue-at  <offset> 옵션을 주면 이어받기 가능(offset 에 - 를 주면 전송이후 부분부터 이어받음)

이어 받기
curl -C - -O  http://www.gnu.org/software/bash/manual/html_node/index.html

특정일 이전/이후 변경되었으면 받기

 -z/--time-cond <time>

HTTP 헤더에 If-Modified-Since: 헤더를 추가하여 특정일 이후에 변경되었으면 다운로드 수행

아래 예제는 2011년 12월 21일 이후에 변경되었으면 다운로드 수행

curl -z 21-Dec-11 http://www.example.com/yy.html

날자앞에 - 를 추가하면 If-Unmodified-Since: 헤더를 추가하여 특정일 이전에 변경되었으면 다운로드 수행

아래 예제는 2011년 12월 21일 이전에 변경되었으면 다운로드함 (날자에 - 추가)

curl -z -21-Dec-11 http://www.example.com/yy.html

http 응답 코드만 출력

HTTP Header 나 contents 는 빼고 HTTP Response code 만 출력한다. 서버의 정상 작동 여부 점검때 유용하다.

curl -L -k -s -o /dev/null -w "%{http_code}\n" http://www.example.com/yy.html

서버의 정상 동작 여부를 점검할 경우 SSL 인증서 검증 제외(-k) 와 301, 302 Redirect 시 따라 가는 옵션(-L)을 추가하는 것이 안전하다.


이를 활용하여 아래처럼 간단한 스크립트로 웹 서버의 정상 동작 여부를 확인할 수 있다.

 Click here to expand...


결과값에 HTTP Header 포함(-i)

-i ,–include 옵션을 사용하면 서버의 응답에 서버가 보낸 HTTP 헤더를 추가하여 출력한다. 디버깅에 유용한다.

curl -i https://api.github.com -u valid_username:valid_password


jq 와 연동해서 서버의 JSON 파싱

명령행 json 처리기인 jq 를 연동해서 서버의 JSON 응답을 보기 좋게 파싱

jq 와 연동
curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5' | jq .


배열로 넘어온 응답중 첫 번째 원소 추출

jq 와 연동
curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5' | jq '.[1]'

HTTP 인증

Basic Auth

id/pwd 가 필요한 사이트의 경우 -u(–user) 옵션 뒤에 userid:password 를 지정하여 인증할 수 있다.

curl -v -u userid:password http://www.example.com/user.html

Bearer token 인증

OAuth 나 JWT 등에 사용하는 Bearer token 을 사용하려면 -H 옵션뒤에  'Authorization: Bearer {TOKEN}' 를 추가하며 {TOKEN} 은 실제 토큰으로 변경하면 된다.

아래는 12345 라는 token 에 서버에 전송하는 예제이다.

curl -v -L  -X POST -H 'Accept: application/json' -H 'Authorization: Bearer 12345' 'https://www..example.com/api/myresource'

POST/File Upload(POST, PUT)

File Upload(PUT)

-T, --upload-file 옵션을 사용하면 서버에 파일을 전송할 수 있음. 아래는 a.pdf 를 서버에 전송하는 예제

curl -T a.pdf http://posttestserver.com/post.php

-T 로 파일을 전송하면 POST 가 아닌 PUT Request 로 처리함.


직접 PUT 으로 method 를 실행할 경우  -X PUT 옵션을 추가해서 URL 을 호출.

curl -L -X PUT 'https://postman-echo.com/put' \
--data-raw 'This is expected to be sent back as part of response body.'


HTTP FORM POST 

-X POST 옵션을 추가하거나 -d( --data) 옵션을 지정하면 기본값으로 POST 로 설정됨

FORM 파일
<form method="POST" action="post.php">
    <input type=text name="first_name">
    <input type=text name="last_name">
    <input type=submit name=press value=" OK ">
 </form>

POST 데이타는 "param1=value1&param2=value2" 형식으로 전달

curl -d "first_name=Bruce&last_name=Wayne&press=%20OK%20" http://posttestserver.com/post.php


데이타에 공백이나 기타 특수 문자가 있을 경우 URL encoding 을 해야 한다.

공백일 경우 일일이 + 로 변환해서 전송해야 하지만 최신 버전의 curl(7.18.0 이후) 은 FORM 파라미터를 URL Encoding 해주는 --data-urlencode 옵션을 사용하면 별도로 인코딩을 해주지 않아도 된다.

curl --data-urlencode "first_name=Bruce" --data-urlencode "last_name=Wayne" --data-urlencode "press= OK " http://posttestserver.com/post.php

Hidden field 전송시 일반 필드처럼 name=value 형식으로 전송하면 된다.

HTTP POST data

-d, --data 옵션뒤에 전송할 데이타를 기술

curl -L -v -d '{"name": "superman", "age" : 30}' -H "Accept: application/json" -H "Content-Type: application/json" http://posttestserver.com/post.php

-d 옵션을 추가하면 -X POST 는 제외 가능


HTTP POST File

file을 POST할 경우 file name 앞에 @ 를 붙여줌 

curl -d @myPostfile http://posttestserver.com/post.php

HTTP POST Binary File

curl 은 POST 시 데이타를 text 로 취급하므로 binary 데이타는 깨질 수 있다. 제대로 전송하려면 --data-binary 옵션을 추가해야 한다.

curl --data-binary @myBinary.jpg http://posttestserver.com/post.php

HTTP File Upload Form

다음과 같은 파일 업로드 FORM 이 있을때

<form method="POST" enctype='multipart/form-data' action="upload.php">
 <input type=file name=upload>
 <input type=submit name=press value="OK">
</form>

localfilename 은 upload 할 파일명, submit 은 press=OK

curl --form upload=@localfilename --form press=OK http://localhost/upload.php

PATCH, DELETE 메서드

PATCH

Remote 에 있는 Resource 의 전체를 교체하는 PUT 과는 달리 일부 항목만 교체할 때 사용하는 메서드로 -X PATCH 옵션을 추가해서 URL 호출.

curl -L -X PATCH 'https://postman-echo.com/patch' \
--data-raw 'This is expected to be sent back as part of response body.'

DELETE

Remote 에 있는 Resource 를 삭제할 때 주로 사용하며 보안 문제가 있으므로 서버는 권한있는 사용자의 호출인지 여부를 확인하고 처리해야 함.

client 는 -X DELETE 옵션을 추가해서 URL 호출.

curl -L -X DELETE 'https://postman-echo.com/delete' \
--data-raw 'This is expected to be sent back as part of response body.'

HTTP Header 설정

특정한 HTTP Header 를 설정해서 보내야 할 경우(Ex: json data등) -H (–header) 옵션으로 헤더를 설정할 수 있다.

Content-Type Header 설정

curl -d @myJson.js -H "Content-Type: application/json" http://localhost:8080/jsonEcho

User-Agent 설정

특정 브라우저인(Browser) 것처럼 동작하기 위해서는 -A ( --user-agent) 옵션을 사용할 수 있다. (http://www.useragentstring.com/)


User-Agent Chrome 24.0

Chrome 24.0 으로 User-Agent 설정
curl -d @myJson.js -H "Content-Type: application/json" --user-agent "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.14 (KHTML, like Gecko) Chrome/24.0.1292.0 Safari/537.14" http://localhost:8080/jsonEcho


User-Agent MSIE(Internet Explorer) 10.0

IE 10.0
curl -d @myJson.js -H "Content-Type: application/json" --user-agent "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)" http://localhost:8080/jsonEcho


User-Agent Firefox 29.0

Firefox 29.0
curl -d @myJson.js -H "Content-Type: application/json" --user-agent "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20120101 Firefox/29.0" http://localhost:8080/jsonEcho

Referer 설정

Referer 를 체크하는 사이트일 경우 -e (–referer) 옵션으로 Referer URL 을 설정할 수 있다.

curl --referer http://www.example.come/from  http://www.example.com/to

아니면 -H 옵션으로 referer 헤더를 지정해도 된다.

curl -H "Referer: http://www.example.come/from"  http://www.example.com/to

Accept-Encoding  으로 컨텐츠 압축 요청

전송 속도 향상을 위해 mod_deflate(apache httpd) 나 ngx_http_gzip_module 을 사용해서 컨텐츠를 압축할 수 있다. 웹 서버가 컨텐츠 압축을 사용하는지 확인하기 위해 curl 실행시 Accept-Encoding 헤더를 설정하면 된다.

curl -I -H 'Accept-Encoding: gzip,deflate' https://www.google.com


HTTP/1.1 200 OK
Date: Wed, 25 Jul 2018 08:29:02 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=UTF-8
P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
Content-Encoding: gzip
Server: gws

압축 여부는 Content-Encoding: gzip 헤더가 서버 response 에 포함되었는지 여부로 확인할 수 있다.

SSL/TLS 옵션

SSL/TLS 인증서 검증 설정

curl은 TLS 연결시 인증서의 유효성(신뢰된 인증기관에서 발급 여부, 인증서내 DN과 host이름  일치 여부, 유효 기간내에 있는지등)을 검증하지만 개발용 서버라 도메인이 없어서 self signed 인증서가 설치되었거나
유효 기간이 지났는데 갱신을 못 했거나 등의 이유가 있을 경우 요청이 실패하게 된다.


이런 경우 -k, --insecure 옵션을 사용하면 인증서 검증을 끄고 TLS 세션을 구성하게 된다.

curl -k -L http://www.example.come

일반적으로 -k 는 -L 과 같이 사용하는 것이 편리하다.


curl 에 인증 기관 인증서가 등록되지 않아서 검증 오류가 날 경우 curl 에 신뢰하는 인증기관 인증서(CA Cert) 추가하기 를 참고해서 인증서를 추가한다.

libcurl 을 사용할 경우 -k 옵션은 다음 2가지 옵션을 호출한 것과 동일(https://github.com/lesstif/php-jira-rest-client/blob/master/src/JiraClient.php#L206-L207) 참고

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);


TLS Version 지정

쿠키를 파일로 저장

파일로 저장할 경우 -c, --cookie-jar 옵션뒤에 쿠키를 저장할 파일명을 적어줌.

아래 예제는 cookiejar.txt 파일에 cookie 를 기록

curl -v -I  -c cookiejar.txt https://www.example.com


파일 또는 문자열에서 쿠키 읽기

 -b, --cookie 옵션을 사용하면 쿠키를 저장한 파일에서 읽거나 또는 직접 쿠키 값을 설정하여 HTTP 요청할 수 있음.


curl -v -I  -b cookiejar.txt https://www.example.com


쿠키 값 설정해서 전송

tomcat 이 사용하는 세션 쿠키인 JSESSIONID 를 설정해서 서버에 요청

curl -v -I  -b "JSESSIONID=8A39E226F2B6D4DC32CE0E8D" https://www.example.com

새로 세션 쿠키 생성

-b 옵션과 함께  -j, --junk-session-cookies 옵션을 사용하면 쿠키를 저장한 파일에서 세션 정보만 읽지 않으므로 새로 세션 쿠키를 생성할 수 있음.

curl -v -I  -b cookiejar.txt -j https://www.example.com


REST API 와 연계

위의 옵션들이 익숙해졌으면 REST 기반의 웹서비스를 개발할 때 curl 을 이용해서 테스트 및 디버깅을 수행할 수 있다. REST API 를 제공하는 유명한 Web App 와 연계하는 방법을 정리해 본다.

curl로 Atlassian JIRA REST API 연계하기


Sonatype nexus Admin API

관리자 암호 변경

curl -v -k -d "{"data":{"userId":"admin","oldPassword":"admin123","newPassword":"admin1234"}}" -u admin:admin123 https://my-nexus-site/nexus/service/local/users_changepw



See Also

Ref