Feature: Make transport-netty-http/transport-simple-http support posting
This commit is contained in:
parent
b02ef82c62
commit
aaeeea37e5
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package com.alibaba.csp.sentinel.transport.command.netty;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -39,10 +40,15 @@ import io.netty.handler.codec.http.FullHttpRequest;
|
|||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||
import io.netty.handler.codec.http.HttpHeaderValues;
|
||||
import io.netty.handler.codec.http.HttpMethod;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.HttpUtil;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import io.netty.handler.codec.http.QueryStringDecoder;
|
||||
import io.netty.handler.codec.http.multipart.HttpData;
|
||||
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
|
||||
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
|
||||
import io.netty.handler.codec.http.multipart.InterfaceHttpData.HttpDataType;
|
||||
|
||||
import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;
|
||||
import static io.netty.handler.codec.http.HttpResponseStatus.INTERNAL_SERVER_ERROR;
|
||||
|
|
@ -171,6 +177,32 @@ public class HttpServerHandler extends SimpleChannelInboundHandler<Object> {
|
|||
}
|
||||
}
|
||||
}
|
||||
// Deal with post method, parameter in post has more privilege compared to that in querystring
|
||||
if (request.method().equals(HttpMethod.POST)) {
|
||||
// support multi-part and form-urlencoded
|
||||
HttpPostRequestDecoder postRequestDecoder = null;
|
||||
try {
|
||||
postRequestDecoder = new HttpPostRequestDecoder(request);
|
||||
for (InterfaceHttpData data : postRequestDecoder.getBodyHttpDatas()) {
|
||||
data.retain(); // must retain each attr before destroy
|
||||
if (data.getHttpDataType() == HttpDataType.Attribute) {
|
||||
if (data instanceof HttpData) {
|
||||
HttpData httpData = (HttpData) data;
|
||||
try {
|
||||
String name = httpData.getName();
|
||||
String value = httpData.getString();
|
||||
serverRequest.addParam(name, value);
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (postRequestDecoder != null) {
|
||||
postRequestDecoder.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Parse command name.
|
||||
String target = parseTarget(queryStringDecoder.rawPath());
|
||||
serverRequest.addMetadata(HttpCommandUtils.REQUEST_TARGET, target);
|
||||
|
|
|
|||
|
|
@ -75,6 +75,61 @@ public class HttpEventTask implements Runnable {
|
|||
CommandCenterLog.info("[SimpleHttpCommandCenter] socket income: " + line
|
||||
+ "," + socket.getInetAddress());
|
||||
CommandRequest request = parseRequest(line);
|
||||
|
||||
if (line.length() > 4 && StringUtil.equalsIgnoreCase("POST", line.substring(0, 4))) {
|
||||
// Deal with post method
|
||||
// Now simple-http only support form-encoded post request.
|
||||
String bodyLine = null;
|
||||
boolean bodyNext = false;
|
||||
boolean supported = false;
|
||||
int maxLength = 8192;
|
||||
while (true) {
|
||||
// Body processing
|
||||
if (bodyNext) {
|
||||
if (!supported) {
|
||||
break;
|
||||
}
|
||||
char[] bodyBytes = new char[maxLength];
|
||||
int read = in.read(bodyBytes);
|
||||
String postData = new String(bodyBytes, 0, read);
|
||||
parseParams(postData, request);
|
||||
break;
|
||||
}
|
||||
|
||||
bodyLine = in.readLine();
|
||||
if (bodyLine == null) {
|
||||
break;
|
||||
}
|
||||
// Body seperator
|
||||
if (StringUtil.isEmpty(bodyLine)) {
|
||||
bodyNext = true;
|
||||
continue;
|
||||
}
|
||||
// Header processing
|
||||
int index = bodyLine.indexOf(":");
|
||||
if (index < 1) {
|
||||
continue;
|
||||
}
|
||||
String headerName = bodyLine.substring(0, index);
|
||||
String header = bodyLine.substring(index + 1).trim();
|
||||
if (StringUtil.equalsIgnoreCase("content-type", headerName)) {
|
||||
if (StringUtil.equals("application/x-www-form-urlencoded", header)) {
|
||||
supported = true;
|
||||
} else {
|
||||
// not support request
|
||||
break;
|
||||
}
|
||||
} else if (StringUtil.equalsIgnoreCase("content-length", headerName)) {
|
||||
try {
|
||||
int len = new Integer(header);
|
||||
if (len > 0) {
|
||||
maxLength = len;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate the target command.
|
||||
String commandName = HttpCommandUtils.getTarget(request);
|
||||
|
|
@ -203,7 +258,12 @@ public class HttpEventTask implements Runnable {
|
|||
return request;
|
||||
}
|
||||
String parameterStr = line.substring(ask != -1 ? ask + 1 : 0, space != -1 ? space : line.length());
|
||||
for (String parameter : parameterStr.split("&")) {
|
||||
parseParams(parameterStr, request);
|
||||
return request;
|
||||
}
|
||||
|
||||
private void parseParams(String queryString, CommandRequest request) {
|
||||
for (String parameter : queryString.split("&")) {
|
||||
if (StringUtil.isBlank(parameter)) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -221,7 +281,6 @@ public class HttpEventTask implements Runnable {
|
|||
|
||||
request.addParam(StringUtil.trim(keyValue[0]), value);
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
private static final String SERVER_ERROR_MESSAGE = "Command server error";
|
||||
|
|
|
|||
Loading…
Reference in New Issue