Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Richiesta http

Linguaggi e sistemi

Moderatori: Foto UtentePaolino, Foto Utentefairyvilje

0
voti

[1] Richiesta http

Messaggioda Foto Utentedaniele1996 » 15 ott 2021, 22:54

Sto sviluppando un web server, e sono arrivato al punto di upload dei file.
Ho sviluppato un programma che accetta la richiesta e restituisce una risposta da me prefissata da me. e un esempio di richiesta http con upload è questa:

Codice: Seleziona tutto
POST /upload.php HTTP/1.1\r\n
Host: 127.0.0.1:8083\r\n
Connection: keep-alive\r\n
Content-Length: 429\r\n
Cache-Control: max-age=0\r\n
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90"\r\n
sec-ch-ua-mobile: ?0\r\n
Upgrade-Insecure-Requests: 1\r\n
Origin: null\r\n
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryyAgwyAoOAfBRKxZd\r\n
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\n
Sec-Fetch-Site: cross-site\r\n
Sec-Fetch-Mode: navigate\r\n
Sec-Fetch-User: ?1\r\n
Sec-Fetch-Dest: document\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7\r\n\r\n
------WebKitFormBoundaryyAgwyAoOAfBRKxZd\r\n
Content-Disposition: form-data; name="the_file"; filename="miofile.txt"\r\n
Content-Type: text/plain\r\n\r\n
riga 1\n
riga 2\n
riga 3\n
\n
\n
riga 6\n
riga 7\n
\n
\n
riga 10\n
\r\n
------WebKitFormBoundaryyAgwyAoOAfBRKxZd\r\n
Content-Disposition: form-data; name="the_file1"; filename="miofile.txt"\r\n
Content-Type: text/plain\r\n\r\n
riga 1\n
riga 2\n
riga 3\n
\n
\n
riga 6\n
riga 7\n
\n
\n
riga 10\n
\r\n
------WebKitFormBoundaryyAgwyAoOAfBRKxZd--\r\n




