mirror of
https://github.com/Telecominfraproject/wlan-cloud-lib-poco.git
synced 2025-11-07 14:08:45 +00:00
initial import
This commit is contained in:
358
Net/src/HTMLForm.cpp
Normal file
358
Net/src/HTMLForm.cpp
Normal file
@@ -0,0 +1,358 @@
|
||||
//
|
||||
// HTMLForm.cpp
|
||||
//
|
||||
// $Id: //poco/1.1.0/Net/src/HTMLForm.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTML
|
||||
// Module: HTMLForm
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Net/HTMLForm.h"
|
||||
#include "Net/HTTPRequest.h"
|
||||
#include "Net/PartSource.h"
|
||||
#include "Net/PartHandler.h"
|
||||
#include "Net/MultipartWriter.h"
|
||||
#include "Net/MultipartReader.h"
|
||||
#include "Net/NullPartHandler.h"
|
||||
#include "Foundation/NullStream.h"
|
||||
#include "Foundation/StreamCopier.h"
|
||||
#include "Foundation/Exception.h"
|
||||
#include "Foundation/URI.h"
|
||||
#include "Foundation/String.h"
|
||||
#include <sstream>
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
using Foundation::NullInputStream;
|
||||
using Foundation::StreamCopier;
|
||||
using Foundation::SyntaxException;
|
||||
using Foundation::URI;
|
||||
using Foundation::icompare;
|
||||
|
||||
|
||||
Net_BEGIN
|
||||
|
||||
|
||||
const std::string HTMLForm::ENCODING_URL = "application/x-www-form-urlencoded";
|
||||
const std::string HTMLForm::ENCODING_MULTIPART = "multipart/form-data";
|
||||
|
||||
|
||||
HTMLForm::HTMLForm():
|
||||
_encoding(ENCODING_URL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTMLForm::HTMLForm(const std::string& encoding):
|
||||
_encoding(encoding)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTMLForm::HTMLForm(const HTTPRequest& request, std::istream& istr, PartHandler& handler)
|
||||
{
|
||||
load(request, istr, handler);
|
||||
}
|
||||
|
||||
|
||||
HTMLForm::HTMLForm(const HTTPRequest& request, std::istream& istr)
|
||||
{
|
||||
load(request, istr);
|
||||
}
|
||||
|
||||
|
||||
HTMLForm::HTMLForm(const HTTPRequest& request)
|
||||
{
|
||||
load(request);
|
||||
}
|
||||
|
||||
|
||||
HTMLForm::~HTMLForm()
|
||||
{
|
||||
for (PartVec::iterator it = _parts.begin(); it != _parts.end(); ++it)
|
||||
{
|
||||
delete it->pSource;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::setEncoding(const std::string& encoding)
|
||||
{
|
||||
_encoding = 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);
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::load(const HTTPRequest& request, std::istream& requestBody, PartHandler& handler)
|
||||
{
|
||||
if (request.getMethod() == HTTPRequest::HTTP_GET)
|
||||
{
|
||||
URI uri(request.getURI());
|
||||
std::istringstream istr(uri.getRawQuery());
|
||||
readUrl(istr);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string mediaType;
|
||||
NameValueCollection params;
|
||||
MessageHeader::splitParameters(request.getContentType(), mediaType, params);
|
||||
_encoding = mediaType;
|
||||
if (_encoding == ENCODING_MULTIPART)
|
||||
{
|
||||
_boundary = params["boundary"];
|
||||
readMultipart(requestBody, handler);
|
||||
}
|
||||
else
|
||||
{
|
||||
readUrl(requestBody);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::load(const HTTPRequest& request, std::istream& requestBody)
|
||||
{
|
||||
NullPartHandler nah;
|
||||
load(request, requestBody, nah);
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::load(const HTTPRequest& request)
|
||||
{
|
||||
NullPartHandler nah;
|
||||
NullInputStream nis;
|
||||
load(request, nis, nah);
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::read(std::istream& istr, PartHandler& handler)
|
||||
{
|
||||
if (_encoding == ENCODING_URL)
|
||||
readUrl(istr);
|
||||
else
|
||||
readMultipart(istr, handler);
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::prepareSubmit(HTTPRequest& request)
|
||||
{
|
||||
if (request.getMethod() == HTTPRequest::HTTP_GET)
|
||||
{
|
||||
std::string uri = request.getURI();
|
||||
std::ostringstream ostr;
|
||||
write(ostr);
|
||||
uri.append("?");
|
||||
uri.append(ostr.str());
|
||||
request.setURI(uri);
|
||||
}
|
||||
else if (request.getMethod() == HTTPRequest::HTTP_POST)
|
||||
{
|
||||
if (_encoding == ENCODING_URL)
|
||||
{
|
||||
request.setContentType(_encoding);
|
||||
}
|
||||
else
|
||||
{
|
||||
_boundary = MultipartWriter::createBoundary();
|
||||
std::string ct(_encoding);
|
||||
ct.append("; boundary=\"");
|
||||
ct.append(_boundary);
|
||||
ct.append("\"");
|
||||
request.setContentType(ct);
|
||||
}
|
||||
if (request.getVersion() == HTTPMessage::HTTP_1_0)
|
||||
{
|
||||
request.setKeepAlive(false);
|
||||
request.setChunkedTransferEncoding(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
request.setChunkedTransferEncoding(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::write(std::ostream& ostr, const std::string& boundary)
|
||||
{
|
||||
if (_encoding == ENCODING_URL)
|
||||
{
|
||||
writeUrl(ostr);
|
||||
}
|
||||
else
|
||||
{
|
||||
_boundary = boundary;
|
||||
writeMultipart(ostr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::write(std::ostream& ostr)
|
||||
{
|
||||
if (_encoding == ENCODING_URL)
|
||||
writeUrl(ostr);
|
||||
else
|
||||
writeMultipart(ostr);
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::readUrl(std::istream& istr)
|
||||
{
|
||||
static const int eof = std::char_traits<char>::eof();
|
||||
|
||||
int ch = istr.get();
|
||||
while (ch != eof)
|
||||
{
|
||||
std::string name;
|
||||
std::string value;
|
||||
while (ch != eof && ch != '=' && ch != '&')
|
||||
{
|
||||
if (ch == '+') ch = ' ';
|
||||
name += (char) ch;
|
||||
ch = istr.get();
|
||||
}
|
||||
if (ch == '=')
|
||||
{
|
||||
ch = istr.get();
|
||||
while (ch != eof && ch != '&')
|
||||
{
|
||||
if (ch == '+') ch = ' ';
|
||||
value += (char) ch;
|
||||
ch = istr.get();
|
||||
}
|
||||
}
|
||||
std::string decodedName;
|
||||
std::string decodedValue;
|
||||
URI::decode(name, decodedName);
|
||||
URI::decode(value, decodedValue);
|
||||
set(decodedName, decodedValue);
|
||||
if (ch == '&') ch = istr.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::readMultipart(std::istream& istr, PartHandler& handler)
|
||||
{
|
||||
static const int eof = std::char_traits<char>::eof();
|
||||
|
||||
MultipartReader reader(istr, _boundary);
|
||||
while (reader.hasNextPart())
|
||||
{
|
||||
MessageHeader header;
|
||||
reader.nextPart(header);
|
||||
std::string disp;
|
||||
NameValueCollection params;
|
||||
if (header.has("Content-Disposition"))
|
||||
{
|
||||
std::string cd = header.get("Content-Disposition");
|
||||
MessageHeader::splitParameters(cd, disp, params);
|
||||
}
|
||||
if (icompare(disp, "file") == 0)
|
||||
{
|
||||
handler.handlePart(header, reader.stream());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string name = params["name"];
|
||||
std::string value;
|
||||
std::istream& istr = reader.stream();
|
||||
int ch = istr.get();
|
||||
while (ch != eof)
|
||||
{
|
||||
value += (char) ch;
|
||||
ch = istr.get();
|
||||
}
|
||||
set(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::writeUrl(std::ostream& ostr)
|
||||
{
|
||||
for (NameValueCollection::ConstIterator it = begin(); it != end(); ++it)
|
||||
{
|
||||
if (it != begin()) ostr << "&";
|
||||
std::string name;
|
||||
URI::encode(it->first, "=&", name);
|
||||
std::string value;
|
||||
URI::encode(it->second, "=&", value);
|
||||
ostr << name << "=" << value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTMLForm::writeMultipart(std::ostream& ostr)
|
||||
{
|
||||
MultipartWriter writer(ostr, _boundary);
|
||||
for (NameValueCollection::ConstIterator it = begin(); it != end(); ++it)
|
||||
{
|
||||
MessageHeader header;
|
||||
std::string disp("form-data; name=\"");
|
||||
disp.append(it->first);
|
||||
disp.append("\"");
|
||||
header.set("Content-Disposition", disp);
|
||||
writer.nextPart(header);
|
||||
ostr << it->second;
|
||||
}
|
||||
for (PartVec::iterator ita = _parts.begin(); ita != _parts.end(); ++ita)
|
||||
{
|
||||
MessageHeader header;
|
||||
std::string disp("file; name=\"");
|
||||
disp.append(ita->name);
|
||||
disp.append("\"");
|
||||
std::string filename = ita->pSource->filename();
|
||||
if (!filename.empty())
|
||||
{
|
||||
disp.append("; filename=\"");
|
||||
disp.append(filename);
|
||||
disp.append("\"");
|
||||
}
|
||||
header.set("Content-Disposition", disp);
|
||||
header.set("Content-Type", ita->pSource->mediaType());
|
||||
writer.nextPart(header);
|
||||
StreamCopier::copyStream(ita->pSource->stream(), ostr);
|
||||
}
|
||||
writer.close();
|
||||
_boundary = writer.boundary();
|
||||
}
|
||||
|
||||
|
||||
Net_END
|
||||
Reference in New Issue
Block a user