Newsgroup: it.comp.java
Titolo: Servlet & Connessioni Persistenti

La teoria dice che per ottenere una connessione HTTP persistente occorre che
il server comunichi al client (browser) la lunghezza del documento. Ciò è
possibile inviando l'intesatzione http Content-Length.
Ammesso che il server (e il client) supporti le connessioni persistenti è
facile verificare ciò provando a richiedere una pagina HTML attraverso una
sessione telnet. Nella risposta ottenuta comparirà proprio l'intestazione
Content-Length con la relativa dimensione.
Una servlet per la sua natura dinamica non può sapere quanto sarà la sua
dimensione, precludendo al web server di inviare l'intestazione
Content-Length.
A questo problema, così dice la teoria, si può ovviare "bufferizzando" la
risposta della Servlet.
Cio è possibile utilizzando il metodo setBufferSize() della classe
HttpServletResponse.
Tuttavia, richiamando via telnet la Servlet nelle intestazioni non compare
l'intestazione Content-Lenght, quando invece per la teoria grazie alla
bufferizzazione il web server avendo la possibilità di stabilire la
dimensione dell'output, prima che sia inviato, avrebbe dovuto e potuto
inserire la sopra citata intestazione.
Qualcuno sa illuminarmi?
Io utilizzo Tomcat 3.3.1a come standalone.
Grazie infinite.
Mr. Deckard

 Io utilizzo Tomcat 3.3.1a come standalone.
Illuminarti non posso, ma da quello che tu dici (onestamente non sono mai
andato a fondo della cosa) mi viene da dire che il comportamento del Servlet
Container non sia diverso sia che la risposta sia bufferizzata, sia che non
lo sia.
Ti dico questo perchè un paio d'anni fa mi scontrai con un bug di Explorer
(e di chi senno'?) che aveva problemi di "comprensione" se lo stream che
riceveva era inferiore agli 8Kb e se non era dichiarata la sua dimensione.
Con le pagine HTML queso non lo si notava, ma all'epoca stavo generando PDF
on the fly e, in quel caso, il pidieffe diventava illeggibile.
Usavo Tomcat 3.2 e, per risolvere il problema, ero stato costretto a
definire il Contnt-Length "a manina" prima di inviare il flusso.
Non credo, quindi, che Tomcat (forse neanche le più recenti 4.x e la futura
5.x) si occupino di gestire la dimensione dello stream che invii, nemmeno se
setti il buffer a 0.  (Magari mi sbaglio, però...)
Ripeto, non essendomi mai sbattuto più di tanto, se haoi proprio necessità
di inviare il Content-Length, potresti probabilmente "rivolgerti" ad un
Filter che si occupa di "cachare" lo stream da inviare e, prima di inviarlo,
ne calcola la dimensione, ne setta il content length e poi lo invia.
    Regards,
        Kazuma
--
I've got nothing against God. It's his fan club I can't stand.
Alex "Kazuma" Garbagnati, 
http://www.kazuma.net
EJB & Tomcat jGuru FAQ Manager, 
http://www.jGuru.com
Tutor "Progetto Scuole", 
http://www.JIA.it
Java Italian Association - SUN - MIUR

 ha scritto nel messaggio
news:je%Ja.116020$Ny5.3...@twister2.libero.it...

Caro Kazuma,
grazie per la tua precisione e clerità. Beh, a dire il vero non ho una
stretta necessità di inviare la suddetta intestazione. Più che altro era il
tentativo di ottimizzare l'invio dell'output e verificare la teoria studia,
già che ci sono! ;-)
Beh, sulla documentazione che ho in mio possesso pare che il buffering delle
risposte permetterebbe al web server di impostare l'intestazione più volte
citata.
Però, a quanto pare, le tue considerazioni sembrano suffragate dalla
pratica.
Possibile che dipenda da qualche settaggio del web server?
Ancora grazie.
Mr. Deckard

 Possibile che dipenda da qualche settaggio del web server?
Sai, nel caso di Tomcat Standalone, la parte Web Server è gestita dal
connettore HTTP. Quello di Tomcat 3.x è abbastanza vecchiotto, magari quello
usato da Tomcat 4.1.x (Coyote Http Connector) è "più meglio".
Puoi provare a vedere settando l'attributo "bufferSize" a 0 e vedere come si
comporta (se manda o meno il Content-Lenght).
(ps: Se fai questa prova, poi fammelo sapere, che magari genero una FAQ pure
su jGuru.)
Nel caso in cui Tomcat sia "dietro" un altro Web Server... bisognerebbe
vedere come il protocollo comunica al Web Server. Se quest'ultimo attende
l'intero stream, probabilmente il COntent-Lenght lo aggiunge lui...
(ps: Se fai anche questa prova, idem come sopra...)



