Newsgroup: it.comp.lang.c++
Titolo: mettere in una stringa il body di un messaggio http

Ciao a tutti,
mi occorrerebbe una funzione il cui prototipo concettualmente sia
 *string getBody(const char* buf)* 
Questa funzione dovrebbe individuare il body di un messaggio http e lo
restituisca in una stringa. 
Ogni messaggio HTTP consiste infatti di un header e di un body, separati da
una riga vuota.
Quindi devo prendere tutto quello che segue la riga vuota e copiarlo in una
stringa. 
Idee? Spero di sì .. grazie. 
Intanto quello che sono riuscito a mettere insieme è questo: 
unsigned int linelen(const char* line) { 
  return strcspn(line, "\n\0"); 
}
/* La funzione strcspn() calcola la lunghezza del segmento iniziale della
stringa che consiste interamente di caratteri diversi da \n\0 */
string getBody(const char* buf) {
  const char* p = buf;
  int len;
  while (len = linelen(p) > 0)
    p += len + 2; 
  len += 2;
 return string(p);
}
Sembra funzionare, ma non mi fido molto delle mie capacità di
programmazione :)

 programmazione :)
Ehm ehm, devo avvertirti che non è detto affatto che ci sia una riga 
vuota fra head e body: </head> e <body> possono stare benissimo sulla 
stessa riga. Sono i tag che decidono, non il fatto di essere su righe 
diverse.
Se ti affidi alle righe, come minimo resti fregato in tutti quei casi in 
cui l'autore ha usato una utility di oscurazione HTML per rendere la 
vita difficile a chi studia il sorgente delle sue pagine (o 
semplicemente per  diminuire il numero di byte da trasmettere).

 semplicemente per  diminuire il numero di byte da trasmettere).
Grazie. Ma allora in questo caso come fare ?

 vuota fra head e body:
L'OP parlava di header e body HTTP, che sono in effetti separati da una 
riga vuota. I tag HTML non c'entrano nulla.
L'unca cosa che va, invece, tenuta presente è che il terminatore di riga 
nel protocollo HTTP è rappresentato da una sequenza <CR><LF>, non un 
singolo <LF>. 
Max

 singolo <LF>. 
\n\0 ... cosa c'è che non va ?


'\0' non serve. Se scrivi "\n", il NULL in fondo c'è già implicitamente. Se
ne aggiungi uno, non cambia nulla. Però '\n' è un singolo <LF>, mentre
-come ho detto- il terminatore di riga HTTP è <CR><LF>. Se, però, il tuo
codice funziona, vuol dire che l'input che analizzi (cioè 'buf') usa un
semplice LF come terminatore di riga (diversamente non troveresti mai una
riga vuota, ma al massimo una riga contentente un singolo '\r').
Max

 Max
Ciao
Matic

 riga vuota, ma al massimo una riga contentente un singolo '\r').
ho omesso che sto programmando sotto Linux. .. forse c'è differenza ?
Mi pare che con \n sia sufficiente. può essere ?

 programmazione :)
Ciao
Matic

 carattere \n).
Infatti io avevo concluso dicendo: "diversamente [cioè se c'è  anche il
<CR>] non troveresti mai una riga vuota, ma al massimo una riga contentente
un singolo '\r'".
Max

 Mi pare che con \n sia sufficiente. può essere ?
Come ho detto, dipende da come è fatto il tuo input. Non mi pare che ci
voglia molto a capire come sono i terminatori di riga. Il protocollo HTTP
stabilisce che ci voglia una sequenza <CR><LF>. Poi, se questa sequenza è
stata ridotta a un semplice '\n', lo puoi sapere solo tu.
Il fatto che stai lavorando su Linux non è rilevante. La questione non
riguarda la sequenza di fine riga dei file testuali (dove c'è in effetti
una differenza tra sistemi *nix, Win o Mac).
Max

 
Come giustamente mi fa notare Max M, secondo l'HTTP non trovi mai una
linea vuota se controlli su '\n', (il carattere '\r' c'è sempre) quindi
qui diventerebbe:
	while( (len = linelen(p)) > 1 )
Ciauz
M`

Ragazzi,
grazie mille; in effetti non funzionava sempre, in quanto prendeva
spesso anche righe dell'header, che non gli competono, appunto.
Adesso sembra funzionare ... Tuttavia mi chiedo se funzionerà in tutti
i casi .. Voi mi avete fatto notare giustamente la questione del
<CR><LF> ... ma allora come fareste voi?
Quello che devo fare è aprire una socket e ricevere un messaggio http
da un server web.
Tuttavia ho notato che su ogni socket viene trasferito un numero max di
bytes ( < 1500 bytes ... forse ha qualcosa a che fare con la mtu?) e
quindi per ricevere una risposta http completa, devo restare in ascolto
finchè la read della socket non restituisca -1 (cioè finchè il
server non chiude).
La read che già uso è fatta così :
int read (socket, buffer, sizeof(buffer)); // dove buffer è char
buffer[MAX]
Il problema che ho adesso è accumulare in un unico buffer quello che
arriva dai vari singoli buffer.
Il mio prof dice che devo fare un' allocazione dinamica ... in che modo
?

 arriva dai vari singoli buffer.
int sock_read(
  int           sockfd,
  char         *buf,
  const size_t  count
) {
  /* Reads from a socket.  Synopsis: the same of read, see read(3) */
  size_t bytes_read = 0;
  int    this_read;
  while (bytes_read < count) {
    do {
      this_read = read(sockfd, buf, count-bytes_read);
    } while (this_read < 0   &&   errno == EINTR);
    if (this_read < 0) {
      return this_read;
    } else if (this_read == 0) {
      return bytes_read;
    }
    bytes_read += this_read;
    buf        += this_read;
  }
  return count;
}
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Dept. of Physics, Univ. of Padova, Italy              ROT13: 
ybe...@cq.vasa.vg

Maurizio,
non so come ringraziarti per il tuo interessamento.
Forse mi farò vivo con qualche obiezione ... cmq grazie ancora