본문 바로가기
프로그래밍/PHP

[정보] HTTP/1.1 METHOD 의 종류와 아파치에서의 제어

by 백룡화검 2008. 10. 16.
RFC 2068 문서를 보던중 호기심에 HTTP/1.1 METHOD중 DELETE method 를 이용해보려고 telnet 으로
접속시도해 보았다.
]$ telnet localhost 80
DELETE /test.gif HTTP/1.1
Host: www.domain.com
Content-Length: 0
그러나 해당 화일은 삭제 되지 않았다.
물론 test.jpg 의 권한은 apache 가 읽고쓸수 있는 권한이었다.

그래서 http method 를 찾아보던중... 생각보다 많은 method들이 있었다.
아래의 URL은 http method 종류를 확인할수 있으며 실시간으로 특정 도메인에 method별로 스켄을 한다.
http://www.askapache.com/online-tools/request-method-scanner/

이곳을 통해 www.domain.com/test.gif 에 delete method 를 적용시켜보니..
alllow 란 항목이 있었으며 특정 메소드만이 적혀 있었다.
이를 보아 특정 메소드만 허락된것이라고 유추할수 있었다.

다시 그럼 이 설정은 어디서 하는것일까?
현재 사용하는 웹서버가 apache 이다.
아파치에 공식사이트에 들어가서 찾아보니..  <Limit> <LimitExcept> 를 통해
method 를 제어하는 것이었다 눈에 들어오지 않는다면..
아래의 설정을 보자 대부분 많이 보던 설정이었을 것이다.

<Directory /home>
    AllowOverride FileInfo AuthConfig Limit
    Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
    <Limit GET POST OPTIONS PROPFIND>
        Order allow,deny
        Allow from all
    </Limit>
    <LimitExcept GET POST OPTIONS PROPFIND>
        Order deny,allow
        Deny from all
    </LimitExcept>
</Directory>

해당 URL 을 참조하면 더욱 쉽게 알수 있을것이다.

http://httpd.apache.org/docs/1.3/mod/core.html#limit
http://httpd.apache.org/docs/2.0/mod/core.html#limit
http://httpd.apache.org/docs/2.2/mod/core.html#limit

아파치 버젼이 달라졌다고 기능이 달라진게 아니어서 내용은 똑같다.
이제 http method를 전체설정, virtualhost 별, 디렉토리별, .htaccess 등에서 사용될수 있다는걸
알수 있을것이다.


[참고1]
하지만 아파치 자체에서는 기본적으로 몇개 안되는 http method만 지원하는거 같다
GET,HEAD,POST,OPTIONS,TRACE
...
DELETE method는 아무리 권한을 주고 설정을 하여도 되질 않았다.
송효진님의 답변에 힌트를 얻어 WEBDAV 를 검색해보니...

아파치 모듈 mod_dav 를 통해 제어가 가능한듯 했다.
실력이 미흡한 관계로 mod_dav 쪽은 설명하기가 힘들듯 하다.
DELETE method를 꼭 이용해 보고 싶으신 분들은 아래의 Link를 참조하길 바란다.
http://www.webdav.org/



[참고2]
아래는 RFC 2068 번역본중 Method 설명에 관련된 부분만 발췌한 것이다.


RFC 2068 - Hypertext Transfer Protocol -- HTTP/1.1
rfc2068 :하이퍼텍스트 전송규약 1.1표준(안)

출처 : 한국전자통신연구소
================================================================================================
9. Method 정의

HTTP/1.1에서 사용되는 일반적인 method 세트를 아래에 규정하였다. 이 세트를 확장할 수 있지만
추가된 method를 별도로 확장된 클라이언트와 서버가 동일한 의미를 공유하고 있다고 가정할 수 없다.

호스트 Request-Header 필드(14.23 절)는 반드시 모든 HTTP/1.1 요구를 따라야 한다.

9.1 안전 및 멱등원(冪等元) method

9.1.1 안전 method

구현자는 소프트웨어가 사용자와의 상호작용이 인터넷을 통하여 표시된다는 점을 인지해야 하며
사용자에게 자신이 취하는 행동이 자신과 다른 사용자에게 예상하지 못한 중요성을 가질 수 있다는 점을
인지시키도록 주의해야 한다.

특히 GET 및 HEAD method가 조회 이외의 작업을 수행하는 중요성을 가져서는 안 된다는 관례가 확립
되었다. 이러한 method는 안전한 것으로 간주해야 한다. 이렇게 하여 사용자 에이전트가 POST, PUT 및
DELETE와 같은 다른 method를 특별한 방식으로 표현할 수 있게 하며 사용자가 안전하지 못한 처리를
요구하고 있다는 사실을 인식할 수 있게 한다.

