test/jdk/sun/net/www/http/KeepAliveCache/B5045306.java
author dfuchs
Thu, 12 Sep 2019 15:46:11 +0100
changeset 58108 5302477c8285
parent 47216 71c04702a3d5
permissions -rw-r--r--
8230858: Replace wildcard address with loopback or local host in tests - part 23 Summary: Add new traces for better diagnosis, refrain binding to the wildcard address when possible. Reviewed-by: chegar, xuelei
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
58108
5302477c8285 8230858: Replace wildcard address with loopback or local host in tests - part 23
dfuchs
parents: 47216
diff changeset
     2
 * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
 * @test
7022
1066bfde0f5e 6993490: SocketTimeoutException on HTTP keep-alive connections
chegar
parents: 5506
diff changeset
    26
 * @bug 5045306 6356004 6993490
30820
0d4717a011d3 8081347: Add @modules to jdk_core tests
mchung
parents: 14342
diff changeset
    27
 * @modules java.base/sun.net.www
44115
bb4e971bf5d4 8176195: Fix misc module dependencies in jdk_core tests
xiaofeya
parents: 30820
diff changeset
    28
 *          java.management
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
 * @library ../../httptest/
13788
3f38e525f30a 6354758: rename old test HttpServer classes
chegar
parents: 7668
diff changeset
    30
 * @build HttpCallback TestHttpServer HttpTransaction
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
 * @run main/othervm B5045306
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
 * @summary Http keep-alive implementation is not efficient
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.net.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.io.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.lang.management.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
/* Part 1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * The http client makes a connection to a URL whos content contains a lot of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * data, more than can fit in the socket buffer. The client only reads
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * 1 byte of the data from the InputStream leaving behind more data than can
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * fit in the socket buffer. The client then makes a second call to the http
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * server. If the connection port used by the client is the same as for the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * first call then that means that the connection is being reused.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * Part 2:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * Test buggy webserver that sends less data than it specifies in its
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * Content-length header.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
public class B5045306
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
    static SimpleHttpTransaction httpTrans;
13788
3f38e525f30a 6354758: rename old test HttpServer classes
chegar
parents: 7668
diff changeset
    55
    static TestHttpServer server;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
    public static void main(String[] args) throws Exception {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
        startHttpServer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
        clientHttpCalls();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
    public static void startHttpServer() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
            httpTrans = new SimpleHttpTransaction();
58108
5302477c8285 8230858: Replace wildcard address with loopback or local host in tests - part 23
dfuchs
parents: 47216
diff changeset
    65
            server = new TestHttpServer(httpTrans, 1, 10, InetAddress.getLocalHost(), 0);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
            e.printStackTrace();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    public static void clientHttpCalls() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
            System.out.println("http server listen on: " + server.getLocalPort());
58108
5302477c8285 8230858: Replace wildcard address with loopback or local host in tests - part 23
dfuchs
parents: 47216
diff changeset
    74
            String hostAddr =  InetAddress.getLocalHost().getHostAddress();
5302477c8285 8230858: Replace wildcard address with loopback or local host in tests - part 23
dfuchs
parents: 47216
diff changeset
    75
            if (hostAddr.indexOf(':') > -1) hostAddr = "[" + hostAddr + "]";
5302477c8285 8230858: Replace wildcard address with loopback or local host in tests - part 23
dfuchs
parents: 47216
diff changeset
    76
            String baseURLStr = "http://" + hostAddr + ":" + server.getLocalPort() + "/";
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
            URL bigDataURL = new URL (baseURLStr + "firstCall");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
            URL smallDataURL = new URL (baseURLStr + "secondCall");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
58108
5302477c8285 8230858: Replace wildcard address with loopback or local host in tests - part 23
dfuchs
parents: 47216
diff changeset
    81
            HttpURLConnection uc = (HttpURLConnection)bigDataURL.openConnection(Proxy.NO_PROXY);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
            //Only read 1 byte of response data and close the stream
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
            InputStream is = uc.getInputStream();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
            byte[] ba = new byte[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
            is.read(ba);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
            is.close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
            // Allow the KeepAliveStreamCleaner thread to read the data left behind and cache the connection.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
            try { Thread.sleep(2000); } catch (Exception e) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
58108
5302477c8285 8230858: Replace wildcard address with loopback or local host in tests - part 23
dfuchs
parents: 47216
diff changeset
    92
            uc = (HttpURLConnection)smallDataURL.openConnection(Proxy.NO_PROXY);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
            uc.getResponseCode();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
            if (SimpleHttpTransaction.failed)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
                throw new RuntimeException("Failed: Initial Keep Alive Connection is not being reused");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
            // Part 2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
            URL part2Url = new URL (baseURLStr + "part2");
58108
5302477c8285 8230858: Replace wildcard address with loopback or local host in tests - part 23
dfuchs
parents: 47216
diff changeset
   100
            uc = (HttpURLConnection)part2Url.openConnection(Proxy.NO_PROXY);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
            is = uc.getInputStream();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
            is.close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
            // Allow the KeepAliveStreamCleaner thread to try and read the data left behind and cache the connection.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
            try { Thread.sleep(2000); } catch (Exception e) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
            ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
            if (threadMXBean.isThreadCpuTimeSupported()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
                long[] threads = threadMXBean.getAllThreadIds();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
                ThreadInfo[] threadInfo = threadMXBean.getThreadInfo(threads);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
                for (int i=0; i<threadInfo.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
                    if (threadInfo[i].getThreadName().equals("Keep-Alive-SocketCleaner"))  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
                        System.out.println("Found Keep-Alive-SocketCleaner thread");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
                        long threadID = threadInfo[i].getThreadId();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
                        long before = threadMXBean.getThreadCpuTime(threadID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
                        try { Thread.sleep(2000); } catch (Exception e) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
                        long after = threadMXBean.getThreadCpuTime(threadID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
                        if (before ==-1 || after == -1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
                            break;  // thread has died, OK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
                        // if Keep-Alive-SocketCleaner consumes more than 50% of cpu then we
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
                        // can assume a recursive loop.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
                        long total = after - before;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
                        if (total >= 1000000000)  // 1 second, or 1 billion nanoseconds
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
                            throw new RuntimeException("Failed: possible recursive loop in Keep-Alive-SocketCleaner");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
            e.printStackTrace();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
        } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
            server.terminate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
class SimpleHttpTransaction implements HttpCallback
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    static boolean failed = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
    // Need to have enough data here that is too large for the socket buffer to hold.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    // Also http.KeepAlive.remainingData must be greater than this value, default is 256K.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
    static final int RESPONSE_DATA_LENGTH = 128 * 1024;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    int port1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
    public void request(HttpTransaction trans) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
            String path = trans.getRequestURI().getPath();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
            if (path.equals("/firstCall")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
                port1 = trans.channel().socket().getPort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
                System.out.println("First connection on client port = " + port1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
                byte[] responseBody = new byte[RESPONSE_DATA_LENGTH];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
                for (int i=0; i<responseBody.length; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
                    responseBody[i] = 0x41;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
                trans.setResponseEntityBody (responseBody, responseBody.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
                trans.sendResponse(200, "OK");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
            } else if (path.equals("/secondCall")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
                int port2 = trans.channel().socket().getPort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
                System.out.println("Second connection on client port = " + port2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
                if (port1 != port2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
                    failed = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
                trans.setResponseHeader ("Content-length", Integer.toString(0));
7022
1066bfde0f5e 6993490: SocketTimeoutException on HTTP keep-alive connections
chegar
parents: 5506
diff changeset
   169
1066bfde0f5e 6993490: SocketTimeoutException on HTTP keep-alive connections
chegar
parents: 5506
diff changeset
   170
                 /* Force the server to not respond for more that the timeout
1066bfde0f5e 6993490: SocketTimeoutException on HTTP keep-alive connections
chegar
parents: 5506
diff changeset
   171
                  * set by the keepalive cleaner (5000 millis). This ensures the
1066bfde0f5e 6993490: SocketTimeoutException on HTTP keep-alive connections
chegar
parents: 5506
diff changeset
   172
                  * timeout is correctly resets the default read timeout,
1066bfde0f5e 6993490: SocketTimeoutException on HTTP keep-alive connections
chegar
parents: 5506
diff changeset
   173
                  * infinity. See 6993490. */
1066bfde0f5e 6993490: SocketTimeoutException on HTTP keep-alive connections
chegar
parents: 5506
diff changeset
   174
                System.out.println("server sleeping...");
1066bfde0f5e 6993490: SocketTimeoutException on HTTP keep-alive connections
chegar
parents: 5506
diff changeset
   175
                try {Thread.sleep(6000); } catch (InterruptedException e) {}
1066bfde0f5e 6993490: SocketTimeoutException on HTTP keep-alive connections
chegar
parents: 5506
diff changeset
   176
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
                trans.sendResponse(200, "OK");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
            } else if(path.equals("/part2")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
                System.out.println("Call to /part2");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
                byte[] responseBody = new byte[RESPONSE_DATA_LENGTH];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
                for (int i=0; i<responseBody.length; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
                    responseBody[i] = 0x41;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
                trans.setResponseEntityBody (responseBody, responseBody.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
                // override the Content-length header to be greater than the actual response body
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
                trans.setResponseHeader("Content-length", Integer.toString(responseBody.length+1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
                trans.sendResponse(200, "OK");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
                // now close the socket
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
                trans.channel().socket().close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
        } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
            e.printStackTrace();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
}