All Downloads are FREE. Search and download functionalities are using the official Maven repository.

geb.download.DownloadSupport.groovy Maven / Gradle / Ivy

Go to download

Geb (pronounced "jeb") is a browser automation solution. It brings together the power of WebDriver, the elegance of jQuery content selection, the robustness of Page Object modelling and the expressiveness of the Groovy language.

There is a newer version: 0.7.2
Show newest version
/* 
 * Copyright 2011 the original author or authors.
 *
 * 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 geb.download

import geb.Browser
import org.openqa.selenium.Cookie

/**
 * Provides methods to directly download content into the running program using HttpURLConnection.
 * 

* Any cookies that the browser currently has will be automatically transferred to the url connection, * allowing it to assume the context of the browser. *

* An instance of this class will be mixed in to all browser, page and module objects making these methods * public methods on those objects. */ class DownloadSupport { /* NOTE - if public methods are added here, make sure they are also added to the binding updater. */ final private Browser browser // HTTP 1.1 states that this charset is the default if none was specified static final private DEFAULT_CHARSET = "ISO-8859-1" DownloadSupport(Browser browser) { this.browser = browser } /** * Creates a http url connection to a url, that has the same cookies as the browser. *

* Valid options are: * *

    *
  • {@code uri} - optional - the uri to resolve relative to the base option (current browser page used if {@code null}) *
  • {@code base} - optional - what to resolve the uri against (current browser page used if {@code null}) *
*/ HttpURLConnection download(Map options = [:]) { def url = resolveUrl(options) def connection = url.openConnection() applyCookies(connection, browser) connection } /** * Calls download with the single option '{@code uri}' as the given value. */ HttpURLConnection download(String uri) { download(uri: uri) } /** * Opens a url connection via {@link #download(Map)} and returns the response input stream. *

* If connectionConfig is given, it is called with the {@link HttpURLConnection} before the request is made. */ InputStream downloadStream(Map options = [:], Closure connectionConfig = null) { wrapInDownloadException(downloadWithConfig(options, connectionConfig)) { it.inputStream } } /** * Opens a url connection via {@link #download(String)} and returns the response input stream. *

* If connectionConfig is given, it is called with the {@link HttpURLConnection} before the request is made. */ InputStream downloadStream(String uri, Closure connectionConfig = null) { downloadStream(uri: uri, connectionConfig) } /** * Opens a url connection via {@link #download()} and returns the response input stream. *

* connectionConfig is called with the {@link HttpURLConnection} before the request is made. */ InputStream downloadStream(Closure connectionConfig) { downloadStream([:], connectionConfig) } /** * Opens a url connection via {@link #download(Map)} and returns the response text, if the content type was textual. *

* If connectionConfig is given, it is called with the {@link HttpURLConnection} before the request is made. */ String downloadText(Map options = [:], Closure connectionConfig = null) { def connection = downloadWithConfig(options, connectionConfig) connection.connect() def contentType = connection.contentType if (isTextContentType(contentType)) { def charset = determineCharset(contentType) wrapInDownloadException(connection) { it.inputStream.getText(charset) } } else { throw new DownloadException(connection, "cannot extract text from connection as content type is non text (is: $contentType)") } } /** * Opens a url connection via {@link #download(String)} and returns the response text, if the content type was textual. *

* If connectionConfig is given, it is called with the {@link HttpURLConnection} before the request is made. */ String downloadText(String uri, Closure connectionConfig = null) { downloadText(uri: uri, connectionConfig) } /** * Opens a url connection via {@link #download()} and returns the response text, if the content type was textual. *

* connectionConfig is called with the {@link HttpURLConnection} before the request is made. */ String downloadText(Closure connectionConfig) { downloadText([:], connectionConfig) } /** * Opens a url connection via {@link #download(Map)} and returns the raw bytes. *

* If connectionConfig is given, it is called with the {@link HttpURLConnection} before the request is made. */ byte[] downloadBytes(Map options = [:], Closure connectionConfig = null) { downloadStream(options, connectionConfig).bytes } /** * Opens a url connection via {@link #download()} and returns the raw bytes. *

* connectionConfig is called with the {@link HttpURLConnection} before the request is made. */ byte[] downloadBytes(Closure connectionConfig) { downloadStream(connectionConfig).bytes } /** * Opens a url connection via {@link #download(String)} and returns the raw bytes. *

* If connectionConfig is given, it is called with the {@link HttpURLConnection} before the request is made. */ byte[] downloadBytes(String uri, Closure connectionConfig = null) { downloadBytes(uri: uri, connectionConfig) } /** * Opens a url connection via {@link #download(Map)} and returns the content object. *

* If connectionConfig is given, it is called with the {@link HttpURLConnection} before the request is made. * * @see URLConnection#getContent() */ Object downloadContent(Map options = [:], Closure connectionConfig = null) { wrapInDownloadException(downloadWithConfig(options, connectionConfig)) { it.content } } /** * Opens a url connection via {@link #download(String)} and returns the content object. *

* If connectionConfig is given, it is called with the {@link HttpURLConnection} before the request is made. * * @see URLConnection#getContent() */ Object downloadContent(String uri, Closure connectionConfig = null) { downloadContent(uri: uri, connectionConfig) } /** * Opens a url connection via {@link #download(String)} and returns the content object. *

* connectionConfig is called with the {@link HttpURLConnection} before the request is made. * * @see URLConnection#getContent() */ Object downloadContent(Closure connectionConfig) { downloadContent([:], connectionConfig) } private HttpURLConnection downloadWithConfig(Map options, Closure config) { def connection = download(options) config?.call(connection) connection } /** * Returns a URL for what is to be downloaded. *

* If uri is non {@code null}, it is resolved against the browser's current page url. If it is {@code null}, * the browser's current page url will be returned. */ private URL resolveUrl(Map options) { def uri = options.uri def base = options.base ?: browser.driver.currentUrl uri ? new URI(base).resolve(uri).toURL() : new URL(base) } /** * Copies the browser's current cookies to the given connection via the "Cookie" header. */ private applyCookies(HttpURLConnection connection, Browser browser) { applyCookies(connection, browser.driver.manage().cookies) } /** * Copies the given cookies to the given connection via the "Cookie" header. */ private applyCookies(HttpURLConnection connection, Collection cookies) { def cookieHeader = cookies.collect { "${it.name}=${it.value}" }.join("; ") connection.setRequestProperty("Cookie", cookieHeader) } private boolean isTextContentType(String contentType) { contentType?.startsWith("text/") } private determineCharset(String contentType) { if (contentType) { def parts = contentType.split(";").collect { it.trim() } def charsetPart = parts.find { it.startsWith("charset=") } if (charsetPart) { charsetPart.split("=", 2)[1] } else { DEFAULT_CHARSET } } else { DEFAULT_CHARSET } } private wrapInDownloadException(HttpURLConnection connection, Closure operation) { try { operation(connection) } catch (Throwable e) { throw new DownloadException(connection, "An error occurred during the download operation", e) } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy