[英]Why http request made with Apache HttpClient5 receives http 404 error if preemptive BASIC authentication used
我需要有關此處描述的 apache http 5 客戶端示例的幫助。 我的目標是做與 CURL 完全相同的事情:
curl --verbose --user "admin:admin" --data-binary @20200802112010-test.csv 'http://localhost:8080/api/test/write?db=test' --trace-ascii trace.txt
我修改了示例以執行 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());
}
}
}
我的服務器端代碼是由 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);
}
執行后 _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]"
一開始我認為 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
我看到 apache http 客戶端附加字符編碼的內容類型存在差異。 現在我想知道:
我描述的問題從未在生產中發生,僅在我的本地開發環境 MacOSX Catalina 中發生。
我很少重新啟動我的 MacBookPro,似乎它引起了問題。 重新啟動硬件后,問題不再發生。
這不是完全答案,但它是使問題無效的唯一方法:(
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.