Skip to content

Commit 9bb1fba

Browse files
committed
Merge pull request #139 from gcurtis/non_global_proxy
Add ability to set non-global proxy
2 parents b51f37f + 142c574 commit 9bb1fba

File tree

3 files changed

+169
-1
lines changed

3 files changed

+169
-1
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package com.box.sdk;
2+
3+
import java.io.ByteArrayOutputStream;
4+
5+
/**
6+
* Contains a method for performing base64 encoding.
7+
*
8+
* <p>This class is included so that we don't need to add a dependency on Apache Commons for base64 encoding.</p>
9+
*
10+
* <p>The code in this class was mostly taken from https://gist.github.com/EmilHernvall/953733#file-base64-java</p>
11+
*/
12+
final class Base64 {
13+
14+
private Base64() { }
15+
16+
static String encode(byte[] data) {
17+
char[] tbl = {
18+
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
19+
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
20+
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
21+
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' };
22+
23+
StringBuilder buffer = new StringBuilder();
24+
int pad = 0;
25+
for (int i = 0; i < data.length; i += 3) {
26+
27+
int b = ((data[i] & 0xFF) << 16) & 0xFFFFFF;
28+
if (i + 1 < data.length) {
29+
b |= (data[i + 1] & 0xFF) << 8;
30+
} else {
31+
pad++;
32+
}
33+
if (i + 2 < data.length) {
34+
b |= (data[i + 2] & 0xFF);
35+
} else {
36+
pad++;
37+
}
38+
39+
for (int j = 0; j < 4 - pad; j++) {
40+
int c = (b & 0xFC0000) >> 18;
41+
buffer.append(tbl[c]);
42+
b <<= 6;
43+
}
44+
}
45+
for (int j = 0; j < pad; j++) {
46+
buffer.append("=");
47+
}
48+
49+
return buffer.toString();
50+
}
51+
52+
public static byte[] decode(String data) {
53+
int[] tbl = {
54+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
55+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
56+
-1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54,
57+
55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2,
58+
3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
59+
20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30,
60+
31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
61+
48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
62+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
63+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
64+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
65+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
66+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
67+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
68+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
69+
byte[] bytes = data.getBytes();
70+
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
71+
for (int i = 0; i < bytes.length;) {
72+
int b = 0;
73+
if (tbl[bytes[i]] != -1) {
74+
b = (tbl[bytes[i]] & 0xFF) << 18;
75+
} else {
76+
i++;
77+
continue;
78+
}
79+
80+
int num = 0;
81+
if (i + 1 < bytes.length && tbl[bytes[i + 1]] != -1) {
82+
b = b | ((tbl[bytes[i + 1]] & 0xFF) << 12);
83+
num++;
84+
}
85+
if (i + 2 < bytes.length && tbl[bytes[i + 2]] != -1) {
86+
b = b | ((tbl[bytes[i + 2]] & 0xFF) << 6);
87+
num++;
88+
}
89+
if (i + 3 < bytes.length && tbl[bytes[i + 3]] != -1) {
90+
b = b | (tbl[bytes[i + 3]] & 0xFF);
91+
num++;
92+
}
93+
94+
while (num > 0) {
95+
int c = (b & 0xFF0000) >> 16;
96+
buffer.write((char) c);
97+
b <<= 8;
98+
num--;
99+
}
100+
i += 4;
101+
}
102+
return buffer.toByteArray();
103+
}
104+
}

src/main/java/com/box/sdk/BoxAPIConnection.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.box.sdk;
22

33
import java.net.MalformedURLException;
4+
import java.net.Proxy;
45
import java.net.URL;
56
import java.util.ArrayList;
67
import java.util.List;
@@ -41,6 +42,10 @@ public class BoxAPIConnection {
4142
private volatile long lastRefresh;
4243
private volatile long expires;
4344

45+
private Proxy proxy;
46+
private String proxyUsername;
47+
private String proxyPassword;
48+
4449
private String userAgent;
4550
private String accessToken;
4651
private String refreshToken;
@@ -330,6 +335,54 @@ public void setMaxRequestAttempts(int attempts) {
330335
this.maxRequestAttempts = attempts;
331336
}
332337

338+
/**
339+
* Gets the proxy value to use for API calls to Box.
340+
* @return the current proxy.
341+
*/
342+
public Proxy getProxy() {
343+
return this.proxy;
344+
}
345+
346+
/**
347+
* Sets the proxy to use for API calls to Box.
348+
* @param proxy the proxy to use for API calls to Box.
349+
*/
350+
public void setProxy(Proxy proxy) {
351+
this.proxy = proxy;
352+
}
353+
354+
/**
355+
* Gets the username to use for a proxy that requires basic auth.
356+
* @return the username to use for a proxy that requires basic auth.
357+
*/
358+
public String getProxyUsername() {
359+
return this.proxyUsername;
360+
}
361+
362+
/**
363+
* Sets the username to use for a proxy that requires basic auth.
364+
* @param proxyUsername the username to use for a proxy that requires basic auth.
365+
*/
366+
public void setProxyUsername(String proxyUsername) {
367+
this.proxyUsername = proxyUsername;
368+
}
369+
370+
/**
371+
* Gets the password to use for a proxy that requires basic auth.
372+
* @return the password to use for a proxy that requires basic auth.
373+
*/
374+
public String getProxyPassword() {
375+
return this.proxyPassword;
376+
}
377+
378+
/**
379+
* Sets the password to use for a proxy that requires basic auth.
380+
* @param proxyPassword the password to use for a proxy that requires basic auth.
381+
*/
382+
public void setProxyPassword(String proxyPassword) {
383+
this.proxyPassword = proxyPassword;
384+
}
385+
333386
/**
334387
* Determines if this connection's access token can be refreshed. An access token cannot be refreshed if a refresh
335388
* token was never set.

src/main/java/com/box/sdk/BoxAPIRequest.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,13 @@ private BoxAPIResponse trySend(ProgressListener listener) {
349349
if (this.api != null) {
350350
connection.addRequestProperty("Authorization", "Bearer " + this.api.lockAccessToken());
351351
connection.setRequestProperty("User-Agent", this.api.getUserAgent());
352+
if (this.api.getProxy() != null) {
353+
if (this.api.getProxyUsername() != null && this.api.getProxyPassword() != null) {
354+
String usernameAndPassword = this.api.getProxyUsername() + ":" + this.api.getProxyPassword();
355+
String encoded = new String(Base64.encode(usernameAndPassword.getBytes()));
356+
connection.addRequestProperty("Proxy-Authorization", "Basic " + encoded);
357+
}
358+
}
352359

353360
if (this.api instanceof SharedLinkAPIConnection) {
354361
SharedLinkAPIConnection sharedItemAPI = (SharedLinkAPIConnection) this.api;
@@ -447,7 +454,11 @@ private HttpURLConnection createConnection() {
447454
HttpURLConnection connection = null;
448455

449456
try {
450-
connection = (HttpURLConnection) this.url.openConnection();
457+
if (this.api == null || this.api.getProxy() == null) {
458+
connection = (HttpURLConnection) this.url.openConnection();
459+
} else {
460+
connection = (HttpURLConnection) this.url.openConnection(this.api.getProxy());
461+
}
451462
} catch (IOException e) {
452463
throw new BoxAPIException("Couldn't connect to the Box API due to a network error.", e);
453464
}

0 commit comments

Comments
 (0)