summaryrefslogtreecommitdiff
path: root/efl
diff options
context:
space:
mode:
authorDave Andreoli <dave@gurumeditation.it>2015-11-16 20:45:07 +0100
committerDave Andreoli <dave@gurumeditation.it>2015-11-16 20:45:07 +0100
commiteaf31100891e631e5d9dd0a713003b6d70178650 (patch)
tree04fd95a407e696bbd3fb0434440d99d07785953d /efl
parentf01ac0788eeb8c5b54b6df31df0def9d4d71f4c3 (diff)
A new ecore module: ecore_con
It's now super easy to perform various network task in a full efl fashion. Implemented "Lookup" for dns query and "Url" to perform http requests. "Server" will come soon. Comes with quite complete docs, examples and unit tests
Diffstat (limited to 'efl')
-rw-r--r--efl/ecore/efl.ecore_events.pxi8
-rw-r--r--efl/ecore_con/efl.ecore_con.pxd179
-rw-r--r--efl/ecore_con/efl.ecore_con.pyx315
-rw-r--r--efl/ecore_con/efl.ecore_con_lookup.pxi88
-rw-r--r--efl/ecore_con/efl.ecore_con_url.pxi827
5 files changed, 1417 insertions, 0 deletions
diff --git a/efl/ecore/efl.ecore_events.pxi b/efl/ecore/efl.ecore_events.pxi
index 880cc7e..d3f739d 100644
--- a/efl/ecore/efl.ecore_events.pxi
+++ b/efl/ecore/efl.ecore_events.pxi
@@ -29,6 +29,11 @@ cdef object _event_mapping_register(int type, cls):
29cdef object _event_mapping_unregister(int type): 29cdef object _event_mapping_unregister(int type):
30 _event_type_mapping.pop(type) 30 _event_type_mapping.pop(type)
31 31
32cdef object _event_mapping_get(int type):
33 if not type in _event_type_mapping:
34 raise ValueError("event type '%d' not registered." % type)
35 return _event_type_mapping.get(type)
36
32 37
33cdef Eina_Bool event_handler_cb(void *data, int type, void *event) with gil: 38cdef Eina_Bool event_handler_cb(void *data, int type, void *event) with gil:
34 cdef EventHandler handler 39 cdef EventHandler handler
@@ -65,6 +70,9 @@ cdef class Event(object):
65 cdef int _set_obj(self, void *obj) except 0: 70 cdef int _set_obj(self, void *obj) except 0:
66 raise NotImplementedError("Event._set_obj() not implemented.") 71 raise NotImplementedError("Event._set_obj() not implemented.")
67 72
73 cdef object _get_obj(self):
74 raise NotImplementedError("Event._get_obj() not implemented.")
75
68 76
69cdef class EventHandler(object): 77cdef class EventHandler(object):
70 def __init__(self, int type, func, *args, **kargs): 78 def __init__(self, int type, func, *args, **kargs):
diff --git a/efl/ecore_con/efl.ecore_con.pxd b/efl/ecore_con/efl.ecore_con.pxd
new file mode 100644
index 0000000..04ec4a6
--- /dev/null
+++ b/efl/ecore_con/efl.ecore_con.pxd
@@ -0,0 +1,179 @@
1# Copyright (C) 2007-2015 various contributors (see AUTHORS)
2#
3# This file is part of Python-EFL.
4#
5# Python-EFL is free software; you can redistribute it and/or
6# modify it under the terms of the GNU Lesser General Public
7# License as published by the Free Software Foundation; either
8# version 3 of the License, or (at your option) any later version.
9#
10# Python-EFL is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13# Lesser General Public License for more details.
14#
15# You should have received a copy of the GNU Lesser General Public License
16# along with this Python-EFL. If not, see <http://www.gnu.org/licenses/>.
17
18
19from efl.eina cimport *
20from efl.c_eo cimport Eo as cEo
21from efl.eo cimport Eo, object_from_instance
22from efl.ecore cimport Ecore_Event_Handler, Event
23from efl.utils.conversions cimport _ctouni, eina_list_strings_to_python_list
24
25
26
27cdef extern from "Ecore_Con.h":
28
29 # where is this defined in real ?
30 cdef struct sockaddr:
31 pass
32
33 # defines
34 int ECORE_CON_EVENT_URL_COMPLETE
35 int ECORE_CON_EVENT_URL_PROGRESS
36 int ECORE_CON_EVENT_URL_DATA
37
38 # typedefs
39 ctypedef cEo Ecore_Con_Url
40
41 ctypedef struct Ecore_Con_Event_Url_Progress_SubParam:
42 double total
43 double now
44
45 ctypedef struct Ecore_Con_Event_Url_Progress:
46 Ecore_Con_Url *url_con
47 Ecore_Con_Event_Url_Progress_SubParam down
48 Ecore_Con_Event_Url_Progress_SubParam up
49
50 ctypedef struct Ecore_Con_Event_Url_Data:
51 Ecore_Con_Url *url_con
52 int size
53 unsigned char *data
54
55 ctypedef struct Ecore_Con_Event_Url_Complete:
56 Ecore_Con_Url *url_con
57 int status
58
59 ctypedef void (*Ecore_Con_Dns_Cb)(const char *canonname, const char *ip,
60 sockaddr *addr, int addrlen, void *data)
61
62 # enums
63 cpdef enum Ecore_Con_Type:
64 ECORE_CON_LOCAL_USER
65 ECORE_CON_LOCAL_SYSTEM
66 ECORE_CON_LOCAL_ABSTRACT
67 ECORE_CON_REMOTE_TCP
68 ECORE_CON_REMOTE_MCAST
69 ECORE_CON_REMOTE_UDP
70 ECORE_CON_REMOTE_BROADCAST
71 ECORE_CON_REMOTE_NODELAY
72 ECORE_CON_REMOTE_CORK
73 ECORE_CON_USE_SSL2
74 ECORE_CON_USE_SSL3
75 ECORE_CON_USE_TLS
76 ECORE_CON_USE_MIXED
77 ECORE_CON_LOAD_CERT
78 ECORE_CON_NO_PROXY
79 ECORE_CON_SOCKET_ACTIVATE
80 ctypedef enum Ecore_Con_Type:
81 pass
82
83 cpdef enum Ecore_Con_Url_Time:
84 ECORE_CON_URL_TIME_NONE
85 ECORE_CON_URL_TIME_IFMODSINCE
86 ECORE_CON_URL_TIME_IFUNMODSINCE
87 ctypedef enum Ecore_Con_Url_Time:
88 pass
89
90 cpdef enum Ecore_Con_Url_Http_Version:
91 ECORE_CON_URL_HTTP_VERSION_1_0
92 ECORE_CON_URL_HTTP_VERSION_1_1
93 ctypedef enum Ecore_Con_Url_Http_Version:
94 pass
95
96 # functions
97 int ecore_con_init()
98 int ecore_con_shutdown()
99# Ecore_Con_Server *ecore_con_server_connect(Ecore_Con_Type type, const char *name, int port, const void *data)
100
101 int ecore_con_url_init()
102 int ecore_con_url_shutdown()
103 void ecore_con_url_pipeline_set(Eina_Bool enable)
104 Eina_Bool ecore_con_url_pipeline_get()
105 Eina_Bool ecore_con_lookup(const char *name, Ecore_Con_Dns_Cb done_cb, const void *data)
106
107 Ecore_Con_Url *ecore_con_url_new(const char *url)
108 void ecore_con_url_free(Ecore_Con_Url *url_obj)
109 Ecore_Con_Url * ecore_con_url_custom_new(const char *url, const char *custom_request)
110 void ecore_con_url_verbose_set(Ecore_Con_Url *url_con, Eina_Bool verbose)
111 Eina_Bool ecore_con_url_http_version_set(Ecore_Con_Url *url_con, Ecore_Con_Url_Http_Version version)
112 void ecore_con_url_timeout_set(Ecore_Con_Url *url_con, double timeout)
113 int ecore_con_url_status_code_get(Ecore_Con_Url *url_con)
114 Eina_Bool ecore_con_url_get(Ecore_Con_Url *url_con)
115 Eina_Bool ecore_con_url_head(Ecore_Con_Url *url_con)
116 Eina_Bool ecore_con_url_post(Ecore_Con_Url *url_con, const void *data, long length, const char *content_type)
117 Eina_Bool ecore_con_url_ftp_upload(Ecore_Con_Url *url_con, const char *filename, const char *user, const char *passwd, const char *upload_dir)
118 void ecore_con_url_ftp_use_epsv_set(Ecore_Con_Url *url_con, Eina_Bool use_epsv)
119
120 Eina_Bool ecore_con_url_url_set(Ecore_Con_Url *obj, const char *url)
121 const char *ecore_con_url_url_get(const Ecore_Con_Url *obj)
122 void ecore_con_url_fd_set(Ecore_Con_Url *url_con, int fd)
123
124 void ecore_con_url_additional_header_add(Ecore_Con_Url *url_con, const char *key, const char *value)
125 void ecore_con_url_additional_headers_clear(Ecore_Con_Url *url_con)
126 const Eina_List *ecore_con_url_response_headers_get(Ecore_Con_Url *url_con)
127 int ecore_con_url_received_bytes_get(Ecore_Con_Url *url_con)
128 Eina_Bool ecore_con_url_httpauth_set(Ecore_Con_Url *url_con, const char *username, const char *password, Eina_Bool safe)
129 void ecore_con_url_time(Ecore_Con_Url *url_con, Ecore_Con_Url_Time time_condition, double timestamp)
130
131 void ecore_con_url_cookies_init(Ecore_Con_Url *url_con)
132 void ecore_con_url_cookies_clear(Ecore_Con_Url *url_con)
133 void ecore_con_url_cookies_session_clear(Ecore_Con_Url *url_con)
134 void ecore_con_url_cookies_ignore_old_session_set(Ecore_Con_Url *url_con, Eina_Bool ignore)
135 void ecore_con_url_cookies_file_add(Ecore_Con_Url *url_con, const char *file_name)
136 Eina_Bool ecore_con_url_cookies_jar_file_set(Ecore_Con_Url *url_con, const char *cookiejar_file)
137 void ecore_con_url_cookies_jar_write(Ecore_Con_Url *url_con)
138
139 void ecore_con_url_ssl_verify_peer_set(Ecore_Con_Url *url_con, Eina_Bool verify)
140 int ecore_con_url_ssl_ca_set(Ecore_Con_Url *url_con, const char *ca_path)
141
142 Eina_Bool ecore_con_url_proxy_set(Ecore_Con_Url *url_con, const char *proxy)
143 Eina_Bool ecore_con_url_proxy_username_set(Ecore_Con_Url *url_con, const char *username)
144 Eina_Bool ecore_con_url_proxy_password_set(Ecore_Con_Url *url_con, const char *password)
145
146
147cdef class Url(Eo):
148 pass
149
150cdef class Lookup(object):
151 cdef object done_cb
152 cdef tuple args
153 cdef dict kargs
154
155cdef class EventUrlComplete(Event):
156 cdef readonly Url url
157 cdef readonly int status
158
159
160cdef class EventUrlProgress(Event):
161 cdef readonly Url url
162 cdef readonly double down_total
163 cdef readonly double down_now
164 cdef readonly double up_total
165 cdef readonly double up_now
166
167
168cdef class EventUrlData(Event):
169 cdef readonly Url url
170 cdef readonly int size
171 cdef readonly bytes data # TODO :/
172
173
174cdef class ConEventFilter(object):
175 cdef dict callbacks
176 cdef dict handlers
177 cdef callback_add(self, int ev_type, Eo obj, object func, tuple args, dict kargs)
178 cdef callback_del(self, int ev_type, Eo obj, object func, tuple args, dict kargs)
179 cdef callback_del_full(self, Eo obj)
diff --git a/efl/ecore_con/efl.ecore_con.pyx b/efl/ecore_con/efl.ecore_con.pyx
new file mode 100644
index 0000000..2d2f094
--- /dev/null
+++ b/efl/ecore_con/efl.ecore_con.pyx
@@ -0,0 +1,315 @@
1# Copyright (C) 2007-2015 various contributors (see AUTHORS)
2#
3# This file is part of Python-EFL.
4#
5# Python-EFL is free software; you can redistribute it and/or
6# modify it under the terms of the GNU Lesser General Public
7# License as published by the Free Software Foundation; either
8# version 3 of the License, or (at your option) any later version.
9#
10# Python-EFL is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13# Lesser General Public License for more details.
14#
15# You should have received a copy of the GNU Lesser General Public License
16# along with this Python-EFL. If not, see <http://www.gnu.org/licenses/>.
17
18"""
19
20:mod:`efl.ecore_con` Module
21###########################
22
23The ecore_con module provide various utilities to perform different network
24related tasks. Everything in a full async ecore way. Most notable are the
25:class:`Lookup` class to perform DNS requests, the :class:`Url` class to
26perform HTTP requests and the :class:`Server` class to implement your own
27server.
28
29Don't forget about the :class:`efl.ecore.FileDownload` class if what you need
30is just to fetch some data to file.
31
32
33Classes
34=======
35
36.. toctree::
37
38 class-lookup.rst
39 class-url.rst
40
41
42
43Enumerations
44============
45
46.. _Ecore_Con_Type:
47
48Ecore Con Type
49--------------
50
51Types for an ecore_con client/server object.
52
53A correct way to set this type is with an ECORE_CON_$TYPE, optionally OR'ed
54with an ECORE_CON_$USE if encryption is desired, and LOAD_CERT if the
55previously loaded certificate should be used.
56
57.. data:: ECORE_CON_LOCAL_USER
58
59 Socket in ~/.ecore.
60
61.. data:: ECORE_CON_LOCAL_SYSTEM
62
63 Socket in /tmp.
64
65.. data:: ECORE_CON_LOCAL_ABSTRACT
66
67 Abstract socket.
68
69.. data:: ECORE_CON_REMOTE_TCP
70
71 Remote server using TCP.
72
73
74.. data:: ECORE_CON_REMOTE_MCAST
75
76 Remote multicast server.
77
78
79.. data:: ECORE_CON_REMOTE_UDP
80
81 Remote server using UDP.
82
83.. data:: ECORE_CON_REMOTE_BROADCAST
84
85 Remote broadcast using UDP.
86
87.. data:: ECORE_CON_REMOTE_NODELAY
88
89 Remote connection sending packets immediately.
90
91.. data:: ECORE_CON_REMOTE_CORK
92
93 Remote connection sending data in large chunks. (only on linux)
94
95.. data:: ECORE_CON_USE_SSL2
96
97 Use SSL2: UNSUPPORTED.
98
99.. data:: ECORE_CON_USE_SSL3
100
101 Use SSL3: UNSUPPORTED.
102
103.. data:: ECORE_CON_USE_TLS
104
105 Use TLS.
106
107.. data:: ECORE_CON_USE_MIXED
108
109 Use both TLS and SSL3.
110
111.. data:: ECORE_CON_LOAD_CERT
112
113 Attempt to use the loaded certificate.
114
115.. data:: ECORE_CON_NO_PROXY
116
117 Disable all types of proxy on the server.
118
119
120.. _Ecore_Con_Url_Time:
121
122Ecore Con Url Time
123------------------
124
125The type of condition to use when making an HTTP request dependent on time, so
126that headers such as "If-Modified-Since" are used.
127
128.. data:: ECORE_CON_URL_TIME_NONE
129
130 Do not place time restrictions on the HTTP requests.
131
132.. data:: ECORE_CON_URL_TIME_IFMODSINCE
133
134 Add the "If-Modified-Since" HTTP header, so that the request is performed by
135 the server only if the target has been modified since the time value passed
136 to it in the request.
137
138.. data:: ECORE_CON_URL_TIME_IFUNMODSINCE
139
140 Add the "If-Unmodified-Since" HTTP header, so that the request is performed
141 by the server only if the target has NOT been modified since the time value
142 passed to it in the request.
143
144
145.. _Ecore_Con_Url_Http_Version:
146
147Ecore Con Url Http Version
148--------------------------
149
150The http version to use.
151
152.. data:: ECORE_CON_URL_HTTP_VERSION_1_0
153
154 HTTP version 1.0.
155
156.. data:: ECORE_CON_URL_HTTP_VERSION_1_1
157
158 HTTP version 1.1 (default)
159
160
161Module level functions
162======================
163
164"""
165
166from libc.stdint cimport uintptr_t
167from cpython cimport PyUnicode_AsUTF8String, Py_INCREF, Py_DECREF
168
169import traceback
170import atexit
171
172
173from efl.ecore cimport _event_mapping_register, _event_mapping_get, \
174 ecore_event_handler_add, ecore_event_handler_del
175
176
177cdef int _con_events_registered = 0
178
179
180def init():
181 """Initialize the Ecore Con library
182
183 .. note::
184 You never need to call this function, it is automatically called when
185 the module is imported.
186
187 .. versionadded:: 1.17
188
189 """
190
191 ecore_con_init()
192 ecore_con_url_init()
193
194 global _con_events_registered
195 if _con_events_registered == 0:
196 _event_mapping_register(ECORE_CON_EVENT_URL_COMPLETE, EventUrlComplete)
197 _event_mapping_register(ECORE_CON_EVENT_URL_PROGRESS, EventUrlProgress)
198 _event_mapping_register(ECORE_CON_EVENT_URL_DATA, EventUrlData)
199 _con_events_registered = 1
200
201
202def shutdown():
203 """Shuts down the Ecore Con library.
204
205 .. note::
206 You never need to call this function, it is automatically called atexit.
207
208 .. versionadded:: 1.17
209
210 """
211 ecore_con_url_shutdown()
212 ecore_con_shutdown()
213
214
215cdef Eina_Bool _con_event_filter_cb(void *data, int ev_type, void *ev) with gil:
216 cdef:
217 ConEventFilter filter = <ConEventFilter>data
218 object event_cls
219 Event py_event
220 list cbs
221 Eo obj
222 object func
223 tuple args
224 dict kargs
225
226 # create correct "EventAbc" python object, using the global mapping
227 event_cls = _event_mapping_get(ev_type)
228 if event_cls:
229 py_event = event_cls()
230 py_event._set_obj(ev)
231
232 # do we have callbacks for this object/event ?
233 try:
234 obj = py_event._get_obj()
235 cbs = filter.callbacks.get(ev_type).get(obj)
236 except:
237 cbs = None
238
239 if cbs:
240 cbs = cbs[:] # copy, so we can change filter.callbacks
241 for func, args, kargs in cbs:
242 try:
243 func(py_event, *args, **kargs)
244 except Exception:
245 traceback.print_exc()
246
247 return 1 # always return true, no matter what
248
249cdef class ConEventFilter(object):
250
251 """
252 self.callbacks = {
253 EV_TYPE: {
254 objX: [(cb,args,kargs), ... ]
255 objY: [(cb,args,kargs), ... ]
256 },
257 ...
258 }
259 """
260
261 def __cinit__(self):
262 self.callbacks = {}
263 self.handlers = {}
264
265 cdef callback_add(self, int ev_type, Eo obj, object func, tuple args, dict kargs):
266 # store the function in the callbacks dict
267 if not ev_type in self.callbacks:
268 self.callbacks[ev_type] = {}
269 if not obj in self.callbacks[ev_type]:
270 self.callbacks[ev_type][obj] = []
271 self.callbacks[ev_type][obj].append((func,args,kargs))
272
273 # connect a single ecore signal, one per event_type
274 cdef Ecore_Event_Handler* ee
275 if not ev_type in self.handlers:
276 ee = ecore_event_handler_add(ev_type, _con_event_filter_cb,
277 <void *>self)
278 self.handlers[ev_type] = <uintptr_t><void *>ee
279
280 cdef callback_del(self, int ev_type, Eo obj, object func, tuple args, dict kargs):
281 try:
282 self.callbacks[ev_type][obj].remove((func, args, kargs))
283 except ValueError:
284 raise ValueError(
285 "callback is not registered: %s, args=%s, kargs=%s" %
286 (func, args, kargs))
287
288 # can delete the ecore handler?
289 if self.callbacks.get(ev_type) and self.callbacks.get(ev_type).get(obj):
290 return
291 if ev_type in self.handlers:
292 handler = self.handlers.pop(ev_type)
293 ecore_event_handler_del(<Ecore_Event_Handler *><uintptr_t>handler)
294
295 cdef callback_del_full(self, Eo obj):
296 for ev_type in self.callbacks:
297 if obj in self.callbacks[ev_type]:
298 # remove all the cbs for the obj
299 self.callbacks[ev_type].pop(obj, None)
300
301 # can delete the ecore handler?
302 if len(self.callbacks[ev_type]) < 1 and ev_type in self.handlers:
303 handler = self.handlers.pop(ev_type)
304 ecore_event_handler_del(<Ecore_Event_Handler *><uintptr_t>handler)
305
306# name suggestions are welcome for this unusual "singleton" instance
307cdef ConEventFilter GEF = ConEventFilter()
308
309
310include "efl.ecore_con_lookup.pxi"
311include "efl.ecore_con_url.pxi"
312
313
314init()
315atexit.register(shutdown)
diff --git a/efl/ecore_con/efl.ecore_con_lookup.pxi b/efl/ecore_con/efl.ecore_con_lookup.pxi
new file mode 100644
index 0000000..e002916
--- /dev/null
+++ b/efl/ecore_con/efl.ecore_con_lookup.pxi
@@ -0,0 +1,88 @@
1# Copyright (C) 2007-2015 various contributors (see AUTHORS)
2#
3# This file is part of Python-EFL.
4#
5# Python-EFL is free software; you can redistribute it and/or
6# modify it under the terms of the GNU Lesser General Public
7# License as published by the Free Software Foundation; either
8# version 3 of the License, or (at your option) any later version.
9#
10# Python-EFL is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13# Lesser General Public License for more details.
14#
15# You should have received a copy of the GNU Lesser General Public License
16# along with this Python-EFL. If not, see <http://www.gnu.org/licenses/>.
17
18
19cdef void _con_dns_lookup_cb(const char *canonname, const char *ip, sockaddr *sockaddr, int addrlen, void *data) with gil:
20 cdef Lookup self = <Lookup>data
21
22 try:
23 # TODO read sockaddr and replace the placeholder None with something
24 # more usefull from the sockaddr struct.
25 self.done_cb(_ctouni(canonname), _ctouni(ip), None, *self.args, **self.kargs)
26 except Exception:
27 traceback.print_exc()
28
29 Py_DECREF(self)
30
31
32cdef class Lookup(object):
33 def __init__(self, name, done_cb, *args, **kargs):
34 """Lookup()
35
36 A simple class to perform asynchronous DNS lookups.
37
38 :param string name: The hostname to query
39 :param callable done_cb: The function to call when done
40 :param \*args: Any other arguments will be passed back in ``done_cb``
41 :param \**kargs: Any other keywords arguments will be passed back in ``done_cb``
42
43 .. versionadded:: 1.17
44
45 Just create an instance and give a callback function to be called
46 when the operation is complete.
47
48 This class performs a DNS lookup on the hostname specified by
49 `name`, then calls `done_cb` with the result and the data given as
50 parameter. The result will be given to the done_cb as follows:
51
52 **expected `done_cb` signature**::
53
54 func(canonname, ip, sockaddr)
55
56 where:
57 * **canonname** (string) is the canonical domain name
58 * **ip** (string) is the recolved ip address
59 * **sockaddr** (None) is a placeholder for future expansion
60
61
62
63 **Usage example**::
64
65 import ecore_con
66
67 def done_cb(canonname, ip, sockaddr):
68 print(canonname)
69 print(ip)
70
71 ecore_con.Lookup('example.com', done_cb)
72
73
74 """
75
76 if not callable(done_cb):
77 raise TypeError("Parameter 'done_cb' must be callable")
78
79 self.done_cb = done_cb
80 self.args = args
81 self.kargs = kargs
82
83 if isinstance(name, unicode): name = PyUnicode_AsUTF8String(name)
84 ecore_con_lookup(<const char *>name if name is not None else NULL,
85 _con_dns_lookup_cb, <void*>self)
86
87 Py_INCREF(self)
88
diff --git a/efl/ecore_con/efl.ecore_con_url.pxi b/efl/ecore_con/efl.ecore_con_url.pxi
new file mode 100644
index 0000000..a48a6f8
--- /dev/null
+++ b/efl/ecore_con/efl.ecore_con_url.pxi
@@ -0,0 +1,827 @@
1# Copyright (C) 2007-2015 various contributors (see AUTHORS)
2#
3# This file is part of Python-EFL.
4#
5# Python-EFL is free software; you can redistribute it and/or
6# modify it under the terms of the GNU Lesser General Public
7# License as published by the Free Software Foundation; either
8# version 3 of the License, or (at your option) any later version.
9#
10# Python-EFL is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13# Lesser General Public License for more details.
14#
15# You should have received a copy of the GNU Lesser General Public License
16# along with this Python-EFL. If not, see <http://www.gnu.org/licenses/>.
17
18# from efl.ecore cimport EventHandler
19# from efl.utils.conversions cimport _ctouni as _charp_to_str
20
21
22
23cdef class EventUrlProgress(Event):
24 """Represents Ecore_Con_Event_Url_Progress event from C-api.
25
26 This event notifies the progress of the current operation.
27
28 attributes:
29 * url (:class:`Url`): the object that generate the event
30 * down_total(double): total size of the downloading data (in bytes)
31 * down_now(double): current size of the downloading data (in bytes)
32 * up_total(double): total size of the uploading data (in bytes)
33 * up_now(double): current size of the uploading data (in bytes)
34
35 """
36 cdef int _set_obj(self, void *ev) except 0:
37 cdef Ecore_Con_Event_Url_Progress *event
38 event = <Ecore_Con_Event_Url_Progress*>ev
39
40 self.url = object_from_instance(event.url_con)
41 self.down_total = event.down.total
42 self.down_now = event.down.now
43 self.up_total = event.up.total
44 self.up_now = event.up.now
45 return 1
46
47 cdef object _get_obj(self):
48 return self.url
49
50cdef class EventUrlComplete(Event):
51 """Represents Ecore_Con_Event_Url_Complete event from C-api.
52
53 This event notifies the operation is completed.
54
55 attributes:
56 * url (:class:`Url`): the object that generate the event
57 * status(int): HTTP status code of the operation (200, 404, 401, etc.)
58
59 """
60 cdef int _set_obj(self, void *ev) except 0:
61 cdef Ecore_Con_Event_Url_Complete *event
62 event = <Ecore_Con_Event_Url_Complete*>ev
63
64 self.url = object_from_instance(event.url_con)
65 self.status = event.status
66 return 1
67
68 cdef object _get_obj(self):
69 return self.url
70
71cdef class EventUrlData(Event):
72 """Represents Ecore_Con_Event_Url_Data event from C-api.
73
74 This event hold the data while the are received.
75
76 .. note::
77 The data attribute is a raw series of bytes, map to ``str`` in python2
78 and ``bytes`` in python3.
79
80 attributes:
81 * url (:class:`Url`): the object that generate the event
82 * size(int): the size of the current received data (in bytes)
83 * data(bytes): the data received on this event
84
85 """
86 cdef int _set_obj(self, void *ev) except 0:
87 cdef Ecore_Con_Event_Url_Data *event
88 event = <Ecore_Con_Event_Url_Data*>ev
89
90 self.url = object_from_instance(event.url_con)
91 self.size = event.size
92 self.data = event.data[:event.size] #raw string copy
93 return 1
94
95 cdef object _get_obj(self):
96 return self.url
97
98
99cdef class Url(Eo):
100 """
101
102 Utility class to make it easy to perform http requests (POST, GET, etc).
103
104 .. versionadded:: 1.17
105
106 Brief usage:
107 1. Create an :class:`Url` object with ecore_con.Url('myurl')
108 2. Register object callbacks using :func:`on_complete_event_add`,
109 :func:`on_progress_event_add` and :func:`on_data_event_add` to
110 receive the response, e.g. for HTTP/FTP downloads.
111 3. Perform the operation with :func:`get`, :func:`head` and :func:`post`
112
113 If it's necessary use the :attr:`url` property. to change the object url.
114
115 .. note::
116 It is good practice to reuse :class:`Url` objects wherever possible,
117 but bear in mind that each one can only perform one operation at a
118 time. You need to wait for the complete event before re-using or
119 destroying the object.
120
121 .. warning::
122 It is **really important** to call the :func:`delete()` method as soon
123 as you have finished with your object, as it automatically remove all
124 the registered events for you, that will otherwise continue to use
125 resources.
126
127 Basic usage examples::
128
129 # HTTP GET
130 u = ecore.Url("http://www.google.com")
131 u.get()
132
133 # HTTP POST
134 u = ecore.Url('https://httpbin.org/post')
135 u.post(b'my data to post', 'text/txt')
136
137 # FTP download
138 u = ecore.Url("ftp://ftp.example.com/pub/myfile")
139 u.get()
140
141 # FTP upload as ftp://ftp.example.com/file
142 u = ecore.Url("ftp://ftp.example.com")
143 u.ftp_upload("/tmp/file", "user", "pass", None)
144
145 # FTP upload as ftp://ftp.example.com/dir/file
146 u = ecore.Url("ftp://ftp.example.com")
147 u.ftp_upload("/tmp/file", "user", "pass", "dir")
148
149 To actually make something usefull with your request you will need to
150 connect the :class:`EventUrlComplete`, :class:`EventUrlProgress` and
151 :class:`EventUrlData` events using the :func:`on_complete_event_add` and
152 friends functions.
153
154 A more complete example::
155
156 from efl import ecore
157
158 def on_data(event):
159 print("data: " + str(event.data[:80]))
160 # do something here with the received data
161
162 def on_progress(event):
163 # print(event)
164 print("received %d on a total of %d bytes" % (
165 event.down_now, event.down_total))
166
167 def on_complete(event):
168 # print(event)
169 print("http result: %d" % event.status)
170 print("Total received bytes: %d" % event.url.received_bytes)
171
172 u.delete() # don't forget to delete !!
173
174 u = ecore.Url('http://www.google.com', verbose=False)
175 u.on_data_event_add(on_data)
176 u.on_progress_event_add(on_progress)
177 u.on_complete_event_add(on_complete)
178 u.get()
179
180 ecore.main_loop_begin()
181
182 If you need to save the received data to a file use the :attr:`fd`
183 property, as::
184
185 fd = open('/tmp/tmpMxBtta', 'w')
186 u = ecore.Url('http://example.com', fd=fd.fileno())
187 u.get()
188
189 .. seealso::
190 If you just need to download a file please consider using the
191 simpler :class:`efl.ecore.FileDownload` class instead.
192
193 .. seealso::
194 The ecore module level functions :func:`url_pipeline_set` and
195 :func:`url_pipeline_get` to enable HTTP 1.1 pipelining.
196
197 """
198 def __init__(self, url, custom_request=None, **kargs):
199 """Url(...)
200
201 :param url: URL that will receive requests.
202 :type url: string
203 :param custom_request: Custom request (e.g. GET, POST, HEAD, PUT, HEAD,
204 SUBSCRIBE and other obscure HTTP requests)
205 :type custom_request: string
206 :param \**kwargs: All the remaining keyword arguments are interpreted
207 as properties of the instance
208
209 .. versionadded:: 1.17
210
211 """
212 if isinstance(url, unicode): url = PyUnicode_AsUTF8String(url)
213 if custom_request is None:
214 self._set_obj(ecore_con_url_new(
215 <const char *>url if url is not None else NULL))
216 else:
217 if isinstance(custom_request, unicode):
218 custom_request = PyUnicode_AsUTF8String(custom_request)
219 self._set_obj(ecore_con_url_custom_new(
220 <const char *>url if url is not None else NULL,
221 <const char *>custom_request if custom_request is not None else NULL))
222
223 self._set_properties_from_keyword_args(kargs)
224
225 def __repr__(self):
226 return "%s(url=%s)" % (self.__class__.__name__, self.url)
227
228 def delete(self):
229 """Delete the :class:`Url` object and free all used resources.
230
231 .. note::
232 This is **really important** to call as soon as you have finished
233 with your object, as it automatically remove all the registered
234 events. That will otherwise continue to use resources.
235
236 """
237 GEF.callback_del_full(self)
238 ecore_con_url_free(self.obj)
239
240 property fd:
241 """Set up a file to have response data written into.
242
243 This attr can be used to easily setup a file where the downloaded data
244 will be saved.
245
246 Note that :class:`EventUrlData` events will not be emitted if a file
247 has been set to receive the response data.
248
249 .. seealso::
250 If you just need to download a file please consider using the
251 simpler :class:`efl.ecore.FileDownload` class instead.
252
253 :type: int (**writeonly**)
254
255 """
256 def __set__(self, int fd):
257 ecore_con_url_fd_set(self.obj, fd)
258
259 def get(self):
260 """Send a GET request.
261
262 The request is performed immediately, but you need to setup event
263 handlers with :func:`on_complete_event_add` or
264 :func:`on_complete_event_add` to get more information about its result.
265
266 :return: ``True`` on success, ``False`` on error.
267
268 """
269 return bool(ecore_con_url_get(self.obj))
270
271 def head(self):
272 """Send a HEAD request.
273
274 The request is performed immediately, but you need to setup event
275 handlers with :func:`on_complete_event_add` or
276 :func:`on_complete_event_add` to get more information about its result.
277
278 :return: ``True`` on success, ``False`` on error.
279
280 """
281 return bool(ecore_con_url_head(self.obj))
282
283 def post(self, bytes data, content_type):
284 """Send a post request.
285
286 The request is performed immediately, but you need to setup event
287 handlers with :func:`on_complete_event_add` or
288 :func:`on_complete_event_add` to get more information about its result.
289
290 :param data: Payload (data sent on the request). Can be ``None``.
291 :type data: bytes
292 :param content_type: Content type of the payload (e.g. `text/xml`).
293 Can be ``None``.
294 :type content_type: string
295
296 :return: ``True`` on success, ``False`` on error.
297
298 """
299 if isinstance(content_type, unicode):
300 content_type = PyUnicode_AsUTF8String(content_type)
301 return bool(ecore_con_url_post(self.obj,
302 <const void*><const char *>data if data is not None else NULL,
303 len(data),
304 <const char *>content_type if content_type is not None else NULL))
305
306 def time(self, Ecore_Con_Url_Time time_condition, double timestamp):
307 """Whether HTTP requests should be conditional, dependent on
308 modification time.
309
310 This function may set the header `If-Modified-Since` or
311 `If-Unmodified-Since`, depending on the value of time_condition, with
312 the value timestamp.
313
314 :param time_condition: Condition to use for HTTP requests.
315 :type time_condition: :ref:`Ecore_Con_Url_Time`
316 :param timestamp: Time since 1 Jan 1970 to use in the condition.
317 :type timestamp: double
318
319 """
320 ecore_con_url_time(self.obj, time_condition, timestamp)
321
322 def ftp_upload(self, filename, user, passwd, upload_dir):
323 """Upload a file to an ftp site.
324
325 :param string filename: The path to the file to send
326 :param string user: The username to log in with
327 :param string passwd: The password to log in with
328 :param string upload_dir: The directory to which the file will upload
329
330 :return: ``True`` on success, ``False`` otherwise.
331 :rtype: bool
332
333 """
334 if isinstance(filename, unicode): filename = PyUnicode_AsUTF8String(filename)
335 if isinstance(user, unicode): user = PyUnicode_AsUTF8String(user)
336 if isinstance(passwd, unicode): passwd = PyUnicode_AsUTF8String(passwd)
337 if isinstance(upload_dir, unicode): upload_dir = PyUnicode_AsUTF8String(upload_dir)
338 return bool(ecore_con_url_ftp_upload(self.obj,
339 <const char *>filename if filename is not None else NULL,
340 <const char *>user if user is not None else NULL,
341 <const char *>passwd if passwd is not None else NULL,
342 <const char *>upload_dir if upload_dir is not None else NULL))
343
344 property ftp_use_epsv:
345 """Enable or disable EPSV extension.
346
347 :type: bool (**writeonly**)
348
349 """
350 def __set__(self, bint use_epsv):
351 ecore_con_url_ftp_use_epsv_set(self.obj, use_epsv)
352
353 def cookies_init(self):
354 """Enable the cookie engine for subsequent HTTP requests.
355
356 After this function is called, cookies set by the server in HTTP
357 responses will be parsed and stored, as well as sent back to the server
358 in new HTTP requests.
359
360 """
361 ecore_con_url_cookies_init(self.obj)
362
363 def cookies_clear(self):
364 """Clear currently loaded cookies.
365
366 The cleared cookies are removed and will not be sent in subsequent HTTP
367 requests, nor will they be written to the cookiejar file set via
368 :attr:`cookies_jar_file`.
369
370 .. note::
371 This function will initialize the cookie engine if it has not been
372 initialized yet. The cookie files set by
373 :func:`cookies_file_add` aren't loaded immediately, just
374 when the request is started. Thus, if you ask to clear the cookies,
375 but has a file already set by that function, the cookies will then
376 be loaded and you will have old cookies set. In order to don't have
377 any old cookie set, you need to don't call
378 :func:`cookies_file_add` ever on the :class:`Url` class, and
379 call this function to clear any cookie set by a previous request on
380 this handler.
381
382 """
383 ecore_con_url_cookies_clear(self.obj)
384
385 def cookies_session_clear(self):
386 """Clear currently loaded session cookies.
387
388 Session cookies are cookies with no expire date set, which usually
389 means they are removed after the current session is closed.
390
391 The cleared cookies are removed and will not be sent in subsequent HTTP
392 requests, nor will they be written to the cookiejar file set via
393 :attr:`cookies_jar_file`.
394
395 .. note::
396 This function will initialize the cookie engine if it has not been
397 initialized yet. The cookie files set by
398 :func:`cookies_file_add` aren't loaded immediately, just
399 when the request is started. Thus, if you ask to clear the session
400 cookies, but has a file already set by that function, the session
401 cookies will then be loaded and you will have old cookies set. In
402 order to don't have any old session cookie set, you need to don't
403 call :func:`cookies_file_add` ever on the :class:`Url` class, and
404 call this function to clear any session cookie set by a previous
405 request on this handler. An easier way to don't use old session
406 cookies is by using the function
407 :attr:`cookies_ignore_old_session`.
408
409 """
410 ecore_con_url_cookies_session_clear(self.obj)
411
412 def cookies_file_add(self, file_name):
413 """Add a file to the list of files from which to load cookies.
414
415 Files must contain cookies defined according to two possible formats:
416 * HTTP-style header ("Set-Cookie: ...").
417 * Netscape/Mozilla cookie data format.
418
419 Cookies will only be read from this file. If you want to save cookies
420 to a file, use :attr:`cookies_jar_file`. Also notice that
421 this function supports the both types of cookie file cited above, while
422 :attr:`cookies_jar_file` will save only in the Netscape/Mozilla's
423 format.
424
425 Please notice that the file will not be read immediately, but rather
426 added to a list of files that will be loaded and parsed at a later
427 time.
428
429 .. note::
430 This function will initialize the cookie engine if it has not been
431 initialized yet.
432
433 :param string file_name: Name of the file that will be added to the list.
434
435 """
436 if isinstance(file_name, unicode):
437 file_name = PyUnicode_AsUTF8String(file_name)
438 ecore_con_url_cookies_file_add(self.obj,
439 <const char *>file_name if file_name is not None else NULL)
440
441 property cookies_jar_file:
442 """The name of the file to which all current cookies will be written
443 when either cookies are flushed or Ecore_Con is shut down.
444
445 Cookies are written following Netscape/Mozilla's data format, also
446 known as cookie-jar.
447
448 Cookies will only be saved to this file. If you need to read cookies
449 from a file, use ecore_con_url_cookies_file_add() instead.
450
451 .. note::
452 This function will initialize the cookie engine if it has not been
453 initialized yet.
454
455 .. seealso:: :func:`cookies_jar_write`
456
457 :type: string (**writeonly**)
458
459 """
460 def __set__(self, cookiejar_file):
461 if isinstance(cookiejar_file, unicode):
462 cookiejar_file = PyUnicode_AsUTF8String(cookiejar_file)
463 ecore_con_url_cookies_jar_file_set(self.obj,
464 <const char *>cookiejar_file if cookiejar_file is not None else NULL)
465 if isinstance(cookiejar_file, unicode):
466 cookiejar_file = PyUnicode_AsUTF8String(cookiejar_file)
467 ecore_con_url_cookies_jar_file_set(self.obj,
468 <const char *>cookiejar_file if cookiejar_file is not None else NULL)
469
470 def cookies_jar_write(self):
471 """Write all current cookies to the cookie jar immediately.
472
473 A cookie-jar file must have been previously set by
474 :attr:`cookies_jar_file`, otherwise nothing will be done.
475
476 .. note::
477 This function will initialize the cookie engine if it has not been
478 initialized yet.
479
480 .. seealso:: :attr:`cookies_jar_file`
481
482 """
483 ecore_con_url_cookies_jar_write(self.obj)
484
485 property cookies_ignore_old_session:
486 """Control whether session cookies from previous sessions shall be loaded.
487
488 Session cookies are cookies with no expire date set, which usually
489 means they are removed after the current session is closed.
490
491 By default, when Ecore_Con_Url loads cookies from a file, all cookies
492 are loaded, including session cookies, which, most of the time, were
493 supposed to be loaded and valid only for that session.
494
495 If ignore is set to ``True``, when Ecore_Con_Url loads cookies from
496 the files passed to :func:`cookies_file_add`, session cookies
497 will not be loaded.
498
499 :type: bool (**writeonly**)
500
501 """
502 def __set__(self, bint ignore):
503 ecore_con_url_cookies_ignore_old_session_set(self.obj, ignore)
504
505 property ssl_verify_peer:
506 """Toggle libcurl's verify peer's certificate option.
507
508 If this is ``True``, libcurl will verify the authenticity of the
509 peer's certificate, otherwise it will not. Default behavior of libcurl
510 is to check peer's certificate.
511
512 :type: bool (**writeonly**)
513
514 """
515 def __set__(self, bint verify):
516 ecore_con_url_ssl_verify_peer_set(self.obj, verify)
517
518 property ssl_ca:
519 """Set a custom CA to trust for SSL/TLS connections.
520
521 Specify the path of a file (in PEM format) containing one or more CA
522 certificate(s) to use for the validation of the server certificate.
523
524 This can also disable CA validation if set to ``None``.
525 However, the server certificate still needs to be valid for the
526 connection to succeed (i.e., the certificate must concern the server
527 the connection is made to).
528
529 :type: string (**writeonly**)
530
531 """
532 def __set__(self, ca_path):
533 if isinstance(ca_path, unicode):
534 ca_path = PyUnicode_AsUTF8String(ca_path)
535 ecore_con_url_ssl_ca_set(self.obj,
536 <const char *>ca_path if ca_path is not None else NULL)
537
538 property proxy:
539 """Set the HTTP proxy to use.
540
541 The parameter is the host name or dotted IP address. To specify port
542 number in this string, append :[port] to the end of the host name. The
543 proxy string may be prefixed with [protocol]:// since any such prefix
544 will be ignored. The proxy's port number may optionally be specified
545 with the separate option. If not specified, libcurl will default to
546 using port 1080 for proxies.
547
548 Set this to ``None`` to disable the usage of proxy.
549
550 :type: string (**writeonly**)
551
552 """
553 def __set__(self, proxy):
554 if isinstance(proxy, unicode): proxy = PyUnicode_AsUTF8String(proxy)
555 ecore_con_url_proxy_set(self.obj,
556 <const char *>proxy if proxy is not None else NULL)
557
558 property proxy_username:
559 """Username to use for proxy.
560
561 If socks protocol is used for proxy, protocol should be socks5 and
562 above.
563
564 :type: string (**writeonly**)
565
566 """
567 def __set__(self, user):
568 if isinstance(user, unicode): user = PyUnicode_AsUTF8String(user)
569 ecore_con_url_proxy_username_set(self.obj,
570 <const char *>user if user is not None else NULL)
571
572 property proxy_password:
573 """Password to use for proxy.
574
575 If socks protocol is used for proxy, protocol should be socks5 and
576 above.
577
578 :type: string (**writeonly**)
579
580 """
581 def __set__(self, passwd):
582 if isinstance(passwd, unicode): passwd = PyUnicode_AsUTF8String(passwd)
583 ecore_con_url_proxy_username_set(self.obj,
584 <const char *>passwd if passwd is not None else NULL)
585
586 property timeout:
587 """transfer timeout in seconds.
588
589 The maximum time in seconds that you allow the :class:`Url` class
590 transfer operation to take. Normally, name lookups can take a
591 considerable time and limiting operations to less than a few minutes
592 risk aborting perfectly normal operations.
593
594 :type: double (**writeonly**)
595
596 """
597 def __set__(self, double timeout):
598 ecore_con_url_timeout_set(self.obj, timeout)
599
600 property http_version:
601 """The HTTP version used for the request.
602
603 Can be :data:`ECORE_CON_URL_HTTP_VERSION_1_0` or
604 :data:`ECORE_CON_URL_HTTP_VERSION_1_1`
605
606 :type: :ref:`Ecore_Con_Url_Http_Version` (**writeonly**)
607
608 """
609 def __set__(self, Ecore_Con_Url_Http_Version version):
610 ecore_con_url_http_version_set(self.obj, version)
611
612 property status_code:
613 """The returned HTTP STATUS code.
614
615 This is used to, at any time, try to return the status code for a
616 transmission.
617
618 :type: int (**readonly**)
619
620 """
621 def __get__(self):
622 return ecore_con_url_status_code_get(self.obj)
623
624 property url:
625 """Controls the URL to send the request to.
626
627 :type: string
628
629 """
630 def __get__(self):
631 return _ctouni(ecore_con_url_url_get(self.obj))
632
633 def __set__(self, url):
634 if isinstance(url, unicode): url = PyUnicode_AsUTF8String(url)
635 ecore_con_url_url_set(self.obj, <const char *>url if url is not None else NULL)
636
637 property verbose:
638 """Toggle libcurl's verbose output.
639
640 If set to ``True``, libcurl will output a lot of verbose
641 information about its operations, which is useful for debugging. The
642 verbose information will be sent to stderr.
643
644 :type: bool (**writeonly**)
645
646 """
647 def __set__(self, bint verbose):
648 ecore_con_url_verbose_set(self.obj, verbose)
649
650 def additional_header_add(self, key, value):
651 """Add an additional header to the request connection object.
652
653 Add an additional header (User-Agent, Content-Type, etc.) to the
654 request connection object. This addition will be valid for only one
655 :func:`get` or :func:`post` call.
656
657 :param string key: Header key
658 :param string value: Header value
659
660 Some functions like :func:`time` also add headers to the request.
661
662 """
663 if isinstance(key, unicode): key = PyUnicode_AsUTF8String(key)
664 if isinstance(value, unicode): value = PyUnicode_AsUTF8String(value)
665 ecore_con_url_additional_header_add(self.obj,
666 <const char *>key if key is not None else NULL,
667 <const char *>value if value is not None else NULL)
668
669 def additional_headers_clear(self):
670 """Clean additional headers.
671
672 Clean additional headers associated with a connection object
673 (previously added with :func:additional_header_add`).
674
675 """
676 ecore_con_url_additional_headers_clear(self.obj)
677
678 property response_headers:
679 """The headers from last request sent.
680
681 Retrieve a list containing the response headers. This function should
682 be used after an :class:`EventUrlComplete` event (headers should
683 normally be ready at that time).
684
685 :type: list of strings (**readonly**)
686
687 """
688 def __get__(self):
689 return eina_list_strings_to_python_list(
690 ecore_con_url_response_headers_get(self.obj))
691
692 property received_bytes:
693 """The number of bytes received.
694
695 Retrieve the number of bytes received on the last request of the
696 :class:`Url` object.
697
698 :type: int (**readonly**)
699
700 """
701 def __get__(self):
702 return ecore_con_url_received_bytes_get(self.obj)
703
704 def httpauth_set(self, username, password, bint safe):
705 """Set to use http auth, with given username and password
706
707 :param string username: Username to use in authentication
708 :param string password: Password to use in authentication
709 :param bool safe: Whether to use "safer" methods (eg, NOT http basic auth)
710
711 :return: ``True`` on success, ``False`` on error.
712 :rtype: bool
713
714 .. warning:: Require libcurl >= 7.19.1 to work, otherwise will
715 always return ``False``.
716
717 """
718 if isinstance(username, unicode):
719 username = PyUnicode_AsUTF8String(username)
720 if isinstance(password, unicode):
721 password = PyUnicode_AsUTF8String(password)
722 return bool(ecore_con_url_httpauth_set(self.obj,
723 <const char *>username if username is not None else NULL,
724 <const char *>password if password is not None else NULL,
725 safe))
726
727 def on_complete_event_add(self, func, *args, **kargs):
728 """Adds event listener to know when the Url operation is completed.
729
730 The given function will be called with the following signature::
731
732 func(event, *args, **kargs)
733
734 The ``event`` parameter is an :class:`EventUrlComplete` instance.
735
736 :see: :func:`on_complete_event_del`
737
738 """
739 GEF.callback_add(ECORE_CON_EVENT_URL_COMPLETE, self, func, args, kargs)
740
741 def on_complete_event_del(self, func, *args, **kargs):
742 """Removes an event listener previously registered
743
744 Parameters must match exactly the ones given in the
745 :func:`on_complete_event_add` call
746
747 :raise ValueError: if parameters don't match an already
748 registered callback.
749 """
750 GEF.callback_del(ECORE_CON_EVENT_URL_COMPLETE, self, func, args, kargs)
751
752 def on_progress_event_add(self, func, *args, **kargs):
753 """Adds event listener to know the operation status progress.
754
755 The given function will be called with the following signature::
756
757 func(event, *args, **kargs)
758
759 The ``event`` parameter is an :class:`EventUrlProgress` instance.
760
761 :see: :func:`on_progress_event_del`
762
763 """
764 GEF.callback_add(ECORE_CON_EVENT_URL_PROGRESS, self, func, args, kargs)
765
766 def on_progress_event_del(self, func, *args, **kargs):
767 """Removes an event listener previously registered
768
769 Parameters must match exactly the ones given in the
770 :func:`on_progress_event_add` call
771
772 :raise ValueError: if parameters don't match an already
773 registered callback.
774 """
775 GEF.callback_del(ECORE_CON_EVENT_URL_PROGRESS, self, func, args, kargs)
776
777 def on_data_event_add(self, func, *args, **kargs):
778 """Adds event listener to collect the data while they are received.
779
780 The given function will be called with the following signature::
781
782 func(event, *args, **kargs)
783
784 The ``event`` parameter is an :class:`EventUrlData` instance.
785
786 :see: :func:`on_data_event_del`
787
788 """
789 GEF.callback_add(ECORE_CON_EVENT_URL_DATA, self, func, args, kargs)
790
791 def on_data_event_del(self, func, *args, **kargs):
792 """Removes an event listener previously registered
793
794 Parameters must match exactly the ones given in the
795 :func:`on_data_event_add` call
796
797 :raise ValueError: if parameters don't match an already
798 registered callback.
799 """
800 GEF.callback_del(ECORE_CON_EVENT_URL_DATA, self, func, args, kargs)
801
802
803def url_pipeline_set(bint enable):
804 """Enable or disable HTTP 1.1 pipelining.
805
806 Pipelining allows to send one request after another one, without having to
807 wait for the reply of the first request. The respective replies are
808 received in the order that the requests were sent.
809
810 .. warning:: Enabling this feature will be valid for all requests done
811 using ecore_con_url.
812
813 .. versionadded:: 1.17
814
815 """
816 ecore_con_url_pipeline_set(enable)
817
818def url_pipeline_get():
819 """Is HTTP 1.1 pipelining enable ?
820
821 :return: ``True`` if enable
822
823 .. versionadded:: 1.17
824
825 """
826 return bool(ecore_con_url_pipeline_get())
827