상세 컨텐츠

본문 제목

Curl로 알아보는 HTTP 요청 메소드

Computer Science/Network

by Yongari 2023. 1. 7. 12:07

본문

 

HTTP 요청 메서드는 무엇인가?

 

HTTP(Hyper Text Transfer Protocol)는 요청 메서드를 정의하며 주어진 리소스에 수행하길 원하는 행동을 나타냅니다. 그래서 행동을 나타내기 때문에 "HTTP 동사" 라고 부르기도 합니다. 각각 메서드는 다른 의미를 구현하지만 일부 기능은 메서드 집합간에 서로 공유합니다.

 

예를 들면 응답 메서드는 안전하거나 캐시 가능하거나 멱등성을 가질 수 있습니다.

 

 

 

1. 안전한 HTTP 메서드는 무엇인가??

안전하다는 의미 : HTTP 메서드가 서버의 상태를 바꾸지 않으면 안전하다고 함, 다른 말로 읽기 작업만 한다는 것을 뜻함

예를 들면 GET, HEAD, OPTIONS가 안전함 그리고 모든 안전한 메서드는 멱등성을 가지지만, 모든 멱등성을 가진 메서드가 안전한 것은 아님, 예를 들면 PUT과 DELETE가 있음 각각의 메서드는 서버의 상태를 변경하는 메서드임

 

2. 그렇다면 멱등성은 대체 무엇인가??


멱등성이란  동일한 요청을 한 번 보내는 것과 여러 번 연속으로 보내는 것이 같은 효과를 지니고, 서버의 상태도 동일하게 남을 때, 해당 HTTP 메서드가 멱등성을 가졌다고 말합니다. 멱등성 메서드에는 통계 기록 등을 제외하면 어떠한 부수 효과(side effect)도 존재해서는 안됩니다. 올바르게 구현한 경우 GET, HEAD, PUT, DELETE 메서드는 멱등성을 가지며, POST 메서드는 그렇지 않습니다. 모든 안전한 메서드는 멱등성도 가집니다.

 

안전함 - MDN Web Docs 용어 사전: 웹 용어 정의 | MDN

안전함은 맥락에 따라 여러가지를 의미할 수 있습니다. 아래의 용어를 가리키는 경우도 있습니다.

developer.mozilla.org

 

위의 메서드를 좀 더 풀이해보자면 100번을 보내든 1번을 보내든 같은 결과를 가져야합니다. 

GET과 POST를 예로 들면

 

GET 으로 /test.html HTTP 1.1 로 요청을 보냈다고 하면 100번을 보내도 같은 응답만 받습니다. 그러나 

POST로 /add.html 로 100번 요청을 보내면 100번 다 html이 추가되는 식으로 동작하기 때문에 POST는 멱등성이 없다고 볼 수 있습니다. 그러나 DELETE 메서드는 POST와 비슷한데 멱등성을 가지고 있습니다. 

DELETE로 /delete.html 에 요청을 보내면 처음에는 삭제되서 상태코드르 200으로 응답받겠지만 이후에는 404로 받을 것입니다. 결국 한번 보내거나 100번 보내도 삭제되는 것은 동일하고 결과도 같다고 할 수 있으므로 멱등성을 가진다고 볼 수 있습니다.

 

 

3. 캐시가 가능하다는 것은 무엇인가?

 

