You are viewing bit8bug

Previous Entry | Next Entry

HTTP POST file with WinSock (Example 2)


#include <winsock2.h>
#include <Windows.h>
#include <stdio.h>
#define BUF_SIZE 1024*1024*12
#pragma comment(lib, "Ws2_32.lib")

struct sockaddr_in clientSAddr;

int postFile(LPCTSTR, SOCKET *, LPSTR content_type);

int main(int argc, char **argv)
{
    WORD iResult;
    char *fileName = "C:\\Users\\Eddie\\AppData\\Local\\Lotus\\Notes\\Data\\user.id";
    LPVOID fileBuffer;
    
    WCHAR ufileName[100];
    
    MultiByteToWideChar(CP_ACP, MB_COMPOSITE, fileName, -1, ufileName, 100);
    

    SOCKET clientSock = INVALID_SOCKET;
    /* Socket Library DataStructure */
    WSADATA WSStartData; 
    /* Initialize the WS Library Version 2.0 */
    WSAStartup(MAKEWORD (2,0), &WSStartData);

    postFile(ufileName, &clientSock, "application/octet-stream");
    return 0;
}

int postFile(LPCTSTR lpFileName, SOCKET *clientSock, LPSTR content_type) {
    DWORD iResult;
    LPVOID retBuffer;
    CHAR strRequest[380];
    DWORD bytesIn;
    DWORD totalBytes = 0;
    HANDLE hIn = CreateFile(lpFileName, GENERIC_READ, (FILE_SHARE_READ | FILE_SHARE_WRITE), NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hIn == INVALID_HANDLE_VALUE)
    {
        return NULL;
    }
    LPVOID buffer = VirtualAlloc(NULL, BUF_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    /* the following while doesn't make much sense*/
    while( ReadFile(hIn, buffer, BUF_SIZE, &bytesIn, NULL) && bytesIn > 0 )
    {
        totalBytes += bytesIn;
    }
    retBuffer = VirtualAlloc(NULL, totalBytes, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    CopyMemory(retBuffer, buffer, totalBytes);
    CloseHandle(hIn);
    /* ignore the Content-Length for now !*/
    /* ignore the name & extension, you can deal with that later */
    LPVOID requestBuffer;
    
    LPSTR sendRequest = "POST /upload.php HTTP/1.1\r\nHost: localhost\r\nContent-Type: multipart/form-data; boundary=---------------------------552335022525\r\nContent-Length: 7078100\r\n\r\n-----------------------------552335022525\r\nContent-Disposition: form-data; name=\"userfile\"; filename=\"bookmark.nsf\"\r\nContent-Type: ";
    LPSTR trailer = "\r\n-----------------------------552335022525--\r\n";
    lstrcpyA(strRequest, sendRequest);
    lstrcatA(strRequest, content_type);
    lstrcatA(strRequest, "\r\n\r\n");
    printf("%s\n", strRequest);
    printf("total bytes %d", totalBytes);
    DWORD total_allocation = totalBytes + strlen(strRequest) + strlen(trailer);
    requestBuffer = VirtualAlloc(NULL, total_allocation, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    CopyMemory(requestBuffer,strRequest, strlen(strRequest)); 
    /* using CopyMemory to ignore null bytes as terminators */
    CopyMemory((PBYTE)requestBuffer+strlen(strRequest),retBuffer, totalBytes);
    CopyMemory((PBYTE)requestBuffer+strlen(strRequest)+totalBytes, trailer, strlen(trailer));

    *clientSock = socket(AF_INET, SOCK_STREAM, 0);
    memset(&clientSAddr, 0, sizeof(clientSAddr));
    clientSAddr.sin_family = AF_INET;
    clientSAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    clientSAddr.sin_port = htons(80);
    iResult = connect(*clientSock, (struct sockaddr *)&clientSAddr,sizeof(clientSAddr));
    /* this while may need a fix */
    DWORD total_send =0;
    iResult = 1;
    printf ("total buffer to send is %d\n", total_allocation);
    while ( iResult > 0)
    {
        printf("remaining till now %d\n", total_allocation-total_send);
        iResult = send(*clientSock, (CCHAR *)requestBuffer, total_allocation-total_send, 0);
        total_send += iResult;
        requestBuffer = (PBYTE)requestBuffer+iResult;
        printf("sent till now %d\n", total_send);
    }
    
    if (iResult == SOCKET_ERROR) 
    {
        printf("send failed: %d\n", WSAGetLastError());
        closesocket(*clientSock);
        WSACleanup();
        return 2;
    }
    printf("Bytes Sent: %ld\n", total_send);
    closesocket(*clientSock);
    VirtualFree(requestBuffer, total_allocation, MEM_RELEASE);
    VirtualFree(buffer, BUF_SIZE, MEM_RELEASE);
    return 1;
}

Tags:

Comments

( 1 comment — Leave a comment )
bit8bug
Jan. 1st, 2013 10:59 am (UTC)
Additional notes
to compile you can use cl.exe main.cpp -DUNICODE -D_UNICODE
I'm ignoring file name and extension and the file size in the HTTP post header , because the upload was successful
( 1 comment — Leave a comment )

Profile

bit8bug
bit8bug

Latest Month

January 2013
S M T W T F S
  12345
6789101112
13141516171819
20212223242526
2728293031  

Page Summary

Powered by LiveJournal.com
Designed by yoksel