1 /*
   2  * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  * @test
  26  * @bug 6373555
  27  * @summary HTTP Server failing to answer client requests
  28  */
  29 
  30 import java.net.*;
  31 import java.io.*;
  32 import javax.xml.soap.*;
  33 import java.util.*;
  34 import com.sun.net.httpserver.*;
  35 import java.util.concurrent.*;
  36 
  37 public class B6373555 {
  38 
  39     private static int s_received = 0;
  40     private static int sent = 0;
  41 
  42     private static int received = 0;
  43     private static int port;
  44 
  45     private static volatile boolean error = false;
  46     private static Object lock;
  47     static HttpServer httpServer;
  48     static ExecutorService pool, execs;
  49     static int NUM = 1000;
  50 
  51     public static void main(String[] args) throws Exception {
  52         try {
  53             lock = new Object();
  54             if (args.length > 0) {
  55                 NUM = Integer.parseInt (args[0]);
  56             }
  57             execs = Executors.newFixedThreadPool(5);
  58             httpServer = createHttpServer(execs);
  59             port = httpServer.getAddress().getPort();
  60             pool = Executors.newFixedThreadPool(10);
  61             httpServer.start();
  62             for (int i=0; i < NUM; i++) {
  63                 pool.execute(new Client());
  64                 if (error) {
  65                     throw new Exception ("error in test");
  66                 }
  67             }
  68             System.out.println("Main thread waiting");
  69             pool.shutdown();
  70             long latest = System.currentTimeMillis() + 200 * 1000;
  71             while (System.currentTimeMillis() < latest) {
  72                 if (pool.awaitTermination(2000L, TimeUnit.MILLISECONDS)) {
  73                     System.out.println("Main thread done!");
  74                     return;
  75                 }
  76                 if (error) {
  77                     throw new Exception ("error in test");
  78                 }
  79             }
  80             throw new Exception ("error in test: timed out");
  81         } finally {
  82             httpServer.stop(0);
  83             pool.shutdownNow();
  84             execs.shutdownNow();
  85         }
  86     }
  87 
  88     public static class Client implements Runnable {
  89 
  90         byte[] getBuf () {
  91             byte[] buf = new byte [5200];
  92             for (int i=0; i< 5200; i++) {
  93                 buf [i] = (byte)i;
  94             }
  95             return buf;
  96         }
  97 
  98         public void run() {
  99             try {
 100                 Thread.sleep(10);
 101                 byte[] buf = getBuf();
 102                 URL url = new URL("http://127.0.0.1:"+port+"/test");
 103                 HttpURLConnection con = (HttpURLConnection)url.openConnection();
 104                 con.setDoOutput(true);
 105                 con.setDoInput(true);
 106                 con.setRequestMethod("POST");
 107                 con.setRequestProperty(
 108                     "Content-Type",
 109                     "Multipart/Related; type=\"application/xop+xml\"; boundary=\"----=_Part_0_6251267.1128549570165\"; start-info=\"text/xml\"");
 110                 OutputStream out = con.getOutputStream();
 111                 out.write(buf);
 112                 out.close();
 113                 InputStream in = con.getInputStream();
 114                 byte[] newBuf = readFully(in);
 115                 in.close();
 116                 if (buf.length != newBuf.length) {
 117                     System.out.println("Doesn't match");
 118                     error = true;
 119                 }
 120                 synchronized(lock) {
 121                     ++received;
 122                     if ((received % 1000) == 0) {
 123                         System.out.println("Received="+received);
 124                     }
 125                 }
 126             }
 127             catch(Exception e) {
 128                 e.printStackTrace();
 129                 System.out.print (".");
 130                 error = true;
 131             }
 132         }
 133     }
 134 
 135     private static byte[] readFully(InputStream istream) throws IOException {
 136         ByteArrayOutputStream bout = new ByteArrayOutputStream();
 137         byte[] buf = new byte[1024];
 138         int num = 0;
 139 
 140         if (istream != null) {
 141             while ((num = istream.read(buf)) != -1) {
 142                 bout.write(buf, 0, num);
 143             }
 144         }
 145         byte[] ret = bout.toByteArray();
 146         return ret;
 147     }
 148 
 149 
 150     private static HttpServer createHttpServer(ExecutorService execs)
 151         throws Exception {
 152         InetSocketAddress inetAddress = new InetSocketAddress(0);
 153         HttpServer testServer = HttpServer.create(inetAddress, 5);
 154         testServer.setExecutor(execs);
 155         HttpContext context = testServer.createContext("/test");
 156         context.setHandler(new HttpHandler() {
 157             public void handle(HttpExchange msg) {
 158                 try {
 159                     synchronized(lock) {
 160                         ++s_received;
 161                             if ((s_received % 1000) == 0) {
 162                             System.out.println("Received="+s_received);
 163                         }
 164                     }
 165                     String method = msg.getRequestMethod();
 166                         if (method.equals("POST")) {
 167                         InputStream is = msg.getRequestBody();
 168                             byte[] buf = readFully(is);
 169                             is.close();
 170                             writePostReply(msg, buf);
 171                     } else {
 172                         System.out.println("****** METHOD not handled ***** "+method);
 173                             System.out.println("Received="+s_received);
 174                     }
 175                     synchronized(lock) {
 176                         ++sent;
 177                             if ((sent % 1000) == 0) {
 178                             System.out.println("sent="+sent);
 179                         }
 180                     }
 181                 }
 182                 catch(Exception e) {
 183                     e.printStackTrace();
 184                 }
 185                 finally {
 186                     msg.close();
 187                 }
 188             }
 189         }
 190         );
 191         return testServer;
 192     }
 193 
 194     private static void writePostReply(HttpExchange msg, byte[] buf)
 195         throws Exception {
 196         msg.getResponseHeaders().add("Content-Type", "text/xml");
 197         msg.sendResponseHeaders(200, buf.length);
 198         OutputStream out = msg.getResponseBody();
 199         out.write(buf);
 200         out.close();
 201     }
 202 
 203 }