캐시 가능(cacheable) 한 응답은 캐시할 수 있는 HTTP 응답으로, 나중에 검색하고 사용하기 위해 저장하여 새 요청을 서버에 저장합니다. 모든 HTTP 응답을 캐시할 수 있는 것은 아니며, 캐시할 HTTP 응답에 대한 제약 조건은 다음과 같습니다.

  • GET 또는 HEAD 메서드는 요청에 사용된 메서드는 그 자체로 캐시 가능합니다. POST 또는 PATCH 요청에 대한 응답은 신선도가 표시되고 Content-Location 헤더가 설정된 경우 캐시될 수도 있지만 거의 구현되지 않았습니다. (예를 들어, Firefox는 https://bugzilla.mozilla.org/show_bug.cgi?id=109553 에 따라 이를 지원하지 않습니다.) PUT 혹은 DELETE 다른 메서드는 캐시 가능하지 않고 그 결과 역시 캐시할 수 없습니다.
  • 애플리케이션 캐싱에 의해 알려진 응답의 상태 코드는 캐시 가능한 것으로 간주됩니다. 200, 203 (en-US), 204, 206, 300, 301, 404, 405, 410, 414, 501 상태 코드는 캐시 가능합니다.
  • 응답에는 Cache-Control과 같은 캐싱을 방지하는 특정 헤더가 있습니다.

 

 

 

다음은 각각의 http 메서드와 curl 커맨드입니다.


curl이란? HTTP 요청을 보낼 수 있는 CLI 커맨드, 서버와 통신할 수 있는 커맨드 명령어 툴로 설명할 수 있겠다. 

 

 

curl 설치 커맨드 

#우분투
sudo apt-get install curl

#Redhat 계열(Centos등)
yum install curl-devel

 

자주 사용하는 옵션

자주 사용하는 옵션은 아래 3가지이다.

-d, --data: <data> Send specified data in POST request. 

-H, --header: <header> Headers to supply with request. 

-X, --request: The request method to use. ex) GET, POST

 

 

 

GET

GET 메서드는 특정 리소스의 표시를 요청합니다. GET을 사용하는 요청은 오직 데이터를 받기만 합니다.

 

command

#리눅스는 주소 앞 뒤에 "", ''로 감싸도 상관없음
#윈도우는 주소 앞 뒤에 ""로만 감싸야함
#요청
curl -X GET "http://google.com"


#응답
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>

 

 

HEAD

HEAD 메서드는 GET 메서드의 요청과 동일한 응답을 요구하지만, 응답 본문을 포함하지 않습니다.

 

command

#요청
curl -I https://reqbin.com/echo

#응답
HTTP/2 403 
date: Sat, 07 Jan 2023 02:53:09 GMT
content-type: text/html; charset=UTF-8
permissions-policy: accelerometer=(),autoplay=(),camera=(),clipboard-read=(),clipboard-write=(),fullscreen=(),geolocation=(),gyroscope=(),hid=(),interest-cohort=(),magnetometer=(),microphone=(),payment=(),publickey-credentials-get=(),screen-wake-lock=(),serial=(),sync-xhr=(),usb=()
cache-control: private, max-age=0, no-store, no-cache, must-revalidate, post-check=0, pre-check=0
expires: Thu, 01 Jan 1970 00:00:01 GMT
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=mI0711YiwVR3vBU%2BtsXs4XF8m4b%2BOVdrftVqG%2FlOrOxqqzXAFnUFdS%2Fb3MVAfbpHcb0hx93KsTdX%2FDHmuXTm06Afxwr6Zr4okWQbm4Gidgu39iUG6%2FoDSHIp7Vo%3D"}],"group":"cf-nel","max_age":604800}
nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
expect-ct: max-age=86400, enforce
referrer-policy: same-origin
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-xss-protection: 1; mode=block
server: cloudflare
cf-ray: 785966c8f9c7f5f5-NRT



POST

POST 메서드는 특정 리소스에 엔티티를 제출할 때 쓰입니다. 이는 종종 서버의 상태의 변화나 부작용을 일으킵니다.

 

command

#요청
curl -d "key1=value1&key2=value2" \
-H "Content-Type: application/x-www-form-urlencoded" \
-X POST http://google.com



#응답
<!DOCTYPE html>
<html lang=en>
  <meta charset=utf-8>
  <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
  <title>Error 405 (Method Not Allowed)!!1</title>
  <style>
    *{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}
  </style>
  <a href=//www.google.com/><span id=logo aria-label=Google></span></a>
  <p><b>405.</b> <ins>That’s an error.</ins>
  <p>The request method <code>POST</code> is inappropriate for the URL <code>/</code>.  <ins>That’s all we know.</ins>

 

 

