Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Verified Commit 12887c9f authored by Nicolas Gelot's avatar Nicolas Gelot
Browse files

Support HTTP redirect on latest links

parent 1c4b8279
Loading
Loading
Loading
Loading
+3 −106
Original line number Diff line number Diff line
@@ -98,15 +98,13 @@ public class DownloadTask extends Task<Boolean>{
     */
    @Override
    protected Boolean call() throws Exception {
        final String latestBuildFilename = fetchLatestBuildFilename(targetUrl);

        final String localFilePath = AppConstants.getSourcesFolderPath() + fileName;

        final String checksumFilePath = localFilePath + checkSumExtension;
        
        if(isCancelled()) return false;
        
        this.updateTitle("Downloading " + latestBuildFilename + checkSumExtension);
        this.updateTitle("Downloading " + targetUrl + checkSumExtension);
        
        
        File checksumLmdFile = new File(AppConstants.getSourcesFolderPath()+"lmd."+fileName+checkSumExtension);
@@ -127,7 +125,7 @@ public class DownloadTask extends Task<Boolean>{

        if(isCancelled()) return false;

        this.updateTitle("Downloading "+ latestBuildFilename);
        this.updateTitle("Downloading "+ targetUrl);

        final String tmpFilePath = AppConstants.getSourcesFolderPath()+"tmp."+fileName;
        
@@ -182,108 +180,6 @@ public class DownloadTask extends Task<Boolean>{
        }
    }

    private String fetchLatestBuildFilename(String archiveUrl) {
        // Extract codeName and codeType from the archiveUrl
        Pair<String, String> codeInfo = getCodeNameFromUrl(archiveUrl);
        if (codeInfo == null) {
            logger.error("Failed to fetch latest build filename: codeName or codeType is null.");
            return null;
        }

        String codeName = codeInfo.getKey();
        String codeType = codeInfo.getValue();

        // Construct API URL using codeName and codeType
        HttpURLConnection apiConnection = getApiConnection(codeName, codeType);
        if (apiConnection == null) {
            logger.error("Failed to fetch latest build filename: API connection is null.");
            return null;
        }

        try {
            String latestBuildFilename = processApiResponse(apiConnection);
            return latestBuildFilename;
        } catch (IOException e) {
            logger.error("Error processing API response: {}", e.getMessage());
            return null;
        } finally {
            if (apiConnection != null) {
                apiConnection.disconnect();
            }
        }
    }

    private Pair<String, String> getCodeNameFromUrl(String archiveUrl) {
        try {
            URL url = new URL(archiveUrl);
            String[] urlParts = url.getPath().split("/");

            for (int i = 0; i < urlParts.length; i++) {
                if (urlParts[i].equals("stable") || urlParts[i].equals("dev")) {
                    if (i + 1 < urlParts.length) {
                        String codeType = urlParts[i];
                        String codeName = urlParts[i + 1];
                        logger.debug("CodeName extracted from URL: {}", codeName);
                        logger.debug("CodeType extracted from URL: {}", codeType);
                        return new Pair<>(codeName, codeType);
                    }
                }
            }

            logger.error("Invalid URL: Can't find codeName or codeType in: {}", archiveUrl);
        } catch (MalformedURLException e) {
            logger.error("Invalid URL: {}", e.getMessage());
        }

        return null;
    }

    private HttpURLConnection getApiConnection(String codeName, String codeType) {
        try {
            URL apiUrl = new URL("https://ota.ecloud.global/api/v1/" + codeName + "/" + codeType + "?format=json");
            HttpURLConnection apiConnection = (HttpURLConnection) apiUrl.openConnection();
            apiConnection.setRequestMethod("GET");
            apiConnection.setRequestProperty("User-Agent", "null eOS v3");
            return apiConnection;
        } catch (IOException e) {
            logger.error("Error establishing API connection: {}", e.getMessage());
        }

        return null;
    }

    private String processApiResponse(HttpURLConnection apiConnection) throws IOException {
        try {
            int responseCode = apiConnection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                String responseString = inputStreamToString(apiConnection.getInputStream());

                // Try parsing the response as JSON
                new JSONObject(responseString);

                JSONObject responseJson = new JSONObject(responseString);
                JSONArray responses = responseJson.getJSONArray("response");

                JSONObject responseObject = responses.getJSONObject(0);
                String filename = responseObject.getString("filename");
                return filename;
            } else {
                logger.error("Error fetching latest build filename: HTTP response code {}", responseCode);
            }
        } catch (JSONException e) {
            logger.warn("API response appears to be invalid JSON. Ignoring...");
            return null;
        } catch (IOException e) {
            logger.error("Error processing API response: {}", e.getMessage());
        } finally {
            if (apiConnection != null) {
                apiConnection.disconnect();
            }
        }

        return null;
    }

    private String inputStreamToString(InputStream inputStream) throws IOException {
        StringBuilder responseString = new StringBuilder();
        Scanner scanner = new Scanner(inputStream);
@@ -310,6 +206,7 @@ public class DownloadTask extends Task<Boolean>{
        HttpURLConnection connect = (HttpURLConnection) new URL(fileURL).openConnection();
        connect.setReadTimeout(30000);
        connect.setConnectTimeout(30000);
        connect.setInstanceFollowRedirects(true);
        
        File localFile = new File(localFilePath);
        if(localFile.exists()){