1 /*
   2  * Copyright (c) 1998, 2010, 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 4160200
  27  * @summary Make sure URLConnection.getContnentHandler
  28  *     can handle MIME types with attributes
  29  * @modules java.base/sun.net.www java.base/sun.net.www.content.text
  30  */
  31 import java.net.*;
  32 import java.io.*;
  33 import sun.net.www.content.text.*;
  34 import sun.net.www.MessageHeader;
  35 
  36 public class HandleContentTypeWithAttrs {
  37 
  38     URL url;
  39 
  40     public HandleContentTypeWithAttrs (int port) throws Exception {
  41 
  42         String localHostName = InetAddress.getLocalHost().getHostName();
  43 
  44         // Request echo.html from myHttpServer.
  45         // In the header of the response, we make
  46         // the content type have some attributes.
  47         url = new URL("http://" + localHostName + ":" + port + "/echo.html");
  48         URLConnection urlConn = url.openConnection();
  49 
  50         // the method getContent() calls the method
  51         // getContentHandler(). With the fix, the method
  52         // getContentHandler() gets the correct content
  53         // handler for our response -  it should be the
  54         // PlainText conten handler; without the fix,
  55         // it gets the UnknownContent handler.
  56         // So based on what the getContent()
  57         // returns, we know whether getContentHandler()
  58         // can handle content type with attributes or not.
  59         Object obj = urlConn.getContent();
  60 
  61         if (!(obj instanceof PlainTextInputStream))
  62             throw new Exception("Cannot get the correct content handler.");
  63     }
  64 
  65     public static void main(String [] argv) throws Exception {
  66         // Start myHttpServer
  67         myHttpServer testServer = new myHttpServer();
  68         testServer.startServer(0);
  69         int serverPort = testServer.getServerLocalPort();
  70         new HandleContentTypeWithAttrs(serverPort);
  71     }
  72 }
  73 
  74 // myHttpServer is pretty much like
  75 // sun.net.www.httpd.BasicHttpServer.
  76 // But we only need it to handle one
  77 // simple request.
  78 class myHttpServer implements Runnable, Cloneable {
  79 
  80     /** Socket for communicating with client. */
  81     public Socket clientSocket = null;
  82     private Thread serverInstance;
  83     private ServerSocket serverSocket;
  84 
  85     /** Stream for printing to the client. */
  86     public PrintStream clientOutput;
  87 
  88     /** Buffered stream for reading replies from client. */
  89     public InputStream clientInput;
  90 
  91     static URL defaultContext;
  92 
  93     /** Close an open connection to the client. */
  94     public void close() throws IOException {
  95         clientSocket.close();
  96         clientSocket = null;
  97         clientInput = null;
  98         clientOutput = null;
  99     }
 100 
 101     final public void run() {
 102         if (serverSocket != null) {
 103             Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
 104 
 105             try {
 106                 // wait for incoming request
 107                 Socket ns = serverSocket.accept();
 108                 myHttpServer n = (myHttpServer)clone();
 109                 n.serverSocket = null;
 110                 n.clientSocket = ns;
 111                 new Thread(n).start();
 112             } catch(Exception e) {
 113                 System.out.print("Server failure\n");
 114                 e.printStackTrace();
 115             } finally {
 116                 try { serverSocket.close(); } catch(IOException unused) {}
 117             }
 118         } else {
 119             try {
 120                 clientOutput = new PrintStream(
 121                     new BufferedOutputStream(clientSocket.getOutputStream()),
 122                                              false);
 123                 clientInput = new BufferedInputStream(
 124                                              clientSocket.getInputStream());
 125                 serviceRequest();
 126 
 127             } catch(Exception e) {
 128                 // System.out.print("Service handler failure\n");
 129                 // e.printStackTrace();
 130             } finally {
 131                 try { close(); }  catch(IOException unused) {}
 132             }
 133         }
 134     }
 135 
 136     /** Start a server on port <i>port</i>.  It will call serviceRequest()
 137         for each new connection. */
 138     final public void startServer(int port) throws IOException {
 139         serverSocket = new ServerSocket(port, 50);
 140         serverInstance = new Thread(this);
 141         serverInstance.start();
 142     }
 143 
 144     final public int getServerLocalPort() throws Exception {
 145         if (serverSocket != null) {
 146             return serverSocket.getLocalPort();
 147         }
 148         throw new Exception("serverSocket is null");
 149     }
 150 
 151     MessageHeader mh;
 152 
 153     final public void serviceRequest() {
 154         //totalConnections++;
 155         try {
 156             mh = new MessageHeader(clientInput);
 157             String cmd = mh.findValue(null);
 158             // if (cmd == null) {
 159             //  error("Missing command " + mh);
 160             //  return;
 161             // }
 162             int fsp = cmd.indexOf(' ');
 163             // if (fsp < 0) {
 164             //  error("Syntax error in command: " + cmd);
 165             //  return;
 166             //  }
 167             String k = cmd.substring(0, fsp);
 168             int nsp = cmd.indexOf(' ', fsp + 1);
 169             String p1, p2;
 170             if (nsp > 0) {
 171                 p1 = cmd.substring(fsp + 1, nsp);
 172                 p2 = cmd.substring(nsp + 1);
 173             } else {
 174                 p1 = cmd.substring(fsp + 1);
 175                 p2 = null;
 176             }
 177             // expectsMime = p2 != null;
 178             if (k.equalsIgnoreCase("get"))
 179                 getRequest(new URL(defaultContext, p1), p2);
 180             else {
 181                 //      error("Unknown command: " + k + " (" + cmd + ")");
 182                 return;
 183             }
 184         } catch(IOException e) {
 185             // totally ignore IOException.  They're usually client crashes.
 186         } catch(Exception e) {
 187             //  error("Exception: " + e);
 188             e.printStackTrace();
 189         }
 190     }
 191 
 192     /** Satisfy one get request.  It is invoked with the clientInput and
 193         clientOutput streams initialized.  This method handles one client
 194         connection. When it is done, it can simply exit. The default
 195         server just echoes it's input. */
 196     protected void getRequest(URL u, String param) {
 197         try {
 198             if (u.getFile().equals("/echo.html")) {
 199                startHtml("Echo reply");
 200                clientOutput.print("<p>URL was " + u.toExternalForm() + "\n");
 201                clientOutput.print("<p>Socket was " + clientSocket + "\n<p><pre>");
 202                mh.print(clientOutput);
 203            }
 204         } catch(Exception e) {
 205             System.out.print("Failed on "+u.getFile()+"\n");
 206             e.printStackTrace();
 207         }
 208     }
 209      /**
 210       * Clone this object;
 211      */
 212     public Object clone() {
 213         try {
 214             return super.clone();
 215         } catch (CloneNotSupportedException e) {
 216             // this shouldn't happen, since we are Cloneable
 217             throw new InternalError();
 218         }
 219     }
 220 
 221     public myHttpServer () {
 222         try {
 223             defaultContext
 224             = new URL("http", InetAddress.getLocalHost().getHostName(), "/");
 225         } catch(Exception e) {
 226             System.out.println("Failed to construct defauit URL context: "
 227                                + e);
 228             e.printStackTrace();
 229         }
 230     }
 231 
 232     // Make the content type have some attributes
 233     protected void startHtml(String title) {
 234         clientOutput.print("HTTP/1.0 200 Document follows\n" +
 235                            "Server: Java/" + getClass().getName() + "\n" +
 236                            "Content-type: text/plain; charset=Shift_JIS \n\n");
 237     }
 238 
 239 }