당연히 서버가 GET 요구를 수행한 결과로서 부작용을 발생하지 않고 있음을 보장할 수 없다.

사실상 몇몇 역동적인 자원은 이것을 하나의 기능으로 보고 있다. 중요한 구별 점은 사용자가 부작용을
요청하지 않았기 때문에 부작용에 대한 책임을 부과할 수는 없다는 것이다.

9.1.2 멱등원(冪等元) method

Method는 또한 N > 0 과 동일한 요구의 부작용이 단일 요구의 부작용과 동일하다는 점에서 "멱등원"
특성을 가질 수 있다.(에러 또는 만기일의 문제는 별도로 하고)  GET, HEAD, PUT 및 DELETE method는
이 특성을 공유하고 있다.

9.2 OPTIONS

OPTIONS method는 Request-URI에 의하여 식별되는 Request/Response chain에서 사용할 수 있는
통신 선택 사항에 관한 정보 요구를 표시한다. 이 method는 클라이언트가 자원 처리를 시도하거나 자원
조회를 시작하지 않고도 선택 사항 및/또는 자원과 관련된 필요 조건, 서버의 처리 능력을 결정할 수 있게
한다.

서버의 응답이 에러가 아닌 이상 응답은 통신 선택 사항이라고 간주할 수 있는 것 이외의 엔터티 정보를
포함해서는 안 된다.(예를 들어 Allow 는 적합하지만 Content-Type은 적합하지 않다).

Request-URI 가 별표("*")이면 OPTIONS 요구는 전체를 서버에 적용하려는 것이다. 200 응답은 모든
적용 가능한 일반 필드 또는 Response-Header 필드 이외에 이 규격에서 규정하지 않는 모든 확장을
포함하여 서버가 구현한(예 Public) 선택 기능을 표시하는 모든 헤더 필드를 포함해야 한다. 5.1.2 절에서
설명된 것처럼  "OPTIONS *" 요구는 경로 정보 없이 Request-URI에 목적지 서버를 명시함으로써
프락시를 통하여 적용할 수 있다.

Request-URI가 별표가 아니면 OPTIONS 요구는 해당 자원과 통신할 때 사용할 수 있는 선택 사항에만
적용된다. 200 응답은 모든 적용 가능한 일반 필드 또는 Response-Header 필드 이외에 이 규격에서
규정하지 않는 모든 확장을 포함하여 서버가 구현한(예 Allow) 선택 기능을 표시하는 모든 헤더 필드를
포함해야 한다. OPTIONS 요구가 프락시를 통한다면 프락시는 프락시의 성능에 관계되는 선택 사항 및
프락시를 통하여 사용할 수 없는 것으로 알려진 선택 사항을 제외할 수 있도록 응답을 반드시 편집해야
한다.

9.3 GET

GET method는 Request-URI가 식별하는 모든 정보(엔터티의 형태로)를 조회한다는 것을 의미한다.
Request-URI가 데이터를 생성하는 프로세스를 참조한다면 텍스트가 우연히 프로세스의 산출물이 아닌
이상 엔터티로서 리턴 되는 것은 프로세스의 소스 텍스트가 아니라 생성된 데이터이다.

GET method의 의미는 요구 메시지가 If-Modified-Since, If-Unmodified-Since, If-Match, If-None-
Match 또는 If-Range 헤더 필드를 포함하고 있으면 "조건적인 GET"으로 변화한다. 조건적인 GET
method는 엔터티가 조건 헤더 필드가 명시한 조건 하에서만 전송되도록 요청하는 것이다.
조건적 GET method는 복수의 요구나 클라이언트가 이미 보유하고 있는 데이터를 전송하지 않고도
캐시 된 엔터티를 갱신할 수 있도록 함으로서 불필요한 네트워크 사용을 감소시키기 위해 사용한다.

GET method의 의미는 요구 메시지가 Range 헤더 필드를 포함하고 있으면 "부분적인 GET"으로
변화한다. 부분적인 GET method는 14.36 절에 설명된 것처럼 엔터티의 일 부분만 전송하도록
요청하는 것이다. 부분적 GET method는 클라이언트가 이미 보유하고 있는 데이터를 전송하지
않고도 부분적으로 조회한 엔터티가 완성될 수 있도록 함으로써 불필요한 네트워크 사용을 감소시키기
위해 사용한다.

