Come difendersi dalle stringhe troppo grandi inserite nel form?

di il
4 risposte

Come difendersi dalle stringhe troppo grandi inserite nel form?

Sto creando un metodo che preleva i dati dal form e lo sto testanto a fondo. In tutte le casistiche esaminate il metodo funziona bene, fatta eccezione quando passo una stringa con 1.000.000.000 di caratteri in UTF-8 che dovrebbe avere una dimensione di 1GB (correggetemi se sbaglio). Sul mio IntelliJ il programma va in crash e la ragione è dovuta alla memoria RAM massima che l'IDE e la JVM possono utilizzare (correggetemi se sbaglio). Ho anche provato ad aumentare l'uso della memoria in questo modo:
Settings (Preferences on Mac) | Build, Execution, Deployment | Compiler | Build process heap size | 8000
Help | Change Memory Settings | 16000
ma non risolvo. La RAM sale fino a 6.9 di 8.0 GB e compare il messaggio:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.base/java.util.Arrays.copyOfRange(Arrays.java:4030)
	at java.base/java.lang.StringLatin1.newString(StringLatin1.java:715)
	at java.base/java.lang.StringBuilder.toString(StringBuilder.java:448)
	at org.thymeleaf.util.StringUtils.repeat(StringUtils.java:298)
1) Perché accade questo e come risolvo su un notebook con 8GB?
2) Al di la di come poter testare una stringa di dimensione massima possibile come scarto quelle stringhe troppo grandi per il mio form dato che un classico ciclo try non risolve?
3) Inoltre, quando la mia applicazione non può chiedere al server ulteriori risorse, come posso aggiungere un servizio (una pagina html statica) che ricorda all'utente che il server ha riempito tutta la RAM disponibile ed eventualmente anche esaurito tutte le risorse di calcolo fornite dalla CPU?
4) Sto usando Spring Boot 2 come framework, c'è qualche dipendenza/metodo/classe che può aiutarmi in questo intento?
ciao e grazie

4 Risposte

  • Re: Come difendersi dalle stringhe troppo grandi inserite nel form?

    iBaffiPro ha scritto:


    Sto creando un metodo che preleva i dati dal form e lo sto testanto a fondo. In tutte le casistiche esaminate il metodo funziona bene, fatta eccezione quando passo una stringa con 1.000.000.000 di caratteri in UTF-8
    Non è per niente chiaro il contesto. Di cosa si sta parlando? Del body (il body, il contenuto) di una request in POST?
    Spring Boot mette già in pratica tutta una serie di limiti con delle property che hanno default abbastanza sensati:

    spring.servlet.multipart.max-file-size (default 1MB)
    spring.servlet.multipart.max-request-size (default 10MB)
    server.tomcat.max-http-form-post-size (default 2MB)

    Quindi quella fantomatica stringa da 1GB da dove/come arriva?
  • Re: Come difendersi dalle stringhe troppo grandi inserite nel form?

    Si il contesto è un po' estremizzato, la stringa infatti arriva da questo codice
    String passwordLunghezzaMassima = StringUtils.repeat("a", 1000000000);
    che manda in errore l'applicazione. Il fatto che Spring Boot 2 abbia questi strumenti è molto buono ma ad un certo punto il server raggiunge comunque i suoi limiti quindi non pensi che sia prudente informare l'utente/l'amministratore in qualche modo?
    Il tuo blog, quando raggiunge 1000000 di visite in contemporanea, forse anche prima ma non ridere ho messo un numero a caso, cosa accade? Hai previsto questo caso limite? Anche solo sapere che le risorse sono venute a mancare a mio avviso è utile.
    Inoltre java non mette proprio niente a disposizione per gestire/risolvere questo problema?
    I cicli try non contemplano questo caso limite.
  • Re: Come difendersi dalle stringhe troppo grandi inserite nel form?

    iBaffiPro ha scritto:


    la stringa infatti arriva da questo codice
    String passwordLunghezzaMassima = StringUtils.repeat("a", 1000000000);
    che manda in errore l'applicazione.
    Ma io continuo a non capire: dove fai tutto questo? Non dirmi "in uno unit-test". Questi test per verificare un uso "malevolo" delle risorse NON vanno fatti con degli unit-test. Anche perché così metti solo in difficoltà l'ambiente di esecuzione degli unit-test.

    E poi se hai l'infrastruttura MVC mock per i test, temo (presumo, probabilmente) che non verifichi quei limiti che ho detto prima di cui ci sono default sensati. Ma non sono sicuro.

    iBaffiPro ha scritto:


    Il fatto che Spring Boot 2 abbia questi strumenti è molto buono ma ad un certo punto il server raggiunge comunque i suoi limiti quindi non pensi che sia prudente informare l'utente/l'amministratore in qualche modo?
    Ti ho già detto prima che Spring Boot applica già dei limiti con i default indicati sopra. Quindi non puoi fare un POST ad un controller passando es. 1GB di roba.

    iBaffiPro ha scritto:


    Il tuo blog, quando raggiunge 1000000 di visite in contemporanea, forse anche prima ma non ridere ho messo un numero a caso, cosa accade? Hai previsto questo caso limite? Anche solo sapere che le risorse sono venute a mancare a mio avviso è utile.
    Inoltre java non mette proprio niente a disposizione per gestire/risolvere questo problema?
    Allora: 1000000 visite contemporanee è un numero enorme, altissimo. Ma metti anche solo 10000.

    Se vuoi davvero gestire carichi elevati, l'approccio è ben diverso. Si deve partire già dall'inizio, PRIMA di sviluppare l'applicazione. Prevedendo ad esempio l'utilizzo di database che possono scalare meglio in "orizzontale" (es. MongoDB ecc...), ipotizzando magari l'utilizzo di meccanismi di caching (es. con Redis o altro) per velocizzare certe operazioni, distribuendo il carico su più macchine mettendo davanti un load-balancer. Ma anche a livello architetturale, facendo magari più microservizi ciascuno orientato ad un singolo aspetto/concetto (es. in un e-commerce fare un microservizio SOLO per generare e inviare le fatture in PDF ai clienti), mettendo in comunicazione i microservizi tramite chiamate HTTP o tramite meccanismi di code (RabbitMQ, Apache Kafka, ecc..).

    Tutto questo richiede tempo, competenze, studio e poi negli aspetti pratici: soldi e personale addetto a gestire poi tutto questo continuamente. E quindi va ben oltre la tua situazione attuale del "provo a fare la mia prima applicazione Spring Boot che vediamo cosa esce...". Ci siamo capiti?

    iBaffiPro ha scritto:


    I cicli try non contemplano questo caso limite.
    I try/catch qui non c'entrano proprio un piffero ..
  • Re: Come difendersi dalle stringhe troppo grandi inserite nel form?

    Ho capito, mi devo accontentare.
    grazie mille
Devi accedere o registrarti per scrivere nel forum
4 risposte