Проблема с закачкой файла

Тема в разделе "WASM.NETWORKS", создана пользователем AlexCasual, 13 ноя 2011.

  1. AlexCasual

    AlexCasual New Member

    Публикаций:
    0
    Регистрация:
    3 авг 2009
    Сообщения:
    120
    Пытаюсь передать файл по http :

    Код (Text):
    1. void HTTP_UPLOAD_REQUEST(char* Server,int Port,char* uploadscript,char* boundary,char* filetoup,char* data)
    2. {
    3.     WSADATA wsaData;
    4.     WSAStartup( MAKEWORD( 1,1 ), &wsaData );
    5.    
    6.     SOCKET Socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
    7.        
    8.     LPHOSTENT hostEntry;
    9.     hostEntry = gethostbyname( Server );//Get ip from Server by hostname
    10.        
    11.     sockaddr_in addr;
    12.     addr.sin_family = AF_INET;
    13.     addr.sin_addr   = *((LPIN_ADDR)*hostEntry->h_addr_list);
    14.     addr.sin_port   = htons( Port );
    15.        
    16.     if(SOCKET_ERROR == connect( Socket, (LPSOCKADDR) &addr, sizeof(struct sockaddr) ))
    17.     {
    18.         return;
    19.     }
    20.  
    21.     char header[512]="";
    22.     sprintf( header, "POST %s HTTP/1.0\r\nContent-Type: multipart/form-data; boundary=%s\r\nContent-Length: %u\r\n\r\n",uploadscript, boundary,2*strlen(data));
    23.        
    24.     char* body=new char[strlen(data)+4000];
    25.     sprintf( body, "--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n\r\n %s\r\n--%s\r\n",boundary,"data",filetoup,data,boundary);
    26.  
    27.     char * Request=new char[strlen(header)+strlen(body)+strlen(data)];
    28.     sprintf( Request, "%s%s", header,body );    
    29.  
    30.     int bytessend =send( Socket, Request, strlen(Request), 0 );
    31.  
    32.     char rec[256];
    33.     recv(Socket, rec, sizeof(rec), 0);
    34.  
    35.     printf("%s", rec);
    36.  
    37.     system("pause");
    38.     closesocket(Socket);
    39.  
    40. }
    Соответтсвующий php-скрипт,который обрабатывает загрузку :

    Код (Text):
    1. <?php
    2. if ($_FILES["file"]["error"] > 0)
    3.   {
    4.   echo "Error: " . $_FILES["file"]["error"] . "<br />";
    5.   }
    6. else
    7.   {
    8.   echo "Upload: " . $_FILES["file"]["name"];
    9.   }
    10. ?>
    Делаю вызов :

    Код (Text):
    1.  HTTP_UPLOAD_REQUEST("localhost",80,"/upload.php","64286573548714285675865","test.txt","test");
    Ответ от localhost :


    HTTP/1.1 200 OK
    Date: Sat, 12 Nov 2011 22:18:19 GMT
    Server: Apache/2.2.4 (Win32) mod_ssl/2.2.4 OpenSSL/0.9.8k PHP/5.3.3
    X-Powered-By: PHP/5.3.3
    Content-Length: 8
    Connection: close
    Content-Type: text/html; charset=windows-1251

    Upload: ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦


    То есть файл не загружен...Правильно ли я понимаю,что C-код загрузки отработал верно (на что указывает HTTP/1.1 200 OK),а PHP-скрипт неверный? Или я вообще жестоко туплю?Может кто-нибудь натолкнуть на решение проблемы?
     
  2. AlexCasual

    AlexCasual New Member

    Публикаций:
    0
    Регистрация:
    3 авг 2009
    Сообщения:
    120
    Если не трудно,напишите как должен выглядеть реально рабочий HHT POST header для закачки файла...
     
  3. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    AlexCasual

    Отправь файл браузером, отснифай ваершарком, сделай var_dump($_FILES) - все вопросы отпадут.
     
  4. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    AlexCasual
    Ну вот, рабочий кажется, спионерил в сети гда-то ...
    Код (Text):
    1. // by SlyBit (c) 07.2008 /SendFileToServer.cpp/
    2.  
    3. #include "winsock2.h"
    4. #include <windows.h>
    5.  
    6. #pragma comment(lib, "Ws2_32.lib")
    7. #pragma comment(linker, "/ENTRY:Entry")
    8.    
    9. #define HOST_NAME "test.ru"
    10. #define FILE_NAME "test_file.rar"
    11. #define URL_NAME  "upload.php"
    12.  
    13. BOOL WINAPI SendDataToServer(PVOID pData, DWORD dwDataSize, WORD wPort, PCHAR pAddress)
    14. {
    15.     SOCKET      ConnectSocket;
    16.     sockaddr_in ClientService;
    17.     INT         nSendBytes = 0;
    18.    
    19.     if(INVALID_SOCKET == (ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))) {
    20.         return 0;
    21.     }
    22.    
    23.     ClientService.sin_family = AF_INET;
    24.     ClientService.sin_port = htons(wPort);
    25.     ClientService.sin_addr.s_addr = inet_addr(pAddress);
    26.    
    27.     if(SOCKET_ERROR == connect(ConnectSocket, (SOCKADDR*)&ClientService, sizeof(ClientService))) {
    28.         closesocket(ConnectSocket);
    29.         return 0;
    30.     }
    31.    
    32.     if(SOCKET_ERROR == (nSendBytes = send(ConnectSocket, (PCHAR)pData, dwDataSize, 0))) {
    33.         closesocket(ConnectSocket);
    34.         return 0;
    35.     }
    36.    
    37.     closesocket(ConnectSocket);
    38.    
    39.     return nSendBytes;
    40. }
    41.    
    42. BOOL WINAPI GetIpByHostName(PCHAR pHostName, PCHAR pIp, DWORD dwIpSize)
    43. {
    44.     hostent *pHosten;
    45.    
    46.     if(!(pHosten = gethostbyname(pHostName))) {
    47.         return 0;
    48.     }
    49.    
    50.     if(lstrlen(inet_ntoa(*(in_addr*)*pHosten->h_addr_list)) > dwIpSize) {
    51.         return 0;
    52.     }
    53.    
    54.     lstrcpy(pIp, inet_ntoa(*(in_addr*)*pHosten->h_addr_list));
    55.    
    56.     return 1;
    57. }
    58.    
    59. BOOL WINAPI SendFileToServer(PCHAR pFileName, PCHAR pAddress, PCHAR pUrl)
    60. {
    61.     PVOID   pFile;
    62.     DWORD   dwFileSize, dwRetSize;
    63.     CHAR    szIp[17];
    64.     PCHAR   pSendData;
    65.     HANDLE  hFile;
    66.    
    67.     if(!GetIpByHostName(pAddress, szIp, 17)) {
    68.         return 0;
    69.     }
    70.    
    71.     if(INVALID_HANDLE_VALUE == (hFile = CreateFile(pFileName, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0))) {
    72.         return 0;
    73.     }
    74.     if(0xFFFFFFFF == (dwFileSize = GetFileSize(hFile, 0))) {
    75.         CloseHandle(hFile);
    76.         return 0;
    77.     }
    78.    
    79.     if(!(pSendData = (PCHAR)VirtualAlloc(0, dwFileSize+300, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE))) {
    80.         VirtualFree(pFile, 0, MEM_RELEASE);
    81.         return 0;
    82.     }
    83.    
    84.     wsprintf(pSendData, "POST /%s?file_name=%s HTTP/1.1\r\nHost: %s\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-length: %i\r\n\r\nupload_file=",
    85.         pUrl, pFileName, pAddress, dwFileSize+strlen("upload_file="));
    86.    
    87.     if(!ReadFile(hFile, pSendData+strlen(pSendData), dwFileSize, &dwRetSize, 0)) {
    88.         VirtualFree(pSendData, 0, MEM_RELEASE);
    89.         CloseHandle(hFile);
    90.         return 0;
    91.     }
    92.     CloseHandle(hFile);
    93.    
    94.     if(!SendDataToServer(pSendData, strlen(pSendData), 80, szIp)) {
    95.         VirtualFree(pSendData, 0, MEM_RELEASE);
    96.         return 0;
    97.     }
    98.  
    99.     VirtualFree(pSendData, 0, MEM_RELEASE);
    100.  
    101.     return 1;
    102. }
    103.    
    104. VOID WINAPI Entry()
    105. {  
    106.     WSAData wsaData;
    107.    
    108.     if(NO_ERROR != WSAStartup(MAKEWORD(2,2), &wsaData)) {
    109.         ExitProcess(0);
    110.     }
    111.      
    112.     if(SendFileToServer(FILE_NAME, HOST_NAME, URL_NAME)) {
    113.         MessageBox(0, "SendFileToServer Ok", 0, 0);
    114.     } else {
    115.         MessageBox(0, "SendFileToServer Error", 0, 0);
    116.     }
    117.    
    118.     ExitProcess(0);
    119. }
    И пхп часть
    Код (Text):
    1. <?php Error_Reporting(E_ALL & ~E_NOTICE);
    2.  
    3. function SaveDataToFile($log_data, $file_name)  
    4. {
    5.     $file = basename($file_name);
    6.     $filehandle = fopen($file, "wb");
    7.     fputs($filehandle, $log_data);
    8.     fclose($filehandle);
    9. }
    10.  
    11. SaveDataToFile($_POST['upload_file'], $_GET['file_name']);
    12.  
    13. ?>
     
  5. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    AlexCasual

    А вообще такой говнокод постить мог бы и постыдиться. Хоть бы код в порядок привел. Почему strlen(data) умножается на два для Content-Length?

    Код (Text):
    1. int bytessend =send( Socket, Request, strlen(Request), 0 );
    Никто не гарантирует что за один send запрос уйдет целиком.
     
  6. samuraishowdown

    samuraishowdown New Member

    Публикаций:
    0
    Регистрация:
    6 мар 2011
    Сообщения:
    70
    Ещё можно использовать CURL. (самый оптимальный вариант если не каждый байт на счету. можно скомпилить "http only" сотня две лишних килобайт а то и меньше).

    Для передачи файлов post не очень хорошо, лучше put. Для post бывают ограничения на max длину запроса, max использования памяти.

    А чё файлы только текстовые?
     
  7. valentin_p

    valentin_p New Member

    Публикаций:
    0
    Регистрация:
    11 фев 2011
    Сообщения:
    382
    проблемы бывают с переносами (db 13,10), с их количеством.
    Код (Text):
    1. POST /post.php HTTP/1.1
    2. Host: some.ru
    3. User-Agent: sss
    4. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    5. Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
    6. Accept-Encoding: gzip, deflate
    7. Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
    8. DNT: 1
    9. Connection: keep-alive
    10. Referer: http://some.ru/index.php
    11. Content-Type: multipart/form-data; boundary=---------------------------481414423196
    12. Content-Length: 204
    13. -----------------------------481414423196
    14. Content-Disposition: form-data; name="myfile"; filename="1.txt"
    15. Content-Type: text/plain
    16.  
    17. в файле перносов нету
    18. -----------------------------481414423196--
    после баунда - перенос и он входит в сумму Content-Length, она дает в десятичной кстати (есть вариант ответа сервера с хекс-значением в другом формате..без content length) Сумма должна быть верной! боунд -уникальным, хотя это мене строго чем переносы.