mirror of
https://github.com/pocoproject/poco.git
synced 2025-04-02 09:49:48 +02:00
#2565: HTMLForm: optional enforcement of Content-Length instead of Chunked Transfer-Encoding
This commit is contained in:
parent
e1aac5ff95
commit
db86fec382
@ -46,6 +46,12 @@ class Net_API HTMLForm: public NameValueCollection
|
||||
/// form fields programmatically. The default limit is 100.
|
||||
{
|
||||
public:
|
||||
enum Options
|
||||
{
|
||||
OPT_USE_CONTENT_LENGTH = 0x01
|
||||
/// Don't use Chunked Transfer-Encoding for multipart requests.
|
||||
};
|
||||
|
||||
HTMLForm();
|
||||
/// Creates an empty HTMLForm and sets the
|
||||
/// encoding to "application/x-www-form-urlencoded".
|
||||
@ -137,7 +143,7 @@ public:
|
||||
/// Note that read() does not clear the form before
|
||||
/// reading the new values.
|
||||
|
||||
void prepareSubmit(HTTPRequest& request);
|
||||
void prepareSubmit(HTTPRequest& request, int options = 0);
|
||||
/// Fills out the request object for submitting the form.
|
||||
///
|
||||
/// If the request method is GET, the encoded form is appended to the
|
||||
@ -150,7 +156,12 @@ public:
|
||||
/// - the content transfer encoding is set to identity encoding
|
||||
/// Otherwise, if the request's HTTP version is HTTP/1.1:
|
||||
/// - the request's persistent connection state is left unchanged
|
||||
/// - the content transfer encoding is set to chunked
|
||||
/// - the content transfer encoding is set to chunked, unless
|
||||
/// the OPT_USE_CONTENT_LENGTH is given in options
|
||||
///
|
||||
/// Note: Not using chunked transfer encoding for multipart forms
|
||||
/// degrades performance, as the request content must be generated
|
||||
/// twice, first to determine its size, then to actually send it.
|
||||
|
||||
std::streamsize calculateContentLength();
|
||||
/// Calculate the content length for the form.
|
||||
|
@ -203,7 +203,7 @@ void HTMLForm::read(const std::string& queryString)
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::prepareSubmit(HTTPRequest& request)
|
||||
void HTMLForm::prepareSubmit(HTTPRequest& request, int options)
|
||||
{
|
||||
if (request.getMethod() == HTTPRequest::HTTP_POST || request.getMethod() == HTTPRequest::HTTP_PUT)
|
||||
{
|
||||
@ -229,11 +229,11 @@ void HTMLForm::prepareSubmit(HTTPRequest& request)
|
||||
request.setKeepAlive(false);
|
||||
request.setChunkedTransferEncoding(false);
|
||||
}
|
||||
else if (_encoding != ENCODING_URL)
|
||||
else if (_encoding != ENCODING_URL && (options & OPT_USE_CONTENT_LENGTH) == 0)
|
||||
{
|
||||
request.setChunkedTransferEncoding(true);
|
||||
}
|
||||
if (!request.getChunkedTransferEncoding())
|
||||
if (!request.getChunkedTransferEncoding() && !request.hasContentLength())
|
||||
{
|
||||
request.setContentLength(calculateContentLength());
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "Poco/Net/NetException.h"
|
||||
#include <sstream>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using Poco::Net::HTMLForm;
|
||||
using Poco::Net::PartSource;
|
||||
@ -294,6 +295,7 @@ void HTMLFormTest::testSubmit2()
|
||||
HTTPRequest req("POST", "/form.cgi");
|
||||
form.prepareSubmit(req);
|
||||
assertTrue (req.getContentType() == HTMLForm::ENCODING_URL);
|
||||
assertTrue (req.getContentLength() == 64);
|
||||
}
|
||||
|
||||
|
||||
@ -331,6 +333,25 @@ void HTMLFormTest::testSubmit4()
|
||||
}
|
||||
|
||||
|
||||
void HTMLFormTest::testSubmit5()
|
||||
{
|
||||
HTMLForm form(HTMLForm::ENCODING_MULTIPART);
|
||||
form.set("field1", "value1");
|
||||
form.set("field2", "value 2");
|
||||
form.set("field3", "value=3");
|
||||
form.set("field4", "value&4");
|
||||
|
||||
HTTPRequest req("POST", "/form.cgi", HTTPMessage::HTTP_1_1);
|
||||
form.prepareSubmit(req, HTMLForm::OPT_USE_CONTENT_LENGTH);
|
||||
std::string expCT(HTMLForm::ENCODING_MULTIPART);
|
||||
expCT.append("; boundary=\"");
|
||||
expCT.append(form.boundary());
|
||||
expCT.append("\"");
|
||||
assertTrue (req.getContentType() == expCT);
|
||||
assertTrue (req.getContentLength() == 403);
|
||||
}
|
||||
|
||||
|
||||
void HTMLFormTest::testFieldLimitUrl()
|
||||
{
|
||||
HTTPRequest req("GET", "/form.cgi?field1=value1&field2=value%202&field3=value%3D3&field4=value%264");
|
||||
@ -416,6 +437,7 @@ CppUnit::Test* HTMLFormTest::suite()
|
||||
CppUnit_addTest(pSuite, HTMLFormTest, testSubmit2);
|
||||
CppUnit_addTest(pSuite, HTMLFormTest, testSubmit3);
|
||||
CppUnit_addTest(pSuite, HTMLFormTest, testSubmit4);
|
||||
CppUnit_addTest(pSuite, HTMLFormTest, testSubmit5);
|
||||
CppUnit_addTest(pSuite, HTMLFormTest, testFieldLimitUrl);
|
||||
CppUnit_addTest(pSuite, HTMLFormTest, testFieldLimitMultipart);
|
||||
|
||||
|
@ -36,6 +36,7 @@ public:
|
||||
void testSubmit2();
|
||||
void testSubmit3();
|
||||
void testSubmit4();
|
||||
void testSubmit5();
|
||||
void testFieldLimitUrl();
|
||||
void testFieldLimitMultipart();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user