[英]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:
现在我想知道:
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.