Ciao,
Humz... hai aggiunto
Connection: Keep-Alive
nella tua richiesta?
Tra l'altro, se la risposta è <= a 4k la bufferizzazione avviene 
automaticamente, vedi 
http://www.io.com/~maus/HttpKeepAlive.html
Eventualmente, al posto di ingrandire il buffer(la tua riposta potrebbe 
non starci ancora...) puoi scrivere il documento in un 
ByteArrayOutputStream, farti dare la dimensione e metterla nel 
content-length, ed in fine spedire il contenuto tramite 
byteArrayStream.writeTo(response.getOutputStream())
Marco

 Puoi provare a vedere settando l'attributo "bufferSize" a 0 e vedere come
si
Beh, allora ora io ho provato a modificare la servlet come dici tu, settando
a 0 il bufferSize (se ho capito cosa intendevi).
Ma almeno con la versione attuale di Tomcat (3.3.1a) il Content-Lenght non
viene restituito.
Adesso mi trovo una postazione estremamente lenta, non posso scaricare una
versione più aggiornata deTomcta, appena reperisco una coneesione veloce
faccio la prova!
Scusa se ho frainteso qualcosa!


Questa è una buona idea! Infatti nell'altro post, che ho appena inviato a
Kazuma, mi domandavo se c'era un qualcosa tipo BufferedOutputStream ma per
le Servlet. Quasto mi sembra un buon indizio.
Grazie anche a te!
Mr. Deckard

 
Bhe, se usi telnet e non mandi il keep-alive, per il server sei un 
cliente che non supporta la persistenza della connessione e dunque non 
fa il lavoro che tu vorresti.
Marco


Ops, scusa... questo l'avevo trascurato... č vero! E come trasmetto via
telnet il keep-alive?
Grazie mille...
Mr. Deckard

 ha scritto nel messaggio
news:3ef8...@news.swissonline.ch...

Allora ho fatto me dici tu e invio Proxy-Connection: Keep-Alive
Ma niente, è sempre più probabile che abbia ragione kazuma, il web server
non manda niente...
Mr. Deckard

 
Ho guardato un po di documentazione(è un po che non ho a che fare con 
queste cose e non ricordo molto..) e ho visto che con http 1.1 l'header 
keep-alive non serve a niente visto che ogni connessione è mantenuta 
aperta di default, a meno che non si specifichi il contrario con
Connection: close
Se non hai messo negli headers della tua richiesta telnet la versione 
http non so quale sia il comportamento atteso, comunque il keep-alive va 
definito come
Connection: Keep-Alive
e non come
Proxy-Connection: Keep-Alive
(che forse va pure bene ma non l'ho mai usato).
Cmq, se non erro, prova a mettere nella richiesta che fai tramite telnet 
i seguenti headers e dovrebbe funzionare
GET /ilTuoServlet HTTP/1.1
Connection: Keep-Alive
Host: 
www.ilTuoHost.com
In teoria dovrebbe funzionare anche senza specificare il keep-alive ma 
non ho voglia d provare  ;)
Marco

 ha scritto nel messaggio
news:3ef8c331$1...@news.swissonline.ch...

Grazie marco,
sì alla fine ero arrivato alle stesse conclusioni, ho provato... ma
niente...
Sigh!
Mr. Deckard

Mr. Deckard
Mi chiedo....
Se queste tue considerazioni partono dalle specifiche HTTP 1.1, ed il
connettore Http 1.1 (anzi, i connettori, visto che sono due, il Coyote
Connector e quello standard) non si comporta secondo le specifiche, si
potrebbe pensare di segnalarlo come bug alla jakarta foundation.
Se lo vuoi fare e se vuoi, posso darti una mano...
	regards,
		Kazuma
---


Prova questo, dovrebbe andare.
http://power2youth.com:8080/examples/servlets/sunexamples/KeepAliveServlet.java
Marco

 ha scritto nel messaggio
news:3ef8...@news.swissonline.ch...