PUT

PUT 메서드는 목적 리소스 모든 현재 표시를 요청 payload로 바꿉니다.

 

command

#요청
curl -X PUT -H "Content-Type: application/json; charset=utf-8" -d '{"message":"hello"}' http://127.0.0.1:3000/api/chat

#응답
curl: (7) Failed to connect to 127.0.0.1 port 3000: 연결이 거부됨

 

 

DELETE

DELETE 메서드는 특정 리소스를 삭제합니다.

 

command

#요청
curl -X DELETE http://google.com


#응답
<!DOCTYPE html>
<html lang=en>
  <meta charset=utf-8>
  <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
  <title>Error 405 (Method Not Allowed)!!1</title>
  <style>
    *{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}
  </style>
  <a href=//www.google.com/><span id=logo aria-label=Google></span></a>
  <p><b>405.</b> <ins>That’s an error.</ins>
  <p>The request method <code>DELETE</code> is inappropriate for the URL <code>/</code>.  <ins>That’s all we know.</ins>

 

CONNECT

CONNECT 메서드는 목적 리소스로 식별되는 서버로의 터널을 맺습니다.


command

#요청 
curl -X CONNECT http://proxy_host:proxy_port/www.example.com:443

 

OPTIONS

OPTIONS 메서드는 목적 리소스의 통신을 설정하는 데 쓰입니다.

command

#요청
curl https://api.reqbin.com/api/v1/requests
   -X OPTIONS
   -H "Access-Control-Request-Method: POST"
   -H "Access-Control-Request-Headers: content-type"
   -H "Origin: https://reqbin.com"
   
   
#응답 결과
   <!DOCTYPE html>
<html lang="en-US">
<head>
    <title>Just a moment...</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge">
    <meta name="robots" content="noindex,nofollow">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link href="/cdn-cgi/styles/challenges.css" rel="stylesheet">
    

