简体   繁体   English

为什么 http 请求使用 Apache HttpClient5 收到 http 404 错误,如果使用抢先 BASIC 身份验证

[英]Why http request made with Apache HttpClient5 receives http 404 error if preemptive BASIC authentication used

I need help with apache http 5 client example described here .我需要有关此处描述的 apache http 5 客户端示例的帮助。 My goal is to do exactly the same as CURL:我的目标是做与 CURL 完全相同的事情:

curl --verbose --user "admin:admin" --data-binary @20200802112010-test.csv  'http://localhost:8080/api/test/write?db=test' --trace-ascii trace.txt

I modified example to perform POST instead of GET:我修改了示例以执行 POST 而不是 GET:

private void _sendFile(File file) throws IOException, URISyntaxException {
        BasicScheme basicScheme = new BasicScheme();

        basicScheme.initPreemptive(new UsernamePasswordCredentials("admin", "admin".toCharArray()));

        HttpClientContext httpClientContext = HttpClientContext.create();

        HttpHost httpHost = new HttpHost("http", "localhost", 8080);

        httpClientContext.resetAuthExchange(httpHost, basicScheme);

        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            FileEntity fileEntity = new FileEntity(file, ContentType.APPLICATION_FORM_URLENCODED);

            HttpPost httpPost = new HttpPost("http://localhost:8080/api/test/write?db=test");

            httpPost.setEntity(fileEntity);

            try (final CloseableHttpResponse httpResponse = httpClient.execute(httpHost, httpPost, httpClientContext)) {
                if (httpResponse.getCode() == 204) {
                    return;
                }

                _logger.warn("Unexpected return code {}", httpResponse.getCode());
            }
        }
    }

My server side code is Spring Boot App generated by JHipster and controller that handles request is this:我的服务器端代码是由 JHipster 生成的 Spring Boot App 和处理请求的 controller 是这样的:

@Profile({"dev", "igor"})
@RequestMapping("/api/test")
@RestController
public class DBEndpointSimulatorResource {

    /**
     * {@code POST  /write} : Simulates file import on INRAE InfluxDB server.
     *
     * @param dataBase the database name
     * @param content the request body
     *
     * @return the {@link ResponseEntity} with status {@code 204 (No Content)}
     * @throws URISyntaxException if the Location URI syntax is incorrect.
     */
    @PostMapping("/write")
    public ResponseEntity<?> simulateWrite(@RequestParam("db") String dataBase, @RequestBody String content)
        throws URISyntaxException {

        _logger.debug("REST request to process file for: {}", dataBase);

        if (content == null) {
            throw new BadRequestAlertException(
                "A content must not be empty", "DB FILE", "ERROR-SIMULATOR-001");
        }

        final ResponseEntity.HeadersBuilder<?> headersBuilder = ResponseEntity.noContent();

        return headersBuilder.build();
    }

    private final Logger _logger = LoggerFactory.getLogger(DBEndpointSimulatorResource.class);

}

Once executed _sendFile code receives HTTP error 404. I turned on logging for httpclient 5 and it logs out proper connect to server side which responds with 404:执行后 _sendFile 代码收到 HTTP 错误 404。我打开了 httpclient 5 的日志记录,它注销了与服务器端的正确连接,它以 404 响应:

     ex-00000032: target auth state: UNCHALLENGED
