Skip to content

Commit 61e5754

Browse files
committed
Use Url class for url handling, support ipv6
1 parent 8b887fb commit 61e5754

File tree

7 files changed

+62
-29
lines changed

7 files changed

+62
-29
lines changed

lib/curlrequester.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
#include <cstring>
77
#include <thread>
88

9-
CurlRequester::CurlRequester(const std::string& addr, const SslConfig& sslConfig)
9+
CurlRequester::CurlRequester(const Url& addr, const SslConfig& sslConfig)
1010
: _curl(curl_easy_init())
1111
{
1212
bool debugEnabled = LogController::instance().isEnabled(LogController::Debug);
13-
curl_easy_setopt(_curl, CURLOPT_URL, addr.c_str());
13+
curl_easy_setopt(_curl, CURLOPT_URL, addr.toStr().c_str());
1414
curl_easy_setopt(_curl, CURLOPT_VERBOSE, debugEnabled);
1515
curl_easy_setopt(_curl, CURLOPT_CONNECTTIMEOUT_MS, 2000);
1616
curl_easy_setopt(_curl, CURLOPT_FAILONERROR, 1);
@@ -162,9 +162,8 @@ void CurlIppPosterBase::setCompression(Compression compression)
162162
deflateInit2(&_zstrm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, level, 7, Z_DEFAULT_STRATEGY);
163163
}
164164

