{ "id": "168618", "key": "TIMOB-24896", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [], "resolution": null, "resolutiondate": null, "created": "2017-06-26T23:13:46.000+0000", "priority": { "name": "Low", "id": "4" }, "labels": [ "android", "engSchedule", "httpclient" ], "versions": [ { "id": "17608", "name": "Release 6.1.0", "archived": false, "released": true, "releaseDate": "2017-05-26" } ], "issuelinks": [], "assignee": null, "updated": "2019-05-14T15:35:32.000+0000", "status": { "description": "The issue is open and ready for the assignee to start work on it.", "name": "Open", "id": "1", "statusCategory": { "id": 2, "key": "new", "colorName": "blue-gray", "name": "To Do" } }, "components": [ { "id": "10202", "name": "Android", "description": "Android Platform" } ], "description": "*Summary:*\r\nTitanium's \"HTTPClient\" API does not support square bracketed literal IPv6 URLs such as \"http://[::1]\".\r\n\r\nThis is a bug in Google's \"Uri\" class which fails to parse the hostname and port number in this case.\r\n https://issuetracker.google.com/issues/37069493\r\n\r\n*Steps to Reproduce:*\r\n# Run the below code on an Android device.\r\n# Tap the \"Send\" button.\r\n# Observe the Android log.\r\n\r\n{code:javascript}\r\nvar listenSocket = Ti.Network.Socket.createTCP(\r\n{\r\n\thost : \"localhost\",\r\n\tport : 40404,\r\n\taccepted : function(e)\r\n\t{\r\n\t\tTi.API.info(\"@@@ accepted() host: \" + e.inbound.host);\r\n\t\tTi.Stream.pump(e.inbound, function(e)\r\n\t\t{\r\n\t\t\tvar httpRequestMessage = \"\";\r\n\t\t\tif (e.buffer) {\r\n\t\t\t\thttpRequestMessage = e.buffer.toString();\r\n\t\t\t}\r\n\t\t\tTi.API.info(\"@@@ Received HTTP Request:\\n\" + httpRequestMessage);\r\n\t\t\tlistenSocket.accept({ timeout: 30000 });\r\n\t\t}, 1024, true);\r\n\t},\r\n\terror : function(e)\r\n\t{\r\n\t\tTi.API.info(\"@@@ Socket Listener Error: \" + e.error);\r\n\t},\r\n});\r\nlistenSocket.listen();\r\nlistenSocket.accept({ timeout: 30000 });\r\n\r\nvar window = Titanium.UI.createWindow();\r\nvar buttonView = Ti.UI.createButton(\r\n{\r\n\ttitle: \"Send HTTP Request\",\r\n\tcenter: {x: \"50%\", y: \"50%\"},\r\n});\r\nvar url = \"http://[::1]:40404/Test\";\r\nbuttonView.addEventListener(\"click\", function(e)\r\n{\r\n\tTi.API.info(\"@@@ Sending HTTP request for url:\\n\" + url);\r\n\tvar httpClient = Ti.Network.createHTTPClient();\r\n\thttpClient.open(\"POST\", url);\r\n\thttpClient.send(\"Original URL:\\n\" + url);\r\n});\r\nwindow.add(buttonView);\r\nwindow.open();\r\n{code}\r\n\r\n*Result:*\r\nThe HTTP request does not get sent and the following caught exception can be seen in the log.\r\n\r\n\r\n{code}\r\n[ERROR] : TiHTTPClient: java.net.MalformedURLException: invalid port: :1%%5D:40404\r\n[ERROR] : TiHTTPClient: \tat java.net.URL.(URL.java:623)\r\n[ERROR] : TiHTTPClient: \tat java.net.URL.(URL.java:486)\r\n[ERROR] : TiHTTPClient: \tat java.net.URL.(URL.java:435)\r\n[ERROR] : TiHTTPClient: \tat ti.modules.titanium.network.TiHTTPClient$ClientRunnable.run(TiHTTPClient.java:1143)\r\n[ERROR] : TiHTTPClient: \tat java.lang.Thread.run(Thread.java:761)\r\n[ERROR] : TiHTTPClient: Caused by: java.lang.IllegalArgumentException: invalid port: :1%%5D:40404\r\n[ERROR] : TiHTTPClient: \tat java.net.URLStreamHandler.parseURL(URLStreamHandler.java:238)\r\n[ERROR] : TiHTTPClient: \tat java.net.URL.(URL.java:618)\r\n{code}\r\n\r\n*Recommended Solution:*\r\nThe Java \"URL\" class (all caps) doesn't have this IPv6 parsing bug. In our \"TiHTTPClient.java\" code, we should use the URL class to fetch the hostname and port number instead. Note that our TiHTTPClient class is already doing this in the open() method if a \"username:password\" component has been found in the URL.\r\n\r\n*Work-Around:*\r\nUse a literal IPv4 address instead.\r\nAnd for IPv6 \"http://[::1]\", use \"http://localhost\" instead.\r\n", "attachment": [], "flagged": false, "summary": "Android: HTTPClient does not support literal IPv6 URLs", "creator": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "environment": null, "comment": { "comments": [], "maxResults": 0, "total": 0, "startAt": 0 } } }