Qore Programming Language  1.12.0
QC_SocketPollOperation.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3  QC_SocketPollOperation.h
4 
5  Qore Programming Language
6 
7  Copyright (C) 2003 - 2022 Qore Technologies, s.r.o.
8 
9  Permission is hereby granted, free of charge, to any person obtaining a
10  copy of this software and associated documentation files (the "Software"),
11  to deal in the Software without restriction, including without limitation
12  the rights to use, copy, modify, merge, publish, distribute, sublicense,
13  and/or sell copies of the Software, and to permit persons to whom the
14  Software is furnished to do so, subject to the following conditions:
15 
16  The above copyright notice and this permission notice shall be included in
17  all copies or substantial portions of the Software.
18 
19  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25  DEALINGS IN THE SOFTWARE.
26 
27  Note that the Qore library is released under a choice of three open-source
28  licenses: MIT (as above), LGPL 2+, or GPL 2+; see README-LICENSE for more
29  information.
30 */
31 
32 #ifndef _QORE_CLASS_SOCKETPOLLOPERATION_H
33 
34 #define _QORE_CLASS_SOCKETPOLLOPERATION_H
35 
36 #include "qore/intern/QC_SocketPollOperationBase.h"
37 #include "qore/intern/qore_socket_private.h"
38 #include "qore/QoreSocketObject.h"
39 
40 #include <memory>
41 
42 // goals: connect, connect-ssl
43 constexpr int SPG_CONNECT = 1;
44 constexpr int SPG_CONNECT_SSL = 2;
45 
46 // states: none -> connecting -> [connecting-ssl ->] connected
47 constexpr int SPS_NONE = 0;
48 constexpr int SPS_CONNECTING = 1;
49 constexpr int SPS_CONNECTING_SSL = 2;
50 constexpr int SPS_CONNECTED = 3;
51 
52 class SocketConnectPollOperation : public SocketPollOperationBase {
53 public:
54  DLLLOCAL SocketConnectPollOperation(ExceptionSink* xsink, bool ssl, const char* target, QoreSocketObject* sock);
55 
56  DLLLOCAL void deref(ExceptionSink* xsink) {
57  if (ROdereference()) {
58  if (set_non_block) {
59  sock->clearNonBlock();
60  }
61  sock->deref(xsink);
62  delete this;
63  }
64  }
65 
66  DLLLOCAL virtual bool goalReached() const {
67  return state == SPS_CONNECTED;
68  }
69 
70  DLLLOCAL virtual QoreHashNode* continuePoll(ExceptionSink* xsink);
71 
72 protected:
73  QoreSocketObject* sock;
74 
76  DLLLOCAL virtual int preVerify(ExceptionSink* xsink) {
77  return 0;
78  }
79 
81  DLLLOCAL virtual void connected();
82 
84  DLLLOCAL int startSslConnect(ExceptionSink* xsink);
85 
86 private:
87  std::unique_ptr<AbstractPollState> poll_state;
88  std::string target;
89 
90  int sgoal = 0;
91  int state = SPS_NONE;
92 
93  bool set_non_block = false;
94 
95  DLLLOCAL virtual const char* getStateImpl() const {
96  switch (state) {
97  case SPS_NONE:
98  return "none";
99  case SPS_CONNECTING:
100  return "connecting";
101  case SPS_CONNECTING_SSL:
102  return "connecting-ssl";
103  case SPS_CONNECTED:
104  return "connected";
105  default:
106  assert(false);
107  }
108  return "";
109  }
110 
111  DLLLOCAL int checkContinuePoll(ExceptionSink* xsink);
112 };
113 
114 class SocketSendPollOperation : public SocketPollOperationBase {
115 public:
116  // "data" must be passed already referenced
117  DLLLOCAL SocketSendPollOperation(ExceptionSink* xsink, QoreStringNode* data, QoreSocketObject* sock);
118 
119  // "data" must be passed already referenced
120  DLLLOCAL SocketSendPollOperation(ExceptionSink* xsink, BinaryNode* data, QoreSocketObject* sock);
121 
122  DLLLOCAL void deref(ExceptionSink* xsink) {
123  if (ROdereference()) {
124  if (set_non_block) {
125  sock->clearNonBlock();
126  }
127  sock->deref(xsink);
128  delete this;
129  }
130  }
131 
132  DLLLOCAL virtual bool goalReached() const {
133  return sent;
134  }
135 
136  DLLLOCAL virtual const char* getStateImpl() const {
137  return sent ? "sent" : "sending";
138  }
139 
140  DLLLOCAL virtual QoreHashNode* continuePoll(ExceptionSink* xsink);
141 
142 private:
143  std::unique_ptr<AbstractPollState> poll_state;
145  QoreSocketObject* sock;
146  const char* buf;
147  size_t size;
148  bool set_non_block = false;
149  bool sent = false;
150 };
151 
152 
153 class SocketRecvPollOperationBase : public SocketPollOperationBase {
154 public:
155  DLLLOCAL SocketRecvPollOperationBase(QoreSocketObject* sock, bool to_string) : sock(sock),
156  to_string(to_string) {
157  }
158 
159  DLLLOCAL virtual void deref(ExceptionSink* xsink) {
160  if (ROdereference()) {
161  if (set_non_block) {
162  sock->clearNonBlock();
163  }
164  sock->deref(xsink);
165  delete this;
166  }
167  }
168 
169  DLLLOCAL virtual bool goalReached() const {
170  return received;
171  }
172 
173  DLLLOCAL virtual const char* getStateImpl() const {
174  return received ? "received" : "receiving";
175  }
176 
177  DLLLOCAL virtual QoreValue getOutput() const {
178  return data ? data->refSelf() : QoreValue();
179  }
180 
181  DLLLOCAL virtual QoreHashNode* continuePoll(ExceptionSink* xsink);
182 
183 protected:
184  std::unique_ptr<AbstractPollState> poll_state;
186  QoreSocketObject* sock;
187  bool to_string;
188  bool set_non_block = false;
189  bool received = false;
190 
191  DLLLOCAL int initIntern(ExceptionSink* xsink);
192 };
193 
194 class SocketRecvPollOperation : public SocketRecvPollOperationBase {
195 public:
196  // "data" must be passed already referenced
197  DLLLOCAL SocketRecvPollOperation(ExceptionSink* xsink, ssize_t size, QoreSocketObject* sock, bool to_string);
198 
199 private:
200  size_t size;
201 };
202 
203 class SocketRecvUntilBytesPollOperation : public SocketRecvPollOperationBase {
204 public:
205  // "data" must be passed already referenced
206  DLLLOCAL SocketRecvUntilBytesPollOperation(ExceptionSink* xsink, const QoreStringNode* pattern,
207  QoreSocketObject* sock, bool to_string);
208 
209 private:
211 };
212 
213 class SocketUpgradeClientSslPollOperation : public SocketPollOperationBase {
214 public:
215  DLLLOCAL SocketUpgradeClientSslPollOperation(ExceptionSink* xsink, QoreSocketObject* sock);
216 
217  DLLLOCAL void deref(ExceptionSink* xsink) {
218  if (ROdereference()) {
219  if (set_non_block) {
220  sock->clearNonBlock();
221  }
222  sock->deref(xsink);
223  delete this;
224  }
225  }
226 
227  DLLLOCAL virtual bool goalReached() const {
228  return done;
229  }
230 
231  DLLLOCAL virtual QoreHashNode* continuePoll(ExceptionSink* xsink);
232 
233  DLLLOCAL virtual const char* getStateImpl() const {
234  return "connecting-ssl";
235  }
236 
237 private:
238  QoreSocketObject* sock;
239  std::unique_ptr<AbstractPollState> poll_state;
240  bool set_non_block = false;
241  bool done = false;
242 };
243 
244 DLLLOCAL QoreClass* initSocketPollOperationClass(QoreNamespace& qorens);
245 
246 #endif // _QORE_CLASS_SOCKETPOLLOPERATION_H
virtual DLLLOCAL void deref()
decrements the reference count of the object without the possibility of throwing a Qore-language exce...
Definition: AbstractPrivateData.h:65
holds arbitrary binary data
Definition: BinaryNode.h:41
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:48
defines a Qore-language class
Definition: QoreClass.h:249
This is the hash or associative list container type in Qore, dynamically allocated only,...
Definition: QoreHashNode.h:50
contains constants, classes, and subnamespaces in QoreProgram objects
Definition: QoreNamespace.h:65
DLLEXPORT bool ROdereference() const
atomically decrements the reference count
Qore's string value type, reference counted, dynamically-allocated only.
Definition: QoreStringNode.h:50
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:275
DLLEXPORT QoreValue refSelf() const
references the contained value if type == QV_Node, returns itself