Can Gradle add an HTTP header to an 'apply from' URL?

This might be more of a feature request, but the name says it all… I need to add Authorization and Accept headers into a call for a gradle script that is HTTP-hosted behind some security. Is this possible or do I need to pre-run a curl script?

Hi Charley,

There’s currently no way to do this. You’ll have to pre fetch the script yourself and have Gradle read it from the filesystem I’m afraid. You could do the fetching yourself within the Gradle build script using a Java HTTP client, or even just ‘java.net.URL’.

Okay, thanks Luke. Do you happen to know of an example of this kind of task in a build script hosted somewhere? The gradle user guide has many small snippets, but not many “big picture” examples of functional scripts.

Hi Charley,

I can’t recall of any examples of this kind of thing unfortunately. Which parts specifically are you unsure about?

At the time of writing, I was a little unclear about the way you can drop java code directly in your gradle scripts. It seems the underlying subtlety from being able to write both imperative and declarative stanzas was lost on me. A lot of this is reflected in ignorance about Groovy, and how the syntax of the gradle script works. I spent the 90 minutes to watch Hans’ video linked on the “Learn” page [link], which was very helpful.

Most of the example snippets in the user guide are oriented towards exploring options of a single part of a gradle script (eg. options for configuring your test lifecycle), while I was looking for a picture of how the language features tie everything together (eg. example working scripts that showcase different features). An example such as adding an HTTP header to the request so you can apply a remote plugin (eg. from a private GitHub repo) fully qualifies. Maybe I can contribute once I figure that out :slight_smile:

I have done something similar by using HTTP Builder from a gradle script. By buildSrc/build.gradle includes

apply plugin: 'groovy'
repositories {
    mavenCentral()
}
dependencies {
    groovy localGroovy()
    compile 'org.codehaus.groovy.modules.http-builder:http-builder:0.6'
    testCompile 'junit:junit:4.11'
}

and a class in there referenced by my build that uses HTTPBuilder to do various GET and POST operations with authentication. I don’t have an easily extractable example at this point, but I found this to be very straightforward to do without any real prior experience with either HTTPBuilder or gradle (but plenty of groovy background). There was not “special” about it though…basically I just called the appropriate code from inside a task’s body.

Is the source of your gradle script that invokes/configures HTTPBuilder available for learning eyes?

If your needs are modest, you can just use the JDK classes…

task downloadFileWithAuthn {
  doLast {
    def name = "username"
    def password = "password"
      def authString = name + ":" + password
    def authStringEnc = authString.bytes.encodeBase64().toString()
      URL url = new URL("http://org.com/someFile.txt")
    URLConnection urlConnection = url.openConnection()
    urlConnection.setRequestProperty("Authorization", "Basic " + authStringEnc)
    urlConnection.inputStream.withStream {
      file("downloaded.txt").bytes = it.bytes
    }
  }
}

‘java.net.URL’ is reasonably capable, it’s just a very weird API.

By contrast, we can get pretty good mileage from the execute() function in Groovy:

try{
    def curl = "curl -o my.gradle -H 'Authorization: basic himom!' http://example.com/my.gradle"
    curl.execute().waitFor()
} catch (Exception e) {
    println 'Failed to get remote gradle script'
}
apply from : "my.gradle"

One thing I noticed here was that curl barfed an error about not being able to use openssl for an https call, but the same command at the command line runs fine. Does the Groovy execute() call load up it’s own path, possibly different from the caller’s exec environment?