151 lines
5.5 KiB
Java
151 lines
5.5 KiB
Java
/*
|
|
* To change this license header, choose License Headers in Project Properties.
|
|
* To change this template file, choose Tools | Templates
|
|
* and open the template in the editor.
|
|
*/
|
|
package org.redkale.mq;
|
|
|
|
import java.net.HttpCookie;
|
|
import java.nio.ByteBuffer;
|
|
import java.util.*;
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
import org.redkale.convert.Convert;
|
|
import org.redkale.convert.json.JsonConvert;
|
|
import static org.redkale.mq.MessageCoder.*;
|
|
import org.redkale.net.http.HttpResult;
|
|
import org.redkale.util.Utility;
|
|
|
|
/**
|
|
* HttpResult的MessageCoder实现
|
|
*
|
|
* <p>
|
|
* 详情见: https://redkale.org
|
|
*
|
|
* @author zhangjx
|
|
*
|
|
* @since 2.1.0
|
|
*/
|
|
public class HttpResultCoder implements MessageCoder<HttpResult> {
|
|
|
|
private static final HttpResultCoder instance = new HttpResultCoder();
|
|
|
|
public static HttpResultCoder getInstance() {
|
|
return instance;
|
|
}
|
|
|
|
//消息内容的类型
|
|
@Override
|
|
public byte ctype() {
|
|
return MessageRecord.CTYPE_HTTP_RESULT;
|
|
}
|
|
|
|
@Override
|
|
public byte[] encode(HttpResult data) {
|
|
if (data == null) {
|
|
return null;
|
|
}
|
|
byte[] contentType = MessageCoder.getBytes(data.getContentType());
|
|
byte[] headers = MessageCoder.getBytes(data.getHeaders());
|
|
byte[] cookies = getBytes(data.getCookies());
|
|
byte[] content;
|
|
if (data.getResult() == null) {
|
|
content = new byte[0]; //""
|
|
} else if (data.getResult() instanceof byte[]) {
|
|
content = (byte[]) data.getResult();
|
|
} else if (data.getResult() instanceof CharSequence) {
|
|
content = MessageCoder.getBytes(data.getResult().toString());
|
|
} else {
|
|
Convert cc = data.convert();
|
|
if (cc == null) {
|
|
cc = JsonConvert.root();
|
|
}
|
|
content = cc.convertToBytes(data.getResult());
|
|
}
|
|
int count = 4 + 2 + contentType.length + headers.length + cookies.length + 4 + (content == null ? 0 : content.length);
|
|
final byte[] bs = new byte[count];
|
|
ByteBuffer buffer = ByteBuffer.wrap(bs);
|
|
buffer.putInt(data.getStatus());
|
|
buffer.putChar((char) contentType.length);
|
|
if (contentType.length > 0) {
|
|
buffer.put(contentType);
|
|
}
|
|
buffer.put(headers);
|
|
buffer.put(cookies);
|
|
if (content == null || content.length == 0) {
|
|
buffer.putInt(0);
|
|
} else {
|
|
buffer.putInt(content.length);
|
|
buffer.put(content);
|
|
}
|
|
return bs;
|
|
}
|
|
|
|
@Override
|
|
public HttpResult<byte[]> decode(byte[] data) {
|
|
if (data == null) {
|
|
return null;
|
|
}
|
|
ByteBuffer buffer = ByteBuffer.wrap(data);
|
|
HttpResult result = new HttpResult();
|
|
result.setStatus(buffer.getInt());
|
|
result.setContentType(MessageCoder.getShortString(buffer));
|
|
result.setHeaders(MessageCoder.getMap(buffer));
|
|
result.setCookies(getCookieList(buffer));
|
|
int len = buffer.getInt();
|
|
if (len > 0) {
|
|
byte[] bs = new byte[len];
|
|
buffer.get(bs);
|
|
result.setResult(bs);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static byte[] getBytes(final List<HttpCookie> list) {
|
|
if (list == null || list.isEmpty()) {
|
|
return new byte[2];
|
|
}
|
|
final AtomicInteger len = new AtomicInteger(2);
|
|
list.forEach(cookie -> {
|
|
len.addAndGet(2 + (cookie.getName() == null ? 0 : Utility.encodeUTF8Length(cookie.getName())));
|
|
len.addAndGet(2 + (cookie.getValue() == null ? 0 : Utility.encodeUTF8Length(cookie.getValue())));
|
|
len.addAndGet(2 + (cookie.getDomain() == null ? 0 : Utility.encodeUTF8Length(cookie.getDomain())));
|
|
len.addAndGet(2 + (cookie.getPath() == null ? 0 : Utility.encodeUTF8Length(cookie.getPath())));
|
|
len.addAndGet(2 + (cookie.getPortlist() == null ? 0 : Utility.encodeUTF8Length(cookie.getPortlist())));
|
|
len.addAndGet(8 + 1 + 1); //maxage Secure HttpOnly
|
|
});
|
|
final byte[] bs = new byte[len.get()];
|
|
final ByteBuffer buffer = ByteBuffer.wrap(bs);
|
|
buffer.putChar((char) list.size());
|
|
list.forEach(cookie -> {
|
|
putShortString(buffer, cookie.getName());
|
|
putShortString(buffer, cookie.getValue());
|
|
putShortString(buffer, cookie.getDomain());
|
|
putShortString(buffer, cookie.getPath());
|
|
putShortString(buffer, cookie.getPortlist());
|
|
buffer.putLong(cookie.getMaxAge());
|
|
buffer.put(cookie.getSecure() ? (byte) 1 : (byte) 0);
|
|
buffer.put(cookie.isHttpOnly() ? (byte) 1 : (byte) 0);
|
|
});
|
|
return bs;
|
|
}
|
|
|
|
public static List<HttpCookie> getCookieList(ByteBuffer buffer) {
|
|
int len = buffer.getChar();
|
|
if (len == 0) {
|
|
return null;
|
|
}
|
|
final List<HttpCookie> list = new ArrayList<>(len);
|
|
for (int i = 0; i < len; i++) {
|
|
HttpCookie cookie = new HttpCookie(getShortString(buffer), getShortString(buffer));
|
|
cookie.setDomain(getShortString(buffer));
|
|
cookie.setPath(getShortString(buffer));
|
|
cookie.setPortlist(getShortString(buffer));
|
|
cookie.setMaxAge(buffer.getLong());
|
|
cookie.setSecure(buffer.get() == 1);
|
|
cookie.setHttpOnly(buffer.get() == 1);
|
|
list.add(cookie);
|
|
}
|
|
return list;
|
|
}
|
|
}
|