[Inference API] Prevent trailing slashes from being included in URLs#141692
[Inference API] Prevent trailing slashes from being included in URLs#141692DonalEvans merged 4 commits intoelastic:mainfrom
Conversation
Update ElasticInferenceService and AzureAiStudio model classes to prevent trailing slashes in the base URL causing errors when sending requests
|
Pinging @elastic/search-inference-team (Team:Search - Inference) |
| } | ||
|
|
||
| return new URI(this.target + COMPLETIONS_URI_PATH); | ||
| return new URIBuilder(this.target).setPath(COMPLETIONS_URI_PATH).build(); |
There was a problem hiding this comment.
Ugh, after looking at how azure does this I think we might need to do more work here. For example I'm able to build an azure deployment with a path like this:
https://ai753146444935.services.ai.azure.com/models
My understanding is that setPath will overwrite any path that was there, which means we'd lose the models portion.
Apache http 5.x luckily has appendPath which is exactly what we need. Sadly we're still on 4.x 😢
I think we'l'l need something like this:
var a = new URIBuilder(this.target)
a.getPath()
Then split it and combine with COMPLETIONS_URI_PATH.
I could be wrong about the behavior though. Let's add a test where the this.target has a path already on it.
There was a problem hiding this comment.
At this point, until we can upgrade to Apache http 5.x and use appendPath(), would it be simpler to just check for trailing slashes in the target and strip them out before concatenating the path constant as a String? It's not pretty, but it's simpler than doing all of the splitting and combining in that static helper method.
| * @param url | ||
| * @return | ||
| */ | ||
| public static String stripTrailingSlash(String url) { |
There was a problem hiding this comment.
I agree in general that it'd be much easier to use a library. The problem is that we should probably handle multiple slashes at the end (probably overkill but might as well).
Since we can't easily do that this is what gemini generated for me 😄
import java.net.URI;
import java.net.URISyntaxException;
import java.util.regex.Pattern;
public class UriUtils {
// Compiling these once saves significant CPU cycles in high-throughput apps
private static final Pattern TRAILING_SLASHES = Pattern.compile("/+$");
private static final Pattern LEADING_SLASHES = Pattern.compile("^/+");
/**
* Combines a base URL with a sub-path, collapsing multiple slashes at the join point.
* * @param baseUrl The base (e.g., "http://google.com//")
* @param extraPath The segment to append (e.g., "///hello")
* @return A URI with exactly one slash at the junction: "http://google.com/hello"
*/
public static URI combineUri(String baseUrl, String extraPath) {
if (baseUrl == null) {
throw new IllegalArgumentException("baseUrl cannot be null");
}
try {
URI baseUri = new URI(baseUrl);
// Extract the existing path from the base URI
String basePath = (baseUri.getPath() == null) ? "" : baseUri.getPath();
// 1. Strip trailing slashes from the existing base path
String cleanBase = TRAILING_SLASHES.matcher(basePath).replaceAll("");
// 2. Strip leading slashes from the new segment
String cleanExtra = (extraPath == null) ? "" : LEADING_SLASHES.matcher(extraPath).replaceAll("");
// 3. Join with exactly one separator
String joinedPath = cleanBase + "/" + cleanExtra;
// Reconstruct the URI using the multi-arg constructor.
// This ensures the path is handled correctly without double-escaping.
return new URI(
baseUri.getScheme(),
baseUri.getAuthority(),
joinedPath,
baseUri.getQuery(),
baseUri.getFragment()
);
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Failed to construct URI: " + e.getMessage(), e);
}
}
}
How do you feel about incorporating something like that? We can probably use the UriBuilder instead of
return new URI(
baseUri.getScheme(),
baseUri.getAuthority(),
joinedPath,
baseUri.getQuery(),
baseUri.getFragment()
);
But URI is probably fine too.
There was a problem hiding this comment.
I think that there's a limit to how much sanitization of user input we should do here. A trailing slash at the end of a URL is a reasonable thing to expect and deal with, but multiple trailing slashes is just an incorrect input. If a user passed a URL like https://ai753146444935.services.ai.azure.com//models (a double slash in the path instead of at the end) we'd still return an error even with the more complex method described in your comment, so I don't think handling double slashes is something we should try to do. We just want to make sure that if a user provides a valid URL, we don't muck it up by accidentally adding one too many slashes.
💔 Backport failed
You can use sqren/backport to manually backport by running |
…lastic#141692) Update ElasticInferenceService and AzureAiStudio model classes to prevent trailing slashes in the base URL causing errors when sending requests (cherry picked from commit 8db18bb) # Conflicts: # x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/elastic/densetextembeddings/ElasticInferenceServiceDenseTextEmbeddingsModel.java # x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/elastic/completion/ElasticInferenceServiceCompletionModelTests.java # x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/elastic/denseembeddings/ElasticInferenceServiceDenseEmbeddingsModelTests.java
…lastic#141692) Update ElasticInferenceService and AzureAiStudio model classes to prevent trailing slashes in the base URL causing errors when sending requests (cherry picked from commit 8db18bb) # Conflicts: # x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/elastic/ElasticInferenceServiceModel.java # x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/elastic/densetextembeddings/ElasticInferenceServiceDenseTextEmbeddingsModel.java # x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/elastic/completion/ElasticInferenceServiceCompletionModelTests.java # x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/elastic/denseembeddings/ElasticInferenceServiceDenseEmbeddingsModelTests.java
💔 Some backports could not be created
Manual backportTo create the backport manually run: Questions ?Please refer to the Backport tool documentation |
Update ElasticInferenceService and AzureAiStudio model classes to prevent trailing slashes in the base URL causing errors when sending requests