Skip to content

Instantly share code, notes, and snippets.

@treyturner
Last active April 9, 2020 09:30
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save treyturner/4c0f609677cbab7cef9f to your computer and use it in GitHub Desktop.
Save treyturner/4c0f609677cbab7cef9f to your computer and use it in GitHub Desktop.
Groovy: Parse a URL while including a handy map of the query string
/**
* Created by tturner on 7/22/15.
*/
import groovy.json.*
static def parseQueryString(String string) {
string.split('&').collectEntries{ param ->
param.split('=', 2).collect{ URLDecoder.decode(it, 'UTF-8') }
}
}
//Usage examples: https://gist.github.com/treyturner/4c0f609677cbab7cef9f
static def parseUri(String uri) {
def parsedUri
try {
parsedUri = new URI(uri)
if (parsedUri.scheme == 'mailto') {
def schemeSpecificPartList = parsedUri.schemeSpecificPart.split('\\?', 2)
def tempMailMap = parseQueryString(schemeSpecificPartList[1])
parsedUri.metaClass.mailMap = [
recipient: schemeSpecificPartList[0],
cc: tempMailMap.find{it.key.toLowerCase() == 'cc'}.value,
bcc: tempMailMap.find{it.key.toLowerCase() == 'bcc'}.value,
subject: tempMailMap.find{it.key.toLowerCase() == 'subject'}.value,
body: tempMailMap.find{it.key.toLowerCase() == 'body'}.value
]
}
if (parsedUri.fragment?.contains('?')) { // handle both fragment and query string
parsedUri.metaClass.rawQuery = parsedUri.rawFragment.split('\\?')[1]
parsedUri.metaClass.query = parsedUri.fragment.split('\\?')[1]
parsedUri.metaClass.rawFragment = parsedUri.rawFragment.split('\\?')[0]
parsedUri.metaClass.fragment = parsedUri.fragment.split('\\?')[0]
}
if (parsedUri.rawQuery) {
parsedUri.metaClass.queryMap = parseQueryString(parsedUri.rawQuery)
} else {
parsedUri.metaClass.queryMap = null
}
if (parsedUri.queryMap) {
parsedUri.queryMap.keySet().each { key ->
def value = parsedUri.queryMap[key]
if (value.startsWith('http') || value.startsWith('/')) {
parsedUri.queryMap[key] = parseUri(value)
}
}
}
} catch (e) {
assert false, "Parsing of URI failed: $uri\n$e"
}
parsedUri
}
//TESTS
/*
def uri = "http://google.com" //simple
//def uri = "http://google.com/" //trailing slash
//def uri = "http://username:password@sub.domain.com:8080/path/to/a/file.php#frag%5Bment%5D" //fragment
//def uri = "https://domain.com/path/to/file.html?param1=%28value1%29&param2=value2" //query string
//def uri = "http://test.domain.com/path/file.html?param=value1%7Cvalue2" //pipe
def parsedUri = parseUri(uri)
println "\nRESULTING URI OBJECT:\n======="
println new JsonBuilder(parsedUri).toPrettyString()
println "\nparsedUri.queryMap.param: ${parsedUri.queryMap?.param}"
*/
//REAL URLS
//facebook not logged in
/*
//not logged in
def uri = "https://www.facebook.com/login.php?next=https%3A%2F%2Fwww.facebook.com%2Fsharer%2Fsharer.php%3Fu%3Dhttp%253A%252F%252Fs3.amazonaws.com%252Finvodo-qa-static%252Fdynamic%252Findex.html%26ret%3Dlogin&display=popup"
//logged in
//def uri = "https://www.facebook.com/sharer/sharer.php?u=http%3A%2F%2Fs3.amazonaws.com%2Finvodo-qa-static%2Fdynamic%2Findex.html"
def parsedUri = parseUri(uri)
println "\nRESULTING URI OBJECT:\n======="
println new JsonBuilder(parsedUri).toPrettyString()
println "\nparsedUri.queryMap: $parsedUri.queryMap"
println "parsedUri.queryMap.u: ${parsedUri.queryMap?.u}"
println "parsedUri.queryMap.u.queryMap: ${parsedUri.queryMap?.u?.queryMap}"
println "parsedUri.queryMap.next: ${parsedUri.queryMap?.next}"
println "parsedUri.queryMap.next.queryMap: ${parsedUri.queryMap?.next?.queryMap}"
println "parsedUri.queryMap.next.queryMap.u: ${parsedUri.queryMap?.next?.queryMap?.u}"
println "parsedUri.queryMap.next.queryMap.u.queryMap: ${parsedUri.queryMap?.next?.queryMap?.u?.queryMap}"
*/
//twitter
/*
//first uri is properly encoded as seen in chrome
def uri = "https://twitter.com/intent/tweet?text=Check%20out%20this%20video%20at%20invodo.com%20%7C%20HomeHeader2&url=http%3A%2F%2Fs3.amazonaws.com%2Finvodo-qa-static%2Fdynamic%2Findex.html&original_referer=http%3A%2F%2Fs3.amazonaws.com%2Finvodo-qa-static%2Fdynamic%2Findex.html"
//second uri has the pipe pre-decoded as seen in firefox
//def uri = "https://twitter.com/intent/tweet?text=Check%20out%20this%20video%20at%20invodo.com%20|%20HomeHeader2&url=http%3A%2F%2Fs3.amazonaws.com%2Finvodo-qa-static%2Fdynamic%2Findex.html&original_referer=http%3A%2F%2Fs3.amazonaws.com%2Finvodo-qa-static%2Fdynamic%2Findex.html"
def parsedUri = parseUri(uri)
println "\nRESULTING URI OBJECT:\n======="
println new JsonBuilder(parsedUri).toPrettyString()
println "\nparsedUri.host: $parsedUri.host"
println "parsedUri.path: $parsedUri.path"
println "parsedUri.queryMap.text: $parsedUri.queryMap.text"
println "parsedUri.queryMap.url: $parsedUri.queryMap.url"
println "parsedUri.queryMap.original_referer: $parsedUri.queryMap.original_referer"
*/
//pinterest
/*
//not logged in
def uri = "https://www.pinterest.com/join/?next=/pin/create/button/%3Fdescription%3DHomeHeader2%2520%257C%2520invodo.com%26media%3Dhttp%3A//e.testing.invodo.com/media/lib/77/video/CE9L4U2H/960_540_pre.jpg%26url%3Dhttp%253A%252F%252Fs3.amazonaws.com%252Finvodo-qa-static%252Fdynamic%252Findex.html"
//logged in
//def uri = "https://www.pinterest.com/pin/create/button/?description=HomeHeader2%20%7C%20invodo.com&media=http://e.testing.invodo.com/media/lib/77/video/CE9L4U2H/960_540_pre.jpg&url=http%3A%2F%2Fs3.amazonaws.com%2Finvodo-qa-static%2Fdynamic%2Findex.html"
def parsedUri = parseUri(uri)
println "\nRESULTING URI OBJECT:\n======="
println new JsonBuilder(parsedUri).toPrettyString()
println "parsedUri.queryMap.next.queryMap.description: ${parsedUri.queryMap.next?.queryMap?.description}"
println "parsedUri.queryMap.next.queryMap.media: ${parsedUri.queryMap.next?.queryMap?.media}"
println "parsedUri.queryMap.next.queryMap.url: ${parsedUri.queryMap.next?.queryMap?.url}"
println "parsedUri.queryMap.description: ${parsedUri.queryMap.description}"
println "parsedUri.queryMap.media: ${parsedUri.queryMap.media}"
println "parsedUri.queryMap.url: ${parsedUri.queryMap.url}"
*/
//mailto, created using http://www.cha4mot.com/t_mailto.html
/*
def uri = "mailto:recipient@domain.com?CC=carboncopy@ccdomain.com&BCC=blindcarboncopy@bccdomain.com&Subject=Subject%20lines%20are%20important%20things%20to%20include%20in%20an%20email%20message&Body=%22Lorem%20ipsum%20dolor%20sit%20amet%2C%20consectetur%20adipiscing%20elit%2C%20sed%20do%20eiusmod%20tempor%20incididunt%20ut%20labore%20et%20dolore%20magna%20aliqua.%20Ut%20enim%20ad%20minim%20veniam%2C%20quis%20nostrud%20exercitation%20ullamco%20laboris%20nisi%20ut%20aliquip%20ex%20ea%20commodo%20consequat.%0A%0ADuis%20aute%20irure%20dolor%20in%20reprehenderit%20in%20voluptate%20velit%20esse%20cillum%20dolore%20eu%20fugiat%20nulla%20pariatur.%20Excepteur%20sint%20occaecat%20cupidatat%20non%20proident%2C%20sunt%20in%20culpa%20qui%20officia%20deserunt%20mollit%20anim%20id%20est%20laborum.%22"
def parsedUri = parseUri(uri)
println "\nRESULTING URI OBJECT:\n======="
println new JsonBuilder(parsedUri).toPrettyString()
println "\nparsedUri.mailMap.recipient: $parsedUri.mailMap.recipient"
println "parsedUri.mailMap.cc: $parsedUri.mailMap.cc"
println "parsedUri.mailMap.bcc: $parsedUri.mailMap.bcc"
println "parsedUri.mailMap.subject: $parsedUri.mailMap.subject"
println "parsedUri.mailMap.body: $parsedUri.mailMap.body"
*/
//eve password reset
/*
def uri = "https://s3.amazonaws.com/invodo-eve-testing/cms-testing-1/index.html#/resetPassword?u=tturner@invodo.com&c=1437540441686&e=574487861&h=33c7ed6903cbd2fbea4744c3a8b9256b"
def parsedUri = parseUri(uri)
println "\nRESULTING URI OBJECT:\n======="
println new JsonBuilder(parsedUri).toPrettyString()
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment