blob: a7e0f9756806175d830c5754d9299f80ca9f6fd2 [file] [log] [blame]
package com.mirantis.mk
/**
*
* HTTP functions
*
*/
/**
* Make generic HTTP call and return parsed JSON
*
* @param url URL to make the request against
* @param method HTTP method to use (default GET)
* @param data JSON data to POST or PUT
* @param headers Map of additional request headers
* @param read_timeout http session read timeout
*/
@NonCPS
def sendHttpRequest(url, method = 'GET', data = null, headers = [:], read_timeout=-1) {
def connection = new URL(url).openConnection()
if (read_timeout != -1){
connection.setReadTimeout(read_timeout*1000)
}
if (method != 'GET') {
connection.setRequestMethod(method)
}
if (data) {
headers['Content-Type'] = 'application/json'
}
headers['User-Agent'] = 'jenkins-groovy'
headers['Accept'] = 'application/json'
for (header in headers) {
connection.setRequestProperty(header.key, header.value)
}
if (data) {
connection.setDoOutput(true)
if (data instanceof String) {
dataStr = data
} else {
dataStr = new groovy.json.JsonBuilder(data).toString()
}
if(env.getEnvironment().containsKey('DEBUG') && env['DEBUG'] == "true"){
println("[HTTP] Request URL: ${url}, method: ${method}, headers: ${headers}, content: ${dataStr}")
}
def output = new OutputStreamWriter(connection.outputStream)
output.write(dataStr)
output.close()
}
if ( connection.responseCode == 200 ) {
response = connection.inputStream.text
try {
response_content = new groovy.json.JsonSlurperClassic().parseText(response)
} catch (groovy.json.JsonException|java.lang.NullPointerException e) {
if(env.getEnvironment().containsKey('DEBUG') && env['DEBUG'] == "true"){
println("[HTTP] Cought exception while trying parsing response as JSON: ${e}")
}
response_content = response
}
if(env.getEnvironment().containsKey('DEBUG') && env['DEBUG'] == "true"){
println("[HTTP] Response: code ${connection.responseCode}")
}
return response_content
} else {
if(env.getEnvironment().containsKey('DEBUG') && env['DEBUG'] == "true"){
println("[HTTP] Response: code ${connection.responseCode}")
}
throw new Exception(connection.responseCode + ": " + connection.inputStream.text)
}
}
/**
* Make HTTP GET request
*
* @param url URL which will requested
* @param data JSON data to PUT
*/
def sendHttpGetRequest(url, data = null, headers = [:]) {
return sendHttpRequest(url, 'GET', data, headers)
}
/**
* Make HTTP POST request
*
* @param url URL which will requested
* @param data JSON data to PUT
* @param read_timeout http session read timeout
*/
def sendHttpPostRequest(url, data = null, headers = [:], read_timeout=-1) {
return sendHttpRequest(url, 'POST', data, headers, read_timeout)
}
/**
* Make HTTP PUT request
*
* @param url URL which will requested
* @param data JSON data to PUT
*/
def sendHttpPutRequest(url, data = null, headers = [:]) {
return sendHttpRequest(url, 'PUT', data, headers)
}
/**
* Make HTTP DELETE request
*
* @param url URL which will requested
* @param data JSON data to PUT
*/
def sendHttpDeleteRequest(url, data = null, headers = [:]) {
return sendHttpRequest(url, 'DELETE', data, headers)
}
/**
* Make generic call using REST API and return parsed JSON
*
* @param base connection object, map with 'url' and optional 'authToken' keys
* @param uri URI which will be appended to connection base URL
* @param method HTTP method to use (default GET)
* @param data JSON data to POST, PUT or PATCH
* @param headers Map of additional request headers
*/
def restCall(base, uri, method = 'GET', data = null, headers = [:]) {
def connection = new URL("${base.url}${uri}").openConnection()
if (method != 'GET') {
connection.setRequestMethod(method)
}
connection.setRequestProperty('User-Agent', 'jenkins-groovy')
connection.setRequestProperty('Accept', 'application/json')
if (base.authToken) {
// XXX: removeme, explicitly use headers instead
connection.setRequestProperty('X-Auth-Token', base.authToken)
}
for (header in headers) {
connection.setRequestProperty(header.key, header.value)
}
if (data) {
connection.setDoOutput(true)
if (data instanceof String) {
dataStr = data
} else {
connection.setRequestProperty('Content-Type', 'application/json')
dataStr = new groovy.json.JsonBuilder(data).toString()
}
def out = new OutputStreamWriter(connection.outputStream)
out.write(dataStr)
out.close()
}
if ( connection.responseCode >= 200 && connection.responseCode < 300 ) {
res = connection.inputStream.text
try {
return new groovy.json.JsonSlurperClassic().parseText(res)
} catch (Exception e) {
return res
}
} else {
throw new Exception(connection.responseCode + ": " + connection.inputStream.text)
}
}
/**
* Make GET request using REST API and return parsed JSON
*
* @param base connection object, map with 'url' and optional 'authToken' keys
* @param uri URI which will be appended to server base URL
*/
def restGet(base, uri, data = null, headers = [:]) {
return restCall(base, uri, 'GET', data, headers)
}
/**
* Make POST request using REST API and return parsed JSON
*
* @param base connection object, map with 'url' and optional 'authToken' keys
* @param uri URI which will be appended to server base URL
* @param data JSON Data to POST
*/
def restPost(base, uri, data = null, headers = ['Accept': '*/*']) {
return restCall(base, uri, 'POST', data, headers)
}
/**
* Make PUT request using REST API and return parsed JSON
*
* @param base connection object, map with 'url' and optional 'authToken' keys
* @param uri URI which will be appended to server base URL
* @param data JSON Data to PUT
*/
def restPut(base, uri, data = null, headers = ['Accept': '*/*']) {
return restCall(base, uri, 'PUT', data, headers)
}
/**
* Make PATCH request using REST API and return parsed JSON
*
* @param base connection object, map with 'url' and optional 'authToken' keys
* @param uri URI which will be appended to server base URL
* @param data JSON Data to PUT
*/
def restPatch(base, uri, data = null, headers = ['Accept': '*/*']) {
return restCall(base, uri, 'PATCH', data, headers)
}
/**
* Make DELETE request using REST API and return parsed JSON
*
* @param base connection object, map with 'url' and optional 'authToken' keys
* @param uri URI which will be appended to server base URL
*/
def restDelete(base, uri, data = null, headers = [:]) {
return restCall(base, uri, 'DELETE', data, headers)
}
/**
* Set HTTP and HTTPS proxy for running JVM
* @param host HTTP proxy host
* @param port HTTP proxy port
* @param nonProxyHosts proxy excluded hosts, optional, default *.local
*/
def enableHttpProxy(host, port, nonProxyHosts="*.local"){
System.getProperties().put("proxySet", "true")
System.getProperties().put("http.proxyHost", host)
System.getProperties().put("http.proxyPort", port)
System.getProperties().put("https.proxyHost", host)
System.getProperties().put("https.proxyPort", port)
System.getProperties().put("http.nonProxyHosts", nonProxyHosts)
System.getProperties().put("https.nonProxyHosts", nonProxyHosts)
}
/**
* Disable HTTP and HTTPS proxy for running JVM
*/
def disableHttpProxy(){
System.getProperties().put("proxySet", "false")
System.getProperties().remove("http.proxyHost")
System.getProperties().remove("http.proxyPort")
System.getProperties().remove("https.proxyHost")
System.getProperties().remove("https.proxyPort")
System.getProperties().remove("http.nonProxyHosts")
System.getProperties().remove("https.nonProxyHosts")
}
/**
* Make HTTP request to the specified URL
*
* @param url URL to do HTTP request to
* @param method HTTP method to execute (`GET` by default)
* @param credsId Jenkins credentials ID to use for authorization
* @param pushData Data to send
* @param pushType MIME-type of pushData
* @param params Custom HTTP-headers
*
* @return Array containing return code and text
*
* @exception org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException
*/
def methodCall(String url, String method = 'GET', String credsId = '',
String pushData = '', String pushType = '', Map params = [:]) {
// Connection object
def httpReq = new URI(url).normalize().toURL().openConnection()
httpReq.setRequestMethod(method)
// Timeouts
httpReq.setConnectTimeout(10*1000) // milliseconds
httpReq.setReadTimeout(600*1000) // milliseconds
// Add authentication data
if (credsId) {
String authHeader = ''
def cred = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
com.cloudbees.plugins.credentials.impl.BaseStandardCredentials.class,
jenkins.model.Jenkins.instance).findAll {it.id == credsId}[0]
if (cred.class == com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl.class) {
authHeader = 'Basic ' + "${cred.getUsername()}:${cred.getPassword()}".getBytes('UTF-8').encodeBase64().toString()
} else if (cred.class == org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl.class) {
authHeader = 'Bearer ' + cred.getSecret()
//params << ['X-JFrog-Art-Api': cred.getSecret()]
}
params << ['Authorization': authHeader]
}
// Add custom headers if any
for (param in params) {
httpReq.setRequestProperty(param.key, param.value.toString())
}
// Do request
try {
if (pushData) {
httpReq.setRequestProperty('Content-Type', pushType ?: 'application/x-www-form-urlencoded')
if (method == 'GET') { // override incorrect method if pushData is passed
httpReq.setRequestMethod('POST')
}
httpReq.setDoOutput(true)
httpReq.getOutputStream().write(pushData.getBytes('UTF-8'))
} else {
httpReq.connect()
}
} catch (org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException e) {
throw e // show sandbox errors
} catch (Exception e) {
echo "Cauhgt '${e.class.name}' error: ${e.getMessage()}"
return [ -1, e.getMessage() ]
}
// Handle return data
int respCode = httpReq.getResponseCode()
String respText = ''
if (respCode >= 400) {
respText = httpReq.getErrorStream().getText() ?: httpReq.getResponseMessage()
} else {
respText = httpReq.getInputStream().getText()
}
// Return result as a tuple of response code and text
return [respCode, respText]
}
/**
* Make HTTP GET request to the specified URL
*
* @param url URL to do HTTP request to
* @param credsId Jenkins credentials ID to use for authorization
* @param params Custom HTTP-headers
*
* @return Array containing return code and text
*/
def doGet(String url, String credsId = '', Map params = [:]) {
return methodCall(url, 'GET', credsId, null, null, params)
}
/**
* Make HTTP POST request to the specified URL
*
* @param url URL to do HTTP request to
* @param credsId Jenkins credentials ID to use for authorization
* @param pushData Data to send
* @param pushType MIME-type of pushData
* @param params Custom HTTP-headers
*
* @return Array containing return code and text
*/
def doPost(String url, String credsId = '',
String pushData = '', String pushType = '', Map params = [:]) {
return methodCall(url, 'POST', credsId, pushData, pushType, params)
}
/**
* Make HTTP PUT request to the specified URL
*
* @param url URL to do HTTP request to
* @param credsId Jenkins credentials ID to use for authorization
* @param pushData Data to send
* @param pushType MIME-type of pushData
* @param params Custom HTTP-headers
*
* @return Array containing return code and text
*/
def doPut(String url, String credsId = '',
String pushData = '', String pushType = '', Map params = [:]) {
return methodCall(url, 'PUT', credsId, pushData, pushType, params)
}
/**
* Make HTTP DELETE request to the specified URL
*
* @param url URL to do HTTP request to
* @param credsId Jenkins credentials ID to use for authorization
* @param params Custom HTTP-headers
*
* @return Array containing return code and text
*/
def doDelete(String url, String credsId = '', Map params = [:]) {
return methodCall(url, 'DELETE', credsId, null, null, params)
}