Skip to content

Commit 4586b62

Browse files
committedAug 23, 2023
Fix parsing urls containing colon in path element
1 parent 0899f7c commit 4586b62

File tree

5 files changed

+54
-23
lines changed

5 files changed

+54
-23
lines changed
 

Diff for: ‎include/restc-cpp/Url.h

+11-11
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#ifndef RESTC_CPP_URL_H_
44
#define RESTC_CPP_URL_H_
55

6-
#include <boost/utility/string_ref.hpp>
6+
#include <boost/utility/string_view.hpp>
77

88
namespace restc_cpp {
99

@@ -20,19 +20,19 @@ namespace restc_cpp {
2020

2121
Url& operator = (const char *url);
2222

23-
boost::string_ref GetProtocolName() const { return protocol_name_; }
24-
boost::string_ref GetHost() const { return host_; }
25-
boost::string_ref GetPort() const { return port_; }
26-
boost::string_ref GetPath() const { return path_; }
27-
boost::string_ref GetArgs() const { return args_; }
23+
boost::string_view GetProtocolName() const { return protocol_name_; }
24+
boost::string_view GetHost() const { return host_; }
25+
boost::string_view GetPort() const { return port_; }
26+
boost::string_view GetPath() const { return path_; }
27+
boost::string_view GetArgs() const { return args_; }
2828
Protocol GetProtocol() const { return protocol_; }
2929

3030
private:
31-
boost::string_ref protocol_name_;
32-
boost::string_ref host_;
33-
boost::string_ref port_;
34-
boost::string_ref path_ = "/";
35-
boost::string_ref args_;
31+
boost::string_view protocol_name_;
32+
boost::string_view host_;
33+
boost::string_view port_;
34+
boost::string_view path_ = "/";
35+
boost::string_view args_;
3636
Protocol protocol_ = Protocol::UNKNOWN;
3737
};
3838

Diff for: ‎include/restc-cpp/url_encode.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
1+
#pragma once
2+
3+
#ifndef RESTC_CPP_URL_ENCODE_H_
4+
#define RESTC_CPP_URL_ENCODE_H_
5+
16
#include "restc-cpp.h"
27

8+
#include <boost/utility/string_view.hpp>
9+
310
namespace restc_cpp {
411

5-
std::string url_encode(const boost::string_ref& src);
12+
std::string url_encode(const boost::string_view& src);
613

714
} // namespace
15+
16+
#endif // RESTC_CPP_URL_ENCODE_H_

Diff for: ‎src/Url.cpp

+14-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include <cassert>
22
#include <array>
33

4-
#include <boost/utility/string_ref.hpp>
4+
#include <boost/utility/string_view.hpp>
55
#include "restc-cpp/restc-cpp.h"
66
#include "restc-cpp/Url.h"
77
#include "restc-cpp/error.h"
@@ -28,44 +28,48 @@ Url& Url::operator = (const char *url) {
2828
constexpr auto magic_7 = 7;
2929

3030
assert(url != nullptr && "A valid URL is required");
31-
protocol_name_ = boost::string_ref(url);
31+
protocol_name_ = boost::string_view(url);
3232
if (protocol_name_.find("https://") == 0) {
33-
protocol_name_ = boost::string_ref(url, magic_8);
33+
protocol_name_ = boost::string_view(url, magic_8);
3434
protocol_ = Protocol::HTTPS;
3535
} else if (protocol_name_.find("http://") == 0) {
36-
protocol_name_ = boost::string_ref(url, magic_7);
36+
protocol_name_ = boost::string_view(url, magic_7);
3737
protocol_ = Protocol::HTTP;
3838
} else {
3939
throw ParseException("Invalid protocol in url. Must be 'http[s]://'");
4040
}
4141

42-
auto remains = boost::string_ref(protocol_name_.end());
42+
auto remains = boost::string_view(protocol_name_.end());
4343
const auto args_start = remains.find('?');
4444
if (args_start != string::npos) {
4545
args_ = {remains.begin() + args_start + 1,
4646
remains.size() - (args_start + 1)};
4747
remains = {remains.begin(), args_start};
4848
}
49+
auto path_start = remains.find('/');
4950
const auto port_start = remains.find(':');
50-
if (port_start != string::npos) {
51+
if (port_start != string::npos &&
52+
( path_start == string::npos ||
53+
port_start < path_start )
54+
) {
5155
if (remains.length() <= static_cast<decltype(host_.length())>(port_start + 2)) {
5256
throw ParseException("Invalid host (no port after column)");
5357
}
54-
//port_ = boost::string_ref(&remains[port_start+1]);
55-
//host_ = boost::string_ref(host_.data(), port_start);
58+
//port_ = boost::string_view(&remains[port_start+1]);
59+
//host_ = boost::string_view(host_.data(), port_start);
5660
host_ = {remains.begin(), port_start};
5761
remains = {remains.begin() + port_start + 1, remains.size() - (port_start + 1)};
5862

59-
const auto path_start = remains.find('/');
6063
if (path_start != string::npos) {
64+
//path_start = remains.find('/');
65+
path_start -= port_start + 1;
6166
path_ = {remains.begin() + path_start, remains.size() - path_start};// &port_[path_start];
6267
port_ = {remains.begin(), path_start};
6368
remains = {};
6469
} else {
6570
port_ = remains;
6671
}
6772
} else {
68-
const auto path_start = remains.find('/');
6973
if (path_start != string::npos) {
7074
//path_ = &host_[path_start];
7175
//host_ = boost::string_ref(host_.data(), path_start);

Diff for: ‎src/url_encode.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ allchars_t get_normal_ch() {
3535

3636
} // anonymous namespace
3737

38-
std::string url_encode(const boost::string_ref& src) {
38+
std::string url_encode(const boost::string_view& src) {
3939
constexpr auto magic_4 = 4;
4040
constexpr auto magic_0x0f = 0x0f;
4141

Diff for: ‎tests/unit/UrlTests.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@ TEST(Url, UrlWithPathAndSlash)
4949
EXPECT_EQ("/jgaa/"s, url.GetPath());
5050
}
5151

52+
TEST(Url, UrlWithPathInclColon)
53+
{
54+
Url url("http://github.com/jgaa:test");
55+
EXPECT_EQ("github.com"s, url.GetHost());
56+
EXPECT_EQ("80"s, url.GetPort());
57+
EXPECT_EQ_ENUM(Url::Protocol::HTTP, url.GetProtocol());
58+
EXPECT_EQ("/jgaa:test"s, url.GetPath());
59+
}
60+
5261
TEST(Url, HttpWithPort)
5362
{
5463
Url url("http://github.com:56");
@@ -85,6 +94,15 @@ TEST(Url, HttpWithPortAndPath)
8594
EXPECT_EQ("/jgaa"s, url.GetPath());
8695
}
8796

97+
TEST(Url, HttpWithPortAndPathInclColon)
98+
{
99+
Url url("http://github.com:12345/jgaa:test");
100+
EXPECT_EQ("github.com"s, url.GetHost());
101+
EXPECT_EQ("12345"s, url.GetPort());
102+
EXPECT_EQ_ENUM(Url::Protocol::HTTP, url.GetProtocol());
103+
EXPECT_EQ("/jgaa:test"s, url.GetPath());
104+
}
105+
88106
TEST(Url, HttpWithPortAndPathPath)
89107
{
90108
Url url("http://github.com:12345/jgaa/andmore");

0 commit comments

Comments
 (0)
Please sign in to comment.