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 }