Newsgroup: it.comp.lang.perl
Titolo: ritornare al client errore 400

Ho uno script CGI perl che viene richiamato dal client tramite HTTP POST.
All'URL viene aggiunta una query-string per indicare al server quale di una
serie di operazioni deve eseguire.
Dopo aver recuperato il parametro tipo operazione, lo script gestisce le
varie operazioni tramite degli if successivi.
if ($optype eq "append") {
print "Content-type:text/xml\n\n";
 #APPEND optype subroutine
 }
elsif ($optype eq "query") {
 print "Content-type:text/xml\n\n";
#QUERY optype subroutine
 }
elsif ($optype eq "remove") {
print "Content-type:text/xml\n\n";
 #REMOVE optype subroutine
 }
elsif ($optype eq "edit") {
print "Content-type:text/xml\n\n";
 #EDIT optype subroutine
 } else {
 #other optype - error;
 die "unknown optype";
}
In ogni caso sarà richiamata una specifica subroutine. Qualora il tipo
operazione non sia nessuno di quelli previsti il server attualmente
restituisce internal server error (errore 500) in quanto nessun header viene
ritornato (la riga print "Content-type:text/xml\n\n"
 è specifica per ogni operazione).
Se metto l'header anche nel caso di "operazione sconosciuta" il server
ritorna il codice status 200 OK, come se tutto fosse andato per il meglio.
Considerato che l'errore di fatto è generato dalla richiesta effettuata dal
client, mi piacerebbe che il server ritornarre un errore 400, che
rappresenta secondo il protocollo HTTP proprio tale casista : 400 Bad
request (errore sintattico nella richiesta).
Come posso ottenere questo?
Grazie per l'aiuto.
--Gabriele

 serie di operazioni deve eseguire.
Prova
perldoc HTTP::Response
oppure
perldoc HTTP::Message

 request (errore sintattico nella richiesta).
Secondo me restituire 400 in questo caso rappresenterebbe un errore
concettuale. *Mi sembra* che l'errore 400 sia pertinente se il 
problema avviene nel corso della transazione HTTP tra client (il
browser?) e il server web.
Nel tuo caso, mi pare di capire, il client ha provveduto 
correttamente a passare i parametri al server, ma a livello 
applicativo questi dati non vanno bene. Quindi l'errore dovrebbe
essere segnalato a livello applicativo.
ciao,
S.

 essere segnalato a livello applicativo.
Quindi secondo te la risposta 200 OK a livello di HTTP è corretta; nel
content body della risposta HTTP poi lo script dovrà scriverci qualcosa per
identificare che il parametro passato non è valido. Giusto?
--Gabriele

 identificare che il parametro passato non è valido. Giusto?
Sì.
ciao,
S.

 writes:
Gabriele> Ho uno script CGI perl che viene richiamato dal client
Gabriele> tramite HTTP POST.  All'URL viene aggiunta una query-string
Gabriele> per indicare al server quale di una serie di operazioni deve
Gabriele> eseguire.
Gabriele> Dopo aver recuperato il parametro tipo operazione, lo script
Gabriele> gestisce le varie operazioni tramite degli if successivi.
Gabriele> if ($optype eq "append") { print
Gabriele> "Content-type:text/xml\n\n"; #APPEND optype subroutine
Gabriele>  }
Gabriele> elsif ($optype eq "query") { print
Gabriele> "Content-type:text/xml\n\n"; #QUERY optype subroutine
Gabriele>  }
Gabriele> elsif ($optype eq "remove") { print
Gabriele> "Content-type:text/xml\n\n"; #REMOVE optype subroutine
Gabriele>  }
Gabriele> elsif ($optype eq "edit") { print
Gabriele> "Content-type:text/xml\n\n"; #EDIT optype subroutine } else
Gabriele> { #other optype - error; die "unknown optype";
Gabriele> }
Gabriele> In ogni caso sarà richiamata una specifica subroutine.
Gabriele> Qualora il tipo operazione non sia nessuno di quelli
Gabriele> previsti il server attualmente restituisce internal server
Gabriele> error (errore 500) in quanto nessun header viene ritornato
Gabriele> (la riga print "Content-type:text/xml\n\n" è specifica per
Gabriele> ogni operazione).
Gabriele> Se metto l'header anche nel caso di "operazione sconosciuta"
Gabriele> il server ritorna il codice status 200 OK, come se tutto
Gabriele> fosse andato per il meglio.  Considerato che l'errore di
Gabriele> fatto è generato dalla richiesta effettuata dal client, mi
Gabriele> piacerebbe che il server ritornarre un errore 400, che
Gabriele> rappresenta secondo il protocollo HTTP proprio tale casista
Gabriele> : 400 Bad request (errore sintattico nella richiesta).
Gabriele> Come posso ottenere questo?
Gabriele> Grazie per l'aiuto.  --Gabriele
Attenzione: "400 Bad request" si riferisce al livello HTTP,
cioe`  "GET / HTTT/1.0"   causa Bad request. (quella giusta e` con HTTP)
prova a scrivere quella riga nel comando
  telnet tuoserverweb 80
L'errore in richiesta HTTP e` una situazione che *non* deve mai accadere
(ci possono essere degli allarmi che automaticamente riportano questi casi:
 a sistemi anti intrusione, e perfino il browser potrebbe sentirsi
 cosi` in colpa da segnalare l'accaduto al team di sviluppo)
le operazioni del tuo programminino (append, query, remove, edit)
non hanno nulla a che vedere con il trasporto HTTP, devono avere
una propria regolazione degli errori.
Puoi usare la fantasia... se ti piace il rigore con cui sono definiti
gli errori (anche se non lo avevi capito), puoi restituire
"Content-Type: text/plain\n\nErrore 400 Bad Request",
ma se proprio voi leggere sul browser un 400 Bad request molto simile
a quello del caso di errore HTTP (non credere che sia una sol. pulita),
puoi ancora ottenerla con qualcosa tipo
print <<"EOT";
Content-Type: text/html
<HTML><HEAD><TITLE>400 Bad Request</TITLE>
</HEAD><BODY><H1>Bad Request</H1>
Your browser sent a request that this server could not understand.<P>
The request line contained invalid characters following the protocol string.<P>
<P><HR><ADDRESS>Programma gesrione xml/$ver</ADDRESS>
</BODY></HTML>
EOT;
rimane una differenza importante e giusta con l'errore http
cioe` il server in quel vero caso inserisce anche la stringa
"HTTP/1.1 400" nell'header della risposta, e come saprai l'header
serve al browser e non fa parte di cio` che viene visualizzato
all'utente, anche per questo e` sbagliato inserire errori
impropri. (introdurresti un errore nell'implementazione del protocollo)
Tantopiu` se lo script girasse un giorno su httpS (e con operazioni di
edit e remove dovrebbe essere anche il caso).
Saluti,
MAR     
http://mar.i.am/co/
-- 
x(t),y(t) = th(3t-34.5)*e^[-(3t-34.5)^2]/2-4.3+e^(-1.8/t^2)/(.8*atg(t-
3)+2)(t-1.8)-.3th(5t-42.5),(1.4e^[-(3t-34.5)^2]+1-sgn[|t-8.5|-.5]*1.5*
|sin(pi*t)|^[2e^(-(t-11.5)^2)+.5+e^(-(.6t-3.3)^2)])/(.5+t)+1  ; 0<t<14