├── .gitignore ├── LICENSE ├── README.md ├── api ├── enum ├── funcs └── opts ├── project.janet ├── src ├── curl.c └── khash.h └── test └── main.janet /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | src/build 3 | build 4 | test/DOWNLOAD 5 | tests/DOWNLOAD 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jurl 2 | 3 | [janet](https://janet-lang.org/) wrapper around libcurl 4 | 5 | ## WIP 6 | is it not yet ready for production ;) 7 | -------------------------------------------------------------------------------- /api/enum: -------------------------------------------------------------------------------- 1 | :=: 2 | CURLSSLBACKEND_NONE 3 | CURLSSLBACKEND_OPENSSL 4 | CURLSSLBACKEND_GNUTLS 5 | CURLSSLBACKEND_NSS 6 | CURLSSLBACKEND_OBSOLETE4 7 | CURLSSLBACKEND_GSKIT 8 | CURLSSLBACKEND_POLARSSL 9 | CURLSSLBACKEND_WOLFSSL 10 | CURLSSLBACKEND_SCHANNEL 11 | CURLSSLBACKEND_DARWINSSL 12 | CURLSSLBACKEND_AXTLS 13 | CURLSSLBACKEND_MBEDTLS 14 | CURLSSLBACKEND_MESALINK 15 | :=: 16 | CURLFILETYPE_FILE 17 | CURLFILETYPE_DIRECTORY 18 | CURLFILETYPE_SYMLINK 19 | CURLFILETYPE_DEVICE_BLOCK 20 | CURLFILETYPE_DEVICE_CHAR 21 | CURLFILETYPE_NAMEDPIPE 22 | CURLFILETYPE_SOCKET 23 | CURLFILETYPE_DOOR 24 | CURLFILETYPE_UNKNOWN 25 | :=: 26 | CURLSOCKTYPE_IPCXN 27 | CURLSOCKTYPE_ACCEPT 28 | CURLSOCKTYPE_LAST 29 | :=: 30 | CURLIOE_OK 31 | CURLIOE_UNKNOWNCMD 32 | CURLIOE_FAILRESTART 33 | CURLIOE_LAST 34 | :=: 35 | CURLIOCMD_NOP 36 | CURLIOCMD_RESTARTREAD 37 | CURLIOCMD_LAST 38 | :=: 39 | CURLINFO_TEXT 40 | CURLINFO_HEADER_IN 41 | CURLINFO_HEADER_OUT 42 | CURLINFO_DATA_IN 43 | CURLINFO_DATA_OUT 44 | CURLINFO_SSL_DATA_IN 45 | CURLINFO_SSL_DATA_OUT 46 | CURLINFO_END 47 | :=: 48 | CURLE_OK 49 | CURLE_UNSUPPORTED_PROTOCOL 50 | CURLE_FAILED_INIT 51 | CURLE_URL_MALFORMAT 52 | CURLE_NOT_BUILT_IN 53 | CURLE_COULDNT_RESOLVE_PROXY 54 | CURLE_COULDNT_RESOLVE_HOST 55 | CURLE_COULDNT_CONNECT 56 | CURLE_WEIRD_SERVER_REPLY 57 | CURLE_REMOTE_ACCESS_DENIED 58 | CURLE_FTP_ACCEPT_FAILED 59 | CURLE_FTP_WEIRD_PASS_REPLY 60 | CURLE_FTP_ACCEPT_TIMEOUT 61 | CURLE_FTP_WEIRD_PASV_REPLY 62 | CURLE_FTP_WEIRD_227_FORMAT 63 | CURLE_FTP_CANT_GET_HOST 64 | CURLE_HTTP2 65 | CURLE_FTP_COULDNT_SET_TYPE 66 | CURLE_PARTIAL_FILE 67 | CURLE_FTP_COULDNT_RETR_FILE 68 | CURLE_OBSOLETE20 69 | CURLE_QUOTE_ERROR 70 | CURLE_HTTP_RETURNED_ERROR 71 | CURLE_WRITE_ERROR 72 | CURLE_OBSOLETE24 73 | CURLE_UPLOAD_FAILED 74 | CURLE_READ_ERROR 75 | CURLE_OUT_OF_MEMORY 76 | CURLE_OPERATION_TIMEDOUT 77 | CURLE_OBSOLETE29 78 | CURLE_FTP_PORT_FAILED 79 | CURLE_FTP_COULDNT_USE_REST 80 | CURLE_OBSOLETE32 81 | CURLE_RANGE_ERROR 82 | CURLE_HTTP_POST_ERROR 83 | CURLE_SSL_CONNECT_ERROR 84 | CURLE_BAD_DOWNLOAD_RESUME 85 | CURLE_FILE_COULDNT_READ_FILE 86 | CURLE_LDAP_CANNOT_BIND 87 | CURLE_LDAP_SEARCH_FAILED 88 | CURLE_OBSOLETE40 89 | CURLE_FUNCTION_NOT_FOUND 90 | CURLE_ABORTED_BY_CALLBACK 91 | CURLE_BAD_FUNCTION_ARGUMENT 92 | CURLE_OBSOLETE44 93 | CURLE_INTERFACE_FAILED 94 | CURLE_OBSOLETE46 95 | CURLE_TOO_MANY_REDIRECTS 96 | CURLE_UNKNOWN_OPTION 97 | CURLE_TELNET_OPTION_SYNTAX 98 | CURLE_OBSOLETE50 99 | CURLE_OBSOLETE51 100 | CURLE_GOT_NOTHING 101 | CURLE_SSL_ENGINE_NOTFOUND 102 | CURLE_SSL_ENGINE_SETFAILED 103 | CURLE_SEND_ERROR 104 | CURLE_RECV_ERROR 105 | CURLE_OBSOLETE57 106 | CURLE_SSL_CERTPROBLEM 107 | CURLE_SSL_CIPHER 108 | CURLE_PEER_FAILED_VERIFICATION 109 | CURLE_BAD_CONTENT_ENCODING 110 | CURLE_LDAP_INVALID_URL 111 | CURLE_FILESIZE_EXCEEDED 112 | CURLE_USE_SSL_FAILED 113 | CURLE_SEND_FAIL_REWIND 114 | CURLE_SSL_ENGINE_INITFAILED 115 | CURLE_LOGIN_DENIED 116 | CURLE_TFTP_NOTFOUND 117 | CURLE_TFTP_PERM 118 | CURLE_REMOTE_DISK_FULL 119 | CURLE_TFTP_ILLEGAL 120 | CURLE_TFTP_UNKNOWNID 121 | CURLE_REMOTE_FILE_EXISTS 122 | CURLE_TFTP_NOSUCHUSER 123 | CURLE_CONV_FAILED 124 | CURLE_CONV_REQD 125 | CURLE_SSL_CACERT_BADFILE 126 | CURLE_REMOTE_FILE_NOT_FOUND 127 | CURLE_SSH 128 | CURLE_SSL_SHUTDOWN_FAILED 129 | CURLE_AGAIN 130 | CURLE_SSL_CRL_BADFILE 131 | CURLE_SSL_ISSUER_ERROR 132 | CURLE_FTP_PRET_FAILED 133 | CURLE_RTSP_CSEQ_ERROR 134 | CURLE_RTSP_SESSION_ERROR 135 | CURLE_FTP_BAD_FILE_LIST 136 | CURLE_CHUNK_FAILED 137 | CURLE_NO_CONNECTION_AVAILABLE 138 | CURLE_SSL_PINNEDPUBKEYNOTMATCH 139 | CURLE_SSL_INVALIDCERTSTATUS 140 | CURLE_HTTP2_STREAM 141 | CURLE_RECURSIVE_API_CALL 142 | :=: 143 | CURLPROXY_HTTP 144 | CURLPROXY_HTTP_1_0 145 | CURLPROXY_HTTPS 146 | CURLPROXY_SOCKS4 147 | CURLPROXY_SOCKS5 148 | CURLPROXY_SOCKS4A 149 | CURLPROXY_SOCKS5_HOSTNAME 150 | :=: 151 | CURLUSESSL_NONE 152 | CURLUSESSL_TRY 153 | CURLUSESSL_CONTROL 154 | CURLUSESSL_ALL 155 | CURLUSESSL_LAST 156 | :=: 157 | CURLFTPSSL_CCC_NONE 158 | CURLFTPSSL_CCC_PASSIVE 159 | CURLFTPSSL_CCC_ACTIVE 160 | CURLFTPSSL_CCC_LAST 161 | :=: 162 | CURLFTPAUTH_DEFAULT 163 | CURLFTPAUTH_SSL 164 | CURLFTPAUTH_TLS 165 | CURLFTPAUTH_LAST 166 | :=: 167 | CURLFTP_CREATE_DIR_NONE 168 | CURLFTP_CREATE_DIR 169 | CURLFTP_CREATE_DIR_RETRY 170 | CURLFTP_CREATE_DIR_LAST 171 | :=: 172 | CURLFTPMETHOD_DEFAULT 173 | CURLFTPMETHOD_MULTICWD 174 | CURLFTPMETHOD_NOCWD 175 | CURLFTPMETHOD_SINGLECWD 176 | CURLFTPMETHOD_LAST 177 | :=: 178 | CURL_HTTP_VERSION_NONE 179 | CURL_HTTP_VERSION_1_0 180 | CURL_HTTP_VERSION_1_1 181 | CURL_HTTP_VERSION_2_0 182 | CURL_HTTP_VERSION_2TLS 183 | CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE 184 | CURL_HTTP_VERSION_LAST 185 | :=: 186 | CURL_RTSPREQ_NONE 187 | CURL_RTSPREQ_OPTIONS 188 | CURL_RTSPREQ_DESCRIBE 189 | CURL_RTSPREQ_ANNOUNCE 190 | CURL_RTSPREQ_SETUP 191 | CURL_RTSPREQ_PLAY 192 | CURL_RTSPREQ_PAUSE 193 | CURL_RTSPREQ_TEARDOWN 194 | CURL_RTSPREQ_GET_PARAMETER 195 | CURL_RTSPREQ_SET_PARAMETER 196 | CURL_RTSPREQ_RECORD 197 | CURL_RTSPREQ_RECEIVE 198 | CURL_RTSPREQ_LAST 199 | :=: 200 | CURL_SSLVERSION_DEFAULT 201 | CURL_SSLVERSION_TLSv1 202 | CURL_SSLVERSION_SSLv2 203 | CURL_SSLVERSION_SSLv3 204 | CURL_SSLVERSION_TLSv1_0 205 | CURL_SSLVERSION_TLSv1_1 206 | CURL_SSLVERSION_TLSv1_2 207 | CURL_SSLVERSION_TLSv1_3 208 | CURL_SSLVERSION_LAST 209 | :=: 210 | CURL_SSLVERSION_MAX_NONE 211 | CURL_SSLVERSION_MAX_DEFAULT 212 | CURL_SSLVERSION_MAX_TLSv1_0 213 | CURL_SSLVERSION_MAX_TLSv1_1 214 | CURL_SSLVERSION_MAX_TLSv1_2 215 | CURL_SSLVERSION_MAX_TLSv1_3 216 | CURL_SSLVERSION_MAX_LAST 217 | :=: 218 | CURL_TIMECOND_NONE 219 | CURL_TIMECOND_IFMODSINCE 220 | CURL_TIMECOND_IFUNMODSINCE 221 | CURL_TIMECOND_LASTMOD 222 | CURL_TIMECOND_LAST 223 | :=: 224 | CURLFORM_NOTHING 225 | CURLFORM_COPYNAME 226 | CURLFORM_PTRNAME 227 | CURLFORM_NAMELENGTH 228 | CURLFORM_COPYCONTENTS 229 | CURLFORM_PTRCONTENTS 230 | CURLFORM_CONTENTSLENGTH 231 | CURLFORM_FILECONTENT 232 | CURLFORM_ARRAY 233 | CURLFORM_OBSOLETE 234 | CURLFORM_FILE 235 | CURLFORM_BUFFER 236 | CURLFORM_BUFFERPTR 237 | CURLFORM_BUFFERLENGTH 238 | CURLFORM_CONTENTTYPE 239 | CURLFORM_CONTENTHEADER 240 | CURLFORM_FILENAME 241 | CURLFORM_END 242 | CURLFORM_OBSOLETE2 243 | CURLFORM_STREAM 244 | CURLFORM_CONTENTLEN 245 | CURLFORM_LASTENTRY 246 | :=: 247 | CURL_FORMADD_OK 248 | CURL_FORMADD_MEMORY 249 | CURL_FORMADD_OPTION_TWICE 250 | CURL_FORMADD_NULL 251 | CURL_FORMADD_UNKNOWN_OPTION 252 | CURL_FORMADD_INCOMPLETE 253 | CURL_FORMADD_ILLEGAL_ARRAY 254 | CURL_FORMADD_DISABLED 255 | CURL_FORMADD_LAST 256 | :=: 257 | CURLSSLSET_OK 258 | CURLSSLSET_UNKNOWN_BACKEND 259 | CURLSSLSET_TOO_LATE 260 | CURLSSLSET_NO_BACKENDS 261 | :=: 262 | CURLINFO_NONE 263 | CURLINFO_EFFECTIVE_URL 264 | CURLINFO_RESPONSE_CODE 265 | CURLINFO_TOTAL_TIME 266 | CURLINFO_NAMELOOKUP_TIME 267 | CURLINFO_CONNECT_TIME 268 | CURLINFO_PRETRANSFER_TIME 269 | CURLINFO_SIZE_UPLOAD 270 | CURLINFO_SIZE_UPLOAD_T 271 | CURLINFO_SIZE_DOWNLOAD 272 | CURLINFO_SIZE_DOWNLOAD_T 273 | CURLINFO_SPEED_DOWNLOAD 274 | CURLINFO_SPEED_DOWNLOAD_T 275 | CURLINFO_SPEED_UPLOAD 276 | CURLINFO_SPEED_UPLOAD_T 277 | CURLINFO_HEADER_SIZE 278 | CURLINFO_REQUEST_SIZE 279 | CURLINFO_SSL_VERIFYRESULT 280 | CURLINFO_FILETIME 281 | CURLINFO_FILETIME_T 282 | CURLINFO_CONTENT_LENGTH_DOWNLOAD 283 | CURLINFO_CONTENT_LENGTH_DOWNLOAD_T 284 | CURLINFO_CONTENT_LENGTH_UPLOAD 285 | CURLINFO_CONTENT_LENGTH_UPLOAD_T 286 | CURLINFO_STARTTRANSFER_TIME 287 | CURLINFO_CONTENT_TYPE 288 | CURLINFO_REDIRECT_TIME 289 | CURLINFO_REDIRECT_COUNT 290 | CURLINFO_PRIVATE 291 | CURLINFO_HTTP_CONNECTCODE 292 | CURLINFO_HTTPAUTH_AVAIL 293 | CURLINFO_PROXYAUTH_AVAIL 294 | CURLINFO_OS_ERRNO 295 | CURLINFO_NUM_CONNECTS 296 | CURLINFO_SSL_ENGINES 297 | CURLINFO_COOKIELIST 298 | CURLINFO_LASTSOCKET 299 | CURLINFO_FTP_ENTRY_PATH 300 | CURLINFO_REDIRECT_URL 301 | CURLINFO_PRIMARY_IP 302 | CURLINFO_APPCONNECT_TIME 303 | CURLINFO_CERTINFO 304 | CURLINFO_CONDITION_UNMET 305 | CURLINFO_RTSP_SESSION_ID 306 | CURLINFO_RTSP_CLIENT_CSEQ 307 | CURLINFO_RTSP_SERVER_CSEQ 308 | CURLINFO_RTSP_CSEQ_RECV 309 | CURLINFO_PRIMARY_PORT 310 | CURLINFO_LOCAL_IP 311 | CURLINFO_LOCAL_PORT 312 | CURLINFO_TLS_SESSION 313 | CURLINFO_ACTIVESOCKET 314 | CURLINFO_TLS_SSL_PTR 315 | CURLINFO_HTTP_VERSION 316 | CURLINFO_PROXY_SSL_VERIFYRESULT 317 | CURLINFO_PROTOCOL 318 | CURLINFO_SCHEME 319 | CURLINFO_TOTAL_TIME_T 320 | CURLINFO_NAMELOOKUP_TIME_T 321 | CURLINFO_CONNECT_TIME_T 322 | CURLINFO_PRETRANSFER_TIME_T 323 | CURLINFO_STARTTRANSFER_TIME_T 324 | CURLINFO_REDIRECT_TIME_T 325 | CURLINFO_APPCONNECT_TIME_T 326 | CURLINFO_LASTONE 327 | :=: 328 | CURLCLOSEPOLICY_NONE 329 | CURLCLOSEPOLICY_OLDEST 330 | CURLCLOSEPOLICY_LEAST_RECENTLY_USED 331 | CURLCLOSEPOLICY_LEAST_TRAFFIC 332 | CURLCLOSEPOLICY_SLOWEST 333 | CURLCLOSEPOLICY_CALLBACK 334 | CURLCLOSEPOLICY_LAST 335 | :=: 336 | CURL_LOCK_DATA_NONE 337 | CURL_LOCK_DATA_SHARE 338 | CURL_LOCK_DATA_COOKIE 339 | CURL_LOCK_DATA_DNS 340 | CURL_LOCK_DATA_SSL_SESSION 341 | CURL_LOCK_DATA_CONNECT 342 | CURL_LOCK_DATA_PSL 343 | CURL_LOCK_DATA_LAST 344 | :=: 345 | CURL_LOCK_ACCESS_NONE 346 | CURL_LOCK_ACCESS_SHARED 347 | CURL_LOCK_ACCESS_SINGLE 348 | CURL_LOCK_ACCESS_LAST 349 | :=: 350 | CURLSHE_OK 351 | CURLSHE_BAD_OPTION 352 | CURLSHE_IN_USE 353 | CURLSHE_INVALID 354 | CURLSHE_NOMEM 355 | CURLSHE_NOT_BUILT_IN 356 | CURLSHE_LAST 357 | :=: 358 | CURLSHOPT_NONE 359 | CURLSHOPT_SHARE 360 | CURLSHOPT_UNSHARE 361 | CURLSHOPT_LOCKFUNC 362 | CURLSHOPT_UNLOCKFUNC 363 | CURLSHOPT_USERDATA 364 | CURLSHOPT_LAST 365 | :=: -------------------------------------------------------------------------------- /api/funcs: -------------------------------------------------------------------------------- 1 | [x] => curl_easy_init 2 | [x] => curl_easy_cleanup 3 | [x] => curl_easy_duphandle 4 | [x] => curl_easy_escape 5 | [x] => curl_easy_unescape 6 | [x] => curl_easy_strerror 7 | [x] => curl_easy_pause 8 | [x] => curl_easy_reset 9 | [x] => curl_easy_upkeep 10 | [x] => curl_easy_recv 11 | [x] => curl_easy_send 12 | [x] => curl_easy_perform 13 | [~] => curl_easy_setopt 14 | [~] => curl_easy_getinfo 15 | 16 | [x] => curl_share_cleanup 17 | [x] => curl_share_init 18 | [x] => curl_share_strerror 19 | [?] => curl_share_setopt => i need to learn more about this function, do we really need 'share' at all 20 | 21 | [x] => curl_url 22 | [x] => curl_url_cleanup 23 | [x] => curl_url_dup 24 | [x] => curl_url_get 25 | [x] => curl_url_set 26 | 27 | [x] => curl_mime_init 28 | [x] => curl_mime_free 29 | [x] => curl_mime_addpart 30 | [x] => curl_mime_subparts 31 | [x] => curl_mime_name 32 | [x] => curl_mime_type 33 | [x] => curl_mime_data 34 | [x] => curl_mime_encoder 35 | [x] => curl_mime_headers 36 | [x] => curl_mime_filedata 37 | [x] => curl_mime_filename 38 | [?] => curl_mime_data_cb 39 | 40 | [ ] => curl_multi_add_handle 41 | [ ] => curl_multi_assign 42 | [ ] => curl_multi_cleanup 43 | [ ] => curl_multi_fdset 44 | [ ] => curl_multi_info_read 45 | [ ] => curl_multi_init 46 | [ ] => curl_multi_perform 47 | [ ] => curl_multi_remove_handle 48 | [ ] => curl_multi_setopt 49 | [ ] => curl_multi_socket_action 50 | [ ] => curl_multi_strerror 51 | [ ] => curl_multi_timeout 52 | [ ] => curl_multi_wait 53 | 54 | [ ] => curl_pushheader_byname 55 | [ ] => curl_pushheader_bynum 56 | 57 | // deprecated or N/A or stupid 58 | 59 | [-] => curl_slist_append 60 | [-] => curl_slist_free_all 61 | 62 | [-] => curl_version 63 | [-] => curl_version_info 64 | 65 | [-] => curl_free 66 | [-] => curl_getdate 67 | 68 | [-] => curl_global_cleanup 69 | [-] => curl_global_init 70 | [-] => curl_global_init_mem 71 | [-] => curl_global_sslset 72 | 73 | [-] => curl_formadd 74 | [-] => curl_formfree 75 | [-] => curl_formget -------------------------------------------------------------------------------- /api/opts: -------------------------------------------------------------------------------- 1 | CURLOPT_WRITEDATA @=> writedata #=> OBJECTPOINT 2 | CURLOPT_READDATA @=> readdata #=> OBJECTPOINT 3 | CURLOPT_ERRORBUFFER @=> errorbuffer #=> OBJECTPOINT 4 | CURLOPT_POSTFIELDS @=> postfields #=> OBJECTPOINT 5 | CURLOPT_HTTPHEADER @=> httpheader #=> OBJECTPOINT 6 | CURLOPT_HTTPPOST @=> httppost #=> OBJECTPOINT 7 | CURLOPT_QUOTE @=> quote #=> OBJECTPOINT 8 | CURLOPT_HEADERDATA @=> headerdata #=> OBJECTPOINT 9 | CURLOPT_STDERR @=> stderr #=> OBJECTPOINT 10 | CURLOPT_POSTQUOTE @=> postquote #=> OBJECTPOINT 11 | CURLOPT_OBSOLETE40 @=> obsolete40 #=> OBJECTPOINT 12 | CURLOPT_PROGRESSDATA @=> progressdata #=> OBJECTPOINT 13 | CURLOPT_TELNETOPTIONS @=> telnetoptions #=> OBJECTPOINT 14 | CURLOPT_PREQUOTE @=> prequote #=> OBJECTPOINT 15 | CURLOPT_DEBUGDATA @=> debugdata #=> OBJECTPOINT 16 | CURLOPT_SHARE @=> share #=> OBJECTPOINT 17 | CURLOPT_PRIVATE @=> private #=> OBJECTPOINT 18 | CURLOPT_HTTP200ALIASES @=> http200-aliases #=> OBJECTPOINT 19 | CURLOPT_SSL_CTX_DATA @=> ssl-ctx-data #=> OBJECTPOINT 20 | CURLOPT_IOCTLDATA @=> ioctldata #=> OBJECTPOINT 21 | CURLOPT_SOCKOPTDATA @=> sockoptdata #=> OBJECTPOINT 22 | CURLOPT_OPENSOCKETDATA @=> opensocketdata #=> OBJECTPOINT 23 | CURLOPT_COPYPOSTFIELDS @=> copypostfields #=> OBJECTPOINT 24 | CURLOPT_SEEKDATA @=> seekdata #=> OBJECTPOINT 25 | CURLOPT_SSH_KEYDATA @=> ssh-keydata #=> OBJECTPOINT 26 | CURLOPT_MAIL_RCPT @=> mail-rcpt #=> OBJECTPOINT 27 | CURLOPT_INTERLEAVEDATA @=> interleavedata #=> OBJECTPOINT 28 | CURLOPT_CHUNK_DATA @=> chunk-data #=> OBJECTPOINT 29 | CURLOPT_FNMATCH_DATA @=> fnmatch-data #=> OBJECTPOINT 30 | CURLOPT_RESOLVE @=> resolve #=> OBJECTPOINT 31 | CURLOPT_CLOSESOCKETDATA @=> closesocketdata #=> OBJECTPOINT 32 | CURLOPT_PROXYHEADER @=> proxyheader #=> OBJECTPOINT 33 | CURLOPT_STREAM_DEPENDS @=> stream-depends #=> OBJECTPOINT 34 | CURLOPT_STREAM_DEPENDS_E @=> stream-depends-e #=> OBJECTPOINT 35 | CURLOPT_CONNECT_TO @=> connect-to #=> OBJECTPOINT 36 | CURLOPT_MIMEPOST @=> mimepost #=> OBJECTPOINT 37 | CURLOPT_RESOLVER_START_DATA @=> resolver-start-data #=> OBJECTPOINT 38 | CURLOPT_CURLU @=> curlu #=> OBJECTPOINT 39 | CURLOPT_TRAILERDATA @=> trailerdata #=> OBJECTPOINT 40 | 41 | :=: 42 | 43 | CURLOPT_URL @=> url #=> STRINGPOINT 44 | CURLOPT_PROXY @=> proxy #=> STRINGPOINT 45 | CURLOPT_USERPWD @=> userpwd #=> STRINGPOINT 46 | CURLOPT_PROXYUSERPWD @=> proxyuserpwd #=> STRINGPOINT 47 | CURLOPT_RANGE @=> range #=> STRINGPOINT 48 | CURLOPT_REFERER @=> referer #=> STRINGPOINT 49 | CURLOPT_FTPPORT @=> ftpport #=> STRINGPOINT 50 | CURLOPT_USERAGENT @=> useragent #=> STRINGPOINT 51 | CURLOPT_COOKIE @=> cookie #=> STRINGPOINT 52 | CURLOPT_SSLCERT @=> sslcert #=> STRINGPOINT 53 | CURLOPT_KEYPASSWD @=> keypasswd #=> STRINGPOINT 54 | CURLOPT_COOKIEFILE @=> cookiefile #=> STRINGPOINT 55 | CURLOPT_CUSTOMREQUEST @=> customrequest #=> STRINGPOINT 56 | CURLOPT_INTERFACE @=> interface #=> STRINGPOINT 57 | CURLOPT_KRBLEVEL @=> krblevel #=> STRINGPOINT 58 | CURLOPT_CAINFO @=> cainfo #=> STRINGPOINT 59 | CURLOPT_RANDOM_FILE @=> random-file #=> STRINGPOINT 60 | CURLOPT_EGDSOCKET @=> egdsocket #=> STRINGPOINT 61 | CURLOPT_COOKIEJAR @=> cookiejar #=> STRINGPOINT 62 | CURLOPT_SSL_CIPHER_LIST @=> ssl-cipher-list #=> STRINGPOINT 63 | CURLOPT_SSLCERTTYPE @=> sslcerttype #=> STRINGPOINT 64 | CURLOPT_SSLKEY @=> sslkey #=> STRINGPOINT 65 | CURLOPT_SSLKEYTYPE @=> sslkeytype #=> STRINGPOINT 66 | CURLOPT_SSLENGINE @=> sslengine #=> STRINGPOINT 67 | CURLOPT_CAPATH @=> capath #=> STRINGPOINT 68 | CURLOPT_ACCEPT_ENCODING @=> accept-encoding #=> STRINGPOINT 69 | CURLOPT_NETRC_FILE @=> netrc-file #=> STRINGPOINT 70 | CURLOPT_FTP_ACCOUNT @=> ftp-account #=> STRINGPOINT 71 | CURLOPT_COOKIELIST @=> cookielist #=> STRINGPOINT 72 | CURLOPT_FTP_ALTERNATIVE_TO_USER @=> ftp-alternative-to-user #=> STRINGPOINT 73 | CURLOPT_SSH_PUBLIC_KEYFILE @=> ssh-public-keyfile #=> STRINGPOINT 74 | CURLOPT_SSH_PRIVATE_KEYFILE @=> ssh-private-keyfile #=> STRINGPOINT 75 | CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 @=> ssh-host-public-key-md5 #=> STRINGPOINT 76 | CURLOPT_CRLFILE @=> crlfile #=> STRINGPOINT 77 | CURLOPT_ISSUERCERT @=> issuercert #=> STRINGPOINT 78 | CURLOPT_USERNAME @=> username #=> STRINGPOINT 79 | CURLOPT_PASSWORD @=> password #=> STRINGPOINT 80 | CURLOPT_PROXYUSERNAME @=> proxyusername #=> STRINGPOINT 81 | CURLOPT_PROXYPASSWORD @=> proxypassword #=> STRINGPOINT 82 | CURLOPT_NOPROXY @=> noproxy #=> STRINGPOINT 83 | CURLOPT_SOCKS5_GSSAPI_SERVICE @=> socks5-gssapi-service #=> STRINGPOINT 84 | CURLOPT_SSH_KNOWNHOSTS @=> ssh-knownhosts #=> STRINGPOINT 85 | CURLOPT_MAIL_FROM @=> mail-from #=> STRINGPOINT 86 | CURLOPT_RTSP_SESSION_ID @=> rtsp-session-id #=> STRINGPOINT 87 | CURLOPT_RTSP_STREAM_URI @=> rtsp-stream-uri #=> STRINGPOINT 88 | CURLOPT_RTSP_TRANSPORT @=> rtsp-transport #=> STRINGPOINT 89 | CURLOPT_TLSAUTH_USERNAME @=> tlsauth-username #=> STRINGPOINT 90 | CURLOPT_TLSAUTH_PASSWORD @=> tlsauth-password #=> STRINGPOINT 91 | CURLOPT_TLSAUTH_TYPE @=> tlsauth-type #=> STRINGPOINT 92 | CURLOPT_DNS_SERVERS @=> dns-servers #=> STRINGPOINT 93 | CURLOPT_MAIL_AUTH @=> mail-auth #=> STRINGPOINT 94 | CURLOPT_XOAUTH2_BEARER @=> xoauth2-bearer #=> STRINGPOINT 95 | CURLOPT_DNS_INTERFACE @=> dns-interface #=> STRINGPOINT 96 | CURLOPT_DNS_LOCAL_IP4 @=> dns-local-ip4 #=> STRINGPOINT 97 | CURLOPT_DNS_LOCAL_IP6 @=> dns-local-ip6 #=> STRINGPOINT 98 | CURLOPT_LOGIN_OPTIONS @=> login-options #=> STRINGPOINT 99 | CURLOPT_PINNEDPUBLICKEY @=> pinnedpublickey #=> STRINGPOINT 100 | CURLOPT_UNIX_SOCKET_PATH @=> unix-socket-path #=> STRINGPOINT 101 | CURLOPT_PROXY_SERVICE_NAME @=> proxy-service-name #=> STRINGPOINT 102 | CURLOPT_SERVICE_NAME @=> service-name #=> STRINGPOINT 103 | CURLOPT_DEFAULT_PROTOCOL @=> default-protocol #=> STRINGPOINT 104 | CURLOPT_PROXY_CAINFO @=> proxy-cainfo #=> STRINGPOINT 105 | CURLOPT_PROXY_CAPATH @=> proxy-capath #=> STRINGPOINT 106 | CURLOPT_PROXY_TLSAUTH_USERNAME @=> proxy-tlsauth-username #=> STRINGPOINT 107 | CURLOPT_PROXY_TLSAUTH_PASSWORD @=> proxy-tlsauth-password #=> STRINGPOINT 108 | CURLOPT_PROXY_TLSAUTH_TYPE @=> proxy-tlsauth-type #=> STRINGPOINT 109 | CURLOPT_PROXY_SSLCERT @=> proxy-sslcert #=> STRINGPOINT 110 | CURLOPT_PROXY_SSLCERTTYPE @=> proxy-sslcerttype #=> STRINGPOINT 111 | CURLOPT_PROXY_SSLKEY @=> proxy-sslkey #=> STRINGPOINT 112 | CURLOPT_PROXY_SSLKEYTYPE @=> proxy-sslkeytype #=> STRINGPOINT 113 | CURLOPT_PROXY_KEYPASSWD @=> proxy-keypasswd #=> STRINGPOINT 114 | CURLOPT_PROXY_SSL_CIPHER_LIST @=> proxy-ssl-cipher-list #=> STRINGPOINT 115 | CURLOPT_PROXY_CRLFILE @=> proxy-crlfile #=> STRINGPOINT 116 | CURLOPT_PRE_PROXY @=> pre-proxy #=> STRINGPOINT 117 | CURLOPT_PROXY_PINNEDPUBLICKEY @=> proxy-pinnedpublickey #=> STRINGPOINT 118 | CURLOPT_ABSTRACT_UNIX_SOCKET @=> abstract-unix-socket #=> STRINGPOINT 119 | CURLOPT_REQUEST_TARGET @=> request-target #=> STRINGPOINT 120 | CURLOPT_TLS13_CIPHERS @=> tls13-ciphers #=> STRINGPOINT 121 | CURLOPT_PROXY_TLS13_CIPHERS @=> proxy-tls13-ciphers #=> STRINGPOINT 122 | CURLOPT_DOH_URL @=> doh-url #=> STRINGPOINT 123 | 124 | :=: 125 | 126 | CURLOPT_PORT @=> port #=> LONG 127 | CURLOPT_TIMEOUT @=> timeout #=> LONG 128 | CURLOPT_INFILESIZE @=> infilesize #=> LONG 129 | CURLOPT_LOW_SPEED_LIMIT @=> low-speed-limit #=> LONG 130 | CURLOPT_LOW_SPEED_TIME @=> low-speed-time #=> LONG 131 | CURLOPT_RESUME_FROM @=> resume-from #=> LONG 132 | CURLOPT_CRLF @=> crlf #=> LONG 133 | CURLOPT_SSLVERSION @=> sslversion #=> LONG 134 | CURLOPT_TIMECONDITION @=> timecondition #=> LONG 135 | CURLOPT_TIMEVALUE @=> timevalue #=> LONG 136 | CURLOPT_VERBOSE @=> verbose #=> LONG 137 | CURLOPT_HEADER @=> header #=> LONG 138 | CURLOPT_NOPROGRESS @=> noprogress #=> LONG 139 | CURLOPT_NOBODY @=> nobody #=> LONG 140 | CURLOPT_FAILONERROR @=> failonerror #=> LONG 141 | CURLOPT_UPLOAD @=> upload #=> LONG 142 | CURLOPT_POST @=> post #=> LONG 143 | CURLOPT_DIRLISTONLY @=> dirlistonly #=> LONG 144 | CURLOPT_APPEND @=> append #=> LONG 145 | CURLOPT_NETRC @=> netrc #=> LONG 146 | CURLOPT_FOLLOWLOCATION @=> followlocation #=> LONG 147 | CURLOPT_TRANSFERTEXT @=> transfertext #=> LONG 148 | CURLOPT_PUT @=> put #=> LONG 149 | CURLOPT_AUTOREFERER @=> autoreferer #=> LONG 150 | CURLOPT_PROXYPORT @=> proxyport #=> LONG 151 | CURLOPT_POSTFIELDSIZE @=> postfieldsize #=> LONG 152 | CURLOPT_HTTPPROXYTUNNEL @=> httpproxytunnel #=> LONG 153 | CURLOPT_SSL_VERIFYPEER @=> ssl-verifypeer #=> LONG 154 | CURLOPT_MAXREDIRS @=> maxredirs #=> LONG 155 | CURLOPT_FILETIME @=> filetime #=> LONG 156 | CURLOPT_MAXCONNECTS @=> maxconnects #=> LONG 157 | CURLOPT_OBSOLETE72 @=> obsolete72 #=> LONG 158 | CURLOPT_FRESH_CONNECT @=> fresh-connect #=> LONG 159 | CURLOPT_FORBID_REUSE @=> forbid-reuse #=> LONG 160 | CURLOPT_CONNECTTIMEOUT @=> connecttimeout #=> LONG 161 | CURLOPT_HTTPGET @=> httpget #=> LONG 162 | CURLOPT_SSL_VERIFYHOST @=> ssl-verifyhost #=> LONG 163 | CURLOPT_HTTP_VERSION @=> http-version #=> LONG 164 | CURLOPT_FTP_USE_EPSV @=> ftp-use-epsv #=> LONG 165 | CURLOPT_SSLENGINE_DEFAULT @=> sslengine-default #=> LONG 166 | CURLOPT_DNS_USE_GLOBAL_CACHE @=> dns-use-global-cache #=> LONG 167 | CURLOPT_DNS_CACHE_TIMEOUT @=> dns-cache-timeout #=> LONG 168 | CURLOPT_COOKIESESSION @=> cookiesession #=> LONG 169 | CURLOPT_BUFFERSIZE @=> buffersize #=> LONG 170 | CURLOPT_NOSIGNAL @=> nosignal #=> LONG 171 | CURLOPT_PROXYTYPE @=> proxytype #=> LONG 172 | CURLOPT_UNRESTRICTED_AUTH @=> unrestricted-auth #=> LONG 173 | CURLOPT_FTP_USE_EPRT @=> ftp-use-eprt #=> LONG 174 | CURLOPT_HTTPAUTH @=> httpauth #=> LONG 175 | CURLOPT_FTP_CREATE_MISSING_DIRS @=> ftp-create-missing-dirs #=> LONG 176 | CURLOPT_PROXYAUTH @=> proxyauth #=> LONG 177 | CURLOPT_FTP_RESPONSE_TIMEOUT @=> ftp-response-timeout #=> LONG 178 | CURLOPT_IPRESOLVE @=> ipresolve #=> LONG 179 | CURLOPT_MAXFILESIZE @=> maxfilesize #=> LONG 180 | CURLOPT_USE_SSL @=> use-ssl #=> LONG 181 | CURLOPT_TCP_NODELAY @=> tcp-nodelay #=> LONG 182 | CURLOPT_FTPSSLAUTH @=> ftpsslauth #=> LONG 183 | CURLOPT_IGNORE_CONTENT_LENGTH @=> ignore-content-length #=> LONG 184 | CURLOPT_FTP_SKIP_PASV_IP @=> ftp-skip-pasv-ip #=> LONG 185 | CURLOPT_FTP_FILEMETHOD @=> ftp-filemethod #=> LONG 186 | CURLOPT_LOCALPORT @=> localport #=> LONG 187 | CURLOPT_LOCALPORTRANGE @=> localportrange #=> LONG 188 | CURLOPT_CONNECT_ONLY @=> connect-only #=> LONG 189 | CURLOPT_SSL_SESSIONID_CACHE @=> ssl-sessionid-cache #=> LONG 190 | CURLOPT_SSH_AUTH_TYPES @=> ssh-auth-types #=> LONG 191 | CURLOPT_FTP_SSL_CCC @=> ftp-ssl-ccc #=> LONG 192 | CURLOPT_TIMEOUT_MS @=> timeout-ms #=> LONG 193 | CURLOPT_CONNECTTIMEOUT_MS @=> connecttimeout-ms #=> LONG 194 | CURLOPT_HTTP_TRANSFER_DECODING @=> http-transfer-decoding #=> LONG 195 | CURLOPT_HTTP_CONTENT_DECODING @=> http-content-decoding #=> LONG 196 | CURLOPT_NEW_FILE_PERMS @=> new-file-perms #=> LONG 197 | CURLOPT_NEW_DIRECTORY_PERMS @=> new-directory-perms #=> LONG 198 | CURLOPT_POSTREDIR @=> postredir #=> LONG 199 | CURLOPT_PROXY_TRANSFER_MODE @=> proxy-transfer-mode #=> LONG 200 | CURLOPT_ADDRESS_SCOPE @=> address-scope #=> LONG 201 | CURLOPT_CERTINFO @=> certinfo #=> LONG 202 | CURLOPT_TFTP_BLKSIZE @=> tftp-blksize #=> LONG 203 | CURLOPT_SOCKS5_GSSAPI_NEC @=> socks5-gssapi-nec #=> LONG 204 | CURLOPT_PROTOCOLS @=> protocols #=> LONG 205 | CURLOPT_REDIR_PROTOCOLS @=> redir-protocols #=> LONG 206 | CURLOPT_FTP_USE_PRET @=> ftp-use-pret #=> LONG 207 | CURLOPT_RTSP_REQUEST @=> rtsp-request #=> LONG 208 | CURLOPT_RTSP_CLIENT_CSEQ @=> rtsp-client-cseq #=> LONG 209 | CURLOPT_RTSP_SERVER_CSEQ @=> rtsp-server-cseq #=> LONG 210 | CURLOPT_WILDCARDMATCH @=> wildcardmatch #=> LONG 211 | CURLOPT_TRANSFER_ENCODING @=> transfer-encoding #=> LONG 212 | CURLOPT_GSSAPI_DELEGATION @=> gssapi-delegation #=> LONG 213 | CURLOPT_ACCEPTTIMEOUT_MS @=> accepttimeout-ms #=> LONG 214 | CURLOPT_TCP_KEEPALIVE @=> tcp-keepalive #=> LONG 215 | CURLOPT_TCP_KEEPIDLE @=> tcp-keepidle #=> LONG 216 | CURLOPT_TCP_KEEPINTVL @=> tcp-keepintvl #=> LONG 217 | CURLOPT_SSL_OPTIONS @=> ssl-options #=> LONG 218 | CURLOPT_SASL_IR @=> sasl-ir #=> LONG 219 | CURLOPT_SSL_ENABLE_NPN @=> ssl-enable-npn #=> LONG 220 | CURLOPT_SSL_ENABLE_ALPN @=> ssl-enable-alpn #=> LONG 221 | CURLOPT_EXPECT_100_TIMEOUT_MS @=> expect-100-timeout-ms #=> LONG 222 | CURLOPT_HEADEROPT @=> headeropt #=> LONG 223 | CURLOPT_SSL_VERIFYSTATUS @=> ssl-verifystatus #=> LONG 224 | CURLOPT_SSL_FALSESTART @=> ssl-falsestart #=> LONG 225 | CURLOPT_PATH_AS_IS @=> path-as-is #=> LONG 226 | CURLOPT_PIPEWAIT @=> pipewait #=> LONG 227 | CURLOPT_STREAM_WEIGHT @=> stream-weight #=> LONG 228 | CURLOPT_TFTP_NO_OPTIONS @=> tftp-no-options #=> LONG 229 | CURLOPT_TCP_FASTOPEN @=> tcp-fastopen #=> LONG 230 | CURLOPT_KEEP_SENDING_ON_ERROR @=> keep-sending-on-error #=> LONG 231 | CURLOPT_PROXY_SSL_VERIFYPEER @=> proxy-ssl-verifypeer #=> LONG 232 | CURLOPT_PROXY_SSL_VERIFYHOST @=> proxy-ssl-verifyhost #=> LONG 233 | CURLOPT_PROXY_SSLVERSION @=> proxy-sslversion #=> LONG 234 | CURLOPT_PROXY_SSL_OPTIONS @=> proxy-ssl-options #=> LONG 235 | CURLOPT_SUPPRESS_CONNECT_HEADERS @=> suppress-connect-headers #=> LONG 236 | CURLOPT_SOCKS5_AUTH @=> socks5-auth #=> LONG 237 | CURLOPT_SSH_COMPRESSION @=> ssh-compression #=> LONG 238 | CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS @=> happy-eyeballs-timeout-ms #=> LONG 239 | CURLOPT_HAPROXYPROTOCOL @=> haproxyprotocol #=> LONG 240 | CURLOPT_DNS_SHUFFLE_ADDRESSES @=> dns-shuffle-addresses #=> LONG 241 | CURLOPT_DISALLOW_USERNAME_IN_URL @=> disallow-username-in-url #=> LONG 242 | CURLOPT_UPLOAD_BUFFERSIZE @=> upload-buffersize #=> LONG 243 | CURLOPT_UPKEEP_INTERVAL_MS @=> upkeep-interval-ms #=> LONG 244 | CURLOPT_HTTP09_ALLOWED @=> http09-allowed #=> LONG 245 | 246 | :=: 247 | 248 | CURLOPT_WRITEFUNCTION @=> writefunction #=> FUNCTIONPOINT 249 | CURLOPT_READFUNCTION @=> readfunction #=> FUNCTIONPOINT 250 | CURLOPT_PROGRESSFUNCTION @=> progressfunction #=> FUNCTIONPOINT 251 | CURLOPT_HEADERFUNCTION @=> headerfunction #=> FUNCTIONPOINT 252 | CURLOPT_DEBUGFUNCTION @=> debugfunction #=> FUNCTIONPOINT 253 | CURLOPT_SSL_CTX_FUNCTION @=> ssl-ctx-function #=> FUNCTIONPOINT 254 | CURLOPT_IOCTLFUNCTION @=> ioctlfunction #=> FUNCTIONPOINT 255 | CURLOPT_CONV_FROM_NETWORK_FUNCTION @=> conv-from-network-function #=> FUNCTIONPOINT 256 | CURLOPT_CONV_TO_NETWORK_FUNCTION @=> conv-to-network-function #=> FUNCTIONPOINT 257 | CURLOPT_CONV_FROM_UTF8_FUNCTION @=> conv-from-utf8-function #=> FUNCTIONPOINT 258 | CURLOPT_SOCKOPTFUNCTION @=> sockoptfunction #=> FUNCTIONPOINT 259 | CURLOPT_OPENSOCKETFUNCTION @=> opensocketfunction #=> FUNCTIONPOINT 260 | CURLOPT_SEEKFUNCTION @=> seekfunction #=> FUNCTIONPOINT 261 | CURLOPT_SSH_KEYFUNCTION @=> ssh-keyfunction #=> FUNCTIONPOINT 262 | CURLOPT_INTERLEAVEFUNCTION @=> interleavefunction #=> FUNCTIONPOINT 263 | CURLOPT_CHUNK_BGN_FUNCTION @=> chunk-bgn-function #=> FUNCTIONPOINT 264 | CURLOPT_CHUNK_END_FUNCTION @=> chunk-end-function #=> FUNCTIONPOINT 265 | CURLOPT_FNMATCH_FUNCTION @=> fnmatch-function #=> FUNCTIONPOINT 266 | CURLOPT_CLOSESOCKETFUNCTION @=> closesocketfunction #=> FUNCTIONPOINT 267 | CURLOPT_XFERINFOFUNCTION @=> xferinfofunction #=> FUNCTIONPOINT 268 | CURLOPT_RESOLVER_START_FUNCTION @=> resolver-start-function #=> FUNCTIONPOINT 269 | CURLOPT_TRAILERFUNCTION @=> trailerfunction #=> FUNCTIONPOINT 270 | 271 | :=: 272 | 273 | CURLOPT_INFILESIZE_LARGE @=> infilesize-large #=> OFF_T 274 | CURLOPT_RESUME_FROM_LARGE @=> resume-from-large #=> OFF_T 275 | CURLOPT_MAXFILESIZE_LARGE @=> maxfilesize-large #=> OFF_T 276 | CURLOPT_POSTFIELDSIZE_LARGE @=> postfieldsize-large #=> OFF_T 277 | CURLOPT_MAX_SEND_SPEED_LARGE @=> max-send-speed-large #=> OFF_T 278 | CURLOPT_MAX_RECV_SPEED_LARGE @=> max-recv-speed-large #=> OFF_T 279 | CURLOPT_TIMEVALUE_LARGE @=> timevalue-large #=> OFF_T -------------------------------------------------------------------------------- /project.janet: -------------------------------------------------------------------------------- 1 | (declare-project 2 | :name "jurl" 3 | :description "Janet wrapper around libcurl" 4 | :author "Sepehr Aryani" 5 | :license "GPLv3" 6 | :url "https://github.com/sepisoad/jurl" 7 | :repo "https://github.com/sepisoad/jurl") 8 | 9 | (def lflags (case (os/which) 10 | :windows @["libcurl.lib"] 11 | :linux @["-lcurl"] 12 | #default 13 | @["-lcurl"])) 14 | 15 | (declare-native 16 | :name "curl" 17 | :lflags lflags 18 | :source ["src/curl.c"]) 19 | -------------------------------------------------------------------------------- /src/curl.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "khash.h" 4 | 5 | //============================================================================== 6 | // ██████╗ ██████╗ ███╗ ██╗███████╗████████╗ █████╗ ███╗ ██╗████████╗███████╗ 7 | // ██╔════╝██╔═══██╗████╗ ██║██╔════╝╚══██╔══╝██╔══██╗████╗ ██║╚══██╔══╝██╔════╝ 8 | // ██║ ██║ ██║██╔██╗ ██║███████╗ ██║ ███████║██╔██╗ ██║ ██║ ███████╗ 9 | // ██║ ██║ ██║██║╚██╗██║╚════██║ ██║ ██╔══██║██║╚██╗██║ ██║ ╚════██║ 10 | // ╚██████╗╚██████╔╝██║ ╚████║███████║ ██║ ██║ ██║██║ ╚████║ ██║ ███████║ 11 | // ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚══════╝ 12 | //============================================================================== 13 | 14 | #define DEFAULT_EASY_RECV_BUF_LEN 2014 15 | 16 | //============================================================================== 17 | // ████████╗██╗ ██╗██████╗ ███████╗███████╗ 18 | // ╚══██╔══╝╚██╗ ██╔╝██╔══██╗██╔════╝██╔════╝ 19 | // ██║ ╚████╔╝ ██████╔╝█████╗ ███████╗ 20 | // ██║ ╚██╔╝ ██╔═══╝ ██╔══╝ ╚════██║ 21 | // ██║ ██║ ██║ ███████╗███████║ 22 | // ╚═╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝ 23 | //============================================================================== 24 | 25 | typedef struct MapCurlOptionToJanetType MapCurlOptionToJanetType; 26 | typedef struct MapCurlInfoToJanetType MapCurlInfoToJanetType; 27 | typedef struct Curl Curl; 28 | typedef struct Curlsh Curlsh; 29 | typedef struct Url Url; 30 | typedef struct Mime Mime; 31 | typedef struct MimePart MimePart; // does not need GC, it gets freed when Mime parent object GC happens 32 | 33 | struct MapCurlOptionToJanetType { 34 | int option; 35 | JanetType type; 36 | }; 37 | 38 | struct MapCurlInfoToJanetType { 39 | int info; 40 | JanetType type; 41 | }; 42 | 43 | struct Curl { 44 | CURL *curl; 45 | JanetFunction *write_function; 46 | JanetFunction *header_function; 47 | JanetFunction *read_function; 48 | JanetFunction *progress_function; 49 | }; 50 | 51 | struct Curlsh { 52 | CURLSH *curlsh; 53 | }; 54 | 55 | struct Url { 56 | CURLU *url; 57 | }; 58 | 59 | struct Mime { 60 | curl_mime *mime; 61 | }; 62 | 63 | struct MimePart { 64 | curl_mimepart *mimepart; 65 | }; 66 | 67 | //============================================================================== 68 | // ██████╗ ██████╗ ██████╗ ████████╗ ██████╗ ████████╗██╗ ██╗██████╗ ███████╗███████╗ 69 | // ██╔══██╗██╔══██╗██╔═══██╗╚══██╔══╝██╔═══██╗╚══██╔══╝╚██╗ ██╔╝██╔══██╗██╔════╝██╔════╝ 70 | // ██████╔╝██████╔╝██║ ██║ ██║ ██║ ██║ ██║ ╚████╔╝ ██████╔╝█████╗ ███████╗ 71 | // ██╔═══╝ ██╔══██╗██║ ██║ ██║ ██║ ██║ ██║ ╚██╔╝ ██╔═══╝ ██╔══╝ ╚════██║ 72 | // ██║ ██║ ██║╚██████╔╝ ██║ ╚██████╔╝ ██║ ██║ ██║ ███████╗███████║ 73 | // ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝ 74 | //============================================================================== 75 | 76 | static int curl_gc_fn(void *data, size_t len); 77 | static int curl_get_fn(void *data, Janet key, Janet *out); 78 | static Janet easy_init(int32_t argc, Janet *argv); 79 | static Janet easy_clone(int32_t argc, Janet *argv); 80 | static Janet easy_escape(int32_t argc, Janet *argv); 81 | static Janet easy_unescape(int32_t argc, Janet *argv); 82 | static Janet easy_strerror(int32_t argc, Janet *argv); 83 | static Janet easy_setopt(int32_t argc, Janet *argv); 84 | static Janet easy_pause(int32_t argc, Janet *argv); 85 | static Janet easy_reset(int32_t argc, Janet *argv); 86 | static Janet easy_upkeep(int32_t argc, Janet *argv); 87 | static Janet easy_recv(int32_t argc, Janet *argv); 88 | static Janet easy_send(int32_t argc, Janet *argv); 89 | static Janet easy_perform(int32_t argc, Janet *argv); 90 | static Janet easy_query(int32_t argc, Janet *argv); 91 | 92 | static int curlsh_gc_fn(void *data, size_t len); 93 | static int curl_mark_fn(void *data, size_t len); 94 | static int curlsh_get_fn(void *data, Janet key, Janet *out); 95 | static Janet share_init(int32_t argc, Janet *argv); 96 | static Janet share_setopt(int32_t argc, Janet *argv); 97 | static Janet share_strerror(int32_t argc, Janet *argv); 98 | 99 | static int url_gc_fn(void *data, size_t len); 100 | static int url_get_fn(void *data, Janet key, Janet *out); 101 | static Janet url_init(int32_t argc, Janet *argv); 102 | static Janet url_clone(int32_t argc, Janet *argv); 103 | static Janet url_get(int32_t argc, Janet *argv); 104 | static Janet url_set(int32_t argc, Janet *argv); 105 | 106 | static int mime_gc_fn(void *data, size_t len); 107 | static int mime_get_fn(void *data, Janet key, Janet *out); 108 | static Janet mime_init(int32_t argc, Janet *argv); 109 | 110 | //============================================================================== 111 | // ██████╗ ██╗ ██████╗ ██████╗ █████╗ ██╗ ███████╗ 112 | // ██╔════╝ ██║ ██╔═══██╗██╔══██╗██╔══██╗██║ ██╔════╝ 113 | // ██║ ███╗██║ ██║ ██║██████╔╝███████║██║ ███████╗ 114 | // ██║ ██║██║ ██║ ██║██╔══██╗██╔══██║██║ ╚════██║ 115 | // ╚██████╔╝███████╗╚██████╔╝██████╔╝██║ ██║███████╗███████║ 116 | // ╚═════╝ ╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝ 117 | //============================================================================== 118 | 119 | KHASH_MAP_INIT_STR(HashMapCurlOptionToJanetType, MapCurlOptionToJanetType *); 120 | khash_t(HashMapCurlOptionToJanetType) *hashmap_opt_to_type = NULL; 121 | 122 | KHASH_MAP_INIT_STR(HashMapCurlInfoToJanetType, MapCurlInfoToJanetType *); 123 | khash_t(HashMapCurlInfoToJanetType) *hashmap_info_to_type = NULL; 124 | 125 | JanetAbstractType curl_obj = {"curl", curl_gc_fn, curl_mark_fn, curl_get_fn, JANET_ATEND_GET}; 126 | JanetAbstractType curlsh_obj = {"curlsh", curlsh_gc_fn, NULL, curlsh_get_fn, JANET_ATEND_GET}; 127 | JanetAbstractType url_obj = {"url", url_gc_fn, NULL, url_get_fn, JANET_ATEND_GET}; 128 | JanetAbstractType mime_obj = {"mime", mime_gc_fn, NULL, mime_get_fn, JANET_ATEND_GET}; 129 | JanetAbstractType mimepart_obj = {"mimepart", JANET_ATEND_NAME}; 130 | 131 | static JanetMethod curl_methods[] = { 132 | {"clone", easy_clone}, 133 | {"escape", easy_escape}, 134 | {"unescape", easy_unescape}, 135 | {"setopt", easy_setopt}, 136 | {"pause", easy_pause}, 137 | {"reset", easy_reset}, 138 | {"upkeep", easy_upkeep}, 139 | {"recv", easy_recv}, 140 | {"send", easy_send}, 141 | {"perform", easy_perform}, 142 | {"query", easy_query}, 143 | {NULL, NULL} 144 | }; 145 | 146 | static JanetMethod curlsh_methods[] = { 147 | {"setopt", easy_setopt}, 148 | {NULL, NULL} 149 | }; 150 | 151 | static JanetMethod url_methods[] = { 152 | {"clone", url_clone}, 153 | {"get", url_get}, 154 | {"set", url_set}, 155 | {NULL, NULL} 156 | }; 157 | 158 | static JanetMethod mime_methods[] = { // FIXME: 159 | {NULL, NULL} 160 | }; 161 | 162 | //============================================================================== 163 | // ██████╗ █████╗ ███████╗███████╗ 164 | // ██╔══██╗██╔══██╗██╔════╝██╔════╝ 165 | // ██████╔╝███████║███████╗█████╗ 166 | // ██╔══██╗██╔══██║╚════██║██╔══╝ 167 | // ██████╔╝██║ ██║███████║███████╗ 168 | // ╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝ 169 | //============================================================================== 170 | 171 | static Janet curl_make(CURL *curl) { 172 | Curl *c = (Curl *) janet_abstract(&curl_obj, sizeof(Curl)); 173 | memset(c, 0, sizeof(Curl)); 174 | c->curl = curl; 175 | return janet_wrap_abstract(c); 176 | } 177 | 178 | static int curl_gc_fn(void *data, size_t len) { 179 | (void) len; 180 | 181 | Curl *c = (Curl *)data; 182 | curl_easy_cleanup(c->curl); 183 | 184 | return 0; 185 | } 186 | 187 | static int curl_mark_fn(void *data, size_t len) { 188 | (void) len; 189 | 190 | Curl *c = (Curl *)data; 191 | if (c->read_function) janet_mark(janet_wrap_function(c->read_function)); 192 | if (c->write_function) janet_mark(janet_wrap_function(c->write_function)); 193 | if (c->progress_function) janet_mark(janet_wrap_function(c->progress_function)); 194 | if (c->header_function) janet_mark(janet_wrap_function(c->header_function)); 195 | return 0; 196 | } 197 | 198 | static int curl_get_fn(void *data, Janet key, Janet *out) { 199 | (void) data; 200 | 201 | if (!janet_checktype(key, JANET_KEYWORD)) 202 | janet_panicf("expected keyword, got %v", key); 203 | return janet_getmethod(janet_unwrap_keyword(key), curl_methods, out); 204 | } 205 | 206 | static Janet curlsh_make(CURLSH *curlsh) { 207 | Curlsh *c = (Curlsh *) janet_abstract(&curl_obj, sizeof(Curlsh)); 208 | c->curlsh = curlsh; 209 | return janet_wrap_abstract(c); 210 | } 211 | 212 | static int curlsh_gc_fn(void *data, size_t len) { 213 | (void) len; 214 | 215 | Curlsh *c = (Curlsh *)data; 216 | curl_share_cleanup(c->curlsh); 217 | 218 | return 0; 219 | } 220 | 221 | static int curlsh_get_fn(void *data, Janet key, Janet *out) { 222 | (void) data; 223 | 224 | if (!janet_checktype(key, JANET_KEYWORD)) 225 | janet_panicf("expected keyword, got %v", key); 226 | return janet_getmethod(janet_unwrap_keyword(key), curlsh_methods, out); 227 | } 228 | 229 | static Janet url_make(CURLU *url) { 230 | Url *u = (Url *) janet_abstract(&url_obj, sizeof(Url)); 231 | u->url = url; 232 | return janet_wrap_abstract(u); 233 | } 234 | 235 | static int url_gc_fn(void *data, size_t len) { 236 | (void) len; 237 | 238 | Url *u = (Url *)data; 239 | curl_url_cleanup(u->url); 240 | 241 | return 0; 242 | } 243 | 244 | static int url_get_fn(void *data, Janet key, Janet *out) { 245 | (void) data; 246 | 247 | if (!janet_checktype(key, JANET_KEYWORD)) 248 | janet_panicf("expected keyword, got %v", key); 249 | return janet_getmethod(janet_unwrap_keyword(key), url_methods, out); 250 | } 251 | 252 | static Janet mime_make(curl_mime *mime) { 253 | Mime *m = (Mime *) janet_abstract(&mime_obj, sizeof(Mime)); 254 | m->mime = mime; 255 | return janet_wrap_abstract(m); 256 | } 257 | 258 | static int mime_gc_fn(void *data, size_t len) { 259 | (void) len; 260 | 261 | Mime *m = (Mime *)data; 262 | curl_mime_free(m->mime); 263 | 264 | return 0; 265 | } 266 | 267 | static int mime_get_fn(void *data, Janet key, Janet *out) { 268 | (void) data; 269 | 270 | if (!janet_checktype(key, JANET_KEYWORD)) 271 | janet_panicf("expected keyword, got %v", key); 272 | return janet_getmethod(janet_unwrap_keyword(key), mime_methods, out); 273 | } 274 | 275 | static Janet mimepart_make(curl_mimepart *mimepart) { 276 | MimePart *mp = (MimePart *) janet_abstract(&mimepart_obj, sizeof(MimePart)); 277 | mp->mimepart = mimepart; 278 | return janet_wrap_abstract(mp); 279 | } 280 | 281 | //============================================================================== 282 | // ██████╗ █████╗ ██╗ ██╗ ██████╗ █████╗ ██████╗██╗ ██╗███████╗ 283 | // ██╔════╝██╔══██╗██║ ██║ ██╔══██╗██╔══██╗██╔════╝██║ ██╔╝██╔════╝ 284 | // ██║ ███████║██║ ██║ ██████╔╝███████║██║ █████╔╝ ███████╗ 285 | // ██║ ██╔══██║██║ ██║ ██╔══██╗██╔══██║██║ ██╔═██╗ ╚════██║ 286 | // ╚██████╗██║ ██║███████╗███████╗██████╔╝██║ ██║╚██████╗██║ ██╗███████║ 287 | // ╚═════╝╚═╝ ╚═╝╚══════╝╚══════╝╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝ 288 | //============================================================================== 289 | 290 | static size_t funcs_write(void *buff, size_t size, size_t count, void *udata) { 291 | const size_t len = size * count; 292 | 293 | if (len > 0 && buff != NULL) { 294 | JanetBuffer *jbuff = janet_buffer(len); 295 | janet_buffer_push_bytes(jbuff, buff, len); 296 | Janet arg = janet_wrap_buffer(jbuff); 297 | 298 | JanetFunction *jfunc = (JanetFunction *)udata; 299 | janet_call(jfunc, 1, &arg); 300 | } 301 | 302 | return len; 303 | } 304 | 305 | static size_t funcs_read(char *buff, size_t size, size_t count, void *udata) { 306 | Janet len = janet_wrap_number(size * count); 307 | JanetFunction *jfunc = (JanetFunction *)udata; 308 | Janet jbuff = janet_call(jfunc, 1, &len); 309 | JanetByteView bytes = janet_getbytes(&jbuff, 0); 310 | if ((size_t) bytes.len > size) bytes.len = (int32_t) size; 311 | memcpy(buff, bytes.bytes, bytes.len); 312 | return (size_t) bytes.len; 313 | } 314 | 315 | static int funcs_progress(void *udata, double dltotal, double dlnow, double ultotal, double ulnow) { 316 | JanetFunction *jfunc = (JanetFunction *)udata; 317 | Janet args[4]; 318 | args[0] = janet_wrap_number(dltotal); 319 | args[1] = janet_wrap_number(dlnow); 320 | args[2] = janet_wrap_number(ultotal); 321 | args[3] = janet_wrap_number(ulnow); 322 | 323 | Janet res = janet_call(jfunc, 4, args); 324 | 325 | return janet_truthy(res); 326 | } 327 | 328 | // static size_t funcs_mime_mem_read(char *buffer, size_t size, size_t nitems, void *instream) 329 | // { 330 | // curl_mimepart *part = (curl_mimepart *) instream; 331 | // size_t sz = (size_t) part->datasize - part->state.offset; 332 | // (void) size; /* Always 1.*/ 333 | 334 | // if(sz > nitems) 335 | // sz = nitems; 336 | 337 | // if(sz) 338 | // memcpy(buffer, (char *) &part->data[part->state.offset], sz); 339 | 340 | // part->state.offset += sz; 341 | // return sz; 342 | // } 343 | 344 | // static int funcs_mime_mem_seek(void *instream, curl_off_t offset, int whence) 345 | // { 346 | // curl_mimepart *part = (curl_mimepart *) instream; 347 | 348 | // switch(whence) { 349 | // case SEEK_CUR: 350 | // offset += part->state.offset; 351 | // break; 352 | // case SEEK_END: 353 | // offset += part->datasize; 354 | // break; 355 | // } 356 | 357 | // if(offset < 0 || offset > part->datasize) 358 | // return CURL_SEEKFUNC_FAIL; 359 | 360 | // part->state.offset = (size_t) offset; 361 | // return CURL_SEEKFUNC_OK; 362 | // } 363 | 364 | // static void funcs_mime_mem_free(void *ptr) 365 | // { 366 | // Curl_safefree(((curl_mimepart *) ptr)->data); 367 | // } 368 | 369 | 370 | //============================================================================== 371 | // ██████╗ ██████╗ ████████╗██╗ ██████╗ ███╗ ██╗███████╗ 372 | // ██╔═══██╗██╔══██╗╚══██╔══╝██║██╔═══██╗████╗ ██║██╔════╝ 373 | // ██║ ██║██████╔╝ ██║ ██║██║ ██║██╔██╗ ██║███████╗ 374 | // ██║ ██║██╔═══╝ ██║ ██║██║ ██║██║╚██╗██║╚════██║ 375 | // ╚██████╔╝██║ ██║ ██║╚██████╔╝██║ ╚████║███████║ 376 | // ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝╚══════╝ 377 | //============================================================================== 378 | 379 | static struct { 380 | char name[64]; 381 | MapCurlOptionToJanetType kjm; 382 | } _key_option_type_arr[] = { 383 | {"url", {CURLOPT_URL, JANET_STRING}}, 384 | {"proxy", {CURLOPT_PROXY, JANET_STRING}}, 385 | {"user-password", {CURLOPT_USERPWD, JANET_STRING}}, 386 | {"proxy-username-password", {CURLOPT_PROXYUSERPWD, JANET_STRING}}, 387 | {"range", {CURLOPT_RANGE, JANET_STRING}}, 388 | {"referer", {CURLOPT_REFERER, JANET_STRING}}, 389 | {"ftp-port", {CURLOPT_FTPPORT, JANET_STRING}}, 390 | {"user-agent", {CURLOPT_USERAGENT, JANET_STRING}}, 391 | {"cookie", {CURLOPT_COOKIE, JANET_STRING}}, 392 | {"ssl-cert", {CURLOPT_SSLCERT, JANET_STRING}}, 393 | {"key-pass", {CURLOPT_KEYPASSWD, JANET_STRING}}, 394 | {"cookie-file", {CURLOPT_COOKIEFILE, JANET_STRING}}, 395 | {"custom-request", {CURLOPT_CUSTOMREQUEST, JANET_STRING}}, 396 | {"interface", {CURLOPT_INTERFACE, JANET_STRING}}, 397 | {"krb-level", {CURLOPT_KRBLEVEL, JANET_STRING}}, 398 | {"ca-info", {CURLOPT_CAINFO, JANET_STRING}}, 399 | {"random-file", {CURLOPT_RANDOM_FILE, JANET_STRING}}, 400 | {"egd-socket", {CURLOPT_EGDSOCKET, JANET_STRING}}, 401 | {"cookie-jar", {CURLOPT_COOKIEJAR, JANET_STRING}}, 402 | {"ssl-cipher-list", {CURLOPT_SSL_CIPHER_LIST, JANET_STRING}}, 403 | {"ssl-cert-type", {CURLOPT_SSLCERTTYPE, JANET_STRING}}, 404 | {"ssl-key", {CURLOPT_SSLKEY, JANET_STRING}}, 405 | {"ssl-key-type", {CURLOPT_SSLKEYTYPE, JANET_STRING}}, 406 | {"ssl-engine", {CURLOPT_SSLENGINE, JANET_STRING}}, 407 | {"ca-path", {CURLOPT_CAPATH, JANET_STRING}}, 408 | {"accept-encoding", {CURLOPT_ACCEPT_ENCODING, JANET_STRING}}, 409 | {"net-rc-file", {CURLOPT_NETRC_FILE, JANET_STRING}}, 410 | {"ftp-account", {CURLOPT_FTP_ACCOUNT, JANET_STRING}}, 411 | {"cookie-list", {CURLOPT_COOKIELIST, JANET_STRING}}, 412 | {"ftp-alternative-to-user", {CURLOPT_FTP_ALTERNATIVE_TO_USER, JANET_STRING}}, 413 | {"ssh-public-key-file", {CURLOPT_SSH_PUBLIC_KEYFILE, JANET_STRING}}, 414 | {"ssh-private-key-file", {CURLOPT_SSH_PRIVATE_KEYFILE, JANET_STRING}}, 415 | {"ssh-host-public-key-md5", {CURLOPT_SSH_HOST_PUBLIC_KEY_MD5, JANET_STRING}}, 416 | {"crl-file", {CURLOPT_CRLFILE, JANET_STRING}}, 417 | {"issuer-cert", {CURLOPT_ISSUERCERT, JANET_STRING}}, 418 | {"username", {CURLOPT_USERNAME, JANET_STRING}}, 419 | {"password", {CURLOPT_PASSWORD, JANET_STRING}}, 420 | {"proxy-username", {CURLOPT_PROXYUSERNAME, JANET_STRING}}, 421 | {"proxy-password", {CURLOPT_PROXYPASSWORD, JANET_STRING}}, 422 | {"no-proxy", {CURLOPT_NOPROXY, JANET_STRING}}, 423 | {"socks5-gss-api-service", {CURLOPT_SOCKS5_GSSAPI_SERVICE, JANET_STRING}}, 424 | {"ssh-known-hosts", {CURLOPT_SSH_KNOWNHOSTS, JANET_STRING}}, 425 | {"mail-from", {CURLOPT_MAIL_FROM, JANET_STRING}}, 426 | {"rtsp-session-id", {CURLOPT_RTSP_SESSION_ID, JANET_STRING}}, 427 | {"rtsp-stream-uri", {CURLOPT_RTSP_STREAM_URI, JANET_STRING}}, 428 | {"rtsp-transport", {CURLOPT_RTSP_TRANSPORT, JANET_STRING}}, 429 | {"tls-auth-username", {CURLOPT_TLSAUTH_USERNAME, JANET_STRING}}, 430 | {"tls-auth-password", {CURLOPT_TLSAUTH_PASSWORD, JANET_STRING}}, 431 | {"tls-auth-type", {CURLOPT_TLSAUTH_TYPE, JANET_STRING}}, 432 | {"dns-servers", {CURLOPT_DNS_SERVERS, JANET_STRING}}, 433 | {"mail-auth", {CURLOPT_MAIL_AUTH, JANET_STRING}}, 434 | {"xoauth2-bearer", {CURLOPT_XOAUTH2_BEARER, JANET_STRING}}, 435 | {"dns-interface", {CURLOPT_DNS_INTERFACE, JANET_STRING}}, 436 | {"dns-local-ip4", {CURLOPT_DNS_LOCAL_IP4, JANET_STRING}}, 437 | {"dns-local-ip6", {CURLOPT_DNS_LOCAL_IP6, JANET_STRING}}, 438 | {"login-options", {CURLOPT_LOGIN_OPTIONS, JANET_STRING}}, 439 | {"pinned-public-key", {CURLOPT_PINNEDPUBLICKEY, JANET_STRING}}, 440 | {"unix-socket-path", {CURLOPT_UNIX_SOCKET_PATH, JANET_STRING}}, 441 | {"proxy-service-name", {CURLOPT_PROXY_SERVICE_NAME, JANET_STRING}}, 442 | {"service-name", {CURLOPT_SERVICE_NAME, JANET_STRING}}, 443 | {"default-protocol", {CURLOPT_DEFAULT_PROTOCOL, JANET_STRING}}, 444 | {"proxy-ca-info", {CURLOPT_PROXY_CAINFO, JANET_STRING}}, 445 | {"proxy-ca-path", {CURLOPT_PROXY_CAPATH, JANET_STRING}}, 446 | {"proxy-tls-auth-username", {CURLOPT_PROXY_TLSAUTH_USERNAME, JANET_STRING}}, 447 | {"proxy-tls-auth-password", {CURLOPT_PROXY_TLSAUTH_PASSWORD, JANET_STRING}}, 448 | {"proxy-tls-auth-type", {CURLOPT_PROXY_TLSAUTH_TYPE, JANET_STRING}}, 449 | {"proxy-ssl-cert", {CURLOPT_PROXY_SSLCERT, JANET_STRING}}, 450 | {"proxy-ssl-cert-type", {CURLOPT_PROXY_SSLCERTTYPE, JANET_STRING}}, 451 | {"proxy-ssl-key", {CURLOPT_PROXY_SSLKEY, JANET_STRING}}, 452 | {"proxy-ssl-key-type", {CURLOPT_PROXY_SSLKEYTYPE, JANET_STRING}}, 453 | {"proxy-key-password", {CURLOPT_PROXY_KEYPASSWD, JANET_STRING}}, 454 | {"proxy-ssl-cipher-list", {CURLOPT_PROXY_SSL_CIPHER_LIST, JANET_STRING}}, 455 | {"proxy-crl-file", {CURLOPT_PROXY_CRLFILE, JANET_STRING}}, 456 | {"pre-proxy", {CURLOPT_PRE_PROXY, JANET_STRING}}, 457 | {"proxy-pinned-public-key", {CURLOPT_PROXY_PINNEDPUBLICKEY, JANET_STRING}}, 458 | {"abstract-unix-socket", {CURLOPT_ABSTRACT_UNIX_SOCKET, JANET_STRING}}, 459 | {"request-target", {CURLOPT_REQUEST_TARGET, JANET_STRING}}, 460 | {"tls13-ciphers", {CURLOPT_TLS13_CIPHERS, JANET_STRING}}, 461 | {"proxy-tls13-ciphers", {CURLOPT_PROXY_TLS13_CIPHERS, JANET_STRING}}, 462 | {"doh-url", {CURLOPT_DOH_URL, JANET_STRING}}, 463 | {"aws-sigv4", {CURLOPT_AWS_SIGV4, JANET_STRING}}, 464 | {"copy-post-fields", {CURLOPT_COPYPOSTFIELDS, JANET_STRING}}, 465 | 466 | {"verbose?", {CURLOPT_VERBOSE, JANET_BOOLEAN}}, 467 | {"header?", {CURLOPT_HEADER, JANET_BOOLEAN}}, 468 | {"no-progress?", {CURLOPT_NOPROGRESS, JANET_BOOLEAN}}, 469 | {"no-body?", {CURLOPT_NOBODY, JANET_BOOLEAN}}, 470 | {"fail-on-error?", {CURLOPT_FAILONERROR, JANET_BOOLEAN}}, 471 | {"upload?", {CURLOPT_UPLOAD, JANET_BOOLEAN}}, 472 | {"post?", {CURLOPT_POST, JANET_BOOLEAN}}, 473 | {"dir-list-only?", {CURLOPT_DIRLISTONLY, JANET_BOOLEAN}}, 474 | {"append?", {CURLOPT_APPEND, JANET_BOOLEAN}}, 475 | {"follow-location?", {CURLOPT_FOLLOWLOCATION, JANET_BOOLEAN}}, 476 | {"transfer-text?", {CURLOPT_TRANSFERTEXT, JANET_BOOLEAN}}, 477 | {"put?", {CURLOPT_PUT, JANET_BOOLEAN}}, 478 | {"auto-referer?", {CURLOPT_AUTOREFERER, JANET_BOOLEAN}}, 479 | {"http-proxy-tunnel?", {CURLOPT_HTTPPROXYTUNNEL, JANET_BOOLEAN}}, 480 | {"ssl-verify-peer?", {CURLOPT_SSL_VERIFYPEER, JANET_BOOLEAN}}, 481 | {"file-time?", {CURLOPT_FILETIME, JANET_BOOLEAN}}, 482 | {"fresh-connect?", {CURLOPT_FRESH_CONNECT, JANET_BOOLEAN}}, 483 | {"forbid-reuse?", {CURLOPT_FORBID_REUSE, JANET_BOOLEAN}}, 484 | {"http-get?", {CURLOPT_HTTPGET, JANET_BOOLEAN}}, 485 | {"ftp-use-epsv?", {CURLOPT_FTP_USE_EPSV, JANET_BOOLEAN}}, 486 | {"ssl-engine-default?", {CURLOPT_SSLENGINE_DEFAULT, JANET_BOOLEAN}}, 487 | {"dns-use-global-cache?", {CURLOPT_DNS_USE_GLOBAL_CACHE, JANET_BOOLEAN}}, 488 | {"cookie-session?", {CURLOPT_COOKIESESSION, JANET_BOOLEAN}}, 489 | {"no-signal?", {CURLOPT_NOSIGNAL, JANET_BOOLEAN}}, 490 | {"unrestricted-auth?", {CURLOPT_UNRESTRICTED_AUTH, JANET_BOOLEAN}}, 491 | {"ftp-use-eprt?", {CURLOPT_FTP_USE_EPRT, JANET_BOOLEAN}}, 492 | {"tcp-no-delay?", {CURLOPT_TCP_NODELAY, JANET_BOOLEAN}}, 493 | {"ignore-content-length?", {CURLOPT_IGNORE_CONTENT_LENGTH, JANET_BOOLEAN}}, 494 | {"ftp-skip-pasv-ip?", {CURLOPT_FTP_SKIP_PASV_IP, JANET_BOOLEAN}}, 495 | {"connect-only?", {CURLOPT_CONNECT_ONLY, JANET_BOOLEAN}}, 496 | {"ssl-sessionid-cache?", {CURLOPT_SSL_SESSIONID_CACHE, JANET_BOOLEAN}}, 497 | {"http-transfer-decoding?", {CURLOPT_HTTP_TRANSFER_DECODING, JANET_BOOLEAN}}, 498 | {"http-content-decoding?", {CURLOPT_HTTP_CONTENT_DECODING, JANET_BOOLEAN}}, 499 | {"proxy-transfer-mode?", {CURLOPT_PROXY_TRANSFER_MODE, JANET_BOOLEAN}}, 500 | {"cert-info?", {CURLOPT_CERTINFO, JANET_BOOLEAN}}, 501 | {"socks5-gss-api-nec?", {CURLOPT_SOCKS5_GSSAPI_NEC, JANET_BOOLEAN}}, 502 | {"ftp-use-pret?", {CURLOPT_FTP_USE_PRET, JANET_BOOLEAN}}, 503 | {"wildcard-match?", {CURLOPT_WILDCARDMATCH, JANET_BOOLEAN}}, 504 | {"transfer-encoding?", {CURLOPT_TRANSFER_ENCODING, JANET_BOOLEAN}}, 505 | {"sasl-ir?", {CURLOPT_SASL_IR, JANET_BOOLEAN}}, 506 | {"ssl-enable-npn?", {CURLOPT_SSL_ENABLE_NPN, JANET_BOOLEAN}}, 507 | {"ssl-enable-alpn?", {CURLOPT_SSL_ENABLE_ALPN, JANET_BOOLEAN}}, 508 | {"ssl-verify-status?", {CURLOPT_SSL_VERIFYSTATUS, JANET_BOOLEAN}}, 509 | {"ssl-false-start?", {CURLOPT_SSL_FALSESTART, JANET_BOOLEAN}}, 510 | {"path-as-is?", {CURLOPT_PATH_AS_IS, JANET_BOOLEAN}}, 511 | {"pipe-wait?", {CURLOPT_PIPEWAIT, JANET_BOOLEAN}}, 512 | {"tftp-no-options?", {CURLOPT_TFTP_NO_OPTIONS, JANET_BOOLEAN}}, 513 | {"tcp-fastopen?", {CURLOPT_TCP_FASTOPEN, JANET_BOOLEAN}}, 514 | {"keep-sending-on-error?", {CURLOPT_KEEP_SENDING_ON_ERROR, JANET_BOOLEAN}}, 515 | {"proxy-ssl-verify-peer?", {CURLOPT_PROXY_SSL_VERIFYPEER, JANET_BOOLEAN}}, 516 | {"suppress-connect-headers?", {CURLOPT_SUPPRESS_CONNECT_HEADERS, JANET_BOOLEAN}}, 517 | {"ssh-compression?", {CURLOPT_SSH_COMPRESSION, JANET_BOOLEAN}}, 518 | {"ha-proxy-protocol?", {CURLOPT_HAPROXYPROTOCOL, JANET_BOOLEAN}}, 519 | {"dns-shuffle-addresses?", {CURLOPT_DNS_SHUFFLE_ADDRESSES, JANET_BOOLEAN}}, 520 | {"disallow-username-in-url?", {CURLOPT_DISALLOW_USERNAME_IN_URL, JANET_BOOLEAN}}, 521 | {"http09-allowed?", {CURLOPT_HTTP09_ALLOWED, JANET_BOOLEAN}}, 522 | {"ssl-verify-host?", {CURLOPT_SSL_VERIFYHOST, JANET_NUMBER}}, 523 | 524 | // ENUMS 525 | {"proxy-type", {CURLOPT_PROXYTYPE, JANET_NUMBER}}, 526 | {"ftp-create-missing-dirs", {CURLOPT_FTP_CREATE_MISSING_DIRS, JANET_NUMBER}}, 527 | {"ip-resolve", {CURLOPT_IPRESOLVE, JANET_NUMBER}}, 528 | {"use-ssl", {CURLOPT_USE_SSL, JANET_NUMBER}}, 529 | {"ftp-ssl-auth", {CURLOPT_FTPSSLAUTH, JANET_NUMBER}}, 530 | {"ftp-file-method", {CURLOPT_FTP_FILEMETHOD, JANET_NUMBER}}, 531 | {"ftp-ssl-ccc", {CURLOPT_FTP_SSL_CCC, JANET_NUMBER}}, 532 | {"rtsp-request", {CURLOPT_RTSP_REQUEST, JANET_NUMBER}}, 533 | {"gss-api-delegation", {CURLOPT_GSSAPI_DELEGATION, JANET_NUMBER}}, 534 | {"proxy-ssl-verify-host", {CURLOPT_PROXY_SSL_VERIFYHOST, JANET_NUMBER}}, 535 | {"proxy-ssl-version", {CURLOPT_PROXY_SSLVERSION, JANET_NUMBER}}, 536 | {"netrc", {CURLOPT_NETRC, JANET_NUMBER}}, 537 | 538 | // MASKS 539 | {"ssh-auth-types", {CURLOPT_SSH_AUTH_TYPES, JANET_NUMBER}}, 540 | {"post-redir", {CURLOPT_POSTREDIR, JANET_NUMBER}}, 541 | {"protocols", {CURLOPT_PROTOCOLS, JANET_NUMBER}}, 542 | {"redir-protocols", {CURLOPT_REDIR_PROTOCOLS, JANET_NUMBER}}, 543 | {"ssl-options", {CURLOPT_SSL_OPTIONS, JANET_NUMBER}}, 544 | {"header-opt", {CURLOPT_HEADEROPT, JANET_NUMBER}}, 545 | {"proxy-ssl-options", {CURLOPT_PROXY_SSL_OPTIONS, JANET_NUMBER}}, 546 | {"http-auth", {CURLOPT_HTTPAUTH, JANET_NUMBER}}, 547 | {"proxy-auth", {CURLOPT_PROXYAUTH, JANET_NUMBER}}, 548 | {"socks5-auth", {CURLOPT_SOCKS5_AUTH, JANET_NUMBER}}, 549 | 550 | {"port", {CURLOPT_PORT, JANET_NUMBER}}, 551 | {"timeout", {CURLOPT_TIMEOUT, JANET_NUMBER}}, 552 | {"infilesize", {CURLOPT_INFILESIZE, JANET_NUMBER}}, 553 | {"low-speed-limit", {CURLOPT_LOW_SPEED_LIMIT, JANET_NUMBER}}, 554 | {"low-speed-time", {CURLOPT_LOW_SPEED_TIME, JANET_NUMBER}}, 555 | {"resume-from", {CURLOPT_RESUME_FROM, JANET_NUMBER}}, 556 | {"crlf", {CURLOPT_CRLF, JANET_NUMBER}}, 557 | {"ssl-version", {CURLOPT_SSLVERSION, JANET_NUMBER}}, 558 | {"time-condition", {CURLOPT_TIMECONDITION, JANET_NUMBER}}, 559 | {"time-value", {CURLOPT_TIMEVALUE, JANET_NUMBER}}, 560 | {"proxy-port", {CURLOPT_PROXYPORT, JANET_NUMBER}}, 561 | {"post-field-size", {CURLOPT_POSTFIELDSIZE, JANET_NUMBER}}, 562 | {"post-fields", {CURLOPT_POSTFIELDS, JANET_POINTER}}, 563 | {"max-redirs", {CURLOPT_MAXREDIRS, JANET_NUMBER}}, 564 | {"max-connects", {CURLOPT_MAXCONNECTS, JANET_NUMBER}}, 565 | {"obsolete72", {CURLOPT_OBSOLETE72, JANET_NUMBER}}, 566 | {"connect-timeout", {CURLOPT_CONNECTTIMEOUT, JANET_NUMBER}}, 567 | {"http-version", {CURLOPT_HTTP_VERSION, JANET_NUMBER}}, 568 | {"dns-cache-timeout", {CURLOPT_DNS_CACHE_TIMEOUT, JANET_NUMBER}}, 569 | {"buffer-size", {CURLOPT_BUFFERSIZE, JANET_NUMBER}}, 570 | {"ftp-response-timeout", {CURLOPT_FTP_RESPONSE_TIMEOUT, JANET_NUMBER}}, 571 | {"max-filesize", {CURLOPT_MAXFILESIZE, JANET_NUMBER}}, 572 | {"local-port", {CURLOPT_LOCALPORT, JANET_NUMBER}}, 573 | {"local-portrange", {CURLOPT_LOCALPORTRANGE, JANET_NUMBER}}, 574 | {"timeout-ms", {CURLOPT_TIMEOUT_MS, JANET_NUMBER}}, 575 | {"connect-timeout-ms", {CURLOPT_CONNECTTIMEOUT_MS, JANET_NUMBER}}, 576 | {"new-file-perms", {CURLOPT_NEW_FILE_PERMS, JANET_NUMBER}}, 577 | {"new-directory-perms", {CURLOPT_NEW_DIRECTORY_PERMS, JANET_NUMBER}}, 578 | {"address-scope", {CURLOPT_ADDRESS_SCOPE, JANET_NUMBER}}, 579 | {"tftp-blk-size", {CURLOPT_TFTP_BLKSIZE, JANET_NUMBER}}, 580 | {"rtsp-client-cseq", {CURLOPT_RTSP_CLIENT_CSEQ, JANET_NUMBER}}, 581 | {"rtsp-server-cseq", {CURLOPT_RTSP_SERVER_CSEQ, JANET_NUMBER}}, 582 | {"accept-timeout-ms", {CURLOPT_ACCEPTTIMEOUT_MS, JANET_NUMBER}}, 583 | {"tcp-keep-alive", {CURLOPT_TCP_KEEPALIVE, JANET_NUMBER}}, 584 | {"tcp-keep-idle", {CURLOPT_TCP_KEEPIDLE, JANET_NUMBER}}, 585 | {"tcp-keep-intvl", {CURLOPT_TCP_KEEPINTVL, JANET_NUMBER}}, 586 | {"expect-100-timeout-ms", {CURLOPT_EXPECT_100_TIMEOUT_MS, JANET_NUMBER}}, 587 | {"stream-weight", {CURLOPT_STREAM_WEIGHT, JANET_NUMBER}}, 588 | {"happy-eyeballs-timeout-ms", {CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS, JANET_NUMBER}}, 589 | {"upload-buffer-size", {CURLOPT_UPLOAD_BUFFERSIZE, JANET_NUMBER}}, 590 | {"upkeep-interval-ms", {CURLOPT_UPKEEP_INTERVAL_MS, JANET_NUMBER}}, 591 | 592 | {"in-file-size-large", {CURLOPT_INFILESIZE_LARGE, JANET_NUMBER}}, 593 | {"resume-from-large", {CURLOPT_RESUME_FROM_LARGE, JANET_NUMBER}}, 594 | {"max-file-size-large", {CURLOPT_MAXFILESIZE_LARGE, JANET_NUMBER}}, 595 | {"post-field-size-large", {CURLOPT_POSTFIELDSIZE_LARGE, JANET_NUMBER}}, 596 | {"max-send-speed-large", {CURLOPT_MAX_SEND_SPEED_LARGE, JANET_NUMBER}}, 597 | {"max-recv-speed-large", {CURLOPT_MAX_RECV_SPEED_LARGE, JANET_NUMBER}}, 598 | {"time-value-large", {CURLOPT_TIMEVALUE_LARGE, JANET_NUMBER}}, 599 | 600 | {"write-function", {CURLOPT_WRITEFUNCTION, JANET_FUNCTION}}, 601 | {"header-function", {CURLOPT_HEADERFUNCTION, JANET_FUNCTION}}, 602 | {"read-function", {CURLOPT_READFUNCTION, JANET_FUNCTION}}, 603 | {"progress-function", {CURLOPT_PROGRESSFUNCTION, JANET_FUNCTION}}, 604 | {"debug-function#TODO", {CURLOPT_DEBUGFUNCTION, JANET_FUNCTION}}, // TODO 605 | {"ssl-ctx-function#TODO", {CURLOPT_SSL_CTX_FUNCTION, JANET_FUNCTION}}, // TODO 606 | {"ioctl-function#TODO", {CURLOPT_IOCTLFUNCTION, JANET_FUNCTION}}, // TODO 607 | {"conv-from-network-function#TODO", {CURLOPT_CONV_FROM_NETWORK_FUNCTION, JANET_FUNCTION}}, // TODO 608 | {"conv-to-network-function#TODO", {CURLOPT_CONV_TO_NETWORK_FUNCTION, JANET_FUNCTION}}, // TODO 609 | {"conv-from-utf8-function#TODO", {CURLOPT_CONV_FROM_UTF8_FUNCTION, JANET_FUNCTION}}, // TODO 610 | {"sockopt-function#TODO", {CURLOPT_SOCKOPTFUNCTION, JANET_FUNCTION}}, // TODO 611 | {"open-socket-function#TODO", {CURLOPT_OPENSOCKETFUNCTION, JANET_FUNCTION}}, // TODO 612 | {"seek-function#TODO", {CURLOPT_SEEKFUNCTION, JANET_FUNCTION}}, // TODO 613 | {"ssh-key-function#TODO", {CURLOPT_SSH_KEYFUNCTION, JANET_FUNCTION}}, // TODO 614 | {"interleave-function#TODO", {CURLOPT_INTERLEAVEFUNCTION, JANET_FUNCTION}}, // TODO 615 | {"chunk-bgn-function#TODO", {CURLOPT_CHUNK_BGN_FUNCTION, JANET_FUNCTION}}, // TODO 616 | {"chunk-end-function#TODO", {CURLOPT_CHUNK_END_FUNCTION, JANET_FUNCTION}}, // TODO 617 | {"fnmatch-function#TODO", {CURLOPT_FNMATCH_FUNCTION, JANET_FUNCTION}}, // TODO 618 | {"close-socket-function#TODO", {CURLOPT_CLOSESOCKETFUNCTION, JANET_FUNCTION}}, // TODO 619 | {"xfer-info-function#TODO", {CURLOPT_XFERINFOFUNCTION, JANET_FUNCTION}}, // TODO 620 | {"resolver-start-function#TODO", {CURLOPT_RESOLVER_START_FUNCTION, JANET_FUNCTION}}, // TODO 621 | {"trailer-function#TODO", {CURLOPT_TRAILERFUNCTION, JANET_FUNCTION}}, // TODO 622 | 623 | {"write-data", {CURLOPT_WRITEDATA, JANET_POINTER}}, 624 | {"header-data", {CURLOPT_HEADERDATA, JANET_POINTER}}, 625 | {"read-data", {CURLOPT_READDATA, JANET_POINTER}}, 626 | {"progress-data", {CURLOPT_PROGRESSDATA, JANET_POINTER}}, 627 | {"http-header", {CURLOPT_HTTPHEADER, JANET_POINTER}}, 628 | {"error-buffer@TODO", {CURLOPT_ERRORBUFFER, JANET_POINTER}}, // TODO 629 | {"http-post@TODO", {CURLOPT_HTTPPOST, JANET_POINTER}}, // TODO 630 | {"quote@TODO", {CURLOPT_QUOTE, JANET_POINTER}}, // TODO 631 | {"stderr@TODO", {CURLOPT_STDERR, JANET_POINTER}}, // TODO 632 | {"post-quote@TODO", {CURLOPT_POSTQUOTE, JANET_POINTER}}, // TODO 633 | {"obsolete40@TODO", {CURLOPT_OBSOLETE40, JANET_POINTER}}, // TODO 634 | {"telnet-options@TODO", {CURLOPT_TELNETOPTIONS, JANET_POINTER}}, // TODO 635 | {"prequote@TODO", {CURLOPT_PREQUOTE, JANET_POINTER}}, // TODO 636 | {"debug-data@TODO", {CURLOPT_DEBUGDATA, JANET_POINTER}}, // TODO 637 | {"share@TODO", {CURLOPT_SHARE, JANET_POINTER}}, // TODO 638 | {"private@TODO", {CURLOPT_PRIVATE, JANET_POINTER}}, // TODO 639 | {"http200-aliases@TODO", {CURLOPT_HTTP200ALIASES, JANET_POINTER}}, // TODO 640 | {"ssl-ctx-data@TODO", {CURLOPT_SSL_CTX_DATA, JANET_POINTER}}, // TODO 641 | {"ioctl-data@TODO", {CURLOPT_IOCTLDATA, JANET_POINTER}}, // TODO 642 | {"sockopt-data@TODO", {CURLOPT_SOCKOPTDATA, JANET_POINTER}}, // TODO 643 | {"open-socket-data@TODO", {CURLOPT_OPENSOCKETDATA, JANET_POINTER}}, // TODO 644 | {"seek-data@TODO", {CURLOPT_SEEKDATA, JANET_POINTER}}, // TODO 645 | {"ssh-key-data@TODO", {CURLOPT_SSH_KEYDATA, JANET_POINTER}}, // TODO 646 | {"mail-rcpt@TODO", {CURLOPT_MAIL_RCPT, JANET_POINTER}}, // TODO 647 | {"interleave-data@TODO", {CURLOPT_INTERLEAVEDATA, JANET_POINTER}}, // TODO 648 | {"chunk-data@TODO", {CURLOPT_CHUNK_DATA, JANET_POINTER}}, // TODO 649 | {"fnmatch-data@TODO", {CURLOPT_FNMATCH_DATA, JANET_POINTER}}, // TODO 650 | {"resolve@TODO", {CURLOPT_RESOLVE, JANET_POINTER}}, // TODO 651 | {"close-socket-data@TODO", {CURLOPT_CLOSESOCKETDATA, JANET_POINTER}}, // TODO 652 | {"proxy-header@TODO", {CURLOPT_PROXYHEADER, JANET_POINTER}}, // TODO 653 | {"stream-depends@TODO", {CURLOPT_STREAM_DEPENDS, JANET_POINTER}}, // TODO 654 | {"stream-depends-e@TODO", {CURLOPT_STREAM_DEPENDS_E, JANET_POINTER}}, // TODO 655 | {"connect-to@TODO", {CURLOPT_CONNECT_TO, JANET_POINTER}}, // TODO 656 | {"mimepost@TODO", {CURLOPT_MIMEPOST, JANET_POINTER}}, // TODO 657 | {"resolver-start-data@TODO", {CURLOPT_RESOLVER_START_DATA, JANET_POINTER}}, // TODO 658 | {"curlu@TODO", {CURLOPT_CURLU, JANET_POINTER}}, // TODO 659 | {"trailer-data@TODO", {CURLOPT_TRAILERDATA, JANET_POINTER}}, // TODO 660 | }; 661 | 662 | static void options_gen_dict(void) { 663 | int32_t size = sizeof(_key_option_type_arr) / sizeof(_key_option_type_arr[0]); 664 | 665 | if (NULL == hashmap_opt_to_type) { 666 | hashmap_opt_to_type = kh_init(HashMapCurlOptionToJanetType); 667 | } 668 | 669 | int absent; 670 | khint_t where; 671 | for (int32_t idx = 0; idx < size; idx++) { 672 | where = kh_put(HashMapCurlOptionToJanetType, hashmap_opt_to_type, _key_option_type_arr[idx].name, &absent); 673 | kh_value(hashmap_opt_to_type, where) = &_key_option_type_arr[idx].kjm; 674 | } 675 | } 676 | 677 | static const MapCurlOptionToJanetType *options_get(const char *key) { 678 | MapCurlOptionToJanetType *val; 679 | khint_t where = kh_get(HashMapCurlOptionToJanetType, hashmap_opt_to_type, key); 680 | val = kh_val(hashmap_opt_to_type, where); 681 | return val; 682 | } 683 | 684 | static struct curl_slist *fill_list_from_tuple(Janet tuple) { 685 | const JanetTupleHead *t = janet_tuple_head(janet_unwrap_tuple(tuple)); 686 | if (t->length <= 0) { 687 | janet_panic("input list cannot be empty"); 688 | } 689 | 690 | const char *str1 = (const char *) janet_unwrap_string(t->data[0]); 691 | struct curl_slist *list = curl_slist_append(NULL, str1); 692 | 693 | for (int32_t idx = 1; idx < t->length; idx++) { 694 | const char *str = (const char *) janet_unwrap_string(t->data[idx]); 695 | list = curl_slist_append(list, str); 696 | } 697 | 698 | return list; 699 | } 700 | 701 | static struct curl_slist *fill_list_from_array(Janet array) { 702 | const JanetArray *a = janet_unwrap_array(array); 703 | if (a->count <= 0) { 704 | janet_panic("input list cannot be empty"); 705 | } 706 | 707 | const char *str1 = (const char *) janet_unwrap_string(a->data[0]); 708 | struct curl_slist *list = curl_slist_append(NULL, str1); 709 | 710 | for (int32_t idx = 1; idx < a->count; idx++) { 711 | const char *str = (const char *) janet_unwrap_string(a->data[idx]); 712 | list = curl_slist_append(list, str); 713 | } 714 | 715 | return list; 716 | } 717 | 718 | static void options_set(Curl *c, Janet *key, Janet *val) { 719 | const char *keyword = (const char *) janet_unwrap_keyword(*key); 720 | const MapCurlOptionToJanetType *map = options_get(keyword); 721 | CURL *curl = c->curl; 722 | if (NULL == map) { 723 | janet_panic("invalid keyword"); 724 | } 725 | 726 | int type = map->type; 727 | int opt = map->option; 728 | JanetFunction *fn; 729 | 730 | switch (type) { 731 | case JANET_NUMBER: 732 | if (!janet_checkint(*val)) janet_panicf("expected integer, got %v", *val); 733 | curl_easy_setopt(curl, opt, janet_unwrap_integer(*val)); 734 | break; 735 | case JANET_BOOLEAN: 736 | curl_easy_setopt(curl, opt, janet_unwrap_boolean(*val)); 737 | break; 738 | case JANET_STRING: 739 | curl_easy_setopt(curl, opt, janet_unwrap_string(*val)); 740 | break; 741 | case JANET_FUNCTION: 742 | fn = janet_unwrap_function(*val); 743 | if (0 == strcmp(keyword, "write-function")) { 744 | curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)fn); 745 | curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, funcs_write); 746 | c->write_function = fn; 747 | } else if (0 == strcmp(keyword, "header-function")) { 748 | curl_easy_setopt(curl, CURLOPT_HEADERDATA, (void *)fn); 749 | curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, funcs_write); 750 | c->header_function = fn; 751 | } else if (0 == strcmp(keyword, "read-function")) { 752 | curl_easy_setopt(curl, CURLOPT_READDATA, (void *)fn); 753 | curl_easy_setopt(curl, CURLOPT_READFUNCTION, funcs_read); 754 | c->read_function = fn; 755 | } else if (0 == strcmp(keyword, "progress-function")) { 756 | curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, (void *)fn); 757 | curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, funcs_progress); 758 | c->progress_function = fn; 759 | } 760 | 761 | break; 762 | case JANET_POINTER: 763 | if (0 == strcmp(keyword, "http-header")) { 764 | struct curl_slist *list; 765 | if (janet_checktype(*val, JANET_TUPLE) != 0) { 766 | list = fill_list_from_tuple(*val); 767 | } else if (janet_checktype(*val, JANET_ARRAY) != 0) { 768 | list = fill_list_from_array(*val); 769 | } else { 770 | janet_panic("header must be an array or a tuple"); 771 | } 772 | 773 | curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); 774 | } else { 775 | janet_panic("not implemented yet"); 776 | } 777 | // TODO: 778 | break; 779 | default: 780 | janet_panic("value type is not supported"); 781 | break; 782 | }; 783 | } 784 | 785 | //============================================================================== 786 | // ██╗███╗ ██╗███████╗ ██████╗ 787 | // ██║████╗ ██║██╔════╝██╔═══██╗ 788 | // ██║██╔██╗ ██║█████╗ ██║ ██║ 789 | // ██║██║╚██╗██║██╔══╝ ██║ ██║ 790 | // ██║██║ ╚████║██║ ╚██████╔╝ 791 | // ╚═╝╚═╝ ╚═══╝╚═╝ ╚═════╝ 792 | //============================================================================== 793 | 794 | static struct { 795 | char name[64]; 796 | MapCurlInfoToJanetType ijm; 797 | } _key_info_type_arr[] = { 798 | {"query-effective-url", {CURLINFO_EFFECTIVE_URL, JANET_STRING}}, 799 | {"query-content-type", {CURLINFO_CONTENT_TYPE, JANET_STRING}}, 800 | {"query-private", {CURLINFO_PRIVATE, JANET_STRING}}, 801 | {"query-ftp-entry-path", {CURLINFO_FTP_ENTRY_PATH, JANET_STRING}}, 802 | {"query-redirect-url", {CURLINFO_REDIRECT_URL, JANET_STRING}}, 803 | {"query-primary-ip", {CURLINFO_PRIMARY_IP, JANET_STRING}}, 804 | {"query-rtsp-session-id", {CURLINFO_RTSP_SESSION_ID, JANET_STRING}}, 805 | {"query-local-ip", {CURLINFO_LOCAL_IP, JANET_STRING}}, 806 | {"query-scheme", {CURLINFO_SCHEME, JANET_STRING}}, 807 | 808 | {"query-response-code", {CURLINFO_RESPONSE_CODE, JANET_NUMBER}}, 809 | {"query-total-time", {CURLINFO_TOTAL_TIME, JANET_NUMBER}}, 810 | {"query-name-lookup-time", {CURLINFO_NAMELOOKUP_TIME, JANET_NUMBER}}, 811 | {"query-connect-time", {CURLINFO_CONNECT_TIME, JANET_NUMBER}}, 812 | {"query-pre-transfer-time", {CURLINFO_PRETRANSFER_TIME, JANET_NUMBER}}, 813 | {"query-size-upload", {CURLINFO_SIZE_UPLOAD, JANET_NUMBER}}, 814 | {"query-size-upload-t", {CURLINFO_SIZE_UPLOAD_T, JANET_NUMBER}}, 815 | {"query-size-download", {CURLINFO_SIZE_DOWNLOAD, JANET_NUMBER}}, 816 | {"query-size-download-t", {CURLINFO_SIZE_DOWNLOAD_T, JANET_NUMBER}}, 817 | {"query-speed-download", {CURLINFO_SPEED_DOWNLOAD, JANET_NUMBER}}, 818 | {"query-speed-download-t", {CURLINFO_SPEED_DOWNLOAD_T, JANET_NUMBER}}, 819 | {"query-speed-upload", {CURLINFO_SPEED_UPLOAD, JANET_NUMBER}}, 820 | {"query-speed-upload-t", {CURLINFO_SPEED_UPLOAD_T, JANET_NUMBER}}, 821 | {"query-header-size", {CURLINFO_HEADER_SIZE, JANET_NUMBER}}, 822 | {"query-request-size", {CURLINFO_REQUEST_SIZE, JANET_NUMBER}}, 823 | {"query-ssl-verify-result", {CURLINFO_SSL_VERIFYRESULT, JANET_NUMBER}}, 824 | {"query-file-time", {CURLINFO_FILETIME, JANET_NUMBER}}, 825 | {"query-file-time-t", {CURLINFO_FILETIME_T, JANET_NUMBER}}, 826 | {"query-content-length-download", {CURLINFO_CONTENT_LENGTH_DOWNLOAD, JANET_NUMBER}}, 827 | {"query-content-length-download-t", {CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, JANET_NUMBER}}, 828 | {"query-content-length-upload", {CURLINFO_CONTENT_LENGTH_UPLOAD, JANET_NUMBER}}, 829 | {"query-content-length-upload-t", {CURLINFO_CONTENT_LENGTH_UPLOAD_T, JANET_NUMBER}}, 830 | {"query-start-transfer-time", {CURLINFO_STARTTRANSFER_TIME, JANET_NUMBER}}, 831 | {"query-redirect-time", {CURLINFO_REDIRECT_TIME, JANET_NUMBER}}, 832 | {"query-redirect-count", {CURLINFO_REDIRECT_COUNT, JANET_NUMBER}}, 833 | {"query-http-connect-code", {CURLINFO_HTTP_CONNECTCODE, JANET_NUMBER}}, 834 | {"query-http-auth-avail", {CURLINFO_HTTPAUTH_AVAIL, JANET_NUMBER}}, 835 | {"query-proxy-auth-avail", {CURLINFO_PROXYAUTH_AVAIL, JANET_NUMBER}}, 836 | {"query-os-errno", {CURLINFO_OS_ERRNO, JANET_NUMBER}}, 837 | {"query-num-connects", {CURLINFO_NUM_CONNECTS, JANET_NUMBER}}, 838 | {"query-last-socket", {CURLINFO_LASTSOCKET, JANET_NUMBER}}, 839 | {"query-app-connect-time", {CURLINFO_APPCONNECT_TIME, JANET_NUMBER}}, 840 | {"query-condition-unmet", {CURLINFO_CONDITION_UNMET, JANET_NUMBER}}, 841 | {"query-rtsp-client-cseq", {CURLINFO_RTSP_CLIENT_CSEQ, JANET_NUMBER}}, 842 | {"query-rtsp-server-cseq", {CURLINFO_RTSP_SERVER_CSEQ, JANET_NUMBER}}, 843 | {"query-rtsp-cseq-recv", {CURLINFO_RTSP_CSEQ_RECV, JANET_NUMBER}}, 844 | {"query-primary-port", {CURLINFO_PRIMARY_PORT, JANET_NUMBER}}, 845 | {"query-local-port", {CURLINFO_LOCAL_PORT, JANET_NUMBER}}, 846 | {"query-http-version", {CURLINFO_HTTP_VERSION, JANET_NUMBER}}, 847 | {"query-proxy-ssl-verify-result", {CURLINFO_PROXY_SSL_VERIFYRESULT, JANET_NUMBER}}, 848 | {"query-protocol", {CURLINFO_PROTOCOL, JANET_NUMBER}}, 849 | {"query-total-time-t", {CURLINFO_TOTAL_TIME_T, JANET_NUMBER}}, 850 | {"query-name-lookup-time-t", {CURLINFO_NAMELOOKUP_TIME_T, JANET_NUMBER}}, 851 | {"query-connect-time-t", {CURLINFO_CONNECT_TIME_T, JANET_NUMBER}}, 852 | {"query-pre-transfer-time-t", {CURLINFO_PRETRANSFER_TIME_T, JANET_NUMBER}}, 853 | {"query-start-transfer-time-t", {CURLINFO_STARTTRANSFER_TIME_T, JANET_NUMBER}}, 854 | {"query-redirect-time-t", {CURLINFO_REDIRECT_TIME_T, JANET_NUMBER}}, 855 | {"query-app-connect-time-t", {CURLINFO_APPCONNECT_TIME_T, JANET_NUMBER}}, 856 | 857 | {"query-ssl-engines", {CURLINFO_SSL_ENGINES, JANET_POINTER}}, // TODO: 858 | {"query-cookie-list", {CURLINFO_COOKIELIST, JANET_POINTER}}, // TODO: 859 | {"query-cert-info", {CURLINFO_CERTINFO, JANET_POINTER}}, // TODO: 860 | {"query-tls-session", {CURLINFO_TLS_SESSION, JANET_POINTER}}, // TODO: 861 | {"query-active-socket", {CURLINFO_ACTIVESOCKET, JANET_POINTER}}, // TODOL 862 | {"query-tls-ssl-ptr", {CURLINFO_TLS_SSL_PTR, JANET_POINTER}}, // TODO: 863 | }; 864 | 865 | static void info_gen_dict(void) { 866 | int32_t size = sizeof(_key_info_type_arr) / sizeof(_key_info_type_arr[0]); 867 | 868 | if (NULL == hashmap_info_to_type) { 869 | hashmap_info_to_type = kh_init(HashMapCurlInfoToJanetType); 870 | } 871 | 872 | int absent; 873 | khint_t where; 874 | for (int32_t idx = 0; idx < size; idx++) { 875 | where = kh_put(HashMapCurlInfoToJanetType, hashmap_info_to_type, _key_info_type_arr[idx].name, &absent); 876 | kh_value(hashmap_info_to_type, where) = &_key_info_type_arr[idx].ijm; 877 | } 878 | } 879 | 880 | static const MapCurlInfoToJanetType *info_get(const char *key) { 881 | MapCurlInfoToJanetType *val; 882 | khint_t where = kh_get(HashMapCurlInfoToJanetType, hashmap_info_to_type, key); 883 | val = kh_val(hashmap_info_to_type, where); 884 | return val; 885 | } 886 | 887 | static Janet info_query(CURL *curl, Janet *key) { 888 | const char *keyword = (const char *) janet_unwrap_keyword(*key); 889 | const MapCurlInfoToJanetType *map = info_get(keyword); 890 | if (NULL == map) { 891 | janet_panic("invalid keyword"); 892 | } 893 | 894 | int type = map->type; 895 | int info = map->info; 896 | 897 | int32_t res_number; 898 | const char *res_string; 899 | 900 | switch (type) { 901 | case JANET_NUMBER: 902 | if (CURLE_OK == curl_easy_getinfo(curl, info, &res_number)) { 903 | return janet_wrap_integer(res_number); 904 | } 905 | break; 906 | case JANET_STRING: 907 | if (CURLE_OK == curl_easy_getinfo(curl, info, &res_string)) { 908 | return janet_wrap_string((const char *)res_string); 909 | } 910 | break; 911 | default: 912 | janet_panic("value type is not supported"); 913 | break; 914 | }; 915 | 916 | return janet_wrap_false(); 917 | } 918 | 919 | //============================================================================== 920 | // ███████╗ █████╗ ███████╗██╗ ██╗ 921 | // ██╔════╝██╔══██╗██╔════╝╚██╗ ██╔╝ 922 | // █████╗ ███████║███████╗ ╚████╔╝ 923 | // ██╔══╝ ██╔══██║╚════██║ ╚██╔╝ 924 | // ███████╗██║ ██║███████║ ██║ 925 | // ╚══════╝╚═╝ ╚═╝╚══════╝ ╚═╝ 926 | //============================================================================== 927 | 928 | static Janet easy_init(int32_t argc, Janet *argv) { 929 | janet_fixarity(argc, 0); 930 | (void)argv; 931 | 932 | CURL *curl = curl_easy_init(); 933 | return curl ? curl_make(curl) : janet_wrap_nil(); 934 | } 935 | 936 | static Janet easy_clone(int32_t argc, Janet *argv) { 937 | janet_fixarity(argc, 1); 938 | 939 | Curl *curl = janet_getabstract(argv, 0, &curl_obj); 940 | CURL *clone = curl_easy_duphandle(curl->curl); 941 | 942 | return clone ? curl_make(clone) : janet_wrap_nil(); 943 | } 944 | 945 | static Janet easy_escape(int32_t argc, Janet *argv) { 946 | janet_fixarity(argc, 2); 947 | 948 | Curl *curl = janet_getabstract(argv, 0, &curl_obj); 949 | const char *iurl = janet_getcstring(argv, 1); 950 | if (NULL == iurl) { 951 | janet_panic("input url string is invalid or null"); 952 | } 953 | 954 | int len = strlen(iurl); 955 | if (0 >= len) { 956 | janet_panic("input url cannot be empty"); 957 | } 958 | 959 | char *ourl = curl_easy_escape(curl->curl, iurl, len); 960 | if (NULL == ourl) { 961 | curl_free(ourl); 962 | return janet_wrap_false(); 963 | } 964 | 965 | Janet res = janet_cstringv(ourl); 966 | curl_free(ourl); 967 | 968 | return res; 969 | } 970 | 971 | static Janet easy_unescape(int32_t argc, Janet *argv) { 972 | janet_fixarity(argc, 2); 973 | 974 | Curl *curl = janet_getabstract(argv, 0, &curl_obj); 975 | const char *iurl = janet_getcstring(argv, 1); 976 | if (NULL == iurl) { 977 | janet_panic("input url string is invalid or null"); 978 | } 979 | 980 | int ilen = strlen(iurl); 981 | if (0 >= ilen) { 982 | janet_panic("input url cannot be empty"); 983 | } 984 | 985 | int olen = 0; 986 | 987 | char *ourl = curl_easy_unescape(curl->curl, iurl, ilen, &olen); 988 | if (NULL == ourl || 0 >= olen) { 989 | return janet_wrap_false(); 990 | } 991 | 992 | Janet res = janet_cstringv(ourl); 993 | curl_free(ourl); 994 | 995 | return res; 996 | } 997 | 998 | static Janet easy_strerror(int32_t argc, Janet *argv) { 999 | janet_fixarity(argc, 1); 1000 | 1001 | int code = janet_getinteger(argv, 0); 1002 | 1003 | const char *errstr = curl_easy_strerror(code); 1004 | Janet res = janet_cstringv(errstr); 1005 | 1006 | return res; 1007 | } 1008 | 1009 | static Janet easy_setopt(int32_t argc, Janet *argv) { 1010 | janet_arity(argc, 2, -1); 1011 | 1012 | if ((argc - 1) % 2 != 0) { 1013 | janet_panic("options count must be even, options are regarded as tuple"); 1014 | } 1015 | 1016 | Curl *curl = janet_getabstract(argv, 0, &curl_obj); 1017 | 1018 | for (int32_t idx = 1; idx < argc; idx += 2) { 1019 | options_set(curl, argv + idx, argv + idx + 1); 1020 | } 1021 | 1022 | return janet_wrap_true(); 1023 | } 1024 | 1025 | static Janet easy_pause(int32_t argc, Janet *argv) { 1026 | janet_fixarity(argc, 2); 1027 | 1028 | Curl *curl = janet_getabstract(argv, 0, &curl_obj); 1029 | const char *modestr = (const char *) janet_getkeyword(argv, 1); 1030 | 1031 | int mode = -1; 1032 | if (0 == strcmp(modestr, "pause-mode-recv")) { 1033 | mode = CURLPAUSE_RECV; 1034 | } else if (0 == strcmp(modestr, "pause-mode-send")) { 1035 | mode = CURLPAUSE_SEND; 1036 | } else if (0 == strcmp(modestr, "paus-modee-all")) { 1037 | mode = CURLPAUSE_ALL; 1038 | } else if (0 == strcmp(modestr, "pause-mode-cont")) { 1039 | mode = CURLPAUSE_CONT; 1040 | } else { 1041 | janet_panic("invalid pause mode"); 1042 | } 1043 | 1044 | curl_easy_pause(curl->curl, mode); 1045 | return janet_wrap_true(); 1046 | } 1047 | 1048 | static Janet easy_reset(int32_t argc, Janet *argv) { 1049 | janet_fixarity(argc, 1); 1050 | 1051 | Curl *curl = janet_getabstract(argv, 0, &curl_obj); 1052 | 1053 | curl_easy_reset(curl->curl); 1054 | return janet_wrap_nil(); 1055 | } 1056 | 1057 | static Janet easy_upkeep(int32_t argc, Janet *argv) { 1058 | janet_fixarity(argc, 1); 1059 | 1060 | Curl *curl = janet_getabstract(argv, 0, &curl_obj); 1061 | 1062 | curl_easy_upkeep(curl->curl); 1063 | return janet_wrap_nil(); 1064 | } 1065 | 1066 | static Janet easy_recv(int32_t argc, Janet *argv) { 1067 | janet_arity(argc, 1, 2); 1068 | 1069 | Curl *curl = janet_getabstract(argv, 0, &curl_obj); 1070 | 1071 | size_t buflen = DEFAULT_EASY_RECV_BUF_LEN; 1072 | size_t recvlen = -1; 1073 | if (argc == 2) { 1074 | buflen = janet_getinteger(argv, 1); 1075 | } 1076 | 1077 | char *buffer = (char *) calloc(buflen, sizeof(char)); 1078 | int res = curl_easy_recv(curl->curl, buffer, buflen, &recvlen); 1079 | JanetBuffer *jbuff = janet_buffer(buflen); 1080 | janet_buffer_push_bytes(jbuff, (const uint8_t *)buffer, buflen); 1081 | free(buffer); 1082 | 1083 | // TODO: i am not satisfied with this function 1084 | 1085 | if (0 == recvlen) { 1086 | return janet_ckeywordv("closed"); 1087 | } 1088 | 1089 | switch (res) { 1090 | case CURLE_OK: 1091 | return janet_wrap_buffer(jbuff); 1092 | break; 1093 | case CURLE_AGAIN: 1094 | return janet_ckeywordv("more"); 1095 | break; 1096 | case CURLE_UNSUPPORTED_PROTOCOL: 1097 | return janet_ckeywordv("unsopported"); 1098 | break; 1099 | default: 1100 | return janet_wrap_false(); 1101 | } 1102 | } 1103 | 1104 | static Janet easy_send(int32_t argc, Janet *argv) { 1105 | janet_fixarity(argc, 2); 1106 | 1107 | Curl *curl = janet_getabstract(argv, 0, &curl_obj); 1108 | 1109 | size_t sendlen = -1; 1110 | JanetByteView buffer = janet_getbytes(argv, 1); 1111 | 1112 | int res = curl_easy_send(curl->curl, buffer.bytes, buffer.len, &sendlen); 1113 | 1114 | switch (res) { 1115 | case CURLE_OK: 1116 | return janet_wrap_true(); 1117 | break; 1118 | case CURLE_AGAIN: 1119 | return janet_ckeywordv("more"); 1120 | break; 1121 | case CURLE_UNSUPPORTED_PROTOCOL: 1122 | return janet_ckeywordv("unsopported"); 1123 | break; 1124 | default: 1125 | return janet_wrap_false(); 1126 | } 1127 | } 1128 | 1129 | static Janet easy_perform(int32_t argc, Janet *argv) { 1130 | janet_fixarity(argc, 1); 1131 | 1132 | Curl *curl = janet_getabstract(argv, 0, &curl_obj); 1133 | 1134 | CURLcode res; 1135 | res = curl_easy_perform(curl->curl); 1136 | return janet_wrap_integer(res); 1137 | } 1138 | 1139 | static Janet easy_query(int32_t argc, Janet *argv) { 1140 | janet_fixarity(argc, 2); 1141 | 1142 | Curl *curl = janet_getabstract(argv, 0, &curl_obj); 1143 | 1144 | return info_query(curl->curl, argv + 1); 1145 | } 1146 | 1147 | static const JanetReg curl_easy_cfuns[] = { 1148 | { 1149 | "easy/init", easy_init, 1150 | "(def curl (easy/init)) \n\n" 1151 | "create a new curl handler" 1152 | }, 1153 | { 1154 | "easy/clone", easy_clone, 1155 | "(easy/clone curl) \n\n" 1156 | "clones a libcurl session handle" 1157 | }, 1158 | { 1159 | "easy/escape", easy_escape, 1160 | "(easy/escape curl \"https://janet-lang.org\") \n\n" 1161 | "encode the input string as an url escaped string" 1162 | }, 1163 | { 1164 | "easy/unescape", easy_unescape, 1165 | "(easy/unescape curl \"https\%3A\%2F\%2Fjanet-lang.org\") \n\n" 1166 | "decode the input url string as an unescape string" 1167 | }, 1168 | { 1169 | "easy/strerror", easy_strerror, 1170 | "(easy/strerror code) \n\n" 1171 | "return error string of an error code" 1172 | }, 1173 | { 1174 | "easy/setopt", easy_setopt, 1175 | "(easy/setopt code :url \"https://janet-lang.org\") \n\n" 1176 | "set options for a curl easy handle" 1177 | }, 1178 | { 1179 | "easy/pause", easy_pause, 1180 | "(easy/pause curl :pause_mode_all) \n\n" 1181 | "pause and unpause a connection" 1182 | }, 1183 | { 1184 | "easy/reset", easy_reset, 1185 | "(easy/reset curl) \n\n" 1186 | "reset all options of a libcurl session handle" 1187 | }, 1188 | { 1189 | "easy/upkeep", easy_upkeep, 1190 | "(easy/upkeep curl) \n\n" 1191 | "perform any connection upkeep checks" 1192 | }, 1193 | { 1194 | "easy/recv", easy_recv, 1195 | "(easy/recv curl) \n\n" 1196 | "receives raw data on an \"easy\" connection" 1197 | }, 1198 | { 1199 | "easy/send", easy_send, 1200 | "(easy/send curl) \n\n" 1201 | "sends raw data over an \"easy\" connection" 1202 | }, 1203 | { 1204 | "easy/perform", easy_perform, 1205 | "(easy/perform curl) \n\n" 1206 | "perform a blocking file transfer" 1207 | }, 1208 | { 1209 | "easy/query", easy_query, 1210 | "(easy/query curl :query-effective-url) \n\n" 1211 | "query information from curl easy handler" 1212 | }, 1213 | {NULL, NULL, NULL} 1214 | }; 1215 | 1216 | static void submod_easy(JanetTable *env) { 1217 | janet_cfuns(env, "curl", curl_easy_cfuns); 1218 | } 1219 | 1220 | //============================================================================== 1221 | // ███████╗██╗ ██╗ █████╗ ██████╗ ███████╗ 1222 | // ██╔════╝██║ ██║██╔══██╗██╔══██╗██╔════╝ 1223 | // ███████╗███████║███████║██████╔╝█████╗ 1224 | // ╚════██║██╔══██║██╔══██║██╔══██╗██╔══╝ 1225 | // ███████║██║ ██║██║ ██║██║ ██║███████╗ 1226 | // ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ 1227 | //============================================================================== 1228 | 1229 | static Janet share_init(int32_t argc, Janet *argv) { 1230 | janet_fixarity(argc, 0); 1231 | (void)argv; 1232 | 1233 | CURLSH *curlsh = curl_share_init(); 1234 | return curlsh ? curlsh_make(curlsh) : janet_wrap_nil(); 1235 | } 1236 | 1237 | static Janet share_setopt(int32_t argc, Janet *argv) { 1238 | janet_arity(argc, 2, -1); 1239 | 1240 | if ((argc - 1) % 2 != 0) { 1241 | janet_panic("options count must be even, options are regarded as tuple"); 1242 | } 1243 | 1244 | janet_panic("this function is implemented yet"); 1245 | 1246 | (void) argv; 1247 | // Curl* curl = janet_getabstract(argv, 0, &curl_obj); 1248 | 1249 | // for (int32_t idx = 1; idx < argc; idx+=2){ 1250 | // options_set(curl, argv + idx, argv + idx + 1); 1251 | // } 1252 | 1253 | return janet_wrap_true(); 1254 | } 1255 | 1256 | static Janet share_strerror(int32_t argc, Janet *argv) { 1257 | janet_fixarity(argc, 1); 1258 | 1259 | int code = janet_getinteger(argv, 0); 1260 | 1261 | const char *errstr = curl_share_strerror(code); 1262 | Janet res = janet_cstringv(errstr); 1263 | 1264 | return res; 1265 | } 1266 | 1267 | static const JanetReg curl_share_cfuns[] = { 1268 | { 1269 | "share/init", share_init, 1270 | "(def curl (share/init)) \n\n" 1271 | "create a new curl share handler" 1272 | }, 1273 | { 1274 | "share/strerror", share_strerror, 1275 | "(share/strerror code) \n\n" 1276 | "return error string of an error code" 1277 | }, 1278 | { 1279 | "share/setopt", share_setopt, 1280 | "(share/setopt code :url \"https://janet-lang.org\") \n\n" 1281 | "set options for a curl share handle" 1282 | }, 1283 | {NULL, NULL, NULL} 1284 | }; 1285 | 1286 | static void submod_share(JanetTable *env) { 1287 | janet_cfuns(env, "curl", curl_share_cfuns); 1288 | } 1289 | 1290 | //============================================================================== 1291 | // ██╗ ██╗██████╗ ██╗ 1292 | // ██║ ██║██╔══██╗██║ 1293 | // ██║ ██║██████╔╝██║ 1294 | // ██║ ██║██╔══██╗██║ 1295 | // ╚██████╔╝██║ ██║███████╗ 1296 | // ╚═════╝ ╚═╝ ╚═╝╚══════╝ 1297 | //============================================================================== 1298 | 1299 | static Janet url_init(int32_t argc, Janet *argv) { 1300 | janet_fixarity(argc, 0); 1301 | (void)argv; 1302 | 1303 | CURLU *url = curl_url(); 1304 | return url ? url_make(url) : janet_wrap_nil(); 1305 | } 1306 | 1307 | static Janet url_clone(int32_t argc, Janet *argv) { 1308 | janet_fixarity(argc, 1); 1309 | 1310 | Url *url = janet_getabstract(argv, 0, &url_obj); 1311 | CURLU *clone = curl_url_dup(url->url); 1312 | 1313 | return clone ? url_make(clone) : janet_wrap_nil(); 1314 | } 1315 | 1316 | static Janet url_get(int32_t argc, Janet *argv) { 1317 | janet_arity(argc, 2, 3); 1318 | 1319 | Url *url = janet_getabstract(argv, 0, &url_obj); 1320 | const uint32_t part = janet_getinteger(argv, 1); 1321 | char *extracted; 1322 | uint32_t flag = 0; 1323 | 1324 | if (3 == argc) { 1325 | flag = (uint32_t) janet_getinteger(argv, 2); 1326 | } 1327 | 1328 | if (CURLUE_OK == curl_url_get(url->url, part, &extracted, flag)) { 1329 | Janet res = janet_cstringv(extracted); 1330 | curl_free(extracted); 1331 | return res; 1332 | } 1333 | 1334 | return janet_wrap_nil(); 1335 | } 1336 | 1337 | static Janet url_set(int32_t argc, Janet *argv) { 1338 | janet_arity(argc, 3, 4); 1339 | 1340 | Url *url = janet_getabstract(argv, 0, &url_obj); 1341 | const uint32_t part = janet_getinteger(argv, 1); 1342 | const char *extracted = janet_getcstring(argv, 2); 1343 | uint32_t flag = 0; 1344 | 1345 | if (4 == argc) { 1346 | flag = (uint32_t) janet_getinteger(argv, 3); 1347 | } 1348 | 1349 | if (CURLUE_OK == curl_url_set(url->url, part, extracted, flag)) { 1350 | return janet_wrap_true(); 1351 | } 1352 | 1353 | return janet_wrap_false(); 1354 | } 1355 | 1356 | static const JanetReg curl_url_cfuns[] = { 1357 | { 1358 | "url/init", url_init, 1359 | "(def url (url/init)) \n\n" 1360 | "create a new url object" 1361 | }, 1362 | { 1363 | "url/clone", url_clone, 1364 | "(url/clone url) \n\n" 1365 | "clones a url object" 1366 | }, 1367 | { 1368 | "url/get", url_get, 1369 | "(url/get url :url-part-host) \n\n" 1370 | "extract a part from a url object" 1371 | }, 1372 | { 1373 | "url/set", url_set, 1374 | "(url/set url :url-part-port \"2019\") \n\n" 1375 | "extract a part from a url object" 1376 | }, 1377 | {NULL, NULL, NULL} 1378 | }; 1379 | 1380 | static void submod_url(JanetTable *env) { 1381 | janet_cfuns(env, "curl", curl_url_cfuns); 1382 | } 1383 | 1384 | //============================================================================== 1385 | // ███╗ ███╗██╗███╗ ███╗███████╗ 1386 | // ████╗ ████║██║████╗ ████║██╔════╝ 1387 | // ██╔████╔██║██║██╔████╔██║█████╗ 1388 | // ██║╚██╔╝██║██║██║╚██╔╝██║██╔══╝ 1389 | // ██║ ╚═╝ ██║██║██║ ╚═╝ ██║███████╗ 1390 | // ╚═╝ ╚═╝╚═╝╚═╝ ╚═╝╚══════╝ 1391 | //============================================================================== 1392 | 1393 | static Janet mime_init(int32_t argc, Janet *argv) { 1394 | janet_fixarity(argc, 1); 1395 | 1396 | Curl *curl = janet_getabstract(argv, 0, &curl_obj); 1397 | curl_mime *mime = curl_mime_init(curl->curl); 1398 | 1399 | return mime ? mime_make(mime) : janet_wrap_nil(); 1400 | } 1401 | 1402 | static Janet mime_part(int32_t argc, Janet *argv) { 1403 | janet_fixarity(argc, 1); 1404 | 1405 | Mime *mime = janet_getabstract(argv, 0, &curl_obj); 1406 | curl_mimepart *mimepart = curl_mime_addpart(mime->mime); 1407 | 1408 | return mimepart ? mimepart_make(mimepart) : janet_wrap_nil(); 1409 | } 1410 | 1411 | static Janet mime_subpart(int32_t argc, Janet *argv) { 1412 | janet_fixarity(argc, 2); 1413 | 1414 | Mime *mime = janet_getabstract(argv, 0, &curl_obj); 1415 | MimePart *mimepart = janet_getabstract(argv, 1, &curl_obj); 1416 | 1417 | if (CURLE_OK == curl_mime_subparts(mimepart->mimepart, mime->mime)) { 1418 | return janet_wrap_true(); 1419 | } 1420 | 1421 | return janet_wrap_false(); 1422 | } 1423 | 1424 | static Janet mime_name(int32_t argc, Janet *argv) { 1425 | janet_fixarity(argc, 2); 1426 | 1427 | MimePart *mimepart = janet_getabstract(argv, 0, &curl_obj); 1428 | const char *name = janet_getcstring(argv, 1); 1429 | 1430 | if (CURLE_OK == curl_mime_name(mimepart->mimepart, name)) { 1431 | return janet_wrap_true(); 1432 | } 1433 | 1434 | return janet_wrap_false(); 1435 | } 1436 | 1437 | static Janet mime_type(int32_t argc, Janet *argv) { 1438 | janet_fixarity(argc, 2); 1439 | 1440 | MimePart *mimepart = janet_getabstract(argv, 0, &curl_obj); 1441 | const char *type = janet_getcstring(argv, 1); 1442 | 1443 | if (CURLE_OK == curl_mime_type(mimepart->mimepart, type)) { 1444 | return janet_wrap_true(); 1445 | } 1446 | 1447 | return janet_wrap_false(); 1448 | } 1449 | 1450 | static Janet mime_data(int32_t argc, Janet *argv) { 1451 | janet_fixarity(argc, 2); 1452 | 1453 | MimePart *mimepart = janet_getabstract(argv, 0, &curl_obj); 1454 | const JanetBuffer *buffer = janet_getbuffer(argv, 1); 1455 | 1456 | if (CURLE_OK == curl_mime_data(mimepart->mimepart, (const char *)buffer->data, buffer->count)) { 1457 | return janet_wrap_true(); 1458 | } 1459 | 1460 | return janet_wrap_false(); 1461 | } 1462 | 1463 | static Janet mime_encoder(int32_t argc, Janet *argv) { 1464 | janet_fixarity(argc, 2); 1465 | 1466 | MimePart *mimepart = janet_getabstract(argv, 0, &curl_obj); 1467 | const char *encoding = janet_getcstring(argv, 1); 1468 | 1469 | if (CURLE_OK == curl_mime_encoder(mimepart->mimepart, encoding)) { 1470 | return janet_wrap_true(); 1471 | } 1472 | 1473 | return janet_wrap_false(); 1474 | } 1475 | 1476 | static Janet mime_headers(int32_t argc, Janet *argv) { 1477 | janet_fixarity(argc, 2); 1478 | 1479 | MimePart *mimepart = janet_getabstract(argv, 0, &curl_obj); 1480 | JanetView array = janet_getindexed(argv, 1); 1481 | 1482 | if (array.len <= 0) { 1483 | janet_panic("input list cannot be empty"); 1484 | } 1485 | 1486 | const char *str1 = (const char *) janet_unwrap_string(array.items[0]); 1487 | struct curl_slist *list = curl_slist_append(NULL, str1); 1488 | 1489 | for (int32_t idx = 1; idx < array.len; idx++) { 1490 | const char *str = (const char *) janet_unwrap_string(array.items[idx]); 1491 | list = curl_slist_append(list, str); 1492 | } 1493 | 1494 | const int auto_free = 1; 1495 | if (CURLE_OK == curl_mime_headers(mimepart->mimepart, list, auto_free)) { 1496 | return janet_wrap_true(); 1497 | } 1498 | 1499 | return janet_wrap_false(); 1500 | } 1501 | 1502 | static Janet mime_filename(int32_t argc, Janet *argv) { 1503 | janet_fixarity(argc, 2); 1504 | 1505 | MimePart *mimepart = janet_getabstract(argv, 0, &curl_obj); 1506 | const char *filename = janet_getcstring(argv, 1); 1507 | 1508 | if (CURLE_OK == curl_mime_filename(mimepart->mimepart, filename)) { 1509 | return janet_wrap_true(); 1510 | } 1511 | 1512 | return janet_wrap_false(); 1513 | } 1514 | 1515 | static Janet mime_filedata(int32_t argc, Janet *argv) { 1516 | janet_fixarity(argc, 2); 1517 | 1518 | MimePart *mimepart = janet_getabstract(argv, 0, &curl_obj); 1519 | const char *filename = janet_getcstring(argv, 1); 1520 | 1521 | if (CURLE_OK == curl_mime_filedata(mimepart->mimepart, filename)) { 1522 | return janet_wrap_true(); 1523 | } 1524 | 1525 | return janet_wrap_false(); 1526 | } 1527 | 1528 | static const JanetReg curl_mime_cfuns[] = { 1529 | { 1530 | "mime/init", mime_init, 1531 | "(mime/init curl) \n\n" 1532 | "create a mime handle" 1533 | }, 1534 | { 1535 | "mime/part", mime_part, 1536 | "(mime/part mime) \n\n" 1537 | "append a new empty part to a mime object" 1538 | }, 1539 | { 1540 | "mime/subpart", mime_subpart, 1541 | "(mime/subpart mimepart mime) \n\n" 1542 | "set subparts of a multipart mime part" 1543 | }, 1544 | { 1545 | "mime/name", mime_name, 1546 | "(mime/name mimepart \"wtf\") \n\n" 1547 | "set a mime part's name" 1548 | }, 1549 | { 1550 | "mime/type", mime_type, 1551 | "(mime/type mimepart \"image\\png\") \n\n" 1552 | "set a mime part's content type" 1553 | }, 1554 | { 1555 | "mime/data", mime_data, 1556 | "(mime/data mimepart buffer) \n\n" 1557 | "set a mime part's content" 1558 | }, 1559 | { 1560 | "mime/encoder", mime_encoder, 1561 | "(mime/encoder mimepart buffer) \n\n" 1562 | "set mime data transfer encoder" 1563 | }, 1564 | { 1565 | "mime/headers", mime_headers, 1566 | "(mime/headers mimepart [\"aaa\" \"bbb\"]) \n\n" 1567 | "set a mime part's custom headers" 1568 | }, 1569 | { 1570 | "mime/filename", mime_filename, 1571 | "(mime/filename mimepart \"myfile.png\") \n\n" 1572 | "set a mime part's remote file name" 1573 | }, 1574 | { 1575 | "mime/filedata", mime_filedata, 1576 | "(mime/filedata mimepart \"/home/lol/myfile.png\") \n\n" 1577 | "set a mime part's body data from a file contents" 1578 | }, 1579 | {NULL, NULL, NULL} 1580 | }; 1581 | 1582 | static void submod_mime(JanetTable *env) { 1583 | janet_cfuns(env, "curl", curl_mime_cfuns); 1584 | } 1585 | 1586 | //============================================================================== 1587 | // ███╗ ███╗ ██████╗ ██████╗ ██╗ ██╗██╗ ███████╗ 1588 | // ████╗ ████║██╔═══██╗██╔══██╗██║ ██║██║ ██╔════╝ 1589 | // ██╔████╔██║██║ ██║██║ ██║██║ ██║██║ █████╗ 1590 | // ██║╚██╔╝██║██║ ██║██║ ██║██║ ██║██║ ██╔══╝ 1591 | // ██║ ╚═╝ ██║╚██████╔╝██████╔╝╚██████╔╝███████╗███████╗ 1592 | // ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚══════╝ 1593 | //============================================================================== 1594 | 1595 | JANET_MODULE_ENTRY(JanetTable *env) { 1596 | options_gen_dict(); 1597 | info_gen_dict(); 1598 | 1599 | // GENERAL 1600 | janet_def(env, "version", janet_cstringv(LIBCURL_VERSION), "underlying libcurl value string"); 1601 | 1602 | // .:ENUMS:. 1603 | // CURLOPT_PROXYTYPE 1604 | janet_def(env, "proxy-type-http", janet_wrap_integer(CURLPROXY_HTTP), "http proxy type"); 1605 | janet_def(env, "proxy-type-https", janet_wrap_integer(CURLPROXY_HTTPS), "https proxy type"); 1606 | janet_def(env, "proxy-type-http-1.0", janet_wrap_integer(CURLPROXY_HTTP_1_0), "http 1.0 proxy type"); 1607 | janet_def(env, "proxy-type-socks4", janet_wrap_integer(CURLPROXY_SOCKS4), "socks4 proxy type"); 1608 | janet_def(env, "proxy-type-socks4a", janet_wrap_integer(CURLPROXY_SOCKS4A), "socks4a proxy type"); 1609 | janet_def(env, "proxy-type-socks5", janet_wrap_integer(CURLPROXY_SOCKS5), "socks5 proxy type"); 1610 | janet_def(env, "proxy-type-socks5-hostname", janet_wrap_integer(CURLPROXY_SOCKS5_HOSTNAME), "socks5 resolver proxy type"); 1611 | 1612 | // CURLOPT_FTP_CREATE_MISSING_DIRS 1613 | janet_def(env, "ftp-create-missing-dir-no", janet_wrap_integer(CURLFTP_CREATE_DIR_NONE), "do not create missing dirs"); 1614 | janet_def(env, "ftp-create-missing-dir-yes", janet_wrap_integer(CURLFTP_CREATE_DIR), "create missing dirs"); 1615 | janet_def(env, "ftp-create-missing-dir-retry", janet_wrap_integer(CURLFTP_CREATE_DIR_RETRY), "retry create missing dirs"); 1616 | 1617 | // CURLOPT_IPRESOLVE 1618 | janet_def(env, "ip-resolve-whatever", janet_wrap_integer(CURL_IPRESOLVE_WHATEVER), "whatever"); 1619 | janet_def(env, "ip-resolve-v4", janet_wrap_integer(CURL_IPRESOLVE_V4), "v4"); 1620 | janet_def(env, "ip-resolve-v6", janet_wrap_integer(CURL_IPRESOLVE_V6), "v6"); 1621 | 1622 | // CURLOPT_USE_SSL 1623 | janet_def(env, "use-ssl-none", janet_wrap_integer(CURLUSESSL_NONE), "do not attempt to use ssl"); 1624 | janet_def(env, "use-ssl-try", janet_wrap_integer(CURLUSESSL_TRY), "try using ssl, proceed anyway otherwise"); 1625 | janet_def(env, "use-ssl-control", janet_wrap_integer(CURLUSESSL_CONTROL), "ssl for the control connection or fail"); 1626 | janet_def(env, "use-ssl-all", janet_wrap_integer(CURLUSESSL_ALL), "ssl for all communication or fail"); 1627 | 1628 | // CURLOPT_FTPSSLAUTH 1629 | janet_def(env, "ftp-auth-default", janet_wrap_integer(CURLFTPAUTH_DEFAULT), "let libcurl decide"); 1630 | janet_def(env, "ftp-auth-ssl", janet_wrap_integer(CURLFTPAUTH_SSL), "use auth ssl"); 1631 | janet_def(env, "ftp-auth-tls", janet_wrap_integer(CURLFTPAUTH_TLS), "use auth tls"); 1632 | 1633 | // CURLOPT_FTP_FILEMETHOD 1634 | janet_def(env, "ftp-method-default", janet_wrap_integer(CURLFTPMETHOD_DEFAULT), "let libcurl pick"); 1635 | janet_def(env, "ftp-method-multicwd", janet_wrap_integer(CURLFTPMETHOD_MULTICWD), "single cwd operation for each path part"); 1636 | janet_def(env, "ftp-method-nocwd", janet_wrap_integer(CURLFTPMETHOD_NOCWD), "no cwd at all"); 1637 | janet_def(env, "ftp-method-singlecwd", janet_wrap_integer(CURLFTPMETHOD_SINGLECWD), "one cwd to full dir, then work on file"); 1638 | 1639 | // CURLOPT_FTP_SSL_CCC 1640 | janet_def(env, "ftp-ssl-ccc-none", janet_wrap_integer(CURLFTPSSL_CCC_NONE), "do not send ccc"); 1641 | janet_def(env, "ftp-ssl-ccc-passive", janet_wrap_integer(CURLFTPSSL_CCC_PASSIVE), "Let the server initiate the shutdown"); 1642 | janet_def(env, "ftp-ssl-ccc-active", janet_wrap_integer(CURLFTPSSL_CCC_ACTIVE), "Initiate the shutdown"); 1643 | 1644 | // CURLOPT_RTSP_REQUEST 1645 | janet_def(env, "rtsp-req-none", janet_wrap_integer(CURL_RTSPREQ_NONE), "//TODO: no description"); 1646 | janet_def(env, "rtsp-req-options", janet_wrap_integer(CURL_RTSPREQ_OPTIONS), "//TODO: no description"); 1647 | janet_def(env, "rtsp-req-describe", janet_wrap_integer(CURL_RTSPREQ_DESCRIBE), "//TODO: no description"); 1648 | janet_def(env, "rtsp-req-announce", janet_wrap_integer(CURL_RTSPREQ_ANNOUNCE), "//TODO: no description"); 1649 | janet_def(env, "rtsp-req-setup", janet_wrap_integer(CURL_RTSPREQ_SETUP), "//TODO: no description"); 1650 | janet_def(env, "rtsp-req-play", janet_wrap_integer(CURL_RTSPREQ_PLAY), "//TODO: no description"); 1651 | janet_def(env, "rtsp-req-pause", janet_wrap_integer(CURL_RTSPREQ_PAUSE), "//TODO: no description"); 1652 | janet_def(env, "rtsp-req-teardown", janet_wrap_integer(CURL_RTSPREQ_TEARDOWN), "//TODO: no description"); 1653 | janet_def(env, "rtsp-req-get-parameter", janet_wrap_integer(CURL_RTSPREQ_GET_PARAMETER), "//TODO: no description"); 1654 | janet_def(env, "rtsp-req-set-parameter", janet_wrap_integer(CURL_RTSPREQ_SET_PARAMETER), "//TODO: no description"); 1655 | janet_def(env, "rtsp-req-record", janet_wrap_integer(CURL_RTSPREQ_RECORD), "//TODO: no description"); 1656 | janet_def(env, "rtsp-req-receive", janet_wrap_integer(CURL_RTSPREQ_RECEIVE), "//TODO: no description"); 1657 | 1658 | // CURLOPT_GSSAPI_DELEGATION 1659 | janet_def(env, "gss-api-delegation-none", janet_wrap_integer(CURLGSSAPI_DELEGATION_NONE), "no delegation (default)"); 1660 | janet_def(env, "gss-api-delegation-policy-flag", janet_wrap_integer(CURLGSSAPI_DELEGATION_POLICY_FLAG), "if permitted by policy"); 1661 | janet_def(env, "gss-api-delegation-flag", janet_wrap_integer(CURLGSSAPI_DELEGATION_FLAG), "delegate always"); 1662 | 1663 | // CURLOPT_PROXY_SSL_VERIFYHOST 1664 | janet_def(env, "proxy-ssl-verifyhost-no", janet_wrap_integer(0), "do not verify"); 1665 | janet_def(env, "proxy-ssl-verifyhost-yes", janet_wrap_integer(2), "do not verify"); 1666 | 1667 | // CURLOPT_PROXY_SSLVERSION 1668 | janet_def(env, "ssl-version-default", janet_wrap_integer(CURL_SSLVERSION_DEFAULT), "default"); 1669 | janet_def(env, "ssl-version-tls-1", janet_wrap_integer(CURL_SSLVERSION_TLSv1), "tls 1"); 1670 | janet_def(env, "ssl-version-ssl-2", janet_wrap_integer(CURL_SSLVERSION_SSLv2), "ssl 2"); 1671 | janet_def(env, "ssl-version-ssl-3", janet_wrap_integer(CURL_SSLVERSION_SSLv3), "ssl 3"); 1672 | janet_def(env, "ssl-version-tls-1.0", janet_wrap_integer(CURL_SSLVERSION_TLSv1_0), "tls 1.0"); 1673 | janet_def(env, "ssl-version-tls-1.1", janet_wrap_integer(CURL_SSLVERSION_TLSv1_1), "tls 1.1"); 1674 | janet_def(env, "ssl-version-tls-1.2", janet_wrap_integer(CURL_SSLVERSION_TLSv1_2), "tls 1.2"); 1675 | janet_def(env, "ssl-version-tls-1.3", janet_wrap_integer(CURL_SSLVERSION_TLSv1_3), "tls 1.3"); 1676 | 1677 | // CURLOPT_NETRC 1678 | janet_def(env, "netrc-ignored", janet_wrap_integer(CURL_NETRC_IGNORED), "ignored"); 1679 | janet_def(env, "netrc-optional", janet_wrap_integer(CURL_NETRC_OPTIONAL), "optional"); 1680 | janet_def(env, "netrc-required", janet_wrap_integer(CURL_NETRC_REQUIRED), "required"); 1681 | 1682 | 1683 | janet_def(env, "url-part-url", janet_wrap_integer(CURLUPART_URL), "url part of url"); 1684 | janet_def(env, "url-part-scheme", janet_wrap_integer(CURLUPART_SCHEME), "scheme part of url"); 1685 | janet_def(env, "url-part-user", janet_wrap_integer(CURLUPART_USER), "user part of url"); 1686 | janet_def(env, "url-part-password", janet_wrap_integer(CURLUPART_PASSWORD), "password part of url"); 1687 | janet_def(env, "url-part-options", janet_wrap_integer(CURLUPART_OPTIONS), "options part of url"); 1688 | janet_def(env, "url-part-host", janet_wrap_integer(CURLUPART_HOST), "host part of url"); 1689 | janet_def(env, "url-part-port", janet_wrap_integer(CURLUPART_PORT), "port part of url"); 1690 | janet_def(env, "url-part-path", janet_wrap_integer(CURLUPART_PATH), "path part of url"); 1691 | janet_def(env, "url-part-query", janet_wrap_integer(CURLUPART_QUERY), "query part of url"); 1692 | janet_def(env, "url-part-fragment", janet_wrap_integer(CURLUPART_FRAGMENT), "fragment part of url"); 1693 | 1694 | // QUERY 1695 | janet_def(env, "query-none", janet_wrap_integer(CURLINFO_NONE), "query none"); 1696 | janet_def(env, "query-effective-url", janet_wrap_integer(CURLINFO_EFFECTIVE_URL), "query effective-url"); 1697 | janet_def(env, "query-response-code", janet_wrap_integer(CURLINFO_RESPONSE_CODE), "query response-code"); 1698 | janet_def(env, "query-total-time", janet_wrap_integer(CURLINFO_TOTAL_TIME), "query total-time"); 1699 | janet_def(env, "query-name-lookup-time", janet_wrap_integer(CURLINFO_NAMELOOKUP_TIME), "query namelookup-time"); 1700 | janet_def(env, "query-connect-time", janet_wrap_integer(CURLINFO_CONNECT_TIME), "query connect-time"); 1701 | janet_def(env, "query-pre-transfer-time", janet_wrap_integer(CURLINFO_PRETRANSFER_TIME), "query pretransfer-time"); 1702 | janet_def(env, "query-size-upload", janet_wrap_integer(CURLINFO_SIZE_UPLOAD), "query size-upload"); 1703 | janet_def(env, "query-size-upload-t", janet_wrap_integer(CURLINFO_SIZE_UPLOAD_T), "query size-upload-t"); 1704 | janet_def(env, "query-size-download", janet_wrap_integer(CURLINFO_SIZE_DOWNLOAD), "query size-download"); 1705 | janet_def(env, "query-size-download-t", janet_wrap_integer(CURLINFO_SIZE_DOWNLOAD_T), "query size-download-t"); 1706 | janet_def(env, "query-speed-download", janet_wrap_integer(CURLINFO_SPEED_DOWNLOAD), "query speed-download"); 1707 | janet_def(env, "query-speed-download-t", janet_wrap_integer(CURLINFO_SPEED_DOWNLOAD_T), "query speed-download-t"); 1708 | janet_def(env, "query-speed-upload", janet_wrap_integer(CURLINFO_SPEED_UPLOAD), "query speed-upload"); 1709 | janet_def(env, "query-speed-upload-t", janet_wrap_integer(CURLINFO_SPEED_UPLOAD_T), "query speed-upload-t"); 1710 | janet_def(env, "query-header-size", janet_wrap_integer(CURLINFO_HEADER_SIZE), "query header-size"); 1711 | janet_def(env, "query-request-size", janet_wrap_integer(CURLINFO_REQUEST_SIZE), "query request-size"); 1712 | janet_def(env, "query-ssl-verify-result", janet_wrap_integer(CURLINFO_SSL_VERIFYRESULT), "query ssl-verifyresult"); 1713 | janet_def(env, "query-file-time", janet_wrap_integer(CURLINFO_FILETIME), "query filetime"); 1714 | janet_def(env, "query-file-time-t", janet_wrap_integer(CURLINFO_FILETIME_T), "query filetime-t"); 1715 | janet_def(env, "query-content-length-download", janet_wrap_integer(CURLINFO_CONTENT_LENGTH_DOWNLOAD), "query content-length-download"); 1716 | janet_def(env, "query-content-length-download-t", janet_wrap_integer(CURLINFO_CONTENT_LENGTH_DOWNLOAD_T), "query content-length-download-t"); 1717 | janet_def(env, "query-content-length-upload", janet_wrap_integer(CURLINFO_CONTENT_LENGTH_UPLOAD), "query content-length-upload"); 1718 | janet_def(env, "query-content-length-upload-t", janet_wrap_integer(CURLINFO_CONTENT_LENGTH_UPLOAD_T), "query content-length-upload-t"); 1719 | janet_def(env, "query-start-transfer-time", janet_wrap_integer(CURLINFO_STARTTRANSFER_TIME), "query starttransfer-time"); 1720 | janet_def(env, "query-content-type", janet_wrap_integer(CURLINFO_CONTENT_TYPE), "query content-type"); 1721 | janet_def(env, "query-redirect-time", janet_wrap_integer(CURLINFO_REDIRECT_TIME), "query redirect-time"); 1722 | janet_def(env, "query-redirect-count", janet_wrap_integer(CURLINFO_REDIRECT_COUNT), "query redirect-count"); 1723 | janet_def(env, "query-private", janet_wrap_integer(CURLINFO_PRIVATE), "query private"); 1724 | janet_def(env, "query-http-connect-code", janet_wrap_integer(CURLINFO_HTTP_CONNECTCODE), "query http-connectcode"); 1725 | janet_def(env, "query-http-auth-avail", janet_wrap_integer(CURLINFO_HTTPAUTH_AVAIL), "query httpauth-avail"); 1726 | janet_def(env, "query-proxy-auth-avail", janet_wrap_integer(CURLINFO_PROXYAUTH_AVAIL), "query proxyauth-avail"); 1727 | janet_def(env, "query-os-errno", janet_wrap_integer(CURLINFO_OS_ERRNO), "query os-errno"); 1728 | janet_def(env, "query-num-connects", janet_wrap_integer(CURLINFO_NUM_CONNECTS), "query num-connects"); 1729 | janet_def(env, "query-ssl-engines", janet_wrap_integer(CURLINFO_SSL_ENGINES), "query ssl-engines"); 1730 | janet_def(env, "query-cookie-list", janet_wrap_integer(CURLINFO_COOKIELIST), "query cookielist"); 1731 | janet_def(env, "query-last-socket", janet_wrap_integer(CURLINFO_LASTSOCKET), "query lastsocket"); 1732 | janet_def(env, "query-ftp-entry-path", janet_wrap_integer(CURLINFO_FTP_ENTRY_PATH), "query ftp-entry-path"); 1733 | janet_def(env, "query-redirect-url", janet_wrap_integer(CURLINFO_REDIRECT_URL), "query redirect-url"); 1734 | janet_def(env, "query-primary-ip", janet_wrap_integer(CURLINFO_PRIMARY_IP), "query primary-ip"); 1735 | janet_def(env, "query-app-connect-time", janet_wrap_integer(CURLINFO_APPCONNECT_TIME), "query appconnect-time"); 1736 | janet_def(env, "query-cert-info", janet_wrap_integer(CURLINFO_CERTINFO), "query certinfo"); 1737 | janet_def(env, "query-condition-unmet", janet_wrap_integer(CURLINFO_CONDITION_UNMET), "query condition-unmet"); 1738 | janet_def(env, "query-rtsp-session-id", janet_wrap_integer(CURLINFO_RTSP_SESSION_ID), "query rtsp-session-id"); 1739 | janet_def(env, "query-rtsp-client-cseq", janet_wrap_integer(CURLINFO_RTSP_CLIENT_CSEQ), "query rtsp-client-cseq"); 1740 | janet_def(env, "query-rtsp-server-cseq", janet_wrap_integer(CURLINFO_RTSP_SERVER_CSEQ), "query rtsp-server-cseq"); 1741 | janet_def(env, "query-rtsp-cseq-recv", janet_wrap_integer(CURLINFO_RTSP_CSEQ_RECV), "query rtsp-cseq-recv"); 1742 | janet_def(env, "query-primary-port", janet_wrap_integer(CURLINFO_PRIMARY_PORT), "query primary-port"); 1743 | janet_def(env, "query-local-ip", janet_wrap_integer(CURLINFO_LOCAL_IP), "query local-ip"); 1744 | janet_def(env, "query-local-port", janet_wrap_integer(CURLINFO_LOCAL_PORT), "query local-port"); 1745 | janet_def(env, "query-tls-session", janet_wrap_integer(CURLINFO_TLS_SESSION), "query tls-session"); 1746 | janet_def(env, "query-active-socket", janet_wrap_integer(CURLINFO_ACTIVESOCKET), "query activesocket"); 1747 | janet_def(env, "query-tls-ssl-ptr", janet_wrap_integer(CURLINFO_TLS_SSL_PTR), "query tls-ssl-ptr"); 1748 | janet_def(env, "query-http-version", janet_wrap_integer(CURLINFO_HTTP_VERSION), "query http-version"); 1749 | janet_def(env, "query-proxy-ssl-verify-result", janet_wrap_integer(CURLINFO_PROXY_SSL_VERIFYRESULT), "query proxy-ssl-verifyresult"); 1750 | janet_def(env, "query-protocol", janet_wrap_integer(CURLINFO_PROTOCOL), "query protocol"); 1751 | janet_def(env, "query-scheme", janet_wrap_integer(CURLINFO_SCHEME), "query scheme"); 1752 | janet_def(env, "query-total-time-t", janet_wrap_integer(CURLINFO_TOTAL_TIME_T), "query total-time-t"); 1753 | janet_def(env, "query-name-lookup-time-t", janet_wrap_integer(CURLINFO_NAMELOOKUP_TIME_T), "query namelookup-time-t"); 1754 | janet_def(env, "query-connect-time-t", janet_wrap_integer(CURLINFO_CONNECT_TIME_T), "query connect-time-t"); 1755 | janet_def(env, "query-pre-transfer-time-t", janet_wrap_integer(CURLINFO_PRETRANSFER_TIME_T), "query pretransfer-time-t"); 1756 | janet_def(env, "query-start-transfer-time-t", janet_wrap_integer(CURLINFO_STARTTRANSFER_TIME_T), "query starttransfer-time-t"); 1757 | janet_def(env, "query-redirect-time-t", janet_wrap_integer(CURLINFO_REDIRECT_TIME_T), "query redirect-time-t"); 1758 | janet_def(env, "query-app-connect-time-t", janet_wrap_integer(CURLINFO_APPCONNECT_TIME_T), "query appconnect-time-t"); 1759 | 1760 | // .:MASK:. 1761 | // CURLOPT_SSH_AUTH_TYPES 1762 | janet_def(env, "ssh-auth-any", janet_wrap_integer(CURLSSH_AUTH_ANY), "any (bitmask)"); 1763 | janet_def(env, "ssh-auth-none", janet_wrap_integer(CURLSSH_AUTH_NONE), "none (bitmask)"); 1764 | janet_def(env, "ssh-auth-public-key", janet_wrap_integer(CURLSSH_AUTH_PUBLICKEY), "public key (bitmask)"); 1765 | janet_def(env, "ssh-auth-password", janet_wrap_integer(CURLSSH_AUTH_PASSWORD), "password (bitmask)"); 1766 | janet_def(env, "ssh-auth-host", janet_wrap_integer(CURLSSH_AUTH_HOST), "host (bitmask)"); 1767 | janet_def(env, "ssh-auth-keyboard", janet_wrap_integer(CURLSSH_AUTH_KEYBOARD), "keyboard (bitmask)"); 1768 | janet_def(env, "ssh-auth-agent", janet_wrap_integer(CURLSSH_AUTH_AGENT), "agent (bitmask)"); 1769 | janet_def(env, "ssh-auth-gss-api", janet_wrap_integer(CURLSSH_AUTH_GSSAPI), "gss api (bitmask)"); 1770 | janet_def(env, "ssh-auth-default", janet_wrap_integer(CURLSSH_AUTH_DEFAULT), "default (bitmask)"); 1771 | 1772 | // CURLOPT_POSTREDIR 1773 | janet_def(env, "redir-get-all", janet_wrap_integer(CURL_REDIR_GET_ALL), "get all (bitmask)"); 1774 | janet_def(env, "redir-post-301", janet_wrap_integer(CURL_REDIR_POST_301), "post 301 (bitmask)"); 1775 | janet_def(env, "redir-post-302", janet_wrap_integer(CURL_REDIR_POST_302), "post 302 (bitmask)"); 1776 | janet_def(env, "redir-post-303", janet_wrap_integer(CURL_REDIR_POST_303), "post 303 (bitmask)"); 1777 | janet_def(env, "redir-post-all", janet_wrap_integer(CURL_REDIR_POST_ALL), "post all (bitmask)"); 1778 | 1779 | // CURLOPT_PROTOCOLS 1780 | janet_def(env, "proto-http", janet_wrap_integer(CURLPROTO_HTTP), "http (bitmask)"); 1781 | janet_def(env, "proto-https", janet_wrap_integer(CURLPROTO_HTTPS), "https (bitmask)"); 1782 | janet_def(env, "proto-ftp", janet_wrap_integer(CURLPROTO_FTP), "ftp (bitmask)"); 1783 | janet_def(env, "proto-ftps", janet_wrap_integer(CURLPROTO_FTPS), "ftps (bitmask)"); 1784 | janet_def(env, "proto-scp", janet_wrap_integer(CURLPROTO_SCP), "scp (bitmask)"); 1785 | janet_def(env, "proto-sftp", janet_wrap_integer(CURLPROTO_SFTP), "sftp (bitmask)"); 1786 | janet_def(env, "proto-telnet", janet_wrap_integer(CURLPROTO_TELNET), "telnet (bitmask)"); 1787 | janet_def(env, "proto-ldap", janet_wrap_integer(CURLPROTO_LDAP), "ldap (bitmask)"); 1788 | janet_def(env, "proto-ldaps", janet_wrap_integer(CURLPROTO_LDAPS), "ldaps (bitmask)"); 1789 | janet_def(env, "proto-dict", janet_wrap_integer(CURLPROTO_DICT), "dict (bitmask)"); 1790 | janet_def(env, "proto-file", janet_wrap_integer(CURLPROTO_FILE), "file (bitmask)"); 1791 | janet_def(env, "proto-tftp", janet_wrap_integer(CURLPROTO_TFTP), "tftp (bitmask)"); 1792 | janet_def(env, "proto-imap", janet_wrap_integer(CURLPROTO_IMAP), "imap (bitmask)"); 1793 | janet_def(env, "proto-imaps", janet_wrap_integer(CURLPROTO_IMAPS), "imaps (bitmask)"); 1794 | janet_def(env, "proto-pop3", janet_wrap_integer(CURLPROTO_POP3), "pop3 (bitmask)"); 1795 | janet_def(env, "proto-pop3s", janet_wrap_integer(CURLPROTO_POP3S), "pop3s (bitmask)"); 1796 | janet_def(env, "proto-smtp", janet_wrap_integer(CURLPROTO_SMTP), "smtp (bitmask)"); 1797 | janet_def(env, "proto-smtps", janet_wrap_integer(CURLPROTO_SMTPS), "smtps (bitmask)"); 1798 | janet_def(env, "proto-rtsp", janet_wrap_integer(CURLPROTO_RTSP), "rtsp (bitmask)"); 1799 | janet_def(env, "proto-rtmp", janet_wrap_integer(CURLPROTO_RTMP), "rtmp (bitmask)"); 1800 | janet_def(env, "proto-rtmpt", janet_wrap_integer(CURLPROTO_RTMPT), "rtmpt (bitmask)"); 1801 | janet_def(env, "proto-rtmpe", janet_wrap_integer(CURLPROTO_RTMPE), "rtmpe (bitmask)"); 1802 | janet_def(env, "proto-rtmpte", janet_wrap_integer(CURLPROTO_RTMPTE), "rtmpte (bitmask)"); 1803 | janet_def(env, "proto-rtmps", janet_wrap_integer(CURLPROTO_RTMPS), "rtmps (bitmask)"); 1804 | janet_def(env, "proto-rtmpts", janet_wrap_integer(CURLPROTO_RTMPTS), "rtmpts (bitmask)"); 1805 | janet_def(env, "proto-gopher", janet_wrap_integer(CURLPROTO_GOPHER), "gopher (bitmask)"); 1806 | janet_def(env, "proto-smb", janet_wrap_integer(CURLPROTO_SMB), "smb (bitmask)"); 1807 | janet_def(env, "proto-smbs", janet_wrap_integer(CURLPROTO_SMBS), "smbs (bitmask)"); 1808 | janet_def(env, "proto-all", janet_wrap_integer(CURLPROTO_ALL), "all (bitmask)"); 1809 | 1810 | // CURLOPT_REDIR_PROTOCOLS 1811 | janet_def(env, "re-dir-proto-http", janet_wrap_integer(CURLPROTO_HTTP), "http (bitmask)"); 1812 | janet_def(env, "re-dir-proto-https", janet_wrap_integer(CURLPROTO_HTTPS), "https (bitmask)"); 1813 | janet_def(env, "re-dir-proto-ftp", janet_wrap_integer(CURLPROTO_FTP), "ftp (bitmask)"); 1814 | janet_def(env, "re-dir-proto-ftps", janet_wrap_integer(CURLPROTO_FTPS), "ftps (bitmask)"); 1815 | janet_def(env, "re-dir-proto-scp", janet_wrap_integer(CURLPROTO_SCP), "scp (bitmask)"); 1816 | janet_def(env, "re-dir-proto-sftp", janet_wrap_integer(CURLPROTO_SFTP), "sftp (bitmask)"); 1817 | janet_def(env, "re-dir-proto-telnet", janet_wrap_integer(CURLPROTO_TELNET), "telnet (bitmask)"); 1818 | janet_def(env, "re-dir-proto-ldap", janet_wrap_integer(CURLPROTO_LDAP), "ldap (bitmask)"); 1819 | janet_def(env, "re-dir-proto-ldaps", janet_wrap_integer(CURLPROTO_LDAPS), "ldaps (bitmask)"); 1820 | janet_def(env, "re-dir-proto-dict", janet_wrap_integer(CURLPROTO_DICT), "dict (bitmask)"); 1821 | janet_def(env, "re-dir-proto-file", janet_wrap_integer(CURLPROTO_FILE), "file (bitmask)"); 1822 | janet_def(env, "re-dir-proto-tftp", janet_wrap_integer(CURLPROTO_TFTP), "tftp (bitmask)"); 1823 | janet_def(env, "re-dir-proto-imap", janet_wrap_integer(CURLPROTO_IMAP), "imap (bitmask)"); 1824 | janet_def(env, "re-dir-proto-imaps", janet_wrap_integer(CURLPROTO_IMAPS), "imaps (bitmask)"); 1825 | janet_def(env, "re-dir-proto-pop3", janet_wrap_integer(CURLPROTO_POP3), "pop3 (bitmask)"); 1826 | janet_def(env, "re-dir-proto-pop3s", janet_wrap_integer(CURLPROTO_POP3S), "pop3s (bitmask)"); 1827 | janet_def(env, "re-dir-proto-smtp", janet_wrap_integer(CURLPROTO_SMTP), "smtp (bitmask)"); 1828 | janet_def(env, "re-dir-proto-smtps", janet_wrap_integer(CURLPROTO_SMTPS), "smtps (bitmask)"); 1829 | janet_def(env, "re-dir-proto-rtsp", janet_wrap_integer(CURLPROTO_RTSP), "rtsp (bitmask)"); 1830 | janet_def(env, "re-dir-proto-rtmp", janet_wrap_integer(CURLPROTO_RTMP), "rtmp (bitmask)"); 1831 | janet_def(env, "re-dir-proto-rtmpt", janet_wrap_integer(CURLPROTO_RTMPT), "rtmpt (bitmask)"); 1832 | janet_def(env, "re-dir-proto-rtmpe", janet_wrap_integer(CURLPROTO_RTMPE), "rtmpe (bitmask)"); 1833 | janet_def(env, "re-dir-proto-rtmpte", janet_wrap_integer(CURLPROTO_RTMPTE), "rtmpte (bitmask)"); 1834 | janet_def(env, "re-dir-proto-rtmps", janet_wrap_integer(CURLPROTO_RTMPS), "rtmps (bitmask)"); 1835 | janet_def(env, "re-dir-proto-rtmpts", janet_wrap_integer(CURLPROTO_RTMPTS), "rtmpts (bitmask)"); 1836 | janet_def(env, "re-dir-proto-gopher", janet_wrap_integer(CURLPROTO_GOPHER), "gopher (bitmask)"); 1837 | janet_def(env, "re-dir-proto-smb", janet_wrap_integer(CURLPROTO_SMB), "smb (bitmask)"); 1838 | janet_def(env, "re-dir-proto-smbs", janet_wrap_integer(CURLPROTO_SMBS), "smbs (bitmask)"); 1839 | janet_def(env, "re-dir-proto-all", janet_wrap_integer(CURLPROTO_ALL), "all (bitmask)"); 1840 | 1841 | // CURLOPT_SSL_OPTIONS 1842 | janet_def(env, "ssl-opt-allow", janet_wrap_integer(CURLSSLOPT_ALLOW_BEAST), "allow beast (bitmask)"); 1843 | janet_def(env, "ssl-opt-no", janet_wrap_integer(CURLSSLOPT_NO_REVOKE), "no revoke (bitmask)"); 1844 | 1845 | // CURLOPT_PROXY_SSL_OPTIONS 1846 | janet_def(env, "proxy-ssl-opt-allow", janet_wrap_integer(CURLSSLOPT_ALLOW_BEAST), "allow beast (bitmask)"); 1847 | janet_def(env, "proxy-ssl-opt-no", janet_wrap_integer(CURLSSLOPT_NO_REVOKE), "no revoke (bitmask)"); 1848 | 1849 | // CURLOPT_HEADEROPT 1850 | janet_def(env, "header-opt-unified", janet_wrap_integer(CURLHEADER_UNIFIED), "unified (bitmask)"); 1851 | janet_def(env, "header-opt-separate", janet_wrap_integer(CURLHEADER_SEPARATE), "separate (bitmask)"); 1852 | 1853 | // CURLOPT_HTTPAUTH 1854 | janet_def(env, "http-auth-none", janet_wrap_integer(CURLAUTH_NONE), "no authentication"); 1855 | janet_def(env, "http-auth-basic", janet_wrap_integer(CURLAUTH_BASIC), "basic authentication type"); 1856 | janet_def(env, "http-auth-digest", janet_wrap_integer(CURLAUTH_DIGEST), "digest authentication type"); 1857 | janet_def(env, "http-auth-digest-ie", janet_wrap_integer(CURLAUTH_DIGEST_IE), "digest authentication type with IE flavor"); 1858 | janet_def(env, "http-auth-negotiate", janet_wrap_integer(CURLAUTH_NEGOTIATE), "negotiate authentication type"); 1859 | janet_def(env, "http-auth-gss-api", janet_wrap_integer(CURLAUTH_GSSAPI), "gss api authentication type"); 1860 | janet_def(env, "http-auth-ntlm", janet_wrap_integer(CURLAUTH_NTLM), "ntlm authentication type"); 1861 | janet_def(env, "http-auth-ntlm-wb", janet_wrap_integer(CURLAUTH_NTLM_WB), "ntlm wb authentication type"); 1862 | janet_def(env, "http-auth-bearer", janet_wrap_integer(CURLAUTH_BEARER), "bearer authentication type"); 1863 | janet_def(env, "http-auth-only", janet_wrap_integer(CURLAUTH_ONLY), "//TODO: how to handle this?"); 1864 | janet_def(env, "http-auth-any", janet_wrap_integer(CURLAUTH_ANY), "any authentication type"); 1865 | janet_def(env, "http-auth-any-safe", janet_wrap_integer(CURLAUTH_ANYSAFE), "any safe authentication type"); 1866 | janet_def(env, "http-auth-aws-sigv4", janet_wrap_integer(CURLAUTH_AWS_SIGV4), "aws sigv4 authentication type"); 1867 | 1868 | // CURLOPT_PROXYAUTH 1869 | janet_def(env, "proxy-none", janet_wrap_integer(CURLAUTH_NONE), "none"); 1870 | janet_def(env, "proxy-basic", janet_wrap_integer(CURLAUTH_BASIC), "basic"); 1871 | janet_def(env, "proxy-digest", janet_wrap_integer(CURLAUTH_DIGEST), "digest"); 1872 | janet_def(env, "proxy-negotiate", janet_wrap_integer(CURLAUTH_NEGOTIATE), "negotiate"); 1873 | janet_def(env, "proxy-gssapi", janet_wrap_integer(CURLAUTH_GSSAPI), "gssapi"); 1874 | janet_def(env, "proxy-ntlm", janet_wrap_integer(CURLAUTH_NTLM), "ntlm"); 1875 | janet_def(env, "proxy-digest-ie", janet_wrap_integer(CURLAUTH_DIGEST_IE), "digest-ie"); 1876 | janet_def(env, "proxy-ntlm-wb", janet_wrap_integer(CURLAUTH_NTLM_WB), "ntlm-wb"); 1877 | janet_def(env, "proxy-bearer", janet_wrap_integer(CURLAUTH_BEARER), "bearer"); 1878 | janet_def(env, "proxy-only", janet_wrap_integer(CURLAUTH_ONLY), "only"); 1879 | janet_def(env, "proxy-any", janet_wrap_integer(CURLAUTH_ANY), "any"); 1880 | janet_def(env, "proxy-anysafe", janet_wrap_integer(CURLAUTH_ANYSAFE), "anysafe"); 1881 | 1882 | // CURLOPT_SOCKS5_AUTH 1883 | janet_def(env, "sock5-auth-none", janet_wrap_integer(CURLAUTH_NONE), "no authentication (bitmask)"); 1884 | janet_def(env, "sock5-auth-basic", janet_wrap_integer(CURLAUTH_BASIC), "basic authentication type (bitmask)"); 1885 | janet_def(env, "sock5-auth-digest", janet_wrap_integer(CURLAUTH_DIGEST), "digest authentication type (bitmask)"); 1886 | janet_def(env, "sock5-auth-digest-ie", janet_wrap_integer(CURLAUTH_DIGEST_IE), "digest authentication type with IE flavor (bitmask)"); 1887 | janet_def(env, "sock5-auth-negotiate", janet_wrap_integer(CURLAUTH_NEGOTIATE), "negotiate authentication type (bitmask)"); 1888 | janet_def(env, "sock5-auth-gss-api", janet_wrap_integer(CURLAUTH_GSSAPI), "gss api authentication type (bitmask)"); 1889 | janet_def(env, "sock5-auth-ntlm", janet_wrap_integer(CURLAUTH_NTLM), "ntlm authentication type (bitmask)"); 1890 | janet_def(env, "sock5-auth-ntlm-wb", janet_wrap_integer(CURLAUTH_NTLM_WB), "ntlm wb authentication type (bitmask)"); 1891 | janet_def(env, "sock5-auth-bearer", janet_wrap_integer(CURLAUTH_BEARER), "bearer authentication type (bitmask)"); 1892 | janet_def(env, "sock5-auth-only", janet_wrap_integer(CURLAUTH_ONLY), "//TODO: how to handle this? (bitmask)"); 1893 | janet_def(env, "sock5-auth-any", janet_wrap_integer(CURLAUTH_ANY), "any authentication type (bitmask)"); 1894 | janet_def(env, "sock5-auth-any-safe", janet_wrap_integer(CURLAUTH_ANYSAFE), "any safe authentication type (bitmask)"); 1895 | 1896 | // CURLU_EXTRACT_FLAGS 1897 | janet_def(env, "url-extract-flag-default-port", janet_wrap_integer(CURLU_DEFAULT_PORT), "default port (bitmask)"); 1898 | janet_def(env, "url-extract-flag-no-default-port", janet_wrap_integer(CURLU_NO_DEFAULT_PORT), "no default port (bitmask)"); 1899 | janet_def(env, "url-extract-flag-default-scheme", janet_wrap_integer(CURLU_DEFAULT_SCHEME), "default scheme (bitmask)"); 1900 | janet_def(env, "url-extract-flag-non-support-scheme", janet_wrap_integer(CURLU_NON_SUPPORT_SCHEME), "non support scheme (bitmask)"); 1901 | janet_def(env, "url-extract-flag-path-as-is", janet_wrap_integer(CURLU_PATH_AS_IS), "path as is (bitmask)"); 1902 | janet_def(env, "url-extract-flag-disallow-user", janet_wrap_integer(CURLU_DISALLOW_USER), "disallow user (bitmask)"); 1903 | janet_def(env, "url-extract-flag-url-decode", janet_wrap_integer(CURLU_URLDECODE), "url decode (bitmask)"); 1904 | janet_def(env, "url-extract-flag-url-encode", janet_wrap_integer(CURLU_URLENCODE), "url encode (bitmask)"); 1905 | janet_def(env, "url-extract-flag-append-query", janet_wrap_integer(CURLU_APPENDQUERY), "append query (bitmask)"); 1906 | janet_def(env, "url-extract-flag-guess-scheme", janet_wrap_integer(CURLU_GUESS_SCHEME), "guess scheme (bitmask)"); 1907 | 1908 | // submodules 1909 | submod_easy(env); 1910 | submod_share(env); 1911 | submod_url(env); 1912 | submod_mime(env); 1913 | } 1914 | -------------------------------------------------------------------------------- /src/khash.h: -------------------------------------------------------------------------------- 1 | /* The MIT License 2 | 3 | Copyright (c) 2008, 2009, 2011 by Attractive Chaos 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 20 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 21 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | */ 25 | 26 | /* 27 | An example: 28 | 29 | #include "khash.h" 30 | KHASH_MAP_INIT_INT(32, char) 31 | int main() { 32 | int ret, is_missing; 33 | khiter_t k; 34 | khash_t(32) *h = kh_init(32); 35 | k = kh_put(32, h, 5, &ret); 36 | kh_value(h, k) = 10; 37 | k = kh_get(32, h, 10); 38 | is_missing = (k == kh_end(h)); 39 | k = kh_get(32, h, 5); 40 | kh_del(32, h, k); 41 | for (k = kh_begin(h); k != kh_end(h); ++k) 42 | if (kh_exist(h, k)) kh_value(h, k) = 1; 43 | kh_destroy(32, h); 44 | return 0; 45 | } 46 | */ 47 | 48 | /* 49 | 2013-05-02 (0.2.8): 50 | 51 | * Use quadratic probing. When the capacity is power of 2, stepping function 52 | i*(i+1)/2 guarantees to traverse each bucket. It is better than double 53 | hashing on cache performance and is more robust than linear probing. 54 | 55 | In theory, double hashing should be more robust than quadratic probing. 56 | However, my implementation is probably not for large hash tables, because 57 | the second hash function is closely tied to the first hash function, 58 | which reduce the effectiveness of double hashing. 59 | 60 | Reference: http://research.cs.vt.edu/AVresearch/hashing/quadratic.php 61 | 62 | 2011-12-29 (0.2.7): 63 | 64 | * Minor code clean up; no actual effect. 65 | 66 | 2011-09-16 (0.2.6): 67 | 68 | * The capacity is a power of 2. This seems to dramatically improve the 69 | speed for simple keys. Thank Zilong Tan for the suggestion. Reference: 70 | 71 | - http://code.google.com/p/ulib/ 72 | - http://nothings.org/computer/judy/ 73 | 74 | * Allow to optionally use linear probing which usually has better 75 | performance for random input. Double hashing is still the default as it 76 | is more robust to certain non-random input. 77 | 78 | * Added Wang's integer hash function (not used by default). This hash 79 | function is more robust to certain non-random input. 80 | 81 | 2011-02-14 (0.2.5): 82 | 83 | * Allow to declare global functions. 84 | 85 | 2009-09-26 (0.2.4): 86 | 87 | * Improve portability 88 | 89 | 2008-09-19 (0.2.3): 90 | 91 | * Corrected the example 92 | * Improved interfaces 93 | 94 | 2008-09-11 (0.2.2): 95 | 96 | * Improved speed a little in kh_put() 97 | 98 | 2008-09-10 (0.2.1): 99 | 100 | * Added kh_clear() 101 | * Fixed a compiling error 102 | 103 | 2008-09-02 (0.2.0): 104 | 105 | * Changed to token concatenation which increases flexibility. 106 | 107 | 2008-08-31 (0.1.2): 108 | 109 | * Fixed a bug in kh_get(), which has not been tested previously. 110 | 111 | 2008-08-31 (0.1.1): 112 | 113 | * Added destructor 114 | */ 115 | 116 | 117 | #ifndef __AC_KHASH_H 118 | #define __AC_KHASH_H 119 | 120 | /*! 121 | @header 122 | 123 | Generic hash table library. 124 | */ 125 | 126 | #define AC_VERSION_KHASH_H "0.2.8" 127 | 128 | #include 129 | #include 130 | #include 131 | 132 | /* compiler specific configuration */ 133 | 134 | #if UINT_MAX == 0xffffffffu 135 | typedef unsigned int khint32_t; 136 | #elif ULONG_MAX == 0xffffffffu 137 | typedef unsigned long khint32_t; 138 | #endif 139 | 140 | #if ULONG_MAX == ULLONG_MAX 141 | typedef unsigned long khint64_t; 142 | #else 143 | typedef unsigned long long khint64_t; 144 | #endif 145 | 146 | #ifndef kh_inline 147 | #ifdef _MSC_VER 148 | #define kh_inline __inline 149 | #else 150 | #define kh_inline inline 151 | #endif 152 | #endif /* kh_inline */ 153 | 154 | #ifndef klib_unused 155 | #if (defined __clang__ && __clang_major__ >= 3) || (defined __GNUC__ && __GNUC__ >= 3) 156 | #define klib_unused __attribute__ ((__unused__)) 157 | #else 158 | #define klib_unused 159 | #endif 160 | #endif /* klib_unused */ 161 | 162 | typedef khint32_t khint_t; 163 | typedef khint_t khiter_t; 164 | 165 | #define __ac_isempty(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&2) 166 | #define __ac_isdel(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&1) 167 | #define __ac_iseither(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&3) 168 | #define __ac_set_isdel_false(flag, i) (flag[i>>4]&=~(1ul<<((i&0xfU)<<1))) 169 | #define __ac_set_isempty_false(flag, i) (flag[i>>4]&=~(2ul<<((i&0xfU)<<1))) 170 | #define __ac_set_isboth_false(flag, i) (flag[i>>4]&=~(3ul<<((i&0xfU)<<1))) 171 | #define __ac_set_isdel_true(flag, i) (flag[i>>4]|=1ul<<((i&0xfU)<<1)) 172 | 173 | #define __ac_fsize(m) ((m) < 16? 1 : (m)>>4) 174 | 175 | #ifndef kroundup32 176 | #define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) 177 | #endif 178 | 179 | #ifndef kcalloc 180 | #define kcalloc(N,Z) calloc(N,Z) 181 | #endif 182 | #ifndef kmalloc 183 | #define kmalloc(Z) malloc(Z) 184 | #endif 185 | #ifndef krealloc 186 | #define krealloc(P,Z) realloc(P,Z) 187 | #endif 188 | #ifndef kfree 189 | #define kfree(P) free(P) 190 | #endif 191 | 192 | static const double __ac_HASH_UPPER = 0.77; 193 | 194 | #define __KHASH_TYPE(name, khkey_t, khval_t) \ 195 | typedef struct kh_##name##_s { \ 196 | khint_t n_buckets, size, n_occupied, upper_bound; \ 197 | khint32_t *flags; \ 198 | khkey_t *keys; \ 199 | khval_t *vals; \ 200 | } kh_##name##_t; 201 | 202 | #define __KHASH_PROTOTYPES(name, khkey_t, khval_t) \ 203 | extern kh_##name##_t *kh_init_##name(void); \ 204 | extern void kh_destroy_##name(kh_##name##_t *h); \ 205 | extern void kh_clear_##name(kh_##name##_t *h); \ 206 | extern khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key); \ 207 | extern int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets); \ 208 | extern khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret); \ 209 | extern void kh_del_##name(kh_##name##_t *h, khint_t x); 210 | 211 | #define __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ 212 | SCOPE kh_##name##_t *kh_init_##name(void) { \ 213 | return (kh_##name##_t*)kcalloc(1, sizeof(kh_##name##_t)); \ 214 | } \ 215 | SCOPE void kh_destroy_##name(kh_##name##_t *h) \ 216 | { \ 217 | if (h) { \ 218 | kfree((void *)h->keys); kfree(h->flags); \ 219 | kfree((void *)h->vals); \ 220 | kfree(h); \ 221 | } \ 222 | } \ 223 | SCOPE void kh_clear_##name(kh_##name##_t *h) \ 224 | { \ 225 | if (h && h->flags) { \ 226 | memset(h->flags, 0xaa, __ac_fsize(h->n_buckets) * sizeof(khint32_t)); \ 227 | h->size = h->n_occupied = 0; \ 228 | } \ 229 | } \ 230 | SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \ 231 | { \ 232 | if (h->n_buckets) { \ 233 | khint_t k, i, last, mask, step = 0; \ 234 | mask = h->n_buckets - 1; \ 235 | k = __hash_func(key); i = k & mask; \ 236 | last = i; \ 237 | while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \ 238 | i = (i + (++step)) & mask; \ 239 | if (i == last) return h->n_buckets; \ 240 | } \ 241 | return __ac_iseither(h->flags, i)? h->n_buckets : i; \ 242 | } else return 0; \ 243 | } \ 244 | SCOPE int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \ 245 | { /* This function uses 0.25*n_buckets bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets. */ \ 246 | khint32_t *new_flags = 0; \ 247 | khint_t j = 1; \ 248 | { \ 249 | kroundup32(new_n_buckets); \ 250 | if (new_n_buckets < 4) new_n_buckets = 4; \ 251 | if (h->size >= (khint_t)(new_n_buckets * __ac_HASH_UPPER + 0.5)) j = 0; /* requested size is too small */ \ 252 | else { /* hash table size to be changed (shrink or expand); rehash */ \ 253 | new_flags = (khint32_t*)kmalloc(__ac_fsize(new_n_buckets) * sizeof(khint32_t)); \ 254 | if (!new_flags) return -1; \ 255 | memset(new_flags, 0xaa, __ac_fsize(new_n_buckets) * sizeof(khint32_t)); \ 256 | if (h->n_buckets < new_n_buckets) { /* expand */ \ 257 | khkey_t *new_keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \ 258 | if (!new_keys) { kfree(new_flags); return -1; } \ 259 | h->keys = new_keys; \ 260 | if (kh_is_map) { \ 261 | khval_t *new_vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \ 262 | if (!new_vals) { kfree(new_flags); return -1; } \ 263 | h->vals = new_vals; \ 264 | } \ 265 | } /* otherwise shrink */ \ 266 | } \ 267 | } \ 268 | if (j) { /* rehashing is needed */ \ 269 | for (j = 0; j != h->n_buckets; ++j) { \ 270 | if (__ac_iseither(h->flags, j) == 0) { \ 271 | khkey_t key = h->keys[j]; \ 272 | khval_t val; \ 273 | khint_t new_mask; \ 274 | new_mask = new_n_buckets - 1; \ 275 | if (kh_is_map) val = h->vals[j]; \ 276 | __ac_set_isdel_true(h->flags, j); \ 277 | while (1) { /* kick-out process; sort of like in Cuckoo hashing */ \ 278 | khint_t k, i, step = 0; \ 279 | k = __hash_func(key); \ 280 | i = k & new_mask; \ 281 | while (!__ac_isempty(new_flags, i)) i = (i + (++step)) & new_mask; \ 282 | __ac_set_isempty_false(new_flags, i); \ 283 | if (i < h->n_buckets && __ac_iseither(h->flags, i) == 0) { /* kick out the existing element */ \ 284 | { khkey_t tmp = h->keys[i]; h->keys[i] = key; key = tmp; } \ 285 | if (kh_is_map) { khval_t tmp = h->vals[i]; h->vals[i] = val; val = tmp; } \ 286 | __ac_set_isdel_true(h->flags, i); /* mark it as deleted in the old hash table */ \ 287 | } else { /* write the element and jump out of the loop */ \ 288 | h->keys[i] = key; \ 289 | if (kh_is_map) h->vals[i] = val; \ 290 | break; \ 291 | } \ 292 | } \ 293 | } \ 294 | } \ 295 | if (h->n_buckets > new_n_buckets) { /* shrink the hash table */ \ 296 | h->keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \ 297 | if (kh_is_map) h->vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \ 298 | } \ 299 | kfree(h->flags); /* free the working space */ \ 300 | h->flags = new_flags; \ 301 | h->n_buckets = new_n_buckets; \ 302 | h->n_occupied = h->size; \ 303 | h->upper_bound = (khint_t)(h->n_buckets * __ac_HASH_UPPER + 0.5); \ 304 | } \ 305 | return 0; \ 306 | } \ 307 | SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \ 308 | { \ 309 | khint_t x; \ 310 | if (h->n_occupied >= h->upper_bound) { /* update the hash table */ \ 311 | if (h->n_buckets > (h->size<<1)) { \ 312 | if (kh_resize_##name(h, h->n_buckets - 1) < 0) { /* clear "deleted" elements */ \ 313 | *ret = -1; return h->n_buckets; \ 314 | } \ 315 | } else if (kh_resize_##name(h, h->n_buckets + 1) < 0) { /* expand the hash table */ \ 316 | *ret = -1; return h->n_buckets; \ 317 | } \ 318 | } /* TODO: to implement automatically shrinking; resize() already support shrinking */ \ 319 | { \ 320 | khint_t k, i, site, last, mask = h->n_buckets - 1, step = 0; \ 321 | x = site = h->n_buckets; k = __hash_func(key); i = k & mask; \ 322 | if (__ac_isempty(h->flags, i)) x = i; /* for speed up */ \ 323 | else { \ 324 | last = i; \ 325 | while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \ 326 | if (__ac_isdel(h->flags, i)) site = i; \ 327 | i = (i + (++step)) & mask; \ 328 | if (i == last) { x = site; break; } \ 329 | } \ 330 | if (x == h->n_buckets) { \ 331 | if (__ac_isempty(h->flags, i) && site != h->n_buckets) x = site; \ 332 | else x = i; \ 333 | } \ 334 | } \ 335 | } \ 336 | if (__ac_isempty(h->flags, x)) { /* not present at all */ \ 337 | h->keys[x] = key; \ 338 | __ac_set_isboth_false(h->flags, x); \ 339 | ++h->size; ++h->n_occupied; \ 340 | *ret = 1; \ 341 | } else if (__ac_isdel(h->flags, x)) { /* deleted */ \ 342 | h->keys[x] = key; \ 343 | __ac_set_isboth_false(h->flags, x); \ 344 | ++h->size; \ 345 | *ret = 2; \ 346 | } else *ret = 0; /* Don't touch h->keys[x] if present and not deleted */ \ 347 | return x; \ 348 | } \ 349 | SCOPE void kh_del_##name(kh_##name##_t *h, khint_t x) \ 350 | { \ 351 | if (x != h->n_buckets && !__ac_iseither(h->flags, x)) { \ 352 | __ac_set_isdel_true(h->flags, x); \ 353 | --h->size; \ 354 | } \ 355 | } 356 | 357 | #define KHASH_DECLARE(name, khkey_t, khval_t) \ 358 | __KHASH_TYPE(name, khkey_t, khval_t) \ 359 | __KHASH_PROTOTYPES(name, khkey_t, khval_t) 360 | 361 | #define KHASH_INIT2(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ 362 | __KHASH_TYPE(name, khkey_t, khval_t) \ 363 | __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) 364 | 365 | #define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ 366 | KHASH_INIT2(name, static kh_inline klib_unused, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) 367 | 368 | /* --- BEGIN OF HASH FUNCTIONS --- */ 369 | 370 | /*! @function 371 | @abstract Integer hash function 372 | @param key The integer [khint32_t] 373 | @return The hash value [khint_t] 374 | */ 375 | #define kh_int_hash_func(key) (khint32_t)(key) 376 | /*! @function 377 | @abstract Integer comparison function 378 | */ 379 | #define kh_int_hash_equal(a, b) ((a) == (b)) 380 | /*! @function 381 | @abstract 64-bit integer hash function 382 | @param key The integer [khint64_t] 383 | @return The hash value [khint_t] 384 | */ 385 | #define kh_int64_hash_func(key) (khint32_t)((key)>>33^(key)^(key)<<11) 386 | /*! @function 387 | @abstract 64-bit integer comparison function 388 | */ 389 | #define kh_int64_hash_equal(a, b) ((a) == (b)) 390 | /*! @function 391 | @abstract const char* hash function 392 | @param s Pointer to a null terminated string 393 | @return The hash value 394 | */ 395 | static kh_inline khint_t __ac_X31_hash_string(const char *s) 396 | { 397 | khint_t h = (khint_t)*s; 398 | if (h) for (++s ; *s; ++s) h = (h << 5) - h + (khint_t)*s; 399 | return h; 400 | } 401 | /*! @function 402 | @abstract Another interface to const char* hash function 403 | @param key Pointer to a null terminated string [const char*] 404 | @return The hash value [khint_t] 405 | */ 406 | #define kh_str_hash_func(key) __ac_X31_hash_string(key) 407 | /*! @function 408 | @abstract Const char* comparison function 409 | */ 410 | #define kh_str_hash_equal(a, b) (strcmp(a, b) == 0) 411 | 412 | static kh_inline khint_t __ac_Wang_hash(khint_t key) 413 | { 414 | key += ~(key << 15); 415 | key ^= (key >> 10); 416 | key += (key << 3); 417 | key ^= (key >> 6); 418 | key += ~(key << 11); 419 | key ^= (key >> 16); 420 | return key; 421 | } 422 | #define kh_int_hash_func2(key) __ac_Wang_hash((khint_t)key) 423 | 424 | /* --- END OF HASH FUNCTIONS --- */ 425 | 426 | /* Other convenient macros... */ 427 | 428 | /*! 429 | @abstract Type of the hash table. 430 | @param name Name of the hash table [symbol] 431 | */ 432 | #define khash_t(name) kh_##name##_t 433 | 434 | /*! @function 435 | @abstract Initiate a hash table. 436 | @param name Name of the hash table [symbol] 437 | @return Pointer to the hash table [khash_t(name)*] 438 | */ 439 | #define kh_init(name) kh_init_##name() 440 | 441 | /*! @function 442 | @abstract Destroy a hash table. 443 | @param name Name of the hash table [symbol] 444 | @param h Pointer to the hash table [khash_t(name)*] 445 | */ 446 | #define kh_destroy(name, h) kh_destroy_##name(h) 447 | 448 | /*! @function 449 | @abstract Reset a hash table without deallocating memory. 450 | @param name Name of the hash table [symbol] 451 | @param h Pointer to the hash table [khash_t(name)*] 452 | */ 453 | #define kh_clear(name, h) kh_clear_##name(h) 454 | 455 | /*! @function 456 | @abstract Resize a hash table. 457 | @param name Name of the hash table [symbol] 458 | @param h Pointer to the hash table [khash_t(name)*] 459 | @param s New size [khint_t] 460 | */ 461 | #define kh_resize(name, h, s) kh_resize_##name(h, s) 462 | 463 | /*! @function 464 | @abstract Insert a key to the hash table. 465 | @param name Name of the hash table [symbol] 466 | @param h Pointer to the hash table [khash_t(name)*] 467 | @param k Key [type of keys] 468 | @param r Extra return code: -1 if the operation failed; 469 | 0 if the key is present in the hash table; 470 | 1 if the bucket is empty (never used); 2 if the element in 471 | the bucket has been deleted [int*] 472 | @return Iterator to the inserted element [khint_t] 473 | */ 474 | #define kh_put(name, h, k, r) kh_put_##name(h, k, r) 475 | 476 | /*! @function 477 | @abstract Retrieve a key from the hash table. 478 | @param name Name of the hash table [symbol] 479 | @param h Pointer to the hash table [khash_t(name)*] 480 | @param k Key [type of keys] 481 | @return Iterator to the found element, or kh_end(h) if the element is absent [khint_t] 482 | */ 483 | #define kh_get(name, h, k) kh_get_##name(h, k) 484 | 485 | /*! @function 486 | @abstract Remove a key from the hash table. 487 | @param name Name of the hash table [symbol] 488 | @param h Pointer to the hash table [khash_t(name)*] 489 | @param k Iterator to the element to be deleted [khint_t] 490 | */ 491 | #define kh_del(name, h, k) kh_del_##name(h, k) 492 | 493 | /*! @function 494 | @abstract Test whether a bucket contains data. 495 | @param h Pointer to the hash table [khash_t(name)*] 496 | @param x Iterator to the bucket [khint_t] 497 | @return 1 if containing data; 0 otherwise [int] 498 | */ 499 | #define kh_exist(h, x) (!__ac_iseither((h)->flags, (x))) 500 | 501 | /*! @function 502 | @abstract Get key given an iterator 503 | @param h Pointer to the hash table [khash_t(name)*] 504 | @param x Iterator to the bucket [khint_t] 505 | @return Key [type of keys] 506 | */ 507 | #define kh_key(h, x) ((h)->keys[x]) 508 | 509 | /*! @function 510 | @abstract Get value given an iterator 511 | @param h Pointer to the hash table [khash_t(name)*] 512 | @param x Iterator to the bucket [khint_t] 513 | @return Value [type of values] 514 | @discussion For hash sets, calling this results in segfault. 515 | */ 516 | #define kh_val(h, x) ((h)->vals[x]) 517 | 518 | /*! @function 519 | @abstract Alias of kh_val() 520 | */ 521 | #define kh_value(h, x) ((h)->vals[x]) 522 | 523 | /*! @function 524 | @abstract Get the start iterator 525 | @param h Pointer to the hash table [khash_t(name)*] 526 | @return The start iterator [khint_t] 527 | */ 528 | #define kh_begin(h) (khint_t)(0) 529 | 530 | /*! @function 531 | @abstract Get the end iterator 532 | @param h Pointer to the hash table [khash_t(name)*] 533 | @return The end iterator [khint_t] 534 | */ 535 | #define kh_end(h) ((h)->n_buckets) 536 | 537 | /*! @function 538 | @abstract Get the number of elements in the hash table 539 | @param h Pointer to the hash table [khash_t(name)*] 540 | @return Number of elements in the hash table [khint_t] 541 | */ 542 | #define kh_size(h) ((h)->size) 543 | 544 | /*! @function 545 | @abstract Get the number of buckets in the hash table 546 | @param h Pointer to the hash table [khash_t(name)*] 547 | @return Number of buckets in the hash table [khint_t] 548 | */ 549 | #define kh_n_buckets(h) ((h)->n_buckets) 550 | 551 | /*! @function 552 | @abstract Iterate over the entries in the hash table 553 | @param h Pointer to the hash table [khash_t(name)*] 554 | @param kvar Variable to which key will be assigned 555 | @param vvar Variable to which value will be assigned 556 | @param code Block of code to execute 557 | */ 558 | #define kh_foreach(h, kvar, vvar, code) { khint_t __i; \ 559 | for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \ 560 | if (!kh_exist(h,__i)) continue; \ 561 | (kvar) = kh_key(h,__i); \ 562 | (vvar) = kh_val(h,__i); \ 563 | code; \ 564 | } } 565 | 566 | /*! @function 567 | @abstract Iterate over the values in the hash table 568 | @param h Pointer to the hash table [khash_t(name)*] 569 | @param vvar Variable to which value will be assigned 570 | @param code Block of code to execute 571 | */ 572 | #define kh_foreach_value(h, vvar, code) { khint_t __i; \ 573 | for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \ 574 | if (!kh_exist(h,__i)) continue; \ 575 | (vvar) = kh_val(h,__i); \ 576 | code; \ 577 | } } 578 | 579 | /* More convenient interfaces */ 580 | 581 | /*! @function 582 | @abstract Instantiate a hash set containing integer keys 583 | @param name Name of the hash table [symbol] 584 | */ 585 | #define KHASH_SET_INIT_INT(name) \ 586 | KHASH_INIT(name, khint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal) 587 | 588 | /*! @function 589 | @abstract Instantiate a hash map containing integer keys 590 | @param name Name of the hash table [symbol] 591 | @param khval_t Type of values [type] 592 | */ 593 | #define KHASH_MAP_INIT_INT(name, khval_t) \ 594 | KHASH_INIT(name, khint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal) 595 | 596 | /*! @function 597 | @abstract Instantiate a hash set containing 64-bit integer keys 598 | @param name Name of the hash table [symbol] 599 | */ 600 | #define KHASH_SET_INIT_INT64(name) \ 601 | KHASH_INIT(name, khint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal) 602 | 603 | /*! @function 604 | @abstract Instantiate a hash map containing 64-bit integer keys 605 | @param name Name of the hash table [symbol] 606 | @param khval_t Type of values [type] 607 | */ 608 | #define KHASH_MAP_INIT_INT64(name, khval_t) \ 609 | KHASH_INIT(name, khint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal) 610 | 611 | typedef const char *kh_cstr_t; 612 | /*! @function 613 | @abstract Instantiate a hash map containing const char* keys 614 | @param name Name of the hash table [symbol] 615 | */ 616 | #define KHASH_SET_INIT_STR(name) \ 617 | KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal) 618 | 619 | /*! @function 620 | @abstract Instantiate a hash map containing const char* keys 621 | @param name Name of the hash table [symbol] 622 | @param khval_t Type of values [type] 623 | */ 624 | #define KHASH_MAP_INIT_STR(name, khval_t) \ 625 | KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal) 626 | 627 | #endif /* __AC_KHASH_H */ -------------------------------------------------------------------------------- /test/main.janet: -------------------------------------------------------------------------------- 1 | (import ../build/curl :as curl) 2 | 3 | (defn download 4 | "Download a file with curl easy" 5 | [url &opt to] 6 | (default to (last (string/split "/" url))) 7 | (def c (curl/easy/init)) 8 | (with [file (file/open to :wb)] 9 | (var run-yet false) 10 | (defn progress [a b c d] 11 | "Progress function while downloading" 12 | (if (zero? b) (break)) 13 | (def out-of-50 14 | (let [x (math/floor (/ (* b 50) a))] 15 | (if (= x x) x 0))) 16 | (def rest (- 50 out-of-50)) 17 | (if run-yet 18 | (:write stdout "\e[F\e[F")) 19 | (set run-yet true) 20 | (print "Downloading \e[36m" url "\n\e[34m[" 21 | (string/repeat "." out-of-50) (string/repeat " " rest) "]\e[0m")) 22 | (:setopt c 23 | :url url 24 | :write-function (fn [buf] (file/write file buf)) 25 | :no-progress? false 26 | :progress-function progress) 27 | (:perform c) 28 | (print "Wrote to \e[36m" to "\e[0m"))) 29 | 30 | (download "https://upload.wikimedia.org/wikipedia/commons/7/79/Big_Buck_Bunny_small.ogv" 31 | "test/DOWNLOAD") 32 | --------------------------------------------------------------------------------