Torna indietro   Hardware Upgrade Forum > Software > Programmazione

OVHcloud Summit 2025: le novità del cloud europeo tra sovranità, IA e quantum
OVHcloud Summit 2025: le novità del cloud europeo tra sovranità, IA e quantum
Abbiamo partecipato all'OVHcloud Summit 2025, conferenza annuale in cui l'azienda francese presenta le sue ultime novità. Abbiamo parlato di cloud pubblico e privato, d'intelligenza artificiale, di computer quantistici e di sovranità. Che forse, però, dovremmo chiamare solo "sicurezza"
Un mostro da MSI: QD-OLED WQHD a 500 Hz con AI Care e DisplayPort 2.1a
Un mostro da MSI: QD-OLED WQHD a 500 Hz con AI Care e DisplayPort 2.1a
Abbiamo potuto mettere le mani in anteprima sul nuovo monitor MSI dedicato ai giocatori: un mostro che adotta un pannello QD-OLED da 26,5 pollici con risoluzione 2560 x 1440 pixel, frequenza di aggiornamento fino a 500 Hz e tempo di risposta di 0,03 ms GtG
DJI Neo 2 in prova: il drone da 160 grammi guadagna il gimbal e molto altro
DJI Neo 2 in prova: il drone da 160 grammi guadagna il gimbal e molto altro
DJI aggiorna la sua linea di droni ultraleggeri con Neo 2, un quadricottero da 160 grammi che mantiene la compattezza del predecessore ma introduce una stabilizzazione meccanica a due assi, sensori omnidirezionali e un sistema LiDAR
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 20-06-2005, 15:46   #1
Gica78R
Senior Member
 
L'Avatar di Gica78R
 
Iscritto dal: Mar 2005
Messaggi: 1653
[C] Proxy: ricevere ed inoltrare una pagina web

Ciao!

Ho un problema nel far funzionare correttamente il proxy http che sto scrivendo: quando un client (generalmente un browser) si connette al mio proxy, quest'ultimo riceve la richiesta in questo formato:
Quote:
GET http://www.hwupgrade.it/ HTTP/1.1
Host: www.hwupgrade.it
User-Agent: Mozilla/5.0 (X11; U; Linux i686; rv:1.7.3) Gecko/20041020 Firefox/0.10.1
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Proxy-Connection: keep-alive
dalla quale estrae il nome dell'host, che usera' poi come parametro nella funzione gethostbyname() per ricavare l'indirizzo IP dell'host. Fin qui tutto ok. Successivamente inizializzo un nuovo socket ed effettuo la connessione all'host di cui sopra, tramite la funzione connect(), inoltrando la stessa richiesta ricevuta dal proxy ma rimuovendo il nome dell'host dalla prima riga (cosi' come descritto nell'RFC 2616 sul protocollo HTTP), in modo che dopo GET vi sia il path assoluto della pagina richiesta.
Il problema e' che il server che risponde tenta di redirigere la connessione de qualche altra parte, e io non so gestire la cosa. Non esiste un modo diverso per fare questa ricezione/inoltro?

Grazie,
Gica
__________________
gica78r@ncc-1701:~$ tar -c
tar: Codardamente mi rifiuto di creare un archivio vuoto

Ultima modifica di Gica78R : 20-06-2005 alle 18:17.
Gica78R è offline   Rispondi citando il messaggio o parte di esso
Old 23-06-2005, 02:36   #2
Gica78R
Senior Member
 
L'Avatar di Gica78R
 
Iscritto dal: Mar 2005
Messaggi: 1653
Ho fatto qualche cambiamento nella parte relativa alla risoluzione dei nomi... Non c'entra nulla con il problema precedente, ma poiche' ho visto che la funzione gethostbyname() e' ormai deprecata, l'ho sostituita con getaddrinfo() (standard POSIX 1003.1-2001). Solo che adesso succede qualcosa di inaspettato. Non vi posto tutto il codice, vi descrivo sommariamente cosa faccio:
1) Nella funzione main() inizializzo i socket per le connessioni, e metto in ascolto il socket associato al server;
2) quando arriva una nuova connessione, genero un processo figlio che si occupa di gestirla, mentre il padre torna in attesa di nuove connessioni;
3) il processo figlio legge sul socket la richiesta inviata dal browser (per ora supporta solo le GET), ne estrae l'URL richiesto e il nome dell'host dove reperirlo, quindi invoca la funzione id_gethostbyname() (opera mia) per la risoluzione dei nomi a dominio, che e' la seguente:
Codice:
/* Function: id_gethostbyname()
 *
 * Purpose: try to get the IPv4 address of the host whose name is passed
 * with the info->h_name string.
 *
 * Parameters:
 *  - struct req_info *info: a pointer to a (preallocated) structure of
 *    req_info type, in which will be stored the response information.
 *
 * Return value:
 *
 *    0 on success, in which case the function returns the IP address
 *    in the h_addr field of info structure passed in;
 *
 *    -1 on error.
 */

