Search in sources :

Example 1 with NettyByteBuffer

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);
    }
}
Also used : HttpHeaders(io.netty.handler.codec.http.HttpHeaders) ByteBuf(io.netty.buffer.ByteBuf) AbstractByteBuf(com.alipay.sofa.rpc.transport.AbstractByteBuf) SofaResponse(com.alipay.sofa.rpc.core.response.SofaResponse) NettyByteBuffer(com.alipay.sofa.rpc.transport.netty.NettyByteBuffer) SofaRpcException(com.alipay.sofa.rpc.core.exception.SofaRpcException) SofaRpcException(com.alipay.sofa.rpc.core.exception.SofaRpcException)

Example 2 with NettyByteBuffer

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);
    }
}
Also used : DefaultFullHttpResponse(io.netty.handler.codec.http.DefaultFullHttpResponse) SofaRequest(com.alipay.sofa.rpc.core.request.SofaRequest) Method(java.lang.reflect.Method) HttpMethod(io.netty.handler.codec.http.HttpMethod) SofaRpcException(com.alipay.sofa.rpc.core.exception.SofaRpcException) SofaRpcException(com.alipay.sofa.rpc.core.exception.SofaRpcException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) NettyByteBuffer(com.alipay.sofa.rpc.transport.netty.NettyByteBuffer) HttpMethod(io.netty.handler.codec.http.HttpMethod)

Example 3 with NettyByteBuffer

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());
        }
    }
}
Also used : SofaRequest(com.alipay.sofa.rpc.core.request.SofaRequest) NettyByteBuffer(com.alipay.sofa.rpc.transport.netty.NettyByteBuffer) SofaRpcException(com.alipay.sofa.rpc.core.exception.SofaRpcException) SofaRpcException(com.alipay.sofa.rpc.core.exception.SofaRpcException)

Aggregations

SofaRpcException (com.alipay.sofa.rpc.core.exception.SofaRpcException)3 NettyByteBuffer (com.alipay.sofa.rpc.transport.netty.NettyByteBuffer)3 SofaRequest (com.alipay.sofa.rpc.core.request.SofaRequest)2 SofaResponse (com.alipay.sofa.rpc.core.response.SofaResponse)1 AbstractByteBuf (com.alipay.sofa.rpc.transport.AbstractByteBuf)1 ByteBuf (io.netty.buffer.ByteBuf)1 DefaultFullHttpResponse (io.netty.handler.codec.http.DefaultFullHttpResponse)1 HttpHeaders (io.netty.handler.codec.http.HttpHeaders)1 HttpMethod (io.netty.handler.codec.http.HttpMethod)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 Method (java.lang.reflect.Method)1