Add getPartList() to HTMLForm #162

This commit is contained in:
Alex Fabijanic 2017-10-11 16:49:08 -05:00
parent f03356b50c
commit ffca55c21b
3 changed files with 106 additions and 25 deletions

View File

@ -19,7 +19,8 @@
#include "Poco/Net/Net.h"
#include "Poco/Net/NameValueCollection.h"
#include "Poco/Net/MessageHeader.h"
#include "Poco/Net/PartSource.h"
#include <ostream>
#include <istream>
#include <vector>
@ -191,6 +192,33 @@ public:
/// Returns the maximum size for form field values
/// stored as strings.
class Part
{
public:
Part(const std::string name, PartSource* pSource);
Part(Part&& other);
~Part();
const std::string& name() const;
const PartSource* source() const;
const MessageHeader& headers() const;
const std::string& filename() const;
const std::string& mediaType() const;
std::istream& stream();
private:
Part();
Part(const Part&);
Part& operator =(const Part&);
std::string _name;
PartSource* _pSource;
};
typedef std::vector<Part> PartVec;
const PartVec& getPartList() const;
static const std::string ENCODING_URL; /// "application/x-www-form-urlencoded"
static const std::string ENCODING_MULTIPART; /// "multipart/form-data"
static const int UNKNOWN_CONTENT_LENGTH;
@ -211,14 +239,6 @@ private:
MAX_NAME_LENGTH = 1024,
DFL_MAX_VALUE_LENGTH = 256*1024
};
struct Part
{
std::string name;
PartSource* pSource;
};
typedef std::vector<Part> PartVec;
int _fieldLimit;
int _valueLengthLimit;
@ -231,6 +251,7 @@ private:
//
// inlines
//
inline const std::string& HTMLForm::getEncoding() const
{
return _encoding;
@ -255,6 +276,50 @@ inline int HTMLForm::getValueLengthLimit() const
}
inline const HTMLForm::PartVec& HTMLForm::getPartList() const
{
return _parts;
}
// HTMLForm::Part
inline const std::string& HTMLForm::Part::name() const
{
return _name;
}
inline const PartSource* HTMLForm::Part::source() const
{
return _pSource;
}
inline const MessageHeader& HTMLForm::Part::headers() const
{
return _pSource->headers();
}
inline const std::string& HTMLForm::Part::filename() const
{
return _pSource->filename();
}
inline const std::string& HTMLForm::Part::mediaType() const
{
return _pSource->mediaType();
}
inline std::istream& HTMLForm::Part::stream()
{
return _pSource->stream();
}
} } // namespace Poco::Net

View File

@ -14,7 +14,6 @@
#include "Poco/Net/HTMLForm.h"
#include "Poco/Net/HTTPRequest.h"
#include "Poco/Net/PartSource.h"
#include "Poco/Net/PartHandler.h"
#include "Poco/Net/MultipartWriter.h"
#include "Poco/Net/MultipartReader.h"
@ -41,6 +40,24 @@ namespace Poco {
namespace Net {
HTMLForm::Part::Part(const std::string name, PartSource* pSource) :
_name(name), _pSource(pSource)
{
}
HTMLForm::Part::Part(Part&& other) : _name(std::move(other._name)), _pSource(other._pSource)
{
other._pSource = 0;
}
HTMLForm::Part::~Part()
{
delete _pSource;
}
const std::string HTMLForm::ENCODING_URL = "application/x-www-form-urlencoded";
const std::string HTMLForm::ENCODING_MULTIPART = "multipart/form-data";
const int HTMLForm::UNKNOWN_CONTENT_LENGTH = -1;
@ -111,10 +128,6 @@ HTMLForm::HTMLForm(const HTTPRequest& request):
HTMLForm::~HTMLForm()
{
for (PartVec::iterator it = _parts.begin(); it != _parts.end(); ++it)
{
delete it->pSource;
}
}
@ -127,11 +140,7 @@ void HTMLForm::setEncoding(const std::string& encoding)
void HTMLForm::addPart(const std::string& name, PartSource* pSource)
{
poco_check_ptr (pSource);
Part part;
part.name = name;
part.pSource = pSource;
_parts.push_back(part);
_parts.push_back(Part(name, pSource));
}
@ -416,11 +425,11 @@ void HTMLForm::writeMultipart(std::ostream& ostr)
}
for (PartVec::iterator ita = _parts.begin(); ita != _parts.end(); ++ita)
{
MessageHeader header(ita->pSource->headers());
MessageHeader header(ita->headers());
std::string disp("form-data; name=\"");
disp.append(ita->name);
disp.append(ita->name());
disp.append("\"");
std::string filename = ita->pSource->filename();
std::string filename = ita->filename();
if (!filename.empty())
{
disp.append("; filename=\"");
@ -428,12 +437,12 @@ void HTMLForm::writeMultipart(std::ostream& ostr)
disp.append("\"");
}
header.set("Content-Disposition", disp);
header.set("Content-Type", ita->pSource->mediaType());
header.set("Content-Type", ita->mediaType());
writer.nextPart(header);
if (pCountingOutputStream)
{
// count only, don't move stream position
std::streamsize partlen = ita->pSource->getContentLength();
std::streamsize partlen = ita->source()->getContentLength();
if (partlen != PartSource::UNKNOWN_CONTENT_LENGTH)
pCountingOutputStream->addChars(static_cast<int>(partlen));
else
@ -441,7 +450,7 @@ void HTMLForm::writeMultipart(std::ostream& ostr)
}
else
{
StreamCopier::copyStream(ita->pSource->stream(), ostr);
StreamCopier::copyStream(ita->stream(), ostr);
}
}
writer.close();

View File

@ -146,6 +146,13 @@ void HTMLFormTest::testWriteMultipart()
"--MIME_boundary_0123456789--\r\n"
);
assert(s.length() == form.calculateContentLength());
const HTMLForm::PartVec& parts = form.getPartList();
assert(parts.size() == 2);
assert(parts[0].name() == "attachment1");
assert(parts[1].name() == "attachment2");
assert(parts[1].filename() == "att2.txt");
assert(parts[1].headers()["Content-ID"] == "1234abcd");
}