0

I am uploading a file with Wininet to a Sharepoint server with HTTP PUT. However, even when I specify a file name with .xlsx extension, I got on the Sharepoint server a file which says it's named .xlsx, but when downloading it, it gets a .zipextension. Also, on Sharepoint, the file does not get the little Excel icon next to it, but a more generic icon. I have tried every combination of setting the Content-type ("mime-type") with HttpAddRequestHeaders and at HttpSendRequest I could come up with.

The code below uploads the file, but Sharepoint gets the content-type wrong:

static int upload_file_to_sharepoint(LPCSTR filename, LPCSTR server, LPCSTR location)
{
    HINTERNET hIntrn = InternetOpenA(
        "magic", 
         INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY,
         NULL,
         NULL,
         0
    );
    if (!hIntrn)
        return printf("No Internet connection: %li.\n", GetLastError());

    HINTERNET hConn = InternetConnectA(
        hIntrn, 
        server,
        INTERNET_DEFAULT_HTTPS_PORT,
        NULL,
        NULL,
        INTERNET_SERVICE_HTTP,
        0,
        NULL
    );

    if (!hConn)
        return printf("Connection to update server failed: %li.\n", GetLastError());

    DWORD dwOpenRequestFlags =
        INTERNET_FLAG_KEEP_CONNECTION |
        INTERNET_FLAG_NO_COOKIES |
        INTERNET_FLAG_NO_CACHE_WRITE |
        INTERNET_FLAG_NO_UI |
        INTERNET_FLAG_RELOAD;

    PCSTR rgpszAcceptTypes[] = {
        "text/*",
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        NULL
    };

    HINTERNET hReq = HttpOpenRequestA(
        hConn,
        "PUT",
        location,
        "HTTP/1.1",
        NULL,
        rgpszAcceptTypes,
        dwOpenRequestFlags,
        NULL
    );


    HANDLE hFile = CreateFileA(
        filename,
        GENERIC_READ,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL
    );

    if (NULL == hFile) {
        ExitProcess(1);
    }

    HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
    if (NULL == hMap) {
        ExitProcess(1);
    }

    LPVOID lpvFile = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);

    DWORD dwFileSize = GetFileSize(hFile, NULL);

    CHAR mimetype[1024];
    sprintf(
        mimetype,
        "Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    //"Content-Type: application/vnd.ms-excel\r\n"
    );

    if (!HttpAddRequestHeadersA(hReq, mimetype, -1, HTTP_ADDREQ_FLAG_REPLACE)) {
        printf("Failed adding mime header\n");
    }

    if (!HttpSendRequestA(
        hReq,
        NULL,// "Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        0, //-1,
        lpvFile,
        dwFileSize)) {
        printf("HttpSendRequest failed: %li.\n", GetLastError());
    }

    UnmapViewOfFile(lpvFile);
    CloseHandle(hMap);
    CloseHandle(hFile);

    printf("Uploaded file to http://%s%s\n", server, location);

    return 0;
}

I captured the headers with Fiddler, got this:

PUT http://x.com/CENSORED/a.xslx HTTP/1.1
Accept: text/*, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Content-Disposition: attachment; filename="a.xlsx"
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
User-Agent: magic
Host: censored
Content-Length: 772303
Connection: Keep-Alive
Pragma: no-cache


HTTP/1.1 200 OK
Cache-Control: private,max-age=0
Content-Length: 0
Expires: Tue, 15 Sep 2015 08:43:16 GMT
Last-Modified: Wed, 30 Sep 2015 08:43:16 GMT
ETag: "{0DC262D0-83AE-489A-90CD-EB23B284A3B3},14"
Server: Microsoft-IIS/7.5
SPRequestGuid: 6aba173e-41db-4b14-b7df-7714c54db282
X-SharePointHealthScore: 0
ResourceTag: rt:0DC262D0-83AE-489A-90CD-EB23B284A3B3@00000000014
Public-Extension: http://schemas.microsoft.com/repl-2
X-Powered-By: ASP.NET
MicrosoftSharePointTeamServices: 14.0.0.7145
X-MS-InvokeApp: 1; RequireReadOnly
ServerName: Xcensored
Date: Wed, 30 Sep 2015 08:43:16 GMT
4
  • You don't seem to be providing the filename to the server, maybe that has something to do with it? Commented Sep 30, 2015 at 4:31
  • @JonathanPotter, that is done AFAIK in HttpOpenRequestA( hConn, "PUT", location, where location is the part of the URL pointing out the filename. Actually is called "output.xslx" on the server in the file list, but when downloading it I get "output.zip". Also I can in the browser upload a file but then I get two files called output.xlsx. The latter is downloaded as an xlsx file. Commented Sep 30, 2015 at 7:24
  • 1
    I think the content type should be application/vnd.ms-excel as you've already tried, but also try adding Content-Disposition: attachment; filename="filename.xlsx" Commented Sep 30, 2015 at 7:34
  • That does not work. It runs without runtime warnings but no cigar: if (!HttpAddRequestHeadersA( hReq, "Content-Disposition: attachment; filename=\"a.xlsx\"", (DWORD)-1, HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD )) { printf("Failed adding mime-type header\n"); } if (!HttpAddRequestHeadersA( hReq, "Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", (DWORD)-1, HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD )) { printf(" @JonathanPotter"); } Commented Sep 30, 2015 at 8:13

1 Answer 1

0

So, it helps if you upload the file as .xlsx instead of .xslx ...

The code works now and looks something like this, no special headers necessary, which is consistent with other examples I have found on the web:

static int upload_file_to_sharepoint(LPCSTR filename, LPCSTR server, LPCSTR location)
{
    HINTERNET hIntrn = InternetOpenA(
        "magic", 
         INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY,
         NULL,
         NULL,
         0
    );
    if (!hIntrn)
        return printf("No Internet connection: %li.\n", GetLastError());

    HINTERNET hConn = InternetConnectA(
        hIntrn, 
        server,
        INTERNET_DEFAULT_HTTPS_PORT,
        NULL,
        NULL,
        INTERNET_SERVICE_HTTP,
        0,
        NULL
    );

    if (!hConn)
        return printf("Connection to update server failed: %li.\n", GetLastError());

    DWORD dwOpenRequestFlags =
        INTERNET_FLAG_KEEP_CONNECTION |
        INTERNET_FLAG_NO_COOKIES |
        INTERNET_FLAG_NO_CACHE_WRITE |
        INTERNET_FLAG_NO_UI |
        INTERNET_FLAG_RELOAD;

    HINTERNET hReq = HttpOpenRequestA(
        hConn,
        "PUT",
        location,
        "HTTP/1.1",
        NULL,
        NULL,
        dwOpenRequestFlags,
        NULL
    );


    HANDLE hFile = CreateFileA(
        filename,
        GENERIC_READ,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL
    );

    if (NULL == hFile) {
        ExitProcess(1);
    }

    HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
    if (NULL == hMap) {
        ExitProcess(1);
    }

    LPVOID lpvFile = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);

    DWORD dwFileSize = GetFileSize(hFile, NULL);    

    if (!HttpSendRequestA(
        hReq,
        NULL,
        0,
        lpvFile,
        dwFileSize)) {
        printf("HttpSendRequest failed: %li.\n", GetLastError());
    }

    UnmapViewOfFile(lpvFile);
    CloseHandle(hMap);
    CloseHandle(hFile);

    printf("Uploaded file to http://%s%s\n", server, location);

    return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.