first working RSS collection with async DB-Saves
[citadel.git] / citadel / event_client.h
1 #define EV_COMPAT3 0
2 #include <ev.h>
3 #include <sys/types.h>
4 #include <sys/socket.h>
5 #include <netdb.h>
6 #include <arpa/nameser.h>
7 #include <ares.h>
8 #include <curl/curl.h>
9
10 typedef struct AsyncIO AsyncIO;
11
12 typedef enum _eNextState {
13         eSendDNSQuery,
14         eReadDNSReply,
15         eConnect,
16         eSendReply, 
17         eSendMore,
18         eReadMessage, 
19         eTerminateConnection,
20         eAbort
21 }eNextState;
22
23 typedef eNextState (*IO_CallBack)(AsyncIO *IO);
24 typedef eReadState (*IO_LineReaderCallback)(AsyncIO *IO);
25 typedef void (*ParseDNSAnswerCb)(AsyncIO*, unsigned char*, int);
26 typedef void (*FreeDNSReply)(void *DNSData);
27
28 typedef struct _DNSQueryParts {
29         ParseDNSAnswerCb DNS_CB;
30         IO_CallBack PostDNS;
31
32         int DNSStatus;
33         void *VParsedDNSReply;
34         FreeDNSReply DNSReplyFree;
35         void *Data;
36 } DNSQueryParts;
37
38 typedef struct _evcurl_request_data 
39 {
40         CURL              *chnd;
41         struct curl_slist *headers;
42         char               errdesc[CURL_ERROR_SIZE];
43
44         int                attached;
45
46         char              *PlainPostData;
47         long               PlainPostDataLen;
48         StrBuf            *PostData;
49
50         StrBuf            *ReplyData;
51         long               httpcode;
52 } evcurl_request_data;
53
54 struct AsyncIO {
55         eNextState NextState;
56
57         /* connection related */
58         ParsedURL *ConnectMe;
59         
60         /* read/send related... */
61         StrBuf *IOBuf;
62         IOBuffer SendBuf, 
63                 RecvBuf;
64
65         /* our events... */
66         ev_cleanup abort_by_shutdown; /* server wants to go down... */
67         ev_timer conn_fail,           /* connection establishing timed out */
68                 rw_timeout;           /* timeout while sending data */
69         ev_idle unwind_stack,         /* get c-ares out of the stack */
70                 conn_fail_immediate;  /* unwind stack, but fail immediately. */
71         ev_io recv_event,             /* receive data from the client */
72                 send_event,           /* send more data to the client */
73                 conn_event;           /* Connection successfully established */
74
75         StrBuf *ErrMsg; /* if we fail to connect, or lookup, error goes here. */
76
77         /* Citadel application callbacks... */
78         IO_CallBack ReadDone, /* Theres new data to read... */
79                 SendDone,     /* we may send more data */
80                 Terminate,    /* shutting down... */
81                 Timeout,      /* Timeout handler; may also be connection timeout */
82                 ConnFail,     /* What to do when one connection failed? */
83                 ShutdownAbort;/* we're going down. make your piece. */ 
84
85         IO_LineReaderCallback LineReader; /* if we have linereaders, maybe we want to read more lines before the real application logic is called? */
86
87         /* DNS Related */
88         ev_io dns_recv_event, 
89                 dns_send_event;
90         struct ares_options DNSOptions;
91         ares_channel DNSChannel;
92         DNSQueryParts *DNSQuery;
93         
94         evcurl_request_data HttpReq;
95
96         /* Saving / loading a message async from / to disk */
97
98         struct CtdlMessage *AsyncMsg;
99         struct recptypes *AsyncRcp;
100         /* Custom data; its expected to contain  AsyncIO so we can save malloc()s... */
101         void *Data;        /* application specific data */
102         void *CitContext;  /* Citadel Session context... */
103 };
104
105 typedef struct _IOAddHandler {
106         AsyncIO *IO;
107         IO_CallBack EvAttch;
108 }IOAddHandler; 
109
110 void FreeAsyncIOContents(AsyncIO *IO);
111
112 void NextDBOperation(AsyncIO *IO, IO_CallBack CB);
113 int QueueDBOperation(AsyncIO *IO, IO_CallBack CB);
114 int QueueEventContext(AsyncIO *IO, IO_CallBack CB);
115 int ShutDownEventQueue(void);
116
117 eNextState InitEventIO(AsyncIO *IO, 
118                        void *pData, 
119                        double conn_timeout, 
120                        double first_rw_timeout,
121                        int ReadFirst);
122 void IO_postdns_callback(struct ev_loop *loop, ev_idle *watcher, int revents);
123
124 int QueueQuery(ns_type Type, const char *name, AsyncIO *IO, DNSQueryParts *QueryParts, IO_CallBack PostDNS);
125 void QueueGetHostByName(AsyncIO *IO, const char *Hostname, DNSQueryParts *QueryParts, IO_CallBack PostDNS);
126
127 void QueryCbDone(AsyncIO *IO);
128
129 void StopClient(AsyncIO *IO);
130
131 void StopClientWatchers(AsyncIO *IO);
132
133 void SetNextTimeout(AsyncIO *IO, double timeout);
134
135 void InitC_ares_dns(AsyncIO *IO);
136
137 #include <curl/curl.h>
138
139 #define OPT(s, v) \
140         do { \
141                 sta = curl_easy_setopt(chnd, (CURLOPT_##s), (v)); \
142                 if (sta)  {                                             \
143                         CtdlLogPrintf(CTDL_ERR, "error setting option " #s " on curl handle: %s", curl_easy_strerror(sta)); \
144         } } while (0)
145
146
147 int evcurl_init(AsyncIO *IO, 
148                 void *CustomData, 
149                 const char* Desc,
150                 IO_CallBack CallBack);
151
152 void evcurl_handle_start(AsyncIO *IO);