</head>
<body class="no-js">
    <div class="main-wrapper" role="main">
    <div class="main-content">
        <h1 class="zone-name-title h1">
            <img class="heading-favicon" src="/favicon.ico"
                 onerror="this.onerror=null;this.parentNode.removeChild(this)">
            api.reqbin.com
        </h1>
        <h2 class="h2" id="challenge-running">
            Checking if the site connection is secure
        </h2>
        <noscript>
            <div id="challenge-error-title">
                <div class="h2">
                    <span class="icon-wrapper">
                        <div class="heading-icon warning-icon"></div>
                    </span>
                    <span id="challenge-error-text">
                        Enable JavaScript and cookies to continue
                    </span>
                </div>
            </div>
        </noscript>
        <div id="trk_jschal_js" style="display:none;background-image:url('/cdn-cgi/images/trace/managed/nojs/transparent.gif?ray=785975a7bbf2afac')"></div>
        <div id="challenge-body-text" class="core-msg spacer">
            api.reqbin.com needs to review the security of your connection before proceeding.
        </div>
        <form id="challenge-form" action="/api/v1/requests?__cf_chl_f_tk=w5WYAanLltSZxASmtasmSMlJOW33u6lHPovj3GYNMVg-1673060599-0-gaNycGzNBz0" method="POST" enctype="application/x-www-form-urlencoded">
            <input type="hidden" name="md" value="dbKwCPH4ofPeFr5tVcTF0Inc69QO7saimqv7QRBmh8A-1673060599-0-AY5OeWHUC0mYiI5Z094rU-2yUN9V3DK3VmNk3vLnS-r_DGbeOnlbCgKKb9Udpyuo1Gq3w6KWHXuvMUW6U4jcASZNiVPWVxjbsrHWzWoE-XR036GvlWhvRjg6D4EjJMS-d-vUCpL6GgkKqcfXue_reQVx_f0gQ6CMHcMdZMJGQdKSEwNf4Ufu_0j_bJ5pCbUzATCAreqLLqb-HRBtEu40Lj836eq9BZxOinJBz1FRoXw1yy09xNjui-YWRZevHtCHKlEFlMs6MuRlraVTMEZmCyA6m7jsQMbz0WMbbTI67zvPsOVh0_iq3Vrsb37zbt4gb6UEe83y6eS1iw84Rm1akBRuKFB77LxV5R-FE_SLoi2FV8FKIotCTnKJcgssIJl1u-JACYjUi5u1Ii7c_uDrzry5Hk5SvN2zsjXg1USEkK_CmsabxcGy4TjilNSyduPkr4bFMk1AAeBqrFczESxb1U2YvCo4riSjMXeiab76OYMGB9N2L6kkplKqh6feiJgHCZAphnF6IdHgGnb8iQN3TIURpdy1G5CqkFBaLhK1Xe0qZysY6IhzjRODaoVsj-hT4_PB05z4oKvbSxZka_EIDFhDAXseEGr2uWJ9dc3QAsfo">
            <input type="hidden" name="r" value=".nKHWgek9lhwHq.leu5er_1VlwDQ2MTMxO6mIg84xdI-1673060599-0-AX6a/dqM5HmVMun/eMwnN7IUMagXyLZH+JtP8akjGJW5/ux4+Yf34sQoIxC8C4QftHasVCSPM2nkGyUhZSJk6FfLD57aUNEw+g13w57wS946nvmzjqBn7772At43I38IvUjcxQKUfJcFHdXQ+XtrW8g7/bTwBCTT8uX47PxoMymLZOrh4JaFVEawVywyJk8c7cHerJuptQ/1u/SFFRrfIvWJTAxYeGQBVHDbKr6RoFq1kAXR1LNVYTiFZQPaZau6KRdm2DceZLAAna4pbardRjtSFI2u+j+YuwY97GPSgTXVyN58zJuD3iK2f6r7T7K+lOTx+VKKkQ4iH6jrb755MCcOiy0FHGN7GETfJk3vNtKptWlyDEVVokK3GfRKvih0RGDgKZg96y8A7rqJyAdO7ZU+w7GSsSByzW97GS7eKlPPm8gXgt4d7tWAiJDDnIN/0s2OIZu6NbR4UEm+gMeppz99rFPI8pnUZy0BKCHJR7tJYU4l33PCt7HLMfCTqtoC/FSn2od4zDycRUI2zgUs0qKLHJiucIFbY5UqX1yqJODuY00/JxFqCAmo/HPP2C0o2J3elLE0Awf/EC+ZDFmkiAVvk4kUNPge2k+n6MZxnrahYyt4mRqq12jHjeL2irqL/8sSq5WqmA0yMD/HAeo9nFRY7Z8YWf5rFQgPl7qvxSJ+viOtobbRu+hC6xbpmoFgAKq5Oky80ELPqSPDjtPW9uay0QGoIqP0KV95Z/9dvhmhfvdZ8ba8stTQdpmvMrBqD77MqmAVyOJ6yWtBXXv+fpJExtgLNlGRaH5zfexwota81BiABC7xWg/lYdBu5LmEIjihPi5ZIi2+l7BiBLu6GXOhocsUvmPwpT6OKch5yMGOw/Ad9oeK+jDmxNZCy2uduBPh+WVo5EYrWF/3/tQ/XlMP4p/lzVjA1I+AdA1q0LosdeH6SlRtioy23l4pRzAHpIFMVhqOliLCdf7MGjeYnc+IXsozNetZESqLveAQngLyprCgYPw10/PTl4qvcK6ZyVBLD5QOwmd1uifwUKCmu+5ZKaiYZmgfUSw9KR+TM+I4w91oLSqcxW5uNHbcjRYg22Y1zJqHuzgGr9kG9duRFe48eNXW2d4vH6myrh5XZuykcZZxaC/noBqscuIQI0xPnOlrDDHi127D8xMQFm0hkJgGOaO+HWf5L212zP66qhw7XAQ5fx/u0sQtdJMwPcE0rbBJuhVmdmv1+9pnOCHUS/sNNbsWMHFgmRcbpII2L4EhduEimZ82B/AoAv9NOIV/FHUrnHLcJsArxTZh6H4t9Ch9rkhsmCaeJbMgnJKUFA6wJusoeXqX64Wm8kj2GFNS0X8NsnJCKTveZQx4BAMqKkfpoOvj57K07BT/wK80nIQIYMIbxQ8+5NbSddPNv17A+rSL4Pc2m5S6EzcYgJ5RxWWut1L4cszs8QMVUhmFbs03D6dP2dQfclh1hqsEqXwFTkkCGu4LP/vi/OS02YaeOuTsh9A4UYlv06mSPhvKlvZq7Nggfq7qgAYIYaqTpR0yqSkkSJAxFLtBxwwOs9y8VHl1FQn3FVlPLm9fz7HfIGgNUGuJ/vADHNGh1hriAAH031un1DmaQCuLVzsiDR1fT+tt7pm3edkmvetE2Rcy4tlAzjiVkp8+UQWk9sUdsf3HmYnWycLklXtYGcGoozhl/zOzjLQbxc0IAAGDYFm26lWSNrYt1Tq1dlP4HYP3izwlCTmlE0iXQIIfAlZXISSIygjroDmNWtDfNX71+LdPfaFCdfTDCh6xoYxM76WKHI616A==">
        </form>
    </div>
