use of com.alipay.sofa.rpc.transport.netty.NettyByteBuffer in project sofa-rpc by sofastack.
the class AbstractHttpClientHandler method receiveHttpResponse.
public void receiveHttpResponse(FullHttpResponse msg) {
HttpHeaders headers = msg.headers();
ByteBuf content = msg.content();
NettyByteBuffer data = new NettyByteBuffer(content);
try {
if (msg.status() == HttpResponseStatus.OK) {
// 正常返回
final SofaResponse response = new SofaResponse();
String isError = headers.get(RemotingConstants.HEAD_RESPONSE_ERROR);
if (CommonUtils.isTrue(isError)) {
// 业务异常
String errorMsg = StringSerializer.decode(data.array());
Throwable throwable = new SofaRpcException(RpcErrorType.SERVER_BIZ, errorMsg);
response.setAppResponse(throwable);
} else {
// 获取序列化类型
if (data.readableBytes() > 0) {
byte serializeType;
String codeName = headers.get(RemotingConstants.HEAD_SERIALIZE_TYPE);
if (codeName != null) {
serializeType = HttpTransportUtils.getSerializeTypeByName(codeName);
} else {
// HEAD_SERIALIZE_TYPE 没设置的话 再取 content-type 兜底下
String contentType = StringUtils.toString(headers.get(HttpHeaderNames.CONTENT_TYPE));
serializeType = HttpTransportUtils.getSerializeTypeByContentType(contentType);
}
response.setSerializeType(serializeType);
content.retain();
response.setData(data);
}
}
onResponse(response);
} else {
// 系统异常
String errorMsg = StringSerializer.decode(data.array());
Throwable throwable = new SofaRpcException(RpcErrorType.SERVER_UNDECLARED_ERROR, errorMsg);
onException(throwable);
}
} catch (final Exception e) {
onException(e);
}
}
use of com.alipay.sofa.rpc.transport.netty.NettyByteBuffer in project sofa-rpc by sofastack.
the class Http1ServerChannelHandler method channelRead0.
@Override
public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
if (HttpUtil.is100ContinueExpected(req)) {
ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE));
}
boolean keepAlive = HttpUtil.isKeepAlive(req);
String uri = req.uri();
// ignore uris
if (RemotingConstants.IGNORE_WEB_BROWSER.equals(uri)) {
sendHttp1Response(ctx, HttpResponseStatus.OK, StringUtils.EMPTY, keepAlive);
return;
}
HttpMethod reqMethod = req.method();
// HEAD for check method exists
if (reqMethod == HttpMethod.HEAD) {
String[] iam = HttpTransportUtils.getInterfaceIdAndMethod(uri);
boolean exists = serverHandler.checkService(iam[0], iam[1]);
sendHttp1Response(ctx, exists ? HttpResponseStatus.OK : HttpResponseStatus.NOT_FOUND, "", keepAlive);
return;
}
// POST(primary) / GET for invoke
if (reqMethod != HttpMethod.POST && reqMethod != HttpMethod.GET) {
sendHttp1Response(ctx, HttpResponseStatus.BAD_REQUEST, "Only support GET/POST/HEAD", keepAlive);
return;
}
// call service
SofaRequest sofaRequest = new SofaRequest();
try {
String[] iam = HttpTransportUtils.getInterfaceIdAndMethod(uri);
String serviceName = iam[0];
String methodName = iam[1];
sofaRequest.setTargetServiceUniqueName(serviceName);
sofaRequest.setMethodName(methodName);
parseHeader(req, sofaRequest);
if (reqMethod == HttpMethod.GET) {
Method method = ReflectCache.getMethodCache(serviceName, methodName);
if (method == null) {
sendHttp1Response(ctx, HttpResponseStatus.NOT_FOUND, "Not found method:" + serviceName + "." + methodName, keepAlive);
return;
}
String params = null;
Class[] classArray = method.getParameterTypes();
int length = classArray.length;
Object[] paramList = new Object[length];
int i = uri.indexOf('?');
if (i >= 0) {
params = uri.substring(i + 1);
paramList = this.parseParamArg(classArray, params);
} else {
if (length != 0) {
throw new SofaRpcException(RpcErrorType.SERVER_DESERIALIZE, "The number of parameter is wrong.");
}
}
sofaRequest.setMethodArgSigs(ReflectCache.getMethodSigsCache(serviceName, methodName));
sofaRequest.setMethodArgs(paramList);
} else {
sofaRequest.setData(new NettyByteBuffer(req.content()));
}
} catch (Exception e) {
String message = "Failed to parse http2 request for uri " + uri + " form " + NetUtils.channelToString(ctx.channel().remoteAddress(), ctx.channel().localAddress()) + ", cause by: " + e.getMessage();
if (LOGGER.isWarnEnabled()) {
LOGGER.warn(message, e);
}
sendHttp1Response(ctx, HttpResponseStatus.BAD_REQUEST, message, keepAlive);
return;
}
try {
serverHandler.handleHttp1Request(sofaRequest, ctx, keepAlive);
} catch (SofaRpcException e) {
int type = e.getErrorType();
if (type == RpcErrorType.SERVER_BUSY) {
sendHttp1Response(ctx, HttpResponseStatus.SERVICE_UNAVAILABLE, e.getMessage(), keepAlive);
} else if (type == RpcErrorType.SERVER_NOT_FOUND_INVOKER) {
sendHttp1Response(ctx, HttpResponseStatus.NOT_FOUND, e.getMessage(), keepAlive);
} else {
sendHttp1Response(ctx, HttpResponseStatus.INTERNAL_SERVER_ERROR, e.getMessage(), keepAlive);
}
} catch (Exception e) {
sendHttp1Response(ctx, HttpResponseStatus.INTERNAL_SERVER_ERROR, e.getMessage(), keepAlive);
}
}
use of com.alipay.sofa.rpc.transport.netty.NettyByteBuffer in project sofa-rpc by sofastack.
the class Http2ServerChannelHandler method handleRequest.
protected void handleRequest(ChannelHandlerContext ctx, int streamId, Http2Headers http2Headers, ByteBuf data) {
String uri = StringUtils.defaultString(http2Headers.path());
// ignore uris
if (RemotingConstants.IGNORE_WEB_BROWSER.equals(uri)) {
sendHttp2Response(ctx, streamId, HttpResponseStatus.OK, StringUtils.EMPTY);
return;
}
CharSequence reqMethod = StringUtils.defaultString(http2Headers.method());
// HEAD for check method exists
if (reqMethod.equals(HttpMethod.HEAD.name())) {
String[] iam = HttpTransportUtils.getInterfaceIdAndMethod(uri);
boolean exists = serverHandler.checkService(iam[0], iam[1]);
sendHttp2Response(ctx, streamId, exists ? HttpResponseStatus.OK : HttpResponseStatus.NOT_FOUND, null);
return;
} else // POST(primary) / GET for invoke
if (!reqMethod.equals(HttpMethod.POST.name())) {
sendHttp2Response(ctx, streamId, HttpResponseStatus.BAD_REQUEST, "Only support POST/HEAD");
return;
}
/**
* https://http2.github.io/http2-spec/#rfc.section.5.1.1 second paragraph
* only when in upgrade h2c mode, 0x01 cannot be selected as a new stream identifier.
* some gateway or proxy product, use 0x01 as first normal request's stream id when
* in prior knowleadge mode.
*/
if (this.isUpgradeH2cMode && streamId > 1 || !this.isUpgradeH2cMode && streamId > 0) {
// 本来这里可以提前检查接口方法是否存在,但是为了日志统一,全部放到serverHandler里去
SofaRequest sofaRequest = new SofaRequest();
try {
String[] iam = HttpTransportUtils.getInterfaceIdAndMethod(uri);
sofaRequest.setTargetServiceUniqueName(iam[0]);
sofaRequest.setMethodName(iam[1]);
sofaRequest.setData(new NettyByteBuffer(data));
parseHttp2Request(http2Headers, sofaRequest);
} catch (Exception e) {
String message = "Failed to parse http2 request for uri " + uri + " form " + NetUtils.channelToString(ctx.channel().remoteAddress(), ctx.channel().localAddress()) + ", cause by: " + e.getMessage();
if (LOGGER.isWarnEnabled()) {
LOGGER.warn(message, e);
}
sendHttp2Response(ctx, streamId, HttpResponseStatus.BAD_REQUEST, message);
return;
}
try {
serverHandler.handleHttp2Request(streamId, sofaRequest, ctx, encoder());
} catch (SofaRpcException e) {
int type = e.getErrorType();
if (type == RpcErrorType.SERVER_BUSY) {
sendHttp2Response(ctx, streamId, HttpResponseStatus.SERVICE_UNAVAILABLE, e.getMessage());
} else if (type == RpcErrorType.SERVER_NOT_FOUND_INVOKER) {
sendHttp2Response(ctx, streamId, HttpResponseStatus.NOT_FOUND, e.getMessage());
} else {
sendHttp2Response(ctx, streamId, HttpResponseStatus.INTERNAL_SERVER_ERROR, e.getMessage());
}
} catch (Exception e) {
sendHttp2Response(ctx, streamId, HttpResponseStatus.INTERNAL_SERVER_ERROR, e.getMessage());
}
}
}
Aggregations