1/*
2 * Copyright (c) 2003, 2014, 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/* @test
25 * @summary Unit test for java.net.ResponseCache
26 * @bug 4837267
27 * @author Yingxian Wang
28 */
29
30import java.net.*;
31import java.util.*;
32import java.io.*;
33import javax.net.ssl.*;
34
35/**
36 * Request should get serviced by the cache handler. Response get
37 * saved through the cache handler.
38 */
39public class ResponseCacheTest implements Runnable {
40    ServerSocket ss;
41    static URL url1;
42    static URL url2;
43    static String FNPrefix, OutFNPrefix;
44    static List<Closeable> streams = new ArrayList<>();
45    static List<File> files = new ArrayList<>();
46
47    /*
48     * Our "http" server to return a 404 */
49    public void run() {
50        Socket s = null;
51        FileInputStream fis = null;
52        try {
53            s = ss.accept();
54
55            InputStream is = s.getInputStream ();
56            BufferedReader r = new BufferedReader(new InputStreamReader(is));
57            String x;
58            while ((x=r.readLine()) != null) {
59                if (x.length() ==0) {
60                    break;
61                }
62            }
63            PrintStream out = new PrintStream(
64                                 new BufferedOutputStream(
65                                    s.getOutputStream() ));
66
67            /* send file2.1 */
68            File file2 = new File(FNPrefix+"file2.1");
69            out.print("HTTP/1.1 200 OK\r\n");
70            out.print("Content-Type: text/html; charset=iso-8859-1\r\n");
71            out.print("Content-Length: "+file2.length()+"\r\n");
72            out.print("Connection: close\r\n");
73            out.print("\r\n");
74            fis = new FileInputStream(file2);
75            byte[] buf = new byte[(int)file2.length()];
76            int len;
77            while ((len = fis.read(buf)) != -1) {
78                out.print(new String(buf));
79            }
80
81            out.flush();
82
83            s.close();
84            ss.close();
85        } catch (Exception e) {
86            e.printStackTrace();
87        } finally {
88            try { ss.close(); } catch (IOException unused) {}
89            try { s.close(); } catch (IOException unused) {}
90            try { fis.close(); } catch (IOException unused) {}
91        }
92    }
93static class NameVerifier implements HostnameVerifier {
94        public boolean verify(String hostname, SSLSession session) {
95            return true;
96        }
97    }
98    ResponseCacheTest() throws Exception {
99        /* start the server */
100        ss = new ServerSocket(0);
101        (new Thread(this)).start();
102        /* establish http connection to server */
103        url1 = new URL("http://localhost/file1.cache");
104        HttpURLConnection http = (HttpURLConnection)url1.openConnection();
105        InputStream is = null;
106        System.out.println("request headers: "+http.getRequestProperties());
107        System.out.println("responsecode is :"+http.getResponseCode());
108        Map<String,List<String>> headers1 = http.getHeaderFields();
109        try {
110            is = http.getInputStream();
111        } catch (IOException ioex) {
112            throw new RuntimeException(ioex.getMessage());
113        }
114        BufferedReader r = new BufferedReader(new InputStreamReader(is));
115        String x;
116        File fileout = new File(OutFNPrefix+"file1");
117        PrintStream out = new PrintStream(
118                                 new BufferedOutputStream(
119                                    new FileOutputStream(fileout)));
120        while ((x=r.readLine()) != null) {
121            out.print(x+"\n");
122        }
123        out.flush();
124        out.close();
125
126        http.disconnect();
127
128        // testing ResponseCacheHandler.put()
129        url2 = new URL("http://localhost:" +
130                       Integer.toString(ss.getLocalPort())+"/file2.1");
131        http = (HttpURLConnection)url2.openConnection();
132        System.out.println("responsecode2 is :"+http.getResponseCode());
133        Map<String,List<String>> headers2 = http.getHeaderFields();
134
135        try {
136            is = http.getInputStream();
137        } catch (IOException ioex) {
138            throw new RuntimeException(ioex.getMessage());
139        }
140        r = new BufferedReader(new InputStreamReader(is));
141        fileout = new File(OutFNPrefix+"file2.2");
142        out = new PrintStream(
143                                 new BufferedOutputStream(
144                                    new FileOutputStream(fileout)));
145        while ((x=r.readLine()) != null) {
146            out.print(x+"\n");
147        }
148        out.flush();
149        out.close();
150
151        // assert (headers1 == headers2 && file1 == file2.2)
152        File file1 = new File(OutFNPrefix+"file1");
153        File file2 = new File(OutFNPrefix+"file2.2");
154        files.add(file1);
155        files.add(file2);
156        System.out.println("headers1"+headers1+"\nheaders2="+headers2);
157        if (!headers1.equals(headers2) || file1.length() != file2.length()) {
158            throw new RuntimeException("test failed");
159        }
160    }
161
162    public static void main(String args[]) throws Exception {
163        try {
164            ResponseCache.setDefault(new MyResponseCache());
165            FNPrefix = System.getProperty("test.src", ".")+"/";
166            OutFNPrefix = System.getProperty("test.scratch", ".")+"/";
167            new ResponseCacheTest();
168        } finally{
169            ResponseCache.setDefault(null);
170            for (Closeable c: streams) {
171                try { c.close(); } catch (IOException unused) {}
172            }
173            for (File f: files) {
174                f.delete();
175            }
176        }
177    }
178
179    static class MyResponseCache extends ResponseCache {
180        public CacheResponse get(URI uri, String rqstMethod,
181                                 Map<String,List<String>> rqstHeaders)
182            throws IOException
183        {
184            try {
185                if (uri.equals(url1.toURI())) {
186                    return new MyCacheResponse(FNPrefix+"file1.cache");
187                }
188            } catch (URISyntaxException ex) {
189                throw new RuntimeException (ex);
190            }
191            return null;
192        }
193
194        public CacheRequest put(URI uri, URLConnection conn)  throws IOException {
195            // save cache to file2.cache
196            // 1. serialize headers into file2.cache
197            // 2. write data to file2.cache
198            return new MyCacheRequest(OutFNPrefix+"file2.cache", conn.getHeaderFields());
199        }
200    }
201
202    static class MyCacheResponse extends CacheResponse {
203        FileInputStream fis;
204        Map<String,List<String>> headers;
205        public MyCacheResponse(String filename) {
206            try {
207                fis = new FileInputStream(new File(filename));
208                streams.add(fis);
209                ObjectInputStream ois = new ObjectInputStream(fis);
210                headers = (Map<String,List<String>>)ois.readObject();
211            } catch (Exception ex) {
212                // throw new RuntimeException(ex.getMessage());
213            }
214        }
215
216        public InputStream getBody() throws IOException {
217            return fis;
218        }
219
220        public Map<String,List<String>> getHeaders() throws IOException {
221            return headers;
222        }
223    }
224
225    static class MyCacheRequest extends CacheRequest {
226        FileOutputStream fos;
227        public MyCacheRequest(String filename, Map<String,List<String>> rspHeaders) {
228            try {
229                File file = new File(filename);
230                fos = new FileOutputStream(file);
231                streams.add(fos);
232                files.add(file);
233                ObjectOutputStream oos = new ObjectOutputStream(fos);
234                oos.writeObject(rspHeaders);
235            } catch (Exception ex) {
236                throw new RuntimeException(ex.getMessage());
237            }
238        }
239        public OutputStream getBody() throws IOException {
240            return fos;
241        }
242
243        public void abort() {
244            // no op
245        }
246    }
247
248
249}
250