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