int
id_gethostbyname(struct req_info *info)
{
   int ret; /* return value */

   struct addrinfo hints; /* hints for the research */
   struct addrinfo *res; /* research result */

   /* hints initialization: we need an IPv4 address to
    * use in a SOCK_STREAM TCP socket */

   hints.ai_flags=0;
   hints.ai_family=PF_INET;
   hints.ai_socktype=SOCK_STREAM;
   hints.ai_protocol=0;

   ret=getaddrinfo(info->h_name, NULL, &hints, &res);

   if (ret!=0)
     {
        printf("Resolution error: %s\n", gai_strerror(ret));
        return -1;
     }


   while (res!=NULL)
     {
        if (res->ai_family==PF_INET)
          {
             info->h_addr.sa_family=res->ai_addr->sa_family;
             strncpy(info->h_addr.sa_data, res->ai_addr->sa_data, 14);
             break;
          }
        else res=res->ai_next;
     }
   freeaddrinfo(res);
   return 0;
}
La definizione della struttura req_info e' la seguente:
Codice:
struct req_info
{
   char URI[URL_MAX];
   char h_name[NAME_MAX];
   struct sockaddr h_addr;
};
e la uso semplicemente per memorizzare i vari campi che mi interessano.
Quando invoco la funzione id_gethostbyname(), passo come argomento l'indirizzo della variabile info , nel cui campo h_name c'e' il nome dell'host di cui voglio l'indirizzo.
Ho eseguito il programma anche con il debugger (gdb), e la cosa strana e' che il processo figlio (che invoca la funzione incriminata) termina correttamente ma, subito dopo la sua terminazione, termina anche il padre e mi viene stampato questo strano messaggio:
Quote:
./proxy: symbol lookup error: ./proxy: undefined symbol: close, version GLIBC_2.0
dove proxy e' il nome dell'eseguibile...

Qualche idea? Anche non strettamente correlata alla funzione, ma piu' al comportamento del programma e all'errore stampato.

Grazie,
Gica

PS: non fate troppo caso al mio inglese maccheronico...
__________________
gica78r@ncc-1701:~$ tar -c
tar: Codardamente mi rifiuto di creare un archivio vuoto

Ultima modifica di Gica78R : 23-06-2005 alle 10:11.
Gica78R è offline   Rispondi citando il messaggio o parte di esso
Old 23-06-2005, 10:31   #3
Gica78R
Senior Member
 
L'Avatar di Gica78R
 
Iscritto dal: Mar 2005
Messaggi: 1653
Risolto... come al solito l'idiozia si era impadronita di me
Solo una cosa, pero'... Io gli voglio tanto bene a R. Stallman pero' gcc e' un po' stranuccio: se in un programma metto una chiamata a una funzione che vuole 3 argomenti, ma io ce ne metto 2, il compilatore mi dice piu' o meno "too few arguments in function vattelapesca"; la funzione wait() vuole un argomento, ma se nel programma scrivo
Codice:
wait();
il compilatore non mi dice nulla... e io divento scemo!

Gica

PS: scemo lo sono gia'...
__________________
gica78r@ncc-1701:~$ tar -c
tar: Codardamente mi rifiuto di creare un archivio vuoto
Gica78R è offline   Rispondi citando il messaggio o parte di esso
Old 23-06-2005, 10:52   #4
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Forse la wait nell'implementazione ha un valore di deafult per l'argomento...
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 09-08-2005, 23:43   #5
Gica78R
Senior Member
 
L'Avatar di Gica78R
 
Iscritto dal: Mar 2005
Messaggi: 1653
Orbene... a distanza di settimane non sono ancora riuscito a scrivere una funzione
  • breve
  • intelligente
  • brillante
  • corretta
  • elegante
per leggere una richiesta http proveniente da un browser e diretta al proxy server. Una delle versioni funzionanti, ma oscene, che ho fatto e' la seguente:
Codice:
int leggi_richiesta(int sock, char *buffer, int dim)
{
    char *pattern="\r\n\r\n";
    char c;
    int termina=0;
    int i=0;
    
    memset(buffer, 0, dim);
    
    while (!termina)
    {
        if (recv(sock, &c, 1, 0)<0)
            return -1;
        buffer[i]=c;
        ++i;
        
        if ((i>=4)&&(strncmp(buffer+i-4, pattern, 4)==0))
            termina=1;
        if ((!termina)&&(i>=dim-1))
            return -1;
    }
    buffer[i]='\0';
    
    return 0;
}
In pratica, poiche' una richiesta http termina con una doppia sequenza di CR-LF (cioe' "\r\n\r\n"), io leggo dal socket (sock) finche' non si verifica una delle seguenti condizioni:
  • ho ricevuto la sequenza "\r\n\r\n"
  • il num di caratteri letti ha raggiunto il limite
  • la funzione recv fallisce
