📄 curl.c
字号:
/* }}} *//* {{{ curl_free_post */static void curl_free_post(void **post){ curl_formfree((struct HttpPost *) *post);}/* }}} *//* {{{ curl_free_slist */static void curl_free_slist(void **slist){ curl_slist_free_all((struct curl_slist *) *slist);}/* }}} *//* {{{ proto string curl_version(void) Return cURL version information. */PHP_FUNCTION(curl_version){ if (ZEND_NUM_ARGS() != 0) { WRONG_PARAM_COUNT; } RETURN_STRING(curl_version(), 1);}/* }}} *//* {{{ alloc_curl_handle */static void alloc_curl_handle(php_curl **ch){ *ch = emalloc(sizeof(php_curl)); (*ch)->handlers = ecalloc(1, sizeof(php_curl_handlers)); (*ch)->handlers->write = ecalloc(1, sizeof(php_curl_write)); (*ch)->handlers->write_header = ecalloc(1, sizeof(php_curl_write)); (*ch)->handlers->read = ecalloc(1, sizeof(php_curl_read)); memset(&(*ch)->err, 0, sizeof((*ch)->err)); (*ch)->in_callback = 0; zend_llist_init(&(*ch)->to_free.str, sizeof(char *), (void(*)(void *)) curl_free_string, 0); zend_llist_init(&(*ch)->to_free.slist, sizeof(struct curl_slist), (void(*)(void *)) curl_free_slist, 0); zend_llist_init(&(*ch)->to_free.post, sizeof(struct HttpPost), (void(*)(void *)) curl_free_post, 0);}/* }}} *//* {{{ proto resource curl_init([string url]) Initialize a CURL session */PHP_FUNCTION(curl_init){ zval **url; php_curl *ch; int argc = ZEND_NUM_ARGS(); if (argc < 0 || argc > 1 || zend_get_parameters_ex(argc, &url) == FAILURE) { WRONG_PARAM_COUNT; } if (argc > 0) { convert_to_string_ex(url); PHP_CURL_CHECK_OPEN_BASEDIR(Z_STRVAL_PP(url), Z_STRLEN_PP(url)); } alloc_curl_handle(&ch); ch->cp = curl_easy_init(); if (! ch->cp) { php_error(E_WARNING, "%s(): Cannot initialize a new cURL handle", get_active_function_name(TSRMLS_C)); RETURN_FALSE; } ch->handlers->write->method = PHP_CURL_STDOUT; ch->handlers->write->type = PHP_CURL_ASCII; ch->handlers->read->method = PHP_CURL_DIRECT; ch->handlers->write_header->method = PHP_CURL_IGNORE; ch->uses = 0; curl_easy_setopt(ch->cp, CURLOPT_NOPROGRESS, 1); curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 0); curl_easy_setopt(ch->cp, CURLOPT_ERRORBUFFER, ch->err.str); curl_easy_setopt(ch->cp, CURLOPT_WRITEFUNCTION, curl_write); curl_easy_setopt(ch->cp, CURLOPT_FILE, (void *) ch); curl_easy_setopt(ch->cp, CURLOPT_READFUNCTION, curl_read); curl_easy_setopt(ch->cp, CURLOPT_INFILE, (void *) ch); curl_easy_setopt(ch->cp, CURLOPT_HEADERFUNCTION, curl_write_header); curl_easy_setopt(ch->cp, CURLOPT_WRITEHEADER, (void *) ch); curl_easy_setopt(ch->cp, CURLOPT_DNS_USE_GLOBAL_CACHE, 1); curl_easy_setopt(ch->cp, CURLOPT_DNS_CACHE_TIMEOUT, 120); curl_easy_setopt(ch->cp, CURLOPT_MAXREDIRS, 20); /* prevent infinite redirects */ if (argc > 0) { char *urlcopy; urlcopy = estrndup(Z_STRVAL_PP(url), Z_STRLEN_PP(url)); curl_easy_setopt(ch->cp, CURLOPT_URL, urlcopy); zend_llist_add_element(&ch->to_free.str, &urlcopy); } ZEND_REGISTER_RESOURCE(return_value, ch, le_curl); ch->id = Z_LVAL_P(return_value);}/* }}} *//* {{{ proto bool curl_setopt(resource ch, int option, mixed value) Set an option for a CURL transfer */PHP_FUNCTION(curl_setopt){ zval **zid, **zoption, **zvalue; php_curl *ch; CURLcode error=CURLE_OK; int option; if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &zid, &zoption, &zvalue) == FAILURE) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(ch, php_curl *, zid, -1, le_curl_name, le_curl); convert_to_long_ex(zoption); option = Z_LVAL_PP(zoption); switch (option) { case CURLOPT_INFILESIZE: case CURLOPT_VERBOSE: case CURLOPT_HEADER: case CURLOPT_NOPROGRESS: case CURLOPT_NOBODY: case CURLOPT_FAILONERROR: case CURLOPT_UPLOAD: case CURLOPT_POST: case CURLOPT_FTPLISTONLY: case CURLOPT_FTPAPPEND: case CURLOPT_NETRC: case CURLOPT_PUT:#if CURLOPT_MUTE != 0 case CURLOPT_MUTE:#endif case CURLOPT_TIMEOUT: case CURLOPT_FTP_USE_EPSV: case CURLOPT_LOW_SPEED_LIMIT: case CURLOPT_SSLVERSION: case CURLOPT_LOW_SPEED_TIME: case CURLOPT_RESUME_FROM: case CURLOPT_TIMEVALUE: case CURLOPT_TIMECONDITION: case CURLOPT_TRANSFERTEXT: case CURLOPT_HTTPPROXYTUNNEL: case CURLOPT_FILETIME: case CURLOPT_MAXREDIRS: case CURLOPT_MAXCONNECTS: case CURLOPT_CLOSEPOLICY: case CURLOPT_FRESH_CONNECT: case CURLOPT_FORBID_REUSE: case CURLOPT_CONNECTTIMEOUT: case CURLOPT_SSL_VERIFYHOST: case CURLOPT_SSL_VERIFYPEER: case CURLOPT_DNS_USE_GLOBAL_CACHE: case CURLOPT_HTTPGET: case CURLOPT_HTTP_VERSION: case CURLOPT_CRLF:#if LIBCURL_VERSION_NUM > 0x070a05 /* CURLOPT_HTTPAUTH is available since curl 7.10.6 */ case CURLOPT_HTTPAUTH:#endif#if LIBCURL_VERSION_NUM > 0x070a06 /* CURLOPT_PROXYAUTH is available since curl 7.10.7 */ case CURLOPT_PROXYAUTH:#endif convert_to_long_ex(zvalue); error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue)); break; case CURLOPT_FOLLOWLOCATION: convert_to_long_ex(zvalue); if ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) { if (Z_LVAL_PP(zvalue) != 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set"); RETURN_FALSE; } } error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue)); break; case CURLOPT_URL: case CURLOPT_PROXY: case CURLOPT_USERPWD: case CURLOPT_PROXYUSERPWD: case CURLOPT_RANGE: case CURLOPT_CUSTOMREQUEST: case CURLOPT_USERAGENT: case CURLOPT_FTPPORT: case CURLOPT_COOKIE: case CURLOPT_REFERER: case CURLOPT_INTERFACE: case CURLOPT_KRB4LEVEL: case CURLOPT_EGDSOCKET: case CURLOPT_CAINFO: case CURLOPT_CAPATH: case CURLOPT_SSL_CIPHER_LIST: case CURLOPT_SSLKEY: case CURLOPT_SSLKEYTYPE: case CURLOPT_SSLKEYPASSWD: case CURLOPT_SSLENGINE: #if LIBCURL_VERSION_NUM >= 0x070a00 case CURLOPT_ENCODING: #endif case CURLOPT_SSLENGINE_DEFAULT: { char *copystr = NULL; convert_to_string_ex(zvalue); if (option == CURLOPT_URL) { PHP_CURL_CHECK_OPEN_BASEDIR(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue)); } copystr = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue)); error = curl_easy_setopt(ch->cp, option, copystr); zend_llist_add_element(&ch->to_free.str, ©str); break; } case CURLOPT_FILE: case CURLOPT_INFILE: case CURLOPT_WRITEHEADER: case CURLOPT_STDERR: { FILE *fp = NULL; int type; void * what; what = zend_fetch_resource(zvalue TSRMLS_CC, -1, "File-Handle", &type, 1, php_file_le_stream()); ZEND_VERIFY_RESOURCE(what); if (FAILURE == php_stream_cast((php_stream *) what, PHP_STREAM_AS_STDIO, (void *) &fp, REPORT_ERRORS)) { RETURN_FALSE; } if (!fp) { RETURN_FALSE; } error = CURLE_OK; switch (option) { case CURLOPT_FILE: ch->handlers->write->fp = fp; ch->handlers->write->method = PHP_CURL_FILE; break; case CURLOPT_WRITEHEADER: ch->handlers->write_header->fp = fp; ch->handlers->write_header->method = PHP_CURL_FILE; break; case CURLOPT_INFILE: zend_list_addref(Z_LVAL_PP(zvalue)); ch->handlers->read->fp = fp; ch->handlers->read->fd = Z_LVAL_PP(zvalue); break; default: error = curl_easy_setopt(ch->cp, option, fp); break; } break; } case CURLOPT_RETURNTRANSFER: convert_to_long_ex(zvalue); if (Z_LVAL_PP(zvalue)) { ch->handlers->write->method = PHP_CURL_RETURN; } else { ch->handlers->write->method = PHP_CURL_STDOUT; } break; case CURLOPT_BINARYTRANSFER: convert_to_long_ex(zvalue); if (Z_LVAL_PP(zvalue)) { ch->handlers->write->type = PHP_CURL_BINARY; } break; case CURLOPT_WRITEFUNCTION: if (ch->handlers->write->func) { zval_ptr_dtor(&ch->handlers->write->func); ch->handlers->write->func = NULL; } zval_add_ref(zvalue); ch->handlers->write->func = *zvalue; ch->handlers->write->method = PHP_CURL_USER; break; case CURLOPT_READFUNCTION: if (ch->handlers->read->func) { zval_ptr_dtor(&ch->handlers->read->func); ch->handlers->read->func = NULL; } zval_add_ref(zvalue); ch->handlers->read->func = *zvalue; ch->handlers->read->method = PHP_CURL_USER; break; case CURLOPT_HEADERFUNCTION: if (ch->handlers->write_header->func) { zval_ptr_dtor(&ch->handlers->write_header->func); ch->handlers->write_header->func = NULL; } zval_add_ref(zvalue); ch->handlers->write_header->func = *zvalue; ch->handlers->write_header->method = PHP_CURL_USER; break;#if CURLOPT_PASSWDFUNCTION != 0 case CURLOPT_PASSWDFUNCTION: if (ch->handlers->passwd) { zval_ptr_dtor(&ch->handlers->passwd); ch->handlers->passwd = NULL; } zval_add_ref(zvalue); ch->handlers->passwd = *zvalue; error = curl_easy_setopt(ch->cp, CURLOPT_PASSWDFUNCTION, curl_passwd); error = curl_easy_setopt(ch->cp, CURLOPT_PASSWDDATA, (void *) ch); break;#endif case CURLOPT_POSTFIELDS: if (Z_TYPE_PP(zvalue) == IS_ARRAY || Z_TYPE_PP(zvalue) == IS_OBJECT) { zval **current; HashTable *postfields; struct HttpPost *first = NULL; struct HttpPost *last = NULL; char *postval; char *string_key = NULL; ulong num_key; uint string_key_len; postfields = HASH_OF(*zvalue); if (! postfields) { php_error(E_WARNING, "%s(): Couldn't get HashTable in CURLOPT_POSTFIELDS", get_active_function_name(TSRMLS_C)); RETURN_FALSE; } for (zend_hash_internal_pointer_reset(postfields); zend_hash_get_current_data(postfields, (void **) ¤t) == SUCCESS; zend_hash_move_forward(postfields)) { SEPARATE_ZVAL(current); convert_to_string_ex(current); zend_hash_get_current_key_ex(postfields, &string_key, &string_key_len, &num_key, 0, NULL); postval = Z_STRVAL_PP(current); if (*postval == '@') { ++postval; /* safe_mode / open_basedir check */ if (php_check_open_basedir(postval TSRMLS_CC) || (PG(safe_mode) && !php_checkuid(postval, "rb+", CHECKUID_CHECK_MODE_PARAM))) { RETURN_FALSE; } error = curl_formadd(&first, &last, CURLFORM_COPYNAME, string_key, CURLFORM_NAMELENGTH, (long)string_key_len - 1, CURLFORM_FILE, postval, CURLFORM_END); } else { error = curl_formadd(&first, &last, CURLFORM_COPYNAME, string_key, CURLFORM_NAMELENGTH, (long)string_key_len - 1, CURLFORM_COPYCONTENTS, postval, CURLFORM_CONTENTSLENGTH, (long)Z_STRLEN_PP(current), CURLFORM_END); } } SAVE_CURL_ERROR(ch, error); if (error != CURLE_OK) { RETURN_FALSE; } zend_llist_add_element(&ch->to_free.post, &first); error = curl_easy_setopt(ch->cp, CURLOPT_HTTPPOST, first); } else { char *post = NULL; convert_to_string_ex(zvalue); post = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue)); zend_llist_add_element(&ch->to_free.str, &post);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -