package com.codeborne.selenide.impl; import com.codeborne.selenide.Configuration; import com.codeborne.selenide.WebDriverRunner; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.client.config.CookieSpecs; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpGet; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.impl.cookie.BasicClientCookie; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.ssl.SSLContextBuilder; import org.apache.http.ssl.TrustStrategy; import org.openqa.selenium.Cookie; import org.openqa.selenium.WebElement; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.security.cert.X509Certificate; import java.util.Set; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import static com.codeborne.selenide.impl.Describe.describe; import static org.apache.commons.io.FileUtils.copyInputStreamToFile; import static org.apache.http.client.protocol.HttpClientContext.COOKIE_STORE; public class DownloadFileWithHttpRequest { private static final Logger log = Logger.getLogger(DownloadFileWithHttpRequest.class.getName()); public static boolean ignoreSelfSignedCerts = true; public File download(WebElement element) throws IOException { String fileToDownloadLocation = element.getAttribute("href"); if (fileToDownloadLocation == null || fileToDownloadLocation.trim().isEmpty()) { throw new IllegalArgumentException("The element does not have href attribute: " + describe(element)); } HttpResponse response = executeHttpRequest(fileToDownloadLocation); if (response.getStatusLine().getStatusCode() >= 500) { throw new RuntimeException("Failed to download file " + fileToDownloadLocation + ": " + response.getStatusLine()); } if (response.getStatusLine().getStatusCode() >= 400) { throw new FileNotFoundException("Failed to download file " + fileToDownloadLocation + ": " + response.getStatusLine()); } File downloadedFile = prepareTargetFile(fileToDownloadLocation, response); return saveFileContent(response, downloadedFile); } protected HttpResponse executeHttpRequest(String fileToDownloadLocation) throws IOException { CloseableHttpClient httpClient = ignoreSelfSignedCerts ? createTrustingHttpClient() : HttpClients.createDefault(); HttpGet httpGet = new HttpGet(fileToDownloadLocation); httpGet.setConfig(RequestConfig.custom() .setConnectTimeout((int) Configuration.timeout) .setSocketTimeout((int) Configuration.timeout) .setConnectionRequestTimeout((int) Configuration.timeout) .setRedirectsEnabled(true) .setCircularRedirectsAllowed(true) .setMaxRedirects(20) .setCookieSpec(CookieSpecs.STANDARD) .build() ); HttpContext localContext = new BasicHttpContext(); localContext.setAttribute(COOKIE_STORE, mimicCookieState()); return httpClient.execute(httpGet, localContext); } private static class TrustAllStrategy implements TrustStrategy { @Override public boolean isTrusted(X509Certificate[] arg0, String arg1) { return true; } } /** configure HttpClient to ignore self-signed certs as described here: http://literatejava.com/networks/ignore-ssl-certificate-errors-apache-httpclient-4-4/ */ private CloseableHttpClient createTrustingHttpClient() throws IOException { try { HttpClientBuilder builder = HttpClientBuilder.create(); SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustAllStrategy()).build(); builder.setSslcontext(sslContext); HostnameVerifier hostnameVerifier = SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER; SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier); Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", PlainConnectionSocketFactory.getSocketFactory()) .register("https", sslSocketFactory) .build(); PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager(socketFactoryRegistry); builder.setConnectionManager(connMgr); return builder.build(); } catch (Exception e) { throw new IOException(e); } } protected File prepareTargetFile(String fileToDownloadLocation, HttpResponse response) throws MalformedURLException { return new File(Configuration.reportsFolder, getFileName(fileToDownloadLocation, response)); } protected String getFileName(String fileToDownloadLocation, HttpResponse response) throws MalformedURLException { for (Header header : response.getAllHeaders()) { String fileName = getFileNameFromContentDisposition(header.getName(), header.getValue()); if (fileName != null) { return fileName; } } log.info("Cannot extract file name from http headers. Found headers: "); for (Header header : response.getAllHeaders()) { log.info(header.getName() + '=' + header.getValue()); } return new URL(fileToDownloadLocation).getFile().replaceFirst("/|\\\\", ""); } protected String getFileNameFromContentDisposition(String headerName, String headerValue) { if ("Content-Disposition".equalsIgnoreCase(headerName)) { Matcher regex = Pattern.compile(".*filename=\"?([^\"]*)\"?.*").matcher(headerValue); return regex.matches() ? regex.replaceFirst("$1") : null; } return null; } protected BasicCookieStore mimicCookieState() { Set<Cookie> seleniumCookieSet = WebDriverRunner.getWebDriver().manage().getCookies(); BasicCookieStore mimicWebDriverCookieStore = new BasicCookieStore(); for (Cookie seleniumCookie : seleniumCookieSet) { mimicWebDriverCookieStore.addCookie(duplicateCookie(seleniumCookie)); } return mimicWebDriverCookieStore; } protected BasicClientCookie duplicateCookie(Cookie seleniumCookie) { BasicClientCookie duplicateCookie = new BasicClientCookie(seleniumCookie.getName(), seleniumCookie.getValue()); duplicateCookie.setDomain(seleniumCookie.getDomain()); duplicateCookie.setAttribute(BasicClientCookie.DOMAIN_ATTR, seleniumCookie.getDomain()); duplicateCookie.setSecure(seleniumCookie.isSecure()); duplicateCookie.setExpiryDate(seleniumCookie.getExpiry()); duplicateCookie.setPath(seleniumCookie.getPath()); return duplicateCookie; } protected File saveFileContent(HttpResponse response, File downloadedFile) throws IOException { copyInputStreamToFile(response.getEntity().getContent(), downloadedFile); return downloadedFile; } }