-4

I want to transfer the file to the site using the POST method on the php site the script accepting "userfile" and which saves it on the server

void SendFile()
{
  const char hdrs[] = "Content-Type: multipart/form-data; boundary=--------071418204214402\n"
  "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";

  char* data1 = "----------071418204214402\n"
  "Content-Disposition: form-data; name=\"userfile\"; filename=\"file.zip\"\n"
  "Content-Type: text/plain\n"
  "Content-Transfer-Encoding: binary\n\n";

  char* filecontent = "Hello World!";       // Simulated the contents of the file with a string.

  char* data2 = "\n----------071418204214402--\n";

  char* allstr = calloc(strlen(data1) + strlen(filecontent) + strlen(data2) + 1, 1);
  strcat(allstr, data1);
  strcat(allstr, filecontent);
  strcat(allstr, data2); 

  HINTERNET hSession = InternetOpen("MyAgent", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
  HINTERNET hConnect = InternetConnect(hSession, "crazra94.beget.tech", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
  HINTERNET hRequest = HttpOpenRequest(hConnect, "POST", "/send.php", NULL, NULL, NULL, 0, 1);

  HttpAddRequestHeaders(hRequest, hdrs, -1, HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD);
  INTERNET_BUFFERS bufferIn;
  LPDWORD bytesWritten;
  memset(&bufferIn, 0, sizeof(INTERNET_BUFFERS));
  bufferIn.dwStructSize = sizeof(INTERNET_BUFFERS);
  bufferIn.dwBufferTotal = strlen(data1) + strlen(filecontent) + strlen(data2)+1;
  HttpSendRequestEx(hRequest, &bufferIn, NULL, HSR_INITIATE, 0);
  InternetWriteFile(hRequest, (const void*)data1, strlen(data1)+1, bytesWritten);
  InternetWriteFile(hRequest, (const void*)filecontent, strlen(filecontent)+1, bytesWritten); // File
  InternetWriteFile(hRequest, (const void*)data2, strlen(data2)+1, bytesWritten);
  HttpEndRequest(hRequest, NULL, HSR_INITIATE, 0);
}

The file is not sent (the request is not correct) can I fix it?

UPD: This code is work correct. But i dont know how i can put the binary file to the array of chars. This is for send text files:

void SendFile()

{

const unsigned char hdrs[] = "Content-Type: multipart/form-data; boundary=--------071418204214402\n"
                    "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";

unsigned char* data1 = "----------071418204214402\r\n"
    "Content-Disposition: form-data; name=\"userfile\"; filename=\"test2.txt\"\r\n"
    "Content-Type: text/plain\r\n"
    "Content-Transfer-Encoding: binary\r\n\r\n";

unsigned char* filecontent = "Hello World!";

unsigned char* data2 = "\r\n----------071418204214402--\r\n";

    unsigned char* allstr = calloc(strlen(data1) + strlen(filecontent) + strlen(data2) + 1, sizeof(unsigned char));
    strcat(allstr, data1);
    strcat(allstr, filecontent);
    strcat(allstr, data2); 

HINTERNET hSession = InternetOpen("MyAgent", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
HINTERNET hConnect = InternetConnect(hSession, "crazra94.beget.tech", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
HINTERNET hRequest = HttpOpenRequest(hConnect, "POST", "/send.php", NULL, NULL, NULL, 0, 1);
HttpSendRequest(hRequest, hdrs, strlen(hdrs), allstr, strlen(allstr));

}

  • Does the real code also completely miss all error checking? If yes, add it along with any sane logging of errors and re-test. – alk Jul 15 '18 at 10:57
  • The code is compiled and executed without errors. But the file does not come to the server. How can I get the latest error information? (I use the GCC compiler) – BLACK CODE Jul 15 '18 at 10:59
  • Also *if* you'd used a C compiler these casts `(const void*)` would no be necessary. Which compiler do you use? – alk Jul 15 '18 at 10:59
  • GCC for windows. C compiler. – BLACK CODE Jul 15 '18 at 11:00
  • When mentioning "*error checking*" I am *not* referring to compile/line time errors, but to error conditions arising while the program runs. Most (if not all) of the functions you are using might very well fail and indicated this in one or the other way. I recommend reading completely the documentation to all the functions you use. – alk Jul 15 '18 at 11:02
  • 3
    You can't know whether or not there are errors because you don't test for them – David Heffernan Jul 15 '18 at 11:58
  • The code in the original post is like the virtual expression of blindness. If I was as harsh as I sound IRL, I'd sue for eye damage. – ImmortaleVBR Jul 15 '18 at 20:06

1 Answers1

3

Aside the fact that the code completely misses any error checking the following issues I see:

  1. Each call to InternetWriteFile() gets passed an uninitialised pointer as last parameter. Doing so invokes undefined behaviour. Everything can happen from then on.

    To fix this change

    LPDWORD bytesWritten;
    

    to be

    DWORD bytesWritten;
    

    and pass to InternetWriteFile() its address like this

    InternetWriteFile(..., &bytesWritten);
    
  2. InternetWriteFile() is told to write the char-array's '\0'-terminator by doing strlen(data1)+1.

    Why? This does not make sense. The 0 is not part of the file but just a C artefact to mark the end of the string.

  3. The HTTP standard mandates that text lines need to end by <CR><LF>. The code uses just <LF> (\n).

    Change this to be \r\n.

  4. Not fatal, but useless are the castings like this

    InternetWriteFile(..., (const void*)data1, ...
    

    C (as opposed to C++) implicitly converts from/to void-pointers. So just use

    InternetWriteFile(..., data1, ...
    
alk
  • 69,737
  • 10
  • 105
  • 255