Skip to content

Commit e6bc6e9

Browse files
authored
use cow types in zhttp packets (#48275)
1 parent 72adf51 commit e6bc6e9

14 files changed

+217
-119
lines changed

src/core/cowbytearray.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,15 @@ class CowByteArray
8080
{
8181
public:
8282
CowByteArray() = default;
83+
CowByteArray(const CowByteArray &other): inner_(other.inner_) {}
8384
CowByteArray(CowByteArrayConstRef ref): inner_(ref.inner_) {}
8485
CowByteArray(CowByteArrayRef ref): inner_(ref.inner_) {}
8586
CowByteArray(const char *data, ssize_t size = -1) : inner_(data, size) {}
8687
CowByteArray(ssize_t size, char ch) : inner_(size, ch) {}
8788
CowByteArray(const QByteArray &other) : inner_(other) {}
89+
CowByteArray & operator=(const CowByteArray &other) { inner_ = other.inner_; return *this; }
8890

91+
bool isNull() const { return inner_.isNull(); }
8992
bool isEmpty() const { return inner_.isEmpty(); }
9093
ssize_t size() const { return inner_.size(); }
9194
ssize_t length() const { return size(); }
@@ -95,6 +98,7 @@ class CowByteArray
9598
ssize_t indexOf(char ch, ssize_t from = 0) const { return inner_.indexOf(ch, from); }
9699
CowByteArray mid(ssize_t pos, ssize_t len = -1) const { return inner_.mid(pos, len); }
97100

101+
void clear() { inner_.clear(); }
98102
void resize(ssize_t size) { inner_.resize(size); }
99103

100104
char operator[](ssize_t i) const { return inner_[(qsizetype)i]; }

src/core/cowbytearraytest.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,14 @@ static void constructors()
6464

6565
static void methods()
6666
{
67+
// isNull
68+
CowByteArray n;
69+
TEST_ASSERT(n.isNull());
70+
TEST_ASSERT(n.isEmpty());
71+
6772
// isEmpty
68-
CowByteArray empty;
73+
CowByteArray empty("");
74+
TEST_ASSERT(!empty.isNull());
6975
TEST_ASSERT(empty.isEmpty());
7076

7177
// size and length
@@ -88,6 +94,12 @@ static void methods()
8894
TEST_ASSERT_EQ(b, "hel");
8995
TEST_ASSERT_EQ(c, "lo");
9096

97+
// clear
98+
CowByteArray d("hello");
99+
TEST_ASSERT(!d.isEmpty());
100+
d.clear();
101+
TEST_ASSERT(d.isEmpty());
102+
91103
// resize down
92104
a.resize(3);
93105
TEST_ASSERT_EQ(a, "hel");
@@ -99,7 +111,10 @@ static void methods()
99111

100112
static void operators()
101113
{
102-
CowByteArray a("hello");
114+
CowByteArray a;
115+
a = CowByteArray("hello");
116+
TEST_ASSERT_EQ(a, "hello");
117+
103118
TEST_ASSERT_EQ(std::as_const(a)[1], 'e');
104119
TEST_ASSERT_EQ(a[1], 'e');
105120

src/core/cowstring.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,34 @@
2626
class CowString
2727
{
2828
public:
29+
CowString() = default;
30+
CowString(const CowString &other): inner_(other.inner_) {}
31+
CowString(const char *str) : inner_(str) {}
2932
CowString(const QString &other) : inner_(other) {}
33+
CowString & operator=(const CowString &other) { inner_ = other.inner_; return *this; }
34+
35+
bool isEmpty() const { return inner_.isEmpty(); }
36+
37+
void clear() { inner_.clear(); }
3038

3139
CowByteArray toUtf8() const { return inner_.toUtf8(); }
3240

3341
const QString & asQString() const { return inner_; }
3442
QString & asQString() { return inner_; }
3543

44+
friend bool operator==(const CowString &lhs, const CowString &rhs);
45+
friend bool operator==(const CowString &lhs, const char *const &rhs);
46+
friend bool operator==(const char *const &lhs, const CowString &rhs);
47+
3648
private:
3749
QString inner_;
3850
};
3951

52+
inline bool operator==(const CowString &lhs, const CowString &rhs) { return lhs.inner_ == rhs.inner_; }
53+
inline bool operator==(const CowString &lhs, const char *const &rhs) { return lhs.inner_ == rhs; }
54+
inline bool operator==(const char *const &lhs, const CowString &rhs) { return lhs == rhs.inner_; }
55+
inline bool operator!=(const CowString &lhs, const CowString &rhs) { return !(lhs == rhs); }
56+
inline bool operator!=(const CowString &lhs, const char *const &rhs) { return !(lhs == rhs); }
57+
inline bool operator!=(const char *const &lhs, const CowString &rhs) { return !(lhs == rhs); }
58+
4059
#endif

src/core/cowstringtest.cpp

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,71 @@
2323
#include "test.h"
2424
#include "cowstring.h"
2525

26-
static void basicUsage()
26+
static void constructors()
2727
{
28-
CowString s("hello");
29-
CowByteArray a = s.toUtf8();
30-
TEST_ASSERT_EQ(s.asQString().toUtf8(), a.asQByteArray());
28+
// default
29+
CowString a;
30+
TEST_ASSERT(a.isEmpty());
31+
32+
// char*
33+
CowString b("hello");
34+
TEST_ASSERT_EQ(b, "hello");
35+
36+
// copy
37+
CowString c(b);
38+
TEST_ASSERT_EQ(c, "hello");
39+
40+
// QString
41+
QString qs("hello");
42+
CowString d(qs);
43+
TEST_ASSERT_EQ(d, "hello");
44+
}
45+
46+
static void methods()
47+
{
48+
// isEmpty
49+
CowString empty;
50+
TEST_ASSERT(empty.isEmpty());
51+
52+
// clear
53+
CowString a("hello");
54+
TEST_ASSERT(!a.isEmpty());
55+
a.clear();
56+
TEST_ASSERT(a.isEmpty());
57+
58+
// toUtf8
59+
CowString b("hello");
60+
CowByteArray ba = b.toUtf8();
61+
TEST_ASSERT_EQ(ba, "hello");
62+
}
63+
64+
static void operators()
65+
{
66+
CowString a;
67+
a = CowString("hello");
68+
TEST_ASSERT_EQ(a, "hello");
69+
70+
TEST_ASSERT(CowString("hello") == CowString("hello"));
71+
TEST_ASSERT(CowString("hello") == "hello");
72+
TEST_ASSERT("hello" == CowString("hello"));
73+
74+
TEST_ASSERT(CowString("hello") != CowString("world"));
75+
TEST_ASSERT(CowString("hello") != "world");
76+
TEST_ASSERT("hello" != CowString("world"));
77+
}
78+
79+
static void conversions()
80+
{
81+
CowString a("hello");
82+
TEST_ASSERT_EQ(a, "hello");
3183
}
3284

3385
extern "C" int cowstring_test(ffi::TestException *out_ex)
3486
{
35-
TEST_CATCH(basicUsage());
87+
TEST_CATCH(constructors());
88+
TEST_CATCH(methods());
89+
TEST_CATCH(operators());
90+
TEST_CATCH(conversions());
3691

3792
return 0;
3893
}

src/core/zhttpmanager.cpp

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ class ZhttpManager::Private
359359
out.from = instanceId;
360360
out.ids += ZhttpResponsePacket::Id(id);
361361
out.type = ZhttpResponsePacket::Cancel;
362-
write(type, out, packet.from, packet.routerResp);
362+
write(type, out, packet.from.asQByteArray(), packet.routerResp);
363363
}
364364
}
365365

@@ -577,10 +577,10 @@ class ZhttpManager::Private
577577

578578
const ZhttpResponsePacket::Id &id = p.ids.first();
579579

580-
ZhttpRequest *req = clientReqsByRid.value(ZhttpRequest::Rid(instanceId, id.id));
580+
ZhttpRequest *req = clientReqsByRid.value(ZhttpRequest::Rid(instanceId, id.id.asQByteArray()));
581581
if(req)
582582
{
583-
req->handle(id.id, id.seq, p);
583+
req->handle(id.id.asQByteArray(), id.seq, p);
584584
if(self.expired())
585585
return;
586586

@@ -628,21 +628,21 @@ class ZhttpManager::Private
628628
foreach(const ZhttpResponsePacket::Id &id, p.ids)
629629
{
630630
// is this for a websocket?
631-
ZWebSocket *sock = clientSocksByRid.value(ZWebSocket::Rid(instanceId, id.id));
631+
ZWebSocket *sock = clientSocksByRid.value(ZWebSocket::Rid(instanceId, id.id.asQByteArray()));
632632
if(sock)
633633
{
634-
sock->handle(id.id, id.seq, p);
634+
sock->handle(id.id.asQByteArray(), id.seq, p);
635635
if(self.expired())
636636
return;
637637

638638
continue;
639639
}
640640

641641
// is this for an http request?
642-
ZhttpRequest *req = clientReqsByRid.value(ZhttpRequest::Rid(instanceId, id.id));
642+
ZhttpRequest *req = clientReqsByRid.value(ZhttpRequest::Rid(instanceId, id.id.asQByteArray()));
643643
if(req)
644644
{
645-
req->handle(id.id, id.seq, p);
645+
req->handle(id.id.asQByteArray(), id.seq, p);
646646
if(self.expired())
647647
return;
648648

@@ -738,18 +738,18 @@ class ZhttpManager::Private
738738

739739
if(p.uri.scheme() == "wss" || p.uri.scheme() == "ws")
740740
{
741-
ZWebSocket::Rid rid(p.from, id.id);
741+
ZWebSocket::Rid rid(p.from.asQByteArray(), id.id.asQByteArray());
742742

743743
ZWebSocket *sock = serverSocksByRid.value(rid);
744744
if(sock)
745745
{
746746
log_warning("zws server: received message for existing request id, canceling");
747-
tryRespondCancel(WebSocketSession, id.id, p);
747+
tryRespondCancel(WebSocketSession, id.id.asQByteArray(), p);
748748
return;
749749
}
750750

751751
sock = new ZWebSocket;
752-
if(!sock->setupServer(q, id.id, id.seq, p))
752+
if(!sock->setupServer(q, id.id.asQByteArray(), id.seq, p))
753753
{
754754
delete sock;
755755
return;
@@ -765,18 +765,18 @@ class ZhttpManager::Private
765765
}
766766
else if(p.uri.scheme() == "https" || p.uri.scheme() == "http")
767767
{
768-
ZhttpRequest::Rid rid(p.from, id.id);
768+
ZhttpRequest::Rid rid(p.from.asQByteArray(), id.id.asQByteArray());
769769

770770
ZhttpRequest *req = serverReqsByRid.value(rid);
771771
if(req)
772772
{
773773
log_warning("zhttp server: received message for existing request id, canceling");
774-
tryRespondCancel(HttpSession, id.id, p);
774+
tryRespondCancel(HttpSession, id.id.asQByteArray(), p);
775775
return;
776776
}
777777

778778
req = new ZhttpRequest;
779-
if(!req->setupServer(q, id.id, id.seq, p))
779+
if(!req->setupServer(q, id.id.asQByteArray(), id.seq, p))
780780
{
781781
delete req;
782782
return;
@@ -793,7 +793,7 @@ class ZhttpManager::Private
793793
else
794794
{
795795
log_debug("zhttp/zws server: rejecting unsupported scheme: %s", qPrintable(p.uri.scheme()));
796-
tryRespondCancel(UnknownSession, id.id, p);
796+
tryRespondCancel(UnknownSession, id.id.asQByteArray(), p);
797797
return;
798798
}
799799
}
@@ -841,21 +841,21 @@ class ZhttpManager::Private
841841
foreach(const ZhttpRequestPacket::Id &id, p.ids)
842842
{
843843
// is this for a websocket?
844-
ZWebSocket *sock = serverSocksByRid.value(ZWebSocket::Rid(p.from, id.id));
844+
ZWebSocket *sock = serverSocksByRid.value(ZWebSocket::Rid(p.from.asQByteArray(), id.id.asQByteArray()));
845845
if(sock)
846846
{
847-
sock->handle(id.id, id.seq, p);
847+
sock->handle(id.id.asQByteArray(), id.seq, p);
848848
if(self.expired())
849849
return;
850850

851851
continue;
852852
}
853853

854854
// is this for an http request?
855-
ZhttpRequest *req = serverReqsByRid.value(ZhttpRequest::Rid(p.from, id.id));
855+
ZhttpRequest *req = serverReqsByRid.value(ZhttpRequest::Rid(p.from.asQByteArray(), id.id.asQByteArray()));
856856
if(req)
857857
{
858-
req->handle(id.id, id.seq, p);
858+
req->handle(id.id.asQByteArray(), id.seq, p);
859859
if(self.expired())
860860
return;
861861

src/core/zhttprequest.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -211,10 +211,10 @@ class ZhttpRequest::Private
211211
if(packet.credits != -1)
212212
outCredits = packet.credits;
213213

214-
requestMethod = packet.method;
214+
requestMethod = packet.method.asQString();
215215
requestUri = packet.uri;
216216
requestHeaders = packet.headers;
217-
requestBodyBuf += packet.body;
217+
requestBodyBuf += packet.body.asQByteArray();
218218

219219
passthrough = packet.passthrough;
220220

@@ -519,7 +519,7 @@ class ZhttpRequest::Private
519519
if(packet.type == ZhttpRequestPacket::Error)
520520
{
521521
errored = true;
522-
errorCondition = convertError(packet.condition);
522+
errorCondition = convertError(packet.condition.asQByteArray());
523523

524524
log_debug("zhttp server: error id=%s cond=%s", id.data(), packet.condition.data());
525525

@@ -581,7 +581,7 @@ class ZhttpRequest::Private
581581

582582
if(packet.type == ZhttpRequestPacket::Data)
583583
{
584-
requestBodyBuf += packet.body;
584+
requestBodyBuf += packet.body.asQByteArray();
585585

586586
bool done = haveRequestBody;
587587

@@ -646,15 +646,15 @@ class ZhttpRequest::Private
646646
return;
647647
}
648648

649-
toAddress = packet.from;
649+
toAddress = packet.from.asQByteArray();
650650

651651
state = ClientRequesting;
652652

653653
startKeepAlive();
654654
}
655655
else if(state == ClientRequestFinishWait)
656656
{
657-
toAddress = packet.from;
657+
toAddress = packet.from.asQByteArray();
658658

659659
state = ClientReceiving;
660660

@@ -665,7 +665,7 @@ class ZhttpRequest::Private
665665
if(packet.type == ZhttpResponsePacket::Error)
666666
{
667667
errored = true;
668-
errorCondition = convertError(packet.condition);
668+
errorCondition = convertError(packet.condition.asQByteArray());
669669

670670
log_debug("zhttp client: error id=%s cond=%s", id.data(), packet.condition.data());
671671

@@ -739,7 +739,7 @@ class ZhttpRequest::Private
739739
haveResponseValues = true;
740740

741741
responseCode = packet.code;
742-
responseReason = packet.reason;
742+
responseReason = packet.reason.asQByteArray();
743743
responseHeaders = packet.headers;
744744

745745
needToSendHeaders = true;
@@ -756,7 +756,7 @@ class ZhttpRequest::Private
756756
log_warning("zhttp client: id=%s server is sending too fast", id.data());
757757
}
758758

759-
responseBodyBuf += packet.body;
759+
responseBodyBuf += packet.body.asQByteArray();
760760

761761
if(packet.more)
762762
{
@@ -1421,7 +1421,7 @@ bool ZhttpRequest::setupServer(ZhttpManager *manager, const QByteArray &id, int
14211421
{
14221422
d->manager = manager;
14231423
d->server = true;
1424-
d->rid = Rid(packet.from, id);
1424+
d->rid = Rid(packet.from.asQByteArray(), id);
14251425
return d->setupServer(seq, packet);
14261426
}
14271427

0 commit comments

Comments
 (0)