Question

I'm writing the program for uploading a file to OneDrive based on Cordova Windows 7 with Visual Studio 2013(on Windows 8.1 Pro).

Although transfer of the file by POST method can do, an error "request_method_invalid:HTTP method 'POST' isn't allowed for this resource." returns.

According to the official document, it is written that can upload with POST method. If that is right, where is wrong in this code?

*picojson is an open source JSON parser.

wstring filePath = L"C:\\..\\test.jpg";
wstring dest = L"https://apis.live.net/v5.0/me/skydrive/files/test.jpg";


file = CreateFile(filePath.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file == INVALID_HANDLE_VALUE) {
    SendErrorMessage(data, CONNECTION_ERR, filePath, dest);
    goto out;
}
file_size.LowPart = GetFileSize(file, &file_size.HighPart);

inet = InternetOpen(L"Cordova", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (!inet) {
    SendErrorMessage(data, CONNECTION_ERR, filePath, dest);
    goto out;
}

// 1- Headers
buf = new BYTE[CHUNK_SIZE];
ws = L"Content-Type: multipart/form-data; boundary=" + BOUNDARY;
if (!HttpAddRequestHeaders(req, ws.c_str(), ws.size(), HTTP_ADDREQ_FLAG_ADD)) {
    SendErrorMessage(data, CONNECTION_ERR, filePath, dest);
    goto end_req;
}
for (picojson::object::iterator i = headers.begin(); i != headers.end(); i++){
    if (i->second.is<wstring>() == false) continue;
    ws = i->first + L": " + i->second.get<wstring>(); // Authorization: Bearer (access_token)
    if (!HttpAddRequestHeaders(req, ws.c_str(), ws.size(), HTTP_ADDREQ_FLAG_ADD)) {
        SendErrorMessage(data, CONNECTION_ERR, filePath, dest);
        goto out;
    }
}

// 2- Contents
// 2.1 Contents headers
ws = L"";
for (picojson::object::iterator i = params.begin(); i != params.end(); i++){
    if (i->second.is<wstring>() == false) continue;
    ws += L"--" + BOUNDARY + L"\r\n";
        + L"Content-Disposition: form-data; name=\"" + i->first + L"\";\r\n\r\n"
        + i->second.get<wstring>() + L"\r\n";
}
ws += L"--" + BOUNDARY + L"\r\n"
    + L"Content-Disposition: form-data; name=\"" + fileKey + L"\"; filename=\"" + fileName + L"\"\r\n"
    + L"Content-Type: " + mimeType + L"\r\n\r\n";


int utf8_len = WideCharToMultiByte(CP_UTF8, 0, ws.c_str(), -1, NULL, 0, NULL, NULL);
utf8_text = new char[utf8_len + 10];
if (!WideCharToMultiByte(CP_UTF8, 0, ws.c_str(), ws.size(), utf8_text, utf8_len + 10, NULL, NULL)) {
    SendErrorMessage(data, CONNECTION_ERR, filePath, dest);
    goto end_req;
}
Was it helpful?

Solution 2

If you want to do the upload via POST your destination location should be the parent folder with the file name in the multipart body. From the example:

POST https://apis.live.net/v5.0/me/skydrive/files?access_token=ACCESS_TOKEN

Content-Type: multipart/form-data; boundary=A300x

--A300x
Content-Disposition: form-data; name="file"; filename="HelloWorld.txt"
Content-Type: application/octet-stream

Hello, World!
--A300x--

OTHER TIPS

That said, it's actually a lot easier to use PUT for file uploads. In that case, the path you specified above is correct (i.e., the file name belongs in the path), and you can just write the contents of your file to the response body as is.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top