#2565: HTMLForm: optional enforcement of Content-Length instead of Chunked Transfer-Encoding

This commit is contained in:
Günter Obiltschnig
2018-12-12 18:00:58 +01:00
parent e1aac5ff95
commit db86fec382
4 changed files with 73 additions and 39 deletions

View File

@@ -46,17 +46,23 @@ 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".
explicit HTMLForm(const std::string& encoding);
/// Creates an empty HTMLForm that uses
/// the given encoding.
///
/// Encoding must be either "application/x-www-form-urlencoded"
/// (which is the default) or "multipart/form-data".
HTMLForm(const HTTPRequest& request, std::istream& requestBody, PartHandler& handler);
/// Creates a HTMLForm from the given HTTP request.
///
@@ -75,7 +81,7 @@ public:
///
/// For POST requests, you must use one of the constructors
/// taking an additional input stream for the request body.
~HTMLForm();
/// Destroys the HTMLForm.
@@ -84,7 +90,7 @@ public:
///
/// Encoding must be either "application/x-www-form-urlencoded"
/// (which is the default) or "multipart/form-data".
const std::string& getEncoding() const;
/// Returns the encoding used for posting the form.
@@ -130,14 +136,14 @@ public:
///
/// Note that read() does not clear the form before
/// reading the new values.
void read(const std::string& queryString);
/// Reads the form data from the given HTTP query string.
///
/// 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.
@@ -174,7 +185,7 @@ public:
/// allowed.
///
/// See setFieldLimit() for more information.
void setFieldLimit(int limit);
/// Sets the maximum number of header fields
/// allowed. This limit is used to defend certain
@@ -182,11 +193,11 @@ public:
/// Specify 0 for unlimited (not recommended).
///
/// The default limit is 100.
void setValueLengthLimit(int limit);
/// Sets the maximum size for form field values
/// stored as strings.
int getValueLengthLimit() const;
/// Returns the maximum size for form field values
/// stored as strings.
@@ -194,7 +205,7 @@ public:
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;
protected:
void readUrl(std::istream& istr);
void readMultipart(std::istream& istr, PartHandler& handler);
@@ -217,9 +228,9 @@ private:
std::string name;
PartSource* pSource;
};
typedef std::vector<Part> PartVec;
int _fieldLimit;
int _valueLengthLimit;
std::string _encoding;