la richiesta è divisa in due segmenti: la parte della richiesta (ottenuta con una prima chiamata a funzione :
Codice: Seleziona tutto
recv(clientfd, recvstr, 10KB,0);

e l'upload richiamando di nuovo la recv questa volta il buffer viene allocato temporaneamente e la sua dimensione viene fornita in "Content-Lenght: 429\r\n" e quindi viene allocata e riempita con la successiva recv.

fin qua tutto a posto, dividendo la stringa e memorizzandola in una lista i singoli elementi vengono memorizzati e visualizzati correttamente.
Codice: Seleziona tutto
tmphead = searchRequestField(req->requestrx,"Content-Length:");
   if(tmphead != NULL){
      sscanf(tmphead->str,"Content-Length: %ld",&req->upload_size);
      req->upload = malloc(req->upload_size * sizeof(char));
      create_upload(req);
      //printf(req->upload);
      //size_t intestazione = 0;
      //size_t iniziofile = 0;
      //size_t finefile = 0;
      /*for(size_t i = 0; i < req->upload_size; i++){
         if(*(req->upload+i) == '\r' && *(req->upload+i+1) == '\n' ){

         }
      }
      */
      size_t a = 0;
      size_t b = 0;
      void * tmpptr;
      void * tmpptr1;
      size_t next = 0;
      /*
      FILE *fp;


      char * namefile;//in a list
      char * fieldname;
*/
      struct upload_request *uptmp;
      //strcat(tmp->upload,"------WebKitFormBoundaryyAgwyAoOAfBRKxZd\r\n");
      //strcat(tmp->upload,"Content-Disposition: form-data; name=\"the_file\"; filename=\"miofile.txt\"\r\n");
      //strcat(tmp->upload,"Content-Type: text/plain\r\n\r\n");
      tmpptr1 = malloc(req->upload_size);
      memcpy(tmpptr1,req->upload,req->upload_size);
      //printf("%s\n",(char *)tmpptr);
      req->upreq = (struct upload_request *)malloc(sizeof(struct upload_request));
      uptmp = req->upreq;
      uptmp->fieldname    = (char *) malloc(50 * sizeof(char));
      uptmp->name       = (char *) malloc(50 * sizeof(char));
      uptmp->ctype       = (char *) malloc(50 * sizeof(char));
      uptmp->cdisposition = (char *) malloc(50 * sizeof(char));
      uptmp->next = NULL;
      do{
         //if(next == 0){
            token = strtok((char *)(tmpptr1+next),"\r\n");
         /*}else{
            token = strtok(NULL,"\r\n");
            printf("->>%s<<-",token);
            break;
         }*/
         //token = strtok(NULL,"\r\n");

         token = strtok(NULL," ");
         token = strtok(NULL,";");
         strcpy(uptmp->cdisposition,token);

         //sscanf(token,"Content-Disposition: %s\0",uptmp->cdisposition);
         //strcpy(uptmp->cdisposition,token + strlen("Content-Disposition: "));
         token = strtok(NULL,"\"");
         token = strtok(NULL,"\"");
         strcpy(uptmp->fieldname,token);
         token = strtok(NULL,"\"");
         token = strtok(NULL,"\"");
         //printf("%s\n",token);
         strcpy(uptmp->name,token);
         token = strtok(NULL," ");
         token = strtok(NULL,"\r\n\r\n");
         strcpy(uptmp->ctype,token);
         /*while(1);
         //sscanf(token,"Content-Disposition: %s",uptmp->cdisposition);
         //sscanf(token,"Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n",uptmp->fieldname,uptmp->name);
         token = strtok(NULL,"\r\n\r\n");
         sscanf(token,"Content-Type: %s",uptmp->ctype);

         */
         printf("Field Name: %s\n",uptmp->fieldname);
         printf("File Name: %s\n",uptmp->name);
         printf("Content Type: %s\n",uptmp->ctype);
         printf("Content Disposition: %s\n",uptmp->cdisposition);

         /*token = strtok(NULL,"\n\r\n");//\n\r\n
         uptmp->file = malloc(strlen(token));
         strcpy(uptmp->file,token);
         printf("File: \n\n\n %s \n\n\n",(char *)uptmp->file); not working
         */

         memcpy(tmpptr1,req->upload,req->upload_size);

         tmpptr = strstr(tmpptr1+next,"\r\n\r\n");
         a = tmpptr - (tmpptr1) + 4 ;
         //printf("%s\n",tmpptr1+a);
         printf("%ld\n",a);
         tmpptr = strstr(tmpptr1+next+a,"\n\r\n");
         printf("%p",tmpptr);
         b = (tmpptr - tmpptr1) - a + 1;//+1;
         printf("%ld\n",b);
         uptmp->file = malloc(b);
         memcpy(uptmp->file,tmpptr1+next+a,b);
         printf("File:\n%s",(char *)uptmp->file);
         token = strtok((char *)(tmpptr1+next+b+a),"\r\n");
         //if(token == NULL)break;
         memcpy(tmpptr1,req->upload,req->upload_size);
         next = next + (token - (char *)tmpptr1)+2;
         printf("\n\n%s\n",token);

         uptmp->next = (struct upload_request *)malloc(sizeof(struct upload_request));
         uptmp = uptmp->next;
         uptmp->fieldname    = (char *) malloc(50 * sizeof(char));
         uptmp->name       = (char *) malloc(50 * sizeof(char));
         uptmp->ctype       = (char *) malloc(50 * sizeof(char));
         uptmp->cdisposition = (char *) malloc(50 * sizeof(char));
         uptmp->next = NULL;
         //next = 1;
         //
         //printf("\n\n%s\n",token);
         //token = strtok(NULL,"\r\n");

         }while(next < req->upload_size);
         while(1);

Come è possibile notare nell'upload la stringa fino al content type va divisa e a questo confine continua con il file, quindi va calcolato l'inizio del file, e questa parte di codice lo svolge correttamente, sscanf non funziona bene, però comunque ho risolto con strtok(..).
Arrivato alla seconda esecuzione il programma crasha
Codice: Seleziona tutto
server@server:~/Documenti/eclipse_workspace_c1/request_parser/Debug$ ./request_parser
POST /upload.php? HTTP/1.1
Host: 127.0.0.1:8083
Connection: keep-alive
Content-Length: 429
Cache-Control: max-age=0
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90"
sec-ch-ua-mobile: ?0
Upgrade-Insecure-Requests: 1
Origin: null
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryyAgwyAoOAfBRKxZd
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Cookie: Test1=Testata; Test2=Testata; Test3=Testata
Accept-Language: it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7
fname=aaa&lname=bbb





Field Name: the_file
File Name: miofile.txt
Content Type: text/plain
Content Disposition: form-data
143
0x556d424c293d47
File:
riga 1
riga 2
riga 3


riga 6
riga 7


riga 10


------WebKitFormBoundaryyAgwyAoOAfBRKxZd
Content-Disposition: form-data; name="the_file1"; filename="miofile.txt"
Content-Type: text/plain

riga 1
riga 2
riga 3


riga 6
riga 7


riga 10

------WebKitFormBoundaryyAgwyAoOAfBRKxZd--

Field Name: the_file1
File Name: miofile.txt
Content Type: text/plain
Content Disposition: form-data
336
(nil)-93927752083919
Errore di segmentazione (core dump creato)
server@server:~/Documenti/eclipse_workspace_c1/request_parser/Debug$


Mi domando: esiste un metodo migliore per scrivere questo codice?
Tipo, strtok non rischia di crashare se mando dati?
altrimenti devo ricorrere al for che scansiona tutta l'area di memoria...
Avatar utente
Foto Utentedaniele1996
610 3 8 11
Sostenitore
Sostenitore
 
Messaggi: 1554
Iscritto il: 29 ago 2011, 11:29

0
voti

[2] Re: Richiesta http

Messaggioda Foto Utentealev » 16 ott 2021, 8:02

Che linguaggio di programmazione stai usando?
Avatar utente
Foto Utentealev
5.993 2 9 12
free expert
 
Messaggi: 6281
Iscritto il: 19 lug 2010, 14:38
Località: Altrove

1
voti

[3] Re: Richiesta http

Messaggioda Foto UtenteGioArca67 » 16 ott 2021, 12:02

memcpy
strstr
printf
malloc
Tutte le istruzioni terminate da ;
...sarà Algol? o BCPL?
Avatar utente
Foto UtenteGioArca67
4.565 4 6 9
Master EY
Master EY
 
Messaggi: 4588
Iscritto il: 12 mar 2021, 9:36

0
voti

[4] Re: Richiesta http

Messaggioda Foto Utentealev » 16 ott 2021, 13:16

Boh, so solo che sembra fatto con qualche linguaggio interpretato :shock:

'Ste cose sarebbe sempre meglio usare linguaggi compilabili in linguaggio macchina, al massimo a runtime
Avatar utente
Foto Utentealev
5.993 2 9 12
free expert
 
Messaggi: 6281
Iscritto il: 19 lug 2010, 14:38
Località: Altrove

0
voti

[5] Re: Richiesta http

Messaggioda Foto Utentenicsergio » 16 ott 2021, 13:39

È PHP.
Avatar utente
Foto Utentenicsergio
4.701 3 9 13
Master
Master
 
Messaggi: 938
Iscritto il: 1 gen 2020, 16:42

-1
voti

[6] Re: Richiesta http

Messaggioda Foto Utentealev » 16 ott 2021, 14:12

Mi pare una scelta perfetta: un webserver in PHP per pubblicare un'applicazione in PHP :roll: :shock:
Sicuramente, è un ottimo metodo per imparare la programmazione in PHP
Avatar utente
Foto Utentealev
5.993 2 9 12
free expert
 
Messaggi: 6281
Iscritto il: 19 lug 2010, 14:38
Località: Altrove

1
voti

[7] Re: Richiesta http

Messaggioda Foto Utentefairyvilje » 16 ott 2021, 16:08

Gente, quello è C.

Edit: tutti i punti negativi di questo mondo non cambieranno il fatto che sia C :).
"640K ought to be enough for anybody" Bill Gates (?) 1981
Qualcosa non ha funzionato...

Lo sapete che l'arroganza in informatica si misura in nanodijkstra? :D
Avatar utente
Foto Utentefairyvilje
15,0k 4 9 12
G.Master EY
G.Master EY
 
Messaggi: 3047
Iscritto il: 24 gen 2012, 19:23

0
voti

[8] Re: Richiesta http

Messaggioda Foto Utentefairyvilje » 16 ott 2021, 16:12

In risposta all'OP, quello è ciò che succede con un linguaggio di programmazione che ti lascia lavorare coi puntatori in modo... discutibile.
PHP sarebbe molto più sicuro in questo contesto :D. Realisticamente se è una tua scelta, ti consiglio di valutare rust per questo tipo di applicazioni. Se è per un esame, buona fortuna!

Ti consiglio di installare valgrind che un profiler per i problemi legati alla memoria. Dovrebbe aiutarti ad isolare il problema. Ha una curva di apprendimento, specialmente per capire il senso dei suoi log, ma è uno strumento insostituibile :).
"640K ought to be enough for anybody" Bill Gates (?) 1981
Qualcosa non ha funzionato...

