NCBI C++ ToolKit
http_reply.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef HTTP_REPLY__HPP
2 #define HTTP_REPLY__HPP
3 
4 /* $Id: http_reply.hpp 101030 2023-10-18 12:38:48Z satskyse $
5  * ===========================================================================
6  *
7  * PUBLIC DOMAIN NOTICE
8  * National Center for Biotechnology Information
9  *
10  * This software/database is a "United States Government Work" under the
11  * terms of the United States Copyright Act. It was written as part of
12  * the author's official duties as a United States Government employee and
13  * thus cannot be copyrighted. This software/database is freely available
14  * to the public for use. The National Library of Medicine and the U.S.
15  * Government have not placed any restriction on its use or reproduction.
16  *
17  * Although all reasonable efforts have been taken to ensure the accuracy
18  * and reliability of the software and data, the NLM and the U.S.
19  * Government do not and cannot warrant the performance or results that
20  * may be obtained by using this software or data. The NLM and the U.S.
21  * Government disclaim all warranties, express or implied, including
22  * warranties of performance, merchantability or fitness for any particular
23  * purpose.
24  *
25  * Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Authors: Dmitri Dmitrienko
30  *
31  * File Description:
32  *
33  */
34 
35 #include <atomic>
36 
37 #include "pending_operation.hpp"
39 
40 
41 static const char * k_ReasonOK = "OK";
42 static const char * k_ReasonAccepted = "Accepted";
43 static const char * k_InternalServerError = "Internal Server Error";
44 static const char * k_BadGateway = "Bad Gateway";
45 static const char * k_ServiceUnavailable = "Service Unavailable";
46 static const char * k_Conflict = "Conflict";
47 static const char * k_NotFound = "Not Found";
48 static const char * k_Unauthorized = "Unauthorized";
49 static const char * k_BadRequest = "Bad Request";
50 
51 void OnLibh2oFinished(size_t request_id);
52 
53 class CHttpProto;
54 class CHttpConnection;
55 
56 
58 {
59  h2o_generator_t m_Generator;
60  size_t m_RequestId;
61  void * m_HttpReply;
62 
64  m_RequestId(0),
66  {
67  m_Generator.stop = nullptr;
68  m_Generator.proceed = nullptr;
69  }
70 };
71 
73 {
74 public:
75  enum EReplyState {
79  };
80 
81  CHttpReply(h2o_req_t * req,
82  CHttpProto * proto,
83  CHttpConnection * http_conn,
84  const char * cd_uid) :
85  m_Req(req),
87  m_RequestId(0),
94  m_HttpProto(proto),
95  m_HttpConn(http_conn),
96  m_DataReady(make_shared<CDataTrigger>(proto)),
98  m_CdUid(cd_uid)
99  {}
100 
101 
102  CHttpReply(const CHttpReply&) = delete;
103  CHttpReply(CHttpReply&&) = delete;
104  CHttpReply& operator=(const CHttpReply&) = delete;
106 
108  {
109  PSG_TRACE("~CHttpReply");
110  x_Clear();
111  }
112 
113  void AssignPendingReq(unique_ptr<CPendingOperation> pending_req)
114  {
115  m_PendingReqs.emplace_back(move(pending_req));
116  }
117 
118  // The method is used only when the reply is finished.
119  // See the comments at the point of invocation.
121  {
122  for (auto req: m_PendingReqs) {
123  req = nullptr;
124  }
125  m_PendingReqs.clear();
126  }
127 
128  void SetContentLength(uint64_t content_length)
129  {
130  if (m_State == eReplyInitialized) {
131  m_Req->res.content_length = content_length;
132  } else {
133  NCBI_THROW(CPubseqGatewayException, eReplyAlreadyStarted,
134  "Reply has already started");
135  }
136  }
137 
138  void SetRequestId(size_t request_id)
139  {
140  m_RequestId = request_id;
141  }
142 
144  {
145  m_ReplyContentType = mime_type;
146  }
147 
148  size_t GetBytesSent(void) const
149  {
150  if (m_Req)
151  return m_Req->bytes_sent;
152  return 0;
153  }
154 
155  void Send(const char * payload, size_t payload_len,
156  bool is_persist, bool is_last)
157  {
158  if (payload_len == 0) {
159  if (is_last) {
160  // If it is not the last and there is nothing to send then the
161  // call will do nothing
162  x_DoSend(nullptr, 0, true);
163  }
164  } else {
165  h2o_iovec_t body;
166  if (is_persist) {
167  body.base = (char*)payload;
168  body.len = payload_len;
169  } else {
170  body = h2o_strdup(&m_Req->pool, payload, payload_len);
171  }
172  x_DoSend(&body, payload_len > 0 ? 1 : 0, is_last);
173  }
174  }
175 
176  void Send(std::vector<h2o_iovec_t> & payload, bool is_last)
177  {
178  size_t payload_size = payload.size();
179  if (payload_size > 0 || is_last) {
180  if (payload_size > 0)
181  x_DoSend(&payload.front(), payload_size, is_last);
182  else
183  x_DoSend(nullptr, payload_size, is_last);
184  }
185  }
186 
188  {
190  }
191 
192  void SendOk(const char * payload, size_t payload_len, bool is_persist)
193  { Send(payload, payload_len, is_persist, true); }
194 
195  void Send202(const char * payload, size_t payload_len)
196  {
197  h2o_iovec_t body = h2o_strdup(&m_Req->pool, payload, payload_len);
198  x_DoSend(&body, 1, true, 202, k_ReasonAccepted);
199  }
200 
201  void Send400(const char * payload)
202  { x_GenericSendError(400, k_BadRequest, payload); }
203 
204  void Send401(const char * payload)
205  { x_GenericSendError(401, k_Unauthorized, payload); }
206 
207  void Send404(const char * payload)
208  { x_GenericSendError(404, k_NotFound, payload); }
209 
210  void Send409(const char * payload)
211  { x_GenericSendError(409, k_Conflict, payload); }
212 
213  void Send500(const char * payload)
214  { x_GenericSendError(500, k_InternalServerError, payload); }
215 
216  void Send502(const char * payload)
217  { x_GenericSendError(502, k_BadGateway, payload); }
218 
219  void Send503(const char * payload)
220  { x_GenericSendError(503, k_ServiceUnavailable, payload); }
221 
223  { return m_HttpConn; }
224 
225  void PeekPending(void)
226  {
227  try {
228  if (!m_Postponed)
229  NCBI_THROW(CPubseqGatewayException, eRequestNotPostponed,
230  "Request has not been postponed");
231  for (auto req: m_PendingReqs) {
232  req->Peek(true);
233  }
234  } catch (const std::exception & e) {
235  Error(e.what());
236  } catch (...) {
237  Error("unexpected failure");
238  }
239  }
240 
241  void CancelPending(bool from_flush=false)
242  {
243  if (!from_flush) {
244  if (!m_Postponed)
245  NCBI_THROW(CPubseqGatewayException, eRequestNotPostponed,
246  "Request has not been postponed");
247  }
248  x_DoCancel();
249  }
250 
251  EReplyState GetState(void) const
252  { return m_State; }
253 
254  bool IsFinished(void) const
255  { return m_State >= eReplyFinished; }
256 
257  bool IsOutputReady(void) const
258  { return m_OutputIsReady; }
259 
260  bool IsPostponed(void) const
261  { return m_Postponed; }
262 
263  bool IsClosed(void) const;
264 
265  bool IsCompleted(void) const
266  { return m_Completed; }
267 
268  void SetCompleted(void);
269 
270  void SetPostponed(void)
271  { m_Postponed = true; }
272 
273  list<shared_ptr<CPendingOperation>> & GetPendingReqs(void)
274  {
275  if (m_PendingReqs.empty())
276  NCBI_THROW(CPubseqGatewayException, ePendingReqNotAssigned,
277  "There are no assigned pending requests");
278  return m_PendingReqs;
279  }
280 
281  h2o_iovec_t PrepareChunk(const unsigned char * data, unsigned int size)
282  {
283  if (m_Req)
284  return h2o_strdup(&m_Req->pool,
285  reinterpret_cast<const char*>(data), size);
286 
287  NCBI_THROW(CPubseqGatewayException, eRequestPoolNotAvailable,
288  "Request pool is not available");
289  }
290 
292  { return m_DataReady->CheckResetTriggered(); }
293 
294  void Error(const char * what)
295  {
296  switch (m_State) {
297  case eReplyInitialized:
299  break;
300  case eReplyStarted:
301  Send(nullptr, 0, true, true); // break
302  break;
303  default:;
304  }
305  CancelPending();
306  }
307 
308  shared_ptr<CCassDataCallbackReceiver> GetDataReadyCB(void)
309  { return static_pointer_cast<CCassDataCallbackReceiver>(m_DataReady); }
310 
311 private:
313  {
314  public:
315  CDataTrigger(const CDataTrigger & from) = delete;
316  CDataTrigger & operator=(const CDataTrigger & from) = delete;
317  CDataTrigger(CDataTrigger && from) = default;
318  CDataTrigger & operator=(CDataTrigger && from) = default;
319 
322  m_Proto(proto)
323  {}
324 
325  virtual void OnData() override;
326 
328  {
329  bool b = true;
330  return m_Triggered.compare_exchange_weak(b, false);
331  }
332 
333  private:
334  std::atomic<bool> m_Triggered;
336  };
337 
338  void AssignGenerator(void)
339  {
340  if (m_RespGenerator != nullptr) {
341  PSG_ERROR("A responce generator is created more than once "
342  "for an http reply. Request ID: " << m_RequestId);
343  }
344 
345  // The memory will be freed by libh2o
347  h2o_mem_alloc_shared(&m_Req->pool,
348  sizeof(SRespGenerator),
353  m_RespGenerator->m_HttpReply = (void *)(this);
354  }
355 
356  void NeedOutput(void);
357 
358  // Called by HTTP daemon when there is no way to send any further data
359  // using this connection
360  void StopCB(void)
361  {
362  PSG_TRACE("CHttpReply::Stop");
363  m_OutputIsReady = true;
364  m_OutputFinished = true;
365  if (m_State != eReplyFinished) {
366  PSG_TRACE("CHttpReply::Stop: need cancel");
367  x_DoCancel();
368  NeedOutput();
369  }
370 
371  if (m_RespGenerator != nullptr) {
372  m_RespGenerator->m_Generator.stop = nullptr;
373  m_RespGenerator->m_Generator.proceed = nullptr;
374  }
375  m_Req = nullptr;
376  }
377 
378  // Called by HTTP daemon after data has already been sent and
379  // it is ready for the next portion
380  void ProceedCB(void)
381  {
382  PSG_TRACE("CHttpReply::Proceed");
383  m_OutputIsReady = true;
384  NeedOutput();
385  }
386 
387  static void s_StopCB(h2o_generator_t * _generator, h2o_req_t * req)
388  {
389  SRespGenerator * gen = (SRespGenerator*)(_generator);
390  CHttpReply * http_reply = (CHttpReply*)(gen->m_HttpReply);
391 
392  http_reply->StopCB();
393  }
394 
395  static void s_ProceedCB(h2o_generator_t * _generator, h2o_req_t * req)
396  {
397  SRespGenerator * gen = (SRespGenerator*)(_generator);
398  CHttpReply * http_reply = (CHttpReply*)(gen->m_HttpReply);
399 
400  http_reply->ProceedCB();
401  }
402 
403  static void s_GeneratorDisposalCB(void * gen)
404  {
405  SRespGenerator * generator = (SRespGenerator*)(gen);
406  OnLibh2oFinished(generator->m_RequestId);
407  }
408 
409  // true => OK
410  // false => No action possible
411  bool x_ConnectionPrecheck(size_t count, bool is_last);
412 
413  void x_HandleConnectionState(int status, const char * reason)
414  {
415  switch (m_State) {
416  case eReplyInitialized:
417  if (!m_Canceled) {
419  x_SetCdUid();
421  m_Req->res.status = status;
422  m_Req->res.reason = reason;
423  AssignGenerator();
424  m_OutputIsReady = false;
425  h2o_start_response(m_Req, &(m_RespGenerator->m_Generator));
426  }
427  break;
428  case eReplyStarted:
429  break;
430  case eReplyFinished:
431  NCBI_THROW(CPubseqGatewayException, eRequestAlreadyFinished,
432  "Request has already been finished");
433  break;
434  }
435  }
436 
437  void x_DoSend(h2o_iovec_t * vec, size_t count, bool is_last,
438  int status=200, const char * reason=k_ReasonOK)
439  {
440  if (!x_ConnectionPrecheck(count, is_last))
441  return;
442 
443  PSG_TRACE("x_DoSend: " << count << " chunks, "
444  "is_last: " << is_last << ", state: " << m_State);
445 
446  x_HandleConnectionState(status, reason);
447 
448  if (m_Canceled) {
450  x_SendCanceled();
451  } else {
452  m_OutputIsReady = false;
453  h2o_send(m_Req, vec, count,
454  is_last ? H2O_SEND_STATE_FINAL : H2O_SEND_STATE_IN_PROGRESS);
455  }
456 
457  if (is_last) {
459  m_OutputFinished = true;
460  }
461  }
462 
463  void x_SendPsg503(const string & msg,
465  {
466  CPSGS_Reply high_level_reply(this);
467  high_level_reply.PrepareReplyMessage(
469  err_code, eDiag_Error);
470 
471  psg_time_point_t start_timestamp;
472  if (m_PendingReqs.empty())
473  start_timestamp = psg_clock_t::now();
474  else
475  start_timestamp = m_PendingReqs.front()->GetStartTimestamp();
476 
478  start_timestamp);
479  high_level_reply.Flush(CPSGS_Reply::ePSGS_SendAndFinish);
480  high_level_reply.SetCompleted();
481  }
482 
483  void x_SendCanceled(void)
484  {
486  x_SendPsg503("Request has been canceled", ePSGS_RequestCancelled);
487  }
488  }
489 
490  void x_DoCancel(void);
491  void x_GenericSendError(int status, const char * head,
492  const char * payload);
493 
494  void x_SetContentType(void)
495  {
497  return;
498 
499  if (m_State != eReplyInitialized)
500  NCBI_THROW(CPubseqGatewayException, eReplyAlreadyStarted,
501  "Reply has already started");
502 
503  switch (m_ReplyContentType) {
504  case ePSGS_JsonMime:
505  h2o_add_header(&m_Req->pool,
506  &m_Req->res.headers,
507  H2O_TOKEN_CONTENT_TYPE, NULL,
508  H2O_STRLIT("application/json"));
509  break;
510  case ePSGS_HtmlMime:
511  h2o_add_header(&m_Req->pool,
512  &m_Req->res.headers,
513  H2O_TOKEN_CONTENT_TYPE, NULL,
514  H2O_STRLIT("text/html"));
515  break;
516  case ePSGS_BinaryMime:
517  h2o_add_header(&m_Req->pool,
518  &m_Req->res.headers,
519  H2O_TOKEN_CONTENT_TYPE, NULL,
520  H2O_STRLIT("application/octet-stream"));
521  break;
522  case ePSGS_PlainTextMime:
523  h2o_add_header(&m_Req->pool,
524  &m_Req->res.headers,
525  H2O_TOKEN_CONTENT_TYPE, NULL,
526  H2O_STRLIT("text/plain"));
527  break;
528  case ePSGS_ImageMime:
529  h2o_add_header(&m_Req->pool,
530  &m_Req->res.headers,
531  H2O_TOKEN_CONTENT_TYPE, NULL,
532  H2O_STRLIT("image/x-icon"));
533  break;
534  case ePSGS_PSGMime:
535  h2o_add_header(&m_Req->pool,
536  &m_Req->res.headers,
537  H2O_TOKEN_CONTENT_TYPE, NULL,
538  H2O_STRLIT("application/x-ncbi-psg"));
539  break;
540  default:
541  // Well, it is not good but without the content type everything
542  // will still work.
543  PSG_WARNING("Unknown content type " << m_ReplyContentType);
544  }
545  }
546 
547  void x_SetCdUid(void)
548  {
549  if (m_CdUid != nullptr) {
550  static int cd_uid_size = strlen(m_CdUid);
551  h2o_add_header_by_str(&m_Req->pool, &m_Req->res.headers,
552  H2O_STRLIT("X-CD-UID"), 0, NULL,
553  m_CdUid, cd_uid_size);
554  }
555  }
556 
557  void x_Clear(void)
558  {
559  for (auto req: m_PendingReqs) {
560  req = nullptr;
561  }
562  m_PendingReqs.clear();
563 
564  m_Req = nullptr;
565  m_OutputIsReady = true;
566  m_OutputFinished = false;
567  m_Postponed = false;
568  m_Canceled = false;
569  m_Completed = false;
571  m_HttpProto = nullptr;
572  m_HttpConn = nullptr;
574  }
575 
576  h2o_req_t * m_Req;
577 
578  // The memory is allocated in the libh2o pool. Thus there is no need to
579  // call 'delete m_RespGenerator;' in the client code.
581  size_t m_RequestId;
582 
591 
592  list<shared_ptr<CPendingOperation>> m_PendingReqs;
593 
594  shared_ptr<CDataTrigger> m_DataReady;
596  const char * m_CdUid;
597 };
598 
599 #endif
600 
void NeedOutput(void)
Definition: http_reply.cpp:161
void x_HandleConnectionState(int status, const char *reason)
Definition: http_reply.hpp:413
CHttpReply(CHttpReply &&)=delete
void x_SetContentType(void)
Definition: http_reply.hpp:494
void SetContentLength(uint64_t content_length)
Definition: http_reply.hpp:128
CHttpConnection * GetHttpConnection(void)
Definition: http_reply.hpp:222
CHttpReply(h2o_req_t *req, CHttpProto *proto, CHttpConnection *http_conn, const char *cd_uid)
Definition: http_reply.hpp:81
void Send202(const char *payload, size_t payload_len)
Definition: http_reply.hpp:195
h2o_iovec_t PrepareChunk(const unsigned char *data, unsigned int size)
Definition: http_reply.hpp:281
void SetPostponed(void)
Definition: http_reply.hpp:270
void SetCompleted(void)
Definition: http_reply.cpp:79
CHttpReply & operator=(const CHttpReply &)=delete
void AssignGenerator(void)
Definition: http_reply.hpp:338
void Send401(const char *payload)
Definition: http_reply.hpp:204
bool IsCompleted(void) const
Definition: http_reply.hpp:265
bool IsPostponed(void) const
Definition: http_reply.hpp:260
void SetRequestId(size_t request_id)
Definition: http_reply.hpp:138
void Send409(const char *payload)
Definition: http_reply.hpp:210
CHttpReply(const CHttpReply &)=delete
size_t GetBytesSent(void) const
Definition: http_reply.hpp:148
void CancelPending(bool from_flush=false)
Definition: http_reply.hpp:241
EReplyState GetState(void) const
Definition: http_reply.hpp:251
h2o_req_t * m_Req
Definition: http_reply.hpp:576
SRespGenerator * m_RespGenerator
Definition: http_reply.hpp:580
void Send404(const char *payload)
Definition: http_reply.hpp:207
CHttpConnection * m_HttpConn
Definition: http_reply.hpp:590
void x_SendPsg503(const string &msg, EPSGS_PubseqGatewayErrorCode err_code)
Definition: http_reply.hpp:463
static void s_ProceedCB(h2o_generator_t *_generator, h2o_req_t *req)
Definition: http_reply.hpp:395
CHttpReply & operator=(CHttpReply &&)=delete
CHttpProto * m_HttpProto
Definition: http_reply.hpp:589
bool m_Canceled
Definition: http_reply.hpp:586
void x_SetCdUid(void)
Definition: http_reply.hpp:547
bool m_OutputIsReady
Definition: http_reply.hpp:583
size_t m_RequestId
Definition: http_reply.hpp:581
static void s_GeneratorDisposalCB(void *gen)
Definition: http_reply.hpp:403
void x_DoSend(h2o_iovec_t *vec, size_t count, bool is_last, int status=200, const char *reason=k_ReasonOK)
Definition: http_reply.hpp:437
bool IsOutputReady(void) const
Definition: http_reply.hpp:257
void ResetPendingRequest(void)
Definition: http_reply.hpp:120
bool m_Completed
Definition: http_reply.hpp:587
bool IsFinished(void) const
Definition: http_reply.hpp:254
void x_Clear(void)
Definition: http_reply.hpp:557
void AssignPendingReq(unique_ptr< CPendingOperation > pending_req)
Definition: http_reply.hpp:113
bool CheckResetDataTriggered(void)
Definition: http_reply.hpp:291
void x_SendCanceled(void)
Definition: http_reply.hpp:483
bool m_OutputFinished
Definition: http_reply.hpp:584
void ProceedCB(void)
Definition: http_reply.hpp:380
void x_GenericSendError(int status, const char *head, const char *payload)
Definition: http_reply.cpp:102
shared_ptr< CDataTrigger > m_DataReady
Definition: http_reply.hpp:594
void Send400(const char *payload)
Definition: http_reply.hpp:201
bool IsClosed(void) const
Definition: http_reply.cpp:73
void Send502(const char *payload)
Definition: http_reply.hpp:216
shared_ptr< CCassDataCallbackReceiver > GetDataReadyCB(void)
Definition: http_reply.hpp:308
list< shared_ptr< CPendingOperation > > & GetPendingReqs(void)
Definition: http_reply.hpp:273
void SetContentType(EPSGS_ReplyMimeType mime_type)
Definition: http_reply.hpp:143
const char * m_CdUid
Definition: http_reply.hpp:596
void x_DoCancel(void)
Definition: http_reply.cpp:89
static void s_StopCB(h2o_generator_t *_generator, h2o_req_t *req)
Definition: http_reply.hpp:387
void Send503(const char *payload)
Definition: http_reply.hpp:219
void Send(std::vector< h2o_iovec_t > &payload, bool is_last)
Definition: http_reply.hpp:176
EReplyState m_State
Definition: http_reply.hpp:588
void Error(const char *what)
Definition: http_reply.hpp:294
void Send500(const char *payload)
Definition: http_reply.hpp:213
list< shared_ptr< CPendingOperation > > m_PendingReqs
Definition: http_reply.hpp:592
void StopCB(void)
Definition: http_reply.hpp:360
EPSGS_ReplyMimeType m_ReplyContentType
Definition: http_reply.hpp:595
void PeekPending(void)
Definition: http_reply.hpp:225
@ eReplyInitialized
Definition: http_reply.hpp:76
void Send(const char *payload, size_t payload_len, bool is_persist, bool is_last)
Definition: http_reply.hpp:155
bool m_Postponed
Definition: http_reply.hpp:585
void NotifyClientConnectionDrop(void)
Definition: http_reply.hpp:187
bool x_ConnectionPrecheck(size_t count, bool is_last)
Definition: http_reply.cpp:46
void SendOk(const char *payload, size_t payload_len, bool is_persist)
Definition: http_reply.hpp:192
@ ePSGS_SendAndFinish
Definition: psgs_reply.hpp:55
void PrepareReplyMessage(const string &msg, CRequestStatus::ECode status, int err_code, EDiagSev severity, bool need_update_last_activity=true)
void PrepareReplyCompletion(CRequestStatus::ECode status, const psg_time_point_t &create_timestamp)
void SetCompleted(void)
Definition: psgs_reply.cpp:87
void Flush(EPSGS_ReplyFlush how)
Definition: psgs_reply.cpp:57
#define head
Definition: ct_nlmzip_i.h:138
#define true
Definition: bool.h:35
#define false
Definition: bool.h:36
char data[12]
Definition: iconv.c:80
Uint8 uint64_t
#define NULL
Definition: ncbistd.hpp:225
@ eDiag_Error
Error message.
Definition: ncbidiag.hpp:653
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
static const char * k_Unauthorized
Definition: http_reply.hpp:48
static const char * k_Conflict
Definition: http_reply.hpp:46
static const char * k_BadGateway
Definition: http_reply.hpp:44
static const char * k_ReasonAccepted
Definition: http_reply.hpp:42
static const char * k_NotFound
Definition: http_reply.hpp:47
static const char * k_BadRequest
Definition: http_reply.hpp:49
static const char * k_ReasonOK
Definition: http_reply.hpp:41
static const char * k_ServiceUnavailable
Definition: http_reply.hpp:45
void OnLibh2oFinished(size_t request_id)
Definition: http_reply.cpp:39
static const char * k_InternalServerError
Definition: http_reply.hpp:43
const struct ncbi::grid::netcache::search::fields::SIZE size
#define nullptr
Definition: ncbimisc.hpp:45
#define PSG_ERROR(message)
#define PSG_WARNING(message)
#define PSG_TRACE(message)
@ ePSGS_JsonMime
@ ePSGS_BinaryMime
@ ePSGS_ImageMime
@ ePSGS_PlainTextMime
@ ePSGS_HtmlMime
EPSGS_PubseqGatewayErrorCode
@ ePSGS_UnknownError
@ ePSGS_RequestCancelled
psg_clock_t::time_point psg_time_point_t
CDataTrigger(CDataTrigger &&from)=default
CDataTrigger(const CDataTrigger &from)=delete
bool CheckResetTriggered(void)
Definition: http_reply.hpp:327
virtual void OnData() override
Definition: http_reply.cpp:172
CDataTrigger(CHttpProto *proto)
Definition: http_reply.hpp:320
CDataTrigger & operator=(const CDataTrigger &from)=delete
std::atomic< bool > m_Triggered
Definition: http_reply.hpp:334
CDataTrigger & operator=(CDataTrigger &&from)=default
size_t m_RequestId
Definition: http_reply.hpp:60
void * m_HttpReply
Definition: http_reply.hpp:61
h2o_generator_t m_Generator
Definition: http_reply.hpp:59
Modified on Sun Apr 14 05:25:48 2024 by modify_doxy.py rev. 669887