PythonSTB commited on
Commit
d99ed4a
·
verified ·
1 Parent(s): 5639c73

Delete pycurl/PYCURL_USER_GUIDE.txt

Browse files
Files changed (1) hide show
  1. pycurl/PYCURL_USER_GUIDE.txt +0 -320
pycurl/PYCURL_USER_GUIDE.txt DELETED
@@ -1,320 +0,0 @@
1
- ================================================================================
2
- PYCURL - USER GUIDE (Android Python STB) - Generated by RIMI
3
- ================================================================================
4
- Covers: what pycurl is, install/verify, Curl object, HTTP GET/POST,
5
- SSL, timeouts, write callbacks, and libcurl-impersonate features.
6
-
7
- Written for: Python 3.12 (RIMI build) on Android
8
- Version: pycurl 7.45.6 (libcurl-impersonate)
9
- Installed: /data/user/0/com.pythonstb.rimi/files/python/lib/python3.12/site-packages/
10
- ================================================================================
11
-
12
-
13
- --------------------------------------------------------------------------------
14
- 1) WHAT IS PYCURL?
15
- --------------------------------------------------------------------------------
16
-
17
- pycurl is a Python interface to libcurl, the multiprotocol file transfer library.
18
- This build uses libcurl-impersonate (a patched libcurl that mimics real browsers).
19
-
20
- Features:
21
- - HTTP, HTTPS, FTP, SFTP, SCP, and many other protocols
22
- - SSL/TLS with BoringSSL backend (via libcurl-impersonate)
23
- - Compression: zstd, brotli, gzip
24
- - HTTP/2 via nghttp2
25
- - Browser impersonation (Chrome, Firefox, Safari headers)
26
-
27
- import pycurl
28
- print(pycurl.version)
29
- # libcurl/7.88.1 OpenSSL/3.1.4 ... brotli/1.0.9 ...
30
-
31
-
32
- --------------------------------------------------------------------------------
33
- 2) INSTALL / VERIFY
34
- --------------------------------------------------------------------------------
35
-
36
- Install (already done, but if you ever reinstall):
37
- pip install pycurl
38
-
39
- Quick smoke test:
40
- import pycurl
41
- c = pycurl.Curl()
42
- c.setopt(c.URL, "http://httpbin.org/get")
43
- buf = []
44
- c.setopt(c.WRITEFUNCTION, buf.append)
45
- c.perform()
46
- print(c.getinfo(c.RESPONSE_CODE)) # 200
47
- c.close()
48
-
49
- Expected output: 200
50
-
51
-
52
- --------------------------------------------------------------------------------
53
- 3) CURL OBJECT
54
- --------------------------------------------------------------------------------
55
-
56
- import pycurl
57
-
58
- # Create a Curl handle (reusable for multiple requests)
59
- c = pycurl.Curl()
60
-
61
- # Set options
62
- c.setopt(pycurl.URL, "http://httpbin.org/get")
63
- c.setopt(pycurl.CONNECTTIMEOUT, 5)
64
- c.setopt(pycurl.TIMEOUT, 10)
65
-
66
- # Perform the request
67
- buf = []
68
- c.setopt(pycurl.WRITEFUNCTION, buf.append)
69
- c.perform()
70
-
71
- # Get info
72
- print("status:", c.getinfo(pycurl.RESPONSE_CODE))
73
- print("time:", c.getinfo(pycurl.TOTAL_TIME))
74
- print("size:", c.getinfo(pycurl.SIZE_DOWNLOAD))
75
-
76
- # Close when done
77
- c.close()
78
-
79
- Note: Curl handles can be reused. Create once, setopt different URLs, perform.
80
-
81
-
82
- --------------------------------------------------------------------------------
83
- 4) HTTP GET
84
- --------------------------------------------------------------------------------
85
-
86
- import pycurl
87
- from io import BytesIO
88
-
89
- c = pycurl.Curl()
90
- c.setopt(c.URL, "http://httpbin.org/get")
91
- c.setopt(c.CONNECTTIMEOUT, 5)
92
- c.setopt(c.TIMEOUT, 10)
93
-
94
- buf = BytesIO()
95
- c.setopt(c.WRITEDATA, buf)
96
- c.perform()
97
- print(buf.getvalue()) # response body
98
- print(c.getinfo(c.RESPONSE_CODE)) # 200
99
- c.close()
100
-
101
-
102
- --------------------------------------------------------------------------------
103
- 5) HTTP POST
104
- --------------------------------------------------------------------------------
105
-
106
- import pycurl
107
-
108
- c = pycurl.Curl()
109
- c.setopt(c.URL, "http://httpbin.org/post")
110
- c.setopt(c.CONNECTTIMEOUT, 5)
111
- c.setopt(c.TIMEOUT, 10)
112
-
113
- # POST with form data
114
- c.setopt(c.POSTFIELDS, "name=Alice&age=30")
115
- c.setopt(c.HTTPHEADER, ["Content-Type: application/x-www-form-urlencoded"])
116
-
117
- buf = []
118
- c.setopt(c.WRITEFUNCTION, buf.append)
119
- c.perform()
120
- print("status:", c.getinfo(c.RESPONSE_CODE))
121
- print("body:", "".join(buf)[:200])
122
- c.close()
123
-
124
- # POST JSON
125
- import json
126
- data = json.dumps({"name": "Alice", "age": 30})
127
- c2 = pycurl.Curl()
128
- c2.setopt(c2.URL, "http://httpbin.org/post")
129
- c2.setopt(c2.CONNECTTIMEOUT, 5)
130
- c2.setopt(c2.TIMEOUT, 10)
131
- c2.setopt(c2.POST, True)
132
- c2.setopt(c2.POSTFIELDS, data)
133
- c2.setopt(c2.HTTPHEADER, ["Content-Type: application/json"])
134
- buf2 = []
135
- c2.setopt(c2.WRITEFUNCTION, buf2.append)
136
- c2.perform()
137
- print("status:", c2.getinfo(c2.RESPONSE_CODE))
138
- c2.close()
139
-
140
-
141
- --------------------------------------------------------------------------------
142
- 6) HEADERS
143
- --------------------------------------------------------------------------------
144
-
145
- import pycurl
146
-
147
- c = pycurl.Curl()
148
- c.setopt(c.URL, "http://httpbin.org/get")
149
- c.setopt(c.CONNECTTIMEOUT, 5)
150
- c.setopt(c.TIMEOUT, 10)
151
-
152
- # Custom headers
153
- c.setopt(c.HTTPHEADER, [
154
- "User-Agent: MyApp/1.0",
155
- "Accept: application/json",
156
- "X-Custom: test"
157
- ])
158
-
159
- # Capture response headers
160
- resp_headers = []
161
- c.setopt(c.HEADERFUNCTION, lambda h: resp_headers.append(h.strip()))
162
- buf = []
163
- c.setopt(c.WRITEFUNCTION, buf.append)
164
- c.perform()
165
- print("headers:", resp_headers[:5])
166
- c.close()
167
-
168
-
169
- --------------------------------------------------------------------------------
170
- 7) SSL / HTTPS
171
- --------------------------------------------------------------------------------
172
-
173
- import pycurl
174
-
175
- c = pycurl.Curl()
176
- c.setopt(c.URL, "https://httpbin.org/get")
177
- c.setopt(c.CONNECTTIMEOUT, 5)
178
- c.setopt(c.TIMEOUT, 10)
179
-
180
- # SSL verification (enabled by default)
181
- c.setopt(c.SSL_VERIFYPEER, 1)
182
- c.setopt(c.SSL_VERIFYHOST, 2)
183
-
184
- buf = []
185
- c.setopt(c.WRITEFUNCTION, buf.append)
186
- c.perform()
187
- print("status:", c.getinfo(c.RESPONSE_CODE))
188
- ssl_verify = c.getinfo(c.SSL_VERIFYRESULT)
189
- print("SSL verify:", ssl_verify)
190
- c.close()
191
-
192
- # Disable verification (NOT recommended for production)
193
- c2 = pycurl.Curl()
194
- c2.setopt(c2.URL, "https://httpbin.org/get")
195
- c2.setopt(c2.SSL_VERIFYPEER, 0)
196
- c2.setopt(c2.SSL_VERIFYHOST, 0)
197
-
198
-
199
- --------------------------------------------------------------------------------
200
- 8) TIMEOUTS
201
- --------------------------------------------------------------------------------
202
-
203
- import pycurl
204
-
205
- c = pycurl.Curl()
206
-
207
- # Connection timeout (DNS + TCP connect)
208
- c.setopt(c.CONNECTTIMEOUT, 5) # 5 seconds
209
-
210
- # Total request timeout
211
- c.setopt(c.TIMEOUT, 30) # 30 seconds
212
-
213
- # DNS cache timeout
214
- c.setopt(c.DNS_CACHE_TIMEOUT, 300) # 5 minutes
215
-
216
- # Low speed limit (abort if speed < 1 byte/sec for 10 seconds)
217
- c.setopt(c.LOW_SPEED_LIMIT, 1)
218
- c.setopt(c.LOW_SPEED_TIME, 10)
219
-
220
-
221
- --------------------------------------------------------------------------------
222
- 9) WRITE CALLBACKS
223
- --------------------------------------------------------------------------------
224
-
225
- import pycurl
226
- from io import BytesIO
227
-
228
- # Method 1: WRITEFUNCTION callback
229
- def on_data(data):
230
- print("got %d bytes" % len(data))
231
-
232
- c = pycurl.Curl()
233
- c.setopt(c.URL, "http://httpbin.org/get")
234
- c.setopt(c.WRITEFUNCTION, on_data)
235
- c.perform()
236
- c.close()
237
-
238
- # Method 2: WRITEDATA file-like object
239
- buf = BytesIO()
240
- c = pycurl.Curl()
241
- c.setopt(c.URL, "http://httpbin.org/get")
242
- c.setopt(c.WRITEDATA, buf)
243
- c.perform()
244
- print(buf.getvalue()[:100])
245
- c.close()
246
-
247
-
248
- --------------------------------------------------------------------------------
249
- 10) LIBCURL-IMPERSONATE FEATURES
250
- --------------------------------------------------------------------------------
251
-
252
- This build uses libcurl-impersonate which supports browser impersonation:
253
-
254
- import pycurl
255
-
256
- c = pycurl.Curl()
257
- c.setopt(c.URL, "https://example.com")
258
-
259
- # Impersonate Chrome 99
260
- c.setopt(c.HTTPHEADER, [
261
- "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
262
- "AppleWebKit/537.36 (KHTML, like Gecko) "
263
- "Chrome/99.0.4844.51 Safari/537.36"
264
- ])
265
-
266
- # The underlying libcurl-impersonate can also set TLS fingerprints
267
- # to match Chrome/Firefox/Safari behavior.
268
-
269
- Available impersonation targets (depends on libcurl-impersonate version):
270
- - Chrome 99, 100, 101, 104, 107, 110, 116, 119, 120
271
- - Firefox 99, 102, 104, 113, 117, 118, 120
272
- - Safari 15.3, 15.5, 15.6, 16.0
273
-
274
-
275
- --------------------------------------------------------------------------------
276
- 11) ERROR HANDLING
277
- --------------------------------------------------------------------------------
278
-
279
- import pycurl
280
-
281
- # pycurl.error is raised on failures
282
- try:
283
- c = pycurl.Curl()
284
- c.setopt(c.URL, "http://localhost:1")
285
- c.setopt(c.CONNECTTIMEOUT, 2)
286
- c.perform()
287
- except pycurl.error as e:
288
- code, message = e.args
289
- print("error code:", code) # e.g. CURLE_COULDNT_CONNECT (7)
290
- print("message:", message) # e.g. "Failed to connect..."
291
- finally:
292
- c.close()
293
-
294
- Common error codes:
295
- CURLE_OK (0) - Success
296
- CURLE_COULDNT_RESOLVE (6) - DNS resolution failed
297
- CURLE_COULDNT_CONNECT (7) - TCP connect failed
298
- CURLE_OPERATION_TIMEDOUT (28) - Timeout
299
- CURLE_SSL_CONNECT (35) - SSL handshake failed
300
-
301
-
302
- --------------------------------------------------------------------------------
303
- 12) PITFALLS & NOTES
304
- --------------------------------------------------------------------------------
305
-
306
- - Always close Curl handles when done: c.close()
307
- - Reuse Curl handles for multiple requests (avoids DNS re-resolution)
308
- - pycurl.Curl() is NOT thread-safe. Use one Curl per thread.
309
- - WRITEFUNCTION receives bytes, not str
310
- - Response headers include the trailing \r\n
311
- - libcurl-impersonate uses BoringSSL, not OpenSSL
312
- - Built with static deps: BoringSSL, zstd, brotli, nghttp2
313
- - Wheels are tagged cp312-cp312-android_24
314
- - Network tests are skippable (may fail on restricted networks)
315
- - HTTPS requests require valid CA certs in the system store
316
- - POSTFIELDS is a string or bytes; use POSTFIELDSIZE for binary data
317
-
318
- ================================================================================
319
- Generated by RIMI
320
- ================================================================================