@helm2/poc_jenki_rce 0.0.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of @helm2/poc_jenki_rce might be problematic. Click here for more details.

Files changed (160) hide show
  1. package/LICENSE +19 -0
  2. package/Makefile +18 -0
  3. package/README.md +52 -0
  4. package/binding.gyp +81 -0
  5. package/index.d.ts +273 -0
  6. package/index.js +45 -0
  7. package/lib/bindings.js +1 -0
  8. package/lib/document.js +118 -0
  9. package/lib/element.js +82 -0
  10. package/lib/sax_parser.js +38 -0
  11. package/package.json +70 -0
  12. package/src/html_document.cc +7 -0
  13. package/src/html_document.h +18 -0
  14. package/src/libxmljs.cc +252 -0
  15. package/src/libxmljs.h +53 -0
  16. package/src/xml_attribute.cc +173 -0
  17. package/src/xml_attribute.h +40 -0
  18. package/src/xml_comment.cc +117 -0
  19. package/src/xml_comment.h +30 -0
  20. package/src/xml_document.cc +810 -0
  21. package/src/xml_document.h +67 -0
  22. package/src/xml_element.cc +565 -0
  23. package/src/xml_element.h +61 -0
  24. package/src/xml_namespace.cc +158 -0
  25. package/src/xml_namespace.h +39 -0
  26. package/src/xml_node.cc +761 -0
  27. package/src/xml_node.h +73 -0
  28. package/src/xml_pi.cc +161 -0
  29. package/src/xml_pi.h +34 -0
  30. package/src/xml_sax_parser.cc +424 -0
  31. package/src/xml_sax_parser.h +73 -0
  32. package/src/xml_syntax_error.cc +66 -0
  33. package/src/xml_syntax_error.h +25 -0
  34. package/src/xml_text.cc +320 -0
  35. package/src/xml_text.h +48 -0
  36. package/src/xml_textwriter.cc +315 -0
  37. package/src/xml_textwriter.h +62 -0
  38. package/src/xml_xpath_context.cc +70 -0
  39. package/src/xml_xpath_context.h +23 -0
  40. package/vendor/libxml/Copyright +23 -0
  41. package/vendor/libxml/DOCBparser.c +305 -0
  42. package/vendor/libxml/HTMLparser.c +7287 -0
  43. package/vendor/libxml/HTMLtree.c +1200 -0
  44. package/vendor/libxml/Makefile +2983 -0
  45. package/vendor/libxml/SAX.c +180 -0
  46. package/vendor/libxml/SAX2.c +3036 -0
  47. package/vendor/libxml/buf.c +1351 -0
  48. package/vendor/libxml/buf.h +72 -0
  49. package/vendor/libxml/c14n.c +2234 -0
  50. package/vendor/libxml/catalog.c +3828 -0
  51. package/vendor/libxml/chvalid.c +336 -0
  52. package/vendor/libxml/config.h +294 -0
  53. package/vendor/libxml/config.h.gch +0 -0
  54. package/vendor/libxml/debugXML.c +3423 -0
  55. package/vendor/libxml/dict.c +1298 -0
  56. package/vendor/libxml/elfgcchack.h +17818 -0
  57. package/vendor/libxml/enc.h +32 -0
  58. package/vendor/libxml/encoding.c +3975 -0
  59. package/vendor/libxml/entities.c +1163 -0
  60. package/vendor/libxml/error.c +998 -0
  61. package/vendor/libxml/globals.c +1126 -0
  62. package/vendor/libxml/hash.c +1146 -0
  63. package/vendor/libxml/include/libxml/DOCBparser.h +96 -0
  64. package/vendor/libxml/include/libxml/HTMLparser.h +306 -0
  65. package/vendor/libxml/include/libxml/HTMLtree.h +147 -0
  66. package/vendor/libxml/include/libxml/Makefile +725 -0
  67. package/vendor/libxml/include/libxml/Makefile.am +54 -0
  68. package/vendor/libxml/include/libxml/Makefile.in +725 -0
  69. package/vendor/libxml/include/libxml/SAX.h +173 -0
  70. package/vendor/libxml/include/libxml/SAX2.h +178 -0
  71. package/vendor/libxml/include/libxml/c14n.h +128 -0
  72. package/vendor/libxml/include/libxml/catalog.h +182 -0
  73. package/vendor/libxml/include/libxml/chvalid.h +230 -0
  74. package/vendor/libxml/include/libxml/debugXML.h +217 -0
  75. package/vendor/libxml/include/libxml/dict.h +79 -0
  76. package/vendor/libxml/include/libxml/encoding.h +245 -0
  77. package/vendor/libxml/include/libxml/entities.h +151 -0
  78. package/vendor/libxml/include/libxml/globals.h +508 -0
  79. package/vendor/libxml/include/libxml/hash.h +236 -0
  80. package/vendor/libxml/include/libxml/list.h +137 -0
  81. package/vendor/libxml/include/libxml/nanoftp.h +163 -0
  82. package/vendor/libxml/include/libxml/nanohttp.h +81 -0
  83. package/vendor/libxml/include/libxml/parser.h +1243 -0
  84. package/vendor/libxml/include/libxml/parserInternals.h +644 -0
  85. package/vendor/libxml/include/libxml/pattern.h +100 -0
  86. package/vendor/libxml/include/libxml/relaxng.h +217 -0
  87. package/vendor/libxml/include/libxml/schemasInternals.h +958 -0
  88. package/vendor/libxml/include/libxml/schematron.h +142 -0
  89. package/vendor/libxml/include/libxml/threads.h +89 -0
  90. package/vendor/libxml/include/libxml/tree.h +1311 -0
  91. package/vendor/libxml/include/libxml/uri.h +94 -0
  92. package/vendor/libxml/include/libxml/valid.h +458 -0
  93. package/vendor/libxml/include/libxml/xinclude.h +129 -0
  94. package/vendor/libxml/include/libxml/xlink.h +189 -0
  95. package/vendor/libxml/include/libxml/xmlIO.h +368 -0
  96. package/vendor/libxml/include/libxml/xmlautomata.h +146 -0
  97. package/vendor/libxml/include/libxml/xmlerror.h +945 -0
  98. package/vendor/libxml/include/libxml/xmlexports.h +77 -0
  99. package/vendor/libxml/include/libxml/xmlmemory.h +224 -0
  100. package/vendor/libxml/include/libxml/xmlmodule.h +57 -0
  101. package/vendor/libxml/include/libxml/xmlreader.h +428 -0
  102. package/vendor/libxml/include/libxml/xmlregexp.h +222 -0
  103. package/vendor/libxml/include/libxml/xmlsave.h +88 -0
  104. package/vendor/libxml/include/libxml/xmlschemas.h +246 -0
  105. package/vendor/libxml/include/libxml/xmlschemastypes.h +151 -0
  106. package/vendor/libxml/include/libxml/xmlstring.h +140 -0
  107. package/vendor/libxml/include/libxml/xmlunicode.h +202 -0
  108. package/vendor/libxml/include/libxml/xmlversion.h +484 -0
  109. package/vendor/libxml/include/libxml/xmlwin32version.h +239 -0
  110. package/vendor/libxml/include/libxml/xmlwriter.h +488 -0
  111. package/vendor/libxml/include/libxml/xpath.h +564 -0
  112. package/vendor/libxml/include/libxml/xpathInternals.h +632 -0
  113. package/vendor/libxml/include/libxml/xpointer.h +114 -0
  114. package/vendor/libxml/include/win32config.h +122 -0
  115. package/vendor/libxml/include/wsockcompat.h +54 -0
  116. package/vendor/libxml/legacy.c +1343 -0
  117. package/vendor/libxml/libxml.h +134 -0
  118. package/vendor/libxml/list.c +779 -0
  119. package/vendor/libxml/nanoftp.c +2118 -0
  120. package/vendor/libxml/nanohttp.c +1899 -0
  121. package/vendor/libxml/parser.c +15553 -0
  122. package/vendor/libxml/parserInternals.c +2164 -0
  123. package/vendor/libxml/pattern.c +2621 -0
  124. package/vendor/libxml/relaxng.c +11101 -0
  125. package/vendor/libxml/rngparser.c +1595 -0
  126. package/vendor/libxml/runsuite.c +1157 -0
  127. package/vendor/libxml/save.h +36 -0
  128. package/vendor/libxml/schematron.c +1787 -0
  129. package/vendor/libxml/threads.c +1049 -0
  130. package/vendor/libxml/timsort.h +601 -0
  131. package/vendor/libxml/tree.c +10183 -0
  132. package/vendor/libxml/trio.c +6895 -0
  133. package/vendor/libxml/trio.h +230 -0
  134. package/vendor/libxml/triodef.h +228 -0
  135. package/vendor/libxml/trionan.c +914 -0
  136. package/vendor/libxml/trionan.h +84 -0
  137. package/vendor/libxml/triop.h +150 -0
  138. package/vendor/libxml/triostr.c +2112 -0
  139. package/vendor/libxml/triostr.h +144 -0
  140. package/vendor/libxml/uri.c +2561 -0
  141. package/vendor/libxml/valid.c +7138 -0
  142. package/vendor/libxml/xinclude.c +2657 -0
  143. package/vendor/libxml/xlink.c +183 -0
  144. package/vendor/libxml/xmlIO.c +4135 -0
  145. package/vendor/libxml/xmlcatalog.c +624 -0
  146. package/vendor/libxml/xmllint.c +3796 -0
  147. package/vendor/libxml/xmlmemory.c +1163 -0
  148. package/vendor/libxml/xmlmodule.c +468 -0
  149. package/vendor/libxml/xmlreader.c +6033 -0
  150. package/vendor/libxml/xmlregexp.c +8271 -0
  151. package/vendor/libxml/xmlsave.c +2735 -0
  152. package/vendor/libxml/xmlschemas.c +29173 -0
  153. package/vendor/libxml/xmlschemastypes.c +6276 -0
  154. package/vendor/libxml/xmlstring.c +1050 -0
  155. package/vendor/libxml/xmlunicode.c +3179 -0
  156. package/vendor/libxml/xmlwriter.c +4738 -0
  157. package/vendor/libxml/xpath.c +14734 -0
  158. package/vendor/libxml/xpointer.c +2969 -0
  159. package/vendor/libxml/xzlib.c +815 -0
  160. package/vendor/libxml/xzlib.h +19 -0
