كيفية إرسال ملف ثنائي (.zip) إلى الخادم باستخدام Wininet

-4

أرغب في نقل الملف إلى الموقع باستخدام طريقة POST على موقع php النصي الذي يقبل "ملف المستخدم" والذي يحفظه على الخادم

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);
}

لم يتم إرسال الملف (الطلب غير صحيح) هل يمكنني إصلاحه؟

UPD: هذا الرمز يعمل بشكل صحيح. لكني لا أعرف كيف يمكنني وضع الملف الثنائي في مجموعة من الأحرف. هذا لإرسال ملفات نصية:

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));

}}

1 إجابة

3
افضل جواب

إلى جانب حقيقة أن الرمز يخطئ تمامًا أي خطأ في التحقق من المشكلات التالية التي أراها:

  1. كل مكالمة InternetWriteFile() يتم تمرير مؤشر غير مهيأ كمعلمة أخيرة. القيام بذلك يستدعي سلوكًا غير محدد. كل شيء يمكن أن يحدث منذ ذلك الحين.

    لإصلاح هذا التغيير

    LPDWORD bytesWritten;
    

    أن تكون

    DWORD bytesWritten;
    

    ويمر إلى InternetWriteFile() عنوانه مثل هذا

    InternetWriteFile(..., &bytesWritten);
    
  2. InternetWriteFile() يقال لكتابة char -الصفيف '\0' المنهي عن طريق العمل strlen(data1)+1 .

    لماذا ا؟ غير منطقي. ال 0 ليس جزءًا من الملف ولكنه مجرد قطعة أثرية C لوضع علامة على نهاية السلسلة.

  3. يفرض معيار HTTP أن تنتهي أسطر النص بـ <CR> <LF>. يستخدم الرمز <LF> فقط ( \n ).

    تغيير هذا ليكون \r\n .

  4. ليست قاتلة ، ولكن لا طائل من المسبوكات مثل هذا

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

    C (على عكس C ++) يتحول ضمنيًا من / إلى void مؤشرات. لذا استخدم فقط

    InternetWriteFile(..., data1, ...
    
:مؤلف
فوق
قائمة طعام