Ciao Marco,
grazie. Ma su questa Servlet non ho dubbi che funzioni. Infatti da una
veloce lettura del codice vedo che calcola da sé la lunghezza dell'output e
poi assegna  l'intestazione con il metodo setContentLength, passando la
dimensione calcolata.
OK, ma il problema che avevo sollevato era leggermente diverso.
Scondo la documentazione (a dir il vero non ufficiale del protocollo HTTP e
di Tomcat, ma penso autorevole) si ha che
il Buffering delle risposte offre un modo semplice per evitare il precalcolo
della lunghezza del contenuto.
Una servlet, dunque, può usare il buffering per calcolare automaticamente la
lunghezza del contenuto.
Secondo i miei test, malgrado effettui il buffering il web server (tomcat
3.3.1) non restiutisce mai l'intestazione Content-Length.
Ciao e grazie ancora
Mr. Deckard


 Ciao Kazuma,
probabilmente hai ragione. Se mi aiuti sarei ben lieto. L'unica cosa, come
avrai notato, prima di dire forse sono in presenza di un bug o voluto
cercare di verificare il più possibile, in quanto la mia esperienza non è
così vasta da permettermi tanta disinvoltura. Per questo se mi hai aiuto
sarò ben lieto e grato.
Allora in primo luogo occorre secondo me verificare l'attendibilità della
fonte o una mia sbagliata interpretazione e verificare se i miei test sono
corretti.
Magari ti passo i miei semplici test per posta e ti descrivo le mie modalita
di verifica.
Allora nella mia documentazione, che reputo attendibile, si dichiara quanto
segue:
"...Il Buffering delle risposte offre un modo semplice per evitare il
precalcolo della lunghezza del contenuto.
Una servlet, dunque, può usare il buffering per calcolare automaticamente la
lunghezza del contenuto.
....
....
Se tutto il corpo della risposta è contenuto nel buffer, il server può
impostare automaticamente l'intestazione Content-Length della risposata
(anche se non è tenuto a farlo)..."
A dire il vero non comprendo cosa significhi "anche se non è tenuto a
farlo.."
Tieni presente che la documentazione è basta su Tomcat e tutte le
argomentazioni sono fatte sulle specifice  Servlet API 2.2 (e in parte 2.3).
Ora il mio web server come posso notare anche dalle intestazioni di risposta
mi specifica che è allineato con JSP 1.1 e Servlet 2.2
Allora detto questo come procediamo?
Ciao e grazie
Mr. Deckard

 
Ho provato anche io. Ho notato che con telnet gli unici 2 casi che 
funzionano sono quelli dove si forza il calcolo del content-length ossia
GET /servlet/sunexamples.KeepAliveServlet?runType=short%20head HTTP/1.1
Host: 
power2youth.com:8080
GET /servlet/sunexamples.KeepAliveServlet?runType=long%20head HTTP/1.1
Host: 
power2youth.com:8080
mentre gli altri (cioè, come giustamente dici tu, quando la lunghezza 
viene calcolata automaticamente tramite buffering) non funzionano(la 
connessione viene chiusa).
Specificare il keep-alive non cambia nulla e dunque mi viene il forte 
sospetto che il problema risieda nel fatto di fare la richiesta tramite 
telnet.
Non ho idea del perchè, ma credo che non riconosca il client come capace 
di mantenere la persistenza del socket e per questa ragione chiuda la 
connessione..
Se scopri la ragione fammelo sapere che sono curioso.
Ciao
Marco


OK, Marco! grazie per aver messo a disposizione il tuo tempo per questo mio
problemino.
Beh adesso almeno ho la certezza che le mie verifiche fossero corrette.
Il fatto è a questo punto capire se i web server (e quindi anche tomcat)
prevede e implementa tale specifica riportata o e solo una possibilità
lascita poi a chi implementa il web server specifico.
Ciao
Mr. Deckard
P.S. Se scopro/scopriamo qlc ti faccio sapere certamente...


Come dici tu, bisogna verificare l'attendibilità, ma soprattutto le
specifiche.
Stiamo parlando di un protocollo Http1.1, quindi prova a dare un
occhiata alle specifiche che sono su w3c (da qualche parte).
Credo che questo sia l'obbligato punto di partenza.
	Regards,


 ha scritto nel messaggio
news:spjifvsl3e6v33kap...@4ax.com...

Cia Kazuma,
ti ho invuato una e-mail al tuo indirizzo personale!
Ciao