Netty series: Handling CORS in netty

Posted by happyneil on Sat, 18 Sep 2021 05:51:38 +0200

brief introduction

The full name of CORS is cross domain resource sharing. It is a mechanism based on HTTP header detection. By controlling HTTP header, the permission management function of cross domain resources can be realized. In the previous CORS detailed article, we have a basic explanation of CORS.

This article will explain how to implement CORS in netty from the perspective of netty implementation.

CORS configuration of server

Friends familiar with CORS should know that all operations of CORS are realized by controlling HTTP headers on top of HTTP protocol. Therefore, if you want to implement CORS support on the server side, you can actually set the HTTP protocol header.

For your convenience, netty provides a CorsConfig class to unify the header settings of CORS.

First look at the attributes defined in the CorsConfig class:

    private final Set<String> origins;
    private final boolean anyOrigin;
    private final boolean enabled;
    private final Set<String> exposeHeaders;
    private final boolean allowCredentials;
    private final long maxAge;
    private final Set<HttpMethod> allowedRequestMethods;
    private final Set<String> allowedRequestHeaders;
    private final boolean allowNullOrigin;
    private final Map<CharSequence, Callable<?>> preflightHeaders;
    private final boolean shortCircuit;

These properties correspond to the HTTP header settings of CORS one-to-one. For example, origins means allowed sources, and anyOrigin means allowed all sources.

It corresponds to the following settings:

Origin: <origin>

exposeHeaders is a one-to-one correspondence with access control expose headers, which means that the server side allows the client to access the header information while obtaining CORS resources. The format is as follows:

Access-Control-Expose-Headers: <header-name>[, <header-name>]*

allowCredentials indicates whether to enable CORS permission authentication. Indicates whether the server side accepts the client's request with the credentials field. If it is used in preflight request, it indicates whether subsequent real requests support credentials. Its format is as follows:

Access-Control-Allow-Credentials: true

allowedRequestMethods refers to the methods allowed to access resources. It is mainly used in preflight request. The format is as follows:

Access-Control-Allow-Methods: <method>[, <method>]*

allowedRequestHeaders is used in preflight request to represent the header field that can really be used for requests. Its format is as follows:

Access-Control-Allow-Headers: <header-name>[, <header-name>]*

When the client sends OPTIONS methods to the server, for security reasons, because the server may not be able to accept these OPTIONS methods, the client needs to send one first
Preflight requests: wait for the server to respond, and then send the real request after the server confirms. Let's give an example. Preflight headers represent the preflight request headers allowed by the server.

shortCircuit indicates whether the request is a valid CORS request. If the request is rejected, a true will be returned.

CorsConfigBuilder

CorsConfig is used to represent the configuration class of Cors, so how to construct this configuration class? Let's look at the constructor of CorsConfig:

    CorsConfig(final CorsConfigBuilder builder) {
        origins = new LinkedHashSet<String>(builder.origins);
        anyOrigin = builder.anyOrigin;
        enabled = builder.enabled;
        exposeHeaders = builder.exposeHeaders;
        allowCredentials = builder.allowCredentials;
        maxAge = builder.maxAge;
        allowedRequestMethods = builder.requestMethods;
        allowedRequestHeaders = builder.requestHeaders;
        allowNullOrigin = builder.allowNullOrigin;
        preflightHeaders = builder.preflightHeaders;
        shortCircuit = builder.shortCircuit;
    }

You can see that CorsConfig is constructed through CorsConfigBuilder. You can set various properties in CorsConfigBuilder. CorsConfigBuilder provides a variety of methods to set properties.

You can use this method to construct CorsConfig as follows:

CorsConfig corsConfig = CorsConfigBuilder.forAnyOrigin().allowNullOrigin().allowCredentials().build();

CorsHandler

With corsConfig, we also need to configure this config in the handler of netty. Netty provides a CorsHandler class to deal with corsConfig. This class is called CorsHandler.

First, take a look at the constructor of CorsHandler:

    public CorsHandler(final CorsConfig config) {
        this(Collections.singletonList(checkNotNull(config, "config")), config.isShortCircuit());
    }

    public CorsHandler(final List<CorsConfig> configList, boolean isShortCircuit) {
        checkNonEmpty(configList, "configList");
        this.configList = configList;
        this.isShortCircuit = isShortCircuit;
    }

CorsHandler has two constructors, one is to pass in CorsConfig, and the other is to pass in a list of CorsConfig.

The main working principle of CorsHandler is to process the responseHeader and set the CORS header during channelRead.

netty support for cors

We have talked about the core classes and methods of cors in netty. The last step is to add the supporting classes of cors to the pipeline of netty. The core code is as follows:

    public void initChannel(SocketChannel ch) {

        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast(new HttpResponseEncoder());
        pipeline.addLast(new HttpRequestDecoder());
        pipeline.addLast(new HttpObjectAggregator(65536));
        pipeline.addLast(new ChunkedWriteHandler());

        CorsConfig corsConfig = CorsConfigBuilder.forAnyOrigin().allowNullOrigin().allowCredentials().build();
        pipeline.addLast(new CorsHandler(corsConfig));

        pipeline.addLast(new CustResponseHandler());
    }

summary

cors is relatively simple, and netty also provides sufficient method support for it. You can use it directly.

Examples of this article can be referred to: learn-netty4

This article has been included in http://www.flydean.com/22-netty-cors/

The most popular interpretation, the most profound dry goods, the most concise tutorial, and many tips you don't know are waiting for you to find!

Welcome to my official account: "those things in procedure", understand technology, know you better!

Topics: Java RESTful http