</div>
<script>
    (function(){
        window._cf_chl_opt={
            cvId: '2',
            cType: 'managed',
            cNounce: '35378',
            cRay: '785975a7bbf2afac',
            cHash: '18f8fa7bb5d3051',
            cUPMDTk: "\/api\/v1\/requests?__cf_chl_tk=w5WYAanLltSZxASmtasmSMlJOW33u6lHPovj3GYNMVg-1673060599-0-gaNycGzNBz0",
            cFPWv: 'b',
            cTTimeMs: '1000',
            cTplV: 4,
            cTplB: 'cf',
            cRq: {
                ru: 'aHR0cHM6Ly9hcGkucmVxYmluLmNvbS9hcGkvdjEvcmVxdWVzdHM=',
                ra: 'Y3VybC83LjY4LjA=',
                rm: 'R0VU',
                d: 'ykjJKEDPcVN2JTPeqeB0z+h6GOX3Nl79LUaryHLWj382CuCBt/BfKKLPARlRtimeWfFm+QG7Lzpz+DSAbp63pmwrY9hl+LkA5vOkoyKlv4J81SNZLpzD6szCH306/dr397CYYf1owmapRV0xICSsBx2S2fSaE17V1ERaa8oLP8XBr1gCpmd2Ilu4t6tn6PWbw8BX++/nJdKlooz6IsMwCS856avpV9SvFQ+CaOGSsvoVtTUzsN2cv1jfFwvAk4uDckMlD3j62uGhLUSeskHNu5k+KTOtIoUjfrPFxSaFHy/jjUQqMEXpIWeUVDo8ppHosJhMFejbaZsl81bL0SEHudWEZbD65NnaNzerpPIKisniCodlOVts4smPxLE8D+wXJHL68yywu5Ske2ULOveN0jgwPSZ9hghoyNMrXuEaUT8CCRYsnrmUvUZFjHDesmqaABvQAM00iBcribbPMBzTRmylu4UbdO+BGaLWSsJ4VWsfwW7SboV35SCgKx73wL8Oi7HpKKxrs7hcdEefcU1nIGl50Wndo5EiMl3eVdwBntGpWFEuD4Hd2GHxOaM7nJxkKrx40pueCQ8VwkMeBzO0RCVAQQk6tNCRwjkdwiBpqY1pmr2evyxaDs6xr8FarXre0Bddv8d2ufgHqnMowKl6VNkvUt17UFBIwlpsJHMzxOuSfoJzbWMyDJr6BhYot/aQDMvtv1ZeAeAsZ4QwKSNFqA==',
                t: 'MTY3MzA2MDU5OC45OTYwMDA=',
                m: 'WhmFiha7w7a48yE8Xnoi6nqF+XIFsBIoZdQIDteW3UU=',
                i1: 'ha+4JXDnzrVaKsulPGwyug==',
                i2: 'a5RPbR7HpPhldrEk8cmNhQ==',
                zh: 'LCW3AZH/FGYMtoptFGg2LyVk23ScKwRlpKwnq4Z30Ks=',
                uh: 'LgBfwTjckPmPFLl2OGGaoWOKkjIgTojK2wwoWSzqSQw=',
                hh: 'Yroa6OR16Vk5B/CHkx07NBI7cTU6hBD0XMZsV2QLxtM=',
            }
        };
        var trkjs = document.createElement('img');
        trkjs.setAttribute('src', '/cdn-cgi/images/trace/managed/js/transparent.gif?ray=785975a7bbf2afac');
        trkjs.setAttribute('style', 'display: none');
        document.body.appendChild(trkjs);
        var cpo = document.createElement('script');
        cpo.src = '/cdn-cgi/challenge-platform/h/b/orchestrate/managed/v1?ray=785975a7bbf2afac';
        window._cf_chl_opt.cOgUHash = location.hash === '' && location.href.indexOf('#') !== -1 ? '#' : location.hash;
        window._cf_chl_opt.cOgUQuery = location.search === '' && location.href.slice(0, -window._cf_chl_opt.cOgUHash.length).indexOf('?') !== -1 ? '?' : location.search;
        if (window.history && window.history.replaceState) {
            var ogU = location.pathname + window._cf_chl_opt.cOgUQuery + window._cf_chl_opt.cOgUHash;
            history.replaceState(null, null, "\/api\/v1\/requests?__cf_chl_rt_tk=w5WYAanLltSZxASmtasmSMlJOW33u6lHPovj3GYNMVg-1673060599-0-gaNycGzNBz0" + window._cf_chl_opt.cOgUHash);
            cpo.onload = function() {
                history.replaceState(null, null, ogU);
            };
        }
        document.getElementsByTagName('head')[0].appendChild(cpo);
    }());
