AJP 프로토콜 모든 것을 분석 해보자
개요
AJP(Apache JServ Protocol)은 Web Server에서 받은 요청을 WAS로 전달해주는 프로토콜이다.
해당 프로토콜은 Apache HTTP Server, Apahce Tomcat, 웹스피어, 웹로직, JBOSS, JEUS, 등 다양한 WAS에서 지원한다.
패킷 구조 분석
개요
- AJP는 HTTP의 내용을 포워드 용도에만 있다.
- AJP는 8K 이상을 전송하지 못한다(헤더는, Body Chunk는 64K 를 보낸다.).
- 그래서 짤라서 여러 번 보내는 것 같다(시퀀셜하게, Body Chunk 또한 64K 씩 잘라서 보낸다.).
- Secure하지 않다. 단지 포워드 용도이기 때문이다. Secure하기 위해서는 HTTPS를 포워딩 하면 된다( 또는 TLS를 입히고 보낸다? ㅋㅋㅋ).
페킷의 데이터 타입
- AJP는 Byte/Boolean/Integer/String 타입이 존재한다.
- Byte는 말그대로 Byte array를 얘기한다.
- Boolean은 말그대로이다. 크기는 1바이트이다.
- Integer는 말그대로이다. 크기는 2바이트이다.
- String은 말그대로이다.
- String을 표현하는 방법은 다음과 같다. String의 구조는 (길이)/(String)/(end) 이다. 길이의 경우, Integer 값이다. 예를 들어 HTTP/1.1 표현할 경우, 길이: 0x0008 이며, String은 아스키 값으로 표현하고 end padding은 0x00을 표기한다.
AJP Request 패킷 구조
-Header: Request: 0x1234 /길이 / 데이터 길이
- Body:
-Prefix_code의 경우, 생략될 수 있다. Request_body값을 보낼 때(헤더를 보낸 후)
Request Prefix Code는 아래와 같다. 주로 쓰는 것은 HTTP 헤더 2번과 HTTP Body none이다.
AJP Response 패킷 구조
prefix_code_4: HTTP Response Header 전송
prefix_code_3: HTTP Response Body 전송
prefix_code_6: AJP 클라이언트의 Body 전송 수신 후, 더 보낼 것이 있는지 확인을 위한 구성
prefix_code_5: prefix_code_6다음으로 AJP 클라이언트가 더이상 보낼 것 이 없으면, 해당 구성을 사용
그 외 사용 패킷
HTTP-Method 표현 방법
- 1~27 Enum 값으로 표현한다.
HTTP-Header 표현 방법
- 헤더는 0xa001 ~ 0xa00E 으로 표현한다.
- Enum 값에 없는 헤더는 String 타입으로 구성한다.
Attribute 표현 방법
- 0x0a 부터 시작 이하 String 타입으로 구성한다.
AJP 플로우
AJP CPing/CPong
Ping 같은 것, AJP를 제대로 사용할 수 있는지 확인한다.
Cping(like ping, like http method option)
0x1234 -> AJP Request
0x0001 -> Data 길이
0x0a -> cping
Cpong
0x4142(ab) -> AJP Response
0x0001 -> Data 길이
0x09 -> Cpong(Cping response)
AJP Request 플로우
- 아래는 AJP의 Request 중 prefix 2번에 해당하는 것이다(HTTP 헤더 전송 부분).
- 도메인 부분은 가렸다.
※위의 그림, 0xff 관련된 것은 버그로 판명
github.com/jrialland/ajp-client/issues/8
(사정상 아래 이미지에서 위의 2개 Reqeust Header는 이미지 삭제)
아래는 prefix_code: none에 해당하는 HTTP Request Body 부분이다.
AJP Response 플로우
아래는 HTTP Response 헤더 전송 부분이다.
아래는 HTTP Response 바디 전송 부분이다.
AJP HTTP 응답의 끝을 알림
AJP Request/Response 전체 플로우
1. Server -> Container: AJP CPing( prefix_code: 10)
2. Container -> Server: AJP Cpong Reply(prefix_code: 9)
3. Server -> Container: AJP Request(헤더 전송: prefix_code: 2)
4. Server -> Container: AJP Request(Body 전송: prefix_code: 없음)
5. Container -> Server
- GET_BODY_CHUNK: 만약에 더 보낼 데이터가 있으면 보내라.(prefix_code:6)
- ff fa(Integer) : 근데 AJP 최대 전송 패킷 크기(200K 가까이 보내면 Apahce HTTPD 에서 fffa씩 짤라서 보냄)
6. Server -> Container
- 1안: 더 보낼 데이터가 있는 경우
-> 반복하다 더 이상 보낼 데이터가 없을 경우, 6-2로 빠진다.
- 2안: 더 보낼 데이터가 없는 경우
-> 00 00 을 보낸다.
7. Container -> Server: AJP Response(헤더 전송: prefix_code: 4)
8. Container -> Server: AJP Response(Body 전송: prefix_code: 3)
9. Container -> Server: AJP Response(끝을 알림: prefix_code: 5)
- reuse: true: (reuse: TCP 커넥션은 새로운 요청을 받을 수 있음을 알림 )
오픈 소스
해당 오픈 소스 테스트 완료 잘 통신됨, 그러나, 8K 이상의 HTTP Body에 대해서는 8K 씩 짤라서 보냄 << 64K 씩 짤라서 보낼 수 있도록 수정 필요
https://github.com/jrialland/ajp-client
마치며
해당 AJP 프로토콜은 중계 서버 또는 신뢰된 서버간의 서버 투 서버 통신에 많이 활용될 수 있다.
- HTTP 보다 더빠른 프로토콜(바이너리 프로토콜)
- TCP Connection Pool의 사용(HTTP는 Stateless 프로토콜, Conection Pool을 구성해도 URI 한정)
- 확장성 용이( 많은 WAS에서 지원)
- 재밌다
레퍼런스
https://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html
The Apache Tomcat Connectors - AJP Protocol Reference (1.2.x) - AJPv13
The container asks for more data from the request (If the body was too large to fit in the first packet sent over or when the request is chuncked). The server will send a body packet back with an amount of data which is the minimum of the request_length, t
tomcat.apache.org
https://developer.jboss.org/blogs/mladen.turk/2007/07/16/comparing-modproxy-and-modjk?_sscc=t
Mladen Turk's Blog: Comparing mod_proxy and mod_jk |JBoss Developer
developer.jboss.org
https://github.com/jrialland/ajp-client
jrialland/ajp-client
java implementation of an ajp13 protocol client, allowing to send requests to a servlet container using this protocol. - jrialland/ajp-client
github.com
'개발관련 > 삽질' 카테고리의 다른 글
SQLite 개념/구조/멀티 DB 실사용기 (0) | 2020.01.08 |
---|---|
AOP(SpringAOP/AspectJ) (0) | 2019.12.02 |
Insert Multiple - Oracle(Tibero) 포팅 삽질기 (0) | 2019.09.11 |
JWT를 분석하고 사용해보자 (3/3) (0) | 2019.08.13 |
JWT를 분석하고 사용해보자 (2/3) (0) | 2019.08.13 |