GET 요구에 대한 응답은 13 장에 설명된 대로 HTTP 캐시 요구 필요 조건을 만족할 경우에만 캐시할
수 있다.

9.4 HEAD

HEAD method는 서버가 응답 메시지에 Message-Body를 반드시 리턴해야 한다는 것 이외에는 GET과
동일하다. HEAD 요구에 대한 응답으로 HTTP 헤더에 포함된 메타 정보는 GET 요구에 대한 응답으로
발송된 정보와 반드시 동일해야 한다. 이 method는 Entity-Body 자체를 전송하지 않고도 요구가 내포
하는 엔터티에 대한 메타 정보를 얻는 데 사용할 수 있다. 이 method는 종종 하이퍼텍스트 링크의 유효성,
접근성 및 최근의 변경 사항을 테스트하기 위해 사용된다.

HEAD 요구에 대한 응답은 응답에 포함된 정보를 해당 자원의 이전 캐시 엔터티를 갱신하는 데 사용할 수
있다는 의미에서 캐시할 수 있다. 새로운 필드 값이 캐시 된 엔터티가 현재의 엔터티 (Content-Length,
Content-MD5, ETag 또는 Last-Modified의 변화에 의해 표시되는 것과 같은)와 상이함을 표시할 때는
캐시는 반드시 이 캐시 엔트리를 낡을 것으로 취급해야 한다.

9.5 POST

POST method는 서버에게 Request-Line의 Request-URI가 식별하는 자원의 새로운 부속물로서 요구에
포함된 엔터티를 접수할 것을 요구하는 데 사용한다. POST는 다음의 기능을 수행하는 일관된 method를
사용할 수 있도록 디자인 되었다.

? 기존 자원의 주해;
 
? 게시판, 뉴스그룹, 편지 발송 목록 또는 유사한 기사 그룹으로 메시지를 송부;
 
? 폼을 제출한 결과로 발생한 데이터 블록을 데이터 처리 프로세스에 제공;
 
? 추가 작업을 통한 데이터 베이스의 확장.

POST method가 실제적으로 수행하는 기능은 서버가 결정하며 보통 Request-URI에 달려 있다.
발송된 엔터티는 파일이 파일을 포함하고 있는 디렉토리에 종속되고, 뉴스 기사가 발송한 뉴스그룹에
종속되며 레코드가 데이터 베이스에 종속되듯이 해당 URI에 종속된다.

POST method가 수행하는 작업이 URI로 식별할 수 있는 자원을 생성하지 않을 수도 있다. 이러한 경우
응답이 결과를 설명하는 엔터티를 포함하고 있는가 여부에 따라 200(OK)이나 204(No Content)가 적절한
응답 상태이다.

새로운 자원이 원서버에서 생성되었다면 응답은 201(Created)이어야 하고 요구의 상태를 설명하며
새로운 자원 및 Location 헤더 (14.30 절 참조)를 지칭하는 엔터티를 포함해야 한다.

이 method에 대한 응답은 응답이 적절한 Cache-Control 또는 Expires 헤더 필드를 포함하지 않는 한
캐시할 수 없다. 그러나 303(See Other) 응답을 사용하여 사용자 에이전트에게 캐시할 수 있는 자원을
조회하도록 지시할 수 있다.

POST 요구는 8.2 절에 설정된 메시지 전송 필요 조건을 반드시 따라야 한다.

9.6 PUT

PUT method는 동봉된 엔터티를 제공된 Request-URI에 저장하도록 요구한다. Request-URI가 이미
존재하는 자원을 지칭할 경우 동봉된 엔터티는 원서버에 있는 엔터티의 변경된 버전으로 간주해야 한다.
Request-URI가 기존 자원을 지칭하지 않고 URI가 요구하는 사용자 에이전트가 새로운 자원으로 규정할
수 있다면 원서버는 해당 URI로 자원을 생성할 수 있다. 만약 새로운 자원이 생성되었으면 원서버는
사용자 에이전트에게 201(Created) 응답을 알려야 한다. 기존 자원이 변경되었다면 200(OK)이나 204
(No Content) 응답 코드를 발송하여 요구를 성공적으로 완료하였음을 표시하여야 한다. Request-URI로
자원을 생성하거나 변경할 수 없는 경우에는 문제의 기본 성격을 반영하는 적절한 에러 응답을 발송해야
한다. 엔터티의 수신측은 이해 또는 구현할 수 없는 Content-* (예: Content-Range) 헤더를 반드시
무시해야 하고 이러한 경우 501(Not Implemented) 응답을 리턴해야 한다.