2020-08-03 10:01:00.009 DEBUG 95767 --- [ta-scheduling-2] o.a.h.c.http.impl.classic.ProtocolExec   : ex-00000032: proxy auth state: UNCHALLENGED
2020-08-03 10:01:00.009 DEBUG 95767 --- [ta-scheduling-2] o.a.h.c.http.impl.classic.ConnectExec    : ex-00000032: acquiring connection with route {}->http://localhost:8080
2020-08-03 10:01:00.009 DEBUG 95767 --- [ta-scheduling-2] o.a.h.c.h.i.classic.InternalHttpClient   : ex-00000032: acquiring endpoint (3 MINUTES)
2020-08-03 10:01:00.009 DEBUG 95767 --- [ta-scheduling-2] h.i.i.PoolingHttpClientConnectionManager : ex-00000032: endpoint lease request (3 MINUTES) [route: {}->http://localhost:8080][total available: 0; route allocated: 0 of 5; total allocated: 0 of 25]
2020-08-03 10:01:00.009 DEBUG 95767 --- [ta-scheduling-2] h.i.i.PoolingHttpClientConnectionManager : ex-00000032: endpoint leased [route: {}->http://localhost:8080][total available: 0; route allocated: 1 of 5; total allocated: 1 of 25]
2020-08-03 10:01:00.009 DEBUG 95767 --- [ta-scheduling-2] h.i.i.PoolingHttpClientConnectionManager : ex-00000032: acquired ep-00000031
2020-08-03 10:01:00.009 DEBUG 95767 --- [ta-scheduling-2] o.a.h.c.h.i.classic.InternalHttpClient   : ex-00000032: acquired endpoint ep-00000031
2020-08-03 10:01:00.009 DEBUG 95767 --- [ta-scheduling-2] o.a.h.c.http.impl.classic.ConnectExec    : ex-00000032: opening connection {}->http://localhost:8080
2020-08-03 10:01:00.009 DEBUG 95767 --- [ta-scheduling-2] o.a.h.c.h.i.classic.InternalHttpClient   : ep-00000031: connecting endpoint (3 MINUTES)
2020-08-03 10:01:00.009 DEBUG 95767 --- [ta-scheduling-2] h.i.i.PoolingHttpClientConnectionManager : ep-00000031: connecting endpoint to http://localhost:8080 (3 MINUTES)
2020-08-03 10:01:00.010 DEBUG 95767 --- [ta-scheduling-2] .i.i.DefaultHttpClientConnectionOperator : http-outgoing-49: connecting to localhost/127.0.0.1:8080
2020-08-03 10:01:00.010 DEBUG 95767 --- [ta-scheduling-2] .i.i.DefaultHttpClientConnectionOperator : http-outgoing-49: connection established 127.0.0.1:52473<->127.0.0.1:8080
2020-08-03 10:01:00.010 DEBUG 95767 --- [ta-scheduling-2] h.i.i.PoolingHttpClientConnectionManager : ep-00000031: connected http-outgoing-49
2020-08-03 10:01:00.010 DEBUG 95767 --- [ta-scheduling-2] o.a.h.c.h.i.classic.InternalHttpClient   : ep-00000031: endpoint connected
2020-08-03 10:01:00.010 DEBUG 95767 --- [ta-scheduling-2] o.a.h.c.h.impl.classic.MainClientExec    : ex-00000032: executing POST /api/test/write?db=test HTTP/1.1
2020-08-03 10:01:00.010 DEBUG 95767 --- [ta-scheduling-2] o.a.h.c.h.i.classic.InternalHttpClient   : ep-00000031: start execution ex-00000032
2020-08-03 10:01:00.010 DEBUG 95767 --- [ta-scheduling-2] h.i.i.PoolingHttpClientConnectionManager : ep-00000031: executing exchange ex-00000032 over http-outgoing-49
2020-08-03 10:01:00.010 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.headers       : http-outgoing-49 >> POST /api/test/write?db=test HTTP/1.1
2020-08-03 10:01:00.011 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.headers       : http-outgoing-49 >> Accept-Encoding: gzip, x-gzip, deflate
2020-08-03 10:01:00.011 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.headers       : http-outgoing-49 >> Content-Length: 29423
2020-08-03 10:01:00.011 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.headers       : http-outgoing-49 >> Content-Type: application/x-www-form-urlencoded; charset=ISO-8859-1
2020-08-03 10:01:00.011 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.headers       : http-outgoing-49 >> Host: localhost:8080
2020-08-03 10:01:00.011 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.headers       : http-outgoing-49 >> Connection: keep-alive
2020-08-03 10:01:00.011 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.headers       : http-outgoing-49 >> User-Agent: Apache-HttpClient/5.0 (Java/1.8.0_202)
2020-08-03 10:01:00.011 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.headers       : http-outgoing-49 >> Authorization: Basic YWRtaW46YWRtaW4=
2020-08-03 10:01:00.011 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.wire          : http-outgoing-49 >> "POST /api/test/write?db=test HTTP/1.1[\r][\n]"
2020-08-03 10:01:00.011 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.wire          : http-outgoing-49 >> "Accept-Encoding: gzip, x-gzip, deflate[\r][\n]"
2020-08-03 10:01:00.011 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.wire          : http-outgoing-49 >> "Content-Length: 29423[\r][\n]"
2020-08-03 10:01:00.011 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.wire          : http-outgoing-49 >> "Content-Type: application/x-www-form-urlencoded; charset=ISO-8859-1[\r][\n]"
2020-08-03 10:01:00.011 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.wire          : http-outgoing-49 >> "Host: localhost:8080[\r][\n]"
2020-08-03 10:01:00.011 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.wire          : http-outgoing-49 >> "Connection: keep-alive[\r][\n]"
2020-08-03 10:01:00.011 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.wire          : http-outgoing-49 >> "User-Agent: Apache-HttpClient/5.0 (Java/1.8.0_202)[\r][\n]"
2020-08-03 10:01:00.011 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.wire          : http-outgoing-49 >> "Authorization: Basic YWRtaW46YWRtaW4=[\r][\n]"
2020-08-03 10:01:00.011 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.wire          : http-outgoing-49 >> "[\r][\n]"
2020-08-03 10:01:00.011 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.wire          : http-outgoing-49 >> "pesmic,dat1=MIC,dat2=2136-0000 dat3="null",dat4=60,dat5=0,dat6=0,dat7=0,activ="null" 1554026400000000000[\n]"
2020-08-03 10:01:00.034 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.wire          : http-outgoing-49 >> "pesmic,dat1=MIC,dat2=2136-0001 dat3="null",dat4=40060,dat5=0,dat6=0,dat7=0,activ="null" 1554530400000000000"
2020-08-03 10:01:00.037 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.wire          : http-outgoing-49 << "HTTP/1.1 404 [\r][\n]"
2020-08-03 10:01:00.037 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.wire          : http-outgoing-49 << "X-Content-Type-Options: nosniff[\r][\n]"
2020-08-03 10:01:00.037 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.wire          : http-outgoing-49 << "X-Frame-Options: SAMEORIGIN[\r][\n]"
2020-08-03 10:01:00.037 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.wire          : http-outgoing-49 << "X-XSS-Protection: 1[\r][\n]"
2020-08-03 10:01:00.037 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.wire          : http-outgoing-49 << "Set-Cookie: JSESSIONID=AEC03A81AD4A85F68CB94BAF23E784E8; Path=/; HttpOnly[\r][\n]"
2020-08-03 10:01:00.037 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.wire          : http-outgoing-49 << "Content-Type: text/html;charset=UTF-8[\r][\n]"
2020-08-03 10:01:00.037 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.wire          : http-outgoing-49 << "Content-Length: 690[\r][\n]"
2020-08-03 10:01:00.037 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.wire          : http-outgoing-49 << "Date: Mon, 03 Aug 2020 08:01:00 GMT[\r][\n]"
2020-08-03 10:01:00.037 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.wire          : http-outgoing-49 << "Keep-Alive: timeout=20[\r][\n]"
2020-08-03 10:01:00.037 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.wire          : http-outgoing-49 << "Connection: keep-alive[\r][\n]"
2020-08-03 10:01:00.037 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.wire          : http-outgoing-49 << "[\r][\n]"
2020-08-03 10:01:00.037 DEBUG 95767 --- [ta-scheduling-2] org.apache.hc.client5.http.wire          : http-outgoing-49 << "[\n]"

In the beginning I thought controller at spring boot side is wrong, but I tried same request with cURL it ended with success:一开始我认为 controller 在 spring 引导端是错误的,但我尝试了与 cURL 相同的请求,它以成功结束:

    => Send header, 236 bytes (0xec)
0000: POST /api/test/write?db=test HTTP/1.1
0027: Host: localhost:8080
003d: Authorization: Basic YWRtaW46YWRtaW4=
0064: User-Agent: curl/7.64.1
007d: Accept: */*
008a: Content-Length: 2689786
00a3: Content-Type: application/x-www-form-urlencoded
00d4: Expect: 100-continue
00ea: 
<= Recv header, 23 bytes (0x17)
0000: HTTP/1.1 100 Continue
<= Recv header, 19 bytes (0x13)
0000: Content-Length: 0
=> Send data, 65536 bytes (0x10000)
== Info: We are completely uploaded and fine
<= Recv header, 25 bytes (0x19)
0000: HTTP/1.1 204 No Content
<= Recv header, 12 bytes (0xc)
0000: Expires: 0

I see difference in content type where apache http client appends character encoding.我看到 apache http 客户端附加字符编码的内容类型存在差异。 Now I wonder:现在我想知道:

  1. should I force utf8 character encoding and how??我应该强制使用 utf8 字符编码吗?如何? or或者
  2. something else is wrong in my apache httpclient post example我的 apache httpclient 帖子示例中还有其他问题

Problem I described never occurred in production, only in my local development environment which is MacOSX Catalina.我描述的问题从未在生产中发生,仅在我的本地开发环境 MacOSX Catalina 中发生。

I rarely restart my MacBookPro and seems it caused issue.我很少重新启动我的 MacBookPro,似乎它引起了问题。 After restarting hardware, issue never happen again.重新启动硬件后,问题不再发生。

This is not quite answer but it is only way to inactivate question:(这不是完全答案,但它是使问题无效的唯一方法:(

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 Apache HttpClient 4 的抢占式基本身份验证 - Preemptive Basic authentication with Apache HttpClient 4 Apache httpclient 4.5.13 抢先认证与否 - Apache httpclient 4.5.13 preemptive authentication or not HTTP2 url在浏览器中成功加载,但在httpclient5中失败 - HTTP2 url loading succesfuly in browser but fails in httpclient5 使用HttpClient在Java中进行Http基本身份验证? - Http Basic Authentication in Java using HttpClient? apache httpclient5 多部分请求 (kotlin) 的编码/字符集问题 - Encoding/charset issues on apache httpclient5 multipart request (kotlin) Apache HTTPClient流式HTTP POST请求? - Apache HTTPClient Streaming HTTP POST Request? 使用 NTLM 身份验证时,最新的 Apache HttpClient 4.1.1 出现 HTTP/1.1 407 错误 - HTTP/1.1 407 error with latest Apache HttpClient 4.1.1 when using NTLM authentication 使用Apache HttpClient进行Https和基本身份验证 - Https and Basic Authentication with Apache HttpClient 如何使用 Apache HttpClient5 设置 bufferSize? - How to set bufferSize with Apache HttpClient5? 如何使用apache httpclient和web身份验证进行http发布? - How to do http post using apache httpclient with web authentication?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM