英文:
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应用程序,处理请求的控制器如下:
@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响应:
...(中间部分省略)
起初,我认为Spring Boot端的控制器有问题,但我尝试了与cURL相同的请求,最终成功:
...(中间部分省略)
我看到了内容类型方面的差异,其中Apache HttpClient添加了字符编码。现在我想知道:
1. 我是否应该强制使用UTF-8字符编码,如何实现?还是
2. 我的Apache HttpClient POST示例中是否有其他问题?
请告诉我您需要对其中哪些部分进行翻译。
英文:
I need help with apache http 5 client example described here. My goal is to do exactly the same as 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:
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:
@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:
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:
=> 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. Now I wonder:
- should I force utf8 character encoding and how?? or
- something else is wrong in my apache httpclient post example
答案1
得分: 0
以下是翻译好的部分:
问题描述从未在生产环境中发生,只在我的本地开发环境中出现,该环境是MacOSX Catalina。
我很少重新启动我的MacBookPro,似乎是这导致了问题。在重新启动硬件后,问题再也没有发生。
这并不完全是答案,但这是唯一使问题停止的方法:(
英文:
Problem I described never occurred in production, only in my local development environment which is MacOSX Catalina.
I rarely restart my MacBookPro and seems it caused issue. After restarting hardware, issue never happen again.
This is not quite answer but it is only way to inactivate question
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论