Java: использование Apache HttpClient для отправки HttpGet в URI с подчеркиванием в имени хоста

Я знаю, что подчеркивание технически не разрешено в именах хостов URI, но, к сожалению, у нас есть клиенты, которые это делают, поэтому нам нужно поддерживать это. Я видел много других сообщений об этом на StackOverflow, где люди спрашивают, как вручную вставить имя хоста в объект URI, и поэтому я уже сделал это, но я все еще получаю SocketException, когда я пытаюсь отправить запрос:

URI uri = new URI("https", "my_ftp.website.com", "/target.jpg", null, null);
MyUtils.setField(uri, "host", "my_ftp.website.com"); // manually set "host" through reflection
HttpGet httpGet = new HttpGet(uri);
HttpClients.createDefault().execute(httpGet);

Как видно из приведенного выше фрагмента кода, я скопировал инструкции по ручной настройке поля «хост» в URI из этого сообщения StackOverflow, но явно не работает. Я даже пытался добавить код из этого сообщения StackOverflow в начало своей программы, но, похоже, в нем не было никаких эффект либо:

MyUtils.setField(URI.class, "L_DASH", 35184372088832L);
MyUtils.setField(URI.class, "H_DASH", 2147483648L);

Независимо от того, что я делаю, я всегда получаю одну и ту же ошибку:

java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:210)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
    at sun.security.ssl.InputRecord.read(InputRecord.java:503)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:975)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:436)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:384)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:374)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:221)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:165)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:140)
    at com.amazon.emf.customerservice.activities.account.TempTest.runTest(TempTest.java:44)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)

person Dasmowenator    schedule 06.02.2020    source источник
comment
Символы подчеркивания недопустимы в именах хостов; и они не будут работать с Java URL или Apache HttpGet. Ваша первая ссылка говорит о совершенно другом проекте с открытым исходным кодом, в котором есть обходной путь для поддержки имен хостов с символами подчеркивания. Это эта ссылка. Похоже на его проект. Удачи! Пробовали ли вы punycode?   -  person Elliott Frisch    schedule 06.02.2020
comment
В этой ссылке на проект LID commons bitbucket, который вы упомянули, похоже, что они используют apache: import org.apache.http.client.methods.HttpGet. Как вы думаете, какой проект с открытым исходным кодом они используют? Я не пробовал punycode - глядя на статью в Википедии, на которую вы ссылаетесь, я не понимаю, как это поможет. Не могли бы вы уточнить?   -  person Dasmowenator    schedule 07.02.2020
comment
Я проверил, вы не можете закодировать _, поэтому я думаю, что вы застряли. Насколько вы контролируете инфраструктуру DNS? Не могли бы вы сделать a.my_ftp.website.com и my_ftp.website.com разрешить a.my_ftp.website.com? Насколько я могу судить, проблема в _ в имени хоста (_ в доменах нормально).   -  person Elliott Frisch    schedule 07.02.2020
comment
У нас нет контроля над инфраструктурой DNS. Эти URL-адреса предоставляются нам клиентами, поэтому эти домены принадлежат им, а не нам.   -  person Dasmowenator    schedule 07.02.2020
comment
Одна из возможностей — использовать java.net.URL и java.net.URLConnection. В то время как java.net.URI проверяет допустимый синтаксис URI, java.net.URL гораздо слабее в этом отношении, вероятно, потому, что это древний класс, восходящий к Java 1.0.   -  person VGR    schedule 07.02.2020
comment
Я не понимаю, как это могло бы помочь. Конструктор HttpGet принимает только строку или URI, но не URL-адрес. Кроме того, как я упоминал в своем посте, я смог использовать отражение, чтобы вручную установить хост в URI, и это все еще не исправило это.   -  person Dasmowenator    schedule 07.02.2020