</script>


    <div class="footer" role="contentinfo">
        <div class="footer-inner">
            <div class="clearfix diagnostic-wrapper">
                <div class="ray-id">Ray ID: <code>785975a7bbf2afac</code></div>
            </div>
            <div class="text-center">Performance &amp; security by <a rel="noopener noreferrer" href="https://www.cloudflare.com?utm_source=challenge&utm_campaign=m" target="_blank">Cloudflare</a></div>
        </div>
    </div>
</body>
</html>

 

 

 

 

 

참고: 
https://developer.mozilla.org/ko/docs/Web/HTTP/Methods 

https://reqbin.com/curl 

https://reqbin.com/req/c-tmyvmbgu/curl-head-request-example 

https://developer.mozilla.org/ko/docs/Web/HTTP/Methods/OPTIONS 

https://developyo.tistory.com/11 

https://stackoverflow.com/questions/63224799/curl-connect-method-without-path-destination-hostname-and-port-instead 

https://fmhelp.filemaker.com/help/16/fmp/ko/index.html#page/FMP_Help/curl-options.html

https://bakyeono.net/post/2016-05-02-rest-api-client-for-cli.html 

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=wideeyed&logNo=221350638501 

https://developer.mozilla.org/ko/docs/Glossary/Idempotent 

https://developer.mozilla.org/ko/docs/Glossary/cacheable