class IMAction extends Action {

    @Override
    public boolean action(Request request, Response response) {<FILL_FUNCTION_BODY>}

    private void sendResponse(Response response, ErrorCode errorCode, byte[] contents) {
        response.setStatus(HttpResponseStatus.OK);
        if(contents == null) {
            ByteBuf ackPayload = Unpooled.buffer();
            ackPayload.ensureWritable(1).writeByte(errorCode.getCode());
            response.setContent(ackPayload);
        } else {
            response.setContent(contents);
        }
        response.send();
    }
}

        if (request.getNettyRequest() instanceof FullHttpRequest) {

            FullHttpRequest fullHttpRequest = (FullHttpRequest)request.getNettyRequest();
            byte[] bytes = Utils.readBytesAndRewind(fullHttpRequest.content());

            String str = new String(bytes);
            try {
                bytes = Base64.getDecoder().decode(str);
            } catch (IllegalArgumentException e) {
                sendResponse(response, ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH, null);
                return true;
            }

            String cid = fullHttpRequest.headers().get("cid");
            byte[] cbytes = Base64.getDecoder().decode(cid);
            cbytes = AES.AESDecrypt(cbytes, "", true);
            if (cbytes == null) {
                sendResponse(response, ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH, null);
                return true;
            }
            cid = new String(cbytes);

            MemorySessionStore.Session session = sessionsStore.getSession(cid);

            if (session != null) {
                bytes = AES.AESDecrypt(bytes, session.getSecret(), true);
            } else {
                sendResponse(response, ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH, null);
                return true;
            }


            if (bytes == null) {
                sendResponse(response, ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH, null);
                return true;
            }

            try {
                WFCMessage.IMHttpWrapper wrapper = WFCMessage.IMHttpWrapper.parseFrom(bytes);
                String token = wrapper.getToken();
                String userId = Tokenor.getUserId(token.getBytes());
                if (userId == null) {
                    sendResponse(response, ErrorCode.ERROR_CODE_TOKEN_ERROR, null);
                } else {
                    if(messagesStore.getUserStatus(userId) == ProtoConstants.UserStatus.Forbidden) {
                        sendResponse(response, ErrorCode.ERROR_CODE_USER_BLOCKED, null);
                        return true;
                    }

                    ServerAPIHelper.sendRequest(userId, wrapper.getClientId(), wrapper.getRequest(), wrapper.getData().toByteArray(), new ServerAPIHelper.Callback() {
                        @Override
                        public void onSuccess(byte[] result) {
                            sendResponse(response, null, result);
                        }

                        @Override
                        public void onError(ErrorCode errorCode) {
                            sendResponse(response, errorCode, null);
                        }

                        @Override
                        public void onTimeout() {
                            sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
                        }

                        @Override
                        public Executor getResponseExecutor() {
                            return command -> {
                                ctx.executor().execute(command);
                            };
                        }
                    }, ProtoConstants.RequestSourceType.Request_From_User);
                    return false;
                }
            } catch (InvalidProtocolBufferException e) {
                sendResponse(response, ErrorCode.ERROR_CODE_INVALID_DATA, null);
            }
        }
        return true;
    
<methods>public non-sealed void <init>() ,public abstract boolean action(com.xiaoleilu.loServer.handler.Request, com.xiaoleilu.loServer.handler.Response) ,public boolean doAction(com.xiaoleilu.loServer.handler.Request, com.xiaoleilu.loServer.handler.Response) ,public static void init(io.moquette.server.config.IConfig) ,public boolean isTransactionAction() ,public cn.wildfirechat.common.ErrorCode preAction(com.xiaoleilu.loServer.handler.Request, com.xiaoleilu.loServer.handler.Response) <variables>protected static win.liyufan.im.RateLimiter adminLimiter,protected static win.liyufan.im.RateLimiter channelLimiter,protected static boolean closeApiVersion,public ChannelHandlerContext ctx,protected static final com.google.gson.Gson gson,public static io.moquette.spi.IMessagesStore messagesStore,protected static win.liyufan.im.RateLimiter robotLimiter,public static io.moquette.spi.ISessionsStore sessionsStore