Lo sapete che l'arroganza in informatica si misura in nanodijkstra? :D
Avatar utente
Foto Utentefairyvilje
15,0k 4 9 12
G.Master EY
G.Master EY
 
Messaggi: 3047
Iscritto il: 24 gen 2012, 19:23

1
voti

[9] Re: Richiesta http

Messaggioda Foto UtenteGioArca67 » 16 ott 2021, 16:34

nicsergio ha scritto:È PHP.

Non è PHP.
Il PHP non è tipizzato e le variabili iniziano con $
Mentre nello stralcio pubblicato è evidente la dichiarazione del tipo.
Avatar utente
Foto UtenteGioArca67
4.565 4 6 9
Master EY
Master EY
 
Messaggi: 4588
Iscritto il: 12 mar 2021, 9:36

0
voti

[10] Re: Richiesta http

Messaggioda Foto Utentenicsergio » 16 ott 2021, 17:11

GioArca67 ha scritto:Il PHP non è tipizzato e le variabili iniziano con $
Mentre nello stralcio pubblicato è evidente la dichiarazione del tipo.

Hai ragione, ho guardato troppo velocemente :ok:
Avatar utente
Foto Utentenicsergio
4.701 3 9 13
Master
Master
 
Messaggi: 938
Iscritto il: 1 gen 2020, 16:42

Prossimo

Torna a PC e informatica

Chi c’è in linea

Visitano il forum: Nessuno e 6 ospiti