Просмотр исходного кода

Feature: Make transport-netty-http/transport-simple-http support posting

master
jason Eric Zhao 5 лет назад
Родитель
Сommit
aaeeea37e5
2 измененных файлов: 93 добавлений и 2 удалений
  1. +32
    -0
      sentinel-transport/sentinel-transport-netty-http/src/main/java/com/alibaba/csp/sentinel/transport/command/netty/HttpServerHandler.java
  2. +61
    -2
      sentinel-transport/sentinel-transport-simple-http/src/main/java/com/alibaba/csp/sentinel/transport/command/http/HttpEventTask.java

+ 32
- 0
sentinel-transport/sentinel-transport-netty-http/src/main/java/com/alibaba/csp/sentinel/transport/command/netty/HttpServerHandler.java Просмотреть файл

@@ -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);


+ 61
- 2
sentinel-transport/sentinel-transport-simple-http/src/main/java/com/alibaba/csp/sentinel/transport/command/http/HttpEventTask.java Просмотреть файл

@@ -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";


Загрузка…
Отмена
Сохранить