Skip to content

Commit 2cd6549

Browse files
author
Karl Rieb
committed
Fix bug where V2 client does not send user locale information to server.
Fixes T97615
1 parent e10d8ad commit 2cd6549

5 files changed

Lines changed: 117 additions & 18 deletions

File tree

ChangeLog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- Response/request objects should no longer always be kept in primary dex.
88
- Add partial download support through range requests.
99
- Fix deserialization bug when handling new server responses that were previously void.
10+
- Fix bug where user locale is ignored for APIv2 requests.
1011

1112
---------------------------------------------
1213
2.0.3 (2016-05-07)

src/main/java/com/dropbox/core/DbxRequestConfig.java

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class DbxRequestConfig {
1717
private final HttpRequestor httpRequestor;
1818
private final int maxRetries;
1919

20-
private DbxRequestConfig(String clientIdentifier, /*@Nullable*/String userLocale, HttpRequestor httpRequestor, int maxRetries) {
20+
private DbxRequestConfig(String clientIdentifier, /*@Nullable*/ String userLocale, HttpRequestor httpRequestor, int maxRetries) {
2121
if (clientIdentifier == null) throw new NullPointerException("clientIdentifier");
2222
if (httpRequestor == null) throw new NullPointerException("httpRequestor");
2323
if (maxRetries < 0) throw new IllegalArgumentException("maxRetries");
@@ -28,11 +28,28 @@ private DbxRequestConfig(String clientIdentifier, /*@Nullable*/String userLocale
2828
this.maxRetries = maxRetries;
2929
}
3030

31-
public DbxRequestConfig(String clientIdentifier, String userLocale) {
31+
/**
32+
* Creates a new configuration.
33+
*
34+
* @param clientIdentifier client identifier typically in the form "Name/Version" to be used in
35+
* the User-Agent header (see {@link #getClientIdentifier}).
36+
* @param userLocale IETF BCP 47 language tag of locale to use for user-visible text in responses, or
37+
* {@code null} to use the user's Dropbox locale preference.
38+
*/
39+
public DbxRequestConfig(String clientIdentifier, /*@Nullable*/ String userLocale) {
3240
this(clientIdentifier, userLocale, StandardHttpRequestor.INSTANCE);
3341
}
3442

35-
public DbxRequestConfig(String clientIdentifier, /*@Nullable*/String userLocale, HttpRequestor httpRequestor) {
43+
/**
44+
* Creates a new configuration.
45+
*
46+
* @param clientIdentifier client identifier typically in the form "Name/Version" to be used in
47+
* the User-Agent header (see {@link #getClientIdentifier}).
48+
* @param userLocale IETF BCP 47 language tag of locale to use for user-visible text in responses, or
49+
* {@code null} to use the user's Dropbox locale preference.
50+
* @param httpRequestor HTTP client to use for issuing requests.
51+
*/
52+
public DbxRequestConfig(String clientIdentifier, /*@Nullable*/ String userLocale, HttpRequestor httpRequestor) {
3653
this(clientIdentifier, userLocale, httpRequestor, 0);
3754
}
3855

@@ -67,17 +84,15 @@ public String getClientIdentifier() {
6784
}
6885

6986
/**
70-
* Returns the locale of the user of your app. This is used by the Dropbox server to localize
71-
* user-visible strings returned by API calls.
87+
* Returns the locale of the user of your app as an IETF BCP 47 language tag. This is used by
88+
* the Dropbox server to localize user-visible strings returned by API calls.
7289
*
73-
* <p>
74-
* If the value is {@code null} or some locale that Dropbox doesn't support, the localized
75-
* strings will be in English.
76-
* </p>
90+
* <p> If the value is {@code null} or some locale that Dropbox doesn't support, the strings
91+
* will be localized based on the user's Dropbox locale preference.
7792
*
7893
* <p> Defaults to {@code null}.
7994
*
80-
* @return locale of app user, or {@code null} if not localized.
95+
* @return locale of app user, or {@code null} to use user's Dropbox locale settings.
8196
*/
8297
public String getUserLocale() {
8398
return userLocale;
@@ -190,26 +205,45 @@ private Builder(String clientIdentifier) {
190205
* Set the locale of the app user. User-visible messages returned by the Dropbox servers
191206
* will be localized to this locale.
192207
*
193-
* <p> Defaults to {@code null}, which disables localization (messages will be in English).
208+
* <p> Defaults to {@code null}, which means strings will be localized according to the
209+
* user's Dropbox locale preference.
210+
*
211+
* @param userLocale locale of app user as an IETF BCP 47 language tag, or {@code null} to
212+
* use the user's Dropbox locale settings.
194213
*
195-
* @param userLocale Locale of app user, or {@code null} to disable localization
196214
* @return this builder
197215
*/
198216
public Builder withUserLocale(/*@Nullable*/ String userLocale) {
199217
this.userLocale = userLocale;
200218
return this;
201219
}
202220

221+
/**
222+
* Set the locale of user-visible messages returned by the Dropbox servers to the user's
223+
* Dropbox locale.
224+
*
225+
* <p> User-visible strings will be localized according to the user's Dropbox locale
226+
* preference.
227+
*
228+
* @return this builder
229+
*/
230+
public Builder withUserLocaleFromPreferences() {
231+
this.userLocale = null;
232+
return this;
233+
}
234+
203235
/**
204236
* Set the locale of the app user. User-visible messages returned by the Dropbox servers
205237
* will be localized to this locale.
206238
*
207-
* <p> Defaults to {@code null}, which disables localization (messages will be in English).
239+
* <p> Defaults to {@code null}, which means strings will be localized according to the
240+
* user's Dropbox locale preference.
241+
*
242+
* @param userLocale Locale of app user, or {@code null} to use user's Dropbox locale settings.
208243
*
209-
* @param userLocale Locale of app user, or {@code null} to disable localization
210244
* @return this builder
211245
*/
212-
public Builder withUserLocale(/*@Nullable*/ Locale userLocale) {
246+
public Builder withUserLocaleFrom(/*@Nullable*/ Locale userLocale) { // not named withUserLocale because of ambiguous calls when passing 'null'
213247
this.userLocale = userLocale == null ? null : userLocale.toLanguageTag();
214248
return this;
215249
}

src/main/java/com/dropbox/core/DbxRequestUtil.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,16 @@ public static List<HttpRequestor.Header> addUserAgentHeader(
119119
return headers;
120120
}
121121

122+
public static List<HttpRequestor.Header> addUserLocaleHeader(/*@Nullable*/List<HttpRequestor.Header> headers, DbxRequestConfig requestConfig) {
123+
if (requestConfig.getUserLocale() == null) {
124+
return headers;
125+
}
126+
127+
if (headers == null) headers = new ArrayList<HttpRequestor.Header>();
128+
headers.add(new HttpRequestor.Header("Dropbox-API-User-Locale", requestConfig.getUserLocale()));
129+
return headers;
130+
}
131+
122132
public static HttpRequestor.Header buildUserAgentHeader(DbxRequestConfig requestConfig, String sdkUserAgentIdentifier) {
123133
return new HttpRequestor.Header("User-Agent", requestConfig.getClientIdentifier() + " " + sdkUserAgentIdentifier + "/" + DbxSdkVersion.Version);
124134
}
@@ -203,6 +213,7 @@ public static HttpRequestor.Response startPostRaw(DbxRequestConfig requestConfig
203213

204214
headers = copyHeaders(headers);
205215
headers = addUserAgentHeader(headers, requestConfig, sdkUserAgentIdentifier);
216+
headers = addUserLocaleHeader(headers, requestConfig);
206217
headers.add(new HttpRequestor.Header("Content-Length", Integer.toString(body.length)));
207218

208219
try {

src/test/java/com/dropbox/core/ITUtil.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public static DbxRequestConfig.Builder newRequestConfig() {
4141
DbxRequestConfig.Builder builder = DbxRequestConfig.newBuilder("sdk-test")
4242
// enable auto-retry to avoid flakiness
4343
.withAutoRetryEnabled(MAX_RETRIES)
44-
.withUserLocale(Locale.US);
44+
.withUserLocaleFrom(Locale.US);
4545

4646
String okHttp = System.getProperty("com.dropbox.test.okHttp");
4747
if (okHttp != null && !okHttp.equals("true") && !okHttp.equals("false")) {
@@ -92,18 +92,34 @@ public static DbxAuthInfo getAuth() {
9292
}
9393

9494
public static DbxClientV1 newClientV1() {
95+
return newClientV1(newRequestConfig());
96+
}
97+
98+
public static DbxClientV1 newClientV1(DbxRequestConfig.Builder config) {
99+
return newClientV1(config.build());
100+
}
101+
102+
public static DbxClientV1 newClientV1(DbxRequestConfig config) {
95103
DbxAuthInfo auth = getAuth();
96104
return new DbxClientV1(
97-
newRequestConfig().build(),
105+
config,
98106
auth.getAccessToken(),
99107
auth.getHost()
100108
);
101109
}
102110

103111
public static DbxClientV2 newClientV2() {
112+
return newClientV2(newRequestConfig());
113+
}
114+
115+
public static DbxClientV2 newClientV2(DbxRequestConfig.Builder config) {
116+
return newClientV2(config.build());
117+
}
118+
119+
public static DbxClientV2 newClientV2(DbxRequestConfig config) {
104120
DbxAuthInfo auth = getAuth();
105121
return new DbxClientV2(
106-
newRequestConfig().build(),
122+
config,
107123
auth.getAccessToken(),
108124
auth.getHost()
109125
);

src/test/java/com/dropbox/core/v2/DbxClientV2IT.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
import java.io.ByteArrayInputStream;
66
import java.io.ByteArrayOutputStream;
77
import java.util.Date;
8+
import java.util.Locale;
89

910
import org.testng.annotations.Test;
1011

1112
import com.dropbox.core.BadRequestException;
13+
import com.dropbox.core.DbxApiException;
1214
import com.dropbox.core.DbxDownloader;
1315
import com.dropbox.core.ITUtil;
1416
import com.dropbox.core.v2.files.FileMetadata;
@@ -202,6 +204,24 @@ public void testError400() throws Exception {
202204
}
203205
}
204206

207+
@Test(enabled=false) // re-enable after T90620 is fixed
208+
public void testUserLocale() throws Exception {
209+
assertUserMessageLocale(Locale.ENGLISH); // en
210+
assertUserMessageLocale(Locale.UK); // en-UK
211+
assertUserMessageLocale(Locale.FRENCH); // fr
212+
assertUserMessageLocale(Locale.FRANCE); // fr-FR
213+
214+
// Use user's Dropbox locale preference
215+
DbxClientV2 client = ITUtil.newClientV2(ITUtil.newRequestConfig().withUserLocaleFromPreferences());
216+
try {
217+
client.sharing().getFolderMetadata("-1");
218+
} catch (DbxApiException ex) {
219+
assertNotNull(ex.getUserMessage());
220+
assertNotNull(ex.getUserMessage().getLocale());
221+
assertNotEquals(ex.getUserMessage().getLocale(), ""); // make sure something is specified
222+
}
223+
}
224+
205225
private static void assertRangeDownload(DbxClientV2 client, String path, byte [] contents, int start, Integer length) throws Exception {
206226
ByteArrayOutputStream out = new ByteArrayOutputStream(contents.length);
207227
byte [] expected;
@@ -222,4 +242,21 @@ private static void assertRangeDownload(DbxClientV2 client, String path, byte []
222242

223243
assertEquals(actual, expected);
224244
}
245+
246+
private static void assertUserMessageLocale(Locale locale) throws Exception {
247+
DbxClientV2 client = ITUtil.newClientV2(ITUtil.newRequestConfig().withUserLocaleFrom(locale));
248+
try {
249+
client.sharing().getFolderMetadata("-1");
250+
} catch (DbxApiException ex) {
251+
assertNotNull(ex.getUserMessage());
252+
System.out.printf("%s: %s\n", locale.toLanguageTag(), ex.getUserMessage());
253+
assertNotNull(ex.getUserMessage().getLocale());
254+
if (ex.getUserMessage().getLocale().contains("-")) {
255+
assertEquals(ex.getUserMessage().getLocale(), locale.toLanguageTag());
256+
} else {
257+
// omit the country code
258+
assertEquals(ex.getUserMessage().getLocale(), locale.getLanguage());
259+
}
260+
}
261+
}
225262
}

0 commit comments

Comments
 (0)