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 เหล่านี้ให้เรา ดังนั้น 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