📄 htmlform.cpp
字号:
//// HTMLForm.cpp//// $Id: //poco/1.2/Net/src/HTMLForm.cpp#3 $//// 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 "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"#include "Poco/Net/NullPartHandler.h"#include "Poco/NullStream.h"#include "Poco/StreamCopier.h"#include "Poco/Exception.h"#include "Poco/URI.h"#include "Poco/String.h"#include <sstream>#include <ctype.h>using Poco::NullInputStream;using Poco::StreamCopier;using Poco::SyntaxException;using Poco::URI;using Poco::icompare;namespace Poco {namespace Net {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& requestBody, PartHandler& handler){ load(request, requestBody, handler);}HTMLForm::HTMLForm(const HTTPRequest& request, std::istream& requestBody){ load(request, requestBody);}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_POST) { 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); } } else { URI uri(request.getURI()); std::istringstream istr(uri.getRawQuery()); readUrl(istr); }}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_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); } } else { std::string uri = request.getURI(); std::ostringstream ostr; write(ostr); uri.append("?"); uri.append(ostr.str()); request.setURI(uri); }}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); add(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 (params.has("filename")) { handler.handlePart(header, reader.stream()); // Ensure that the complete part has been read. while (reader.stream().good()) reader.stream().get(); } 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(); } add(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();}} } // namespace Poco::Net
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -