Вашите промени (фиксове, оптимизации) по framework-a

Докато правих подготовката за изпита се натъкнах на няколко проблема по framework-a, за които намерих лесни фиксове (или workaround-и).

Споделям ги тук удобство на колегите, които също са се сблъскали или тепърва ще се сблъскат с тях.

 

Първият проблем е свързан с наличието на space (" ") в пътя към Javache (напр. "C:\My Projects\javache"), като в този случай няма да успеете да вдигнете Javache ("Request Handler priority configuration file does not exist.").

Решението е просто - заменете всички "%20" с " " в SERVER_ROOT_FOLDER_PATH  (javache -> WebConstants.java):

    public static final String SERVER_ROOT_FOLDER_PATH =
            Server
                    .class
                    .getResource("")
                    .toString()
                    .replace("file:/", "")
                    .replace(WEB_SERVER_PACKAGE_PATH, "")
                    .replace("%20", " "); // NOTE - replace %20 with " " to allow paths with spaces

 

Вторият проблем е донякъде свързан с първият (наличи на " " в пътя), но проявлението му е, че не може да се заредят статичните ресурси (напр. bootsrap.min.css).

Решението на този проблем е в toyote -> ResourceHandler.java:


    private void handleResourceRequest(String resourcesFolder, String resourceName, HttpResponse response) {
        try {
//            Path resourcePath = Paths.get(new URL("file:/" + new File(resourcesFolder + File.separator + resourceName).getCanonicalPath()).toURI());
            Path resourcePath = Paths.get(resourcesFolder + File.separator + resourceName); // NOTE - fixed loading of static resources (like CSS files) when path contains spaces

 

 

 

Третият проблем е краш при събмитване на форма с празно поле (напр. login с празно име или парола) в резултат на който не получаваме response (This page isn’t working + localhost didn’t send any data. + ERR_EMPTY_RESPONSE).

Причината за краша е, че такива полета пристигат като name= и при сплит по "=" в initBodyParameters получаваме масив само с един елемент (name), а се опитваме да достъпим 2 елемента. 

Решението е в javache -> HttpRequestImpl.java (initBodyParameters), като в тази ситуация слагаме "" за value:

    private void initBodyParameters(String requestContent) {
        if (this.getMethod().equals("POST")) {
            this.bodyParameters = new HashMap<>();

            List<String> requestParams = Arrays.asList(requestContent.split("\\r\\n"));

            if (requestParams.size() > this.headers.size() + 2) {
                List<String> bodyParams = Arrays.asList(requestParams.get(this.headers.size() + 2).split("&"));

                for (int i = 0; i < bodyParams.size(); i++) {
                    String[] bodyKeyValuePair = bodyParams.get(i).split("=");

                    // NOTE: Fixed crash on empty parameters from input form (ex. "username=")
                    if (bodyKeyValuePair.length == 2) {
                        this.addBodyParameter(bodyKeyValuePair[0], bodyKeyValuePair[1]);
                    } else if (bodyKeyValuePair.length == 1) {
                        this.addBodyParameter(bodyKeyValuePair[0], "");
                    }
                }
            }
        }
    }

 

 

Накрая ще споделя и една малка оптимизация в процеса на тестване на app-a.

Може да пренасочите artifact-a да се създава директно в javache\target\classes\webapps папката, като по този начин си спестявате ръчното копиране на ROOT.jar файла при всяка промяна в app-a.