Uno dei problemi che si presentano e' che, se sul socket si riceve qualcosa di diverso da una richiesta http, che magari e' lunga meno di 4 caratteri, la funzione resta in attesa indefinitamente...
Sbirciando tra i sorgenti di un server http molto semplice, ho visto che l'autore risolve il problema ponendo il socket in modalita' non bloccante, in modo che la recv ritorni sempre (anche se non ci sono dati sul socket), e facendo in modo che, se sul socket non si leggono dati per piu' di 30 secondi, la funzione di lettura termini ugualmente.
Prescindendo da questa soluzione (che non mi ispira molto), sapreste suggerirmi un modo per rendere meno oscena la mia funzione?

Grazie
__________________
gica78r@ncc-1701:~$ tar -c
tar: Codardamente mi rifiuto di creare un archivio vuoto
Gica78R è offline   Rispondi citando il messaggio o parte di esso
Old 10-08-2005, 10:58   #6
Gica78R
Senior Member
 
L'Avatar di Gica78R
 
Iscritto dal: Mar 2005
Messaggi: 1653
Funzione per leggere una richiesta http da un socket

Ho perfezionato la funzione precedente affiche' funzioni in tutti i casi:
Codice:
int leggi_richiesta(int sock, char *buffer, int dim)
{
    char *pattern="\r\n\r\n"; // Sequenza di uscita
    char c;
    int timeout=30;
    int i=0;
    time_t istante_ultimo_dato_ricevuto = time(NULL);
    
    memset(buffer, 0, dim);
    
    /* Pongo il socket in modalita'non bloccante */
    if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0)
          return -1;
    
    do 
    {
        while (recv(sock, &c, 1, 0) < 0)
            if (time(NULL) - istante_ultimo_dato_ricevuto > timeout)
                return -1;
        
        istante_ultimo_dato_ricevuto = time(NULL);
        
        buffer[i] = c;
        i++;
        
        if ( (i>=4) && (strncmp(buffer+i-4, pattern, 4)==0) )
        {
            buffer[i] = '\0';
            return 0;
        }
        
    } while (i < dim-1);
    
    return -1;
}
La funzione ritorna se si verifica una delle seguenti condizioni:
  • e' stata ricevuta la sequenza di uscita ("\r\n\r\n")
  • si e' superata la capacita' del buffer (dim)
  • sono passati piu' di 30 secondi dall'ultimo carattere letto sul socket
Credo che la funzione sia corretta e faccia tutto quello che deve fare, ma non mi soddisfa ancora la forma. Suggerimenti?
Alla faccenda del socket non bloccante ci avevo gia' pensato; l'idea del timeout, invece, l'ho presa guardando i sorgenti di questo progetto.
__________________
gica78r@ncc-1701:~$ tar -c
tar: Codardamente mi rifiuto di creare un archivio vuoto
Gica78R è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


OVHcloud Summit 2025: le novità del cloud europeo tra sovranità, IA e quantum OVHcloud Summit 2025: le novità del cloud...
Un mostro da MSI: QD-OLED WQHD a 500 Hz con AI Care e DisplayPort 2.1a Un mostro da MSI: QD-OLED WQHD a 500 Hz con AI C...
DJI Neo 2 in prova: il drone da 160 grammi guadagna il gimbal e molto altro DJI Neo 2 in prova: il drone da 160 grammi guada...
L'IA "seria" di Appian è diversa: inserita nei processi e rispetta dati e persone L'IA "seria" di Appian è divers...
Polestar 3 Performance, test drive: comodità e potenza possono convivere Polestar 3 Performance, test drive: comodit&agra...
AWS Transform si evolve: agenti IA per m...
I social network hanno stancato gli ital...
Star Citizen supera i 900 milioni di dol...
Netflix ha eliminato la funzione Cast pe...
L'IA è una bolla e scoppier&agrav...
Un rapporto collega i data center di Ama...
Troppa concorrenza per Cherry (quella de...
Entro il 2035 la Cina vuole costruire de...
Tineco in super sconto: ultimo giorno di...
La Cina creerà una costellazione ...
I veicoli elettrici emettono radiazioni ...
Stai per acquistare una PS5? Attento al ...
iPhone 17 Pro Max finalmente disponibile...
Apple, Sony, Bose, Beats, Sennheiser, CM...
Arriva il Raspberry Pi 5 da 1 GB, ma por...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 23:47.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v