|
1 /* |
|
2 * Copyright (c) 2009, 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. Oracle designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Oracle in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 * or visit www.oracle.com if you need additional information or have any |
|
23 * questions. |
|
24 */ |
|
25 |
|
26 package sun.net.www.http; |
|
27 |
|
28 import java.io.*; |
|
29 import java.util.ArrayList; |
|
30 import java.util.regex.*; |
|
31 import sun.net.NetProperties; |
|
32 import sun.util.logging.PlatformLogger; |
|
33 |
|
34 /** |
|
35 * Main class of the HTTP traffic capture tool. |
|
36 * Captures are triggered by the sun.net.http.captureRules system property. |
|
37 * If set, it should point to a file containing the capture rules. |
|
38 * Format for the file is simple: |
|
39 * - 1 rule per line |
|
40 * - Lines starting with a # are considered comments and ignored |
|
41 * - a rule is a pair of a regular expression and file pattern, separated by a comma |
|
42 * - The regular expression is applied to URLs, if it matches, the traffic for |
|
43 * that URL will be captured in the associated file. |
|
44 * - if the file name contains a '%d', then that sequence will be replaced by a |
|
45 * unique random number for each URL. This allow for multi-threaded captures |
|
46 * of URLs matching the same pattern. |
|
47 * - Rules are checked in sequence, in the same order as in the file, until a |
|
48 * match is found or the end of the list is reached. |
|
49 * |
|
50 * Examples of rules: |
|
51 * www\.sun\.com , sun%d.log |
|
52 * yahoo\.com\/.*asf , yahoo.log |
|
53 * |
|
54 * @author jccollet |
|
55 */ |
|
56 public class HttpCapture { |
|
57 private File file; |
|
58 private boolean incoming = true; |
|
59 private BufferedWriter out; |
|
60 private static boolean initialized; |
|
61 private static volatile ArrayList<Pattern> patterns; |
|
62 private static volatile ArrayList<String> capFiles; |
|
63 |
|
64 private static synchronized void init() { |
|
65 initialized = true; |
|
66 String rulesFile = java.security.AccessController.doPrivileged( |
|
67 new java.security.PrivilegedAction<>() { |
|
68 public String run() { |
|
69 return NetProperties.get("sun.net.http.captureRules"); |
|
70 } |
|
71 }); |
|
72 if (rulesFile != null && !rulesFile.isEmpty()) { |
|
73 BufferedReader in; |
|
74 try { |
|
75 in = new BufferedReader(new FileReader(rulesFile)); |
|
76 } catch (FileNotFoundException ex) { |
|
77 return; |
|
78 } |
|
79 try { |
|
80 String line = in.readLine(); |
|
81 while (line != null) { |
|
82 line = line.trim(); |
|
83 if (!line.startsWith("#")) { |
|
84 // skip line if it's a comment |
|
85 String[] s = line.split(","); |
|
86 if (s.length == 2) { |
|
87 if (patterns == null) { |
|
88 patterns = new ArrayList<>(); |
|
89 capFiles = new ArrayList<>(); |
|
90 } |
|
91 patterns.add(Pattern.compile(s[0].trim())); |
|
92 capFiles.add(s[1].trim()); |
|
93 } |
|
94 } |
|
95 line = in.readLine(); |
|
96 } |
|
97 } catch (IOException ioe) { |
|
98 |
|
99 } finally { |
|
100 try { |
|
101 in.close(); |
|
102 } catch (IOException ex) { |
|
103 } |
|
104 } |
|
105 } |
|
106 } |
|
107 |
|
108 private static synchronized boolean isInitialized() { |
|
109 return initialized; |
|
110 } |
|
111 |
|
112 private HttpCapture(File f, java.net.URL url) { |
|
113 file = f; |
|
114 try { |
|
115 out = new BufferedWriter(new FileWriter(file, true)); |
|
116 out.write("URL: " + url + "\n"); |
|
117 } catch (IOException ex) { |
|
118 PlatformLogger.getLogger(HttpCapture.class.getName()).severe(null, ex); |
|
119 } |
|
120 } |
|
121 |
|
122 public synchronized void sent(int c) throws IOException { |
|
123 if (incoming) { |
|
124 out.write("\n------>\n"); |
|
125 incoming = false; |
|
126 out.flush(); |
|
127 } |
|
128 out.write(c); |
|
129 } |
|
130 |
|
131 public synchronized void received(int c) throws IOException { |
|
132 if (!incoming) { |
|
133 out.write("\n<------\n"); |
|
134 incoming = true; |
|
135 out.flush(); |
|
136 } |
|
137 out.write(c); |
|
138 } |
|
139 |
|
140 public synchronized void flush() throws IOException { |
|
141 out.flush(); |
|
142 } |
|
143 |
|
144 public static HttpCapture getCapture(java.net.URL url) { |
|
145 if (!isInitialized()) { |
|
146 init(); |
|
147 } |
|
148 if (patterns == null || patterns.isEmpty()) { |
|
149 return null; |
|
150 } |
|
151 String s = url.toString(); |
|
152 for (int i = 0; i < patterns.size(); i++) { |
|
153 Pattern p = patterns.get(i); |
|
154 if (p.matcher(s).find()) { |
|
155 String f = capFiles.get(i); |
|
156 File fi; |
|
157 if (f.indexOf("%d") >= 0) { |
|
158 java.util.Random rand = new java.util.Random(); |
|
159 do { |
|
160 String f2 = f.replace("%d", Integer.toString(rand.nextInt())); |
|
161 fi = new File(f2); |
|
162 } while (fi.exists()); |
|
163 } else { |
|
164 fi = new File(f); |
|
165 } |
|
166 return new HttpCapture(fi, url); |
|
167 } |
|
168 } |
|
169 return null; |
|
170 } |
|
171 } |