class RnHttpContext extends WebContextBase {
    private final HttpServerRequest _request;
    private final HttpServerResponse _response;
    private final HttpRequestParser _request_parse;
    public RnHttpContext(HttpServerRequest request, HttpServerResponse response, HttpRequestParser request_parse) {
        _request = request;
        _response = response;

        try {
            _request_parse = request_parse.parse();
        }catch (Exception ex){
            throw new RuntimeException(ex);
        }
    }

    @Override
    public Object request() {
        return _request;
    }

    @Override
    public String remoteIp() {
        return _request.remoteAddress().getAddress().getHostAddress();
    }

    @Override
    public int remotePort() {
        return _request.remoteAddress().getPort();
    }

    @Override
    public String method() {
        return _request.method().name();
    }

    @Override
    public String protocol() {
        return _request.version().protocolName();
    }

    private URI _uri;
    @Override
    public URI uri() {
        if(_uri == null){
            _uri = URI.create(url());
        }
        return _uri;
    }

    @Override
    public boolean isSecure() {
        return "https".equals(uri().getScheme());
    }

    private String _url;
    @Override
    public String url() {
        if (_url == null) {
            _url = _request.uri();

            if (_url != null && _url.startsWith("/")) {
                _url = _request.scheme()+"://" + header("Host") + _url;
            }
        }

        return _url;
    }

    @Override
    public long contentLength() {
        return _request.receiveContent().count().block();
    }

    @Override
    public String contentType() {
        return header("Content-Type");
    }

    @Override
    public String queryString() {
        return null;
    }

    @Override
    public InputStream bodyAsStream() throws IOException {
        return _request.receive().asInputStream().blockFirst();
    }


    private NvMap _paramMap;
    @Override
    public NvMap paramMap() {
        if(_paramMap == null){
            _paramMap = new NvMap();

            _request_parse.parmMap.forEach((k,l)->{
                if(l.size() > 0){
                    _paramMap.put(k,l.get(0));
                }
            });
        }

        return _paramMap;
    }

    @Override
    public Map<String, List<String>> paramsMap() {
        return _request_parse.parmMap;
    }

    @Override
    public Map<String, List<UploadedFile>> filesMap() throws IOException {
        return _request_parse.fileMap;
    }


    private NvMap _cookieMap;
    @Override
    public NvMap cookieMap() {
        if(_cookieMap == null){
            _cookieMap = new NvMap();

            String _cookieMapStr = _request.requestHeaders().get(COOKIE);
            if (_cookieMapStr != null) {
                Set<Cookie> tmp = ServerCookieDecoder.LAX.decode(_cookieMapStr);

                for(Cookie c1 :tmp){
                    _cookieMap.put(c1.name(),c1.value());
                }
            }
        }

        return _cookieMap;
    }

    private NvMap _headerMap;
    @Override
    public NvMap headerMap() {
        if(_headerMap == null) {
            _headerMap = new NvMap();
            HttpHeaders headers = _request.requestHeaders();

            for(Map.Entry<String, String> kv : headers){
                _headerMap.put(kv.getKey(), kv.getValue());
            }
        }

        return _headerMap;
    }

    private Map<String, List<String>> _headersMap;
    @Override
    public Map<String, List<String>> headersMap() {
        if (_headersMap == null) {
            _headersMap = new IgnoreCaseMap<>();

            HttpHeaders headers = _request.requestHeaders();

            for (Map.Entry<String, String> kv : headers) {
                List<String> values = _headersMap.get(kv.getKey());
                if (values == null) {
                    values = new ArrayList<>();
                    _headersMap.put(kv.getKey(), values);
                }

                values.add(kv.getValue());
            }
        }
        return _headersMap;
    }

    @Override
    public Object response() {
        return _response;
    }

    @Override
    protected void contentTypeDoSet(String contentType) {
        if (charset != null) {
            if (contentType.indexOf(";") < 0) {
                headerSet("Content-Type", contentType + ";charset=" + charset);
                return;
            }
        }

        headerSet("Content-Type", contentType);
    }

    @Override
    public OutputStream outputStream() throws IOException{
        return _outputStream;
    }

    @Override
    public void output(byte[] bytes) {
        try {
            OutputStream out = outputStream();

            out.write(bytes);
        }catch (Throwable ex){
            throw new RuntimeException(ex);
        }
    }

    @Override
    public void output(InputStream stream) {
        try {
            OutputStream out = outputStream();

            IoUtil.transferTo(stream, out);
        }catch (Throwable ex){
            throw new RuntimeException(ex);
        }
    }

    protected ByteBufOutputStream _outputStream = new ByteBufOutputStream(Unpooled.buffer());

    @Override
    public void headerSet(String key, String val) {
        _response.header(key,val);
    }

    @Override
    public void headerAdd(String key, String val) {
        _response.addHeader(key,val);
    }

    @Override
    public String headerOfResponse(String name) {
        return null;
    }

    @Override
    public void cookieSet(String key, String val, String domain, String path, int maxAge) {<FILL_FUNCTION_BODY>}

    @Override
    public void redirect(String url, int code) {
        url = RedirectUtils.getRedirectPath(url);

        headerSet(Constants.HEADER_LOCATION, url);
        statusDoSet(code);
    }

    @Override
    public int status() {
        return _status;
    }

    private int _status = 200;

    @Override
    protected void statusDoSet(int status) {
        _status = status;
        _response.status(status);
    }

    @Override
    public void flush() throws IOException {
        //不用实现
    }

    @Override
    public void close() throws IOException {

    }

    @Override
    public boolean asyncSupported() {
        return false;
    }

    @Override
    public void asyncStart(long timeout, ContextAsyncListener listener) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void asyncComplete() {
        throw new UnsupportedOperationException();
    }
}

        StringBuilder sb = new StringBuilder();
        sb.append(key).append("=").append(val).append(";");

        if (Utils.isNotEmpty(path)) {
            sb.append("path=").append(path).append(";");
        }

        if (maxAge >= 0) {
            sb.append("max-age=").append(maxAge).append(";");
        }

        if (Utils.isNotEmpty(domain)) {
            sb.append("domain=").append(domain.toLowerCase()).append(";");
        }

        _response.addHeader(SET_COOKIE, sb.toString());
    
<methods>public non-sealed void <init>() ,public java.lang.String contentCharset() ,public java.lang.String contentType() ,public void filesDelete() throws java.io.IOException,public void outputAsFile(org.noear.solon.core.handle.DownloadedFile) throws java.io.IOException,public void outputAsFile(java.io.File) throws java.io.IOException,public final T session(java.lang.String, Class<T>) ,public final double sessionAsDouble(java.lang.String) ,public final double sessionAsDouble(java.lang.String, double) ,public final int sessionAsInt(java.lang.String) ,public final int sessionAsInt(java.lang.String, int) ,public final long sessionAsLong(java.lang.String) ,public final long sessionAsLong(java.lang.String, long) ,public final void sessionClear() ,public final java.lang.String sessionId() ,public final T sessionOrDefault(java.lang.String, T) ,public final void sessionRemove(java.lang.String) ,public final void sessionSet(java.lang.String, java.lang.Object) <variables>protected Map<java.lang.String,List<org.noear.solon.core.handle.UploadedFile>> _filesMap,private java.lang.String contentCharset