Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:ClickHouse ClickHouse Poco HTMLForm

From Leeroopedia
Revision as of 14:37, 16 February 2026 by Admin (talk | contribs) (Auto-imported from implementations/ClickHouse_ClickHouse_Poco_HTMLForm.md)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)


Source File base/poco/Net/src/HTMLForm.cpp
Lines of Code 467
Principle Principle:ClickHouse_ClickHouse_HTTP_Client_Communication
Domain Networking, HTTP
Language C++
Last Updated 2026-02-08 00:00 GMT

Overview

Implementation of HTML form handling for HTTP requests, supporting both URL-encoded and multipart/form-data encodings with file upload capabilities.

Purpose

Provides comprehensive HTML form parsing and generation for HTTP communication, handling form data extraction from requests and formatting for transmission.

Key Classes

  • HTMLForm: Main form container extending `NameValueCollection`
  • HTMLFormCountingOutputStream: Utility for calculating content length
  • Part: Internal structure for multipart attachments

Core Functionality

Form Initialization

Multiple construction modes:

// Empty form
HTMLForm();
HTMLForm(const std::string& encoding);

// Parse from HTTP request
HTMLForm(const HTTPRequest& request);
HTMLForm(const HTTPRequest& request, std::istream& requestBody);
HTMLForm(const HTTPRequest& request, std::istream& requestBody, PartHandler& handler);

Loading Forms

Extract form data from HTTP requests:

void load(const HTTPRequest& request);
void load(const HTTPRequest& request, std::istream& requestBody);
void load(const HTTPRequest& request, std::istream& requestBody, PartHandler& handler);

// Parse query string
void read(const std::string& queryString);

// Read from stream
void read(std::istream& istr);
void read(std::istream& istr, PartHandler& handler);

Handles:

  • Query parameters from URI
  • POST/PUT body in URL-encoded format
  • Multipart/form-data with file uploads

Writing Forms

Generate form data for transmission:

void prepareSubmit(HTTPRequest& request, int options = 0);
void write(std::ostream& ostr);
void write(std::ostream& ostr, const std::string& boundary);

std::streamsize calculateContentLength();

Options:

  • `OPT_USE_CONTENT_LENGTH`: Force Content-Length header (vs chunked)

Encoding Support

Two primary encodings:

static const std::string ENCODING_URL;        // "application/x-www-form-urlencoded"
static const std::string ENCODING_MULTIPART;  // "multipart/form-data"

void setEncoding(const std::string& encoding);
const std::string& getEncoding() const;

Multipart Support

Handle file uploads and complex data:

struct Part {
    std::string name;
    PartSource* pSource;
};

void addPart(const std::string& name, PartSource* pSource);

`PartSource` provides:

  • Stream interface to file/data
  • Content type
  • Filename
  • Content length

Security Limits

Protect against malicious inputs:

void setFieldLimit(int limit);          // Maximum number of fields
void setValueLengthLimit(int limit);    // Maximum field value length

static const int MAX_NAME_LENGTH = 1024;
static const int DFL_FIELD_LIMIT = 100;
static const int DFL_MAX_VALUE_LENGTH = 256 * 1024;

Implementation Details

URL-Encoded Parsing

Parse `application/x-www-form-urlencoded` data:

void readUrl(std::istream& istr) {
    // Read name=value&name=value format
    // '+' → space
    // URL decode names and values
    // Remove UTF-8 BOM from first field
    // Enforce field and value limits
}

Format: `field1=value1&field2=value2`

  • Plus signs converted to spaces
  • Percent-encoding decoded
  • UTF-8 BOM stripped from first field name

Multipart Parsing

Parse `multipart/form-data`:

void readMultipart(std::istream& istr, PartHandler& handler) {
    MultipartReader reader(istr, _boundary);
    while (reader.hasNextPart()) {
        MessageHeader header;
        reader.nextPart(header);
        // Extract Content-Disposition parameters
        if (has filename) {
            handler.handlePart(header, reader.stream());
        } else {
            // Read field value
        }
    }
}

