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 }