Java tutorial
/* * jBrowserDriver (TM) * Copyright (C) 2014-2016 Machine Publishers, LLC and the jBrowserDriver contributors * https://github.com/MachinePublishers/jBrowserDriver * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.machinepublishers.jbrowserdriver; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.GZIPInputStream; import java.util.zip.InflaterInputStream; import org.apache.commons.lang.StringUtils; class ResponseHandler { private static final Pattern head = Pattern.compile("<head\\b[^>]*>", Pattern.CASE_INSENSITIVE); private static final Pattern html = Pattern.compile("<html\\b[^>]*>", Pattern.CASE_INSENSITIVE); private static final Pattern body = Pattern.compile("<body\\b[^>]*>", Pattern.CASE_INSENSITIVE); private static final Set<Integer> redirectCodes = Collections .unmodifiableSet(new HashSet<Integer>(Arrays.asList(new Integer[] { 301, 302, 303, 307, 308 }))); static InputStream handleResponse(StreamConnection conn, InputStream inputStream) throws IOException { String url = conn.getURL().toExternalForm(); byte[] bytes = new byte[0]; try { if ("gzip".equalsIgnoreCase(conn.getContentEncoding())) { bytes = Util.toBytes(new GZIPInputStream(inputStream)); } else if ("deflate".equalsIgnoreCase(conn.getContentEncoding())) { bytes = Util.toBytes(new InflaterInputStream(inputStream)); } else { bytes = Util.toBytes(inputStream); } conn.removeContentEncoding(); conn.setContentLength(bytes.length); Settings settings = SettingsManager.settings(); if (settings != null) { String disposition = conn.getHeaderField("Content-Disposition"); if (settings.saveAttachments() && disposition != null && StatusMonitor.instance().isPrimaryDocument(true, url)) { writeContentToDisk(bytes, StreamConnection.attachmentsDir(), url, conn.getContentTypeRaw(), disposition); } if (settings.saveMedia() && ((StreamConnection) conn).isMedia()) { writeContentToDisk(bytes, StreamConnection.mediaDir(), url, conn.getContentTypeRaw(), disposition); } } byte[] newContent = getBody(conn, bytes, url); if (newContent != null) { bytes = newContent; } } catch (Throwable t) { LogsServer.instance().exception(t); } finally { Util.close(inputStream); } conn.setContentLength(bytes.length); return new ByteArrayInputStream(bytes); } private static void writeContentToDisk(byte[] content, File dir, String url, String contentType, String contentDisposition) { String filename = Util.randomFileName(); File contentFile = new File(dir, new StringBuilder().append(filename).append(".content").toString()); File metaFile = new File(dir, new StringBuilder().append(filename).append(".metadata").toString()); contentFile.deleteOnExit(); metaFile.deleteOnExit(); try { Files.write(contentFile.toPath(), content); Files.write(metaFile.toPath(), (new StringBuilder().append(StringUtils.isEmpty(url) ? "" : url).append("\n") .append(StringUtils.isEmpty(contentType) ? "" : contentType).append("\n") .append(StringUtils.isEmpty(contentDisposition) ? "" : contentDisposition).toString()) .getBytes("utf-8")); } catch (Throwable t) { } } private static byte[] getBody(StreamConnection connection, byte[] inflatedContent, String url) { final Settings settings = SettingsManager.settings(); try { if (settings.quickRender() && ((StreamConnection) connection).isMedia()) { LogsServer.instance().trace("Media discarded: " + url); StatusMonitor.instance().addDiscarded(url); return new byte[0]; } else if (!redirectCodes.contains(connection.getResponseCode()) && (connection.getContentType() == null || connection.getContentType().indexOf("text/html") > -1) && StatusMonitor.instance().isPrimaryDocument(false, url)) { String intercepted = null; String charset = Util.charset(connection); String content = new String(inflatedContent, charset); Matcher matcher = head.matcher(content); if (matcher.find()) { intercepted = matcher.replaceFirst(matcher.group(0) + settings.script()); } else { matcher = html.matcher(content); if (matcher.find()) { intercepted = matcher.replaceFirst(new StringBuilder().append(matcher.group(0)) .append("<head>").append(settings.script()).append("</head>").toString()); } else { matcher = body.matcher(content); if (matcher.find()) { intercepted = (new StringBuilder().append("<html><head>").append(settings.script()) .append("</head>").append(content).append("</html>").toString()); } else { intercepted = content; } } } return intercepted == null ? null : intercepted.getBytes(charset); } } catch (Throwable t) { } return null; } }