165-
std::string http_url(const std::string& str)
165+
std::string http_url(Url& url)
166166
{
167-
Url url(str);
168167
if(url.getScheme() == "ipp")
169168
{
170169
url.setScheme("http");
@@ -184,7 +183,7 @@ std::string http_url(const std::string& str)
184183
return url.toStr();
185184
}
186185

187-
CurlIppPosterBase::CurlIppPosterBase(const std::string& addr, const SslConfig& sslConfig)
186+
CurlIppPosterBase::CurlIppPosterBase(Url addr, const SslConfig& sslConfig)
188187
: CurlRequester(http_url(addr), sslConfig)
189188
{
190189
_canWrite.unlock();
@@ -213,22 +212,22 @@ CURLcode CurlIppPosterBase::await(Bytestream* data)
213212
return CurlRequester::await(data);
214213
}
215214

216-
CurlIppPoster::CurlIppPoster(const std::string& addr, Bytestream&& data, const SslConfig& sslConfig)
215+
CurlIppPoster::CurlIppPoster(const Url& addr, Bytestream&& data, const SslConfig& sslConfig)
217216
: CurlIppPosterBase(addr, sslConfig)
218217
{
219218
curl_easy_setopt(_curl, CURLOPT_POSTFIELDSIZE, data.size());
220219
write(std::move(data));
221220
doRun();
222221
}
223222

224-
CurlIppStreamer::CurlIppStreamer(const std::string& addr, const SslConfig& sslConfig)
223+
CurlIppStreamer::CurlIppStreamer(const Url& addr, const SslConfig& sslConfig)
225224
: CurlIppPosterBase(addr, sslConfig)
226225
{
227226
_opts = curl_slist_append(_opts, "Transfer-Encoding: chunked");
228227
doRun();
229228
}
230229

231-
CurlHttpGetter::CurlHttpGetter(const std::string& addr, const SslConfig& sslConfig)
230+
CurlHttpGetter::CurlHttpGetter(const Url& addr, const SslConfig& sslConfig)
232231
: CurlRequester(addr, sslConfig)
233232
{
234233
doRun();

lib/curlrequester.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class CurlRequester
3333

3434
protected:
3535

36-
CurlRequester(const std::string& addr, const SslConfig& sslConfig);
36+
CurlRequester(const Url& addr, const SslConfig& sslConfig);
3737

3838
void doRun();
3939

@@ -99,7 +99,7 @@ class CurlIppPosterBase : public CurlRequester
9999
}
100100

101101
protected:
102-
CurlIppPosterBase(const std::string& addr, const SslConfig& sslConfig=SslConfig());
102+
CurlIppPosterBase(Url addr, const SslConfig& sslConfig=SslConfig());
103103

104104
private:
105105
std::mutex _canWrite;
@@ -115,19 +115,19 @@ class CurlIppPosterBase : public CurlRequester
115115
class CurlIppPoster : public CurlIppPosterBase
116116
{
117117
public:
118-
CurlIppPoster(const std::string& addr, Bytestream&& data, const SslConfig& sslConfig=SslConfig());
118+
CurlIppPoster(const Url& addr, Bytestream&& data, const SslConfig& sslConfig=SslConfig());
119119
};
120120

121121
class CurlIppStreamer : public CurlIppPosterBase
122122
{
123123
public:
124-
CurlIppStreamer(const std::string& addr, const SslConfig& sslConfig=SslConfig());
124+
CurlIppStreamer(const Url& addr, const SslConfig& sslConfig=SslConfig());
125125
};
126126

127127
class CurlHttpGetter : public CurlRequester
128128
{
129129
public:
130-
CurlHttpGetter(const std::string& addr, const SslConfig& sslConfig=SslConfig());
130+
CurlHttpGetter(const Url& addr, const SslConfig& sslConfig=SslConfig());
131131
};
132132

133133
#endif // CURLREQUESTER_H

lib/ippprinter.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
#include <filesystem>
88

9-
IppPrinter::IppPrinter(std::string addr, CurlRequester::SslConfig sslConfig)
9+
IppPrinter::IppPrinter(Url addr, CurlRequester::SslConfig sslConfig)
1010
: _addr(std::move(addr)), _sslConfig(std::move(sslConfig))
1111
{
1212
_error = refresh();
@@ -15,9 +15,13 @@ IppPrinter::IppPrinter(std::string addr, CurlRequester::SslConfig sslConfig)
1515
Error IppPrinter::refresh()
1616
{
1717
Error error;
18-
if(string_starts_with(_addr, "file://"))
18+
if(!_addr.isValid())
1919
{
20-
std::ifstream ifs(_addr.substr(7), std::ios::in | std::ios::binary);
20+
return Error("Invalid printer address.");
21+
}
22+
else if(_addr.getScheme() == "file")
23+
{
24+
std::ifstream ifs(_addr.getPath(), std::ios::in | std::ios::binary);
2125
if(!ifs)
2226
{
2327
return Error("Failed to open fake-printer file.");
@@ -78,7 +82,7 @@ Error IppPrinter::runJob(IppPrintJob& job, const std::string& inFile, const std:
7882
{
7983
return Error("No conversion method found for " + inFormat + " to " + job.targetFormat);
8084
}
81-
else if(string_starts_with(_addr, "file://"))
85+
else if(_addr.getScheme() == "file")
8286
{
8387
doPrintToFile(job, inFile, convertFun.value(), progressFun);
8488
}

lib/ippprinter.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class IppPrinter
3939
std::string stateMessage;
4040
};
4141

42-
IppPrinter(std::string addr, CurlRequester::SslConfig sslConfig);
42+
IppPrinter(Url addr, CurlRequester::SslConfig sslConfig);
4343
IppPrinter(IppAttrs printerAttrs) : _printerAttrs(std::move(printerAttrs))
4444
{}
4545
Error refresh();
@@ -106,7 +106,7 @@ class IppPrinter
106106
const IppAttrs& printerAttrs=IppAttrs()) const;
107107
void _applyOverrides();
108108

109-
std::string _addr;
109+
Url _addr;
110110
CurlRequester::SslConfig _sslConfig;
111111
bool _printJobId = false;
112112

lib/url.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
class Url
88
{
99
public:
10-
Url() = delete;
10+
Url() = default;
1111
Url(const std::string& str)
1212
{
1313
match(str);
@@ -83,7 +83,7 @@ class Url
8383

8484
void match(const std::string& str)
8585
{
86-
static const std::regex regex("(([a-z]+)://)([a-z0-9-.]+)(:([0-9]+))?(/.*)?$");
86+
static const std::regex regex("(([a-z]+)://)((\\[[:a-z-A-Z0-9]+\\])|([a-z0-9-.]*))(:([0-9]+))?(/.*)?$");
8787
std::smatch match;
8888

8989
_valid = false;
@@ -97,15 +97,15 @@ class Url
9797
_valid = true;
9898
_scheme = match[2];
9999
_host = match[3];
100-
_port = match[5] == "" ? 0 : stoul(match[5]);
101-
_path = match[6];
100+
_port = match[7] == "" ? 0 : stoul(match[7]);
101+
_path = match[8];
102102
}
103103
}
104104

105-
bool _valid;
105+
bool _valid = false;
106106
std::string _scheme;
107107
std::string _host;
108-
uint16_t _port;
108+
uint16_t _port = 0;
109109
std::string _path;
110110
};
111111

tests/test.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2468,13 +2468,15 @@ TEST(malicious_dns)
24682468
TEST(url)
24692469
{
24702470
Url url("ipp://myprinter:631/ipp/print");
2471+
ASSERT(url.isValid());
24712472
ASSERT(url.getScheme() == "ipp");
24722473
ASSERT(url.getHost() == "myprinter");
24732474
ASSERT(url.getPort() == 631);
24742475
ASSERT(url.getPath() == "/ipp/print");
24752476
ASSERT(url.toStr() == "ipp://myprinter:631/ipp/print");
24762477

24772478
url = "ipp://myprinter/ipp/print";
2479+
ASSERT(url.isValid());
24782480
ASSERT(url.getScheme() == "ipp");
24792481
ASSERT(url.getHost() == "myprinter");
24802482
ASSERT(url.getPort() == 0);
@@ -2486,6 +2488,7 @@ TEST(url)
24862488
ASSERT(url.toStr() == "ipp://myprinter:631/ipp/print");
24872489

24882490
url = "ipp://myprinter";
2491+
ASSERT(url.isValid());
24892492
ASSERT(url.getScheme() == "ipp");
24902493
ASSERT(url.getHost() == "myprinter");
24912494
ASSERT(url.getPort() == 0);
@@ -2499,9 +2502,34 @@ TEST(url)
24992502
ASSERT(url.toStr() == "ipps://yourprinter:666/foo/bar");
25002503

25012504
url = "foo/bar/baz";
2505+
ASSERT_FALSE(url.isValid());
25022506
ASSERT(url.getScheme() == "");
25032507
ASSERT(url.getHost() == "");
25042508
ASSERT(url.getPort() == 0);
25052509
ASSERT(url.getPath() == "");
25062510
ASSERT(url.toStr() == "");
2511+
2512+
url = "file:///foo/bar/baz";
2513+
ASSERT(url.isValid());
2514+
ASSERT(url.getScheme() == "file");
2515+
ASSERT(url.getHost() == "");
2516+
ASSERT(url.getPort() == 0);
2517+
ASSERT(url.getPath() == "/foo/bar/baz");
2518+
ASSERT(url.toStr() == "file:///foo/bar/baz");
2519+
2520+
url = "ipp://127.0.0.1/ipp/print";
2521+
ASSERT(url.isValid());
2522+
ASSERT(url.getScheme() == "ipp");
2523+
ASSERT(url.getHost() == "127.0.0.1");
2524+
ASSERT(url.getPort() == 0);
2525+
ASSERT(url.getPath() == "/ipp/print");
2526+
ASSERT(url.toStr() == "ipp://127.0.0.1/ipp/print");
2527+
2528+
url = "ipp://[::1]:631/ipp/print";
2529+
ASSERT(url.isValid());
2530+
ASSERT(url.getScheme() == "ipp");
2531+
ASSERT(url.getHost() == "[::1]");
2532+
ASSERT(url.getPort() == 631);
2533+
ASSERT(url.getPath() == "/ipp/print");
2534+
ASSERT(url.toStr() == "ipp://[::1]:631/ipp/print");
25072535
}

utils/ippclient.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ int main(int argc, char** argv)
196196

197197
int id;
198198

199-
std::string addr;
199+
std::string addrString;
200200
std::string attrs;
201201
std::string inFile;
202202

@@ -249,7 +249,7 @@ int main(int argc, char** argv)
249249

250250
SwitchArg<int> idOpt(id, {"--id"}, "Id of print job.");
251251

252-
PosArg addrArg(addr, "printer address");
252+
PosArg addrArg(addrString, "printer address");
253253
PosArg attrsArg(attrs, "name=value[,name=value]");
254254
PosArg pdfArg(inFile, "input file");
255255

@@ -293,13 +293,15 @@ int main(int argc, char** argv)
293293
LogController::instance().enable(LogController::Debug);
294294
}
295295

296-
if(verifySslOpt.isSet() && !string_starts_with(addr, "ipps://"))
296+
Url addr(addrString);
297+
298+
if(verifySslOpt.isSet() && addr.getScheme() != "ipps")
297299
{
298300
std::cerr << "--verify-ssl given, but address is not ipps." << std::endl;
299301
return 1;
300302
}
301303

302-
if(pinnedPublicKeyOpt.isSet() && !string_starts_with(addr, "ipps://"))
304+
if(pinnedPublicKeyOpt.isSet() && addr.getScheme() != "ipps")
303305
{
304306
std::cerr << "--ssl-pubkey given, but address is not ipps." << std::endl;
305307
return 1;

0 commit comments

Comments
 (0)