Skip to content
This repository was archived by the owner on Jan 31, 2022. It is now read-only.

Commit 9fcff0a

Browse files
authored
Merge pull request #387 from algolia/fix/large-api-key
Fix the case when header is bigger than 8KB
2 parents 30200c5 + 18a2bcb commit 9fcff0a

File tree

3 files changed

+48
-4
lines changed

3 files changed

+48
-4
lines changed

algoliasearch/src/main/java/com/algolia/search/saas/AbstractClient.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ private static class HostStatus {
107107
/** This library's version. */
108108
private final static String version = "3.12.0";
109109

110+
/** Maximum size for an API key to be sent in the HTTP headers. Bigger keys will go inside the body. */
111+
private final static int MAX_API_KEY_LENGTH = 500;
112+
110113
// ----------------------------------------------------------------------
111114
// Fields
112115
// ----------------------------------------------------------------------
@@ -545,7 +548,18 @@ private byte[] _requestRaw(Method m, String url, String json, List<String> hosts
545548

546549
// set auth headers
547550
hostConnection.setRequestProperty("X-Algolia-Application-Id", this.applicationID);
548-
hostConnection.setRequestProperty("X-Algolia-API-Key", this.apiKey);
551+
// If API key is too big, send it in the request's body (if applicable).
552+
if (this.apiKey != null && this.apiKey.length() > MAX_API_KEY_LENGTH && json != null) {
553+
try {
554+
final JSONObject body = new JSONObject(json);
555+
body.put("apiKey", this.apiKey);
556+
json = body.toString();
557+
} catch (JSONException e) {
558+
throw new AlgoliaException("Failed to patch JSON body");
559+
}
560+
} else {
561+
hostConnection.setRequestProperty("X-Algolia-API-Key", this.apiKey);
562+
}
549563
for (Map.Entry<String, String> entry : this.headers.entrySet()) {
550564
hostConnection.setRequestProperty(entry.getKey(), entry.getValue());
551565
}

algoliasearch/src/test/java/com/algolia/search/saas/Helpers.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
package com.algolia.search.saas;
2525

2626
import android.support.annotation.NonNull;
27+
import java.util.Arrays;
2728

2829
public class Helpers {
2930
public static String app_id = "%ALGOLIA_APPLICATION_ID%";
@@ -34,6 +35,13 @@ public class Helpers {
3435

3536
public static int wait = 30;
3637

38+
static String getLongApiKey() {
39+
int n = 65000;
40+
char[] chars = new char[n];
41+
Arrays.fill(chars, 'c');
42+
return new String(chars);
43+
}
44+
3745
static String safeIndexName(String name) {
3846
if (job_number.matches("\\d+\\.\\d+")) {
3947
name = String.format("%s_travis-%s", name, job_number);

algoliasearch/src/test/java/com/algolia/search/saas/IndexTest.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747

4848
import static org.junit.Assert.assertEquals;
4949
import static org.junit.Assert.assertFalse;
50+
import static org.junit.Assert.assertNotEquals;
5051
import static org.junit.Assert.assertNotNull;
5152
import static org.junit.Assert.assertNull;
5253
import static org.junit.Assert.assertTrue;
@@ -74,7 +75,9 @@ public class IndexTest extends RobolectricTestCase {
7475
private static boolean didInitIndices = false;
7576

7677
Client client;
78+
Client clientWithLongApiKey;
7779
Index index;
80+
Index indexWithLongApiKey;
7881
String indexName;
7982

8083
List<JSONObject> objects;
@@ -84,9 +87,11 @@ public class IndexTest extends RobolectricTestCase {
8487
public void setUp() throws Exception {
8588
super.setUp();
8689
client = new Client(Helpers.app_id, Helpers.api_key);
90+
clientWithLongApiKey = new Client(Helpers.app_id, Helpers.getLongApiKey());
8791
// WARNING: Robolectric cannot work with custom executors in `AsyncTask`, so we substitute the client's
8892
// executor with a Robolectric-compliant one.
8993
Whitebox.setInternalState(client, "searchExecutorService", new RoboExecutorService());
94+
Whitebox.setInternalState(clientWithLongApiKey, "searchExecutorService", new RoboExecutorService());
9095

9196
if (!didInitIndices) {
9297
Index originalIndex = client.getIndex(originalIndexName);
@@ -119,6 +124,7 @@ public void setUp() throws Exception {
119124
objects = new ArrayList<>(originalObjects);
120125
indexName = originalIndexName + countIndices++;
121126
index = client.getIndex(indexName);
127+
indexWithLongApiKey = clientWithLongApiKey.getIndex("some_index_name");
122128
}
123129

124130
@Override
@@ -141,7 +147,8 @@ public void searchAsync(int waitTimeoutSeconds) throws Exception {
141147
final long begin = System.nanoTime();
142148
// Search with query.
143149
index.searchAsync(new Query("Francisco"), new AssertCompletionHandler() {
144-
@Override public void doRequestCompleted(JSONObject content, AlgoliaException error) {
150+
@Override
151+
public void doRequestCompleted(JSONObject content, AlgoliaException error) {
145152
if (error == null) {
146153
assertEquals(1, content.optInt("nbHits"));
147154
} else {
@@ -155,6 +162,22 @@ public void searchAsync(int waitTimeoutSeconds) throws Exception {
155162
assertTrue("The test took longer than given timeout (" + elapsedMillis + " > " + waitTimeoutMillis + ").", elapsedMillis <= waitTimeoutMillis);
156163
}
157164

165+
@Test
166+
public void searchAsyncWithVeryLongApiKey() throws Exception {
167+
final long begin = System.nanoTime();
168+
// Search with query.
169+
indexWithLongApiKey.searchAsync(new Query("Francisco"), new AssertCompletionHandler() {
170+
@Override
171+
public void doRequestCompleted(JSONObject content, AlgoliaException error) {
172+
assertNotEquals(494, error.getStatusCode());
173+
}
174+
});
175+
176+
final long elapsedMillis = (System.nanoTime() - begin) / 1000000;
177+
final int waitTimeoutMillis = Helpers.wait * 1000;
178+
assertTrue("The test took longer than given timeout (" + elapsedMillis + " > " + waitTimeoutMillis + ").", elapsedMillis <= waitTimeoutMillis);
179+
}
180+
158181
@Test
159182
public void searchDisjunctiveFacetingAsync() throws Exception {
160183
// Set index settings.
@@ -508,8 +531,7 @@ public void DNSTimeout() throws Exception {
508531
// Expect failed search after timeout
509532
final long startTime = System.nanoTime();
510533
index.searchAsync(new Query(), new AssertCompletionHandler() {
511-
@Override
512-
public void doRequestCompleted(JSONObject content, AlgoliaException error) {
534+
@Override public void doRequestCompleted(JSONObject content, AlgoliaException error) {
513535
if (error != null) {
514536
final long duration = (System.nanoTime() - startTime) / 1000000;
515537
assertTrue("We should hit 4 times the timeout before failing, but test took only " + duration + " ms.", duration > timeout * 4);

0 commit comments

Comments
 (0)