|
|
|
![]() |
|
Strumenti |
![]() |
#1 | |
Senior Member
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:
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 17:17. |
|
![]() |
![]() |
![]() |
#2 | |
Senior Member
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; } Codice:
struct req_info { char URI[URL_MAX]; char h_name[NAME_MAX]; struct sockaddr h_addr; }; 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:
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 09:11. |
|
![]() |
![]() |
![]() |
#3 |
Senior Member
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 ![]() Codice:
wait(); ![]() Gica PS: scemo lo sono gia'... ![]()
__________________
gica78r@ncc-1701:~$ tar -c tar: Codardamente mi rifiuto di creare un archivio vuoto ![]() |
![]() |
![]() |
![]() |
#4 |
Senior Member
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...
|
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Mar 2005
Messaggi: 1653
|
Orbene... a distanza di settimane non sono ancora riuscito a scrivere una funzione
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; }
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 ![]() |
![]() |
![]() |
![]() |
#6 |
Senior Member
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; }
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 ![]() |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 23:10.