2017-09-26 180 views
0

如何讓netty的CorsHandler關閉其連接?它在原點通過時默認關閉,但當原點不被允許時關閉。我用CorsHandler實例設置了一個這樣的服務器。如何關閉與netty的連接CorsHandler

import io.netty.bootstrap.ServerBootstrap; 
import io.netty.channel.*; 
import io.netty.channel.nio.NioEventLoopGroup; 
import io.netty.channel.socket.nio.NioServerSocketChannel; 
import io.netty.handler.codec.http.HttpMethod; 
import io.netty.handler.codec.http.HttpObjectAggregator; 
import io.netty.handler.codec.http.HttpServerCodec; 
import io.netty.handler.codec.http.cors.CorsConfigBuilder; 
import io.netty.handler.codec.http.cors.CorsHandler; 
import io.netty.handler.logging.LogLevel; 
import io.netty.handler.logging.LoggingHandler; 

/** 
* Runs netty with a CORS handler on 8080 
*/ 
public class NettyCorsApp { 
    private static final int PORT = 8080; 

    public static void main(String[] args) throws Exception { 
     EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); 
     try { 
      ServerBootstrap bootstrap = new ServerBootstrap() 
        .group(eventLoopGroup) 
        .handler(new LoggingHandler(LogLevel.INFO)) 
        .childHandler(new ChannelInitializer<Channel>() { 
         @Override 
         protected void initChannel(Channel ch) throws Exception { 
          ChannelPipeline pipeline = ch.pipeline(); 
          pipeline.addLast(new HttpServerCodec()); 
          pipeline.addLast(new HttpObjectAggregator(1024 * 1024)); // 1MB 
          pipeline.addLast(new CorsHandler(
            CorsConfigBuilder.forOrigin("http://example.com") 
              .allowedRequestMethods(HttpMethod.POST) 
              .build()) 
          ); 
         } 
        }) 
        .channel(NioServerSocketChannel.class); 
      Channel channel = bootstrap.bind(PORT).sync().channel(); 
      channel.closeFuture().sync(); 
     } finally { 
      eventLoopGroup.shutdownGracefully(); 
     } 
    } 
} 

當您通過CORS檢查的來源請求時,CorsHandler會像您期望的那樣關閉連接。

$ curl -sv -X OPTIONS -H 'Origin: http://example.com' -H 'Access-Control-Request-Method: POST' http://localhost:8080 
* Rebuilt URL to: http://localhost:8080/ 
* Trying ::1... 
* TCP_NODELAY set 
* Connected to localhost (::1) port 8080 (#0) 
> OPTIONS/HTTP/1.1 
> Host: localhost:8080 
> User-Agent: curl/7.54.0 
> Accept: */* 
> Origin: http://example.com 
> Access-Control-Request-Method: POST 
> 
< HTTP/1.1 200 OK 
< access-control-allow-origin: http://example.com 
< vary: origin 
< access-control-allow-methods: POST 
< access-control-allow-headers: 
< access-control-max-age: 0 
< date: "Tue, 26 Sep 2017 20:03:53 GMT" 
< content-length: 0 
< 
* Connection #0 to host localhost left intact 

但是,當您從未通過CORS檢查的來源請求時,它不會關閉連接。

$ curl -sv -X OPTIONS -H 'Origin: http://invalid.com' -H 'Access-Control-Request-Method: POST' http://localhost:8080 
* Rebuilt URL to: http://localhost:8080/ 
* Trying ::1... 
* TCP_NODELAY set 
* Connected to localhost (::1) port 8080 (#0) 
> OPTIONS/HTTP/1.1 
> Host: localhost:8080 
> User-Agent: curl/7.54.0 
> Accept: */* 
> Origin: http://invalid.com 
> Access-Control-Request-Method: POST 
> 
< HTTP/1.1 200 OK 
* no chunk, no close, no size. Assume close to signal end 
< 

這可能是netty中的一個錯誤,如果有的話我會在那裏提交它。

+0

我與網狀4.1.6決賽和4.1.16-最後,相同的結果進行測試。 – mgbelisle

+0

堆棧溢出不是一個錯誤報告網站,你應該在github的netty問題部分報告錯誤:https://github.com/netty/netty/issues另外,在頂部的例子中,netty不關閉連接(有一個連接頭) – Ferrybig

+0

你是對的,謝謝你指出。我不太瞭解連接保持活躍與關閉和http 1.0 vs 1.1,但我現在就看看你在說什麼。我確實記下了我在這裏提交的netty中的一個bug: https://github.com/netty/netty/pull/7261 我在這裏問過,不知道它是否像我在第一次說的那樣是一個bug帖子。如果我知道這是一個錯誤,肯定不會提交給SO。 – mgbelisle

回答

1

以下是@Ferrybig指出的,CorsHandler未故意關閉連接,因爲請求中沒有Connection: close標頭。 Http 1.0假定tcp連接默認關閉,並且http 1.1(默認爲curl defafdults)保持打開狀態。

curl沒有退出的原因是因爲CorsHandler在其響應中沒有包含Content-Length標頭,這是一個錯誤。

https://github.com/netty/netty/pull/7261