Path: blob/master/src/java.base/share/classes/sun/net/www/http/HttpCapture.java
41161 views
/*1* Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.net.www.http;2627import java.io.*;28import java.util.ArrayList;29import java.util.regex.*;30import sun.net.NetProperties;31import sun.util.logging.PlatformLogger;3233/**34* Main class of the HTTP traffic capture tool.35* Captures are triggered by the sun.net.http.captureRules system property.36* If set, it should point to a file containing the capture rules.37* Format for the file is simple:38* - 1 rule per line39* - Lines starting with a # are considered comments and ignored40* - a rule is a pair of a regular expression and file pattern, separated by a comma41* - The regular expression is applied to URLs, if it matches, the traffic for42* that URL will be captured in the associated file.43* - if the file name contains a '%d', then that sequence will be replaced by a44* unique random number for each URL. This allow for multi-threaded captures45* of URLs matching the same pattern.46* - Rules are checked in sequence, in the same order as in the file, until a47* match is found or the end of the list is reached.48*49* Examples of rules:50* www\.sun\.com , sun%d.log51* yahoo\.com\/.*asf , yahoo.log52*53* @author jccollet54*/55public class HttpCapture {56// HttpCapture does blocking I/O operations while holding monitors.57// This is not a concern because it is rarely used.58private File file;59private boolean incoming = true;60private BufferedWriter out;61private static boolean initialized;62private static volatile ArrayList<Pattern> patterns;63private static volatile ArrayList<String> capFiles;6465private static synchronized void init() {66initialized = true;67@SuppressWarnings("removal")68String rulesFile = java.security.AccessController.doPrivileged(69new java.security.PrivilegedAction<>() {70public String run() {71return NetProperties.get("sun.net.http.captureRules");72}73});74if (rulesFile != null && !rulesFile.isEmpty()) {75BufferedReader in;76try {77in = new BufferedReader(new FileReader(rulesFile));78} catch (FileNotFoundException ex) {79return;80}81try {82String line = in.readLine();83while (line != null) {84line = line.trim();85if (!line.startsWith("#")) {86// skip line if it's a comment87String[] s = line.split(",");88if (s.length == 2) {89if (patterns == null) {90patterns = new ArrayList<>();91capFiles = new ArrayList<>();92}93patterns.add(Pattern.compile(s[0].trim()));94capFiles.add(s[1].trim());95}96}97line = in.readLine();98}99} catch (IOException ioe) {100101} finally {102try {103in.close();104} catch (IOException ex) {105}106}107}108}109110private static synchronized boolean isInitialized() {111return initialized;112}113114private HttpCapture(File f, java.net.URL url) {115file = f;116try {117out = new BufferedWriter(new FileWriter(file, true));118out.write("URL: " + url + "\n");119} catch (IOException ex) {120PlatformLogger.getLogger(HttpCapture.class.getName()).severe(null, ex);121}122}123124public synchronized void sent(int c) throws IOException {125if (incoming) {126out.write("\n------>\n");127incoming = false;128out.flush();129}130out.write(c);131}132133public synchronized void received(int c) throws IOException {134if (!incoming) {135out.write("\n<------\n");136incoming = true;137out.flush();138}139out.write(c);140}141142public synchronized void flush() throws IOException {143out.flush();144}145146public static HttpCapture getCapture(java.net.URL url) {147if (!isInitialized()) {148init();149}150if (patterns == null || patterns.isEmpty()) {151return null;152}153String s = url.toString();154for (int i = 0; i < patterns.size(); i++) {155Pattern p = patterns.get(i);156if (p.matcher(s).find()) {157String f = capFiles.get(i);158File fi;159if (f.indexOf("%d") >= 0) {160java.util.Random rand = new java.util.Random();161do {162String f2 = f.replace("%d", Integer.toString(rand.nextInt()));163fi = new File(f2);164} while (fi.exists());165} else {166fi = new File(f);167}168return new HttpCapture(fi, url);169}170}171return null;172}173}174175176