Skip to content

Add setAppInfo() for passing custom application information in headers #449

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,16 @@ Please take care to set conservative read timeouts. Some API requests can take
some time, and a short timeout increases the likelihood of a problem within our
servers.

### Writing a plugin

If you're writing a plugin that uses the library, we'd appreciate it if you
identified using `Stripe.setAppInfo()`:

Stripe.setAppInfo("MyAwesomePlugin", "1.2.34", "https://myawesomeplugin.info");

This information is passed along when the library makes calls to the Stripe
API.

## Testing

You must have Gradle installed. To run the tests:
Expand Down
27 changes: 27 additions & 0 deletions src/main/java/com/stripe/Stripe.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import java.net.PasswordAuthentication;
import java.net.Proxy;

import java.util.HashMap;
import java.util.Map;

public abstract class Stripe {
private final static int DEFAULT_CONNECT_TIMEOUT = 30 * 1000;
private final static int DEFAULT_READ_TIMEOUT = 80 * 1000;
Expand All @@ -27,6 +30,8 @@ public abstract class Stripe {
private static volatile Proxy connectionProxy = null;
private static volatile PasswordAuthentication proxyCredential = null;

private static volatile Map<String, String> appInfo = null;


/**
* (FOR TESTING ONLY) If you'd like your API requests to hit your own
Expand Down Expand Up @@ -116,4 +121,26 @@ public static void setProxyCredential(final PasswordAuthentication auth) {
public static PasswordAuthentication getProxyCredential() {
return proxyCredential;
}

public static void setAppInfo(String name) {
setAppInfo(name, null, null);
}

public static void setAppInfo(String name, String version) {
setAppInfo(name, version, null);
}

public static void setAppInfo(String name, String version, String url) {
if (appInfo == null) {
appInfo = new HashMap<String, String>();
}

appInfo.put("name", name);
appInfo.put("version", version);
appInfo.put("url", url);
}

public static Map<String, String> getAppInfo() {
return appInfo;
}
}
23 changes: 21 additions & 2 deletions src/main/java/com/stripe/net/LiveStripeResponseGetter.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,29 @@ private static String urlEncodePair(String k, String v)
return String.format("%s=%s", APIResource.urlEncode(k), APIResource.urlEncode(v));
}

static String formatAppInfo(Map<String, String> info) {
String str = info.get("name");
if (info.get("version") != null) {
str += String.format("/%s", info.get("version"));
}
if (info.get("url") != null) {
str += String.format(" (%s)", info.get("url"));
}
return str;
}

static Map<String, String> getHeaders(RequestOptions options) {
Map<String, String> headers = new HashMap<String, String>();

String userAgent = String.format("Stripe/v1 JavaBindings/%s", Stripe.VERSION);
if (Stripe.getAppInfo() != null) {
userAgent += " " + formatAppInfo(Stripe.getAppInfo());
}
headers.put("User-Agent", userAgent);

String apiVersion = options.getStripeVersion();
headers.put("Accept-Charset", APIResource.CHARSET);
headers.put("Accept", "application/json");
headers.put("User-Agent",
String.format("Stripe/v1 JavaBindings/%s", Stripe.VERSION));

headers.put("Authorization", String.format("Bearer %s", options.getApiKey()));

Expand All @@ -110,6 +126,9 @@ static Map<String, String> getHeaders(RequestOptions options) {
propertyMap.put("bindings.version", Stripe.VERSION);
propertyMap.put("lang", "Java");
propertyMap.put("publisher", "Stripe");
if (Stripe.getAppInfo() != null) {
propertyMap.put("application", APIResource.GSON.toJson(Stripe.getAppInfo()));
}
headers.put("X-Stripe-Client-User-Agent", APIResource.GSON.toJson(propertyMap));
if (apiVersion != null) {
headers.put("Stripe-Version", apiVersion);
Expand Down
30 changes: 30 additions & 0 deletions src/test/java/com/stripe/net/LiveStripeResponseGetterTest.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package com.stripe.net;

import com.stripe.Stripe;
import com.stripe.exception.StripeException;
import com.stripe.net.LiveStripeResponseGetter;
import com.stripe.net.RequestOptions;
import com.stripe.net.RequestOptions.RequestOptionsBuilder;

import com.google.gson.Gson;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
Expand All @@ -14,6 +19,7 @@
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

public class LiveStripeResponseGetterTest {
LiveStripeResponseGetter srg;
Expand Down Expand Up @@ -126,4 +132,28 @@ public void testCorrectAdditionalOwners() throws StripeException, UnsupportedEnc

assertEquals(encode("legal_entity[additional_owners][0][first_name]=Stripe"), LiveStripeResponseGetter.createQuery(params));
}

@Test
public void testAppInfo() {
RequestOptions options = (new RequestOptionsBuilder()).setApiKey("sk_foobar").build();

Stripe.setAppInfo("MyAwesomePlugin", "1.2.34", "https://myawesomeplugin.info");

Map<String, String> headers = srg.getHeaders(options);

String expectedUserAgent = String.format(
"Stripe/v1 JavaBindings/%s MyAwesomePlugin/1.2.34 (https://myawesomeplugin.info)",
Stripe.VERSION);
assertEquals(expectedUserAgent, headers.get("User-Agent"));

Gson gson = new Gson();

Map<String, String> uaMap = gson.fromJson(headers.get("X-Stripe-Client-User-Agent"), Map.class);
assertNotNull(uaMap.get("application"));

Map<String, String> appMap = gson.fromJson(uaMap.get("application"), Map.class);
assertEquals("MyAwesomePlugin", appMap.get("name"));
assertEquals("1.2.34", appMap.get("version"));
assertEquals("https://myawesomeplugin.info", appMap.get("url"));
}
}