פרוטוקול TCP מותאם אישית יכול לעבור דרך פרוקסי HTTP כאשר הפרוקסי מתיר CONNECT אל היעד. פרוטוקול היישום אינו חייב להפוך ל-HTTP: HTTP מקים את המנהרה, ואחר כך היישום מחליף בה את הבתים שלו עצמו.

OpenJDK 25 מספק נתיב דרך פרוקסי HTTP ב-Socket(Proxy). המימוש שלו מבצע את חילופי ה-CONNECT ומחזיר socket מחובר לשימוש היישום.

Proxy route = new Proxy(
    Proxy.Type.HTTP,
    new InetSocketAddress("proxy.example", 8080));

try (Socket socket = new Socket(route)) {
    socket.setSoTimeout(10000);
    socket.connect(
        InetSocketAddress.createUnresolved("tcp-service.example", 8443),
        5000);
    InputStream input = socket.getInputStream();
    OutputStream output = socket.getOutputStream();
}

הקטע הזה משתמש במחלקות מ-java.net ומ-java.io. החליפו את שתי נקודות הקצה ובצעו את חילופי הפרוטוקול לפני יציאה מבלוק ה-try. עבור יעד TCP ציבורי מותר, בחרו מועמדים ל-HTTP מתוך רשימת פרוקסי ה-HTTP רק לאחר בדיקת הרשאת CONNECT לפורט של אותו יעד. כתובת הפרוקסי היא המקום שאליו Java מתחברת תחילה; הכתובת שמועברת ל-connect מזהה את השירות שהפרוקסי אמור להגיע אליו.

היעד שאינו פתור שומר על שם המארח שלו עבור בקשת ה-CONNECT של המימוש הזה. לעומת זאת, InetSocketAddress פתור מספק לבקשה הזו את כתובת ה-IP הפתורה שלו. ההבחנה הזו חשובה כאשר הפרוקסי חייב לפתור את שם השירות או להחיל מדיניות המבוססת על שם מארח.

מה חיבור מוצלח משאיר לכם

הזרמים שמתקבלים נושאים את הנתונים של השירות שעובר במנהרה. הם אינם חושפים תגובת HTTP נפרדת שהיישום שלכם אמור לקרוא ולזרוק. הוספת חילופי CONNECT שניים תשלח טקסט HTTP אל השירות לאחר שה-JDK כבר הקים את המנהרה.

הדוגמה קובעת פסק זמן לחיבור ופסק זמן לקריאה מה-socket; אלה בקרות נפרדות, ולא מועד אחרון כולל אחד להפעלת היישום.

הרשאת CONNECT עדיין שייכת לפרוקסי. נקודת קצה שמעבירה בקשות אינטרנט רגילות עשויה לדחות את הפורט של השירות או לדרוש אימות לפני פתיחת מנהרה. שמרו על הכשלים האלה נפרדים משרת שמקבל את המנהרה אך מאוחר יותר דוחה את פרוטוקול היישום שלכם.

אם הפרוטוקול הזה צריך TLS, נהלו משא ומתן על TLS דרך ה-socket המחובר עם שם המארח המיועד של השירות ועם בדיקות התעודה הרגילות. CONNECT לבדו אינו מצפין את הזרם. עבור HTTP API אמיתי, לקוח HTTP נשאר הממשק הנוח יותר מפני שהוא גם מטפל בהודעות HTTP.

מאמרים קשורים