HTTP手动解析CHUNKED传输报文

HTTP返回response头信息中

带有Transfer-Encoding = chunked表示使用chunked封包传输

 

Chunked格式:

 

0000-000F   48 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 0d   HTTP/1.1 200 OK.

0010-001F   0a 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 74   .Content-Type: t

0020-002F   65 78 74 2f 70 6c 61 69 6e 0d 0a 54 72 61 6e 73   ext/plain..Trans

0030-003F   66 65 72 2d 45 6e 63 6f 64 69 6e 67 3a 20 63 68   fer-Encoding: ch

0040-004F   75 6e 6b 65 64 0d 0a 0d 0a 32 35 0d 0a 54 68 69   unked....25..Thi

0050-005F   73 20 69 73 20 74 68 65 20 64 61 74 61 20 69 6e   s is the data in

0060-006F   20 74 68 65 20 66 69 72 73 74 20 63 68 75 6e 6b    the first chunk

0070-007F   0d 0a 0d 0a 31 41 0d 0a 61 6e 64 20 74 68 69 73   ....1A..and this

0080-008F   20 69 73 20 74 68 65 20 73 65 63 6f 6e 64 20 6f    is the second o

0090-009F   6e 65 0d 0a 30 0d 0a 0d 0a                                     ne..0....

 

 

 

StringBuilder sb = new StringBuilder();
sb.append("HTTP/1.1 200 OK\r\n");
sb.append("Content-Type: text/plain\r\n");
sb.append("Transfer-Encoding: chunked\r\n\r\n");
sb.append("25\r\n");		
sb.append("This is the data in the first chunk\r\n"); // 37 bytes
sb.append("\r\n1A\r\n");
sb.append("and this is the second one"); // 26 bytes
sb.append("\r\n0\r\n\r\n");

 

 

十六进制包长+\r\n+报文包+\r\n  为一个传输单元

0+\r\n+\r\n 当遇到这种空传输单元时结束

 

Chunked解析:

 

public static void main(String[] args) {
	StringBuilder sb = new StringBuilder();
	sb.append("25\r\n");
	sb.append("This is the data in the first chunk\r\n");
	sb.append("\r\n1A\r\n");
	sb.append("and this is the second one");
	sb.append("\r\n0\r\n\r\n");
	ByteBuffer in = ByteBuffer.allocate(1024);
	in.put(sb.toString().getBytes());
	in.flip();
	int start = in.position();
	int end = in.limit();
	ByteBuffer content = ByteBuffer.allocate(1024);
	while (true) { // 封包循环
		for (int i = start; i < end - 1; i++) {
			if (in.get(i) == 0x0D && in.get(i + 1) == 0x0A) {
				byte[] nums = new byte[i - start];
				in.get(nums);
				// 丢弃\r\n
				in.get(new byte[2]);
				int num = Integer.parseInt(new String(nums), 16);
				byte[] strs = new byte[num];
				in.get(strs);
				content.put(strs);
				// 丢弃\r\n
				in.get(new byte[2]);
				start = i + 4 + num;
				break;
			}
		}
		if (in.get(start) == 0x30 && in.get(start + 1) == 0x0D && in.get(start + 2) == 0x0A && in.get(start + 3) == 0x0D && in.get(start + 4) == 0x0A) {
			content.flip();
			in.get(new byte[5]);
			break;
		}
	}
	System.out.println(new String(content.array(), 0, content.limit()));
}

  
因为主流Http Server都将Chunked解析代码封装好了,只有自己编写socket或是mina开发中会遇到
所以给出个采用NIO的Buffer传输的示例,若用字节流或是byte[]需要稍作修改

你可能感兴趣的:(socket,ext,Mina)