netty: IllegalArgumentException on AIX J9 1.6 (20121024_126067) with example-http2 demo in netty source code

Expected behavior

this demo should run without exception the demo runs correctly with environment below, but not on AIX j9 1.6 with jvm version J9VM - ``` 20121024_126067

on windows, sun jdk 1.7
on linux, sun jdk 1.8
on aix, j9 jdk 1.6 with jvm version J9VM - 20110203_074623(notice this small difference)

Actual behavior

----------------OUTBOUND--------------------
[id: 0x38163a7b, L:/127.0.0.1:33534 - R:/127.0.0.1:8080] DATA: streamId=5, padding=0, endStream=true, length=10, bytes=74657374206461746121
------------------------------------
Feb 22, 2017 5:15:04 PM io.netty.handler.codec.http2.Http2FrameLogger log
INFO: 
----------------OUTBOUND--------------------
[id: 0x38163a7b, L:/127.0.0.1:33534 - R:/127.0.0.1:8080] HEADERS: streamId=7, headers=DefaultHttp2Headers[:path: /whatever, :method: GET, :scheme: http, :authority: 127.0.0.1:8080, accept-encoding: gzip, accept-encoding: deflate], streamDependency=0, weight=16, exclusive=false, padding=0, endStream=true
------------------------------------
Exception in thread "main" java.lang.IllegalArgumentException: a header value contains a prohibited character ' ': 127.0.0.1:8080
	at io.netty.handler.codec.http.DefaultHttpHeaders$HeaderValueConverterAndValidator.validateValueChar(DefaultHttpHeaders.java:431)
	at io.netty.handler.codec.http.DefaultHttpHeaders$HeaderValueConverterAndValidator.convertObject(DefaultHttpHeaders.java:411)
Feb 22, 2017 5:15:04 PM io.netty.handler.codec.http2.Http2FrameLogger log
INFO: 
----------------OUTBOUND--------------------
[id: 0x38163a7b, L:/127.0.0.1:33534 - R:/127.0.0.1:8080] HEADERS: streamId=9, headers=DefaultHttp2Headers[:path: /thisispost, :method: POST, :scheme: http, :authority: 127.0.0.1:8080, accept-encoding: gzip, accept-encoding: deflate], streamDependency=0, weight=16, exclusive=false, padding=0, endStream=false
------------------------------------
	at io.netty.handler.codec.http.DefaultHttpHeaders$HeaderValueConverterAndValidator.convertObject(DefaultHttpHeaders.java:402)
	at io.netty.handler.codec.DefaultHeaders.addObject(DefaultHeaders.java:318)
	at io.netty.handler.codec.http.DefaultHttpHeaders.add(DefaultHttpHeaders.java:123)
	at io.netty.example.http2.helloworld.client.Http2Client.doRequest(Http2Client.java:118)
	at io.netty.example.http2.helloworld.client.Http2Client.main(Http2Client.java:101)
Feb 22, 2017 5:15:04 PM io.netty.handler.codec.http2.Http2FrameLogger log

the prohibited character is \0 as it’s invisible

Steps to reproduce

use demo io/netty/example/http2 in netty source code, i have change this demo to do get and post at same time, and repeat for 100 times.

Minimal yet complete reproducer code (or URL to code)

Http2Client.java after change:

public final class Http2Client {

    static final boolean SSL      = System.getProperty("ssl") != null;
    static final String  HOST     = System.getProperty("host", "127.0.0.1");
    static final int     PORT     = Integer.parseInt(System.getProperty("port", SSL ? "8443" : "8080"));
    static final String  URL      = System.getProperty("url", "/whatever");
    static final String  URL2     = System.getProperty("url2", "/thisispost");
    static final String  URL2DATA = System.getProperty("url2data", "test data!");

    public static void main(String[] args) throws Exception {
        // Configure SSL.
        final SslContext sslCtx;
        if (SSL) {
            SslProvider provider = OpenSsl.isAlpnSupported() ? SslProvider.OPENSSL : SslProvider.JDK;
            sslCtx = SslContextBuilder.forClient().sslProvider(provider)
                /* NOTE: the cipher filter may not include all ciphers required by the HTTP/2 specification.
                 * Please refer to the HTTP/2 specification for cipher requirements. */
                    .ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE)
                    .trustManager(InsecureTrustManagerFactory.INSTANCE)
                    .applicationProtocolConfig(new ApplicationProtocolConfig(Protocol.ALPN,
                            // NO_ADVERTISE is currently the only mode supported by both OpenSsl and JDK providers.
                            SelectorFailureBehavior.NO_ADVERTISE,
                            // ACCEPT is currently the only mode supported by both OpenSsl and JDK providers.
                            SelectedListenerFailureBehavior.ACCEPT, ApplicationProtocolNames.HTTP_2,
                            ApplicationProtocolNames.HTTP_1_1)).build();
        } else {
            sslCtx = null;
        }

        EventLoopGroup workerGroup = new NioEventLoopGroup();
        Http2ClientInitializer initializer = new Http2ClientInitializer(sslCtx, Integer.MAX_VALUE);

        try {
            // Configure the client.
            Bootstrap b = new Bootstrap();
            b.group(workerGroup);
            b.channel(NioSocketChannel.class);
            b.option(ChannelOption.SO_KEEPALIVE, true);
            b.remoteAddress(HOST, PORT);
            b.handler(initializer);

            // Start the client.
            Channel channel = b.connect().syncUninterruptibly().channel();
            System.out.println("Connected to [" + HOST + ':' + PORT + ']');

            // Wait for the HTTP/2 upgrade to occur.
            Http2SettingsHandler http2SettingsHandler = initializer.settingsHandler();
            http2SettingsHandler.awaitSettings(5, TimeUnit.SECONDS);

            HttpResponseHandler responseHandler = initializer.responseHandler();
            int streamId = 3;
            HttpScheme scheme = SSL ? HttpScheme.HTTPS : HttpScheme.HTTP;
            AsciiString hostName = new AsciiString(HOST + ':' + PORT);
            System.err.println("Sending request(s)...");
            for (int i = 0; i < 100; i++) {
                doRequest(channel, responseHandler, streamId, scheme, hostName);
            }
            responseHandler.awaitResponses(5, TimeUnit.SECONDS);
            System.out.println("Finished HTTP/2 request(s)");

            // Wait until the connection is closed.
            channel.close().syncUninterruptibly();
        } finally {
            workerGroup.shutdownGracefully();
        }
    }

    private static void doRequest(Channel channel, HttpResponseHandler responseHandler, int streamId, HttpScheme scheme,
            AsciiString hostName) {
        if (URL != null) {
            // Create a simple GET request.
            FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, GET, URL);
            request.headers().add(HttpHeaderNames.HOST, hostName);
            request.headers().add(HttpConversionUtil.ExtensionHeaderNames.SCHEME.text(), scheme.name());
            request.headers().add(HttpHeaderNames.ACCEPT_ENCODING, HttpHeaderValues.GZIP);
            request.headers().add(HttpHeaderNames.ACCEPT_ENCODING, HttpHeaderValues.DEFLATE);
            responseHandler.put(streamId, channel.writeAndFlush(request), channel.newPromise());
            streamId += 2;
        }
        if (URL2 != null) {
            // Create a simple POST request with a body.
            FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, POST, URL2,
                    Unpooled.copiedBuffer(URL2DATA.getBytes(CharsetUtil.UTF_8)));
            request.headers().add(HttpHeaderNames.HOST, hostName);
            request.headers().add(HttpConversionUtil.ExtensionHeaderNames.SCHEME.text(), scheme.name());
            request.headers().add(HttpHeaderNames.ACCEPT_ENCODING, HttpHeaderValues.GZIP);
            request.headers().add(HttpHeaderNames.ACCEPT_ENCODING, HttpHeaderValues.DEFLATE);
            responseHandler.put(streamId, channel.writeAndFlush(request), channel.newPromise());
            streamId += 2;
        }
    }
}

Netty version

4.1.8.FINAL

JVM version (e.g. java -version)

run demo below with ibm j9 JDK, version:

java version "1.6.0"
Java(TM) SE Runtime Environment (build pwi3260sr12ifix-20121108_01(SR12+IV31417))
IBM J9 VM (build 2.4, JRE 1.6.0 IBM J9 2.4 Windows XP x86-32 jvmwi3260sr12-20121
024_126067 (JIT enabled, AOT enabled)
J9VM - 20121024_126067
JIT  - r9_20120914_26057
GC   - 20120928_AA)
JCL  - 20121108_01

OS version (e.g. uname -a)

AIX JT-OWT01 1 6 00f914cd4c00

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 50 (35 by maintainers)

Most upvoted comments

Hi guys, I can help with debugging and provide some logs.

$ cat /proc/version Linux version 2.6.32-642.13.1.el6.ppc64 (mockbuild@ppc-030.build.eng.bos.redhat.com) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC) ) #1 SMP Wed Nov 23 16:02:25 EST 2016

$ java -version java version “1.8.0” Java™ SE Runtime Environment (build pxp3280sr4fp1-20170215_01(SR4 FP1)) IBM J9 VM (build 2.8, JRE 1.8.0 Linux ppc-32 20170209_336038 (JIT enabled, AOT enabled) J9VM - R28_20170209_0201_B336038 JIT - tr.r14.java.green_20170125_131456 GC - R28_20170209_0201_B336038 J9CL - 20170209_336038) JCL - 20170215_01 based on Oracle jdk8u121-b13

I used the client by D3Hunter (with the additional logs requested) and everything else from master (a9d7c72cde9d522161e7275df6490a8b9765d57f) i.e. netty-example-4.1.9.Final-SNAPSHOT

http2-client-jdk8.txt http2-server-jdk8.txt

Just ask if you need anything else.

Chris