interface.c 110 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Copyright (c) The PHP Group |
  4. +----------------------------------------------------------------------+
  5. | This source file is subject to version 3.01 of the PHP license, |
  6. | that is bundled with this package in the file LICENSE, and is |
  7. | available through the world-wide-web at the following url: |
  8. | https://www.php.net/license/3_01.txt |
  9. | If you did not receive a copy of the PHP license and are unable to |
  10. | obtain it through the world-wide-web, please send a note to |
  11. | license@php.net so we can mail you a copy immediately. |
  12. +----------------------------------------------------------------------+
  13. | Author: Sterling Hughes <sterling@php.net> |
  14. +----------------------------------------------------------------------+
  15. */
  16. #define ZEND_INCLUDE_FULL_WINDOWS_HEADERS
  17. #ifdef HAVE_CONFIG_H
  18. #include "config.h"
  19. #endif
  20. #include "php.h"
  21. #include "Zend/zend_exceptions.h"
  22. #include <stdio.h>
  23. #include <string.h>
  24. #ifdef PHP_WIN32
  25. #include <winsock2.h>
  26. #include <sys/types.h>
  27. #endif
  28. #include <curl/curl.h>
  29. #include <curl/easy.h>
  30. /* As of curl 7.11.1 this is no longer defined inside curl.h */
  31. #ifndef HttpPost
  32. #define HttpPost curl_httppost
  33. #endif
  34. /* {{{ cruft for thread safe SSL crypto locks */
  35. #if defined(ZTS) && defined(HAVE_CURL_OLD_OPENSSL)
  36. # if defined(HAVE_OPENSSL_CRYPTO_H)
  37. # define PHP_CURL_NEED_OPENSSL_TSL
  38. # include <openssl/crypto.h>
  39. # else
  40. # warning \
  41. "libcurl was compiled with OpenSSL support, but configure could not find " \
  42. "openssl/crypto.h; thus no SSL crypto locking callbacks will be set, which may " \
  43. "cause random crashes on SSL requests"
  44. # endif
  45. #endif /* ZTS && HAVE_CURL_OLD_OPENSSL */
  46. /* }}} */
  47. #define SMART_STR_PREALLOC 4096
  48. #include "zend_smart_str.h"
  49. #include "ext/standard/info.h"
  50. #include "ext/standard/file.h"
  51. #include "ext/standard/url.h"
  52. #include "curl_private.h"
  53. #include "curl_arginfo.h"
  54. #ifdef PHP_CURL_NEED_OPENSSL_TSL /* {{{ */
  55. static MUTEX_T *php_curl_openssl_tsl = NULL;
  56. /* Locking callbacks are no longer used since OpenSSL 1.1. Mark the functions as unused to
  57. * avoid warnings due to this. */
  58. static ZEND_ATTRIBUTE_UNUSED void php_curl_ssl_lock(int mode, int n, const char * file, int line)
  59. {
  60. if (mode & CRYPTO_LOCK) {
  61. tsrm_mutex_lock(php_curl_openssl_tsl[n]);
  62. } else {
  63. tsrm_mutex_unlock(php_curl_openssl_tsl[n]);
  64. }
  65. }
  66. static ZEND_ATTRIBUTE_UNUSED unsigned long php_curl_ssl_id(void)
  67. {
  68. return (unsigned long) tsrm_thread_id();
  69. }
  70. #endif
  71. /* }}} */
  72. #define CAAL(s, v) add_assoc_long_ex(return_value, s, sizeof(s) - 1, (zend_long) v);
  73. #define CAAD(s, v) add_assoc_double_ex(return_value, s, sizeof(s) - 1, (double) v);
  74. #define CAAS(s, v) add_assoc_string_ex(return_value, s, sizeof(s) - 1, (char *) (v ? v : ""));
  75. #define CAASTR(s, v) add_assoc_str_ex(return_value, s, sizeof(s) - 1, \
  76. v ? zend_string_copy(v) : ZSTR_EMPTY_ALLOC());
  77. #define CAAZ(s, v) add_assoc_zval_ex(return_value, s, sizeof(s) -1 , (zval *) v);
  78. #if defined(PHP_WIN32) || defined(__GNUC__)
  79. # define php_curl_ret(__ret) RETVAL_FALSE; return __ret;
  80. #else
  81. # define php_curl_ret(__ret) RETVAL_FALSE; return;
  82. #endif
  83. static int php_curl_option_str(php_curl *ch, zend_long option, const char *str, const size_t len)
  84. {
  85. if (strlen(str) != len) {
  86. zend_value_error("%s(): cURL option must not contain any null bytes", get_active_function_name());
  87. return FAILURE;
  88. }
  89. CURLcode error = curl_easy_setopt(ch->cp, option, str);
  90. SAVE_CURL_ERROR(ch, error);
  91. return error == CURLE_OK ? SUCCESS : FAILURE;
  92. }
  93. static int php_curl_option_url(php_curl *ch, const char *url, const size_t len) /* {{{ */
  94. {
  95. /* Disable file:// if open_basedir are used */
  96. if (PG(open_basedir) && *PG(open_basedir)) {
  97. curl_easy_setopt(ch->cp, CURLOPT_PROTOCOLS, CURLPROTO_ALL & ~CURLPROTO_FILE);
  98. }
  99. #if LIBCURL_VERSION_NUM > 0x073800 && defined(PHP_WIN32)
  100. if (len > sizeof("file://") - 1 && '/' != url[sizeof("file://") - 1] && !strncmp("file://", url, sizeof("file://") - 1) && len < MAXPATHLEN - 2) {
  101. char _tmp[MAXPATHLEN] = {0};
  102. memmove(_tmp, "file:///", sizeof("file:///") - 1);
  103. memmove(_tmp + sizeof("file:///") - 1, url + sizeof("file://") - 1, len - sizeof("file://") + 1);
  104. return php_curl_option_str(ch, CURLOPT_URL, _tmp, len + 1);
  105. }
  106. #endif
  107. return php_curl_option_str(ch, CURLOPT_URL, url, len);
  108. }
  109. /* }}} */
  110. void _php_curl_verify_handlers(php_curl *ch, int reporterror) /* {{{ */
  111. {
  112. php_stream *stream;
  113. ZEND_ASSERT(ch);
  114. if (!Z_ISUNDEF(ch->handlers.std_err)) {
  115. stream = (php_stream *)zend_fetch_resource2_ex(&ch->handlers.std_err, NULL, php_file_le_stream(), php_file_le_pstream());
  116. if (stream == NULL) {
  117. if (reporterror) {
  118. php_error_docref(NULL, E_WARNING, "CURLOPT_STDERR resource has gone away, resetting to stderr");
  119. }
  120. zval_ptr_dtor(&ch->handlers.std_err);
  121. ZVAL_UNDEF(&ch->handlers.std_err);
  122. curl_easy_setopt(ch->cp, CURLOPT_STDERR, stderr);
  123. }
  124. }
  125. if (ch->handlers.read && !Z_ISUNDEF(ch->handlers.read->stream)) {
  126. stream = (php_stream *)zend_fetch_resource2_ex(&ch->handlers.read->stream, NULL, php_file_le_stream(), php_file_le_pstream());
  127. if (stream == NULL) {
  128. if (reporterror) {
  129. php_error_docref(NULL, E_WARNING, "CURLOPT_INFILE resource has gone away, resetting to default");
  130. }
  131. zval_ptr_dtor(&ch->handlers.read->stream);
  132. ZVAL_UNDEF(&ch->handlers.read->stream);
  133. ch->handlers.read->res = NULL;
  134. ch->handlers.read->fp = 0;
  135. curl_easy_setopt(ch->cp, CURLOPT_INFILE, (void *) ch);
  136. }
  137. }
  138. if (ch->handlers.write_header && !Z_ISUNDEF(ch->handlers.write_header->stream)) {
  139. stream = (php_stream *)zend_fetch_resource2_ex(&ch->handlers.write_header->stream, NULL, php_file_le_stream(), php_file_le_pstream());
  140. if (stream == NULL) {
  141. if (reporterror) {
  142. php_error_docref(NULL, E_WARNING, "CURLOPT_WRITEHEADER resource has gone away, resetting to default");
  143. }
  144. zval_ptr_dtor(&ch->handlers.write_header->stream);
  145. ZVAL_UNDEF(&ch->handlers.write_header->stream);
  146. ch->handlers.write_header->fp = 0;
  147. ch->handlers.write_header->method = PHP_CURL_IGNORE;
  148. curl_easy_setopt(ch->cp, CURLOPT_WRITEHEADER, (void *) ch);
  149. }
  150. }
  151. if (ch->handlers.write && !Z_ISUNDEF(ch->handlers.write->stream)) {
  152. stream = (php_stream *)zend_fetch_resource2_ex(&ch->handlers.write->stream, NULL, php_file_le_stream(), php_file_le_pstream());
  153. if (stream == NULL) {
  154. if (reporterror) {
  155. php_error_docref(NULL, E_WARNING, "CURLOPT_FILE resource has gone away, resetting to default");
  156. }
  157. zval_ptr_dtor(&ch->handlers.write->stream);
  158. ZVAL_UNDEF(&ch->handlers.write->stream);
  159. ch->handlers.write->fp = 0;
  160. ch->handlers.write->method = PHP_CURL_STDOUT;
  161. curl_easy_setopt(ch->cp, CURLOPT_FILE, (void *) ch);
  162. }
  163. }
  164. return;
  165. }
  166. /* }}} */
  167. /* {{{ curl_module_entry */
  168. zend_module_entry curl_module_entry = {
  169. STANDARD_MODULE_HEADER,
  170. "curl",
  171. ext_functions,
  172. PHP_MINIT(curl),
  173. PHP_MSHUTDOWN(curl),
  174. NULL,
  175. NULL,
  176. PHP_MINFO(curl),
  177. PHP_CURL_VERSION,
  178. STANDARD_MODULE_PROPERTIES
  179. };
  180. /* }}} */
  181. #ifdef COMPILE_DL_CURL
  182. ZEND_GET_MODULE (curl)
  183. #endif
  184. /* CurlHandle class */
  185. zend_class_entry *curl_ce;
  186. zend_class_entry *curl_share_ce;
  187. static zend_object_handlers curl_object_handlers;
  188. static zend_object *curl_create_object(zend_class_entry *class_type);
  189. static void curl_free_obj(zend_object *object);
  190. static HashTable *curl_get_gc(zend_object *object, zval **table, int *n);
  191. static zend_function *curl_get_constructor(zend_object *object);
  192. static zend_object *curl_clone_obj(zend_object *object);
  193. php_curl *init_curl_handle_into_zval(zval *curl);
  194. static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields);
  195. /* {{{ PHP_INI_BEGIN */
  196. PHP_INI_BEGIN()
  197. PHP_INI_ENTRY("curl.cainfo", "", PHP_INI_SYSTEM, NULL)
  198. PHP_INI_END()
  199. /* }}} */
  200. /* {{{ PHP_MINFO_FUNCTION */
  201. PHP_MINFO_FUNCTION(curl)
  202. {
  203. curl_version_info_data *d;
  204. char **p;
  205. char str[1024];
  206. size_t n = 0;
  207. d = curl_version_info(CURLVERSION_NOW);
  208. php_info_print_table_start();
  209. php_info_print_table_row(2, "cURL support", "enabled");
  210. php_info_print_table_row(2, "cURL Information", d->version);
  211. sprintf(str, "%d", d->age);
  212. php_info_print_table_row(2, "Age", str);
  213. /* To update on each new cURL release using src/main.c in cURL sources */
  214. if (d->features) {
  215. struct feat {
  216. const char *name;
  217. int bitmask;
  218. };
  219. unsigned int i;
  220. static const struct feat feats[] = {
  221. {"AsynchDNS", CURL_VERSION_ASYNCHDNS},
  222. {"CharConv", CURL_VERSION_CONV},
  223. {"Debug", CURL_VERSION_DEBUG},
  224. {"GSS-Negotiate", CURL_VERSION_GSSNEGOTIATE},
  225. {"IDN", CURL_VERSION_IDN},
  226. {"IPv6", CURL_VERSION_IPV6},
  227. {"krb4", CURL_VERSION_KERBEROS4},
  228. {"Largefile", CURL_VERSION_LARGEFILE},
  229. {"libz", CURL_VERSION_LIBZ},
  230. {"NTLM", CURL_VERSION_NTLM},
  231. {"NTLMWB", CURL_VERSION_NTLM_WB},
  232. {"SPNEGO", CURL_VERSION_SPNEGO},
  233. {"SSL", CURL_VERSION_SSL},
  234. {"SSPI", CURL_VERSION_SSPI},
  235. {"TLS-SRP", CURL_VERSION_TLSAUTH_SRP},
  236. #if LIBCURL_VERSION_NUM >= 0x072100 /* 7.33.0 */
  237. {"HTTP2", CURL_VERSION_HTTP2},
  238. #endif
  239. #if LIBCURL_VERSION_NUM >= 0x072600 /* 7.38.0 */
  240. {"GSSAPI", CURL_VERSION_GSSAPI},
  241. #endif
  242. #if LIBCURL_VERSION_NUM >= 0x072800 /* 7.40.0 */
  243. {"KERBEROS5", CURL_VERSION_KERBEROS5},
  244. {"UNIX_SOCKETS", CURL_VERSION_UNIX_SOCKETS},
  245. #endif
  246. #if LIBCURL_VERSION_NUM >= 0x072f00 /* 7.47.0 */
  247. {"PSL", CURL_VERSION_PSL},
  248. #endif
  249. #if LIBCURL_VERSION_NUM >= 0x073400 /* 7.52.0 */
  250. {"HTTPS_PROXY", CURL_VERSION_HTTPS_PROXY},
  251. #endif
  252. #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
  253. {"MULTI_SSL", CURL_VERSION_MULTI_SSL},
  254. #endif
  255. #if LIBCURL_VERSION_NUM >= 0x073900 /* 7.57.0 */
  256. {"BROTLI", CURL_VERSION_BROTLI},
  257. #endif
  258. {NULL, 0}
  259. };
  260. php_info_print_table_row(1, "Features");
  261. for(i=0; i<sizeof(feats)/sizeof(feats[0]); i++) {
  262. if (feats[i].name) {
  263. php_info_print_table_row(2, feats[i].name, d->features & feats[i].bitmask ? "Yes" : "No");
  264. }
  265. }
  266. }
  267. n = 0;
  268. p = (char **) d->protocols;
  269. while (*p != NULL) {
  270. n += sprintf(str + n, "%s%s", *p, *(p + 1) != NULL ? ", " : "");
  271. p++;
  272. }
  273. php_info_print_table_row(2, "Protocols", str);
  274. php_info_print_table_row(2, "Host", d->host);
  275. if (d->ssl_version) {
  276. php_info_print_table_row(2, "SSL Version", d->ssl_version);
  277. }
  278. if (d->libz_version) {
  279. php_info_print_table_row(2, "ZLib Version", d->libz_version);
  280. }
  281. #if defined(CURLVERSION_SECOND) && CURLVERSION_NOW >= CURLVERSION_SECOND
  282. if (d->ares) {
  283. php_info_print_table_row(2, "ZLib Version", d->ares);
  284. }
  285. #endif
  286. #if defined(CURLVERSION_THIRD) && CURLVERSION_NOW >= CURLVERSION_THIRD
  287. if (d->libidn) {
  288. php_info_print_table_row(2, "libIDN Version", d->libidn);
  289. }
  290. #endif
  291. if (d->iconv_ver_num) {
  292. php_info_print_table_row(2, "IconV Version", d->iconv_ver_num);
  293. }
  294. if (d->libssh_version) {
  295. php_info_print_table_row(2, "libSSH Version", d->libssh_version);
  296. }
  297. php_info_print_table_end();
  298. DISPLAY_INI_ENTRIES();
  299. }
  300. /* }}} */
  301. #define REGISTER_CURL_CONSTANT(__c) REGISTER_LONG_CONSTANT(#__c, __c, CONST_CS | CONST_PERSISTENT)
  302. /* {{{ PHP_MINIT_FUNCTION */
  303. PHP_MINIT_FUNCTION(curl)
  304. {
  305. REGISTER_INI_ENTRIES();
  306. /* See http://curl.haxx.se/lxr/source/docs/libcurl/symbols-in-versions
  307. or curl src/docs/libcurl/symbols-in-versions for a (almost) complete list
  308. of options and which version they were introduced */
  309. /* Constants for curl_setopt() */
  310. REGISTER_CURL_CONSTANT(CURLOPT_AUTOREFERER);
  311. REGISTER_CURL_CONSTANT(CURLOPT_BINARYTRANSFER);
  312. REGISTER_CURL_CONSTANT(CURLOPT_BUFFERSIZE);
  313. REGISTER_CURL_CONSTANT(CURLOPT_CAINFO);
  314. REGISTER_CURL_CONSTANT(CURLOPT_CAPATH);
  315. REGISTER_CURL_CONSTANT(CURLOPT_CONNECTTIMEOUT);
  316. REGISTER_CURL_CONSTANT(CURLOPT_COOKIE);
  317. REGISTER_CURL_CONSTANT(CURLOPT_COOKIEFILE);
  318. REGISTER_CURL_CONSTANT(CURLOPT_COOKIEJAR);
  319. REGISTER_CURL_CONSTANT(CURLOPT_COOKIESESSION);
  320. REGISTER_CURL_CONSTANT(CURLOPT_CRLF);
  321. REGISTER_CURL_CONSTANT(CURLOPT_CUSTOMREQUEST);
  322. REGISTER_CURL_CONSTANT(CURLOPT_DNS_CACHE_TIMEOUT);
  323. REGISTER_CURL_CONSTANT(CURLOPT_DNS_USE_GLOBAL_CACHE);
  324. REGISTER_CURL_CONSTANT(CURLOPT_EGDSOCKET);
  325. REGISTER_CURL_CONSTANT(CURLOPT_ENCODING);
  326. REGISTER_CURL_CONSTANT(CURLOPT_FAILONERROR);
  327. REGISTER_CURL_CONSTANT(CURLOPT_FILE);
  328. REGISTER_CURL_CONSTANT(CURLOPT_FILETIME);
  329. REGISTER_CURL_CONSTANT(CURLOPT_FOLLOWLOCATION);
  330. REGISTER_CURL_CONSTANT(CURLOPT_FORBID_REUSE);
  331. REGISTER_CURL_CONSTANT(CURLOPT_FRESH_CONNECT);
  332. REGISTER_CURL_CONSTANT(CURLOPT_FTPAPPEND);
  333. REGISTER_CURL_CONSTANT(CURLOPT_FTPLISTONLY);
  334. REGISTER_CURL_CONSTANT(CURLOPT_FTPPORT);
  335. REGISTER_CURL_CONSTANT(CURLOPT_FTP_USE_EPRT);
  336. REGISTER_CURL_CONSTANT(CURLOPT_FTP_USE_EPSV);
  337. REGISTER_CURL_CONSTANT(CURLOPT_HEADER);
  338. REGISTER_CURL_CONSTANT(CURLOPT_HEADERFUNCTION);
  339. REGISTER_CURL_CONSTANT(CURLOPT_HTTP200ALIASES);
  340. REGISTER_CURL_CONSTANT(CURLOPT_HTTPGET);
  341. REGISTER_CURL_CONSTANT(CURLOPT_HTTPHEADER);
  342. REGISTER_CURL_CONSTANT(CURLOPT_HTTPPROXYTUNNEL);
  343. REGISTER_CURL_CONSTANT(CURLOPT_HTTP_VERSION);
  344. REGISTER_CURL_CONSTANT(CURLOPT_INFILE);
  345. REGISTER_CURL_CONSTANT(CURLOPT_INFILESIZE);
  346. REGISTER_CURL_CONSTANT(CURLOPT_INTERFACE);
  347. REGISTER_CURL_CONSTANT(CURLOPT_KRB4LEVEL);
  348. REGISTER_CURL_CONSTANT(CURLOPT_LOW_SPEED_LIMIT);
  349. REGISTER_CURL_CONSTANT(CURLOPT_LOW_SPEED_TIME);
  350. REGISTER_CURL_CONSTANT(CURLOPT_MAXCONNECTS);
  351. REGISTER_CURL_CONSTANT(CURLOPT_MAXREDIRS);
  352. REGISTER_CURL_CONSTANT(CURLOPT_NETRC);
  353. REGISTER_CURL_CONSTANT(CURLOPT_NOBODY);
  354. REGISTER_CURL_CONSTANT(CURLOPT_NOPROGRESS);
  355. REGISTER_CURL_CONSTANT(CURLOPT_NOSIGNAL);
  356. REGISTER_CURL_CONSTANT(CURLOPT_PORT);
  357. REGISTER_CURL_CONSTANT(CURLOPT_POST);
  358. REGISTER_CURL_CONSTANT(CURLOPT_POSTFIELDS);
  359. REGISTER_CURL_CONSTANT(CURLOPT_POSTQUOTE);
  360. REGISTER_CURL_CONSTANT(CURLOPT_PREQUOTE);
  361. REGISTER_CURL_CONSTANT(CURLOPT_PRIVATE);
  362. REGISTER_CURL_CONSTANT(CURLOPT_PROGRESSFUNCTION);
  363. REGISTER_CURL_CONSTANT(CURLOPT_PROXY);
  364. REGISTER_CURL_CONSTANT(CURLOPT_PROXYPORT);
  365. REGISTER_CURL_CONSTANT(CURLOPT_PROXYTYPE);
  366. REGISTER_CURL_CONSTANT(CURLOPT_PROXYUSERPWD);
  367. REGISTER_CURL_CONSTANT(CURLOPT_PUT);
  368. REGISTER_CURL_CONSTANT(CURLOPT_QUOTE);
  369. REGISTER_CURL_CONSTANT(CURLOPT_RANDOM_FILE);
  370. REGISTER_CURL_CONSTANT(CURLOPT_RANGE);
  371. REGISTER_CURL_CONSTANT(CURLOPT_READDATA);
  372. REGISTER_CURL_CONSTANT(CURLOPT_READFUNCTION);
  373. REGISTER_CURL_CONSTANT(CURLOPT_REFERER);
  374. REGISTER_CURL_CONSTANT(CURLOPT_RESUME_FROM);
  375. REGISTER_CURL_CONSTANT(CURLOPT_RETURNTRANSFER);
  376. REGISTER_CURL_CONSTANT(CURLOPT_SHARE);
  377. REGISTER_CURL_CONSTANT(CURLOPT_SSLCERT);
  378. REGISTER_CURL_CONSTANT(CURLOPT_SSLCERTPASSWD);
  379. REGISTER_CURL_CONSTANT(CURLOPT_SSLCERTTYPE);
  380. REGISTER_CURL_CONSTANT(CURLOPT_SSLENGINE);
  381. REGISTER_CURL_CONSTANT(CURLOPT_SSLENGINE_DEFAULT);
  382. REGISTER_CURL_CONSTANT(CURLOPT_SSLKEY);
  383. REGISTER_CURL_CONSTANT(CURLOPT_SSLKEYPASSWD);
  384. REGISTER_CURL_CONSTANT(CURLOPT_SSLKEYTYPE);
  385. REGISTER_CURL_CONSTANT(CURLOPT_SSLVERSION);
  386. REGISTER_CURL_CONSTANT(CURLOPT_SSL_CIPHER_LIST);
  387. REGISTER_CURL_CONSTANT(CURLOPT_SSL_VERIFYHOST);
  388. REGISTER_CURL_CONSTANT(CURLOPT_SSL_VERIFYPEER);
  389. REGISTER_CURL_CONSTANT(CURLOPT_STDERR);
  390. REGISTER_CURL_CONSTANT(CURLOPT_TELNETOPTIONS);
  391. REGISTER_CURL_CONSTANT(CURLOPT_TIMECONDITION);
  392. REGISTER_CURL_CONSTANT(CURLOPT_TIMEOUT);
  393. REGISTER_CURL_CONSTANT(CURLOPT_TIMEVALUE);
  394. REGISTER_CURL_CONSTANT(CURLOPT_TRANSFERTEXT);
  395. REGISTER_CURL_CONSTANT(CURLOPT_UNRESTRICTED_AUTH);
  396. REGISTER_CURL_CONSTANT(CURLOPT_UPLOAD);
  397. REGISTER_CURL_CONSTANT(CURLOPT_URL);
  398. REGISTER_CURL_CONSTANT(CURLOPT_USERAGENT);
  399. REGISTER_CURL_CONSTANT(CURLOPT_USERPWD);
  400. REGISTER_CURL_CONSTANT(CURLOPT_VERBOSE);
  401. REGISTER_CURL_CONSTANT(CURLOPT_WRITEFUNCTION);
  402. REGISTER_CURL_CONSTANT(CURLOPT_WRITEHEADER);
  403. /* */
  404. REGISTER_CURL_CONSTANT(CURLE_ABORTED_BY_CALLBACK);
  405. REGISTER_CURL_CONSTANT(CURLE_BAD_CALLING_ORDER);
  406. REGISTER_CURL_CONSTANT(CURLE_BAD_CONTENT_ENCODING);
  407. REGISTER_CURL_CONSTANT(CURLE_BAD_DOWNLOAD_RESUME);
  408. REGISTER_CURL_CONSTANT(CURLE_BAD_FUNCTION_ARGUMENT);
  409. REGISTER_CURL_CONSTANT(CURLE_BAD_PASSWORD_ENTERED);
  410. REGISTER_CURL_CONSTANT(CURLE_COULDNT_CONNECT);
  411. REGISTER_CURL_CONSTANT(CURLE_COULDNT_RESOLVE_HOST);
  412. REGISTER_CURL_CONSTANT(CURLE_COULDNT_RESOLVE_PROXY);
  413. REGISTER_CURL_CONSTANT(CURLE_FAILED_INIT);
  414. REGISTER_CURL_CONSTANT(CURLE_FILE_COULDNT_READ_FILE);
  415. REGISTER_CURL_CONSTANT(CURLE_FTP_ACCESS_DENIED);
  416. REGISTER_CURL_CONSTANT(CURLE_FTP_BAD_DOWNLOAD_RESUME);
  417. REGISTER_CURL_CONSTANT(CURLE_FTP_CANT_GET_HOST);
  418. REGISTER_CURL_CONSTANT(CURLE_FTP_CANT_RECONNECT);
  419. REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_GET_SIZE);
  420. REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_RETR_FILE);
  421. REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_SET_ASCII);
  422. REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_SET_BINARY);
  423. REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_STOR_FILE);
  424. REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_USE_REST);
  425. REGISTER_CURL_CONSTANT(CURLE_FTP_PARTIAL_FILE);
  426. REGISTER_CURL_CONSTANT(CURLE_FTP_PORT_FAILED);
  427. REGISTER_CURL_CONSTANT(CURLE_FTP_QUOTE_ERROR);
  428. REGISTER_CURL_CONSTANT(CURLE_FTP_USER_PASSWORD_INCORRECT);
  429. REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_227_FORMAT);
  430. REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_PASS_REPLY);
  431. REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_PASV_REPLY);
  432. REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_SERVER_REPLY);
  433. REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_USER_REPLY);
  434. REGISTER_CURL_CONSTANT(CURLE_FTP_WRITE_ERROR);
  435. REGISTER_CURL_CONSTANT(CURLE_FUNCTION_NOT_FOUND);
  436. REGISTER_CURL_CONSTANT(CURLE_GOT_NOTHING);
  437. REGISTER_CURL_CONSTANT(CURLE_HTTP_NOT_FOUND);
  438. REGISTER_CURL_CONSTANT(CURLE_HTTP_PORT_FAILED);
  439. REGISTER_CURL_CONSTANT(CURLE_HTTP_POST_ERROR);
  440. REGISTER_CURL_CONSTANT(CURLE_HTTP_RANGE_ERROR);
  441. REGISTER_CURL_CONSTANT(CURLE_HTTP_RETURNED_ERROR);
  442. REGISTER_CURL_CONSTANT(CURLE_LDAP_CANNOT_BIND);
  443. REGISTER_CURL_CONSTANT(CURLE_LDAP_SEARCH_FAILED);
  444. REGISTER_CURL_CONSTANT(CURLE_LIBRARY_NOT_FOUND);
  445. REGISTER_CURL_CONSTANT(CURLE_MALFORMAT_USER);
  446. REGISTER_CURL_CONSTANT(CURLE_OBSOLETE);
  447. REGISTER_CURL_CONSTANT(CURLE_OK);
  448. REGISTER_CURL_CONSTANT(CURLE_OPERATION_TIMEDOUT);
  449. REGISTER_CURL_CONSTANT(CURLE_OPERATION_TIMEOUTED);
  450. REGISTER_CURL_CONSTANT(CURLE_OUT_OF_MEMORY);
  451. REGISTER_CURL_CONSTANT(CURLE_PARTIAL_FILE);
  452. REGISTER_CURL_CONSTANT(CURLE_READ_ERROR);
  453. REGISTER_CURL_CONSTANT(CURLE_RECV_ERROR);
  454. REGISTER_CURL_CONSTANT(CURLE_SEND_ERROR);
  455. REGISTER_CURL_CONSTANT(CURLE_SHARE_IN_USE);
  456. REGISTER_CURL_CONSTANT(CURLE_SSL_CACERT);
  457. REGISTER_CURL_CONSTANT(CURLE_SSL_CERTPROBLEM);
  458. REGISTER_CURL_CONSTANT(CURLE_SSL_CIPHER);
  459. REGISTER_CURL_CONSTANT(CURLE_SSL_CONNECT_ERROR);
  460. REGISTER_CURL_CONSTANT(CURLE_SSL_ENGINE_NOTFOUND);
  461. REGISTER_CURL_CONSTANT(CURLE_SSL_ENGINE_SETFAILED);
  462. REGISTER_CURL_CONSTANT(CURLE_SSL_PEER_CERTIFICATE);
  463. #if LIBCURL_VERSION_NUM >= 0x072700 /* Available since 7.39.0 */
  464. REGISTER_CURL_CONSTANT(CURLE_SSL_PINNEDPUBKEYNOTMATCH);
  465. #endif
  466. REGISTER_CURL_CONSTANT(CURLE_TELNET_OPTION_SYNTAX);
  467. REGISTER_CURL_CONSTANT(CURLE_TOO_MANY_REDIRECTS);
  468. REGISTER_CURL_CONSTANT(CURLE_UNKNOWN_TELNET_OPTION);
  469. REGISTER_CURL_CONSTANT(CURLE_UNSUPPORTED_PROTOCOL);
  470. REGISTER_CURL_CONSTANT(CURLE_URL_MALFORMAT);
  471. REGISTER_CURL_CONSTANT(CURLE_URL_MALFORMAT_USER);
  472. REGISTER_CURL_CONSTANT(CURLE_WRITE_ERROR);
  473. /* cURL info constants */
  474. REGISTER_CURL_CONSTANT(CURLINFO_CONNECT_TIME);
  475. REGISTER_CURL_CONSTANT(CURLINFO_CONTENT_LENGTH_DOWNLOAD);
  476. REGISTER_CURL_CONSTANT(CURLINFO_CONTENT_LENGTH_UPLOAD);
  477. REGISTER_CURL_CONSTANT(CURLINFO_CONTENT_TYPE);
  478. REGISTER_CURL_CONSTANT(CURLINFO_EFFECTIVE_URL);
  479. REGISTER_CURL_CONSTANT(CURLINFO_FILETIME);
  480. REGISTER_CURL_CONSTANT(CURLINFO_HEADER_OUT);
  481. REGISTER_CURL_CONSTANT(CURLINFO_HEADER_SIZE);
  482. REGISTER_CURL_CONSTANT(CURLINFO_HTTP_CODE);
  483. REGISTER_CURL_CONSTANT(CURLINFO_LASTONE);
  484. REGISTER_CURL_CONSTANT(CURLINFO_NAMELOOKUP_TIME);
  485. REGISTER_CURL_CONSTANT(CURLINFO_PRETRANSFER_TIME);
  486. REGISTER_CURL_CONSTANT(CURLINFO_PRIVATE);
  487. REGISTER_CURL_CONSTANT(CURLINFO_REDIRECT_COUNT);
  488. REGISTER_CURL_CONSTANT(CURLINFO_REDIRECT_TIME);
  489. REGISTER_CURL_CONSTANT(CURLINFO_REQUEST_SIZE);
  490. REGISTER_CURL_CONSTANT(CURLINFO_SIZE_DOWNLOAD);
  491. REGISTER_CURL_CONSTANT(CURLINFO_SIZE_UPLOAD);
  492. REGISTER_CURL_CONSTANT(CURLINFO_SPEED_DOWNLOAD);
  493. REGISTER_CURL_CONSTANT(CURLINFO_SPEED_UPLOAD);
  494. REGISTER_CURL_CONSTANT(CURLINFO_SSL_VERIFYRESULT);
  495. REGISTER_CURL_CONSTANT(CURLINFO_STARTTRANSFER_TIME);
  496. REGISTER_CURL_CONSTANT(CURLINFO_TOTAL_TIME);
  497. /* Other */
  498. REGISTER_CURL_CONSTANT(CURLMSG_DONE);
  499. REGISTER_CURL_CONSTANT(CURLVERSION_NOW);
  500. /* Curl Multi Constants */
  501. REGISTER_CURL_CONSTANT(CURLM_BAD_EASY_HANDLE);
  502. REGISTER_CURL_CONSTANT(CURLM_BAD_HANDLE);
  503. REGISTER_CURL_CONSTANT(CURLM_CALL_MULTI_PERFORM);
  504. REGISTER_CURL_CONSTANT(CURLM_INTERNAL_ERROR);
  505. REGISTER_CURL_CONSTANT(CURLM_OK);
  506. REGISTER_CURL_CONSTANT(CURLM_OUT_OF_MEMORY);
  507. #if LIBCURL_VERSION_NUM >= 0x072001 /* Available since 7.32.1 */
  508. REGISTER_CURL_CONSTANT(CURLM_ADDED_ALREADY);
  509. #endif
  510. /* Curl proxy constants */
  511. REGISTER_CURL_CONSTANT(CURLPROXY_HTTP);
  512. REGISTER_CURL_CONSTANT(CURLPROXY_SOCKS4);
  513. REGISTER_CURL_CONSTANT(CURLPROXY_SOCKS5);
  514. /* Curl Share constants */
  515. REGISTER_CURL_CONSTANT(CURLSHOPT_NONE);
  516. REGISTER_CURL_CONSTANT(CURLSHOPT_SHARE);
  517. REGISTER_CURL_CONSTANT(CURLSHOPT_UNSHARE);
  518. /* Curl Http Version constants (CURLOPT_HTTP_VERSION) */
  519. REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_1_0);
  520. REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_1_1);
  521. REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_NONE);
  522. /* Curl Lock constants */
  523. REGISTER_CURL_CONSTANT(CURL_LOCK_DATA_COOKIE);
  524. REGISTER_CURL_CONSTANT(CURL_LOCK_DATA_DNS);
  525. REGISTER_CURL_CONSTANT(CURL_LOCK_DATA_SSL_SESSION);
  526. /* Curl NETRC constants (CURLOPT_NETRC) */
  527. REGISTER_CURL_CONSTANT(CURL_NETRC_IGNORED);
  528. REGISTER_CURL_CONSTANT(CURL_NETRC_OPTIONAL);
  529. REGISTER_CURL_CONSTANT(CURL_NETRC_REQUIRED);
  530. /* Curl SSL Version constants (CURLOPT_SSLVERSION) */
  531. REGISTER_CURL_CONSTANT(CURL_SSLVERSION_DEFAULT);
  532. REGISTER_CURL_CONSTANT(CURL_SSLVERSION_SSLv2);
  533. REGISTER_CURL_CONSTANT(CURL_SSLVERSION_SSLv3);
  534. REGISTER_CURL_CONSTANT(CURL_SSLVERSION_TLSv1);
  535. /* Curl TIMECOND constants (CURLOPT_TIMECONDITION) */
  536. REGISTER_CURL_CONSTANT(CURL_TIMECOND_IFMODSINCE);
  537. REGISTER_CURL_CONSTANT(CURL_TIMECOND_IFUNMODSINCE);
  538. REGISTER_CURL_CONSTANT(CURL_TIMECOND_LASTMOD);
  539. REGISTER_CURL_CONSTANT(CURL_TIMECOND_NONE);
  540. /* Curl version constants */
  541. REGISTER_CURL_CONSTANT(CURL_VERSION_ASYNCHDNS);
  542. REGISTER_CURL_CONSTANT(CURL_VERSION_CONV);
  543. REGISTER_CURL_CONSTANT(CURL_VERSION_DEBUG);
  544. REGISTER_CURL_CONSTANT(CURL_VERSION_GSSNEGOTIATE);
  545. REGISTER_CURL_CONSTANT(CURL_VERSION_IDN);
  546. REGISTER_CURL_CONSTANT(CURL_VERSION_IPV6);
  547. REGISTER_CURL_CONSTANT(CURL_VERSION_KERBEROS4);
  548. REGISTER_CURL_CONSTANT(CURL_VERSION_LARGEFILE);
  549. REGISTER_CURL_CONSTANT(CURL_VERSION_LIBZ);
  550. REGISTER_CURL_CONSTANT(CURL_VERSION_NTLM);
  551. REGISTER_CURL_CONSTANT(CURL_VERSION_SPNEGO);
  552. REGISTER_CURL_CONSTANT(CURL_VERSION_SSL);
  553. REGISTER_CURL_CONSTANT(CURL_VERSION_SSPI);
  554. /* Available since 7.10.6 */
  555. REGISTER_CURL_CONSTANT(CURLOPT_HTTPAUTH);
  556. /* http authentication options */
  557. REGISTER_CURL_CONSTANT(CURLAUTH_ANY);
  558. REGISTER_CURL_CONSTANT(CURLAUTH_ANYSAFE);
  559. REGISTER_CURL_CONSTANT(CURLAUTH_BASIC);
  560. REGISTER_CURL_CONSTANT(CURLAUTH_DIGEST);
  561. REGISTER_CURL_CONSTANT(CURLAUTH_GSSNEGOTIATE);
  562. REGISTER_CURL_CONSTANT(CURLAUTH_NONE);
  563. REGISTER_CURL_CONSTANT(CURLAUTH_NTLM);
  564. /* Available since 7.10.7 */
  565. REGISTER_CURL_CONSTANT(CURLINFO_HTTP_CONNECTCODE);
  566. REGISTER_CURL_CONSTANT(CURLOPT_FTP_CREATE_MISSING_DIRS);
  567. REGISTER_CURL_CONSTANT(CURLOPT_PROXYAUTH);
  568. /* Available since 7.10.8 */
  569. REGISTER_CURL_CONSTANT(CURLE_FILESIZE_EXCEEDED);
  570. REGISTER_CURL_CONSTANT(CURLE_LDAP_INVALID_URL);
  571. REGISTER_CURL_CONSTANT(CURLINFO_HTTPAUTH_AVAIL);
  572. REGISTER_CURL_CONSTANT(CURLINFO_RESPONSE_CODE);
  573. REGISTER_CURL_CONSTANT(CURLINFO_PROXYAUTH_AVAIL);
  574. REGISTER_CURL_CONSTANT(CURLOPT_FTP_RESPONSE_TIMEOUT);
  575. REGISTER_CURL_CONSTANT(CURLOPT_IPRESOLVE);
  576. REGISTER_CURL_CONSTANT(CURLOPT_MAXFILESIZE);
  577. REGISTER_CURL_CONSTANT(CURL_IPRESOLVE_V4);
  578. REGISTER_CURL_CONSTANT(CURL_IPRESOLVE_V6);
  579. REGISTER_CURL_CONSTANT(CURL_IPRESOLVE_WHATEVER);
  580. /* Available since 7.11.0 */
  581. REGISTER_CURL_CONSTANT(CURLE_FTP_SSL_FAILED);
  582. REGISTER_CURL_CONSTANT(CURLFTPSSL_ALL);
  583. REGISTER_CURL_CONSTANT(CURLFTPSSL_CONTROL);
  584. REGISTER_CURL_CONSTANT(CURLFTPSSL_NONE);
  585. REGISTER_CURL_CONSTANT(CURLFTPSSL_TRY);
  586. REGISTER_CURL_CONSTANT(CURLOPT_FTP_SSL);
  587. REGISTER_CURL_CONSTANT(CURLOPT_NETRC_FILE);
  588. /* Available since 7.11.2 */
  589. REGISTER_CURL_CONSTANT(CURLOPT_TCP_NODELAY);
  590. /* Available since 7.12.2 */
  591. REGISTER_CURL_CONSTANT(CURLFTPAUTH_DEFAULT);
  592. REGISTER_CURL_CONSTANT(CURLFTPAUTH_SSL);
  593. REGISTER_CURL_CONSTANT(CURLFTPAUTH_TLS);
  594. REGISTER_CURL_CONSTANT(CURLOPT_FTPSSLAUTH);
  595. /* Available since 7.13.0 */
  596. REGISTER_CURL_CONSTANT(CURLOPT_FTP_ACCOUNT);
  597. /* Available since 7.12.2 */
  598. REGISTER_CURL_CONSTANT(CURLINFO_OS_ERRNO);
  599. /* Available since 7.12.3 */
  600. REGISTER_CURL_CONSTANT(CURLINFO_NUM_CONNECTS);
  601. REGISTER_CURL_CONSTANT(CURLINFO_SSL_ENGINES);
  602. /* Available since 7.14.1 */
  603. REGISTER_CURL_CONSTANT(CURLINFO_COOKIELIST);
  604. REGISTER_CURL_CONSTANT(CURLOPT_COOKIELIST);
  605. REGISTER_CURL_CONSTANT(CURLOPT_IGNORE_CONTENT_LENGTH);
  606. /* Available since 7.15.0 */
  607. REGISTER_CURL_CONSTANT(CURLOPT_FTP_SKIP_PASV_IP);
  608. /* Available since 7.15.1 */
  609. REGISTER_CURL_CONSTANT(CURLOPT_FTP_FILEMETHOD);
  610. /* Available since 7.15.2 */
  611. REGISTER_CURL_CONSTANT(CURLOPT_CONNECT_ONLY);
  612. REGISTER_CURL_CONSTANT(CURLOPT_LOCALPORT);
  613. REGISTER_CURL_CONSTANT(CURLOPT_LOCALPORTRANGE);
  614. /* Available since 7.15.3 */
  615. REGISTER_CURL_CONSTANT(CURLFTPMETHOD_MULTICWD);
  616. REGISTER_CURL_CONSTANT(CURLFTPMETHOD_NOCWD);
  617. REGISTER_CURL_CONSTANT(CURLFTPMETHOD_SINGLECWD);
  618. /* Available since 7.15.4 */
  619. REGISTER_CURL_CONSTANT(CURLINFO_FTP_ENTRY_PATH);
  620. /* Available since 7.15.5 */
  621. REGISTER_CURL_CONSTANT(CURLOPT_FTP_ALTERNATIVE_TO_USER);
  622. REGISTER_CURL_CONSTANT(CURLOPT_MAX_RECV_SPEED_LARGE);
  623. REGISTER_CURL_CONSTANT(CURLOPT_MAX_SEND_SPEED_LARGE);
  624. /* Available since 7.16.0 */
  625. REGISTER_CURL_CONSTANT(CURLE_SSL_CACERT_BADFILE);
  626. REGISTER_CURL_CONSTANT(CURLOPT_SSL_SESSIONID_CACHE);
  627. REGISTER_CURL_CONSTANT(CURLMOPT_PIPELINING);
  628. /* Available since 7.16.1 */
  629. REGISTER_CURL_CONSTANT(CURLE_SSH);
  630. REGISTER_CURL_CONSTANT(CURLOPT_FTP_SSL_CCC);
  631. REGISTER_CURL_CONSTANT(CURLOPT_SSH_AUTH_TYPES);
  632. REGISTER_CURL_CONSTANT(CURLOPT_SSH_PRIVATE_KEYFILE);
  633. REGISTER_CURL_CONSTANT(CURLOPT_SSH_PUBLIC_KEYFILE);
  634. REGISTER_CURL_CONSTANT(CURLFTPSSL_CCC_ACTIVE);
  635. REGISTER_CURL_CONSTANT(CURLFTPSSL_CCC_NONE);
  636. REGISTER_CURL_CONSTANT(CURLFTPSSL_CCC_PASSIVE);
  637. /* Available since 7.16.2 */
  638. REGISTER_CURL_CONSTANT(CURLOPT_CONNECTTIMEOUT_MS);
  639. REGISTER_CURL_CONSTANT(CURLOPT_HTTP_CONTENT_DECODING);
  640. REGISTER_CURL_CONSTANT(CURLOPT_HTTP_TRANSFER_DECODING);
  641. REGISTER_CURL_CONSTANT(CURLOPT_TIMEOUT_MS);
  642. /* Available since 7.16.3 */
  643. REGISTER_CURL_CONSTANT(CURLMOPT_MAXCONNECTS);
  644. /* Available since 7.16.4 */
  645. REGISTER_CURL_CONSTANT(CURLOPT_KRBLEVEL);
  646. REGISTER_CURL_CONSTANT(CURLOPT_NEW_DIRECTORY_PERMS);
  647. REGISTER_CURL_CONSTANT(CURLOPT_NEW_FILE_PERMS);
  648. /* Available since 7.17.0 */
  649. REGISTER_CURL_CONSTANT(CURLOPT_APPEND);
  650. REGISTER_CURL_CONSTANT(CURLOPT_DIRLISTONLY);
  651. REGISTER_CURL_CONSTANT(CURLOPT_USE_SSL);
  652. /* Curl SSL Constants */
  653. REGISTER_CURL_CONSTANT(CURLUSESSL_ALL);
  654. REGISTER_CURL_CONSTANT(CURLUSESSL_CONTROL);
  655. REGISTER_CURL_CONSTANT(CURLUSESSL_NONE);
  656. REGISTER_CURL_CONSTANT(CURLUSESSL_TRY);
  657. /* Available since 7.17.1 */
  658. REGISTER_CURL_CONSTANT(CURLOPT_SSH_HOST_PUBLIC_KEY_MD5);
  659. /* Available since 7.18.0 */
  660. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_TRANSFER_MODE);
  661. REGISTER_CURL_CONSTANT(CURLPAUSE_ALL);
  662. REGISTER_CURL_CONSTANT(CURLPAUSE_CONT);
  663. REGISTER_CURL_CONSTANT(CURLPAUSE_RECV);
  664. REGISTER_CURL_CONSTANT(CURLPAUSE_RECV_CONT);
  665. REGISTER_CURL_CONSTANT(CURLPAUSE_SEND);
  666. REGISTER_CURL_CONSTANT(CURLPAUSE_SEND_CONT);
  667. REGISTER_CURL_CONSTANT(CURL_READFUNC_PAUSE);
  668. REGISTER_CURL_CONSTANT(CURL_WRITEFUNC_PAUSE);
  669. REGISTER_CURL_CONSTANT(CURLPROXY_SOCKS4A);
  670. REGISTER_CURL_CONSTANT(CURLPROXY_SOCKS5_HOSTNAME);
  671. /* Available since 7.18.2 */
  672. REGISTER_CURL_CONSTANT(CURLINFO_REDIRECT_URL);
  673. /* Available since 7.19.0 */
  674. REGISTER_CURL_CONSTANT(CURLINFO_APPCONNECT_TIME);
  675. REGISTER_CURL_CONSTANT(CURLINFO_PRIMARY_IP);
  676. REGISTER_CURL_CONSTANT(CURLOPT_ADDRESS_SCOPE);
  677. REGISTER_CURL_CONSTANT(CURLOPT_CRLFILE);
  678. REGISTER_CURL_CONSTANT(CURLOPT_ISSUERCERT);
  679. REGISTER_CURL_CONSTANT(CURLOPT_KEYPASSWD);
  680. REGISTER_CURL_CONSTANT(CURLSSH_AUTH_ANY);
  681. REGISTER_CURL_CONSTANT(CURLSSH_AUTH_DEFAULT);
  682. REGISTER_CURL_CONSTANT(CURLSSH_AUTH_HOST);
  683. REGISTER_CURL_CONSTANT(CURLSSH_AUTH_KEYBOARD);
  684. REGISTER_CURL_CONSTANT(CURLSSH_AUTH_NONE);
  685. REGISTER_CURL_CONSTANT(CURLSSH_AUTH_PASSWORD);
  686. REGISTER_CURL_CONSTANT(CURLSSH_AUTH_PUBLICKEY);
  687. /* Available since 7.19.1 */
  688. REGISTER_CURL_CONSTANT(CURLINFO_CERTINFO);
  689. REGISTER_CURL_CONSTANT(CURLOPT_CERTINFO);
  690. REGISTER_CURL_CONSTANT(CURLOPT_PASSWORD);
  691. REGISTER_CURL_CONSTANT(CURLOPT_POSTREDIR);
  692. REGISTER_CURL_CONSTANT(CURLOPT_PROXYPASSWORD);
  693. REGISTER_CURL_CONSTANT(CURLOPT_PROXYUSERNAME);
  694. REGISTER_CURL_CONSTANT(CURLOPT_USERNAME);
  695. REGISTER_CURL_CONSTANT(CURL_REDIR_POST_301);
  696. REGISTER_CURL_CONSTANT(CURL_REDIR_POST_302);
  697. REGISTER_CURL_CONSTANT(CURL_REDIR_POST_ALL);
  698. /* Available since 7.19.3 */
  699. REGISTER_CURL_CONSTANT(CURLAUTH_DIGEST_IE);
  700. /* Available since 7.19.4 */
  701. REGISTER_CURL_CONSTANT(CURLINFO_CONDITION_UNMET);
  702. REGISTER_CURL_CONSTANT(CURLOPT_NOPROXY);
  703. REGISTER_CURL_CONSTANT(CURLOPT_PROTOCOLS);
  704. REGISTER_CURL_CONSTANT(CURLOPT_REDIR_PROTOCOLS);
  705. REGISTER_CURL_CONSTANT(CURLOPT_SOCKS5_GSSAPI_NEC);
  706. REGISTER_CURL_CONSTANT(CURLOPT_SOCKS5_GSSAPI_SERVICE);
  707. REGISTER_CURL_CONSTANT(CURLOPT_TFTP_BLKSIZE);
  708. REGISTER_CURL_CONSTANT(CURLPROTO_ALL);
  709. REGISTER_CURL_CONSTANT(CURLPROTO_DICT);
  710. REGISTER_CURL_CONSTANT(CURLPROTO_FILE);
  711. REGISTER_CURL_CONSTANT(CURLPROTO_FTP);
  712. REGISTER_CURL_CONSTANT(CURLPROTO_FTPS);
  713. REGISTER_CURL_CONSTANT(CURLPROTO_HTTP);
  714. REGISTER_CURL_CONSTANT(CURLPROTO_HTTPS);
  715. REGISTER_CURL_CONSTANT(CURLPROTO_LDAP);
  716. REGISTER_CURL_CONSTANT(CURLPROTO_LDAPS);
  717. REGISTER_CURL_CONSTANT(CURLPROTO_SCP);
  718. REGISTER_CURL_CONSTANT(CURLPROTO_SFTP);
  719. REGISTER_CURL_CONSTANT(CURLPROTO_TELNET);
  720. REGISTER_CURL_CONSTANT(CURLPROTO_TFTP);
  721. REGISTER_CURL_CONSTANT(CURLPROXY_HTTP_1_0);
  722. REGISTER_CURL_CONSTANT(CURLFTP_CREATE_DIR);
  723. REGISTER_CURL_CONSTANT(CURLFTP_CREATE_DIR_NONE);
  724. REGISTER_CURL_CONSTANT(CURLFTP_CREATE_DIR_RETRY);
  725. /* Available since 7.19.6 */
  726. REGISTER_CURL_CONSTANT(CURL_VERSION_CURLDEBUG);
  727. REGISTER_CURL_CONSTANT(CURLOPT_SSH_KNOWNHOSTS);
  728. /* Available since 7.20.0 */
  729. REGISTER_CURL_CONSTANT(CURLINFO_RTSP_CLIENT_CSEQ);
  730. REGISTER_CURL_CONSTANT(CURLINFO_RTSP_CSEQ_RECV);
  731. REGISTER_CURL_CONSTANT(CURLINFO_RTSP_SERVER_CSEQ);
  732. REGISTER_CURL_CONSTANT(CURLINFO_RTSP_SESSION_ID);
  733. REGISTER_CURL_CONSTANT(CURLOPT_FTP_USE_PRET);
  734. REGISTER_CURL_CONSTANT(CURLOPT_MAIL_FROM);
  735. REGISTER_CURL_CONSTANT(CURLOPT_MAIL_RCPT);
  736. REGISTER_CURL_CONSTANT(CURLOPT_RTSP_CLIENT_CSEQ);
  737. REGISTER_CURL_CONSTANT(CURLOPT_RTSP_REQUEST);
  738. REGISTER_CURL_CONSTANT(CURLOPT_RTSP_SERVER_CSEQ);
  739. REGISTER_CURL_CONSTANT(CURLOPT_RTSP_SESSION_ID);
  740. REGISTER_CURL_CONSTANT(CURLOPT_RTSP_STREAM_URI);
  741. REGISTER_CURL_CONSTANT(CURLOPT_RTSP_TRANSPORT);
  742. REGISTER_CURL_CONSTANT(CURLPROTO_IMAP);
  743. REGISTER_CURL_CONSTANT(CURLPROTO_IMAPS);
  744. REGISTER_CURL_CONSTANT(CURLPROTO_POP3);
  745. REGISTER_CURL_CONSTANT(CURLPROTO_POP3S);
  746. REGISTER_CURL_CONSTANT(CURLPROTO_RTSP);
  747. REGISTER_CURL_CONSTANT(CURLPROTO_SMTP);
  748. REGISTER_CURL_CONSTANT(CURLPROTO_SMTPS);
  749. REGISTER_CURL_CONSTANT(CURL_RTSPREQ_ANNOUNCE);
  750. REGISTER_CURL_CONSTANT(CURL_RTSPREQ_DESCRIBE);
  751. REGISTER_CURL_CONSTANT(CURL_RTSPREQ_GET_PARAMETER);
  752. REGISTER_CURL_CONSTANT(CURL_RTSPREQ_OPTIONS);
  753. REGISTER_CURL_CONSTANT(CURL_RTSPREQ_PAUSE);
  754. REGISTER_CURL_CONSTANT(CURL_RTSPREQ_PLAY);
  755. REGISTER_CURL_CONSTANT(CURL_RTSPREQ_RECEIVE);
  756. REGISTER_CURL_CONSTANT(CURL_RTSPREQ_RECORD);
  757. REGISTER_CURL_CONSTANT(CURL_RTSPREQ_SET_PARAMETER);
  758. REGISTER_CURL_CONSTANT(CURL_RTSPREQ_SETUP);
  759. REGISTER_CURL_CONSTANT(CURL_RTSPREQ_TEARDOWN);
  760. /* Available since 7.21.0 */
  761. REGISTER_CURL_CONSTANT(CURLINFO_LOCAL_IP);
  762. REGISTER_CURL_CONSTANT(CURLINFO_LOCAL_PORT);
  763. REGISTER_CURL_CONSTANT(CURLINFO_PRIMARY_PORT);
  764. REGISTER_CURL_CONSTANT(CURLOPT_FNMATCH_FUNCTION);
  765. REGISTER_CURL_CONSTANT(CURLOPT_WILDCARDMATCH);
  766. REGISTER_CURL_CONSTANT(CURLPROTO_RTMP);
  767. REGISTER_CURL_CONSTANT(CURLPROTO_RTMPE);
  768. REGISTER_CURL_CONSTANT(CURLPROTO_RTMPS);
  769. REGISTER_CURL_CONSTANT(CURLPROTO_RTMPT);
  770. REGISTER_CURL_CONSTANT(CURLPROTO_RTMPTE);
  771. REGISTER_CURL_CONSTANT(CURLPROTO_RTMPTS);
  772. REGISTER_CURL_CONSTANT(CURL_FNMATCHFUNC_FAIL);
  773. REGISTER_CURL_CONSTANT(CURL_FNMATCHFUNC_MATCH);
  774. REGISTER_CURL_CONSTANT(CURL_FNMATCHFUNC_NOMATCH);
  775. /* Available since 7.21.2 */
  776. REGISTER_CURL_CONSTANT(CURLPROTO_GOPHER);
  777. /* Available since 7.21.3 */
  778. REGISTER_CURL_CONSTANT(CURLAUTH_ONLY);
  779. REGISTER_CURL_CONSTANT(CURLOPT_RESOLVE);
  780. /* Available since 7.21.4 */
  781. REGISTER_CURL_CONSTANT(CURLOPT_TLSAUTH_PASSWORD);
  782. REGISTER_CURL_CONSTANT(CURLOPT_TLSAUTH_TYPE);
  783. REGISTER_CURL_CONSTANT(CURLOPT_TLSAUTH_USERNAME);
  784. REGISTER_CURL_CONSTANT(CURL_TLSAUTH_SRP);
  785. REGISTER_CURL_CONSTANT(CURL_VERSION_TLSAUTH_SRP);
  786. /* Available since 7.21.6 */
  787. REGISTER_CURL_CONSTANT(CURLOPT_ACCEPT_ENCODING);
  788. REGISTER_CURL_CONSTANT(CURLOPT_TRANSFER_ENCODING);
  789. /* Available since 7.22.0 */
  790. REGISTER_CURL_CONSTANT(CURLAUTH_NTLM_WB);
  791. REGISTER_CURL_CONSTANT(CURLGSSAPI_DELEGATION_FLAG);
  792. REGISTER_CURL_CONSTANT(CURLGSSAPI_DELEGATION_POLICY_FLAG);
  793. REGISTER_CURL_CONSTANT(CURLOPT_GSSAPI_DELEGATION);
  794. REGISTER_CURL_CONSTANT(CURL_VERSION_NTLM_WB);
  795. /* Available since 7.24.0 */
  796. REGISTER_CURL_CONSTANT(CURLOPT_ACCEPTTIMEOUT_MS);
  797. REGISTER_CURL_CONSTANT(CURLOPT_DNS_SERVERS);
  798. /* Available since 7.25.0 */
  799. REGISTER_CURL_CONSTANT(CURLOPT_MAIL_AUTH);
  800. REGISTER_CURL_CONSTANT(CURLOPT_SSL_OPTIONS);
  801. REGISTER_CURL_CONSTANT(CURLOPT_TCP_KEEPALIVE);
  802. REGISTER_CURL_CONSTANT(CURLOPT_TCP_KEEPIDLE);
  803. REGISTER_CURL_CONSTANT(CURLOPT_TCP_KEEPINTVL);
  804. REGISTER_CURL_CONSTANT(CURLSSLOPT_ALLOW_BEAST);
  805. /* Available since 7.25.1 */
  806. REGISTER_CURL_CONSTANT(CURL_REDIR_POST_303);
  807. /* Available since 7.28.0 */
  808. REGISTER_CURL_CONSTANT(CURLSSH_AUTH_AGENT);
  809. #if LIBCURL_VERSION_NUM >= 0x071e00 /* Available since 7.30.0 */
  810. REGISTER_CURL_CONSTANT(CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE);
  811. REGISTER_CURL_CONSTANT(CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE);
  812. REGISTER_CURL_CONSTANT(CURLMOPT_MAX_HOST_CONNECTIONS);
  813. REGISTER_CURL_CONSTANT(CURLMOPT_MAX_PIPELINE_LENGTH);
  814. REGISTER_CURL_CONSTANT(CURLMOPT_MAX_TOTAL_CONNECTIONS);
  815. #endif
  816. #if LIBCURL_VERSION_NUM >= 0x071f00 /* Available since 7.31.0 */
  817. REGISTER_CURL_CONSTANT(CURLOPT_SASL_IR);
  818. #endif
  819. #if LIBCURL_VERSION_NUM >= 0x072100 /* Available since 7.33.0 */
  820. REGISTER_CURL_CONSTANT(CURLOPT_DNS_INTERFACE);
  821. REGISTER_CURL_CONSTANT(CURLOPT_DNS_LOCAL_IP4);
  822. REGISTER_CURL_CONSTANT(CURLOPT_DNS_LOCAL_IP6);
  823. REGISTER_CURL_CONSTANT(CURLOPT_XOAUTH2_BEARER);
  824. REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_2_0);
  825. REGISTER_CURL_CONSTANT(CURL_VERSION_HTTP2);
  826. #endif
  827. #if LIBCURL_VERSION_NUM >= 0x072200 /* Available since 7.34.0 */
  828. REGISTER_CURL_CONSTANT(CURLOPT_LOGIN_OPTIONS);
  829. REGISTER_CURL_CONSTANT(CURL_SSLVERSION_TLSv1_0);
  830. REGISTER_CURL_CONSTANT(CURL_SSLVERSION_TLSv1_1);
  831. REGISTER_CURL_CONSTANT(CURL_SSLVERSION_TLSv1_2);
  832. #endif
  833. #if LIBCURL_VERSION_NUM >= 0x072400 /* Available since 7.36.0 */
  834. REGISTER_CURL_CONSTANT(CURLOPT_EXPECT_100_TIMEOUT_MS);
  835. REGISTER_CURL_CONSTANT(CURLOPT_SSL_ENABLE_ALPN);
  836. REGISTER_CURL_CONSTANT(CURLOPT_SSL_ENABLE_NPN);
  837. #endif
  838. #if LIBCURL_VERSION_NUM >= 0x072500 /* Available since 7.37.0 */
  839. REGISTER_CURL_CONSTANT(CURLHEADER_SEPARATE);
  840. REGISTER_CURL_CONSTANT(CURLHEADER_UNIFIED);
  841. REGISTER_CURL_CONSTANT(CURLOPT_HEADEROPT);
  842. REGISTER_CURL_CONSTANT(CURLOPT_PROXYHEADER);
  843. #endif
  844. #if LIBCURL_VERSION_NUM >= 0x072600 /* Available since 7.38.0 */
  845. REGISTER_CURL_CONSTANT(CURLAUTH_NEGOTIATE);
  846. REGISTER_CURL_CONSTANT(CURL_VERSION_GSSAPI);
  847. #endif
  848. #if LIBCURL_VERSION_NUM >= 0x072700 /* Available since 7.39.0 */
  849. REGISTER_CURL_CONSTANT(CURLOPT_PINNEDPUBLICKEY);
  850. #endif
  851. #if LIBCURL_VERSION_NUM >= 0x072800 /* Available since 7.40.0 */
  852. REGISTER_CURL_CONSTANT(CURLOPT_UNIX_SOCKET_PATH);
  853. REGISTER_CURL_CONSTANT(CURLPROTO_SMB);
  854. REGISTER_CURL_CONSTANT(CURLPROTO_SMBS);
  855. REGISTER_CURL_CONSTANT(CURL_VERSION_KERBEROS5);
  856. REGISTER_CURL_CONSTANT(CURL_VERSION_UNIX_SOCKETS);
  857. #endif
  858. #if LIBCURL_VERSION_NUM >= 0x072900 /* Available since 7.41.0 */
  859. REGISTER_CURL_CONSTANT(CURLOPT_SSL_VERIFYSTATUS);
  860. #endif
  861. #if LIBCURL_VERSION_NUM >= 0x072a00 /* Available since 7.42.0 */
  862. REGISTER_CURL_CONSTANT(CURLOPT_PATH_AS_IS);
  863. REGISTER_CURL_CONSTANT(CURLOPT_SSL_FALSESTART);
  864. #endif
  865. #if LIBCURL_VERSION_NUM >= 0x072b00 /* Available since 7.43.0 */
  866. REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_2);
  867. REGISTER_CURL_CONSTANT(CURLOPT_PIPEWAIT);
  868. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_SERVICE_NAME);
  869. REGISTER_CURL_CONSTANT(CURLOPT_SERVICE_NAME);
  870. REGISTER_CURL_CONSTANT(CURLPIPE_NOTHING);
  871. REGISTER_CURL_CONSTANT(CURLPIPE_HTTP1);
  872. REGISTER_CURL_CONSTANT(CURLPIPE_MULTIPLEX);
  873. #endif
  874. #if LIBCURL_VERSION_NUM >= 0x072c00 /* Available since 7.44.0 */
  875. REGISTER_CURL_CONSTANT(CURLSSLOPT_NO_REVOKE);
  876. #endif
  877. #if LIBCURL_VERSION_NUM >= 0x072d00 /* Available since 7.45.0 */
  878. REGISTER_CURL_CONSTANT(CURLOPT_DEFAULT_PROTOCOL);
  879. #endif
  880. #if LIBCURL_VERSION_NUM >= 0x072e00 /* Available since 7.46.0 */
  881. REGISTER_CURL_CONSTANT(CURLOPT_STREAM_WEIGHT);
  882. REGISTER_CURL_CONSTANT(CURLMOPT_PUSHFUNCTION);
  883. REGISTER_CURL_CONSTANT(CURL_PUSH_OK);
  884. REGISTER_CURL_CONSTANT(CURL_PUSH_DENY);
  885. #endif
  886. #if LIBCURL_VERSION_NUM >= 0x072f00 /* Available since 7.47.0 */
  887. REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_2TLS);
  888. REGISTER_CURL_CONSTANT(CURL_VERSION_PSL);
  889. #endif
  890. #if LIBCURL_VERSION_NUM >= 0x073000 /* Available since 7.48.0 */
  891. REGISTER_CURL_CONSTANT(CURLOPT_TFTP_NO_OPTIONS);
  892. #endif
  893. #if LIBCURL_VERSION_NUM >= 0x073100 /* Available since 7.49.0 */
  894. REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
  895. REGISTER_CURL_CONSTANT(CURLOPT_CONNECT_TO);
  896. REGISTER_CURL_CONSTANT(CURLOPT_TCP_FASTOPEN);
  897. #endif
  898. #if LIBCURL_VERSION_NUM >= 0x073200 /* Available since 7.50.0 */
  899. REGISTER_CURL_CONSTANT(CURLINFO_HTTP_VERSION);
  900. #endif
  901. #if LIBCURL_VERSION_NUM >= 0x073300 /* Available since 7.51.0 */
  902. REGISTER_CURL_CONSTANT(CURLE_WEIRD_SERVER_REPLY);
  903. REGISTER_CURL_CONSTANT(CURLOPT_KEEP_SENDING_ON_ERROR);
  904. #endif
  905. #if LIBCURL_VERSION_NUM >= 0x073400 /* Available since 7.52.0 */
  906. REGISTER_CURL_CONSTANT(CURL_SSLVERSION_TLSv1_3);
  907. REGISTER_CURL_CONSTANT(CURL_VERSION_HTTPS_PROXY);
  908. REGISTER_CURL_CONSTANT(CURLINFO_PROTOCOL);
  909. REGISTER_CURL_CONSTANT(CURLINFO_PROXY_SSL_VERIFYRESULT);
  910. REGISTER_CURL_CONSTANT(CURLINFO_SCHEME);
  911. REGISTER_CURL_CONSTANT(CURLOPT_PRE_PROXY);
  912. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_CAINFO);
  913. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_CAPATH);
  914. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_CRLFILE);
  915. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_KEYPASSWD);
  916. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_PINNEDPUBLICKEY);
  917. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_SSL_CIPHER_LIST);
  918. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_SSL_OPTIONS);
  919. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_SSL_VERIFYHOST);
  920. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_SSL_VERIFYPEER);
  921. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_SSLCERT);
  922. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_SSLCERTTYPE);
  923. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_SSLKEY);
  924. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_SSLKEYTYPE);
  925. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_SSLVERSION);
  926. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_TLSAUTH_PASSWORD);
  927. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_TLSAUTH_TYPE);
  928. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_TLSAUTH_USERNAME);
  929. REGISTER_CURL_CONSTANT(CURLPROXY_HTTPS);
  930. #endif
  931. #if LIBCURL_VERSION_NUM >= 0x073500 /* Available since 7.53.0 */
  932. REGISTER_CURL_CONSTANT(CURL_MAX_READ_SIZE);
  933. REGISTER_CURL_CONSTANT(CURLOPT_ABSTRACT_UNIX_SOCKET);
  934. #endif
  935. #if LIBCURL_VERSION_NUM >= 0x073600 /* Available since 7.54.0 */
  936. REGISTER_CURL_CONSTANT(CURL_SSLVERSION_MAX_DEFAULT);
  937. REGISTER_CURL_CONSTANT(CURL_SSLVERSION_MAX_NONE);
  938. REGISTER_CURL_CONSTANT(CURL_SSLVERSION_MAX_TLSv1_0);
  939. REGISTER_CURL_CONSTANT(CURL_SSLVERSION_MAX_TLSv1_1);
  940. REGISTER_CURL_CONSTANT(CURL_SSLVERSION_MAX_TLSv1_2);
  941. REGISTER_CURL_CONSTANT(CURL_SSLVERSION_MAX_TLSv1_3);
  942. REGISTER_CURL_CONSTANT(CURLOPT_SUPPRESS_CONNECT_HEADERS);
  943. #endif
  944. #if LIBCURL_VERSION_NUM >= 0x073601 /* Available since 7.54.1 */
  945. REGISTER_CURL_CONSTANT(CURLAUTH_GSSAPI);
  946. #endif
  947. #if LIBCURL_VERSION_NUM >= 0x073700 /* Available since 7.55.0 */
  948. REGISTER_CURL_CONSTANT(CURLINFO_CONTENT_LENGTH_DOWNLOAD_T);
  949. REGISTER_CURL_CONSTANT(CURLINFO_CONTENT_LENGTH_UPLOAD_T);
  950. REGISTER_CURL_CONSTANT(CURLINFO_SIZE_DOWNLOAD_T);
  951. REGISTER_CURL_CONSTANT(CURLINFO_SIZE_UPLOAD_T);
  952. REGISTER_CURL_CONSTANT(CURLINFO_SPEED_DOWNLOAD_T);
  953. REGISTER_CURL_CONSTANT(CURLINFO_SPEED_UPLOAD_T);
  954. REGISTER_CURL_CONSTANT(CURLOPT_REQUEST_TARGET);
  955. REGISTER_CURL_CONSTANT(CURLOPT_SOCKS5_AUTH);
  956. #endif
  957. #if LIBCURL_VERSION_NUM >= 0x073800 /* Available since 7.56.0 */
  958. REGISTER_CURL_CONSTANT(CURLOPT_SSH_COMPRESSION);
  959. REGISTER_CURL_CONSTANT(CURL_VERSION_MULTI_SSL);
  960. #endif
  961. #if LIBCURL_VERSION_NUM >= 0x073900 /* Available since 7.57.0 */
  962. REGISTER_CURL_CONSTANT(CURL_VERSION_BROTLI);
  963. REGISTER_CURL_CONSTANT(CURL_LOCK_DATA_CONNECT);
  964. #endif
  965. #if LIBCURL_VERSION_NUM >= 0x073a00 /* Available since 7.58.0 */
  966. REGISTER_CURL_CONSTANT(CURLSSH_AUTH_GSSAPI);
  967. #endif
  968. #if LIBCURL_VERSION_NUM >= 0x073b00 /* Available since 7.59.0 */
  969. REGISTER_CURL_CONSTANT(CURLINFO_FILETIME_T);
  970. REGISTER_CURL_CONSTANT(CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS);
  971. REGISTER_CURL_CONSTANT(CURLOPT_TIMEVALUE_LARGE);
  972. #endif
  973. #if LIBCURL_VERSION_NUM >= 0x073c00 /* Available since 7.60.0 */
  974. REGISTER_CURL_CONSTANT(CURLOPT_DNS_SHUFFLE_ADDRESSES);
  975. REGISTER_CURL_CONSTANT(CURLOPT_HAPROXYPROTOCOL);
  976. #endif
  977. #if LIBCURL_VERSION_NUM >= 0x073d00 /* Available since 7.61.0 */
  978. REGISTER_CURL_CONSTANT(CURL_LOCK_DATA_PSL);
  979. REGISTER_CURL_CONSTANT(CURLAUTH_BEARER);
  980. REGISTER_CURL_CONSTANT(CURLINFO_APPCONNECT_TIME_T);
  981. REGISTER_CURL_CONSTANT(CURLINFO_CONNECT_TIME_T);
  982. REGISTER_CURL_CONSTANT(CURLINFO_NAMELOOKUP_TIME_T);
  983. REGISTER_CURL_CONSTANT(CURLINFO_PRETRANSFER_TIME_T);
  984. REGISTER_CURL_CONSTANT(CURLINFO_REDIRECT_TIME_T);
  985. REGISTER_CURL_CONSTANT(CURLINFO_STARTTRANSFER_TIME_T);
  986. REGISTER_CURL_CONSTANT(CURLINFO_TOTAL_TIME_T);
  987. REGISTER_CURL_CONSTANT(CURLOPT_DISALLOW_USERNAME_IN_URL);
  988. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_TLS13_CIPHERS);
  989. REGISTER_CURL_CONSTANT(CURLOPT_TLS13_CIPHERS);
  990. #endif
  991. #if LIBCURL_VERSION_NUM >= 0x073E00 /* Available since 7.62.0 */
  992. REGISTER_CURL_CONSTANT(CURLOPT_DOH_URL);
  993. #endif
  994. #if LIBCURL_VERSION_NUM >= 0x074000 /* Available since 7.64.0 */
  995. REGISTER_CURL_CONSTANT(CURLOPT_HTTP09_ALLOWED);
  996. #endif
  997. #if LIBCURL_VERSION_NUM >= 0x074001 /* Available since 7.64.1 */
  998. REGISTER_CURL_CONSTANT(CURL_VERSION_ALTSVC);
  999. #endif
  1000. #if LIBCURL_VERSION_NUM >= 0x074700 /* Available since 7.71.0 */
  1001. REGISTER_CURL_CONSTANT(CURLOPT_ISSUERCERT_BLOB);
  1002. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_ISSUERCERT);
  1003. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_ISSUERCERT_BLOB);
  1004. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_SSLCERT_BLOB);
  1005. REGISTER_CURL_CONSTANT(CURLOPT_PROXY_SSLKEY_BLOB);
  1006. REGISTER_CURL_CONSTANT(CURLOPT_SSLCERT_BLOB);
  1007. REGISTER_CURL_CONSTANT(CURLOPT_SSLKEY_BLOB);
  1008. #endif
  1009. REGISTER_CURL_CONSTANT(CURLOPT_SAFE_UPLOAD);
  1010. #ifdef PHP_CURL_NEED_OPENSSL_TSL
  1011. if (!CRYPTO_get_id_callback()) {
  1012. int i, c = CRYPTO_num_locks();
  1013. php_curl_openssl_tsl = malloc(c * sizeof(MUTEX_T));
  1014. if (!php_curl_openssl_tsl) {
  1015. return FAILURE;
  1016. }
  1017. for (i = 0; i < c; ++i) {
  1018. php_curl_openssl_tsl[i] = tsrm_mutex_alloc();
  1019. }
  1020. CRYPTO_set_id_callback(php_curl_ssl_id);
  1021. CRYPTO_set_locking_callback(php_curl_ssl_lock);
  1022. }
  1023. #endif
  1024. if (curl_global_init(CURL_GLOBAL_DEFAULT) != CURLE_OK) {
  1025. return FAILURE;
  1026. }
  1027. curl_ce = register_class_CurlHandle();
  1028. curl_ce->create_object = curl_create_object;
  1029. memcpy(&curl_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
  1030. curl_object_handlers.offset = XtOffsetOf(php_curl, std);
  1031. curl_object_handlers.free_obj = curl_free_obj;
  1032. curl_object_handlers.get_gc = curl_get_gc;
  1033. curl_object_handlers.get_constructor = curl_get_constructor;
  1034. curl_object_handlers.clone_obj = curl_clone_obj;
  1035. curl_object_handlers.cast_object = curl_cast_object;
  1036. curl_object_handlers.compare = zend_objects_not_comparable;
  1037. curl_multi_ce = register_class_CurlMultiHandle();
  1038. curl_multi_register_handlers();
  1039. curl_share_ce = register_class_CurlShareHandle();
  1040. curl_share_register_handlers();
  1041. curlfile_register_class();
  1042. return SUCCESS;
  1043. }
  1044. /* }}} */
  1045. /* CurlHandle class */
  1046. static zend_object *curl_create_object(zend_class_entry *class_type) {
  1047. php_curl *intern = zend_object_alloc(sizeof(php_curl), class_type);
  1048. zend_object_std_init(&intern->std, class_type);
  1049. object_properties_init(&intern->std, class_type);
  1050. intern->std.handlers = &curl_object_handlers;
  1051. return &intern->std;
  1052. }
  1053. static zend_function *curl_get_constructor(zend_object *object) {
  1054. zend_throw_error(NULL, "Cannot directly construct CurlHandle, use curl_init() instead");
  1055. return NULL;
  1056. }
  1057. static zend_object *curl_clone_obj(zend_object *object) {
  1058. php_curl *ch;
  1059. CURL *cp;
  1060. zval *postfields;
  1061. zend_object *clone_object;
  1062. php_curl *clone_ch;
  1063. clone_object = curl_create_object(curl_ce);
  1064. clone_ch = curl_from_obj(clone_object);
  1065. init_curl_handle(clone_ch);
  1066. ch = curl_from_obj(object);
  1067. cp = curl_easy_duphandle(ch->cp);
  1068. if (!cp) {
  1069. zend_throw_exception(NULL, "Failed to clone CurlHandle", 0);
  1070. return &clone_ch->std;
  1071. }
  1072. clone_ch->cp = cp;
  1073. _php_setup_easy_copy_handlers(clone_ch, ch);
  1074. postfields = &clone_ch->postfields;
  1075. if (Z_TYPE_P(postfields) != IS_UNDEF) {
  1076. if (build_mime_structure_from_hash(clone_ch, postfields) != SUCCESS) {
  1077. zend_throw_exception(NULL, "Failed to clone CurlHandle", 0);
  1078. return &clone_ch->std;
  1079. }
  1080. }
  1081. return &clone_ch->std;
  1082. }
  1083. static HashTable *curl_get_gc(zend_object *object, zval **table, int *n)
  1084. {
  1085. php_curl *curl = curl_from_obj(object);
  1086. zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create();
  1087. zend_get_gc_buffer_add_zval(gc_buffer, &curl->postfields);
  1088. if (curl->handlers.read) {
  1089. zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers.read->func_name);
  1090. zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers.read->stream);
  1091. }
  1092. if (curl->handlers.write) {
  1093. zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers.write->func_name);
  1094. zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers.write->stream);
  1095. }
  1096. if (curl->handlers.write_header) {
  1097. zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers.write_header->func_name);
  1098. zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers.write_header->stream);
  1099. }
  1100. if (curl->handlers.progress) {
  1101. zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers.progress->func_name);
  1102. }
  1103. #if LIBCURL_VERSION_NUM >= 0x071500
  1104. if (curl->handlers.fnmatch) {
  1105. zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers.fnmatch->func_name);
  1106. }
  1107. #endif
  1108. zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers.std_err);
  1109. zend_get_gc_buffer_add_zval(gc_buffer, &curl->private_data);
  1110. zend_get_gc_buffer_use(gc_buffer, table, n);
  1111. return zend_std_get_properties(object);
  1112. }
  1113. int curl_cast_object(zend_object *obj, zval *result, int type)
  1114. {
  1115. if (type == IS_LONG) {
  1116. /* For better backward compatibility, make (int) $curl_handle return the object ID,
  1117. * similar to how it previously returned the resource ID. */
  1118. ZVAL_LONG(result, obj->handle);
  1119. return SUCCESS;
  1120. }
  1121. return zend_std_cast_object_tostring(obj, result, type);
  1122. }
  1123. /* {{{ PHP_MSHUTDOWN_FUNCTION */
  1124. PHP_MSHUTDOWN_FUNCTION(curl)
  1125. {
  1126. curl_global_cleanup();
  1127. #ifdef PHP_CURL_NEED_OPENSSL_TSL
  1128. if (php_curl_openssl_tsl) {
  1129. int i, c = CRYPTO_num_locks();
  1130. CRYPTO_set_id_callback(NULL);
  1131. CRYPTO_set_locking_callback(NULL);
  1132. for (i = 0; i < c; ++i) {
  1133. tsrm_mutex_free(php_curl_openssl_tsl[i]);
  1134. }
  1135. free(php_curl_openssl_tsl);
  1136. php_curl_openssl_tsl = NULL;
  1137. }
  1138. #endif
  1139. UNREGISTER_INI_ENTRIES();
  1140. return SUCCESS;
  1141. }
  1142. /* }}} */
  1143. /* {{{ curl_write_nothing
  1144. * Used as a work around. See _php_curl_close_ex
  1145. */
  1146. static size_t curl_write_nothing(char *data, size_t size, size_t nmemb, void *ctx)
  1147. {
  1148. return size * nmemb;
  1149. }
  1150. /* }}} */
  1151. /* {{{ curl_write */
  1152. static size_t curl_write(char *data, size_t size, size_t nmemb, void *ctx)
  1153. {
  1154. php_curl *ch = (php_curl *) ctx;
  1155. php_curl_write *t = ch->handlers.write;
  1156. size_t length = size * nmemb;
  1157. #if PHP_CURL_DEBUG
  1158. fprintf(stderr, "curl_write() called\n");
  1159. fprintf(stderr, "data = %s, size = %d, nmemb = %d, ctx = %x\n", data, size, nmemb, ctx);
  1160. #endif
  1161. switch (t->method) {
  1162. case PHP_CURL_STDOUT:
  1163. PHPWRITE(data, length);
  1164. break;
  1165. case PHP_CURL_FILE:
  1166. return fwrite(data, size, nmemb, t->fp);
  1167. case PHP_CURL_RETURN:
  1168. if (length > 0) {
  1169. smart_str_appendl(&t->buf, data, (int) length);
  1170. }
  1171. break;
  1172. case PHP_CURL_USER: {
  1173. zval argv[2];
  1174. zval retval;
  1175. int error;
  1176. zend_fcall_info fci;
  1177. GC_ADDREF(&ch->std);
  1178. ZVAL_OBJ(&argv[0], &ch->std);
  1179. ZVAL_STRINGL(&argv[1], data, length);
  1180. fci.size = sizeof(fci);
  1181. fci.object = NULL;
  1182. ZVAL_COPY_VALUE(&fci.function_name, &t->func_name);
  1183. fci.retval = &retval;
  1184. fci.param_count = 2;
  1185. fci.params = argv;
  1186. fci.named_params = NULL;
  1187. ch->in_callback = 1;
  1188. error = zend_call_function(&fci, &t->fci_cache);
  1189. ch->in_callback = 0;
  1190. if (error == FAILURE) {
  1191. php_error_docref(NULL, E_WARNING, "Could not call the CURLOPT_WRITEFUNCTION");
  1192. length = -1;
  1193. } else if (!Z_ISUNDEF(retval)) {
  1194. _php_curl_verify_handlers(ch, 1);
  1195. length = zval_get_long(&retval);
  1196. }
  1197. zval_ptr_dtor(&argv[0]);
  1198. zval_ptr_dtor(&argv[1]);
  1199. break;
  1200. }
  1201. }
  1202. return length;
  1203. }
  1204. /* }}} */
  1205. /* {{{ curl_fnmatch */
  1206. static int curl_fnmatch(void *ctx, const char *pattern, const char *string)
  1207. {
  1208. php_curl *ch = (php_curl *) ctx;
  1209. php_curl_callback *t = ch->handlers.fnmatch;
  1210. int rval = CURL_FNMATCHFUNC_FAIL;
  1211. zval argv[3];
  1212. zval retval;
  1213. int error;
  1214. zend_fcall_info fci;
  1215. GC_ADDREF(&ch->std);
  1216. ZVAL_OBJ(&argv[0], &ch->std);
  1217. ZVAL_STRING(&argv[1], pattern);
  1218. ZVAL_STRING(&argv[2], string);
  1219. fci.size = sizeof(fci);
  1220. ZVAL_COPY_VALUE(&fci.function_name, &t->func_name);
  1221. fci.object = NULL;
  1222. fci.retval = &retval;
  1223. fci.param_count = 3;
  1224. fci.params = argv;
  1225. fci.named_params = NULL;
  1226. ch->in_callback = 1;
  1227. error = zend_call_function(&fci, &t->fci_cache);
  1228. ch->in_callback = 0;
  1229. if (error == FAILURE) {
  1230. php_error_docref(NULL, E_WARNING, "Cannot call the CURLOPT_FNMATCH_FUNCTION");
  1231. } else if (!Z_ISUNDEF(retval)) {
  1232. _php_curl_verify_handlers(ch, 1);
  1233. rval = zval_get_long(&retval);
  1234. }
  1235. zval_ptr_dtor(&argv[0]);
  1236. zval_ptr_dtor(&argv[1]);
  1237. zval_ptr_dtor(&argv[2]);
  1238. return rval;
  1239. }
  1240. /* }}} */
  1241. /* {{{ curl_progress */
  1242. static size_t curl_progress(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
  1243. {
  1244. php_curl *ch = (php_curl *)clientp;
  1245. php_curl_callback *t = ch->handlers.progress;
  1246. size_t rval = 0;
  1247. #if PHP_CURL_DEBUG
  1248. fprintf(stderr, "curl_progress() called\n");
  1249. fprintf(stderr, "clientp = %x, dltotal = %f, dlnow = %f, ultotal = %f, ulnow = %f\n", clientp, dltotal, dlnow, ultotal, ulnow);
  1250. #endif
  1251. zval argv[5];
  1252. zval retval;
  1253. int error;
  1254. zend_fcall_info fci;
  1255. GC_ADDREF(&ch->std);
  1256. ZVAL_OBJ(&argv[0], &ch->std);
  1257. ZVAL_LONG(&argv[1], (zend_long)dltotal);
  1258. ZVAL_LONG(&argv[2], (zend_long)dlnow);
  1259. ZVAL_LONG(&argv[3], (zend_long)ultotal);
  1260. ZVAL_LONG(&argv[4], (zend_long)ulnow);
  1261. fci.size = sizeof(fci);
  1262. ZVAL_COPY_VALUE(&fci.function_name, &t->func_name);
  1263. fci.object = NULL;
  1264. fci.retval = &retval;
  1265. fci.param_count = 5;
  1266. fci.params = argv;
  1267. fci.named_params = NULL;
  1268. ch->in_callback = 1;
  1269. error = zend_call_function(&fci, &t->fci_cache);
  1270. ch->in_callback = 0;
  1271. if (error == FAILURE) {
  1272. php_error_docref(NULL, E_WARNING, "Cannot call the CURLOPT_PROGRESSFUNCTION");
  1273. } else if (!Z_ISUNDEF(retval)) {
  1274. _php_curl_verify_handlers(ch, 1);
  1275. if (0 != zval_get_long(&retval)) {
  1276. rval = 1;
  1277. }
  1278. }
  1279. zval_ptr_dtor(&argv[0]);
  1280. return rval;
  1281. }
  1282. /* }}} */
  1283. /* {{{ curl_read */
  1284. static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx)
  1285. {
  1286. php_curl *ch = (php_curl *)ctx;
  1287. php_curl_read *t = ch->handlers.read;
  1288. int length = 0;
  1289. switch (t->method) {
  1290. case PHP_CURL_DIRECT:
  1291. if (t->fp) {
  1292. length = fread(data, size, nmemb, t->fp);
  1293. }
  1294. break;
  1295. case PHP_CURL_USER: {
  1296. zval argv[3];
  1297. zval retval;
  1298. int error;
  1299. zend_fcall_info fci;
  1300. GC_ADDREF(&ch->std);
  1301. ZVAL_OBJ(&argv[0], &ch->std);
  1302. if (t->res) {
  1303. GC_ADDREF(t->res);
  1304. ZVAL_RES(&argv[1], t->res);
  1305. } else {
  1306. ZVAL_NULL(&argv[1]);
  1307. }
  1308. ZVAL_LONG(&argv[2], (int)size * nmemb);
  1309. fci.size = sizeof(fci);
  1310. ZVAL_COPY_VALUE(&fci.function_name, &t->func_name);
  1311. fci.object = NULL;
  1312. fci.retval = &retval;
  1313. fci.param_count = 3;
  1314. fci.params = argv;
  1315. fci.named_params = NULL;
  1316. ch->in_callback = 1;
  1317. error = zend_call_function(&fci, &t->fci_cache);
  1318. ch->in_callback = 0;
  1319. if (error == FAILURE) {
  1320. php_error_docref(NULL, E_WARNING, "Cannot call the CURLOPT_READFUNCTION");
  1321. length = CURL_READFUNC_ABORT;
  1322. } else if (!Z_ISUNDEF(retval)) {
  1323. _php_curl_verify_handlers(ch, 1);
  1324. if (Z_TYPE(retval) == IS_STRING) {
  1325. length = MIN((int) (size * nmemb), Z_STRLEN(retval));
  1326. memcpy(data, Z_STRVAL(retval), length);
  1327. }
  1328. zval_ptr_dtor(&retval);
  1329. }
  1330. zval_ptr_dtor(&argv[0]);
  1331. zval_ptr_dtor(&argv[1]);
  1332. break;
  1333. }
  1334. }
  1335. return length;
  1336. }
  1337. /* }}} */
  1338. /* {{{ curl_write_header */
  1339. static size_t curl_write_header(char *data, size_t size, size_t nmemb, void *ctx)
  1340. {
  1341. php_curl *ch = (php_curl *) ctx;
  1342. php_curl_write *t = ch->handlers.write_header;
  1343. size_t length = size * nmemb;
  1344. switch (t->method) {
  1345. case PHP_CURL_STDOUT:
  1346. /* Handle special case write when we're returning the entire transfer
  1347. */
  1348. if (ch->handlers.write->method == PHP_CURL_RETURN && length > 0) {
  1349. smart_str_appendl(&ch->handlers.write->buf, data, (int) length);
  1350. } else {
  1351. PHPWRITE(data, length);
  1352. }
  1353. break;
  1354. case PHP_CURL_FILE:
  1355. return fwrite(data, size, nmemb, t->fp);
  1356. case PHP_CURL_USER: {
  1357. zval argv[2];
  1358. zval retval;
  1359. int error;
  1360. zend_fcall_info fci;
  1361. GC_ADDREF(&ch->std);
  1362. ZVAL_OBJ(&argv[0], &ch->std);
  1363. ZVAL_STRINGL(&argv[1], data, length);
  1364. fci.size = sizeof(fci);
  1365. ZVAL_COPY_VALUE(&fci.function_name, &t->func_name);
  1366. fci.object = NULL;
  1367. fci.retval = &retval;
  1368. fci.param_count = 2;
  1369. fci.params = argv;
  1370. fci.named_params = NULL;
  1371. ch->in_callback = 1;
  1372. error = zend_call_function(&fci, &t->fci_cache);
  1373. ch->in_callback = 0;
  1374. if (error == FAILURE) {
  1375. php_error_docref(NULL, E_WARNING, "Could not call the CURLOPT_HEADERFUNCTION");
  1376. length = -1;
  1377. } else if (!Z_ISUNDEF(retval)) {
  1378. _php_curl_verify_handlers(ch, 1);
  1379. length = zval_get_long(&retval);
  1380. }
  1381. zval_ptr_dtor(&argv[0]);
  1382. zval_ptr_dtor(&argv[1]);
  1383. break;
  1384. }
  1385. case PHP_CURL_IGNORE:
  1386. return length;
  1387. default:
  1388. return -1;
  1389. }
  1390. return length;
  1391. }
  1392. /* }}} */
  1393. static int curl_debug(CURL *cp, curl_infotype type, char *buf, size_t buf_len, void *ctx) /* {{{ */
  1394. {
  1395. php_curl *ch = (php_curl *)ctx;
  1396. if (type == CURLINFO_HEADER_OUT) {
  1397. if (ch->header.str) {
  1398. zend_string_release_ex(ch->header.str, 0);
  1399. }
  1400. ch->header.str = zend_string_init(buf, buf_len, 0);
  1401. }
  1402. return 0;
  1403. }
  1404. /* }}} */
  1405. /* {{{ curl_free_post */
  1406. static void curl_free_post(void **post)
  1407. {
  1408. #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
  1409. curl_mime_free((curl_mime *)*post);
  1410. #else
  1411. curl_formfree((struct HttpPost *)*post);
  1412. #endif
  1413. }
  1414. /* }}} */
  1415. struct mime_data_cb_arg {
  1416. zend_string *filename;
  1417. php_stream *stream;
  1418. };
  1419. /* {{{ curl_free_cb_arg */
  1420. static void curl_free_cb_arg(void **cb_arg_p)
  1421. {
  1422. struct mime_data_cb_arg *cb_arg = (struct mime_data_cb_arg *) *cb_arg_p;
  1423. ZEND_ASSERT(cb_arg->stream == NULL);
  1424. zend_string_release(cb_arg->filename);
  1425. efree(cb_arg);
  1426. }
  1427. /* }}} */
  1428. #if LIBCURL_VERSION_NUM < 0x073800 /* 7.56.0 */
  1429. /* {{{ curl_free_buffers */
  1430. static void curl_free_buffers(void **buffer)
  1431. {
  1432. zend_string_release((zend_string *) *buffer);
  1433. }
  1434. /* }}} */
  1435. #endif
  1436. /* {{{ curl_free_slist */
  1437. static void curl_free_slist(zval *el)
  1438. {
  1439. curl_slist_free_all(((struct curl_slist *)Z_PTR_P(el)));
  1440. }
  1441. /* }}} */
  1442. /* {{{ Return cURL version information. */
  1443. PHP_FUNCTION(curl_version)
  1444. {
  1445. curl_version_info_data *d;
  1446. ZEND_PARSE_PARAMETERS_NONE();
  1447. d = curl_version_info(CURLVERSION_NOW);
  1448. if (d == NULL) {
  1449. RETURN_FALSE;
  1450. }
  1451. array_init(return_value);
  1452. CAAL("version_number", d->version_num);
  1453. CAAL("age", d->age);
  1454. CAAL("features", d->features);
  1455. CAAL("ssl_version_number", d->ssl_version_num);
  1456. CAAS("version", d->version);
  1457. CAAS("host", d->host);
  1458. CAAS("ssl_version", d->ssl_version);
  1459. CAAS("libz_version", d->libz_version);
  1460. /* Add an array of protocols */
  1461. {
  1462. char **p = (char **) d->protocols;
  1463. zval protocol_list;
  1464. array_init(&protocol_list);
  1465. while (*p != NULL) {
  1466. add_next_index_string(&protocol_list, *p);
  1467. p++;
  1468. }
  1469. CAAZ("protocols", &protocol_list);
  1470. }
  1471. if (d->age >= 1) {
  1472. CAAS("ares", d->ares);
  1473. CAAL("ares_num", d->ares_num);
  1474. }
  1475. if (d->age >= 2) {
  1476. CAAS("libidn", d->libidn);
  1477. }
  1478. if (d->age >= 3) {
  1479. CAAL("iconv_ver_num", d->iconv_ver_num);
  1480. CAAS("libssh_version", d->libssh_version);
  1481. }
  1482. #if LIBCURL_VERSION_NUM >= 0x073900 /* Available since 7.57.0 */
  1483. if (d->age >= 4) {
  1484. CAAL("brotli_ver_num", d->brotli_ver_num);
  1485. CAAS("brotli_version", d->brotli_version);
  1486. }
  1487. #endif
  1488. }
  1489. /* }}} */
  1490. php_curl *init_curl_handle_into_zval(zval *curl)
  1491. {
  1492. php_curl *ch;
  1493. object_init_ex(curl, curl_ce);
  1494. ch = Z_CURL_P(curl);
  1495. init_curl_handle(ch);
  1496. return ch;
  1497. }
  1498. void init_curl_handle(php_curl *ch)
  1499. {
  1500. ch->to_free = ecalloc(1, sizeof(struct _php_curl_free));
  1501. ch->handlers.write = ecalloc(1, sizeof(php_curl_write));
  1502. ch->handlers.write_header = ecalloc(1, sizeof(php_curl_write));
  1503. ch->handlers.read = ecalloc(1, sizeof(php_curl_read));
  1504. ch->handlers.progress = NULL;
  1505. ch->handlers.fnmatch = NULL;
  1506. ch->clone = emalloc(sizeof(uint32_t));
  1507. *ch->clone = 1;
  1508. memset(&ch->err, 0, sizeof(struct _php_curl_error));
  1509. zend_llist_init(&ch->to_free->post, sizeof(struct HttpPost *), (llist_dtor_func_t)curl_free_post, 0);
  1510. zend_llist_init(&ch->to_free->stream, sizeof(struct mime_data_cb_arg *), (llist_dtor_func_t)curl_free_cb_arg, 0);
  1511. #if LIBCURL_VERSION_NUM < 0x073800 /* 7.56.0 */
  1512. zend_llist_init(&ch->to_free->buffers, sizeof(zend_string *), (llist_dtor_func_t)curl_free_buffers, 0);
  1513. #endif
  1514. ch->to_free->slist = emalloc(sizeof(HashTable));
  1515. zend_hash_init(ch->to_free->slist, 4, NULL, curl_free_slist, 0);
  1516. ZVAL_UNDEF(&ch->postfields);
  1517. }
  1518. /* }}} */
  1519. /* {{{ create_certinfo */
  1520. static void create_certinfo(struct curl_certinfo *ci, zval *listcode)
  1521. {
  1522. int i;
  1523. if (ci) {
  1524. zval certhash;
  1525. for (i=0; i<ci->num_of_certs; i++) {
  1526. struct curl_slist *slist;
  1527. array_init(&certhash);
  1528. for (slist = ci->certinfo[i]; slist; slist = slist->next) {
  1529. int len;
  1530. char s[64];
  1531. char *tmp;
  1532. strncpy(s, slist->data, sizeof(s));
  1533. s[sizeof(s)-1] = '\0';
  1534. tmp = memchr(s, ':', sizeof(s));
  1535. if(tmp) {
  1536. *tmp = '\0';
  1537. len = strlen(s);
  1538. add_assoc_string(&certhash, s, &slist->data[len+1]);
  1539. } else {
  1540. php_error_docref(NULL, E_WARNING, "Could not extract hash key from certificate info");
  1541. }
  1542. }
  1543. add_next_index_zval(listcode, &certhash);
  1544. }
  1545. }
  1546. }
  1547. /* }}} */
  1548. /* {{{ _php_curl_set_default_options()
  1549. Set default options for a handle */
  1550. static void _php_curl_set_default_options(php_curl *ch)
  1551. {
  1552. char *cainfo;
  1553. curl_easy_setopt(ch->cp, CURLOPT_NOPROGRESS, 1);
  1554. curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 0);
  1555. curl_easy_setopt(ch->cp, CURLOPT_ERRORBUFFER, ch->err.str);
  1556. curl_easy_setopt(ch->cp, CURLOPT_WRITEFUNCTION, curl_write);
  1557. curl_easy_setopt(ch->cp, CURLOPT_FILE, (void *) ch);
  1558. curl_easy_setopt(ch->cp, CURLOPT_READFUNCTION, curl_read);
  1559. curl_easy_setopt(ch->cp, CURLOPT_INFILE, (void *) ch);
  1560. curl_easy_setopt(ch->cp, CURLOPT_HEADERFUNCTION, curl_write_header);
  1561. curl_easy_setopt(ch->cp, CURLOPT_WRITEHEADER, (void *) ch);
  1562. #ifndef ZTS
  1563. curl_easy_setopt(ch->cp, CURLOPT_DNS_USE_GLOBAL_CACHE, 1);
  1564. #endif
  1565. curl_easy_setopt(ch->cp, CURLOPT_DNS_CACHE_TIMEOUT, 120);
  1566. curl_easy_setopt(ch->cp, CURLOPT_MAXREDIRS, 20); /* prevent infinite redirects */
  1567. cainfo = INI_STR("openssl.cafile");
  1568. if (!(cainfo && cainfo[0] != '\0')) {
  1569. cainfo = INI_STR("curl.cainfo");
  1570. }
  1571. if (cainfo && cainfo[0] != '\0') {
  1572. curl_easy_setopt(ch->cp, CURLOPT_CAINFO, cainfo);
  1573. }
  1574. #ifdef ZTS
  1575. curl_easy_setopt(ch->cp, CURLOPT_NOSIGNAL, 1);
  1576. #endif
  1577. }
  1578. /* }}} */
  1579. /* {{{ Initialize a cURL session */
  1580. PHP_FUNCTION(curl_init)
  1581. {
  1582. php_curl *ch;
  1583. CURL *cp;
  1584. zend_string *url = NULL;
  1585. ZEND_PARSE_PARAMETERS_START(0,1)
  1586. Z_PARAM_OPTIONAL
  1587. Z_PARAM_STR_OR_NULL(url)
  1588. ZEND_PARSE_PARAMETERS_END();
  1589. cp = curl_easy_init();
  1590. if (!cp) {
  1591. php_error_docref(NULL, E_WARNING, "Could not initialize a new cURL handle");
  1592. RETURN_FALSE;
  1593. }
  1594. ch = init_curl_handle_into_zval(return_value);
  1595. ch->cp = cp;
  1596. ch->handlers.write->method = PHP_CURL_STDOUT;
  1597. ch->handlers.read->method = PHP_CURL_DIRECT;
  1598. ch->handlers.write_header->method = PHP_CURL_IGNORE;
  1599. _php_curl_set_default_options(ch);
  1600. if (url) {
  1601. if (php_curl_option_url(ch, ZSTR_VAL(url), ZSTR_LEN(url)) == FAILURE) {
  1602. zval_ptr_dtor(return_value);
  1603. RETURN_FALSE;
  1604. }
  1605. }
  1606. }
  1607. /* }}} */
  1608. void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source)
  1609. {
  1610. if (!Z_ISUNDEF(source->handlers.write->stream)) {
  1611. Z_ADDREF(source->handlers.write->stream);
  1612. }
  1613. ch->handlers.write->stream = source->handlers.write->stream;
  1614. ch->handlers.write->method = source->handlers.write->method;
  1615. if (!Z_ISUNDEF(source->handlers.read->stream)) {
  1616. Z_ADDREF(source->handlers.read->stream);
  1617. }
  1618. ch->handlers.read->stream = source->handlers.read->stream;
  1619. ch->handlers.read->method = source->handlers.read->method;
  1620. ch->handlers.write_header->method = source->handlers.write_header->method;
  1621. if (!Z_ISUNDEF(source->handlers.write_header->stream)) {
  1622. Z_ADDREF(source->handlers.write_header->stream);
  1623. }
  1624. ch->handlers.write_header->stream = source->handlers.write_header->stream;
  1625. ch->handlers.write->fp = source->handlers.write->fp;
  1626. ch->handlers.write_header->fp = source->handlers.write_header->fp;
  1627. ch->handlers.read->fp = source->handlers.read->fp;
  1628. ch->handlers.read->res = source->handlers.read->res;
  1629. if (!Z_ISUNDEF(source->handlers.write->func_name)) {
  1630. ZVAL_COPY(&ch->handlers.write->func_name, &source->handlers.write->func_name);
  1631. }
  1632. if (!Z_ISUNDEF(source->handlers.read->func_name)) {
  1633. ZVAL_COPY(&ch->handlers.read->func_name, &source->handlers.read->func_name);
  1634. }
  1635. if (!Z_ISUNDEF(source->handlers.write_header->func_name)) {
  1636. ZVAL_COPY(&ch->handlers.write_header->func_name, &source->handlers.write_header->func_name);
  1637. }
  1638. curl_easy_setopt(ch->cp, CURLOPT_ERRORBUFFER, ch->err.str);
  1639. curl_easy_setopt(ch->cp, CURLOPT_FILE, (void *) ch);
  1640. curl_easy_setopt(ch->cp, CURLOPT_INFILE, (void *) ch);
  1641. curl_easy_setopt(ch->cp, CURLOPT_WRITEHEADER, (void *) ch);
  1642. curl_easy_setopt(ch->cp, CURLOPT_DEBUGDATA, (void *) ch);
  1643. if (source->handlers.progress) {
  1644. ch->handlers.progress = ecalloc(1, sizeof(php_curl_callback));
  1645. if (!Z_ISUNDEF(source->handlers.progress->func_name)) {
  1646. ZVAL_COPY(&ch->handlers.progress->func_name, &source->handlers.progress->func_name);
  1647. }
  1648. curl_easy_setopt(ch->cp, CURLOPT_PROGRESSDATA, (void *) ch);
  1649. }
  1650. if (source->handlers.fnmatch) {
  1651. ch->handlers.fnmatch = ecalloc(1, sizeof(php_curl_callback));
  1652. if (!Z_ISUNDEF(source->handlers.fnmatch->func_name)) {
  1653. ZVAL_COPY(&ch->handlers.fnmatch->func_name, &source->handlers.fnmatch->func_name);
  1654. }
  1655. curl_easy_setopt(ch->cp, CURLOPT_FNMATCH_DATA, (void *) ch);
  1656. }
  1657. ZVAL_COPY(&ch->private_data, &source->private_data);
  1658. efree(ch->to_free->slist);
  1659. efree(ch->to_free);
  1660. ch->to_free = source->to_free;
  1661. efree(ch->clone);
  1662. ch->clone = source->clone;
  1663. /* Keep track of cloned copies to avoid invoking curl destructors for every clone */
  1664. (*source->clone)++;
  1665. }
  1666. #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
  1667. static size_t read_cb(char *buffer, size_t size, size_t nitems, void *arg) /* {{{ */
  1668. {
  1669. struct mime_data_cb_arg *cb_arg = (struct mime_data_cb_arg *) arg;
  1670. ssize_t numread;
  1671. if (cb_arg->stream == NULL) {
  1672. if (!(cb_arg->stream = php_stream_open_wrapper(ZSTR_VAL(cb_arg->filename), "rb", IGNORE_PATH, NULL))) {
  1673. return CURL_READFUNC_ABORT;
  1674. }
  1675. }
  1676. numread = php_stream_read(cb_arg->stream, buffer, nitems * size);
  1677. if (numread < 0) {
  1678. php_stream_close(cb_arg->stream);
  1679. cb_arg->stream = NULL;
  1680. return CURL_READFUNC_ABORT;
  1681. }
  1682. return numread;
  1683. }
  1684. /* }}} */
  1685. static int seek_cb(void *arg, curl_off_t offset, int origin) /* {{{ */
  1686. {
  1687. struct mime_data_cb_arg *cb_arg = (struct mime_data_cb_arg *) arg;
  1688. int res;
  1689. if (cb_arg->stream == NULL) {
  1690. return CURL_SEEKFUNC_CANTSEEK;
  1691. }
  1692. res = php_stream_seek(cb_arg->stream, offset, origin);
  1693. return res == SUCCESS ? CURL_SEEKFUNC_OK : CURL_SEEKFUNC_CANTSEEK;
  1694. }
  1695. /* }}} */
  1696. static void free_cb(void *arg) /* {{{ */
  1697. {
  1698. struct mime_data_cb_arg *cb_arg = (struct mime_data_cb_arg *) arg;
  1699. if (cb_arg->stream != NULL) {
  1700. php_stream_close(cb_arg->stream);
  1701. cb_arg->stream = NULL;
  1702. }
  1703. }
  1704. /* }}} */
  1705. #endif
  1706. static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields) /* {{{ */
  1707. {
  1708. HashTable *postfields = Z_ARRVAL_P(zpostfields);
  1709. CURLcode error = CURLE_OK;
  1710. zval *current;
  1711. zend_string *string_key;
  1712. zend_ulong num_key;
  1713. #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
  1714. curl_mime *mime = NULL;
  1715. curl_mimepart *part;
  1716. CURLcode form_error;
  1717. #else
  1718. struct HttpPost *first = NULL;
  1719. struct HttpPost *last = NULL;
  1720. CURLFORMcode form_error;
  1721. #endif
  1722. #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
  1723. if (zend_hash_num_elements(postfields) > 0) {
  1724. mime = curl_mime_init(ch->cp);
  1725. if (mime == NULL) {
  1726. return FAILURE;
  1727. }
  1728. }
  1729. #endif
  1730. ZEND_HASH_FOREACH_KEY_VAL(postfields, num_key, string_key, current) {
  1731. zend_string *postval, *tmp_postval;
  1732. /* Pretend we have a string_key here */
  1733. if (!string_key) {
  1734. string_key = zend_long_to_str(num_key);
  1735. } else {
  1736. zend_string_addref(string_key);
  1737. }
  1738. ZVAL_DEREF(current);
  1739. if (Z_TYPE_P(current) == IS_OBJECT &&
  1740. instanceof_function(Z_OBJCE_P(current), curl_CURLFile_class)) {
  1741. /* new-style file upload */
  1742. zval *prop, rv;
  1743. char *type = NULL, *filename = NULL;
  1744. #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
  1745. struct mime_data_cb_arg *cb_arg;
  1746. php_stream *stream;
  1747. php_stream_statbuf ssb;
  1748. size_t filesize = -1;
  1749. curl_seek_callback seekfunc = seek_cb;
  1750. #endif
  1751. prop = zend_read_property(curl_CURLFile_class, Z_OBJ_P(current), "name", sizeof("name")-1, 0, &rv);
  1752. ZVAL_DEREF(prop);
  1753. if (Z_TYPE_P(prop) != IS_STRING) {
  1754. php_error_docref(NULL, E_WARNING, "Invalid filename for key %s", ZSTR_VAL(string_key));
  1755. } else {
  1756. postval = Z_STR_P(prop);
  1757. if (php_check_open_basedir(ZSTR_VAL(postval))) {
  1758. return 1;
  1759. }
  1760. prop = zend_read_property(curl_CURLFile_class, Z_OBJ_P(current), "mime", sizeof("mime")-1, 0, &rv);
  1761. ZVAL_DEREF(prop);
  1762. if (Z_TYPE_P(prop) == IS_STRING && Z_STRLEN_P(prop) > 0) {
  1763. type = Z_STRVAL_P(prop);
  1764. }
  1765. prop = zend_read_property(curl_CURLFile_class, Z_OBJ_P(current), "postname", sizeof("postname")-1, 0, &rv);
  1766. ZVAL_DEREF(prop);
  1767. if (Z_TYPE_P(prop) == IS_STRING && Z_STRLEN_P(prop) > 0) {
  1768. filename = Z_STRVAL_P(prop);
  1769. }
  1770. #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
  1771. zval_ptr_dtor(&ch->postfields);
  1772. ZVAL_COPY(&ch->postfields, zpostfields);
  1773. if ((stream = php_stream_open_wrapper(ZSTR_VAL(postval), "rb", STREAM_MUST_SEEK, NULL))) {
  1774. if (!stream->readfilters.head && !php_stream_stat(stream, &ssb)) {
  1775. filesize = ssb.sb.st_size;
  1776. }
  1777. } else {
  1778. seekfunc = NULL;
  1779. }
  1780. cb_arg = emalloc(sizeof *cb_arg);
  1781. cb_arg->filename = zend_string_copy(postval);
  1782. cb_arg->stream = stream;
  1783. part = curl_mime_addpart(mime);
  1784. if (part == NULL) {
  1785. zend_string_release_ex(string_key, 0);
  1786. return FAILURE;
  1787. }
  1788. if ((form_error = curl_mime_name(part, ZSTR_VAL(string_key))) != CURLE_OK
  1789. || (form_error = curl_mime_data_cb(part, filesize, read_cb, seekfunc, free_cb, cb_arg)) != CURLE_OK
  1790. || (form_error = curl_mime_filename(part, filename ? filename : ZSTR_VAL(postval))) != CURLE_OK
  1791. || (form_error = curl_mime_type(part, type ? type : "application/octet-stream")) != CURLE_OK) {
  1792. error = form_error;
  1793. }
  1794. zend_llist_add_element(&ch->to_free->stream, &cb_arg);
  1795. #else
  1796. form_error = curl_formadd(&first, &last,
  1797. CURLFORM_COPYNAME, ZSTR_VAL(string_key),
  1798. CURLFORM_NAMELENGTH, ZSTR_LEN(string_key),
  1799. CURLFORM_FILENAME, filename ? filename : ZSTR_VAL(postval),
  1800. CURLFORM_CONTENTTYPE, type ? type : "application/octet-stream",
  1801. CURLFORM_FILE, ZSTR_VAL(postval),
  1802. CURLFORM_END);
  1803. if (form_error != CURL_FORMADD_OK) {
  1804. /* Not nice to convert between enums but we only have place for one error type */
  1805. error = (CURLcode)form_error;
  1806. }
  1807. #endif
  1808. }
  1809. zend_string_release_ex(string_key, 0);
  1810. continue;
  1811. }
  1812. if (Z_TYPE_P(current) == IS_OBJECT && instanceof_function(Z_OBJCE_P(current), curl_CURLStringFile_class)) {
  1813. /* new-style file upload from string */
  1814. zval *prop, rv;
  1815. char *type = NULL, *filename = NULL;
  1816. prop = zend_read_property(curl_CURLStringFile_class, Z_OBJ_P(current), "postname", sizeof("postname")-1, 0, &rv);
  1817. if (EG(exception)) {
  1818. zend_string_release_ex(string_key, 0);
  1819. return FAILURE;
  1820. }
  1821. ZVAL_DEREF(prop);
  1822. ZEND_ASSERT(Z_TYPE_P(prop) == IS_STRING);
  1823. filename = Z_STRVAL_P(prop);
  1824. prop = zend_read_property(curl_CURLStringFile_class, Z_OBJ_P(current), "mime", sizeof("mime")-1, 0, &rv);
  1825. if (EG(exception)) {
  1826. zend_string_release_ex(string_key, 0);
  1827. return FAILURE;
  1828. }
  1829. ZVAL_DEREF(prop);
  1830. ZEND_ASSERT(Z_TYPE_P(prop) == IS_STRING);
  1831. type = Z_STRVAL_P(prop);
  1832. prop = zend_read_property(curl_CURLStringFile_class, Z_OBJ_P(current), "data", sizeof("data")-1, 0, &rv);
  1833. if (EG(exception)) {
  1834. zend_string_release_ex(string_key, 0);
  1835. return FAILURE;
  1836. }
  1837. ZVAL_DEREF(prop);
  1838. ZEND_ASSERT(Z_TYPE_P(prop) == IS_STRING);
  1839. postval = Z_STR_P(prop);
  1840. #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
  1841. zval_ptr_dtor(&ch->postfields);
  1842. ZVAL_COPY(&ch->postfields, zpostfields);
  1843. part = curl_mime_addpart(mime);
  1844. if (part == NULL) {
  1845. zend_string_release_ex(string_key, 0);
  1846. return FAILURE;
  1847. }
  1848. if ((form_error = curl_mime_name(part, ZSTR_VAL(string_key))) != CURLE_OK
  1849. || (form_error = curl_mime_data(part, ZSTR_VAL(postval), ZSTR_LEN(postval))) != CURLE_OK
  1850. || (form_error = curl_mime_filename(part, filename)) != CURLE_OK
  1851. || (form_error = curl_mime_type(part, type)) != CURLE_OK) {
  1852. error = form_error;
  1853. }
  1854. #else
  1855. postval = zend_string_copy(postval);
  1856. zend_llist_add_element(&ch->to_free->buffers, &postval);
  1857. form_error = curl_formadd(&first, &last,
  1858. CURLFORM_COPYNAME, ZSTR_VAL(string_key),
  1859. CURLFORM_NAMELENGTH, ZSTR_LEN(string_key),
  1860. CURLFORM_BUFFER, filename,
  1861. CURLFORM_CONTENTTYPE, type,
  1862. CURLFORM_BUFFERPTR, ZSTR_VAL(postval),
  1863. CURLFORM_BUFFERLENGTH, ZSTR_LEN(postval),
  1864. CURLFORM_END);
  1865. if (form_error != CURL_FORMADD_OK) {
  1866. /* Not nice to convert between enums but we only have place for one error type */
  1867. error = (CURLcode)form_error;
  1868. }
  1869. #endif
  1870. zend_string_release_ex(string_key, 0);
  1871. continue;
  1872. }
  1873. postval = zval_get_tmp_string(current, &tmp_postval);
  1874. #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
  1875. part = curl_mime_addpart(mime);
  1876. if (part == NULL) {
  1877. zend_tmp_string_release(tmp_postval);
  1878. zend_string_release_ex(string_key, 0);
  1879. return FAILURE;
  1880. }
  1881. if ((form_error = curl_mime_name(part, ZSTR_VAL(string_key))) != CURLE_OK
  1882. || (form_error = curl_mime_data(part, ZSTR_VAL(postval), ZSTR_LEN(postval))) != CURLE_OK) {
  1883. error = form_error;
  1884. }
  1885. #else
  1886. /* The arguments after _NAMELENGTH and _CONTENTSLENGTH
  1887. * must be explicitly cast to long in curl_formadd
  1888. * use since curl needs a long not an int. */
  1889. form_error = curl_formadd(&first, &last,
  1890. CURLFORM_COPYNAME, ZSTR_VAL(string_key),
  1891. CURLFORM_NAMELENGTH, ZSTR_LEN(string_key),
  1892. CURLFORM_COPYCONTENTS, ZSTR_VAL(postval),
  1893. CURLFORM_CONTENTSLENGTH, ZSTR_LEN(postval),
  1894. CURLFORM_END);
  1895. if (form_error != CURL_FORMADD_OK) {
  1896. /* Not nice to convert between enums but we only have place for one error type */
  1897. error = (CURLcode)form_error;
  1898. }
  1899. #endif
  1900. zend_tmp_string_release(tmp_postval);
  1901. zend_string_release_ex(string_key, 0);
  1902. } ZEND_HASH_FOREACH_END();
  1903. SAVE_CURL_ERROR(ch, error);
  1904. if (error != CURLE_OK) {
  1905. return FAILURE;
  1906. }
  1907. if ((*ch->clone) == 1) {
  1908. zend_llist_clean(&ch->to_free->post);
  1909. }
  1910. #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
  1911. zend_llist_add_element(&ch->to_free->post, &mime);
  1912. error = curl_easy_setopt(ch->cp, CURLOPT_MIMEPOST, mime);
  1913. #else
  1914. zend_llist_add_element(&ch->to_free->post, &first);
  1915. error = curl_easy_setopt(ch->cp, CURLOPT_HTTPPOST, first);
  1916. #endif
  1917. SAVE_CURL_ERROR(ch, error);
  1918. return error == CURLE_OK ? SUCCESS : FAILURE;
  1919. }
  1920. /* }}} */
  1921. /* {{{ Copy a cURL handle along with all of it's preferences */
  1922. PHP_FUNCTION(curl_copy_handle)
  1923. {
  1924. php_curl *ch;
  1925. CURL *cp;
  1926. zval *zid;
  1927. php_curl *dupch;
  1928. zval *postfields;
  1929. ZEND_PARSE_PARAMETERS_START(1,1)
  1930. Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
  1931. ZEND_PARSE_PARAMETERS_END();
  1932. ch = Z_CURL_P(zid);
  1933. cp = curl_easy_duphandle(ch->cp);
  1934. if (!cp) {
  1935. php_error_docref(NULL, E_WARNING, "Cannot duplicate cURL handle");
  1936. RETURN_FALSE;
  1937. }
  1938. dupch = init_curl_handle_into_zval(return_value);
  1939. dupch->cp = cp;
  1940. _php_setup_easy_copy_handlers(dupch, ch);
  1941. postfields = &ch->postfields;
  1942. if (Z_TYPE_P(postfields) != IS_UNDEF) {
  1943. if (build_mime_structure_from_hash(dupch, postfields) != SUCCESS) {
  1944. zval_ptr_dtor(return_value);
  1945. php_error_docref(NULL, E_WARNING, "Cannot rebuild mime structure");
  1946. RETURN_FALSE;
  1947. }
  1948. }
  1949. }
  1950. /* }}} */
  1951. static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue, bool is_array_config) /* {{{ */
  1952. {
  1953. CURLcode error = CURLE_OK;
  1954. zend_long lval;
  1955. switch (option) {
  1956. /* Long options */
  1957. case CURLOPT_SSL_VERIFYHOST:
  1958. lval = zval_get_long(zvalue);
  1959. if (lval == 1) {
  1960. php_error_docref(NULL, E_NOTICE, "CURLOPT_SSL_VERIFYHOST no longer accepts the value 1, value 2 will be used instead");
  1961. error = curl_easy_setopt(ch->cp, option, 2);
  1962. break;
  1963. }
  1964. ZEND_FALLTHROUGH;
  1965. case CURLOPT_AUTOREFERER:
  1966. case CURLOPT_BUFFERSIZE:
  1967. case CURLOPT_CONNECTTIMEOUT:
  1968. case CURLOPT_COOKIESESSION:
  1969. case CURLOPT_CRLF:
  1970. case CURLOPT_DNS_CACHE_TIMEOUT:
  1971. case CURLOPT_DNS_USE_GLOBAL_CACHE:
  1972. case CURLOPT_FAILONERROR:
  1973. case CURLOPT_FILETIME:
  1974. case CURLOPT_FORBID_REUSE:
  1975. case CURLOPT_FRESH_CONNECT:
  1976. case CURLOPT_FTP_USE_EPRT:
  1977. case CURLOPT_FTP_USE_EPSV:
  1978. case CURLOPT_HEADER:
  1979. case CURLOPT_HTTPGET:
  1980. case CURLOPT_HTTPPROXYTUNNEL:
  1981. case CURLOPT_HTTP_VERSION:
  1982. case CURLOPT_INFILESIZE:
  1983. case CURLOPT_LOW_SPEED_LIMIT:
  1984. case CURLOPT_LOW_SPEED_TIME:
  1985. case CURLOPT_MAXCONNECTS:
  1986. case CURLOPT_MAXREDIRS:
  1987. case CURLOPT_NETRC:
  1988. case CURLOPT_NOBODY:
  1989. case CURLOPT_NOPROGRESS:
  1990. case CURLOPT_NOSIGNAL:
  1991. case CURLOPT_PORT:
  1992. case CURLOPT_POST:
  1993. case CURLOPT_PROXYPORT:
  1994. case CURLOPT_PROXYTYPE:
  1995. case CURLOPT_PUT:
  1996. case CURLOPT_RESUME_FROM:
  1997. case CURLOPT_SSLVERSION:
  1998. case CURLOPT_SSL_VERIFYPEER:
  1999. case CURLOPT_TIMECONDITION:
  2000. case CURLOPT_TIMEOUT:
  2001. case CURLOPT_TIMEVALUE:
  2002. case CURLOPT_TRANSFERTEXT:
  2003. case CURLOPT_UNRESTRICTED_AUTH:
  2004. case CURLOPT_UPLOAD:
  2005. case CURLOPT_VERBOSE:
  2006. case CURLOPT_HTTPAUTH:
  2007. case CURLOPT_FTP_CREATE_MISSING_DIRS:
  2008. case CURLOPT_PROXYAUTH:
  2009. case CURLOPT_FTP_RESPONSE_TIMEOUT:
  2010. case CURLOPT_IPRESOLVE:
  2011. case CURLOPT_MAXFILESIZE:
  2012. case CURLOPT_TCP_NODELAY:
  2013. case CURLOPT_FTPSSLAUTH:
  2014. case CURLOPT_IGNORE_CONTENT_LENGTH:
  2015. case CURLOPT_FTP_SKIP_PASV_IP:
  2016. case CURLOPT_FTP_FILEMETHOD:
  2017. case CURLOPT_CONNECT_ONLY:
  2018. case CURLOPT_LOCALPORT:
  2019. case CURLOPT_LOCALPORTRANGE:
  2020. case CURLOPT_SSL_SESSIONID_CACHE:
  2021. case CURLOPT_FTP_SSL_CCC:
  2022. case CURLOPT_SSH_AUTH_TYPES:
  2023. case CURLOPT_CONNECTTIMEOUT_MS:
  2024. case CURLOPT_HTTP_CONTENT_DECODING:
  2025. case CURLOPT_HTTP_TRANSFER_DECODING:
  2026. case CURLOPT_TIMEOUT_MS:
  2027. case CURLOPT_NEW_DIRECTORY_PERMS:
  2028. case CURLOPT_NEW_FILE_PERMS:
  2029. case CURLOPT_USE_SSL:
  2030. case CURLOPT_APPEND:
  2031. case CURLOPT_DIRLISTONLY:
  2032. case CURLOPT_PROXY_TRANSFER_MODE:
  2033. case CURLOPT_ADDRESS_SCOPE:
  2034. case CURLOPT_CERTINFO:
  2035. case CURLOPT_PROTOCOLS:
  2036. case CURLOPT_REDIR_PROTOCOLS:
  2037. case CURLOPT_SOCKS5_GSSAPI_NEC:
  2038. case CURLOPT_TFTP_BLKSIZE:
  2039. case CURLOPT_FTP_USE_PRET:
  2040. case CURLOPT_RTSP_CLIENT_CSEQ:
  2041. case CURLOPT_RTSP_REQUEST:
  2042. case CURLOPT_RTSP_SERVER_CSEQ:
  2043. case CURLOPT_WILDCARDMATCH:
  2044. case CURLOPT_GSSAPI_DELEGATION:
  2045. case CURLOPT_ACCEPTTIMEOUT_MS:
  2046. case CURLOPT_SSL_OPTIONS:
  2047. case CURLOPT_TCP_KEEPALIVE:
  2048. case CURLOPT_TCP_KEEPIDLE:
  2049. case CURLOPT_TCP_KEEPINTVL:
  2050. #if LIBCURL_VERSION_NUM >= 0x071f00 /* Available since 7.31.0 */
  2051. case CURLOPT_SASL_IR:
  2052. #endif
  2053. #if LIBCURL_VERSION_NUM >= 0x072400 /* Available since 7.36.0 */
  2054. case CURLOPT_EXPECT_100_TIMEOUT_MS:
  2055. case CURLOPT_SSL_ENABLE_ALPN:
  2056. case CURLOPT_SSL_ENABLE_NPN:
  2057. #endif
  2058. #if LIBCURL_VERSION_NUM >= 0x072500 /* Available since 7.37.0 */
  2059. case CURLOPT_HEADEROPT:
  2060. #endif
  2061. #if LIBCURL_VERSION_NUM >= 0x072900 /* Available since 7.41.0 */
  2062. case CURLOPT_SSL_VERIFYSTATUS:
  2063. #endif
  2064. #if LIBCURL_VERSION_NUM >= 0x072a00 /* Available since 7.42.0 */
  2065. case CURLOPT_PATH_AS_IS:
  2066. case CURLOPT_SSL_FALSESTART:
  2067. #endif
  2068. #if LIBCURL_VERSION_NUM >= 0x072b00 /* Available since 7.43.0 */
  2069. case CURLOPT_PIPEWAIT:
  2070. #endif
  2071. #if LIBCURL_VERSION_NUM >= 0x072e00 /* Available since 7.46.0 */
  2072. case CURLOPT_STREAM_WEIGHT:
  2073. #endif
  2074. #if LIBCURL_VERSION_NUM >= 0x073000 /* Available since 7.48.0 */
  2075. case CURLOPT_TFTP_NO_OPTIONS:
  2076. #endif
  2077. #if LIBCURL_VERSION_NUM >= 0x073100 /* Available since 7.49.0 */
  2078. case CURLOPT_TCP_FASTOPEN:
  2079. #endif
  2080. #if LIBCURL_VERSION_NUM >= 0x073300 /* Available since 7.51.0 */
  2081. case CURLOPT_KEEP_SENDING_ON_ERROR:
  2082. #endif
  2083. #if LIBCURL_VERSION_NUM >= 0x073400 /* Available since 7.52.0 */
  2084. case CURLOPT_PROXY_SSL_OPTIONS:
  2085. case CURLOPT_PROXY_SSL_VERIFYHOST:
  2086. case CURLOPT_PROXY_SSL_VERIFYPEER:
  2087. case CURLOPT_PROXY_SSLVERSION:
  2088. #endif
  2089. #if LIBCURL_VERSION_NUM >= 0x073600 /* Available since 7.54.0 */
  2090. case CURLOPT_SUPPRESS_CONNECT_HEADERS:
  2091. #endif
  2092. #if LIBCURL_VERSION_NUM >= 0x073700 /* Available since 7.55.0 */
  2093. case CURLOPT_SOCKS5_AUTH:
  2094. #endif
  2095. #if LIBCURL_VERSION_NUM >= 0x073800 /* Available since 7.56.0 */
  2096. case CURLOPT_SSH_COMPRESSION:
  2097. #endif
  2098. #if LIBCURL_VERSION_NUM >= 0x073b00 /* Available since 7.59.0 */
  2099. case CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS:
  2100. #endif
  2101. #if LIBCURL_VERSION_NUM >= 0x073c00 /* Available since 7.60.0 */
  2102. case CURLOPT_DNS_SHUFFLE_ADDRESSES:
  2103. case CURLOPT_HAPROXYPROTOCOL:
  2104. #endif
  2105. #if LIBCURL_VERSION_NUM >= 0x073d00 /* Available since 7.61.0 */
  2106. case CURLOPT_DISALLOW_USERNAME_IN_URL:
  2107. #endif
  2108. #if LIBCURL_VERSION_NUM >= 0x074000 /* Available since 7.64.0 */
  2109. case CURLOPT_HTTP09_ALLOWED:
  2110. #endif
  2111. lval = zval_get_long(zvalue);
  2112. if ((option == CURLOPT_PROTOCOLS || option == CURLOPT_REDIR_PROTOCOLS) &&
  2113. (PG(open_basedir) && *PG(open_basedir)) && (lval & CURLPROTO_FILE)) {
  2114. php_error_docref(NULL, E_WARNING, "CURLPROTO_FILE cannot be activated when an open_basedir is set");
  2115. return 1;
  2116. }
  2117. # if defined(ZTS)
  2118. if (option == CURLOPT_DNS_USE_GLOBAL_CACHE && lval) {
  2119. php_error_docref(NULL, E_WARNING, "CURLOPT_DNS_USE_GLOBAL_CACHE cannot be activated when thread safety is enabled");
  2120. return 1;
  2121. }
  2122. # endif
  2123. error = curl_easy_setopt(ch->cp, option, lval);
  2124. break;
  2125. case CURLOPT_SAFE_UPLOAD:
  2126. if (!zend_is_true(zvalue)) {
  2127. zend_value_error("%s(): Disabling safe uploads is no longer supported", get_active_function_name());
  2128. return FAILURE;
  2129. }
  2130. break;
  2131. /* String options */
  2132. case CURLOPT_CAINFO:
  2133. case CURLOPT_CAPATH:
  2134. case CURLOPT_COOKIE:
  2135. case CURLOPT_EGDSOCKET:
  2136. case CURLOPT_INTERFACE:
  2137. case CURLOPT_PROXY:
  2138. case CURLOPT_PROXYUSERPWD:
  2139. case CURLOPT_REFERER:
  2140. case CURLOPT_SSLCERTTYPE:
  2141. case CURLOPT_SSLENGINE:
  2142. case CURLOPT_SSLENGINE_DEFAULT:
  2143. case CURLOPT_SSLKEY:
  2144. case CURLOPT_SSLKEYPASSWD:
  2145. case CURLOPT_SSLKEYTYPE:
  2146. case CURLOPT_SSL_CIPHER_LIST:
  2147. case CURLOPT_USERAGENT:
  2148. case CURLOPT_USERPWD:
  2149. case CURLOPT_COOKIELIST:
  2150. case CURLOPT_FTP_ALTERNATIVE_TO_USER:
  2151. case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
  2152. case CURLOPT_PASSWORD:
  2153. case CURLOPT_PROXYPASSWORD:
  2154. case CURLOPT_PROXYUSERNAME:
  2155. case CURLOPT_USERNAME:
  2156. case CURLOPT_NOPROXY:
  2157. case CURLOPT_SOCKS5_GSSAPI_SERVICE:
  2158. case CURLOPT_MAIL_FROM:
  2159. case CURLOPT_RTSP_STREAM_URI:
  2160. case CURLOPT_RTSP_TRANSPORT:
  2161. case CURLOPT_TLSAUTH_TYPE:
  2162. case CURLOPT_TLSAUTH_PASSWORD:
  2163. case CURLOPT_TLSAUTH_USERNAME:
  2164. case CURLOPT_ACCEPT_ENCODING:
  2165. case CURLOPT_TRANSFER_ENCODING:
  2166. case CURLOPT_DNS_SERVERS:
  2167. case CURLOPT_MAIL_AUTH:
  2168. #if LIBCURL_VERSION_NUM >= 0x072200 /* Available since 7.34.0 */
  2169. case CURLOPT_LOGIN_OPTIONS:
  2170. #endif
  2171. #if LIBCURL_VERSION_NUM >= 0x072700 /* Available since 7.39.0 */
  2172. case CURLOPT_PINNEDPUBLICKEY:
  2173. #endif
  2174. #if LIBCURL_VERSION_NUM >= 0x072b00 /* Available since 7.43.0 */
  2175. case CURLOPT_PROXY_SERVICE_NAME:
  2176. case CURLOPT_SERVICE_NAME:
  2177. #endif
  2178. #if LIBCURL_VERSION_NUM >= 0x072d00 /* Available since 7.45.0 */
  2179. case CURLOPT_DEFAULT_PROTOCOL:
  2180. #endif
  2181. #if LIBCURL_VERSION_NUM >= 0x073400 /* Available since 7.52.0 */
  2182. case CURLOPT_PRE_PROXY:
  2183. case CURLOPT_PROXY_CAINFO:
  2184. case CURLOPT_PROXY_CAPATH:
  2185. case CURLOPT_PROXY_CRLFILE:
  2186. case CURLOPT_PROXY_KEYPASSWD:
  2187. case CURLOPT_PROXY_PINNEDPUBLICKEY:
  2188. case CURLOPT_PROXY_SSL_CIPHER_LIST:
  2189. case CURLOPT_PROXY_SSLCERT:
  2190. case CURLOPT_PROXY_SSLCERTTYPE:
  2191. case CURLOPT_PROXY_SSLKEY:
  2192. case CURLOPT_PROXY_SSLKEYTYPE:
  2193. case CURLOPT_PROXY_TLSAUTH_PASSWORD:
  2194. case CURLOPT_PROXY_TLSAUTH_TYPE:
  2195. case CURLOPT_PROXY_TLSAUTH_USERNAME:
  2196. #endif
  2197. #if LIBCURL_VERSION_NUM >= 0x073500 /* Available since 7.53.0 */
  2198. case CURLOPT_ABSTRACT_UNIX_SOCKET:
  2199. #endif
  2200. #if LIBCURL_VERSION_NUM >= 0x073700 /* Available since 7.55.0 */
  2201. case CURLOPT_REQUEST_TARGET:
  2202. #endif
  2203. #if LIBCURL_VERSION_NUM >= 0x073d00 /* Available since 7.61.0 */
  2204. case CURLOPT_PROXY_TLS13_CIPHERS:
  2205. case CURLOPT_TLS13_CIPHERS:
  2206. #endif
  2207. #if LIBCURL_VERSION_NUM >= 0x074700 /* Available since 7.71.0 */
  2208. case CURLOPT_PROXY_ISSUERCERT:
  2209. #endif
  2210. {
  2211. zend_string *tmp_str;
  2212. zend_string *str = zval_get_tmp_string(zvalue, &tmp_str);
  2213. int ret = php_curl_option_str(ch, option, ZSTR_VAL(str), ZSTR_LEN(str));
  2214. zend_tmp_string_release(tmp_str);
  2215. return ret;
  2216. }
  2217. /* Curl nullable string options */
  2218. case CURLOPT_CUSTOMREQUEST:
  2219. case CURLOPT_FTPPORT:
  2220. case CURLOPT_RANGE:
  2221. case CURLOPT_FTP_ACCOUNT:
  2222. case CURLOPT_RTSP_SESSION_ID:
  2223. #if LIBCURL_VERSION_NUM >= 0x072100 /* Available since 7.33.0 */
  2224. case CURLOPT_DNS_INTERFACE:
  2225. case CURLOPT_DNS_LOCAL_IP4:
  2226. case CURLOPT_DNS_LOCAL_IP6:
  2227. case CURLOPT_XOAUTH2_BEARER:
  2228. #endif
  2229. #if LIBCURL_VERSION_NUM >= 0x072800 /* Available since 7.40.0 */
  2230. case CURLOPT_UNIX_SOCKET_PATH:
  2231. #endif
  2232. #if LIBCURL_VERSION_NUM >= 0x073E00 /* Available since 7.62.0 */
  2233. case CURLOPT_DOH_URL:
  2234. #endif
  2235. case CURLOPT_KRBLEVEL:
  2236. {
  2237. if (Z_ISNULL_P(zvalue)) {
  2238. error = curl_easy_setopt(ch->cp, option, NULL);
  2239. } else {
  2240. zend_string *tmp_str;
  2241. zend_string *str = zval_get_tmp_string(zvalue, &tmp_str);
  2242. int ret = php_curl_option_str(ch, option, ZSTR_VAL(str), ZSTR_LEN(str));
  2243. zend_tmp_string_release(tmp_str);
  2244. return ret;
  2245. }
  2246. break;
  2247. }
  2248. /* Curl private option */
  2249. case CURLOPT_PRIVATE:
  2250. {
  2251. zval_ptr_dtor(&ch->private_data);
  2252. ZVAL_COPY(&ch->private_data, zvalue);
  2253. return SUCCESS;
  2254. }
  2255. /* Curl url option */
  2256. case CURLOPT_URL:
  2257. {
  2258. zend_string *tmp_str;
  2259. zend_string *str = zval_get_tmp_string(zvalue, &tmp_str);
  2260. int ret = php_curl_option_url(ch, ZSTR_VAL(str), ZSTR_LEN(str));
  2261. zend_tmp_string_release(tmp_str);
  2262. return ret;
  2263. }
  2264. /* Curl file handle options */
  2265. case CURLOPT_FILE:
  2266. case CURLOPT_INFILE:
  2267. case CURLOPT_STDERR:
  2268. case CURLOPT_WRITEHEADER: {
  2269. FILE *fp = NULL;
  2270. php_stream *what = NULL;
  2271. if (Z_TYPE_P(zvalue) != IS_NULL) {
  2272. what = (php_stream *)zend_fetch_resource2_ex(zvalue, "File-Handle", php_file_le_stream(), php_file_le_pstream());
  2273. if (!what) {
  2274. return FAILURE;
  2275. }
  2276. if (FAILURE == php_stream_cast(what, PHP_STREAM_AS_STDIO, (void *) &fp, REPORT_ERRORS)) {
  2277. return FAILURE;
  2278. }
  2279. if (!fp) {
  2280. return FAILURE;
  2281. }
  2282. }
  2283. error = CURLE_OK;
  2284. switch (option) {
  2285. case CURLOPT_FILE:
  2286. if (!what) {
  2287. if (!Z_ISUNDEF(ch->handlers.write->stream)) {
  2288. zval_ptr_dtor(&ch->handlers.write->stream);
  2289. ZVAL_UNDEF(&ch->handlers.write->stream);
  2290. }
  2291. ch->handlers.write->fp = NULL;
  2292. ch->handlers.write->method = PHP_CURL_STDOUT;
  2293. } else if (what->mode[0] != 'r' || what->mode[1] == '+') {
  2294. zval_ptr_dtor(&ch->handlers.write->stream);
  2295. ch->handlers.write->fp = fp;
  2296. ch->handlers.write->method = PHP_CURL_FILE;
  2297. ZVAL_COPY(&ch->handlers.write->stream, zvalue);
  2298. } else {
  2299. zend_value_error("%s(): The provided file handle must be writable", get_active_function_name());
  2300. return FAILURE;
  2301. }
  2302. break;
  2303. case CURLOPT_WRITEHEADER:
  2304. if (!what) {
  2305. if (!Z_ISUNDEF(ch->handlers.write_header->stream)) {
  2306. zval_ptr_dtor(&ch->handlers.write_header->stream);
  2307. ZVAL_UNDEF(&ch->handlers.write_header->stream);
  2308. }
  2309. ch->handlers.write_header->fp = NULL;
  2310. ch->handlers.write_header->method = PHP_CURL_IGNORE;
  2311. } else if (what->mode[0] != 'r' || what->mode[1] == '+') {
  2312. zval_ptr_dtor(&ch->handlers.write_header->stream);
  2313. ch->handlers.write_header->fp = fp;
  2314. ch->handlers.write_header->method = PHP_CURL_FILE;
  2315. ZVAL_COPY(&ch->handlers.write_header->stream, zvalue);
  2316. } else {
  2317. zend_value_error("%s(): The provided file handle must be writable", get_active_function_name());
  2318. return FAILURE;
  2319. }
  2320. break;
  2321. case CURLOPT_INFILE:
  2322. if (!what) {
  2323. if (!Z_ISUNDEF(ch->handlers.read->stream)) {
  2324. zval_ptr_dtor(&ch->handlers.read->stream);
  2325. ZVAL_UNDEF(&ch->handlers.read->stream);
  2326. }
  2327. ch->handlers.read->fp = NULL;
  2328. ch->handlers.read->res = NULL;
  2329. } else {
  2330. zval_ptr_dtor(&ch->handlers.read->stream);
  2331. ch->handlers.read->fp = fp;
  2332. ch->handlers.read->res = Z_RES_P(zvalue);
  2333. ZVAL_COPY(&ch->handlers.read->stream, zvalue);
  2334. }
  2335. break;
  2336. case CURLOPT_STDERR:
  2337. if (!what) {
  2338. if (!Z_ISUNDEF(ch->handlers.std_err)) {
  2339. zval_ptr_dtor(&ch->handlers.std_err);
  2340. ZVAL_UNDEF(&ch->handlers.std_err);
  2341. }
  2342. } else if (what->mode[0] != 'r' || what->mode[1] == '+') {
  2343. zval_ptr_dtor(&ch->handlers.std_err);
  2344. ZVAL_COPY(&ch->handlers.std_err, zvalue);
  2345. } else {
  2346. zend_value_error("%s(): The provided file handle must be writable", get_active_function_name());
  2347. return FAILURE;
  2348. }
  2349. ZEND_FALLTHROUGH;
  2350. default:
  2351. error = curl_easy_setopt(ch->cp, option, fp);
  2352. break;
  2353. }
  2354. break;
  2355. }
  2356. /* Curl linked list options */
  2357. case CURLOPT_HTTP200ALIASES:
  2358. case CURLOPT_HTTPHEADER:
  2359. case CURLOPT_POSTQUOTE:
  2360. case CURLOPT_PREQUOTE:
  2361. case CURLOPT_QUOTE:
  2362. case CURLOPT_TELNETOPTIONS:
  2363. case CURLOPT_MAIL_RCPT:
  2364. case CURLOPT_RESOLVE:
  2365. #if LIBCURL_VERSION_NUM >= 0x072500 /* Available since 7.37.0 */
  2366. case CURLOPT_PROXYHEADER:
  2367. #endif
  2368. #if LIBCURL_VERSION_NUM >= 0x073100 /* Available since 7.49.0 */
  2369. case CURLOPT_CONNECT_TO:
  2370. #endif
  2371. {
  2372. zval *current;
  2373. HashTable *ph;
  2374. zend_string *val, *tmp_val;
  2375. struct curl_slist *slist = NULL;
  2376. if (Z_TYPE_P(zvalue) != IS_ARRAY) {
  2377. char *name = NULL;
  2378. switch (option) {
  2379. case CURLOPT_HTTPHEADER:
  2380. name = "CURLOPT_HTTPHEADER";
  2381. break;
  2382. case CURLOPT_QUOTE:
  2383. name = "CURLOPT_QUOTE";
  2384. break;
  2385. case CURLOPT_HTTP200ALIASES:
  2386. name = "CURLOPT_HTTP200ALIASES";
  2387. break;
  2388. case CURLOPT_POSTQUOTE:
  2389. name = "CURLOPT_POSTQUOTE";
  2390. break;
  2391. case CURLOPT_PREQUOTE:
  2392. name = "CURLOPT_PREQUOTE";
  2393. break;
  2394. case CURLOPT_TELNETOPTIONS:
  2395. name = "CURLOPT_TELNETOPTIONS";
  2396. break;
  2397. case CURLOPT_MAIL_RCPT:
  2398. name = "CURLOPT_MAIL_RCPT";
  2399. break;
  2400. case CURLOPT_RESOLVE:
  2401. name = "CURLOPT_RESOLVE";
  2402. break;
  2403. #if LIBCURL_VERSION_NUM >= 0x072500 /* Available since 7.37.0 */
  2404. case CURLOPT_PROXYHEADER:
  2405. name = "CURLOPT_PROXYHEADER";
  2406. break;
  2407. #endif
  2408. #if LIBCURL_VERSION_NUM >= 0x073100 /* Available since 7.49.0 */
  2409. case CURLOPT_CONNECT_TO:
  2410. name = "CURLOPT_CONNECT_TO";
  2411. break;
  2412. #endif
  2413. }
  2414. zend_type_error("%s(): The %s option must have an array value", get_active_function_name(), name);
  2415. return FAILURE;
  2416. }
  2417. ph = Z_ARRVAL_P(zvalue);
  2418. ZEND_HASH_FOREACH_VAL(ph, current) {
  2419. ZVAL_DEREF(current);
  2420. val = zval_get_tmp_string(current, &tmp_val);
  2421. slist = curl_slist_append(slist, ZSTR_VAL(val));
  2422. zend_tmp_string_release(tmp_val);
  2423. if (!slist) {
  2424. php_error_docref(NULL, E_WARNING, "Could not build curl_slist");
  2425. return 1;
  2426. }
  2427. } ZEND_HASH_FOREACH_END();
  2428. if (slist) {
  2429. if ((*ch->clone) == 1) {
  2430. zend_hash_index_update_ptr(ch->to_free->slist, option, slist);
  2431. } else {
  2432. zend_hash_next_index_insert_ptr(ch->to_free->slist, slist);
  2433. }
  2434. }
  2435. error = curl_easy_setopt(ch->cp, option, slist);
  2436. break;
  2437. }
  2438. case CURLOPT_BINARYTRANSFER:
  2439. /* Do nothing, just backward compatibility */
  2440. break;
  2441. case CURLOPT_FOLLOWLOCATION:
  2442. lval = zend_is_true(zvalue);
  2443. error = curl_easy_setopt(ch->cp, option, lval);
  2444. break;
  2445. case CURLOPT_HEADERFUNCTION:
  2446. if (!Z_ISUNDEF(ch->handlers.write_header->func_name)) {
  2447. zval_ptr_dtor(&ch->handlers.write_header->func_name);
  2448. ch->handlers.write_header->fci_cache = empty_fcall_info_cache;
  2449. }
  2450. ZVAL_COPY(&ch->handlers.write_header->func_name, zvalue);
  2451. ch->handlers.write_header->method = PHP_CURL_USER;
  2452. break;
  2453. case CURLOPT_POSTFIELDS:
  2454. if (Z_TYPE_P(zvalue) == IS_ARRAY) {
  2455. if (zend_hash_num_elements(HASH_OF(zvalue)) == 0) {
  2456. /* no need to build the mime structure for empty hashtables;
  2457. also works around https://github.com/curl/curl/issues/6455 */
  2458. curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDS, "");
  2459. error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDSIZE, 0);
  2460. } else {
  2461. return build_mime_structure_from_hash(ch, zvalue);
  2462. }
  2463. } else {
  2464. zend_string *tmp_str;
  2465. zend_string *str = zval_get_tmp_string(zvalue, &tmp_str);
  2466. /* with curl 7.17.0 and later, we can use COPYPOSTFIELDS, but we have to provide size before */
  2467. error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDSIZE, ZSTR_LEN(str));
  2468. error = curl_easy_setopt(ch->cp, CURLOPT_COPYPOSTFIELDS, ZSTR_VAL(str));
  2469. zend_tmp_string_release(tmp_str);
  2470. }
  2471. break;
  2472. case CURLOPT_PROGRESSFUNCTION:
  2473. curl_easy_setopt(ch->cp, CURLOPT_PROGRESSFUNCTION, curl_progress);
  2474. curl_easy_setopt(ch->cp, CURLOPT_PROGRESSDATA, ch);
  2475. if (ch->handlers.progress == NULL) {
  2476. ch->handlers.progress = ecalloc(1, sizeof(php_curl_callback));
  2477. } else if (!Z_ISUNDEF(ch->handlers.progress->func_name)) {
  2478. zval_ptr_dtor(&ch->handlers.progress->func_name);
  2479. ch->handlers.progress->fci_cache = empty_fcall_info_cache;
  2480. }
  2481. ZVAL_COPY(&ch->handlers.progress->func_name, zvalue);
  2482. break;
  2483. case CURLOPT_READFUNCTION:
  2484. if (!Z_ISUNDEF(ch->handlers.read->func_name)) {
  2485. zval_ptr_dtor(&ch->handlers.read->func_name);
  2486. ch->handlers.read->fci_cache = empty_fcall_info_cache;
  2487. }
  2488. ZVAL_COPY(&ch->handlers.read->func_name, zvalue);
  2489. ch->handlers.read->method = PHP_CURL_USER;
  2490. break;
  2491. case CURLOPT_RETURNTRANSFER:
  2492. if (zend_is_true(zvalue)) {
  2493. ch->handlers.write->method = PHP_CURL_RETURN;
  2494. } else {
  2495. ch->handlers.write->method = PHP_CURL_STDOUT;
  2496. }
  2497. break;
  2498. case CURLOPT_WRITEFUNCTION:
  2499. if (!Z_ISUNDEF(ch->handlers.write->func_name)) {
  2500. zval_ptr_dtor(&ch->handlers.write->func_name);
  2501. ch->handlers.write->fci_cache = empty_fcall_info_cache;
  2502. }
  2503. ZVAL_COPY(&ch->handlers.write->func_name, zvalue);
  2504. ch->handlers.write->method = PHP_CURL_USER;
  2505. break;
  2506. /* Curl off_t options */
  2507. case CURLOPT_MAX_RECV_SPEED_LARGE:
  2508. case CURLOPT_MAX_SEND_SPEED_LARGE:
  2509. #if LIBCURL_VERSION_NUM >= 0x073b00 /* Available since 7.59.0 */
  2510. case CURLOPT_TIMEVALUE_LARGE:
  2511. #endif
  2512. lval = zval_get_long(zvalue);
  2513. error = curl_easy_setopt(ch->cp, option, (curl_off_t)lval);
  2514. break;
  2515. case CURLOPT_POSTREDIR:
  2516. lval = zval_get_long(zvalue);
  2517. error = curl_easy_setopt(ch->cp, CURLOPT_POSTREDIR, lval & CURL_REDIR_POST_ALL);
  2518. break;
  2519. /* the following options deal with files, therefore the open_basedir check
  2520. * is required.
  2521. */
  2522. case CURLOPT_COOKIEFILE:
  2523. case CURLOPT_COOKIEJAR:
  2524. case CURLOPT_RANDOM_FILE:
  2525. case CURLOPT_SSLCERT:
  2526. case CURLOPT_NETRC_FILE:
  2527. case CURLOPT_SSH_PRIVATE_KEYFILE:
  2528. case CURLOPT_SSH_PUBLIC_KEYFILE:
  2529. case CURLOPT_CRLFILE:
  2530. case CURLOPT_ISSUERCERT:
  2531. case CURLOPT_SSH_KNOWNHOSTS:
  2532. {
  2533. zend_string *tmp_str;
  2534. zend_string *str = zval_get_tmp_string(zvalue, &tmp_str);
  2535. int ret;
  2536. if (ZSTR_LEN(str) && php_check_open_basedir(ZSTR_VAL(str))) {
  2537. zend_tmp_string_release(tmp_str);
  2538. return FAILURE;
  2539. }
  2540. ret = php_curl_option_str(ch, option, ZSTR_VAL(str), ZSTR_LEN(str));
  2541. zend_tmp_string_release(tmp_str);
  2542. return ret;
  2543. }
  2544. case CURLINFO_HEADER_OUT:
  2545. if (zend_is_true(zvalue)) {
  2546. curl_easy_setopt(ch->cp, CURLOPT_DEBUGFUNCTION, curl_debug);
  2547. curl_easy_setopt(ch->cp, CURLOPT_DEBUGDATA, (void *)ch);
  2548. curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 1);
  2549. } else {
  2550. curl_easy_setopt(ch->cp, CURLOPT_DEBUGFUNCTION, NULL);
  2551. curl_easy_setopt(ch->cp, CURLOPT_DEBUGDATA, NULL);
  2552. curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 0);
  2553. }
  2554. break;
  2555. case CURLOPT_SHARE:
  2556. {
  2557. if (Z_TYPE_P(zvalue) == IS_OBJECT && Z_OBJCE_P(zvalue) == curl_share_ce) {
  2558. php_curlsh *sh = Z_CURL_SHARE_P(zvalue);
  2559. curl_easy_setopt(ch->cp, CURLOPT_SHARE, sh->share);
  2560. if (ch->share) {
  2561. OBJ_RELEASE(&ch->share->std);
  2562. }
  2563. GC_ADDREF(&sh->std);
  2564. ch->share = sh;
  2565. }
  2566. }
  2567. break;
  2568. case CURLOPT_FNMATCH_FUNCTION:
  2569. curl_easy_setopt(ch->cp, CURLOPT_FNMATCH_FUNCTION, curl_fnmatch);
  2570. curl_easy_setopt(ch->cp, CURLOPT_FNMATCH_DATA, ch);
  2571. if (ch->handlers.fnmatch == NULL) {
  2572. ch->handlers.fnmatch = ecalloc(1, sizeof(php_curl_callback));
  2573. } else if (!Z_ISUNDEF(ch->handlers.fnmatch->func_name)) {
  2574. zval_ptr_dtor(&ch->handlers.fnmatch->func_name);
  2575. ch->handlers.fnmatch->fci_cache = empty_fcall_info_cache;
  2576. }
  2577. ZVAL_COPY(&ch->handlers.fnmatch->func_name, zvalue);
  2578. break;
  2579. /* Curl blob options */
  2580. #if LIBCURL_VERSION_NUM >= 0x074700 /* Available since 7.71.0 */
  2581. case CURLOPT_ISSUERCERT_BLOB:
  2582. case CURLOPT_PROXY_ISSUERCERT_BLOB:
  2583. case CURLOPT_PROXY_SSLCERT_BLOB:
  2584. case CURLOPT_PROXY_SSLKEY_BLOB:
  2585. case CURLOPT_SSLCERT_BLOB:
  2586. case CURLOPT_SSLKEY_BLOB:
  2587. {
  2588. zend_string *tmp_str;
  2589. zend_string *str = zval_get_tmp_string(zvalue, &tmp_str);
  2590. struct curl_blob stblob;
  2591. stblob.data = ZSTR_VAL(str);
  2592. stblob.len = ZSTR_LEN(str);
  2593. stblob.flags = CURL_BLOB_COPY;
  2594. error = curl_easy_setopt(ch->cp, option, &stblob);
  2595. zend_tmp_string_release(tmp_str);
  2596. }
  2597. break;
  2598. #endif
  2599. default:
  2600. if (is_array_config) {
  2601. zend_argument_value_error(2, "must contain only valid cURL options");
  2602. } else {
  2603. zend_argument_value_error(2, "is not a valid cURL option");
  2604. }
  2605. error = CURLE_UNKNOWN_OPTION;
  2606. break;
  2607. }
  2608. SAVE_CURL_ERROR(ch, error);
  2609. if (error != CURLE_OK) {
  2610. return FAILURE;
  2611. } else {
  2612. return SUCCESS;
  2613. }
  2614. }
  2615. /* }}} */
  2616. /* {{{ Set an option for a cURL transfer */
  2617. PHP_FUNCTION(curl_setopt)
  2618. {
  2619. zval *zid, *zvalue;
  2620. zend_long options;
  2621. php_curl *ch;
  2622. ZEND_PARSE_PARAMETERS_START(3, 3)
  2623. Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
  2624. Z_PARAM_LONG(options)
  2625. Z_PARAM_ZVAL(zvalue)
  2626. ZEND_PARSE_PARAMETERS_END();
  2627. ch = Z_CURL_P(zid);
  2628. if (_php_curl_setopt(ch, options, zvalue, 0) == SUCCESS) {
  2629. RETURN_TRUE;
  2630. } else {
  2631. RETURN_FALSE;
  2632. }
  2633. }
  2634. /* }}} */
  2635. /* {{{ Set an array of option for a cURL transfer */
  2636. PHP_FUNCTION(curl_setopt_array)
  2637. {
  2638. zval *zid, *arr, *entry;
  2639. php_curl *ch;
  2640. zend_ulong option;
  2641. zend_string *string_key;
  2642. ZEND_PARSE_PARAMETERS_START(2, 2)
  2643. Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
  2644. Z_PARAM_ARRAY(arr)
  2645. ZEND_PARSE_PARAMETERS_END();
  2646. ch = Z_CURL_P(zid);
  2647. ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(arr), option, string_key, entry) {
  2648. if (string_key) {
  2649. zend_argument_value_error(2, "contains an invalid cURL option");
  2650. RETURN_THROWS();
  2651. }
  2652. ZVAL_DEREF(entry);
  2653. if (_php_curl_setopt(ch, (zend_long) option, entry, 1) == FAILURE) {
  2654. RETURN_FALSE;
  2655. }
  2656. } ZEND_HASH_FOREACH_END();
  2657. RETURN_TRUE;
  2658. }
  2659. /* }}} */
  2660. /* {{{ _php_curl_cleanup_handle(ch)
  2661. Cleanup an execution phase */
  2662. void _php_curl_cleanup_handle(php_curl *ch)
  2663. {
  2664. smart_str_free(&ch->handlers.write->buf);
  2665. if (ch->header.str) {
  2666. zend_string_release_ex(ch->header.str, 0);
  2667. ch->header.str = NULL;
  2668. }
  2669. memset(ch->err.str, 0, CURL_ERROR_SIZE + 1);
  2670. ch->err.no = 0;
  2671. }
  2672. /* }}} */
  2673. /* {{{ Perform a cURL session */
  2674. PHP_FUNCTION(curl_exec)
  2675. {
  2676. CURLcode error;
  2677. zval *zid;
  2678. php_curl *ch;
  2679. ZEND_PARSE_PARAMETERS_START(1, 1)
  2680. Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
  2681. ZEND_PARSE_PARAMETERS_END();
  2682. ch = Z_CURL_P(zid);
  2683. _php_curl_verify_handlers(ch, 1);
  2684. _php_curl_cleanup_handle(ch);
  2685. error = curl_easy_perform(ch->cp);
  2686. SAVE_CURL_ERROR(ch, error);
  2687. if (error != CURLE_OK) {
  2688. smart_str_free(&ch->handlers.write->buf);
  2689. RETURN_FALSE;
  2690. }
  2691. if (!Z_ISUNDEF(ch->handlers.std_err)) {
  2692. php_stream *stream;
  2693. stream = (php_stream*)zend_fetch_resource2_ex(&ch->handlers.std_err, NULL, php_file_le_stream(), php_file_le_pstream());
  2694. if (stream) {
  2695. php_stream_flush(stream);
  2696. }
  2697. }
  2698. if (ch->handlers.write->method == PHP_CURL_RETURN && ch->handlers.write->buf.s) {
  2699. smart_str_0(&ch->handlers.write->buf);
  2700. RETURN_STR_COPY(ch->handlers.write->buf.s);
  2701. }
  2702. /* flush the file handle, so any remaining data is synched to disk */
  2703. if (ch->handlers.write->method == PHP_CURL_FILE && ch->handlers.write->fp) {
  2704. fflush(ch->handlers.write->fp);
  2705. }
  2706. if (ch->handlers.write_header->method == PHP_CURL_FILE && ch->handlers.write_header->fp) {
  2707. fflush(ch->handlers.write_header->fp);
  2708. }
  2709. if (ch->handlers.write->method == PHP_CURL_RETURN) {
  2710. RETURN_EMPTY_STRING();
  2711. } else {
  2712. RETURN_TRUE;
  2713. }
  2714. }
  2715. /* }}} */
  2716. /* {{{ Get information regarding a specific transfer */
  2717. PHP_FUNCTION(curl_getinfo)
  2718. {
  2719. zval *zid;
  2720. php_curl *ch;
  2721. zend_long option;
  2722. bool option_is_null = 1;
  2723. ZEND_PARSE_PARAMETERS_START(1, 2)
  2724. Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
  2725. Z_PARAM_OPTIONAL
  2726. Z_PARAM_LONG_OR_NULL(option, option_is_null)
  2727. ZEND_PARSE_PARAMETERS_END();
  2728. ch = Z_CURL_P(zid);
  2729. if (option_is_null) {
  2730. char *s_code;
  2731. /* libcurl expects long datatype. So far no cases are known where
  2732. it would be an issue. Using zend_long would truncate a 64-bit
  2733. var on Win64, so the exact long datatype fits everywhere, as
  2734. long as there's no 32-bit int overflow. */
  2735. long l_code;
  2736. double d_code;
  2737. struct curl_certinfo *ci = NULL;
  2738. zval listcode;
  2739. #if LIBCURL_VERSION_NUM >= 0x073d00 /* 7.61.0 */
  2740. curl_off_t co;
  2741. #endif
  2742. array_init(return_value);
  2743. if (curl_easy_getinfo(ch->cp, CURLINFO_EFFECTIVE_URL, &s_code) == CURLE_OK) {
  2744. CAAS("url", s_code);
  2745. }
  2746. if (curl_easy_getinfo(ch->cp, CURLINFO_CONTENT_TYPE, &s_code) == CURLE_OK) {
  2747. if (s_code != NULL) {
  2748. CAAS("content_type", s_code);
  2749. } else {
  2750. zval retnull;
  2751. ZVAL_NULL(&retnull);
  2752. CAAZ("content_type", &retnull);
  2753. }
  2754. }
  2755. if (curl_easy_getinfo(ch->cp, CURLINFO_HTTP_CODE, &l_code) == CURLE_OK) {
  2756. CAAL("http_code", l_code);
  2757. }
  2758. if (curl_easy_getinfo(ch->cp, CURLINFO_HEADER_SIZE, &l_code) == CURLE_OK) {
  2759. CAAL("header_size", l_code);
  2760. }
  2761. if (curl_easy_getinfo(ch->cp, CURLINFO_REQUEST_SIZE, &l_code) == CURLE_OK) {
  2762. CAAL("request_size", l_code);
  2763. }
  2764. if (curl_easy_getinfo(ch->cp, CURLINFO_FILETIME, &l_code) == CURLE_OK) {
  2765. CAAL("filetime", l_code);
  2766. }
  2767. if (curl_easy_getinfo(ch->cp, CURLINFO_SSL_VERIFYRESULT, &l_code) == CURLE_OK) {
  2768. CAAL("ssl_verify_result", l_code);
  2769. }
  2770. if (curl_easy_getinfo(ch->cp, CURLINFO_REDIRECT_COUNT, &l_code) == CURLE_OK) {
  2771. CAAL("redirect_count", l_code);
  2772. }
  2773. if (curl_easy_getinfo(ch->cp, CURLINFO_TOTAL_TIME, &d_code) == CURLE_OK) {
  2774. CAAD("total_time", d_code);
  2775. }
  2776. if (curl_easy_getinfo(ch->cp, CURLINFO_NAMELOOKUP_TIME, &d_code) == CURLE_OK) {
  2777. CAAD("namelookup_time", d_code);
  2778. }
  2779. if (curl_easy_getinfo(ch->cp, CURLINFO_CONNECT_TIME, &d_code) == CURLE_OK) {
  2780. CAAD("connect_time", d_code);
  2781. }
  2782. if (curl_easy_getinfo(ch->cp, CURLINFO_PRETRANSFER_TIME, &d_code) == CURLE_OK) {
  2783. CAAD("pretransfer_time", d_code);
  2784. }
  2785. if (curl_easy_getinfo(ch->cp, CURLINFO_SIZE_UPLOAD, &d_code) == CURLE_OK) {
  2786. CAAD("size_upload", d_code);
  2787. }
  2788. if (curl_easy_getinfo(ch->cp, CURLINFO_SIZE_DOWNLOAD, &d_code) == CURLE_OK) {
  2789. CAAD("size_download", d_code);
  2790. }
  2791. if (curl_easy_getinfo(ch->cp, CURLINFO_SPEED_DOWNLOAD, &d_code) == CURLE_OK) {
  2792. CAAD("speed_download", d_code);
  2793. }
  2794. if (curl_easy_getinfo(ch->cp, CURLINFO_SPEED_UPLOAD, &d_code) == CURLE_OK) {
  2795. CAAD("speed_upload", d_code);
  2796. }
  2797. if (curl_easy_getinfo(ch->cp, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d_code) == CURLE_OK) {
  2798. CAAD("download_content_length", d_code);
  2799. }
  2800. if (curl_easy_getinfo(ch->cp, CURLINFO_CONTENT_LENGTH_UPLOAD, &d_code) == CURLE_OK) {
  2801. CAAD("upload_content_length", d_code);
  2802. }
  2803. if (curl_easy_getinfo(ch->cp, CURLINFO_STARTTRANSFER_TIME, &d_code) == CURLE_OK) {
  2804. CAAD("starttransfer_time", d_code);
  2805. }
  2806. if (curl_easy_getinfo(ch->cp, CURLINFO_REDIRECT_TIME, &d_code) == CURLE_OK) {
  2807. CAAD("redirect_time", d_code);
  2808. }
  2809. if (curl_easy_getinfo(ch->cp, CURLINFO_REDIRECT_URL, &s_code) == CURLE_OK) {
  2810. CAAS("redirect_url", s_code);
  2811. }
  2812. if (curl_easy_getinfo(ch->cp, CURLINFO_PRIMARY_IP, &s_code) == CURLE_OK) {
  2813. CAAS("primary_ip", s_code);
  2814. }
  2815. if (curl_easy_getinfo(ch->cp, CURLINFO_CERTINFO, &ci) == CURLE_OK) {
  2816. array_init(&listcode);
  2817. create_certinfo(ci, &listcode);
  2818. CAAZ("certinfo", &listcode);
  2819. }
  2820. if (curl_easy_getinfo(ch->cp, CURLINFO_PRIMARY_PORT, &l_code) == CURLE_OK) {
  2821. CAAL("primary_port", l_code);
  2822. }
  2823. if (curl_easy_getinfo(ch->cp, CURLINFO_LOCAL_IP, &s_code) == CURLE_OK) {
  2824. CAAS("local_ip", s_code);
  2825. }
  2826. if (curl_easy_getinfo(ch->cp, CURLINFO_LOCAL_PORT, &l_code) == CURLE_OK) {
  2827. CAAL("local_port", l_code);
  2828. }
  2829. #if LIBCURL_VERSION_NUM >= 0x073200 /* Available since 7.50.0 */
  2830. if (curl_easy_getinfo(ch->cp, CURLINFO_HTTP_VERSION, &l_code) == CURLE_OK) {
  2831. CAAL("http_version", l_code);
  2832. }
  2833. #endif
  2834. #if LIBCURL_VERSION_NUM >= 0x073400 /* Available since 7.52.0 */
  2835. if (curl_easy_getinfo(ch->cp, CURLINFO_PROTOCOL, &l_code) == CURLE_OK) {
  2836. CAAL("protocol", l_code);
  2837. }
  2838. if (curl_easy_getinfo(ch->cp, CURLINFO_PROXY_SSL_VERIFYRESULT, &l_code) == CURLE_OK) {
  2839. CAAL("ssl_verifyresult", l_code);
  2840. }
  2841. if (curl_easy_getinfo(ch->cp, CURLINFO_SCHEME, &s_code) == CURLE_OK) {
  2842. CAAS("scheme", s_code);
  2843. }
  2844. #endif
  2845. #if LIBCURL_VERSION_NUM >= 0x073d00 /* Available since 7.61.0 */
  2846. if (curl_easy_getinfo(ch->cp, CURLINFO_APPCONNECT_TIME_T, &co) == CURLE_OK) {
  2847. CAAL("appconnect_time_us", co);
  2848. }
  2849. if (curl_easy_getinfo(ch->cp, CURLINFO_CONNECT_TIME_T, &co) == CURLE_OK) {
  2850. CAAL("connect_time_us", co);
  2851. }
  2852. if (curl_easy_getinfo(ch->cp, CURLINFO_NAMELOOKUP_TIME_T, &co) == CURLE_OK) {
  2853. CAAL("namelookup_time_us", co);
  2854. }
  2855. if (curl_easy_getinfo(ch->cp, CURLINFO_PRETRANSFER_TIME_T, &co) == CURLE_OK) {
  2856. CAAL("pretransfer_time_us", co);
  2857. }
  2858. if (curl_easy_getinfo(ch->cp, CURLINFO_REDIRECT_TIME_T, &co) == CURLE_OK) {
  2859. CAAL("redirect_time_us", co);
  2860. }
  2861. if (curl_easy_getinfo(ch->cp, CURLINFO_STARTTRANSFER_TIME_T, &co) == CURLE_OK) {
  2862. CAAL("starttransfer_time_us", co);
  2863. }
  2864. if (curl_easy_getinfo(ch->cp, CURLINFO_TOTAL_TIME_T, &co) == CURLE_OK) {
  2865. CAAL("total_time_us", co);
  2866. }
  2867. #endif
  2868. if (ch->header.str) {
  2869. CAASTR("request_header", ch->header.str);
  2870. }
  2871. } else {
  2872. switch (option) {
  2873. case CURLINFO_HEADER_OUT:
  2874. if (ch->header.str) {
  2875. RETURN_STR_COPY(ch->header.str);
  2876. } else {
  2877. RETURN_FALSE;
  2878. }
  2879. case CURLINFO_CERTINFO: {
  2880. struct curl_certinfo *ci = NULL;
  2881. array_init(return_value);
  2882. if (curl_easy_getinfo(ch->cp, CURLINFO_CERTINFO, &ci) == CURLE_OK) {
  2883. create_certinfo(ci, return_value);
  2884. } else {
  2885. RETURN_FALSE;
  2886. }
  2887. break;
  2888. }
  2889. case CURLINFO_PRIVATE:
  2890. if (!Z_ISUNDEF(ch->private_data)) {
  2891. RETURN_COPY(&ch->private_data);
  2892. } else {
  2893. RETURN_FALSE;
  2894. }
  2895. break;
  2896. default: {
  2897. int type = CURLINFO_TYPEMASK & option;
  2898. switch (type) {
  2899. case CURLINFO_STRING:
  2900. {
  2901. char *s_code = NULL;
  2902. if (curl_easy_getinfo(ch->cp, option, &s_code) == CURLE_OK && s_code) {
  2903. RETURN_STRING(s_code);
  2904. } else {
  2905. RETURN_FALSE;
  2906. }
  2907. break;
  2908. }
  2909. case CURLINFO_LONG:
  2910. {
  2911. zend_long code = 0;
  2912. if (curl_easy_getinfo(ch->cp, option, &code) == CURLE_OK) {
  2913. RETURN_LONG(code);
  2914. } else {
  2915. RETURN_FALSE;
  2916. }
  2917. break;
  2918. }
  2919. case CURLINFO_DOUBLE:
  2920. {
  2921. double code = 0.0;
  2922. if (curl_easy_getinfo(ch->cp, option, &code) == CURLE_OK) {
  2923. RETURN_DOUBLE(code);
  2924. } else {
  2925. RETURN_FALSE;
  2926. }
  2927. break;
  2928. }
  2929. case CURLINFO_SLIST:
  2930. {
  2931. struct curl_slist *slist;
  2932. if (curl_easy_getinfo(ch->cp, option, &slist) == CURLE_OK) {
  2933. struct curl_slist *current = slist;
  2934. array_init(return_value);
  2935. while (current) {
  2936. add_next_index_string(return_value, current->data);
  2937. current = current->next;
  2938. }
  2939. curl_slist_free_all(slist);
  2940. } else {
  2941. RETURN_FALSE;
  2942. }
  2943. break;
  2944. }
  2945. #if LIBCURL_VERSION_NUM >= 0x073700 /* Available since 7.55.0 */
  2946. case CURLINFO_OFF_T:
  2947. {
  2948. curl_off_t c_off;
  2949. if (curl_easy_getinfo(ch->cp, option, &c_off) == CURLE_OK) {
  2950. RETURN_LONG((long) c_off);
  2951. } else {
  2952. RETURN_FALSE;
  2953. }
  2954. break;
  2955. }
  2956. #endif
  2957. default:
  2958. RETURN_FALSE;
  2959. }
  2960. }
  2961. }
  2962. }
  2963. }
  2964. /* }}} */
  2965. /* {{{ Return a string contain the last error for the current session */
  2966. PHP_FUNCTION(curl_error)
  2967. {
  2968. zval *zid;
  2969. php_curl *ch;
  2970. ZEND_PARSE_PARAMETERS_START(1, 1)
  2971. Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
  2972. ZEND_PARSE_PARAMETERS_END();
  2973. ch = Z_CURL_P(zid);
  2974. if (ch->err.no) {
  2975. ch->err.str[CURL_ERROR_SIZE] = 0;
  2976. RETURN_STRING(ch->err.str);
  2977. } else {
  2978. RETURN_EMPTY_STRING();
  2979. }
  2980. }
  2981. /* }}} */
  2982. /* {{{ Return an integer containing the last error number */
  2983. PHP_FUNCTION(curl_errno)
  2984. {
  2985. zval *zid;
  2986. php_curl *ch;
  2987. ZEND_PARSE_PARAMETERS_START(1,1)
  2988. Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
  2989. ZEND_PARSE_PARAMETERS_END();
  2990. ch = Z_CURL_P(zid);
  2991. RETURN_LONG(ch->err.no);
  2992. }
  2993. /* }}} */
  2994. /* {{{ Close a cURL session */
  2995. PHP_FUNCTION(curl_close)
  2996. {
  2997. zval *zid;
  2998. php_curl *ch;
  2999. ZEND_PARSE_PARAMETERS_START(1, 1)
  3000. Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
  3001. ZEND_PARSE_PARAMETERS_END();
  3002. ch = Z_CURL_P(zid);
  3003. if (ch->in_callback) {
  3004. zend_throw_error(NULL, "%s(): Attempt to close cURL handle from a callback", get_active_function_name());
  3005. RETURN_THROWS();
  3006. }
  3007. }
  3008. /* }}} */
  3009. static void curl_free_obj(zend_object *object)
  3010. {
  3011. php_curl *ch = curl_from_obj(object);
  3012. #if PHP_CURL_DEBUG
  3013. fprintf(stderr, "DTOR CALLED, ch = %x\n", ch);
  3014. #endif
  3015. if (!ch->cp) {
  3016. /* Can happen if constructor throws. */
  3017. zend_object_std_dtor(&ch->std);
  3018. return;
  3019. }
  3020. _php_curl_verify_handlers(ch, 0);
  3021. /*
  3022. * Libcurl is doing connection caching. When easy handle is cleaned up,
  3023. * if the handle was previously used by the curl_multi_api, the connection
  3024. * remains open un the curl multi handle is cleaned up. Some protocols are
  3025. * sending content like the FTP one, and libcurl try to use the
  3026. * WRITEFUNCTION or the HEADERFUNCTION. Since structures used in those
  3027. * callback are freed, we need to use an other callback to which avoid
  3028. * segfaults.
  3029. *
  3030. * Libcurl commit d021f2e8a00 fix this issue and should be part of 7.28.2
  3031. */
  3032. curl_easy_setopt(ch->cp, CURLOPT_HEADERFUNCTION, curl_write_nothing);
  3033. curl_easy_setopt(ch->cp, CURLOPT_WRITEFUNCTION, curl_write_nothing);
  3034. curl_easy_cleanup(ch->cp);
  3035. /* cURL destructors should be invoked only by last curl handle */
  3036. if (--(*ch->clone) == 0) {
  3037. zend_llist_clean(&ch->to_free->post);
  3038. zend_llist_clean(&ch->to_free->stream);
  3039. #if LIBCURL_VERSION_NUM < 0x073800 /* 7.56.0 */
  3040. zend_llist_clean(&ch->to_free->buffers);
  3041. #endif
  3042. zend_hash_destroy(ch->to_free->slist);
  3043. efree(ch->to_free->slist);
  3044. efree(ch->to_free);
  3045. efree(ch->clone);
  3046. }
  3047. smart_str_free(&ch->handlers.write->buf);
  3048. zval_ptr_dtor(&ch->handlers.write->func_name);
  3049. zval_ptr_dtor(&ch->handlers.read->func_name);
  3050. zval_ptr_dtor(&ch->handlers.write_header->func_name);
  3051. zval_ptr_dtor(&ch->handlers.std_err);
  3052. if (ch->header.str) {
  3053. zend_string_release_ex(ch->header.str, 0);
  3054. }
  3055. zval_ptr_dtor(&ch->handlers.write_header->stream);
  3056. zval_ptr_dtor(&ch->handlers.write->stream);
  3057. zval_ptr_dtor(&ch->handlers.read->stream);
  3058. efree(ch->handlers.write);
  3059. efree(ch->handlers.write_header);
  3060. efree(ch->handlers.read);
  3061. if (ch->handlers.progress) {
  3062. zval_ptr_dtor(&ch->handlers.progress->func_name);
  3063. efree(ch->handlers.progress);
  3064. }
  3065. if (ch->handlers.fnmatch) {
  3066. zval_ptr_dtor(&ch->handlers.fnmatch->func_name);
  3067. efree(ch->handlers.fnmatch);
  3068. }
  3069. zval_ptr_dtor(&ch->postfields);
  3070. zval_ptr_dtor(&ch->private_data);
  3071. if (ch->share) {
  3072. OBJ_RELEASE(&ch->share->std);
  3073. }
  3074. zend_object_std_dtor(&ch->std);
  3075. }
  3076. /* }}} */
  3077. /* {{{ return string describing error code */
  3078. PHP_FUNCTION(curl_strerror)
  3079. {
  3080. zend_long code;
  3081. const char *str;
  3082. ZEND_PARSE_PARAMETERS_START(1, 1)
  3083. Z_PARAM_LONG(code)
  3084. ZEND_PARSE_PARAMETERS_END();
  3085. str = curl_easy_strerror(code);
  3086. if (str) {
  3087. RETURN_STRING(str);
  3088. } else {
  3089. RETURN_NULL();
  3090. }
  3091. }
  3092. /* }}} */
  3093. /* {{{ _php_curl_reset_handlers()
  3094. Reset all handlers of a given php_curl */
  3095. static void _php_curl_reset_handlers(php_curl *ch)
  3096. {
  3097. if (!Z_ISUNDEF(ch->handlers.write->stream)) {
  3098. zval_ptr_dtor(&ch->handlers.write->stream);
  3099. ZVAL_UNDEF(&ch->handlers.write->stream);
  3100. }
  3101. ch->handlers.write->fp = NULL;
  3102. ch->handlers.write->method = PHP_CURL_STDOUT;
  3103. if (!Z_ISUNDEF(ch->handlers.write_header->stream)) {
  3104. zval_ptr_dtor(&ch->handlers.write_header->stream);
  3105. ZVAL_UNDEF(&ch->handlers.write_header->stream);
  3106. }
  3107. ch->handlers.write_header->fp = NULL;
  3108. ch->handlers.write_header->method = PHP_CURL_IGNORE;
  3109. if (!Z_ISUNDEF(ch->handlers.read->stream)) {
  3110. zval_ptr_dtor(&ch->handlers.read->stream);
  3111. ZVAL_UNDEF(&ch->handlers.read->stream);
  3112. }
  3113. ch->handlers.read->fp = NULL;
  3114. ch->handlers.read->res = NULL;
  3115. ch->handlers.read->method = PHP_CURL_DIRECT;
  3116. if (!Z_ISUNDEF(ch->handlers.std_err)) {
  3117. zval_ptr_dtor(&ch->handlers.std_err);
  3118. ZVAL_UNDEF(&ch->handlers.std_err);
  3119. }
  3120. if (ch->handlers.progress) {
  3121. zval_ptr_dtor(&ch->handlers.progress->func_name);
  3122. efree(ch->handlers.progress);
  3123. ch->handlers.progress = NULL;
  3124. }
  3125. if (ch->handlers.fnmatch) {
  3126. zval_ptr_dtor(&ch->handlers.fnmatch->func_name);
  3127. efree(ch->handlers.fnmatch);
  3128. ch->handlers.fnmatch = NULL;
  3129. }
  3130. }
  3131. /* }}} */
  3132. /* {{{ Reset all options of a libcurl session handle */
  3133. PHP_FUNCTION(curl_reset)
  3134. {
  3135. zval *zid;
  3136. php_curl *ch;
  3137. ZEND_PARSE_PARAMETERS_START(1, 1)
  3138. Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
  3139. ZEND_PARSE_PARAMETERS_END();
  3140. ch = Z_CURL_P(zid);
  3141. if (ch->in_callback) {
  3142. zend_throw_error(NULL, "%s(): Attempt to reset cURL handle from a callback", get_active_function_name());
  3143. RETURN_THROWS();
  3144. }
  3145. curl_easy_reset(ch->cp);
  3146. _php_curl_reset_handlers(ch);
  3147. _php_curl_set_default_options(ch);
  3148. }
  3149. /* }}} */
  3150. /* {{{ URL encodes the given string */
  3151. PHP_FUNCTION(curl_escape)
  3152. {
  3153. zend_string *str;
  3154. char *res;
  3155. zval *zid;
  3156. php_curl *ch;
  3157. ZEND_PARSE_PARAMETERS_START(2,2)
  3158. Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
  3159. Z_PARAM_STR(str)
  3160. ZEND_PARSE_PARAMETERS_END();
  3161. ch = Z_CURL_P(zid);
  3162. if (ZEND_SIZE_T_INT_OVFL(ZSTR_LEN(str))) {
  3163. RETURN_FALSE;
  3164. }
  3165. if ((res = curl_easy_escape(ch->cp, ZSTR_VAL(str), ZSTR_LEN(str)))) {
  3166. RETVAL_STRING(res);
  3167. curl_free(res);
  3168. } else {
  3169. RETURN_FALSE;
  3170. }
  3171. }
  3172. /* }}} */
  3173. /* {{{ URL decodes the given string */
  3174. PHP_FUNCTION(curl_unescape)
  3175. {
  3176. char *out = NULL;
  3177. int out_len;
  3178. zval *zid;
  3179. zend_string *str;
  3180. php_curl *ch;
  3181. ZEND_PARSE_PARAMETERS_START(2,2)
  3182. Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
  3183. Z_PARAM_STR(str)
  3184. ZEND_PARSE_PARAMETERS_END();
  3185. ch = Z_CURL_P(zid);
  3186. if (ZEND_SIZE_T_INT_OVFL(ZSTR_LEN(str))) {
  3187. RETURN_FALSE;
  3188. }
  3189. if ((out = curl_easy_unescape(ch->cp, ZSTR_VAL(str), ZSTR_LEN(str), &out_len))) {
  3190. RETVAL_STRINGL(out, out_len);
  3191. curl_free(out);
  3192. } else {
  3193. RETURN_FALSE;
  3194. }
  3195. }
  3196. /* }}} */
  3197. /* {{{ pause and unpause a connection */
  3198. PHP_FUNCTION(curl_pause)
  3199. {
  3200. zend_long bitmask;
  3201. zval *zid;
  3202. php_curl *ch;
  3203. ZEND_PARSE_PARAMETERS_START(2,2)
  3204. Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
  3205. Z_PARAM_LONG(bitmask)
  3206. ZEND_PARSE_PARAMETERS_END();
  3207. ch = Z_CURL_P(zid);
  3208. RETURN_LONG(curl_easy_pause(ch->cp, bitmask));
  3209. }
  3210. /* }}} */