Skip to content
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

Low Level Rest Client shows successful response bad request with empty response #28923

Closed
kevcodez opened this issue Mar 7, 2018 · 9 comments
Labels
:Clients/Java Low Level REST Client Minimal dependencies Java Client for Elasticsearch feedback_needed

Comments

@kevcodez
Copy link

kevcodez commented Mar 7, 2018

Using the AWS Elasticsearch Service with the latest possible version (6.0.1) deployed.

When doing basic requests like an index check using HEAD /<indexname> I am getting a response with status code 400 and an empty response body. The request works fine with a basic HTTP Client.

I was unable to produce this locally. This seems to be an issue in the low level REST Client.

Elasticsearch version 6.0.1

@Bean
open fun elasticsearchLowClient(): RestClient {
    return RestClient.builder(
        HttpHost(elasticsearchHost, elasticsearchPort, elasticsearchProtocol)
    ).build()
}
val indexExistsResponse = elasticsearchLowClient.performRequest("HEAD", index, mapOf()) // <- 400 empty response

if (indexExistsResponse.statusLine.statusCode == 404) {
    elasticsearchLowClient.performRequest(
            "PUT", index, hashMapOf(),
            StringEntity("...valid", ContentType.APPLICATION_JSON)
    )

}
@kevcodez kevcodez changed the title Low Level Rest Client shows successful response as empty bad request Low Level Rest Client shows successful response bad request with empty response Mar 7, 2018
@jasontedor
Copy link
Member

We have a test case that tests that HEAD requests for an existing index operate correctly.

This is not to say that there is not a bug here, but it is to say that without a correlating log message or a reproduction, we are unlikely to make much progress on this issue. Do you have anything here? What happens if you send the request without GET instead of HEAD?

@jasontedor jasontedor added :Clients/Java Low Level REST Client Minimal dependencies Java Client for Elasticsearch feedback_needed labels Mar 7, 2018
@jasontedor
Copy link
Member

FYI @elastic/es-core-infra.

@kevcodez
Copy link
Author

kevcodez commented Mar 7, 2018

@jasontedor Same goes for GET - 400 bad request with empty response. Executing both GET and HEAD via curl against the ES instance did just fine.

Switchting to the basic apache http client with the same request URL resulted in a 200 OK rather than 400. This was just getting more strange, as I could not reproduce this locally.

I will try to get some logs out of the AWS service by tomorrow, I cannot access the logs today.

@jasontedor
Copy link
Member

Do you have a proxy between the client and the instance? There might be a problem with that here; I did just now test the client through a proxy and I had no troubles, but maybe your proxy configuration is different.

This worked fine for me:

public class Head {

    public static void main(String[] args) throws IOException {
        final HttpHost host = new HttpHost("<redacted>", 9243, "https");
        final Header header = new BasicHeader("Authorization", "Basic <redacted>");
        try (RestClient client = RestClient.builder(host).setDefaultHeaders(new Header[] { header }).build()) {
            final Response response = client.performRequest("HEAD", "/metricbeat-6.2.1-2018.03.07", Collections.emptyMap());
            System.out.println(response.getStatusLine());
        }
    }

}

where the address I used here is a proxy.

Output:

09:44:56 [jason:~/src/jasontedor/head] $ ./gradlew run

> Task :run 
HTTP/1.1 200 OK


BUILD SUCCESSFUL in 1s
2 actionable tasks: 2 executed

@jasontedor
Copy link
Member

No additional feedback, closing.

@gskoropada
Copy link

@kevcodez I've just came across the same issue and figured out that the problem was a missing / in the URI.
It worked fine with a local Elasticsearch docker container, but got 400s from AWS.
When I added that / it worked just fine.

@aug24
Copy link

aug24 commented Aug 8, 2018

I'll add to this for posterity, as it's taken me ~15 hours to work this one out:

When making a new high level ElasticSearch java client, and making requests via the underlying low level client, to an AWS ELB/ALB, failure to put the leading slash on the URI will result in a 400 from the ELB/ALB, EVEN THOUGH direct connections (eg your test database) will work just fine.

The line causing the problem is (I think)
https://github.com/elastic/elasticsearch/blob/master/client/rest/src/main/java/org/elasticsearch/client/RestClient.java#L806

Which ought to be replaced with a check to see if the path begins with "/" and prepends it if not.

[edit]

Just found out that this was discussed here: #30119 (comment)

The official 'fix' is to use the 'pathPrefix' option to always prepend with "/". The 'benefit' of this approach is that users can make invalid requests if they really really want to!

The remaining problem is that your error will simply be a 400 from AWS because the request is not valid HTTP, so if you are here reading this, then I hope I have improved your day!

@rorticus0502
Copy link

@kevcodez I've just came across the same issue and figured out that the problem was a missing / in the URI. It worked fine with a local Elasticsearch docker container, but got 400s from AWS. When I added that / it worked just fine.

I am getting 400 from AWS when running an updateByQuery, but the exact same borequest works when run against local elastic running in docker. I have just added a forward slash to the uri and it still works locally, so I am going to try this now in AWS env. If it works then a big thank you to you.

@rorticus0502
Copy link

I'll add to this for posterity, as it's taken me ~15 hours to work this one out:

When making a new high level ElasticSearch java client, and making requests via the underlying low level client, to an AWS ELB/ALB, failure to put the leading slash on the URI will result in a 400 from the ELB/ALB, EVEN THOUGH direct connections (eg your test database) will work just fine.

The line causing the problem is (I think) https://github.com/elastic/elasticsearch/blob/master/client/rest/src/main/java/org/elasticsearch/client/RestClient.java#L806

Which ought to be replaced with a check to see if the path begins with "/" and prepends it if not.

[edit]

Just found out that this was discussed here: #30119 (comment)

The official 'fix' is to use the 'pathPrefix' option to always prepend with "/". The 'benefit' of this approach is that users can make invalid requests if they really really want to!

The remaining problem is that your error will simply be a 400 from AWS because the request is not valid HTTP, so if you are here reading this, then I hope I have improved your day!

yes, thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Clients/Java Low Level REST Client Minimal dependencies Java Client for Elasticsearch feedback_needed
Projects
None yet
Development

No branches or pull requests

6 participants
@jasontedor @aug24 @gskoropada @kevcodez @rorticus0502 and others