요구가 캐시를 통과할 경우 Request-URI는 하나 또는 그 이상의 현재 캐시 된 엔터티를 식별한다.
이러한 엔터티는 낡은 것으로 취급해야 하며 이러한 method에 대한 응답은 캐시할 수 없다.

POST와 PUT 요구의 근본적인 차이점은 Request-URI의 다른 의미에 반영된다. POST의 URI는
동봉된 엔터티를 처리할 자원을 식별한다. 그 자원은 데이터를 접수하는 프로세스, 다른 규약으로의
게이트웨이 또는 주석을 접수하는 별도의 엔터티일 수 있다. 이에 비하여 PUT 요구의 URI는 요구에
포함된 엔터티를 식별한다. - 사용자 에이전트는 어떤 URI를 의도하고 있으며 서버는 요구를 다른 자원에
적용해서는 절대로 안 된다는 것을 알고 있다. 만약 서버가 해당 요구를 다른 URI에 적용하고자 한다면
서버는 301(Moved Permanently) 응답을 반드시 발송해야 한다. 그러면 사용자 에이전트는 해당 요구의
방향을 재설정 할 것인지에 관한 자신의 결정을 한다.

단일 자원이 복수의 상이한 URI에 의하여 식별될 수 있다. 예를 들어 기사(article)는 각각의 특별한
버전을 식별하는 URI와 구별되는 "현재 버전"을 확인하기 위한 URI를 가질 수 있다.
이 경우 일반 URI의 PUT 요구는 원서버에 의하여 규정되는 복수의 URI를 생성할 수도 있다.

HTTP/1.1은 PUT method가 어떻게 원서버의 상태에 영향을 미치는가에 대해서는 규정하지 않는다.

PUT 요구는 8.2 절에 설정된 메시지 전송 필요 조건을 반드시 따라야 한다.

9.7 DELETE

DELETE method는 Request-URI가 식별하는 자원을 삭제하도록 원서버에 요구한다. 이 method는
원서버에서 사용자의 개입(또는 다른 방법)에 의하여 무시될 수 있다. 클라이언트는 비록 원서버에서
발송한 상태 코드가 해당 작업이 성공적으로 완수되었다는 표시를 하여도 실제로 작업이 완료되었다는
보장을 받을 수 없다. 그러나 서버는 요구를 접수한 시점에서 자원을 삭제하거나 접근할 수 없는 위치로
이동할 의사가 없는 한 성공을 표시해서는 안 된다.

성공적인 응답은 응답이 상태를 설명하는 엔터티를 포함한다면 200 (OK), 처리가 시작되지 않았으면
202 (Accepted), 응답은 OK이나 엔터티를 포함하지 않고 있으면 204 (No Content)이다.

요구가 캐시를 통과할 경우 Request-URI는 하나 또는 그 이상의 현재 캐시 된 엔터티를 식별한다.
이러한 엔터티는 낡은 것으로 취급해야 하며 이러한 method에 대한 응답은 캐시할 수 없다.

9.8 TRACE

TRACE method는 요구 메시지의 원격지, 애플리케이션-계층 루프백(loop back)을 호출하는 데 사용
한다. 응답의 최종 수신측은 클라이언트에게 되돌려 진 메시지를 200(OK) 응답의 Entity-Body로 수신
해야 한다. 마지막 수신측은 메시지의 Max-Forwards 제로 값(14.31 절)을 수신하는 원서버, 첫 프락시
또는 게이트웨이이다. TRACE 요구는 절대 엔터티를 포함해서는 안 된다.

TRACE는 클라이언트가 Request chain의 다른 끝 쪽에 무엇이 수신되는가를 알 수 있게 하며 그 데이터
를 시험 또는 진단 정보로 사용한다. Via 헤더 필드(14.44 절)의 값은 Request chain의 추적 역할을
수행하기 때문에 특히 주목할 만하다. Max-Forwards 헤더 필드를 사용하면 클라이언트가 Request
chain의 길이를 제한할 수 있으며 이는 무한 루프에서 메시지를 전달하는 프락시 고리를 테스트하는 데
유용하다.

성공적이면 응답은 "message/http" 의 Content-Type을 가진 Entity-Body의 전체 요구 메시지를 포함할
수 있어야 한다. 이러한 method에 대한 응답을 절대 캐시해서는 안 된다.

출처 : PHPSCHOOL