Delegates file uploads to `PartHandler`:

  • `NullPartHandler`: Ignores file parts
  • Custom handlers can save to disk, database, etc.

URL-Encoded Writing

Generate URL-encoded output:

void writeUrl(std::ostream& ostr) {
    // Format: name1=value1&name2=value2
    // Encode special characters: !?#/'\",;:$&()[]*+=@
    for (auto& field : fields) {
        URI::encode(name, reserved, encoded_name);
        URI::encode(value, reserved, encoded_value);
        ostr << encoded_name << "=" << encoded_value;
        if (not_last) ostr << "&";
    }
}

Multipart Writing

Generate multipart/form-data:

void writeMultipart(std::ostream& ostr) {
    MultipartWriter writer(ostr, _boundary);

    // Write simple fields
    for (auto& field : fields) {
        MessageHeader header;
        header.set("Content-Disposition",
                   "form-data; name=\"" + name + "\"");
        writer.nextPart(header);
        ostr << value;
    }

    // Write file parts
    for (auto& part : _parts) {
        MessageHeader header(part.pSource->headers());
        header.set("Content-Disposition",
                   "form-data; name=\"" + name +
                   "\"; filename=\"" + filename + "\"");
        header.set("Content-Type", part.pSource->mediaType());
        writer.nextPart(header);
        StreamCopier::copyStream(part.pSource->stream(), ostr);
    }

    writer.close();
}

Content Length Calculation

For non-chunked transmission:

std::streamsize calculateContentLength() {
    HTMLFormCountingOutputStream counter;
    write(counter);
    if (counter.isValid())
        return counter.chars();
    else
        return UNKNOWN_CONTENT_LENGTH;
}

`HTMLFormCountingOutputStream` counts bytes without writing, but sets invalid flag if any `PartSource` has unknown length.

Usage Examples

Parsing Form Data

// From HTTP request
HTTPRequest request;
std::istream& body = session.receiveRequest(request);
HTMLForm form(request, body);

// Access fields
std::string username = form.get("username");
std::string password = form.get("password");

Creating Form Submission

// URL-encoded form
HTMLForm form(HTMLForm::ENCODING_URL);
form.set("user", "alice");
form.set("pass", "secret");

HTTPRequest request(HTTPRequest::HTTP_POST, "/login");
form.prepareSubmit(request);

std::ostream& ostr = session.sendRequest(request);
form.write(ostr);

File Upload

// Multipart form with file
HTMLForm form(HTMLForm::ENCODING_MULTIPART);
form.set("description", "My file");
form.addPart("file", new FilePartSource("/path/to/file.pdf"));

HTTPRequest request(HTTPRequest::HTTP_POST, "/upload");
form.prepareSubmit(request);

std::ostream& ostr = session.sendRequest(request);
form.write(ostr);

Handling File Uploads (Server)

class MyPartHandler : public PartHandler {
public:
    void handlePart(const MessageHeader& header, std::istream& stream) override {
        // Extract filename from Content-Disposition
        // Save stream to file
    }
};

MyPartHandler handler;
HTMLForm form(request, body, handler);

Dependencies

  • `Poco::Net::HTTPRequest`: HTTP request representation
  • `Poco::Net::MultipartReader`: Multipart parsing
  • `Poco::Net::MultipartWriter`: Multipart generation
  • `Poco::Net::PartSource`: File/data source abstraction
  • `Poco::Net::PartHandler`: File upload callback
  • `Poco::URI`: URL encoding/decoding
  • `Poco::StreamCopier`: Stream copying utilities

Security Considerations

  • Field count limits prevent DoS attacks
  • Value length limits prevent memory exhaustion
  • Input validation prevents injection attacks
  • Proper encoding prevents XSS vulnerabilities
  • UTF-8 BOM handling prevents parser confusion

Testing Considerations

  • Test both URL-encoded and multipart forms
  • Verify proper URL encoding/decoding
  • Test file upload/download
  • Check limit enforcement
  • Test with empty values and special characters
  • Verify UTF-8 and international characters
  • Test boundary collision handling in multipart

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment