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 */
31import java.net.*;
32import java.io.*;
33import sun.net.www.content.text.*;
34import sun.net.www.MessageHeader;
35import static java.net.Proxy.NO_PROXY;
36
37public 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.
77class 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}
239