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