aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mod/build-config.cxx4
-rw-r--r--mod/mod-package-details.cxx2
-rw-r--r--mod/mod-package-version-details.cxx6
-rw-r--r--mod/mod-repository-details.cxx4
-rw-r--r--mod/page.cxx8
-rw-r--r--web/apache/request.cxx27
-rw-r--r--web/mime-url-encoding.cxx124
-rw-r--r--web/mime-url-encoding.hxx23
8 files changed, 71 insertions, 127 deletions
diff --git a/mod/build-config.cxx b/mod/build-config.cxx
index aa25511..cbde252 100644
--- a/mod/build-config.cxx
+++ b/mod/build-config.cxx
@@ -118,9 +118,9 @@ namespace brep
// the package version into the URL path part and so don't encode it.
//
string url (host + root.representation () +
- mime_url_encode (b.package_name) + '/' +
+ mime_url_encode (b.package_name, false) + '/' +
b.package_version.string () + "/log/" +
- mime_url_encode (b.configuration) + '/' +
+ mime_url_encode (b.configuration, false) + '/' +
b.toolchain_version.string ());
if (op != nullptr)
diff --git a/mod/mod-package-details.cxx b/mod/mod-package-details.cxx
index dce7f3b..ca2b94a 100644
--- a/mod/mod-package-details.cxx
+++ b/mod/mod-package-details.cxx
@@ -75,7 +75,7 @@ handle (request& rq, response& rs)
const dir_path& root (options_->root ());
const string& name (*rq.path ().rbegin ());
- const string ename (mime_url_encode (name));
+ const string ename (mime_url_encode (name, false));
params::package_details params;
bool full;
diff --git a/mod/mod-package-version-details.cxx b/mod/mod-package-version-details.cxx
index 134fb9a..26838f7 100644
--- a/mod/mod-package-version-details.cxx
+++ b/mod/mod-package-version-details.cxx
@@ -130,7 +130,9 @@ handle (request& rq, response& rs)
s << DIV(ID="heading")
<< H1
- << A(HREF=root / path (mime_url_encode (name))) << name << ~A
+ << A(HREF=root / path (mime_url_encode (name, false)))
+ << name
+ << ~A
<< "/"
<< A(HREF=url ()) << sver << ~A
<< ~H1
@@ -255,7 +257,7 @@ handle (request& rq, response& rs)
const auto& dcon (d.constraint);
const string& dname (p->id.name);
- string ename (mime_url_encode (dname));
+ string ename (mime_url_encode (dname, false));
if (r->url)
{
diff --git a/mod/mod-repository-details.cxx b/mod/mod-repository-details.cxx
index 177f49d..53cd3aa 100644
--- a/mod/mod-repository-details.cxx
+++ b/mod/mod-repository-details.cxx
@@ -99,7 +99,9 @@ handle (request& rq, response& rs)
//
string id (html_id (r.name));
s << H1(ID=id)
- << A(HREF="#" + web::mime_url_encode (id)) << r.display_name << ~A
+ << A(HREF="#" + web::mime_url_encode (id, false))
+ << r.display_name
+ << ~A
<< ~H1;
if (r.summary)
diff --git a/mod/page.cxx b/mod/page.cxx
index a7ec087..566406e 100644
--- a/mod/page.cxx
+++ b/mod/page.cxx
@@ -188,7 +188,7 @@ namespace brep
// Propagate search criteria to the package details page.
//
- << root_ / path (mime_url_encode (name_)) << query_param_
+ << root_ / path (mime_url_encode (name_, false)) << query_param_
<< ~HREF
<< name_
@@ -218,7 +218,7 @@ namespace brep
else
{
assert (root_ != nullptr);
- s << A(HREF=*root_ / dir_path (mime_url_encode (*package_)) /
+ s << A(HREF=*root_ / dir_path (mime_url_encode (*package_, false)) /
path (version_))
<< version_;
@@ -393,7 +393,7 @@ namespace brep
? p->internal_repository.load ()
: p->other_repositories[0].load ());
- auto en (mime_url_encode (n));
+ auto en (mime_url_encode (n, false));
if (r->url)
s << A(HREF=*r->url + en) << n << ~A;
@@ -542,7 +542,7 @@ namespace brep
<< SPAN(CLASS="value")
<< A
<< HREF
- << root_ << "?about#" << mime_url_encode (html_id (name_))
+ << root_ << "?about#" << mime_url_encode (html_id (name_), false)
<< ~HREF
<< name_
<< ~A
diff --git a/web/apache/request.cxx b/web/apache/request.cxx
index 3393555..51590e3 100644
--- a/web/apache/request.cxx
+++ b/web/apache/request.cxx
@@ -18,7 +18,6 @@
#include <memory> // unique_ptr
#include <string>
#include <cassert>
-#include <sstream>
#include <ostream>
#include <istream>
#include <cstring> // str*(), memcpy(), size_t
@@ -353,7 +352,7 @@ namespace web
{
if (path_.empty ())
{
- path_ = path_type (rec_->uri);
+ path_ = path_type (rec_->uri); // Is already URL-decoded.
// Module request handler can not be called if URI is empty.
//
@@ -514,10 +513,9 @@ namespace web
{
assert (!buffer); // Cookie buffering is not implemented yet.
- ostringstream s;
- mime_url_encode (name, s);
- s << "=";
- mime_url_encode (value, s);
+ string s (mime_url_encode (name));
+ s += "=";
+ s += mime_url_encode (value);
if (max_age)
{
@@ -528,20 +526,27 @@ namespace web
//
char b[100];
strftime (b, sizeof (b), "%a, %d-%b-%Y %H:%M:%S GMT", gmtime (&t));
- s << "; Expires=" << b;
+ s += "; Expires=";
+ s += b;
}
if (path)
- s << ";Path=" << path;
+ {
+ s += ";Path=";
+ s += path;
+ }
if (domain)
- s << ";Domain=" << domain;
+ {
+ s += ";Domain=";
+ s += domain;
+ }
if (secure)
- s << ";Secure";
+ s += ";Secure";
state (request_state::headers);
- apr_table_add (rec_->err_headers_out, "Set-Cookie", s.str ().c_str ());
+ apr_table_add (rec_->err_headers_out, "Set-Cookie", s.c_str ());
}
void request::
diff --git a/web/mime-url-encoding.cxx b/web/mime-url-encoding.cxx
index e0022bc..00f8852 100644
--- a/web/mime-url-encoding.cxx
+++ b/web/mime-url-encoding.cxx
@@ -4,132 +4,64 @@
#include <web/mime-url-encoding.hxx>
-#include <ios> // hex, uppercase, right
#include <string>
-#include <iomanip> // setw(), setfill()
-#include <ostream>
-#include <sstream>
-#include <cstring> // size_t, strspn()
-#include <stdexcept> // invalid_argument
+#include <iterator> // back_inserter
+
+#include <libbutl/url.mxx>
using namespace std;
+using namespace butl;
namespace web
{
- // Encode characters different from unreserved ones specified in
- // "2.3. Unreserved Characters" of http://tools.ietf.org/html/rfc3986.
- //
- void
- mime_url_encode (const char* v, ostream& o)
+ inline static bool
+ encode_query (char& c)
{
- char f (o.fill ());
- ostream::fmtflags g (o.flags ());
- o << hex << uppercase << right << setfill ('0');
-
- char c;
- while ((c = *v++) != '\0')
+ if (c == ' ')
{
- if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
- (c >= '0' && c <= '9'))
- {
- o << c;
- }
- else
- {
- switch (c)
- {
- case ' ': o << '+'; break;
- case '.':
- case '_':
- case '-':
- case '~': o << c; break;
- default:
- {
- o << "%" << setw (2) << static_cast<unsigned short> (c);
- break;
- }
- }
- }
+ c = '+';
+ return false;
}
- o.flags (g);
- o.fill (f);
+ return !url::unreserved (c);
}
string
- mime_url_encode (const char* v)
+ mime_url_encode (const char* v, bool query)
{
- stringstream o;
- mime_url_encode (v, o);
- return o.str ();
+ return query ? url::encode (v, encode_query) : url::encode (v);
}
string
- mime_url_encode (const string& v)
+ mime_url_encode (const string& v, bool query)
{
- return mime_url_encode (v.c_str ());
+ return query ? url::encode (v, encode_query) : url::encode (v);
}
string
- mime_url_decode (const char* b, const char* e, bool trim)
+ mime_url_decode (const char* b, const char* e, bool trim, bool query)
{
if (trim)
{
- b += strspn (b, " ");
+ for (; b != e && *b == ' '; ++b) ;
- if (b >= e)
+ if (b == e)
return string ();
while (*--e == ' ');
++e;
}
- string value;
- value.reserve (e - b);
-
- char bf[3];
- bf[2] = '\0';
-
- while (b != e)
- {
- char c (*b++);
- switch (c)
- {
- case '+':
- {
- value.append (" ");
- break;
- }
- case '%':
- {
- if (*b == '\0' || b[1] == '\0')
- {
- throw invalid_argument ("::web::mime_url_decode short");
- }
-
- *bf = *b;
- bf[1] = b[1];
-
- char* ebf (nullptr);
- size_t vl (strtoul (bf, &ebf, 16));
-
- if (*ebf != '\0')
- {
- throw invalid_argument ("::web::mime_url_decode wrong");
- }
-
- value.append (1, static_cast<char> (vl));
- b += 2;
- break;
- }
- default:
- {
- value.append (1, c);
- break;
- }
- }
- }
-
- return value;
+ string r;
+ if (!query)
+ url::decode (b, e, back_inserter (r));
+ else
+ url::decode (b, e, back_inserter (r),
+ [] (char& c)
+ {
+ if (c == '+')
+ c = ' ';
+ });
+ return r;
}
}
diff --git a/web/mime-url-encoding.hxx b/web/mime-url-encoding.hxx
index d45f4ca..f748738 100644
--- a/web/mime-url-encoding.hxx
+++ b/web/mime-url-encoding.hxx
@@ -6,25 +6,28 @@
#define WEB_MIME_URL_ENCODING_HXX
#include <string>
-#include <iosfwd>
namespace web
{
- // @@ Add the query flag (true by default). If true, then the encoding is
- // applied to the URL query part, and so the plus character is used to
- // encode the space character. Audit use cases afterwards.
+ // URL-encode characters other than unreserved (see RFC3986). If the query
+ // flag is true, then the encoding is applied to the URL query part, and so
+ // convert space characters to plus characters rather than percent-encode
+ // them.
//
- void
- mime_url_encode (const char* v, std::ostream& o);
-
std::string
- mime_url_encode (const char* v);
+ mime_url_encode (const char*, bool query = true);
std::string
- mime_url_encode (const std::string& v);
+ mime_url_encode (const std::string&, bool query = true);
+ // If the query flag is true, then convert plus characters to space
+ // characters (see above). Throw std::invalid_argument if an invalid encoding
+ // sequence is encountered.
+ //
std::string
- mime_url_decode (const char* b, const char* e, bool trim = false);
+ mime_url_decode (const char* b, const char* e,
+ bool trim = false,
+ bool query = true);
}
#endif // WEB_MIME_URL_ENCODING_HXX