Project

General

Profile

Bug #6344

Wt::Http::Request getUploadedFile or uploadedFiles always empty

Added by Claudio White over 3 years ago. Updated over 3 years ago.

Status:
Feedback
Priority:
Urgent
Assignee:
-
Target version:
-
Start date:
04/17/2018
Due date:
% Done:

0%

Estimated time:

Description

main.cpp:

#include <UploadResource2.h>

#ifndef WT_WIN32 
extern char **environ;
#endif // WT_WIN32 

int main(int argc, char **argv)
{
        try {
            Wt::WServer server(argv[0]);
            server.setServerConfiguration(argc, argv, WTHTTP_CONFIGURATION);

            UploadResource2 uploadResource2;
            server.addResource(&uploadResource2, "/ur2");

            if (server.start())
            {
                int sig = Wt::WServer::waitForShutdown();
                std::cerr << "Shutdown (signal = " << sig << ")" << std::endl;
                server.stop();
#ifndef WT_WIN32
                if (sig == SIGHUP)
                    Wt::WServer::restart(argc, argv, environ);
#endif // WT_WIN32 
            }
        }
        catch (Wt::WServer::Exception& e) {
            std::cerr << e.what() << "\n";
            g_trc.flush();
            return 1;
        }
        catch (std::exception& e) {
            std::cerr << "exception: " << e.what() << "\n";
            g_trc.flush();
            return 1;
        }
        catch (...) {
            std::cerr << "exception: unknown" << "\n";
            g_trc.flush();
            return 1;
        }

    return 0;
}

UploadResource2.h:

#pragma once
#include <Wt/WServer> 
#include <Wt/WResource>
#include <Wt/Http/Request>
#include <Wt/Http/Response>
#include <Wt/WTemplate>
#include <Wt/Utils>

#include <Wt/WAnchor>
#include <Wt/WApplication>
#include <Wt/WEnvironment>
#include <Wt/WLogger>

using namespace std;

class UploadResource2 : public Wt::WResource
{
public:
    UploadResource2();
    virtual ~UploadResource2();
protected:
    virtual void handleRequest(const Wt::Http::Request& request, Wt::Http::Response& response);
};

UploadResource2::UploadResource2() {}
UploadResource2::~UploadResource2() {}

typedef std::pair<std::string, Wt::Http::UploadedFile> UploadedFilePair;

void UploadResource2::handleRequest(const Wt::Http::Request& request, Wt::Http::Response& response)
{
    Wt::log("TestUpload") << " Request Too Large? : " << request.tooLarge();
    Wt::log("TestUpload") << " Method             : " << request.method();
    Wt::log("TestUpload") << " Content Type       : " << request.contentType();
    Wt::log("TestUpload") << " Content Length     : " << request.contentLength();
    Wt::log("TestUpload") << " Content-Length     : " << request.headerValue("Content-Length");
    Wt::log("TestUpload") << " Expect             : " << request.headerValue("Expect");

    auto uf = request.getUploadedFile("upload-file"); //tried also: -d

    if (uf && !uf->clientFileName().empty()) {
        Wt::log("TestUpload") << " File details     : ";
        Wt::log("TestUpload") << "  Spool File Name : " << uf->spoolFileName();
        Wt::log("TestUpload") << "  Client File Name: " << uf->clientFileName();
        Wt::log("TestUpload") << "  Content type    : " << uf->contentType();
    }

    Wt::log("TestUpload") << " Continuation       : " << request.continuation();
    auto params = request.getParameterMap();
    //Wt::log("TestUpload") << " ParameterMap       : " << params.size() ? params[0] : "";

    Wt::Http::UploadedFileMap fm = request.uploadedFiles();
    for_each(fm.begin(), fm.end(), [](Wt::Http::UploadedFileMap::value_type v) {
        Wt::log("TestUpload") << " Filemap Key      : " << v.first;
        Wt::log("TestUpload") << " File details     : ";
        Wt::log("TestUpload") << "  Spool File Name : " << v.second.spoolFileName();
        Wt::log("TestUpload") << "  Client File Name: " << v.second.clientFileName();
        Wt::log("TestUpload") << "  Content type    : " << v.second.contentType();
    });

    if (request.headerValue("Expect") == "100-continue") {
        // Should the response return status code 100 as per the HTTP standard? If yes, then the client actually receives status code 500!
        // Uncommenting the following line sends status code 500 to the client.
        //response.setStatus(100);
    }
    else {
        response.out() << "No 100-continue.\n";
    }

    std::ofstream f("srv.file", std::ios::out | std::ios::trunc | std::ios::binary);
    f << request.in().rdbuf();

    response.out() << "Done!\n\n" << request.in().rdbuf();
}

Starting from Visual Studio 2015 with Debugsession-Args:

---docroot . ---http-address 0.0.0.0 ---http-port 8095 ---config C:/Dev/wt336_15/projects/UplResTest/src/Main/wt_config.xml

Output after Start is:

[info] "config: reading Wt config file: C:/Dev/wt336_15/projects/UplResTest/src/Main/wt_config.xml (location = 'C:\Dev\wt336_15\projects\UplResTest\Debug\uplrestest.exe')"

[info] "WServer/wthttp: initializing built-in wthttpd"

[info] "wthttp: started server: http://0.0.0.0:8095"


Uploading a Text-File (Length 1767 bytes) with curl try #1# with command like below:

curl -i ---upload-file Temp.txt http://localhost:8095/ur2 ---header "Content-Type:text/text"

Result-WT-Server-DOS-Window:

[info] "WebRequest: took 15ms"

[TestUpload] \" Request Too Large? : 0\"

[TestUpload] \" Method : PUT\"

[TestUpload] \" Content Type : text/text\"

[TestUpload] \" Content Length : 1767\"

[TestUpload] \" Content-Length : 1767\"

[TestUpload] \" Expect : 100-continue\"

[TestUpload] \" Continuation : 00000000\"

"PUT /ur2 HTTP/1.1" 200 7

[info] "WebRequest: took 6408ms"

"POST /?wtd=0I3ObHqqwPmRV4ZR HTTP/1.1" 200 0

[info] "WebRequest: took 15ms"

Result-Curl-DOS-Window:

HTTP/1.1 200 OK

Date: Wed, 17 Apr 2018 08:36:16 GMT

Content-Type:

Transfer-Encoding: chunked

Done!

My Comment: request.getUploadedFile(...) and request.uploadedFiles() delivers nothing - but request.length and the other methods are showing that file must be there, because they know the correct length of the text Input file.


Uploading a Text-File (Length 1767 bytes) with curl try #2# with command like below:

curl -X POST -d @Temp.txt http://localhost:8095/ur2

Result-WT-Server-DOS-Window:

[TestUpload] \" Request Too Large? : 0\"

[TestUpload] \" Method : POST\"

[TestUpload] \" Content Type : application/x-www-form-urlencoded\"

[TestUpload] \" Content Length : 1767\"

[TestUpload] \" Content-Length : 1767\"

[TestUpload] \" Expect : 100-continue\"

[TestUpload] \" Continuation : 00000000\"

"POST /ur2 HTTP/1.1" 200 7

[info] "WebRequest: took 2833ms"

Result-Curl-DOS-Window:

Done!

My Comment: request.getUploadedFile(...) and request.uploadedFiles() delivers nothing - but request.length and the other methods are showing that file must be there, because they know the correct length of the text Input file.


Uploading a Text-File (Length 1767 bytes) with curl try #3# with command like below:

curl -X POST ---upload-file Temp.txt http://localhost:8095/ur2 ---header "Content-Type:text/text"

Result-WT-Server-DOS-Window:

[TestUpload] \" Request Too Large? : 0\"

[TestUpload] \" Method : POST\"

[TestUpload] \" Content Type : text/text\"

[TestUpload] \" Content Length : 1767\"

[TestUpload] \" Content-Length : 1767\"

[TestUpload] \" Expect : 100-continue\"

[TestUpload] \" Continuation : 00000000\"

"POST /ur2 HTTP/1.1" 200 7

[info] "WebRequest: took 1110.33ms"

Result-Curl-DOS-Window:

Done!

My Comment: request.getUploadedFile(...) and request.uploadedFiles() delivers nothing - but request.length and the other methods are showing that file must be there, because they know the correct length of the text Input file.


I did not found any help in the Forum and not any example (including the blog example) with using request.uploadedFiles() and/or request.getUploadedFile(...) so i guess noone is using this and therefore it was never seen that this methods not working properly.


My Environment i use is:

Windows 7 (64bit)

Visual Studio 2015

WT 3.3.6 (32bit)

For some reasons i cannot currently switch to newest WT 4.x and maybe the bug is still in v4.x too.

If i can help more to find out please feel free to contact me.

#1

Updated by Claudio White over 3 years ago

One more hint:

std::ofstream f("srv.file", std::ios::out | std::ios::trunc | std::ios::binary);

f << request.in().rdbuf();

Content of uploading is found in srv.file - so upload itself is working:-) That's the good News.

But i do expect that request.getParameter("upload-file") will giving back the value of the Parameter ---upload-file and this should be the value "Temp.txt" and not null as now.

Also i do expect that request.getUploadedFile("srv.file") will giving back the uploaded file and not null as now.

Same for request.uploadedFiles should giving back a map of all uploaded files and not null as now.

Is it only a missunderstanding of mine using request with calls from third Party Clients like curl or SoapUI, will request.getParameter(...), request.getUploadedFile(...) and request.uploadedFiles only be filled when using internal instantiated file Uploads using FileUpload?

If it is a missinderstanding of mine please Close this Ticket - but please leave a clarify message in which situations request.getUploadedFile and request-uploaededFiles are filled.

#2

Updated by Roel Standaert over 3 years ago

  • Status changed from New to Feedback

Can you switch to Wt 3.3.10 first?

#3

Updated by Roel Standaert over 3 years ago

Although, reading it a bit further. It looks to me that it is working as intended: the contents of the file are in the body of the request.

I believe uploadedFiles is more intended to be used with files uploaded through submitting a form. It should be working properly, since WFileUpload en WFileDropWidget are working properly.

Also available in: Atom PDF