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