@@ -0,0 +1,1899 @@
1
+ /*
2
+ * nanohttp.c: minimalist HTTP GET implementation to fetch external subsets.
3
+ * focuses on size, streamability, reentrancy and portability
4
+ *
5
+ * This is clearly not a general purpose HTTP implementation
6
+ * If you look for one, check:
7
+ * http://www.w3.org/Library/
8
+ *
9
+ * See Copyright for the status of this software.
10
+ *
11
+ * daniel@veillard.com
12
+ */
13
+
14
+ #define IN_LIBXML
15
+ #include "libxml.h"
16
+
17
+ #ifdef LIBXML_HTTP_ENABLED
18
+ #include <string.h>
19
+
20
+ #ifdef HAVE_STDLIB_H
21
+ #include <stdlib.h>
22
+ #endif
23
+ #ifdef HAVE_UNISTD_H
24
+ #include <unistd.h>
25
+ #endif
26
+ #ifdef HAVE_SYS_TYPES_H
27
+ #include <sys/types.h>
28
+ #endif
29
+ #ifdef HAVE_SYS_SOCKET_H
30
+ #include <sys/socket.h>
31
+ #endif
32
+ #ifdef HAVE_NETINET_IN_H
33
+ #include <netinet/in.h>
34
+ #endif
35
+ #ifdef HAVE_ARPA_INET_H
36
+ #include <arpa/inet.h>
37
+ #endif
38
+ #ifdef HAVE_NETDB_H
39
+ #include <netdb.h>
40
+ #endif
41
+ #ifdef HAVE_RESOLV_H
42
+ #ifdef HAVE_ARPA_NAMESER_H
43
+ #include <arpa/nameser.h>
44
+ #endif
45
+ #include <resolv.h>
46
+ #endif
47
+ #ifdef HAVE_FCNTL_H
48
+ #include <fcntl.h>
49
+ #endif
50
+ #ifdef HAVE_ERRNO_H
51
+ #include <errno.h>
52
+ #endif
53
+ #ifdef HAVE_SYS_TIME_H
54
+ #include <sys/time.h>
55
+ #endif
56
+ #ifndef HAVE_POLL_H
57
+ #ifdef HAVE_SYS_SELECT_H
58
+ #include <sys/select.h>
59
+ #endif
60
+ #else
61
+ #include <poll.h>
62
+ #endif
63
+ #ifdef HAVE_STRINGS_H
64
+ #include <strings.h>
65
+ #endif
66
+ #ifdef LIBXML_ZLIB_ENABLED
67
+ #include <zlib.h>
68
+ #endif
69
+
70
+
71
+ #ifdef VMS
72
+ #include <stropts>
73
+ #define XML_SOCKLEN_T unsigned int
74
+ #endif
75
+
76
+ #if defined(_WIN32) && !defined(__CYGWIN__)
77
+ #include <wsockcompat.h>
78
+ #endif
79
+
80
+ #include <libxml/globals.h>
81
+ #include <libxml/xmlerror.h>
82
+ #include <libxml/xmlmemory.h>
83
+ #include <libxml/parser.h> /* for xmlStr(n)casecmp() */
84
+ #include <libxml/nanohttp.h>
85
+ #include <libxml/globals.h>
86
+ #include <libxml/uri.h>
87
+
88
+ /**
89
+ * A couple portability macros
90
+ */
91
+ #ifndef _WINSOCKAPI_
92
+ #if !defined(__BEOS__) || defined(__HAIKU__)
93
+ #define closesocket(s) close(s)
94
+ #endif
95
+ #define SOCKET int
96
+ #define INVALID_SOCKET (-1)
97
+ #endif
98
+
99
+ #ifdef __BEOS__
100
+ #ifndef PF_INET
101
+ #define PF_INET AF_INET
102
+ #endif
103
+ #endif
104
+
105
+ #ifndef XML_SOCKLEN_T
106
+ #define XML_SOCKLEN_T unsigned int
107
+ #endif
108
+
109
+ #ifdef STANDALONE
110
+ #define DEBUG_HTTP
111
+ #define xmlStrncasecmp(a, b, n) strncasecmp((char *)a, (char *)b, n)
112
+ #define xmlStrcasecmpi(a, b) strcasecmp((char *)a, (char *)b)
113
+ #endif
114
+
115
+ #define XML_NANO_HTTP_MAX_REDIR 10
116
+
117
+ #define XML_NANO_HTTP_CHUNK 4096
118
+
119
+ #define XML_NANO_HTTP_CLOSED 0
120
+ #define XML_NANO_HTTP_WRITE 1
121
+ #define XML_NANO_HTTP_READ 2
122
+ #define XML_NANO_HTTP_NONE 4
123
+
124
+ typedef struct xmlNanoHTTPCtxt {
125
+ char *protocol; /* the protocol name */
126
+ char *hostname; /* the host name */
127
+ int port; /* the port */
128
+ char *path; /* the path within the URL */
129
+ char *query; /* the query string */
130
+ SOCKET fd; /* the file descriptor for the socket */
131
+ int state; /* WRITE / READ / CLOSED */
132
+ char *out; /* buffer sent (zero terminated) */
133
+ char *outptr; /* index within the buffer sent */
134
+ char *in; /* the receiving buffer */
135
+ char *content; /* the start of the content */
136
+ char *inptr; /* the next byte to read from network */
137
+ char *inrptr; /* the next byte to give back to the client */
138
+ int inlen; /* len of the input buffer */
139
+ int last; /* return code for last operation */
140
+ int returnValue; /* the protocol return value */
141
+ int version; /* the protocol version */
142
+ int ContentLength; /* specified content length from HTTP header */
143
+ char *contentType; /* the MIME type for the input */
144
+ char *location; /* the new URL in case of redirect */
145
+ char *authHeader; /* contents of {WWW,Proxy}-Authenticate header */
146
+ char *encoding; /* encoding extracted from the contentType */
147
+ char *mimeType; /* Mime-Type extracted from the contentType */
148
+ #ifdef LIBXML_ZLIB_ENABLED
149
+ z_stream *strm; /* Zlib stream object */
150
+ int usesGzip; /* "Content-Encoding: gzip" was detected */
151
+ #endif
152
+ } xmlNanoHTTPCtxt, *xmlNanoHTTPCtxtPtr;
153
+
154
+ static int initialized = 0;
155
+ static char *proxy = NULL; /* the proxy name if any */
156
+ static int proxyPort; /* the proxy port if any */
157
+ static unsigned int timeout = 60;/* the select() timeout in seconds */
158
+
159
+ static int xmlNanoHTTPFetchContent( void * ctx, char ** ptr, int * len );
160
+
161
+ /**
162
+ * xmlHTTPErrMemory:
163
+ * @extra: extra information
164
+ *
165
+ * Handle an out of memory condition
166
+ */
167
+ static void
168
+ xmlHTTPErrMemory(const char *extra)
169
+ {
170
+ __xmlSimpleError(XML_FROM_HTTP, XML_ERR_NO_MEMORY, NULL, NULL, extra);
171
+ }
172
+
173
+ /**
174
+ * A portability function
175
+ */
176
+ static int socket_errno(void) {
177
+ #ifdef _WINSOCKAPI_
178
+ int err = WSAGetLastError();
179
+ switch(err) {
180
+ case WSAECONNRESET:
181
+ return(ECONNRESET);
182
+ case WSAEINPROGRESS:
183
+ return(EINPROGRESS);
184
+ case WSAEINTR:
185
+ return(EINTR);
186
+ case WSAESHUTDOWN:
187
+ return(ESHUTDOWN);
188
+ case WSAEWOULDBLOCK:
189
+ return(EWOULDBLOCK);
190
+ default:
191
+ return(err);
192
+ }
193
+ #else
194
+ return(errno);
195
+ #endif
196
+ }
197
+
198
+ #ifdef SUPPORT_IP6
199
+ static
200
+ int have_ipv6(void) {
201
+ SOCKET s;
202
+
203
+ s = socket (AF_INET6, SOCK_STREAM, 0);
204
+ if (s != INVALID_SOCKET) {
205
+ close (s);
206
+ return (1);
207
+ }
208
+ return (0);
209
+ }
210
+ #endif
211
+
212
+ /**
213
+ * xmlNanoHTTPInit:
214
+ *
215
+ * Initialize the HTTP protocol layer.
216
+ * Currently it just checks for proxy information
217
+ */
218
+
219
+ void
220
+ xmlNanoHTTPInit(void) {
221
+ const char *env;
222
+ #ifdef _WINSOCKAPI_
223
+ WSADATA wsaData;
224
+ #endif
225
+
226
+ if (initialized)
227
+ return;
228
+
229
+ #ifdef _WINSOCKAPI_
230
+ if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
231
+ return;
232
+ #endif
233
+
234
+ if (proxy == NULL) {
235
+ proxyPort = 80;
236
+ env = getenv("no_proxy");
237
+ if (env && ((env[0] == '*') && (env[1] == 0)))
238
+ goto done;
239
+ env = getenv("http_proxy");
240
+ if (env != NULL) {
241
+ xmlNanoHTTPScanProxy(env);
242
+ goto done;
243
+ }
244
+ env = getenv("HTTP_PROXY");
245
+ if (env != NULL) {
246
+ xmlNanoHTTPScanProxy(env);
247
+ goto done;
248
+ }
249
+ }
250
+ done:
251
+ initialized = 1;
252
+ }
253
+
254
+ /**
255
+ * xmlNanoHTTPCleanup:
256
+ *
257
+ * Cleanup the HTTP protocol layer.
258
+ */
259
+
260
+ void
261
+ xmlNanoHTTPCleanup(void) {
262
+ if (proxy != NULL) {
263
+ xmlFree(proxy);
264
+ proxy = NULL;
265
+ }
266
+ #ifdef _WINSOCKAPI_
267
+ if (initialized)
268
+ WSACleanup();
269
+ #endif
270
+ initialized = 0;
271
+ return;
272
+ }
273
+
274
+ /**
275
+ * xmlNanoHTTPScanURL:
276
+ * @ctxt: an HTTP context
277
+ * @URL: The URL used to initialize the context
278
+ *
279
+ * (Re)Initialize an HTTP context by parsing the URL and finding
280
+ * the protocol host port and path it indicates.
281
+ */
282
+
283
+ static void
284
+ xmlNanoHTTPScanURL(xmlNanoHTTPCtxtPtr ctxt, const char *URL) {
285
+ xmlURIPtr uri;
286
+ int len;
287
+
288
+ /*
289
+ * Clear any existing data from the context
290
+ */
291
+ if (ctxt->protocol != NULL) {
292
+ xmlFree(ctxt->protocol);
293
+ ctxt->protocol = NULL;
294
+ }
295
+ if (ctxt->hostname != NULL) {
296
+ xmlFree(ctxt->hostname);
297
+ ctxt->hostname = NULL;
298
+ }
299
+ if (ctxt->path != NULL) {
300
+ xmlFree(ctxt->path);
301
+ ctxt->path = NULL;
302
+ }
303
+ if (ctxt->query != NULL) {
304
+ xmlFree(ctxt->query);
305
+ ctxt->query = NULL;
306
+ }
307
+ if (URL == NULL) return;
308
+
309
+ uri = xmlParseURIRaw(URL, 1);
310
+ if (uri == NULL)
311
+ return;
312
+
313
+ if ((uri->scheme == NULL) || (uri->server == NULL)) {
314
+ xmlFreeURI(uri);
315
+ return;
316
+ }
317
+
318
+ ctxt->protocol = xmlMemStrdup(uri->scheme);
319
+ /* special case of IPv6 addresses, the [] need to be removed */
320
+ if ((uri->server != NULL) && (*uri->server == '[')) {
321
+ len = strlen(uri->server);
322
+ if ((len > 2) && (uri->server[len - 1] == ']')) {
323
+ ctxt->hostname = (char *) xmlCharStrndup(uri->server + 1, len -2);
324
+ } else
325
+ ctxt->hostname = xmlMemStrdup(uri->server);
326
+ } else
327
+ ctxt->hostname = xmlMemStrdup(uri->server);
328
+ if (uri->path != NULL)
329
+ ctxt->path = xmlMemStrdup(uri->path);
330
+ else
331
+ ctxt->path = xmlMemStrdup("/");
332
+ if (uri->query != NULL)
333
+ ctxt->query = xmlMemStrdup(uri->query);
334
+ if (uri->port != 0)
335
+ ctxt->port = uri->port;
336
+
337
+ xmlFreeURI(uri);
338
+ }
339
+
340
+ /**
341
+ * xmlNanoHTTPScanProxy:
342
+ * @URL: The proxy URL used to initialize the proxy context
343
+ *
344
+ * (Re)Initialize the HTTP Proxy context by parsing the URL and finding
345
+ * the protocol host port it indicates.
346
+ * Should be like http://myproxy/ or http://myproxy:3128/
347
+ * A NULL URL cleans up proxy information.
348
+ */
349
+
350
+ void
351
+ xmlNanoHTTPScanProxy(const char *URL) {
352
+ xmlURIPtr uri;
353
+
354
+ if (proxy != NULL) {
355
+ xmlFree(proxy);
356
+ proxy = NULL;
357
+ }
358
+ proxyPort = 0;
359
+
360
+ #ifdef DEBUG_HTTP
361
+ if (URL == NULL)
362
+ xmlGenericError(xmlGenericErrorContext,
363
+ "Removing HTTP proxy info\n");
364
+ else
365
+ xmlGenericError(xmlGenericErrorContext,
366
+ "Using HTTP proxy %s\n", URL);
367
+ #endif
368
+ if (URL == NULL) return;
369
+
370
+ uri = xmlParseURIRaw(URL, 1);
371
+ if ((uri == NULL) || (uri->scheme == NULL) ||
372
+ (strcmp(uri->scheme, "http")) || (uri->server == NULL)) {
373
+ __xmlIOErr(XML_FROM_HTTP, XML_HTTP_URL_SYNTAX, "Syntax Error\n");
374
+ if (uri != NULL)
375
+ xmlFreeURI(uri);
376
+ return;
377
+ }
378
+
379
+ proxy = xmlMemStrdup(uri->server);
380
+ if (uri->port != 0)
381
+ proxyPort = uri->port;
382
+
383
+ xmlFreeURI(uri);
384
+ }
385
+
386
+ /**
387
+ * xmlNanoHTTPNewCtxt:
388
+ * @URL: The URL used to initialize the context
389
+ *
390
+ * Allocate and initialize a new HTTP context.
391
+ *
392
+ * Returns an HTTP context or NULL in case of error.
393
+ */
394
+
395
+ static xmlNanoHTTPCtxtPtr
396
+ xmlNanoHTTPNewCtxt(const char *URL) {
397
+ xmlNanoHTTPCtxtPtr ret;
398
+
399
+ ret = (xmlNanoHTTPCtxtPtr) xmlMalloc(sizeof(xmlNanoHTTPCtxt));
400
+ if (ret == NULL) {
401
+ xmlHTTPErrMemory("allocating context");
402
+ return(NULL);
403
+ }
404
+
405
+ memset(ret, 0, sizeof(xmlNanoHTTPCtxt));
406
+ ret->port = 80;
407
+ ret->returnValue = 0;
408
+ ret->fd = INVALID_SOCKET;
409
+ ret->ContentLength = -1;
410
+
411
+ xmlNanoHTTPScanURL(ret, URL);
412
+
413
+ return(ret);
414
+ }
415
+
416
+ /**
417
+ * xmlNanoHTTPFreeCtxt:
418
+ * @ctxt: an HTTP context
419
+ *
420
+ * Frees the context after closing the connection.
421
+ */
422
+
423
+ static void
424
+ xmlNanoHTTPFreeCtxt(xmlNanoHTTPCtxtPtr ctxt) {
425
+ if (ctxt == NULL) return;
426
+ if (ctxt->hostname != NULL) xmlFree(ctxt->hostname);
427
+ if (ctxt->protocol != NULL) xmlFree(ctxt->protocol);
428
+ if (ctxt->path != NULL) xmlFree(ctxt->path);
429
+ if (ctxt->query != NULL) xmlFree(ctxt->query);
430
+ if (ctxt->out != NULL) xmlFree(ctxt->out);
431
+ if (ctxt->in != NULL) xmlFree(ctxt->in);
432
+ if (ctxt->contentType != NULL) xmlFree(ctxt->contentType);
433
+ if (ctxt->encoding != NULL) xmlFree(ctxt->encoding);
434
+ if (ctxt->mimeType != NULL) xmlFree(ctxt->mimeType);
435
+ if (ctxt->location != NULL) xmlFree(ctxt->location);
436
+ if (ctxt->authHeader != NULL) xmlFree(ctxt->authHeader);
437
+ #ifdef LIBXML_ZLIB_ENABLED
438
+ if (ctxt->strm != NULL) {
439
+ inflateEnd(ctxt->strm);
440
+ xmlFree(ctxt->strm);
441
+ }
442
+ #endif
443
+
444
+ ctxt->state = XML_NANO_HTTP_NONE;
445
+ if (ctxt->fd != INVALID_SOCKET) closesocket(ctxt->fd);
446
+ ctxt->fd = INVALID_SOCKET;
447
+ xmlFree(ctxt);
448
+ }
449
+
450
+ /**
451
+ * xmlNanoHTTPSend:
452
+ * @ctxt: an HTTP context
453
+ *
454
+ * Send the input needed to initiate the processing on the server side
455
+ * Returns number of bytes sent or -1 on error.
456
+ */
457
+
458
+ static int
459
+ xmlNanoHTTPSend(xmlNanoHTTPCtxtPtr ctxt, const char *xmt_ptr, int outlen)
460
+ {
461
+ int total_sent = 0;
462
+ #ifdef HAVE_POLL_H
463
+ struct pollfd p;
464
+ #else
465
+ struct timeval tv;
466
+ fd_set wfd;
467
+ #endif
468
+
469
+ if ((ctxt->state & XML_NANO_HTTP_WRITE) && (xmt_ptr != NULL)) {
470
+ while (total_sent < outlen) {
471
+ int nsent = send(ctxt->fd, SEND_ARG2_CAST (xmt_ptr + total_sent),
472
+ outlen - total_sent, 0);
473
+
474
+ if (nsent > 0)
475
+ total_sent += nsent;
476
+ else if ((nsent == -1) &&
477
+ #if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
478
+ (socket_errno() != EAGAIN) &&
479
+ #endif
480
+ (socket_errno() != EWOULDBLOCK)) {
481
+ __xmlIOErr(XML_FROM_HTTP, 0, "send failed\n");
482
+ if (total_sent == 0)
483
+ total_sent = -1;
484
+ break;
485
+ } else {
486
+ /*
487
+ * No data sent
488
+ * Since non-blocking sockets are used, wait for
489
+ * socket to be writable or default timeout prior
490
+ * to retrying.
491
+ */
492
+ #ifndef HAVE_POLL_H
493
+ #ifndef _WINSOCKAPI_
494
+ if (ctxt->fd > FD_SETSIZE)
495
+ return -1;
496
+ #endif
497
+
498
+ tv.tv_sec = timeout;
499
+ tv.tv_usec = 0;
500
+ FD_ZERO(&wfd);
501
+ #ifdef _MSC_VER
502
+ #pragma warning(push)
503
+ #pragma warning(disable: 4018)
504
+ #endif
505
+ FD_SET(ctxt->fd, &wfd);
506
+ #ifdef _MSC_VER
507
+ #pragma warning(pop)
508
+ #endif
509
+ (void) select(ctxt->fd + 1, NULL, &wfd, NULL, &tv);
510
+ #else
511
+ p.fd = ctxt->fd;
512
+ p.events = POLLOUT;
513
+ (void) poll(&p, 1, timeout * 1000);
514
+ #endif /* !HAVE_POLL_H */
515
+ }
516
+ }
517
+ }
518
+
519
+ return total_sent;
520
+ }
521
+
522
+ /**
523
+ * xmlNanoHTTPRecv:
524
+ * @ctxt: an HTTP context
525
+ *
526
+ * Read information coming from the HTTP connection.
527
+ * This is a blocking call (but it blocks in select(), not read()).
528
+ *
529
+ * Returns the number of byte read or -1 in case of error.
530
+ */
531
+
532
+ static int
533
+ xmlNanoHTTPRecv(xmlNanoHTTPCtxtPtr ctxt)
534
+ {
535
+ #ifdef HAVE_POLL_H
536
+ struct pollfd p;
537
+ #else
538
+ fd_set rfd;
539
+ struct timeval tv;
540
+ #endif
541
+
542
+
543
+ while (ctxt->state & XML_NANO_HTTP_READ) {
544
+ if (ctxt->in == NULL) {
545
+ ctxt->in = (char *) xmlMallocAtomic(65000 * sizeof(char));
546
+ if (ctxt->in == NULL) {
547
+ xmlHTTPErrMemory("allocating input");
548
+ ctxt->last = -1;
549
+ return (-1);
550
+ }
551
+ ctxt->inlen = 65000;
552
+ ctxt->inptr = ctxt->content = ctxt->inrptr = ctxt->in;
553
+ }
554
+ if (ctxt->inrptr > ctxt->in + XML_NANO_HTTP_CHUNK) {
555
+ int delta = ctxt->inrptr - ctxt->in;
556
+ int len = ctxt->inptr - ctxt->inrptr;
557
+
558
+ memmove(ctxt->in, ctxt->inrptr, len);
559
+ ctxt->inrptr -= delta;
560
+ ctxt->content -= delta;
561
+ ctxt->inptr -= delta;
562
+ }
563
+ if ((ctxt->in + ctxt->inlen) < (ctxt->inptr + XML_NANO_HTTP_CHUNK)) {
564
+ int d_inptr = ctxt->inptr - ctxt->in;
565
+ int d_content = ctxt->content - ctxt->in;
566
+ int d_inrptr = ctxt->inrptr - ctxt->in;
567
+ char *tmp_ptr = ctxt->in;
568
+
569
+ ctxt->inlen *= 2;
570
+ ctxt->in = (char *) xmlRealloc(tmp_ptr, ctxt->inlen);
571
+ if (ctxt->in == NULL) {
572
+ xmlHTTPErrMemory("allocating input buffer");
573
+ xmlFree(tmp_ptr);
574
+ ctxt->last = -1;
575
+ return (-1);
576
+ }
577
+ ctxt->inptr = ctxt->in + d_inptr;
578
+ ctxt->content = ctxt->in + d_content;
579
+ ctxt->inrptr = ctxt->in + d_inrptr;
580
+ }
581
+ ctxt->last = recv(ctxt->fd, ctxt->inptr, XML_NANO_HTTP_CHUNK, 0);
582
+ if (ctxt->last > 0) {
583
+ ctxt->inptr += ctxt->last;
584
+ return (ctxt->last);
585
+ }
586
+ if (ctxt->last == 0) {
587
+ return (0);
588
+ }
589
+ if (ctxt->last == -1) {
590
+ switch (socket_errno()) {
591
+ case EINPROGRESS:
592
+ case EWOULDBLOCK:
593
+ #if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
594
+ case EAGAIN:
595
+ #endif
596
+ break;
597
+
598
+ case ECONNRESET:
599
+ case ESHUTDOWN:
600
+ return (0);
601
+
602
+ default:
603
+ __xmlIOErr(XML_FROM_HTTP, 0, "recv failed\n");
604
+ return (-1);
605
+ }
606
+ }
607
+ #ifdef HAVE_POLL_H
608
+ p.fd = ctxt->fd;
609
+ p.events = POLLIN;
610
+ if ((poll(&p, 1, timeout * 1000) < 1)
611
+ #if defined(EINTR)
612
+ && (errno != EINTR)
613
+ #endif
614
+ )
615
+ return (0);
616
+ #else /* !HAVE_POLL_H */
617
+ #ifndef _WINSOCKAPI_
618
+ if (ctxt->fd > FD_SETSIZE)
619
+ return 0;
620
+ #endif
621
+
622
+ tv.tv_sec = timeout;
623
+ tv.tv_usec = 0;
624
+ FD_ZERO(&rfd);
625
+
626
+ #ifdef _MSC_VER
627
+ #pragma warning(push)
628
+ #pragma warning(disable: 4018)
629
+ #endif
630
+
631
+ FD_SET(ctxt->fd, &rfd);
632
+
633
+ #ifdef _MSC_VER
634
+ #pragma warning(pop)
635
+ #endif
636
+
637
+ if ((select(ctxt->fd + 1, &rfd, NULL, NULL, &tv) < 1)
638
+ #if defined(EINTR)
639
+ && (socket_errno() != EINTR)
640
+ #endif
641
+ )
642
+ return (0);
643
+ #endif /* !HAVE_POLL_H */
644
+ }
645
+ return (0);
646
+ }
647
+
648
+ /**
649
+ * xmlNanoHTTPReadLine:
650
+ * @ctxt: an HTTP context
651
+ *
652
+ * Read one line in the HTTP server output, usually for extracting
653
+ * the HTTP protocol information from the answer header.
654
+ *
655
+ * Returns a newly allocated string with a copy of the line, or NULL
656
+ * which indicate the end of the input.
657
+ */
658
+
659
+ static char *
660
+ xmlNanoHTTPReadLine(xmlNanoHTTPCtxtPtr ctxt) {
661
+ char buf[4096];
662
+ char *bp = buf;
663
+ int rc;
664
+
665
+ while (bp - buf < 4095) {
666
+ if (ctxt->inrptr == ctxt->inptr) {
667
+ if ( (rc = xmlNanoHTTPRecv(ctxt)) == 0) {
668
+ if (bp == buf)
669
+ return(NULL);
670
+ else
671
+ *bp = 0;
672
+ return(xmlMemStrdup(buf));
673
+ }
674
+ else if ( rc == -1 ) {
675
+ return ( NULL );
676
+ }
677
+ }
678
+ *bp = *ctxt->inrptr++;
679
+ if (*bp == '\n') {
680
+ *bp = 0;
681
+ return(xmlMemStrdup(buf));
682
+ }
683
+ if (*bp != '\r')
684
+ bp++;
685
+ }
686
+ buf[4095] = 0;
687
+ return(xmlMemStrdup(buf));
688
+ }
689
+
690
+
691
+ /**
692
+ * xmlNanoHTTPScanAnswer:
693
+ * @ctxt: an HTTP context
694
+ * @line: an HTTP header line
695
+ *
696
+ * Try to extract useful information from the server answer.
697
+ * We currently parse and process:
698
+ * - The HTTP revision/ return code
699
+ * - The Content-Type, Mime-Type and charset used
700
+ * - The Location for redirect processing.
701
+ *
702
+ * Returns -1 in case of failure, the file descriptor number otherwise
703
+ */
704
+
705
+ static void
706
+ xmlNanoHTTPScanAnswer(xmlNanoHTTPCtxtPtr ctxt, const char *line) {
707
+ const char *cur = line;
708
+
709
+ if (line == NULL) return;
710
+
711
+ if (!strncmp(line, "HTTP/", 5)) {
712
+ int version = 0;
713
+ int ret = 0;
714
+
715
+ cur += 5;
716
+ while ((*cur >= '0') && (*cur <= '9')) {
717
+ version *= 10;
718
+ version += *cur - '0';
719
+ cur++;
720
+ }
721
+ if (*cur == '.') {
722
+ cur++;
723
+ if ((*cur >= '0') && (*cur <= '9')) {
724
+ version *= 10;
725
+ version += *cur - '0';
726
+ cur++;
727
+ }
728
+ while ((*cur >= '0') && (*cur <= '9'))
729
+ cur++;
730
+ } else
731
+ version *= 10;
732
+ if ((*cur != ' ') && (*cur != '\t')) return;
733
+ while ((*cur == ' ') || (*cur == '\t')) cur++;
734
+ if ((*cur < '0') || (*cur > '9')) return;
735
+ while ((*cur >= '0') && (*cur <= '9')) {
736
+ ret *= 10;
737
+ ret += *cur - '0';
738
+ cur++;
739
+ }
740
+ if ((*cur != 0) && (*cur != ' ') && (*cur != '\t')) return;
741
+ ctxt->returnValue = ret;
742
+ ctxt->version = version;
743
+ } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Content-Type:", 13)) {
744
+ const xmlChar *charset, *last, *mime;
745
+ cur += 13;
746
+ while ((*cur == ' ') || (*cur == '\t')) cur++;
747
+ if (ctxt->contentType != NULL)
748
+ xmlFree(ctxt->contentType);
749
+ ctxt->contentType = xmlMemStrdup(cur);
750
+ mime = (const xmlChar *) cur;
751
+ last = mime;
752
+ while ((*last != 0) && (*last != ' ') && (*last != '\t') &&
753
+ (*last != ';') && (*last != ','))
754
+ last++;
755
+ if (ctxt->mimeType != NULL)
756
+ xmlFree(ctxt->mimeType);
757
+ ctxt->mimeType = (char *) xmlStrndup(mime, last - mime);
758
+ charset = xmlStrstr(BAD_CAST ctxt->contentType, BAD_CAST "charset=");
759
+ if (charset != NULL) {
760
+ charset += 8;
761
+ last = charset;
762
+ while ((*last != 0) && (*last != ' ') && (*last != '\t') &&
763
+ (*last != ';') && (*last != ','))
764
+ last++;
765
+ if (ctxt->encoding != NULL)
766
+ xmlFree(ctxt->encoding);
767
+ ctxt->encoding = (char *) xmlStrndup(charset, last - charset);
768
+ }
769
+ } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"ContentType:", 12)) {
770
+ const xmlChar *charset, *last, *mime;
771
+ cur += 12;
772
+ if (ctxt->contentType != NULL) return;
773
+ while ((*cur == ' ') || (*cur == '\t')) cur++;
774
+ ctxt->contentType = xmlMemStrdup(cur);
775
+ mime = (const xmlChar *) cur;
776
+ last = mime;
777
+ while ((*last != 0) && (*last != ' ') && (*last != '\t') &&
778
+ (*last != ';') && (*last != ','))
779
+ last++;
780
+ if (ctxt->mimeType != NULL)
781
+ xmlFree(ctxt->mimeType);
782
+ ctxt->mimeType = (char *) xmlStrndup(mime, last - mime);
783
+ charset = xmlStrstr(BAD_CAST ctxt->contentType, BAD_CAST "charset=");
784
+ if (charset != NULL) {
785
+ charset += 8;
786
+ last = charset;
787
+ while ((*last != 0) && (*last != ' ') && (*last != '\t') &&
788
+ (*last != ';') && (*last != ','))
789
+ last++;
790
+ if (ctxt->encoding != NULL)
791
+ xmlFree(ctxt->encoding);
792
+ ctxt->encoding = (char *) xmlStrndup(charset, last - charset);
793
+ }
794
+ } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Location:", 9)) {
795
+ cur += 9;
796
+ while ((*cur == ' ') || (*cur == '\t')) cur++;
797
+ if (ctxt->location != NULL)
798
+ xmlFree(ctxt->location);
799
+ if (*cur == '/') {
800
+ xmlChar *tmp_http = xmlStrdup(BAD_CAST "http://");
801
+ xmlChar *tmp_loc =
802
+ xmlStrcat(tmp_http, (const xmlChar *) ctxt->hostname);
803
+ ctxt->location =
804
+ (char *) xmlStrcat (tmp_loc, (const xmlChar *) cur);
805
+ } else {
806
+ ctxt->location = xmlMemStrdup(cur);
807
+ }
808
+ } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"WWW-Authenticate:", 17)) {
809
+ cur += 17;
810
+ while ((*cur == ' ') || (*cur == '\t')) cur++;
811
+ if (ctxt->authHeader != NULL)
812
+ xmlFree(ctxt->authHeader);
813
+ ctxt->authHeader = xmlMemStrdup(cur);
814
+ } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Proxy-Authenticate:", 19)) {
815
+ cur += 19;
816
+ while ((*cur == ' ') || (*cur == '\t')) cur++;
817
+ if (ctxt->authHeader != NULL)
818
+ xmlFree(ctxt->authHeader);
819
+ ctxt->authHeader = xmlMemStrdup(cur);
820
+ #ifdef LIBXML_ZLIB_ENABLED
821
+ } else if ( !xmlStrncasecmp( BAD_CAST line, BAD_CAST"Content-Encoding:", 17) ) {
822
+ cur += 17;
823
+ while ((*cur == ' ') || (*cur == '\t')) cur++;
824
+ if ( !xmlStrncasecmp( BAD_CAST cur, BAD_CAST"gzip", 4) ) {
825
+ ctxt->usesGzip = 1;
826
+
827
+ ctxt->strm = xmlMalloc(sizeof(z_stream));
828
+
829
+ if (ctxt->strm != NULL) {
830
+ ctxt->strm->zalloc = Z_NULL;
831
+ ctxt->strm->zfree = Z_NULL;
832
+ ctxt->strm->opaque = Z_NULL;
833
+ ctxt->strm->avail_in = 0;
834
+ ctxt->strm->next_in = Z_NULL;
835
+
836
+ inflateInit2( ctxt->strm, 31 );
837
+ }
838
+ }
839
+ #endif
840
+ } else if ( !xmlStrncasecmp( BAD_CAST line, BAD_CAST"Content-Length:", 15) ) {
841
+ cur += 15;
842
+ ctxt->ContentLength = strtol( cur, NULL, 10 );
843
+ }
844
+ }
845
+
846
+ /**
847
+ * xmlNanoHTTPConnectAttempt:
848
+ * @addr: a socket address structure
849
+ *
850
+ * Attempt a connection to the given IP:port endpoint. It forces
851
+ * non-blocking semantic on the socket, and allow 60 seconds for
852
+ * the host to answer.
853
+ *
854
+ * Returns -1 in case of failure, the file descriptor number otherwise
855
+ */
856
+
857
+ static SOCKET
858
+ xmlNanoHTTPConnectAttempt(struct sockaddr *addr)
859
+ {
860
+ #ifndef HAVE_POLL_H
861
+ fd_set wfd;
862
+ #ifdef _WINSOCKAPI_
863
+ fd_set xfd;
864
+ #endif
865
+ struct timeval tv;
866
+ #else /* !HAVE_POLL_H */
867
+ struct pollfd p;
868
+ #endif /* !HAVE_POLL_H */
869
+ int status;
870
+
871
+ int addrlen;
872
+
873
+ SOCKET s;
874
+
875
+ #ifdef SUPPORT_IP6
876
+ if (addr->sa_family == AF_INET6) {
877
+ s = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
878
+ addrlen = sizeof(struct sockaddr_in6);
879
+ } else
880
+ #endif
881
+ {
882
+ s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
883
+ addrlen = sizeof(struct sockaddr_in);
884
+ }
885
+ if (s == INVALID_SOCKET) {
886
+ #ifdef DEBUG_HTTP
887
+ perror("socket");
888
+ #endif
889
+ __xmlIOErr(XML_FROM_HTTP, 0, "socket failed\n");
890
+ return INVALID_SOCKET;
891
+ }
892
+ #ifdef _WINSOCKAPI_
893
+ {
894
+ u_long one = 1;
895
+
896
+ status = ioctlsocket(s, FIONBIO, &one) == SOCKET_ERROR ? -1 : 0;
897
+ }
898
+ #else /* _WINSOCKAPI_ */
899
+ #if defined(VMS)
900
+ {
901
+ int enable = 1;
902
+
903
+ status = ioctl(s, FIONBIO, &enable);
904
+ }
905
+ #else /* VMS */
906
+ #if defined(__BEOS__) && !defined(__HAIKU__)
907
+ {
908
+ bool noblock = true;
909
+
910
+ status =
911
+ setsockopt(s, SOL_SOCKET, SO_NONBLOCK, &noblock,
912
+ sizeof(noblock));
913
+ }
914
+ #else /* __BEOS__ */
915
+ if ((status = fcntl(s, F_GETFL, 0)) != -1) {
916
+ #ifdef O_NONBLOCK
917
+ status |= O_NONBLOCK;
918
+ #else /* O_NONBLOCK */
919
+ #ifdef F_NDELAY
920
+ status |= F_NDELAY;
921
+ #endif /* F_NDELAY */
922
+ #endif /* !O_NONBLOCK */
923
+ status = fcntl(s, F_SETFL, status);
924
+ }
925
+ if (status < 0) {
926
+ #ifdef DEBUG_HTTP
927
+ perror("nonblocking");
928
+ #endif
929
+ __xmlIOErr(XML_FROM_HTTP, 0, "error setting non-blocking IO\n");
930
+ closesocket(s);
931
+ return INVALID_SOCKET;
932
+ }
933
+ #endif /* !__BEOS__ */
934
+ #endif /* !VMS */
935
+ #endif /* !_WINSOCKAPI_ */
936
+
937
+ if (connect(s, addr, addrlen) == -1) {
938
+ switch (socket_errno()) {
939
+ case EINPROGRESS:
940
+ case EWOULDBLOCK:
941
+ break;
942
+ default:
943
+ __xmlIOErr(XML_FROM_HTTP, 0,
944
+ "error connecting to HTTP server");
945
+ closesocket(s);
946
+ return INVALID_SOCKET;
947
+ }
948
+ }
949
+ #ifndef HAVE_POLL_H
950
+ tv.tv_sec = timeout;
951
+ tv.tv_usec = 0;
952
+
953
+ #ifdef _MSC_VER
954
+ #pragma warning(push)
955
+ #pragma warning(disable: 4018)
956
+ #endif
957
+ #ifndef _WINSOCKAPI_
958
+ if (s > FD_SETSIZE)
959
+ return INVALID_SOCKET;
960
+ #endif
961
+ FD_ZERO(&wfd);
962
+ FD_SET(s, &wfd);
963
+
964
+ #ifdef _WINSOCKAPI_
965
+ FD_ZERO(&xfd);
966
+ FD_SET(s, &xfd);
967
+
968
+ switch (select(s + 1, NULL, &wfd, &xfd, &tv))
969
+ #else
970
+ switch (select(s + 1, NULL, &wfd, NULL, &tv))
971
+ #endif
972
+ #ifdef _MSC_VER
973
+ #pragma warning(pop)
974
+ #endif
975
+
976
+ #else /* !HAVE_POLL_H */
977
+ p.fd = s;
978
+ p.events = POLLOUT;
979
+ switch (poll(&p, 1, timeout * 1000))
980
+ #endif /* !HAVE_POLL_H */
981
+
982
+ {
983
+ case 0:
984
+ /* Time out */
985
+ __xmlIOErr(XML_FROM_HTTP, 0, "Connect attempt timed out");
986
+ closesocket(s);
987
+ return INVALID_SOCKET;
988
+ case -1:
989
+ /* Ermm.. ?? */
990
+ __xmlIOErr(XML_FROM_HTTP, 0, "Connect failed");
991
+ closesocket(s);
992
+ return INVALID_SOCKET;
993
+ }
994
+
995
+ #ifndef HAVE_POLL_H
996
+ if (FD_ISSET(s, &wfd)
997
+ #ifdef _WINSOCKAPI_
998
+ || FD_ISSET(s, &xfd)
999
+ #endif
1000
+ )
1001
+ #else /* !HAVE_POLL_H */
1002
+ if (p.revents == POLLOUT)
1003
+ #endif /* !HAVE_POLL_H */
1004
+ {
1005
+ XML_SOCKLEN_T len;
1006
+
1007
+ len = sizeof(status);
1008
+ #ifdef SO_ERROR
1009
+ if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char *) &status, &len) <
1010
+ 0) {
1011
+ /* Solaris error code */
1012
+ __xmlIOErr(XML_FROM_HTTP, 0, "getsockopt failed\n");
1013
+ closesocket(s);
1014
+ return INVALID_SOCKET;
1015
+ }
1016
+ #endif
1017
+ if (status) {
1018
+ __xmlIOErr(XML_FROM_HTTP, 0,
1019
+ "Error connecting to remote host");
1020
+ closesocket(s);
1021
+ errno = status;
1022
+ return INVALID_SOCKET;
1023
+ }
1024
+ } else {
1025
+ /* pbm */
1026
+ __xmlIOErr(XML_FROM_HTTP, 0, "select failed\n");
1027
+ closesocket(s);
1028
+ return INVALID_SOCKET;
1029
+ }
1030
+
1031
+ return (s);
1032
+ }
1033
+
1034
+ /**
1035
+ * xmlNanoHTTPConnectHost:
1036
+ * @host: the host name
1037
+ * @port: the port number
1038
+ *
1039
+ * Attempt a connection to the given host:port endpoint. It tries
1040
+ * the multiple IP provided by the DNS if available.
1041
+ *
1042
+ * Returns -1 in case of failure, the file descriptor number otherwise
1043
+ */
1044
+
1045
+ static SOCKET
1046
+ xmlNanoHTTPConnectHost(const char *host, int port)
1047
+ {
1048
+ struct sockaddr *addr = NULL;
1049
+ struct sockaddr_in sockin;
1050
+
1051
+ #ifdef SUPPORT_IP6
1052
+ struct in6_addr ia6;
1053
+ struct sockaddr_in6 sockin6;
1054
+ #endif
1055
+ SOCKET s;
1056
+
1057
+ memset (&sockin, 0, sizeof(sockin));
1058
+ #ifdef SUPPORT_IP6
1059
+ memset (&sockin6, 0, sizeof(sockin6));
1060
+ #endif
1061
+
1062
+ #if !defined(HAVE_GETADDRINFO) && defined(SUPPORT_IP6) && defined(RES_USE_INET6)
1063
+ if (have_ipv6 ())
1064
+ {
1065
+ if (!(_res.options & RES_INIT))
1066
+ res_init();
1067
+ _res.options |= RES_USE_INET6;
1068
+ }
1069
+ #endif
1070
+
1071
+ #if defined(HAVE_GETADDRINFO) && defined(SUPPORT_IP6) && !defined(_WIN32)
1072
+ if (have_ipv6 ())
1073
+ #endif
1074
+ #if defined(HAVE_GETADDRINFO) && (defined(SUPPORT_IP6) || defined(_WIN32))
1075
+ {
1076
+ int status;
1077
+ struct addrinfo hints, *res, *result;
1078
+
1079
+ result = NULL;
1080
+ memset (&hints, 0,sizeof(hints));
1081
+ hints.ai_socktype = SOCK_STREAM;
1082
+
1083
+ status = getaddrinfo (host, NULL, &hints, &result);
1084
+ if (status) {
1085
+ __xmlIOErr(XML_FROM_HTTP, 0, "getaddrinfo failed\n");
1086
+ return INVALID_SOCKET;
1087
+ }
1088
+
1089
+ for (res = result; res; res = res->ai_next) {
1090
+ if (res->ai_family == AF_INET) {
1091
+ if ((size_t)res->ai_addrlen > sizeof(sockin)) {
1092
+ __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");
1093
+ freeaddrinfo (result);
1094
+ return INVALID_SOCKET;
1095
+ }
1096
+ memcpy (&sockin, res->ai_addr, res->ai_addrlen);
1097
+ sockin.sin_port = htons (port);
1098
+ addr = (struct sockaddr *)&sockin;
1099
+ #ifdef SUPPORT_IP6
1100
+ } else if (have_ipv6 () && (res->ai_family == AF_INET6)) {
1101
+ if ((size_t)res->ai_addrlen > sizeof(sockin6)) {
1102
+ __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");
1103
+ freeaddrinfo (result);
1104
+ return INVALID_SOCKET;
1105
+ }
1106
+ memcpy (&sockin6, res->ai_addr, res->ai_addrlen);
1107
+ sockin6.sin6_port = htons (port);
1108
+ addr = (struct sockaddr *)&sockin6;
1109
+ #endif
1110
+ } else
1111
+ continue; /* for */
1112
+
1113
+ s = xmlNanoHTTPConnectAttempt (addr);
1114
+ if (s != INVALID_SOCKET) {
1115
+ freeaddrinfo (result);
1116
+ return (s);
1117
+ }
1118
+ }
1119
+
1120
+ if (result)
1121
+ freeaddrinfo (result);
1122
+ }
1123
+ #endif
1124
+ #if defined(HAVE_GETADDRINFO) && defined(SUPPORT_IP6) && !defined(_WIN32)
1125
+ else
1126
+ #endif
1127
+ #if !defined(HAVE_GETADDRINFO) || !defined(_WIN32)
1128
+ {
1129
+ struct hostent *h;
1130
+ struct in_addr ia;
1131
+ int i;
1132
+
1133
+ h = gethostbyname (GETHOSTBYNAME_ARG_CAST host);
1134
+ if (h == NULL) {
1135
+
1136
+ /*
1137
+ * Okay, I got fed up by the non-portability of this error message
1138
+ * extraction code. it work on Linux, if it work on your platform
1139
+ * and one want to enable it, send me the defined(foobar) needed
1140
+ */
1141
+ #if defined(HAVE_NETDB_H) && defined(HOST_NOT_FOUND) && defined(__linux__)
1142
+ const char *h_err_txt = "";
1143
+
1144
+ switch (h_errno) {
1145
+ case HOST_NOT_FOUND:
1146
+ h_err_txt = "Authoritative host not found";
1147
+ break;
1148
+
1149
+ case TRY_AGAIN:
1150
+ h_err_txt =
1151
+ "Non-authoritative host not found or server failure.";
1152
+ break;
1153
+
1154
+ case NO_RECOVERY:
1155
+ h_err_txt =
1156
+ "Non-recoverable errors: FORMERR, REFUSED, or NOTIMP.";
1157
+ break;
1158
+
1159
+ #ifdef NO_ADDRESS
1160
+ case NO_ADDRESS:
1161
+ h_err_txt =
1162
+ "Valid name, no data record of requested type.";
1163
+ break;
1164
+ #endif
1165
+
1166
+ default:
1167
+ h_err_txt = "No error text defined.";
1168
+ break;
1169
+ }
1170
+ __xmlIOErr(XML_FROM_HTTP, 0, h_err_txt);
1171
+ #else
1172
+ __xmlIOErr(XML_FROM_HTTP, 0, "Failed to resolve host");
1173
+ #endif
1174
+ return INVALID_SOCKET;
1175
+ }
1176
+
1177
+ for (i = 0; h->h_addr_list[i]; i++) {
1178
+ if (h->h_addrtype == AF_INET) {
1179
+ /* A records (IPv4) */
1180
+ if ((unsigned int) h->h_length > sizeof(ia)) {
1181
+ __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");
1182
+ return INVALID_SOCKET;
1183
+ }
1184
+ memcpy (&ia, h->h_addr_list[i], h->h_length);
1185
+ sockin.sin_family = h->h_addrtype;
1186
+ sockin.sin_addr = ia;
1187
+ sockin.sin_port = (unsigned short)htons ((unsigned short)port);
1188
+ addr = (struct sockaddr *) &sockin;
1189
+ #ifdef SUPPORT_IP6
1190
+ } else if (have_ipv6 () && (h->h_addrtype == AF_INET6)) {
1191
+ /* AAAA records (IPv6) */
1192
+ if ((unsigned int) h->h_length > sizeof(ia6)) {
1193
+ __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");
1194
+ return INVALID_SOCKET;
1195
+ }
1196
+ memcpy (&ia6, h->h_addr_list[i], h->h_length);
1197
+ sockin6.sin6_family = h->h_addrtype;
1198
+ sockin6.sin6_addr = ia6;
1199
+ sockin6.sin6_port = htons (port);
1200
+ addr = (struct sockaddr *) &sockin6;
1201
+ #endif
1202
+ } else
1203
+ break; /* for */
1204
+
1205
+ s = xmlNanoHTTPConnectAttempt (addr);
1206
+ if (s != INVALID_SOCKET)
1207
+ return (s);
1208
+ }
1209
+ }
1210
+ #endif
1211
+
1212
+ #ifdef DEBUG_HTTP
1213
+ xmlGenericError(xmlGenericErrorContext,
1214
+ "xmlNanoHTTPConnectHost: unable to connect to '%s'.\n",
1215
+ host);
1216
+ #endif
1217
+ return INVALID_SOCKET;
1218
+ }
1219
+
1220
+
1221
+ /**
1222
+ * xmlNanoHTTPOpen:
1223
+ * @URL: The URL to load
1224
+ * @contentType: if available the Content-Type information will be
1225
+ * returned at that location
1226
+ *
1227
+ * This function try to open a connection to the indicated resource
1228
+ * via HTTP GET.
1229
+ *
1230
+ * Returns NULL in case of failure, otherwise a request handler.
1231
+ * The contentType, if provided must be freed by the caller
1232
+ */
1233
+
1234
+ void*
1235
+ xmlNanoHTTPOpen(const char *URL, char **contentType) {
1236
+ if (contentType != NULL) *contentType = NULL;
1237
+ return(xmlNanoHTTPMethod(URL, NULL, NULL, contentType, NULL, 0));
1238
+ }
1239
+
1240
+ /**
1241
+ * xmlNanoHTTPOpenRedir:
1242
+ * @URL: The URL to load
1243
+ * @contentType: if available the Content-Type information will be
1244
+ * returned at that location
1245
+ * @redir: if available the redirected URL will be returned
1246
+ *
1247
+ * This function try to open a connection to the indicated resource
1248
+ * via HTTP GET.
1249
+ *
1250
+ * Returns NULL in case of failure, otherwise a request handler.
1251
+ * The contentType, if provided must be freed by the caller
1252
+ */
1253
+
1254
+ void*
1255
+ xmlNanoHTTPOpenRedir(const char *URL, char **contentType, char **redir) {
1256
+ if (contentType != NULL) *contentType = NULL;
1257
+ if (redir != NULL) *redir = NULL;
1258
+ return(xmlNanoHTTPMethodRedir(URL, NULL, NULL, contentType, redir, NULL,0));
1259
+ }
1260
+
1261
+ /**
1262
+ * xmlNanoHTTPRead:
1263
+ * @ctx: the HTTP context
1264
+ * @dest: a buffer
1265
+ * @len: the buffer length
1266
+ *
1267
+ * This function tries to read @len bytes from the existing HTTP connection
1268
+ * and saves them in @dest. This is a blocking call.
1269
+ *
1270
+ * Returns the number of byte read. 0 is an indication of an end of connection.
1271
+ * -1 indicates a parameter error.
1272
+ */
1273
+ int
1274
+ xmlNanoHTTPRead(void *ctx, void *dest, int len) {
1275
+ xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx;
1276
+ #ifdef LIBXML_ZLIB_ENABLED
1277
+ int bytes_read = 0;
1278
+ int orig_avail_in;
1279
+ int z_ret;
1280
+ #endif
1281
+
1282
+ if (ctx == NULL) return(-1);
1283
+ if (dest == NULL) return(-1);
1284
+ if (len <= 0) return(0);
1285
+
1286
+ #ifdef LIBXML_ZLIB_ENABLED
1287
+ if (ctxt->usesGzip == 1) {
1288
+ if (ctxt->strm == NULL) return(0);
1289
+
1290
+ ctxt->strm->next_out = dest;
1291
+ ctxt->strm->avail_out = len;
1292
+ ctxt->strm->avail_in = ctxt->inptr - ctxt->inrptr;
1293
+
1294
+ while (ctxt->strm->avail_out > 0 &&
1295
+ (ctxt->strm->avail_in > 0 || xmlNanoHTTPRecv(ctxt) > 0)) {
1296
+ orig_avail_in = ctxt->strm->avail_in =
1297
+ ctxt->inptr - ctxt->inrptr - bytes_read;
1298
+ ctxt->strm->next_in = BAD_CAST (ctxt->inrptr + bytes_read);
1299
+
1300
+ z_ret = inflate(ctxt->strm, Z_NO_FLUSH);
1301
+ bytes_read += orig_avail_in - ctxt->strm->avail_in;
1302
+
1303
+ if (z_ret != Z_OK) break;
1304
+ }
1305
+
1306
+ ctxt->inrptr += bytes_read;
1307
+ return(len - ctxt->strm->avail_out);
1308
+ }
1309
+ #endif
1310
+
1311
+ while (ctxt->inptr - ctxt->inrptr < len) {
1312
+ if (xmlNanoHTTPRecv(ctxt) <= 0) break;
1313
+ }
1314
+ if (ctxt->inptr - ctxt->inrptr < len)
1315
+ len = ctxt->inptr - ctxt->inrptr;
1316
+ memcpy(dest, ctxt->inrptr, len);
1317
+ ctxt->inrptr += len;
1318
+ return(len);
1319
+ }
1320
+
1321
+ /**
1322
+ * xmlNanoHTTPClose:
1323
+ * @ctx: the HTTP context
1324
+ *
1325
+ * This function closes an HTTP context, it ends up the connection and
1326
+ * free all data related to it.
1327
+ */
1328
+ void
1329
+ xmlNanoHTTPClose(void *ctx) {
1330
+ xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx;
1331
+
1332
+ if (ctx == NULL) return;
1333
+
1334
+ xmlNanoHTTPFreeCtxt(ctxt);
1335
+ }
1336
+
1337
+ /**
1338
+ * xmlNanoHTTPMethodRedir:
1339
+ * @URL: The URL to load
1340
+ * @method: the HTTP method to use
1341
+ * @input: the input string if any
1342
+ * @contentType: the Content-Type information IN and OUT
1343
+ * @redir: the redirected URL OUT
1344
+ * @headers: the extra headers
1345
+ * @ilen: input length
1346
+ *
1347
+ * This function try to open a connection to the indicated resource
1348
+ * via HTTP using the given @method, adding the given extra headers
1349
+ * and the input buffer for the request content.
1350
+ *
1351
+ * Returns NULL in case of failure, otherwise a request handler.
1352
+ * The contentType, or redir, if provided must be freed by the caller
1353
+ */
1354
+
1355
+ void*
1356
+ xmlNanoHTTPMethodRedir(const char *URL, const char *method, const char *input,
1357
+ char **contentType, char **redir,
1358
+ const char *headers, int ilen ) {
1359
+ xmlNanoHTTPCtxtPtr ctxt;
1360
+ char *bp, *p;
1361
+ int blen;
1362
+ SOCKET ret;
1363
+ int nbRedirects = 0;
1364
+ char *redirURL = NULL;
1365
+ #ifdef DEBUG_HTTP
1366
+ int xmt_bytes;
1367
+ #endif
1368
+
1369
+ if (URL == NULL) return(NULL);
1370
+ if (method == NULL) method = "GET";
1371
+ xmlNanoHTTPInit();
1372
+
1373
+ retry:
1374
+ if (redirURL == NULL) {
1375
+ ctxt = xmlNanoHTTPNewCtxt(URL);
1376
+ if (ctxt == NULL)
1377
+ return(NULL);
1378
+ } else {
1379
+ ctxt = xmlNanoHTTPNewCtxt(redirURL);
1380
+ if (ctxt == NULL)
1381
+ return(NULL);
1382
+ ctxt->location = xmlMemStrdup(redirURL);
1383
+ }
1384
+
1385
+ if ((ctxt->protocol == NULL) || (strcmp(ctxt->protocol, "http"))) {
1386
+ __xmlIOErr(XML_FROM_HTTP, XML_HTTP_URL_SYNTAX, "Not a valid HTTP URI");
1387
+ xmlNanoHTTPFreeCtxt(ctxt);
1388
+ if (redirURL != NULL) xmlFree(redirURL);
1389
+ return(NULL);
1390
+ }
1391
+ if (ctxt->hostname == NULL) {
1392
+ __xmlIOErr(XML_FROM_HTTP, XML_HTTP_UNKNOWN_HOST,
1393
+ "Failed to identify host in URI");
1394
+ xmlNanoHTTPFreeCtxt(ctxt);
1395
+ if (redirURL != NULL) xmlFree(redirURL);
1396
+ return(NULL);
1397
+ }
1398
+ if (proxy) {
1399
+ blen = strlen(ctxt->hostname) * 2 + 16;
1400
+ ret = xmlNanoHTTPConnectHost(proxy, proxyPort);
1401
+ }
1402
+ else {
1403
+ blen = strlen(ctxt->hostname);
1404
+ ret = xmlNanoHTTPConnectHost(ctxt->hostname, ctxt->port);
1405
+ }
1406
+ if (ret == INVALID_SOCKET) {
1407
+ xmlNanoHTTPFreeCtxt(ctxt);
1408
+ if (redirURL != NULL) xmlFree(redirURL);
1409
+ return(NULL);
1410
+ }
1411
+ ctxt->fd = ret;
1412
+
1413
+ if (input == NULL)
1414
+ ilen = 0;
1415
+ else
1416
+ blen += 36;
1417
+
1418
+ if (headers != NULL)
1419
+ blen += strlen(headers) + 2;
1420
+ if (contentType && *contentType)
1421
+ /* reserve for string plus 'Content-Type: \r\n" */
1422
+ blen += strlen(*contentType) + 16;
1423
+ if (ctxt->query != NULL)
1424
+ /* 1 for '?' */
1425
+ blen += strlen(ctxt->query) + 1;
1426
+ blen += strlen(method) + strlen(ctxt->path) + 24;
1427
+ #ifdef LIBXML_ZLIB_ENABLED
1428
+ /* reserve for possible 'Accept-Encoding: gzip' string */
1429
+ blen += 23;
1430
+ #endif
1431
+ if (ctxt->port != 80) {
1432
+ /* reserve space for ':xxxxx', incl. potential proxy */
1433
+ if (proxy)
1434
+ blen += 17;
1435
+ else
1436
+ blen += 11;
1437
+ }
1438
+ bp = (char*)xmlMallocAtomic(blen);
1439
+ if ( bp == NULL ) {
1440
+ xmlNanoHTTPFreeCtxt( ctxt );
1441
+ xmlHTTPErrMemory("allocating header buffer");
1442
+ return ( NULL );
1443
+ }
1444
+
1445
+ p = bp;
1446
+
1447
+ if (proxy) {
1448
+ if (ctxt->port != 80) {
1449
+ p += snprintf( p, blen - (p - bp), "%s http://%s:%d%s",
1450
+ method, ctxt->hostname,
1451
+ ctxt->port, ctxt->path );
1452
+ }
1453
+ else
1454
+ p += snprintf( p, blen - (p - bp), "%s http://%s%s", method,
1455
+ ctxt->hostname, ctxt->path);
1456
+ }
1457
+ else
1458
+ p += snprintf( p, blen - (p - bp), "%s %s", method, ctxt->path);
1459
+
1460
+ if (ctxt->query != NULL)
1461
+ p += snprintf( p, blen - (p - bp), "?%s", ctxt->query);
1462
+
1463
+ if (ctxt->port == 80) {
1464
+ p += snprintf( p, blen - (p - bp), " HTTP/1.0\r\nHost: %s\r\n",
1465
+ ctxt->hostname);
1466
+ } else {
1467
+ p += snprintf( p, blen - (p - bp), " HTTP/1.0\r\nHost: %s:%d\r\n",
1468
+ ctxt->hostname, ctxt->port);
1469
+ }
1470
+
1471
+ #ifdef LIBXML_ZLIB_ENABLED
1472
+ p += snprintf(p, blen - (p - bp), "Accept-Encoding: gzip\r\n");
1473
+ #endif
1474
+
1475
+ if (contentType != NULL && *contentType)
1476
+ p += snprintf(p, blen - (p - bp), "Content-Type: %s\r\n", *contentType);
1477
+
1478
+ if (headers != NULL)
1479
+ p += snprintf( p, blen - (p - bp), "%s", headers );
1480
+
1481
+ if (input != NULL)
1482
+ snprintf(p, blen - (p - bp), "Content-Length: %d\r\n\r\n", ilen );
1483
+ else
1484
+ snprintf(p, blen - (p - bp), "\r\n");
1485
+
1486
+ #ifdef DEBUG_HTTP
1487
+ xmlGenericError(xmlGenericErrorContext,
1488
+ "-> %s%s", proxy? "(Proxy) " : "", bp);
1489
+ if ((blen -= strlen(bp)+1) < 0)
1490
+ xmlGenericError(xmlGenericErrorContext,
1491
+ "ERROR: overflowed buffer by %d bytes\n", -blen);
1492
+ #endif
1493
+ ctxt->outptr = ctxt->out = bp;
1494
+ ctxt->state = XML_NANO_HTTP_WRITE;
1495
+ blen = strlen( ctxt->out );
1496
+ #ifdef DEBUG_HTTP
1497
+ xmt_bytes = xmlNanoHTTPSend(ctxt, ctxt->out, blen );
1498
+ if ( xmt_bytes != blen )
1499
+ xmlGenericError( xmlGenericErrorContext,
1500
+ "xmlNanoHTTPMethodRedir: Only %d of %d %s %s\n",
1501
+ xmt_bytes, blen,
1502
+ "bytes of HTTP headers sent to host",
1503
+ ctxt->hostname );
1504
+ #else
1505
+ xmlNanoHTTPSend(ctxt, ctxt->out, blen );
1506
+ #endif
1507
+
1508
+ if ( input != NULL ) {
1509
+ #ifdef DEBUG_HTTP
1510
+ xmt_bytes = xmlNanoHTTPSend( ctxt, input, ilen );
1511
+
1512
+ if ( xmt_bytes != ilen )
1513
+ xmlGenericError( xmlGenericErrorContext,
1514
+ "xmlNanoHTTPMethodRedir: Only %d of %d %s %s\n",
1515
+ xmt_bytes, ilen,
1516
+ "bytes of HTTP content sent to host",
1517
+ ctxt->hostname );
1518
+ #else
1519
+ xmlNanoHTTPSend( ctxt, input, ilen );
1520
+ #endif
1521
+ }
1522
+
1523
+ ctxt->state = XML_NANO_HTTP_READ;
1524
+
1525
+ while ((p = xmlNanoHTTPReadLine(ctxt)) != NULL) {
1526
+ if (*p == 0) {
1527
+ ctxt->content = ctxt->inrptr;
1528
+ xmlFree(p);
1529
+ break;
1530
+ }
1531
+ xmlNanoHTTPScanAnswer(ctxt, p);
1532
+
1533
+ #ifdef DEBUG_HTTP
1534
+ xmlGenericError(xmlGenericErrorContext, "<- %s\n", p);
1535
+ #endif
1536
+ xmlFree(p);
1537
+ }
1538
+
1539
+ if ((ctxt->location != NULL) && (ctxt->returnValue >= 300) &&
1540
+ (ctxt->returnValue < 400)) {
1541
+ #ifdef DEBUG_HTTP
1542
+ xmlGenericError(xmlGenericErrorContext,
1543
+ "\nRedirect to: %s\n", ctxt->location);
1544
+ #endif
1545
+ while ( xmlNanoHTTPRecv(ctxt) > 0 )
1546
+ ;
1547
+ if (nbRedirects < XML_NANO_HTTP_MAX_REDIR) {
1548
+ nbRedirects++;
1549
+ if (redirURL != NULL)
1550
+ xmlFree(redirURL);
1551
+ redirURL = xmlMemStrdup(ctxt->location);
1552
+ xmlNanoHTTPFreeCtxt(ctxt);
1553
+ goto retry;
1554
+ }
1555
+ xmlNanoHTTPFreeCtxt(ctxt);
1556
+ if (redirURL != NULL) xmlFree(redirURL);
1557
+ #ifdef DEBUG_HTTP
1558
+ xmlGenericError(xmlGenericErrorContext,
1559
+ "xmlNanoHTTPMethodRedir: Too many redirects, aborting ...\n");
1560
+ #endif
1561
+ return(NULL);
1562
+ }
1563
+
1564
+ if (contentType != NULL) {
1565
+ if (ctxt->contentType != NULL)
1566
+ *contentType = xmlMemStrdup(ctxt->contentType);
1567
+ else
1568
+ *contentType = NULL;
1569
+ }
1570
+
1571
+ if ((redir != NULL) && (redirURL != NULL)) {
1572
+ *redir = redirURL;
1573
+ } else {
1574
+ if (redirURL != NULL)
1575
+ xmlFree(redirURL);
1576
+ if (redir != NULL)
1577
+ *redir = NULL;
1578
+ }
1579
+
1580
+ #ifdef DEBUG_HTTP
1581
+ if (ctxt->contentType != NULL)
1582
+ xmlGenericError(xmlGenericErrorContext,
1583
+ "\nCode %d, content-type '%s'\n\n",
1584
+ ctxt->returnValue, ctxt->contentType);
1585
+ else
1586
+ xmlGenericError(xmlGenericErrorContext,
1587
+ "\nCode %d, no content-type\n\n",
1588
+ ctxt->returnValue);
1589
+ #endif
1590
+
1591
+ return((void *) ctxt);
1592
+ }
1593
+
1594
+ /**
1595
+ * xmlNanoHTTPMethod:
1596
+ * @URL: The URL to load
1597
+ * @method: the HTTP method to use
1598
+ * @input: the input string if any
1599
+ * @contentType: the Content-Type information IN and OUT
1600
+ * @headers: the extra headers
1601
+ * @ilen: input length
1602
+ *
1603
+ * This function try to open a connection to the indicated resource
1604
+ * via HTTP using the given @method, adding the given extra headers
1605
+ * and the input buffer for the request content.
1606
+ *
1607
+ * Returns NULL in case of failure, otherwise a request handler.
1608
+ * The contentType, if provided must be freed by the caller
1609
+ */
1610
+
1611
+ void*
1612
+ xmlNanoHTTPMethod(const char *URL, const char *method, const char *input,
1613
+ char **contentType, const char *headers, int ilen) {
1614
+ return(xmlNanoHTTPMethodRedir(URL, method, input, contentType,
1615
+ NULL, headers, ilen));
1616
+ }
1617
+
1618
+ /**
1619
+ * xmlNanoHTTPFetch:
1620
+ * @URL: The URL to load
1621
+ * @filename: the filename where the content should be saved
1622
+ * @contentType: if available the Content-Type information will be
1623
+ * returned at that location
1624
+ *
1625
+ * This function try to fetch the indicated resource via HTTP GET
1626
+ * and save it's content in the file.
1627
+ *
1628
+ * Returns -1 in case of failure, 0 in case of success. The contentType,
1629
+ * if provided must be freed by the caller
1630
+ */
1631
+ int
1632
+ xmlNanoHTTPFetch(const char *URL, const char *filename, char **contentType) {
1633
+ void *ctxt = NULL;
1634
+ char *buf = NULL;
1635
+ int fd;
1636
+ int len;
1637
+ int ret = 0;
1638
+
1639
+ if (filename == NULL) return(-1);
1640
+ ctxt = xmlNanoHTTPOpen(URL, contentType);
1641
+ if (ctxt == NULL) return(-1);
1642
+
1643
+ if (!strcmp(filename, "-"))
1644
+ fd = 0;
1645
+ else {
1646
+ fd = open(filename, O_CREAT | O_WRONLY, 00644);
1647
+ if (fd < 0) {
1648
+ xmlNanoHTTPClose(ctxt);
1649
+ if ((contentType != NULL) && (*contentType != NULL)) {
1650
+ xmlFree(*contentType);
1651
+ *contentType = NULL;
1652
+ }
1653
+ return(-1);
1654
+ }
1655
+ }
1656
+
1657
+ xmlNanoHTTPFetchContent( ctxt, &buf, &len );
1658
+ if ( len > 0 ) {
1659
+ if (write(fd, buf, len) == -1) {
1660
+ ret = -1;
1661
+ }
1662
+ }
1663
+
1664
+ xmlNanoHTTPClose(ctxt);
1665
+ close(fd);
1666
+ return(ret);
1667
+ }
1668
+
1669
+ #ifdef LIBXML_OUTPUT_ENABLED
1670
+ /**
1671
+ * xmlNanoHTTPSave:
1672
+ * @ctxt: the HTTP context
1673
+ * @filename: the filename where the content should be saved
1674
+ *
1675
+ * This function saves the output of the HTTP transaction to a file
1676
+ * It closes and free the context at the end
1677
+ *
1678
+ * Returns -1 in case of failure, 0 in case of success.
1679
+ */
1680
+ int
1681
+ xmlNanoHTTPSave(void *ctxt, const char *filename) {
1682
+ char *buf = NULL;
1683
+ int fd;
1684
+ int len;
1685
+ int ret = 0;
1686
+
1687
+ if ((ctxt == NULL) || (filename == NULL)) return(-1);
1688
+
1689
+ if (!strcmp(filename, "-"))
1690
+ fd = 0;
1691
+ else {
1692
+ fd = open(filename, O_CREAT | O_WRONLY, 0666);
1693
+ if (fd < 0) {
1694
+ xmlNanoHTTPClose(ctxt);
1695
+ return(-1);
1696
+ }
1697
+ }
1698
+
1699
+ xmlNanoHTTPFetchContent( ctxt, &buf, &len );
1700
+ if ( len > 0 ) {
1701
+ if (write(fd, buf, len) == -1) {
1702
+ ret = -1;
1703
+ }
1704
+ }
1705
+
1706
+ xmlNanoHTTPClose(ctxt);
1707
+ close(fd);
1708
+ return(ret);
1709
+ }
1710
+ #endif /* LIBXML_OUTPUT_ENABLED */
1711
+
1712
+ /**
1713
+ * xmlNanoHTTPReturnCode:
1714
+ * @ctx: the HTTP context
1715
+ *
1716
+ * Get the latest HTTP return code received
1717
+ *
1718
+ * Returns the HTTP return code for the request.
1719
+ */
1720
+ int
1721
+ xmlNanoHTTPReturnCode(void *ctx) {
1722
+ xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx;
1723
+
1724
+ if (ctxt == NULL) return(-1);
1725
+
1726
+ return(ctxt->returnValue);
1727
+ }
1728
+
1729
+ /**
1730
+ * xmlNanoHTTPAuthHeader:
1731
+ * @ctx: the HTTP context
1732
+ *
1733
+ * Get the authentication header of an HTTP context
1734
+ *
1735
+ * Returns the stashed value of the WWW-Authenticate or Proxy-Authenticate
1736
+ * header.
1737
+ */
1738
+ const char *
1739
+ xmlNanoHTTPAuthHeader(void *ctx) {
1740
+ xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx;
1741
+
1742
+ if (ctxt == NULL) return(NULL);
1743
+
1744
+ return(ctxt->authHeader);
1745
+ }
1746
+
1747
+ /**
1748
+ * xmlNanoHTTPContentLength:
1749
+ * @ctx: the HTTP context
1750
+ *
1751
+ * Provides the specified content length from the HTTP header.
1752
+ *
1753
+ * Return the specified content length from the HTTP header. Note that
1754
+ * a value of -1 indicates that the content length element was not included in
1755
+ * the response header.
1756
+ */
1757
+ int
1758
+ xmlNanoHTTPContentLength( void * ctx ) {
1759
+ xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr)ctx;
1760
+
1761
+ return ( ( ctxt == NULL ) ? -1 : ctxt->ContentLength );
1762
+ }
1763
+
1764
+ /**
1765
+ * xmlNanoHTTPRedir:
1766
+ * @ctx: the HTTP context
1767
+ *
1768
+ * Provides the specified redirection URL if available from the HTTP header.
1769
+ *
1770
+ * Return the specified redirection URL or NULL if not redirected.
1771
+ */
1772
+ const char *
1773
+ xmlNanoHTTPRedir( void * ctx ) {
1774
+ xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr)ctx;
1775
+
1776
+ return ( ( ctxt == NULL ) ? NULL : ctxt->location );
1777
+ }
1778
+
1779
+ /**
1780
+ * xmlNanoHTTPEncoding:
1781
+ * @ctx: the HTTP context
1782
+ *
1783
+ * Provides the specified encoding if specified in the HTTP headers.
1784
+ *
1785
+ * Return the specified encoding or NULL if not available
1786
+ */
1787
+ const char *
1788
+ xmlNanoHTTPEncoding( void * ctx ) {
1789
+ xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr)ctx;
1790
+
1791
+ return ( ( ctxt == NULL ) ? NULL : ctxt->encoding );
1792
+ }
1793
+
1794
+ /**
1795
+ * xmlNanoHTTPMimeType:
1796
+ * @ctx: the HTTP context
1797
+ *
1798
+ * Provides the specified Mime-Type if specified in the HTTP headers.
1799
+ *
1800
+ * Return the specified Mime-Type or NULL if not available
1801
+ */
1802
+ const char *
1803
+ xmlNanoHTTPMimeType( void * ctx ) {
1804
+ xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr)ctx;
1805
+
1806
+ return ( ( ctxt == NULL ) ? NULL : ctxt->mimeType );
1807
+ }
1808
+
1809
+ /**
1810
+ * xmlNanoHTTPFetchContent:
1811
+ * @ctx: the HTTP context
1812
+ * @ptr: pointer to set to the content buffer.
1813
+ * @len: integer pointer to hold the length of the content
1814
+ *
1815
+ * Check if all the content was read
1816
+ *
1817
+ * Returns 0 if all the content was read and available, returns
1818
+ * -1 if received content length was less than specified or an error
1819
+ * occurred.
1820
+ */
1821
+ static int
1822
+ xmlNanoHTTPFetchContent( void * ctx, char ** ptr, int * len ) {
1823
+ xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr)ctx;
1824
+
1825
+ int rc = 0;
1826
+ int cur_lgth;
1827
+ int rcvd_lgth;
1828
+ int dummy_int;
1829
+ char * dummy_ptr = NULL;
1830
+
1831
+ /* Dummy up return input parameters if not provided */
1832
+
1833
+ if ( len == NULL )
1834
+ len = &dummy_int;
1835
+
1836
+ if ( ptr == NULL )
1837
+ ptr = &dummy_ptr;
1838
+
1839
+ /* But can't work without the context pointer */
1840
+
1841
+ if ( ( ctxt == NULL ) || ( ctxt->content == NULL ) ) {
1842
+ *len = 0;
1843
+ *ptr = NULL;
1844
+ return ( -1 );
1845
+ }
1846
+
1847
+ rcvd_lgth = ctxt->inptr - ctxt->content;
1848
+
1849
+ while ( (cur_lgth = xmlNanoHTTPRecv( ctxt )) > 0 ) {
1850
+
1851
+ rcvd_lgth += cur_lgth;
1852
+ if ( (ctxt->ContentLength > 0) && (rcvd_lgth >= ctxt->ContentLength) )
1853
+ break;
1854
+ }
1855
+
1856
+ *ptr = ctxt->content;
1857
+ *len = rcvd_lgth;
1858
+
1859
+ if ( ( ctxt->ContentLength > 0 ) && ( rcvd_lgth < ctxt->ContentLength ) )
1860
+ rc = -1;
1861
+ else if ( rcvd_lgth == 0 )
1862
+ rc = -1;
1863
+
1864
+ return ( rc );
1865
+ }
1866
+
1867
+ #ifdef STANDALONE
1868
+ int main(int argc, char **argv) {
1869
+ char *contentType = NULL;
1870
+
1871
+ if (argv[1] != NULL) {
1872
+ if (argv[2] != NULL)
1873
+ xmlNanoHTTPFetch(argv[1], argv[2], &contentType);
1874
+ else
1875
+ xmlNanoHTTPFetch(argv[1], "-", &contentType);
1876
+ if (contentType != NULL) xmlFree(contentType);
1877
+ } else {
1878
+ xmlGenericError(xmlGenericErrorContext,
1879
+ "%s: minimal HTTP GET implementation\n", argv[0]);
1880
+ xmlGenericError(xmlGenericErrorContext,
1881
+ "\tusage %s [ URL [ filename ] ]\n", argv[0]);
1882
+ }
1883
+ xmlNanoHTTPCleanup();
1884
+ xmlMemoryDump();
1885
+ return(0);
1886
+ }
1887
+ #endif /* STANDALONE */
1888
+ #else /* !LIBXML_HTTP_ENABLED */
1889
+ #ifdef STANDALONE
1890
+ #include <stdio.h>
1891
+ int main(int argc, char **argv) {
1892
+ xmlGenericError(xmlGenericErrorContext,
1893
+ "%s : HTTP support not compiled in\n", argv[0]);
1894
+ return(0);
1895
+ }
1896
+ #endif /* STANDALONE */
1897
+ #endif /* LIBXML_HTTP_ENABLED */
1898
+ #define bottom_nanohttp
1899
+ #include "elfgcchack.h"