diff --git a/src/main/java/com/smartystreets/api/ClientBuilder.java b/src/main/java/com/smartystreets/api/ClientBuilder.java
index 949187f..f1d8032 100644
--- a/src/main/java/com/smartystreets/api/ClientBuilder.java
+++ b/src/main/java/com/smartystreets/api/ClientBuilder.java
@@ -7,8 +7,10 @@
import java.util.Map;
/**
- * The ClientBuilder class helps you build a client object for one of the supported SmartyStreets APIs.
- * You can use ClientBuilder's methods to customize settings like maximum retries or timeout duration. These methods
+ * The ClientBuilder class helps you build a client object for one of the
+ * supported SmartyStreets APIs.
+ * You can use ClientBuilder's methods to customize settings like maximum
+ * retries or timeout duration. These methods
* are chainable, so you can usually get set up with one line of code.
*/
public class ClientBuilder {
@@ -30,6 +32,7 @@ public class ClientBuilder {
private Proxy proxy;
private Map customHeaders;
private List licenses = new ArrayList<>();
+ private String ip;
private ClientBuilder() {
this.serializer = new SmartySerializer();
@@ -47,7 +50,8 @@ public ClientBuilder(String authId, String authToken) {
}
/**
- * @param maxRetries The maximum number of times to retry sending the request to the API. (Default is 5)
+ * @param maxRetries The maximum number of times to retry sending the request to
+ * the API. (Default is 5)
* @return Returns this to accommodate method chaining.
*/
public ClientBuilder retryAtMost(int maxRetries) {
@@ -56,7 +60,8 @@ public ClientBuilder retryAtMost(int maxRetries) {
}
/**
- * @param maxTimeout The maximum time (in milliseconds) to wait for a connection, and also to wait for
+ * @param maxTimeout The maximum time (in milliseconds) to wait for a
+ * connection, and also to wait for
* the response to be read. (Default is 10000)
* @return Returns this to accommodate method chaining.
*/
@@ -66,7 +71,8 @@ public ClientBuilder withMaxTimeout(int maxTimeout) {
}
/**
- * @param sender Default is a series of nested senders. See buildSender().
+ * @param sender Default is a series of nested senders. See
+ * buildSender().
* @return Returns this to accommodate method chaining.
*/
public ClientBuilder withSender(Sender sender) {
@@ -76,6 +82,7 @@ public ClientBuilder withSender(Sender sender) {
/**
* Changes the Serializer from the default SmartySerializer.
+ *
* @param serializer An object that implements the Serializer interface.
* @return Returns this to accommodate method chaining.
*/
@@ -86,7 +93,9 @@ public ClientBuilder withSerializer(Serializer serializer) {
/**
* This may be useful when using a local installation of the SmartyStreets APIs.
- * @param baseUrl Defaults to the URL for the API corresponding to the Client object being built.
+ *
+ * @param baseUrl Defaults to the URL for the API corresponding to the
+ * Client object being built.
* @return Returns this to accommodate method chaining.
*/
public ClientBuilder withCustomBaseUrl(String baseUrl) {
@@ -96,7 +105,9 @@ public ClientBuilder withCustomBaseUrl(String baseUrl) {
/**
* Use this to add any additional headers you need.
- * @param customHeaders A String to Object Map of header name/value pairs.
+ *
+ * @param customHeaders A String to Object Map of header name/value
+ * pairs.
* @return Returns this to accommodate method chaining.
*/
public ClientBuilder withCustomHeaders(Map customHeaders) {
@@ -106,6 +117,7 @@ public ClientBuilder withCustomHeaders(Map customHeaders) {
/**
* Use this to specify a proxy through which to send all lookups.
+ *
* @param proxyType Choose a java.net.Proxy.Type.
* @param proxyHost The host of the proxy server (do not include the port).
* @param proxyPort The port on the proxy server to which you wish to connect.
@@ -116,8 +128,15 @@ public ClientBuilder withProxy(Proxy.Type proxyType, String proxyHost, int proxy
return this;
}
+ public ClientBuilder withXForwardedFor(String ip) {
+ this.ip = ip;
+ return this;
+ }
+
/**
- * Enables debug mode, which will print information about the HTTP request and response to the console.
+ * Enables debug mode, which will print information about the HTTP request and
+ * response to the console.
+ *
* @return Returns this to accommodate method chaining.
*/
public ClientBuilder withDebug() {
@@ -127,6 +146,7 @@ public ClientBuilder withDebug() {
/**
* Allows caller to specify licenses (aka "tracks") they wish to use.
+ *
* @return Returns this to accommodate method chaining.
*/
public ClientBuilder withLicenses(List licenses) {
@@ -184,23 +204,27 @@ private Sender buildSender() {
return this.httpSender;
Sender sender;
- if (this.proxy != null)
+ if (this.proxy != null) {
sender = new SmartySender(this.maxTimeout, this.proxy);
- else
+ } else {
sender = new SmartySender(this.maxTimeout);
+ }
sender = new StatusCodeSender(sender);
-
- if (this.customHeaders != null)
+ if (this.ip != null) {
+ customHeaders.put("X-Forwarded-For", this.ip);
+ }
+ if (this.customHeaders != null) {
sender = new CustomHeaderSender(this.customHeaders, sender);
-
- if (this.signer != null)
+ }
+ if (this.signer != null) {
sender = new SigningSender(this.signer, sender);
-
+ }
sender = new URLPrefixSender(this.urlPrefix, sender);
- if (this.maxRetries > 0)
+ if (this.maxRetries > 0) {
sender = new RetrySender(this.maxRetries, new MySleeper(), new MyLogger(), sender);
+ }
sender = new LicenseSender(this.licenses, sender);
diff --git a/src/test/java/com/smartystreets/api/CustomHeaderSenderTest.java b/src/test/java/com/smartystreets/api/CustomHeaderSenderTest.java
index 902c3df..40381c2 100644
--- a/src/test/java/com/smartystreets/api/CustomHeaderSenderTest.java
+++ b/src/test/java/com/smartystreets/api/CustomHeaderSenderTest.java
@@ -19,12 +19,10 @@ public void testAllCustomHeadersAreAddedToTheRequest() throws Exception {
RequestCapturingSender inner = new RequestCapturingSender();
CustomHeaderSender sender = new CustomHeaderSender(headers, inner);
Request request = new Request();
-
sender.send(request);
Map requestHeaders = inner.getRequest().getHeaders();
assertNotNull("There should be headers here.", requestHeaders);
assertEquals(headers.get("A"), inner.getRequest().getHeaders().get("A"));
-
}
}
diff --git a/src/test/java/com/smartystreets/api/XForwardedForTest.java b/src/test/java/com/smartystreets/api/XForwardedForTest.java
new file mode 100644
index 0000000..d8fc715
--- /dev/null
+++ b/src/test/java/com/smartystreets/api/XForwardedForTest.java
@@ -0,0 +1,29 @@
+package com.smartystreets.api;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+
+import com.smartystreets.api.mocks.RequestCapturingSender;
+
+public class XForwardedForTest {
+ @Test
+ public void testAllCustomHeadersAreAddedToTheRequest() throws Exception {
+ HashMap headers = new HashMap<>();
+ headers.put("X-Forwarded-For", "ip");
+ RequestCapturingSender inner = new RequestCapturingSender();
+ CustomHeaderSender sender = new CustomHeaderSender(headers, inner);
+ Request request = new Request();
+
+ sender.send(request);
+
+ Map requestHeaders = inner.getRequest().getHeaders();
+ assertNotNull("Headers here.", requestHeaders);
+ assertEquals(headers.get("X-Forwarded-For"), inner.getRequest().getHeaders().get("X-Forwarded-For"));
+
+ }
+}