Enhancements to HTTPContext
* Default port is no 80. * Support for HTTP Basic Authentication. * Support for HTTPS. * Support for Content-Type. Defaults to "applicaion/json" but also supports passing a map to be encoded as "application/x-www-form-urlencoded".
This commit is contained in:
parent
3929968af1
commit
0494b53108
@ -1,6 +1,6 @@
|
|||||||
#Sat, 21 Sep 2013 02:27:46 -0500
|
#Sun, 21 Sep 2014 03:05:17 -0500
|
||||||
name=jdb-util
|
name=jdb-util
|
||||||
version=2.2
|
version=2.3
|
||||||
lib.local=true
|
lib.local=true
|
||||||
|
|
||||||
build.number=8
|
build.number=9
|
||||||
|
@ -4,6 +4,10 @@
|
|||||||
package com.jdbernard.net
|
package com.jdbernard.net
|
||||||
|
|
||||||
import java.net.Socket
|
import java.net.Socket
|
||||||
|
import java.net.URLEncoder
|
||||||
|
import javax.net.ssl.SSLSocket
|
||||||
|
import javax.net.ssl.SSLSocketFactory
|
||||||
|
import javax.xml.bind.DatatypeConverter
|
||||||
import groovy.json.JsonBuilder
|
import groovy.json.JsonBuilder
|
||||||
import groovy.json.JsonSlurper
|
import groovy.json.JsonSlurper
|
||||||
|
|
||||||
@ -15,19 +19,34 @@ public class HttpContext {
|
|||||||
public String host = 'vbs-test'
|
public String host = 'vbs-test'
|
||||||
|
|
||||||
/** The port number.*/
|
/** The port number.*/
|
||||||
public int port = 8000
|
public int port = 80
|
||||||
|
|
||||||
/** A cookie value to send in the request. This value will be automatically
|
/** A cookie value to send in the request. This value will be automatically
|
||||||
* set from any `Set-Cookie` header in the request response. */
|
* set from any `Set-Cookie` header in the request response. */
|
||||||
public String cookie
|
public String cookie
|
||||||
|
|
||||||
|
/** HTTP Basic Authentication information. If this is a string, it will be
|
||||||
|
* Base64 encoded as-is. Otherwise it may be an object with "username" and
|
||||||
|
* "password" properties. The username and password will be concatenated
|
||||||
|
* with a colon in between. The result will be Base64 encoded. */
|
||||||
|
public def basicAuth
|
||||||
|
|
||||||
|
/** Set this to `true` to use HTTPS. Otherwise, HTTP will be used. */
|
||||||
|
public boolean secure = false
|
||||||
|
|
||||||
|
/** The default Content-Type that we will send with our requests. This can
|
||||||
|
* be overridden using the different method overloads. */
|
||||||
|
public String defaultContentType = "application/json"
|
||||||
|
|
||||||
|
private SSLSocketFactory sslSocketFactory = null;
|
||||||
|
|
||||||
/** #### makeMessage
|
/** #### makeMessage
|
||||||
* Make and return an HTTP request for the given HTTP method and URL. If
|
* Make and return an HTTP request for the given HTTP method and URL. If
|
||||||
* `request` is not null, it is expected to be an object which will be
|
* `request` is not null, it is expected to be an object which will be
|
||||||
* converted to JSON and included as the request body. The `Host`,
|
* converted to JSON and included as the request body. The `Host`,
|
||||||
* `Cookie`, and `Content-Length` headers will be added based on the
|
* `Cookie`, and `Content-Length` headers will be added based on the
|
||||||
* `host` and `cookie` fields and the `request` object. */
|
* `host` and `cookie` fields and the `request` object. */
|
||||||
public String makeMessage(String method, String url, def request) {
|
public String makeMessage(String method, String url, String contentType, def request) {
|
||||||
StringBuilder message = new StringBuilder()
|
StringBuilder message = new StringBuilder()
|
||||||
message.append(method)
|
message.append(method)
|
||||||
message.append(" ")
|
message.append(" ")
|
||||||
@ -46,24 +65,60 @@ public class HttpContext {
|
|||||||
message.append(cookie)
|
message.append(cookie)
|
||||||
message.append("\r\n") }
|
message.append("\r\n") }
|
||||||
|
|
||||||
|
if (basicAuth) {
|
||||||
|
message.append("Authorization: Basic ")
|
||||||
|
|
||||||
|
if (basicAuth instanceof String) message.append(
|
||||||
|
DatatypeConverter.printBase64Binary(
|
||||||
|
(basicAuth as String).bytes))
|
||||||
|
|
||||||
|
else message.append(
|
||||||
|
DatatypeConverter.printBase64Binary(
|
||||||
|
"${basicAuth.username ?: ''}:${basicAuth.password ?: ''}".bytes))
|
||||||
|
|
||||||
|
message.append("\r\n") }
|
||||||
|
|
||||||
|
if (contentType) {
|
||||||
|
message.append("Content-Type: ")
|
||||||
|
message.append(contentType)
|
||||||
|
message.append("\r\n") }
|
||||||
|
|
||||||
if (request) {
|
if (request) {
|
||||||
|
String requestBody
|
||||||
|
if (contentType.startsWith("application/json") &&
|
||||||
|
request instanceof Map) {
|
||||||
def jsonRequestBuilder = new JsonBuilder(request)
|
def jsonRequestBuilder = new JsonBuilder(request)
|
||||||
String requestBody = jsonRequestBuilder.toString()
|
requestBody = jsonRequestBuilder.toString() }
|
||||||
|
|
||||||
|
else if (contentType.startsWith("application/x-www-form-urlencoded") &&
|
||||||
|
request instanceof Map)
|
||||||
|
requestBody = urlEncode(request)
|
||||||
|
|
||||||
|
else requestBody = request.toString()
|
||||||
|
|
||||||
message.append("Content-Length: ")
|
message.append("Content-Length: ")
|
||||||
message.append(requestBody.length())
|
message.append(requestBody.length())
|
||||||
message.append("\r\n\r\n")
|
message.append("\r\n\r\n")
|
||||||
message.append(requestBody) }
|
message.append(requestBody)
|
||||||
|
|
||||||
|
message.append("\r\n") }
|
||||||
|
else message.append("\r\n")
|
||||||
|
|
||||||
message.append("\r\n")
|
|
||||||
return message.toString()
|
return message.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** #### send
|
||||||
|
* A wrapper around `makeMessage` and `send(String message)` to create a
|
||||||
|
* request, send it, and return the response. This version allows you to
|
||||||
|
* specify the request's Content-Type.*/
|
||||||
|
public def send(String method, String url, String contentType, def request) {
|
||||||
|
return send(makeMessage(method, url, contentType, request)) }
|
||||||
|
|
||||||
/** #### send
|
/** #### send
|
||||||
* A wrapper around `makeMessage` and `send(String message)` to create a
|
* A wrapper around `makeMessage` and `send(String message)` to create a
|
||||||
* request, send it, and return the response. */
|
* request, send it, and return the response. */
|
||||||
public def send(String method, String url, def request) {
|
public def send(String method, String url, def request) {
|
||||||
return send(makeMessage(method, url, request)) }
|
return send(makeMessage(method, url, defaultContentType, request)) }
|
||||||
|
|
||||||
/** #### send
|
/** #### send
|
||||||
* Send a message to the host specified by the object's `host` and `port`
|
* Send a message to the host specified by the object's `host` and `port`
|
||||||
@ -79,7 +134,18 @@ public class HttpContext {
|
|||||||
*/
|
*/
|
||||||
public def send(String message) {
|
public def send(String message) {
|
||||||
Map result = [headers:[], content: null]
|
Map result = [headers:[], content: null]
|
||||||
Socket sock = new Socket(host, port)
|
|
||||||
|
Socket sock
|
||||||
|
|
||||||
|
if (secure) {
|
||||||
|
if (!sslSocketFactory)
|
||||||
|
sslSocketFactory = SSLSocketFactory.getDefault()
|
||||||
|
|
||||||
|
sock = sslSocketFactory.createSocket(host, port)
|
||||||
|
}
|
||||||
|
|
||||||
|
else sock = new Socket(host, port)
|
||||||
|
|
||||||
def startTime
|
def startTime
|
||||||
|
|
||||||
sock.withStreams { strin, out ->
|
sock.withStreams { strin, out ->
|
||||||
@ -164,4 +230,18 @@ public class HttpContext {
|
|||||||
* `send(String method, String url, def request)` with `method =
|
* `send(String method, String url, def request)` with `method =
|
||||||
* "POST"`. */
|
* "POST"`. */
|
||||||
public def post(String url, def body) { return send('POST', url, body) }
|
public def post(String url, def body) { return send('POST', url, body) }
|
||||||
|
|
||||||
|
/** #### post
|
||||||
|
* A wrapper to perform a `POST` request. This calls
|
||||||
|
* `send(String method, String url, def request)` with `method =
|
||||||
|
* "POST"`. This version also allows you to set the request's
|
||||||
|
* Content-Type. */
|
||||||
|
public def post(String url, String contentType, def body) {
|
||||||
|
return send('POST', url, contentType, body) }
|
||||||
|
|
||||||
|
private String urlEncode(Map m) {
|
||||||
|
List<String> parts = m.collect { k, v ->
|
||||||
|
"$k=${URLEncoder.encode(v.toString(), 'UTF-8')}" }
|
||||||
|
return parts.join("&") }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user