{"record":{"id":"0615ad0f4fcb7be6","repo":"jhy/jsoup","slug":"only-http-https-protocols-supported","errorCode":null,"errorMessage":"Only http & https protocols supported","messagePattern":"Only http & https protocols supported","errorType":"exception","errorClass":"MalformedURLException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/jsoup/helper/HttpConnection.java","lineNumber":910,"sourceCode":"         Tests if two URLs share an HTTP origin, as defined by scheme, host, and effective port.\n         See <a href=\"https://www.rfc-editor.org/rfc/rfc9110.html#section-4.3.1\">RFC 9110, Section 4.3.1</a>.\n         */\n        static boolean sameOrigin(URL first, URL second) {\n            int firstPort = first.getPort() != -1 ? first.getPort() : first.getDefaultPort();\n            int secondPort = second.getPort() != -1 ? second.getPort() : second.getDefaultPort();\n            return first.getProtocol().equalsIgnoreCase(second.getProtocol())\n                && first.getHost().equalsIgnoreCase(second.getHost())\n                && firstPort == secondPort;\n        }\n\n        static Response execute(HttpConnection.Request req, @Nullable Response prevRes) throws IOException {\n            Validate.isTrue(req.executing.tryLock(), \"Multiple threads were detected trying to execute the same request concurrently. Make sure to use Connection#newRequest() and do not share an executing request between threads.\");\n            Validate.notNullParam(req, \"req\");\n            URL url = req.url();\n            Validate.notNull(url, \"URL must be specified to connect\");\n            String protocol = url.getProtocol();\n            if (!protocol.equals(\"http\") && !protocol.equals(\"https\"))\n                throw new MalformedURLException(\"Only http & https protocols supported\");\n            final boolean supportsBody = req.method().hasBody();\n            final boolean hasBody = req.body != null;\n            if (!supportsBody)\n                Validate.isFalse(hasBody, \"Cannot set a request body for HTTP method \" + req.method());\n\n            // set up the request for execution\n            if (!req.data().isEmpty() && (!supportsBody || hasBody))\n                serialiseRequestUrl(req);\n            else if (supportsBody)\n                setOutputContentType(req);\n\n            long startTime = System.nanoTime();\n            RequestExecutor executor = RequestDispatch.get(req, prevRes);\n            Response res = null;\n            try {\n                res = executor.execute();\n\n                Method nextMethod = redirectMethod(res.statusCode, req.method());","sourceCodeStart":892,"sourceCodeEnd":928,"githubUrl":"https://github.com/jhy/jsoup/blob/9851ac5d9c576c6888910b5a51a2362bbc978959/src/main/java/org/jsoup/helper/HttpConnection.java#L892-L928","documentation":"During execute(), jsoup checks the target URL's protocol and throws MalformedURLException if it is not http or https. The connection executor only implements HTTP(S); other schemes like file:, ftp:, or ws: cannot be executed.","triggerScenarios":"Jsoup.connect(\"file:///etc/hosts\").execute(); calling url(new URL(\"ftp://...\")) then execute(); user-supplied URLs carrying non-HTTP schemes.","commonSituations":"Trying to scrape local files via file:// (should use Jsoup.parse(new File(...), charset)); websockets or other protocols mistakenly routed through Jsoup; dynamic URLs from crawls that preserve ftp/mailto links.","solutions":["Use only http:// or https:// URLs with Jsoup","For local files use Jsoup.parse(File, charset) instead of connect()","Validate protocol before executing: new URL(u).getProtocol() in (\"http\",\"https\")"],"exampleFix":"// before\nDocument doc = Jsoup.connect(\"file:///var/www/page.html\").get();\n// after\nDocument doc = Jsoup.parse(new File(\"/var/www/page.html\"), \"utf-8\");","handlingStrategy":"validation","validationCode":"String proto = new URL(target).getProtocol(); if (!proto.equals(\"http\") && !proto.equals(\"https\")) throw new IllegalArgumentException(\"Unsupported protocol: \" + proto);","typeGuard":"boolean isHttpUrl(URL u) { return u.getProtocol().equals(\"http\") || u.getProtocol().equals(\"https\"); }","tryCatchPattern":"try { return Jsoup.connect(url).execute(); } catch (MalformedURLException e) { /* non-HTTP scheme: route to file/FTP handler */ }","preventionTips":["Sanitize URLs from crawls/user input to http(s) only","Use Jsoup.parse(File, charset) for local files","Reject mailto:, ftp:, file: schemes at the crawler boundary"],"tags":["java","jsoup","url","protocol"],"backgroundTag":"invalid-url","analyzedSha":"9851ac5d9c576c6888910b5a51a2362bbc978959","analyzedAt":"2026-09-08T15:22:04.931Z","contentChangedAt":"2026-09-08T15:22:04.931Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}