PDA

Visualizza la versione completa : [C++] Upload file via POST non funziona con immagini


Xadoom
15-03-2011, 08:57
Ho la necessità di implementare l'upload di un file su di un server web in C++, dopo un pò di sbattimento sono riuscito nell'impresa con il seguente codice:


#include <windows.h>
#include <wininet.h>
#include <iostream>


#define ERROR_OPEN_FILE 10
#define ERROR_MEMORY 11
#define ERROR_SIZE 12
#define ERROR_INTERNET_OPEN 13
#define ERROR_INTERNET_CONN 14
#define ERROR_INTERNET_REQ 15
#define ERROR_INTERNET_SEND 16

using namespace std;

int main()
{
// Local variables
static char *filename = "test.txt"; //Filename to be loaded
static char *type = "image/jpg";
static char boundary[] = "pippo"; //Header boundary
static char nameForm[] = "uploadedfile"; //Input form name
static char iaddr[] = "localhost"; //IP address
static char url[] = "test.php"; //URL

char hdrs[255]; //Headers
char * buffer; //Buffer containing file + headers
char * content; //Buffer containing file
FILE * pFile; //File pointer
long lSize; //File size
size_t result;


// Open file
pFile = fopen ( filename , "rb" );
if (pFile==NULL) return ERROR_OPEN_FILE;

// obtain file size:
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);

// allocate memory to contain the whole file:
content = (char*) malloc (sizeof(char)*lSize);
if (content == NULL) return ERROR_MEMORY;

// copy the file into the buffer:
result = fread (content,1,lSize,pFile);
if (result != lSize) return ERROR_SIZE;

// terminate
fclose (pFile);

//allocate memory to contain the whole file + HEADER
buffer = (char*) malloc (sizeof(char)*lSize + 2048);

//print header
sprintf(hdrs,"Content-Type: multipart/form-data; boundary=%s",boundary);
sprintf(buffer,"--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n",boundary,nameForm,filename);
sprintf(buffer,"%sContent-Type: %s\r\n\r\n",buffer,type);
sprintf(buffer,"%s%s\r\n",buffer,content);
sprintf(buffer,"%s--%s--\r\n",buffer,boundary);

//Open internet connection
HINTERNET hSession = InternetOpen("WinSock",INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if(hSession==NULL) return ERROR_INTERNET_OPEN;

HINTERNET hConnect = InternetConnect(hSession, iaddr,INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
if(hConnect==NULL) return ERROR_INTERNET_CONN;

HINTERNET hRequest = HttpOpenRequest(hConnect, (const char*)"POST",url, NULL, NULL, (const char**)"*/*\0", 0, 1);
if(hRequest==NULL) return ERROR_INTERNET_REQ;

BOOL sent= HttpSendRequest(hRequest, hdrs, strlen(hdrs), buffer, strlen(buffer));
if(!sent) return ERROR_INTERNET_SEND;

//close any valid internet-handles
InternetCloseHandle(hSession);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);

return 0;
}


Utilizzando in pratica una lettura da file e l'invio tramite le API di windows.
Il tutto funziona perfettamente con i file di testo, ovviamente sul server c'è uno script PHP che gestisce il salvataggio da file utilizzando la variabile $_POST.
Tuttavia il programma non funziona con i file immagine, in pratica quello che succede è che lato server il file viene creato correttamente ma dentro ci viene scritto solo qualche byte. A naso credo che il problema risieda nella lettura del file (non di testo) e scrittura dello stesso su una stringa; ma non so come aggirarlo.
Suggerimenti?
:ciauz: :ciauz:

Xadoom
15-03-2011, 12:11
Ho risolto implementando una codifica base64 sul contenuto letto da dile prima di concatenarlo alla stringa con la richiesta POST. Ovviamente anche lato server è stato necessario decodificare il testo prima di scrivere il file.
:ciauz: :ciauz:

Loading