Пример #1
0
/**
 * Construct an instance of the Channel class. If the $args array contains a
 * "credentials" key mapping to a ChannelCredentials object, a secure channel
 * will be created with those credentials.
 * @param string $target The hostname to associate with this channel
 * @param array $args The arguments to pass to the Channel (optional)
 */
PHP_METHOD(Channel, __construct) {
  wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(getThis());
  zend_string *target;
  zval *args_array = NULL;
  grpc_channel_args args;
  HashTable *array_hash;
  zval *creds_obj = NULL;
  wrapped_grpc_channel_credentials *creds = NULL;

  /* "Sa" == 1 string, 1 array */
#ifndef FAST_ZPP
  if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sa", &target, &args_array)
      == FAILURE) {
    zend_throw_exception(spl_ce_InvalidArgumentException,
                         "Channel expects a string and an array", 1);
    return;
  }
#else
  ZEND_PARSE_PARAMETERS_START(2, 2)
    Z_PARAM_STR(target)
    Z_PARAM_ARRAY(args_array)
  ZEND_PARSE_PARAMETERS_END();
#endif

  array_hash = HASH_OF(args_array);
  if ((creds_obj = zend_hash_str_find(array_hash, "credentials",
                                      sizeof("credentials") - 1)) != NULL) {
    if (Z_TYPE_P(creds_obj) == IS_NULL) {
      creds = NULL;
      zend_hash_str_del(array_hash, "credentials", sizeof("credentials") - 1);
    } else if (Z_OBJ_P(creds_obj)->ce != grpc_ce_channel_credentials) {
      zend_throw_exception(spl_ce_InvalidArgumentException,
                           "credentials must be a ChannelCredentials object",
                           1);
      return;
    } else {
      creds = Z_WRAPPED_GRPC_CHANNEL_CREDS_P(creds_obj);
      zend_hash_str_del(array_hash, "credentials", sizeof("credentials") - 1);
    }
  }
  php_grpc_read_args_array(args_array, &args);
  if (creds == NULL) {
    channel->wrapped = grpc_insecure_channel_create(ZSTR_VAL(target),
                                                    &args, NULL);
  } else {
    channel->wrapped =
        grpc_secure_channel_create(creds->wrapped, ZSTR_VAL(target),
                                   &args, NULL);
  }
  efree(args.args);
}
Пример #2
0
PDO_API void php_pdo_unregister_driver(pdo_driver_t *driver) /* {{{ */
{
	if (!zend_hash_str_exists(&module_registry, "pdo", sizeof("pdo") - 1)) {
		return;
	}

	zend_hash_str_del(&pdo_driver_hash, (char*)driver->driver_name, driver->driver_name_len);
}
Пример #3
0
SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry)
{
	if (SG(sapi_started) && EG(current_execute_data)) {
		return;
	}
	zend_hash_str_del(&SG(known_post_content_types), post_entry->content_type,
			post_entry->content_type_len);
}
Пример #4
0
/* Upgly hack to fix HTTP_PROXY issue, see bug #72573 */
static void check_http_proxy(HashTable *var_table)
{
	if (zend_hash_str_exists(var_table, "HTTP_PROXY", sizeof("HTTP_PROXY")-1)) {
		char *local_proxy = getenv("HTTP_PROXY");

		if (!local_proxy) {
			zend_hash_str_del(var_table, "HTTP_PROXY", sizeof("HTTP_PROXY")-1);
		} else {
			zval local_zval;
			ZVAL_STRING(&local_zval, local_proxy);
			zend_hash_str_update(var_table, "HTTP_PROXY", sizeof("HTTP_PROXY")-1, &local_zval);
		}
	}
}
Пример #5
0
static void
on_broken_connection_detected(php_yrmcds_t* conn, yrmcds_error err,
                              yrmcds_status status) {
    if( err != YRMCDS_OK )
        PRINT_YRMCDS_ERROR(err);
    if( status != YRMCDS_STATUS_OK && status != YRMCDS_STATUS_UNKNOWNCOMMAND ) {
        char buf[256];
        snprintf(buf, sizeof(buf), "yrmcds: unexpected response (%d)", status);
        php_log_err(buf);
    }
    php_log_err("yrmcds: broken persistent connection");
    if( conn->reference_count == 0 ) {
        // Since `conn` is the last user of this persistent connection,
        // we should clean up resources.
        zend_hash_str_del(&EG(persistent_list), conn->pkey, conn->pkey_len);
    }
}
Пример #6
0
static int timecop_class_override_clear()
{
	const struct timecop_override_class_entry *p;
	zend_class_entry *ce_orig;
	zend_function *zf_orig, *zf_ovrd, *zf_save;

	p = &(timecop_override_class_table[0]);
	while (p->orig_class != NULL) {
		ce_orig = zend_hash_str_find_ptr(EG(class_table),
										 p->orig_class, strlen(p->orig_class));
		if (ce_orig == NULL) {
			php_error_docref("https://github.com/hnw/php-timecop", E_WARNING,
							 "timecop couldn't find class %s.", p->orig_class);
			p++;
			continue;
		}

		zf_orig = zend_hash_str_find_ptr(&ce_orig->function_table,
										 p->save_method, strlen(p->save_method));
		if (zf_orig == NULL) {
			php_error_docref("https://github.com/hnw/php-timecop", E_WARNING,
							 "timecop couldn't find method %s::%s.",
							 p->orig_class, p->save_method);
			p++;
			continue;
		}

		zend_hash_str_update_mem(&ce_orig->function_table, p->orig_method, strlen(p->orig_method),
								 zf_orig, sizeof(zend_internal_function));
		function_add_ref(zf_orig);

		zend_hash_str_del(&ce_orig->function_table, p->save_method, strlen(p->save_method));

		if (strcmp(p->orig_method, "__construct") == 0) {
			ce_orig->constructor = zf_orig;
		}
		p++;
	}
	return SUCCESS;
}
Пример #7
0
/*  clear overrideed function. */
static int timecop_func_override_clear()
{
	const struct timecop_override_func_entry *p;
	zend_function *zf_orig;

	p = &(timecop_override_func_table[0]);
	while (p->orig_func != NULL) {
		zf_orig = zend_hash_str_find_ptr(EG(function_table),
										 p->save_func, strlen(p->save_func));
		if (zf_orig == NULL) {
			p++;
			continue;
		}

		zend_hash_str_update_mem(EG(function_table), p->orig_func, strlen(p->orig_func),
								 zf_orig, sizeof(zend_internal_function));
		function_add_ref(zf_orig);

		zend_hash_str_del(EG(function_table), p->save_func, strlen(p->save_func));

		p++;
	}
	return SUCCESS;
}
Пример #8
0
/* {{{ mysqlnd_vio::open_tcp_or_unix */
static php_stream *
MYSQLND_METHOD(mysqlnd_vio, open_tcp_or_unix)(MYSQLND_VIO * const vio, const MYSQLND_CSTRING scheme, const zend_bool persistent,
											  MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info)
{
#if PHP_API_VERSION < 20100412
	unsigned int streams_options = ENFORCE_SAFE_MODE;
#else
	unsigned int streams_options = 0;
#endif
	unsigned int streams_flags = STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT;
	char * hashed_details = NULL;
	int hashed_details_len = 0;
	zend_string *errstr = NULL;
	int errcode = 0;
	struct timeval tv;
	dtor_func_t origin_dtor;
	php_stream * net_stream = NULL;

	DBG_ENTER("mysqlnd_vio::open_tcp_or_unix");

	vio->data->stream = NULL;

	if (persistent) {
		hashed_details_len = mnd_sprintf(&hashed_details, 0, "%p", vio);
		DBG_INF_FMT("hashed_details=%s", hashed_details);
	}

	if (vio->data->options.timeout_connect) {
		tv.tv_sec = vio->data->options.timeout_connect;
		tv.tv_usec = 0;
	}

	DBG_INF_FMT("calling php_stream_xport_create");
	net_stream = php_stream_xport_create(scheme.s, scheme.l, streams_options, streams_flags,
										  hashed_details, (vio->data->options.timeout_connect) ? &tv : NULL,
										  NULL /*ctx*/, &errstr, &errcode);
	if (errstr || !net_stream) {
		DBG_ERR("Error");
		if (hashed_details) {
			mnd_sprintf_free(hashed_details);
		}
		errcode = CR_CONNECTION_ERROR;
		SET_CLIENT_ERROR(error_info,
						 CR_CONNECTION_ERROR,
						 UNKNOWN_SQLSTATE,
						 errstr? ZSTR_VAL(errstr):"Unknown error while connecting");
		if (errstr) {
			zend_string_release(errstr);
		}
		DBG_RETURN(NULL);
	}
	if (hashed_details) {
		/*
		  If persistent, the streams register it in EG(persistent_list).
		  This is unwanted. ext/mysql or ext/mysqli are responsible to clean,
		  whatever they have to.
		*/
		zend_resource *le;

		if ((le = zend_hash_str_find_ptr(&EG(persistent_list), hashed_details, hashed_details_len))) {
			origin_dtor = EG(persistent_list).pDestructor;
			/*
			  in_free will let streams code skip destructing - big HACK,
			  but STREAMS suck big time regarding persistent streams.
			  Just not compatible for extensions that need persistency.
			*/
			EG(persistent_list).pDestructor = NULL;
			zend_hash_str_del(&EG(persistent_list), hashed_details, hashed_details_len);
			EG(persistent_list).pDestructor = origin_dtor;
			pefree(le, 1);
		}
#if ZEND_DEBUG
		/* Shut-up the streams, they don't know what they are doing */
		net_stream->__exposed = 1;
#endif
		mnd_sprintf_free(hashed_details);
	}

	/*
	  Streams are not meant for C extensions! Thus we need a hack. Every connected stream will
	  be registered as resource (in EG(regular_list). So far, so good. However, it won't be
	  unregistered until the script ends. So, we need to take care of that.
	*/
	origin_dtor = EG(regular_list).pDestructor;
	EG(regular_list).pDestructor = NULL;
	zend_hash_index_del(&EG(regular_list), net_stream->res->handle); /* ToDO: should it be res->handle, do streams register with addref ?*/
	efree(net_stream->res);
	net_stream->res = NULL;
	EG(regular_list).pDestructor = origin_dtor;
	DBG_RETURN(net_stream);
}
php_http_message_parser_state_t php_http_message_parser_parse(php_http_message_parser_t *parser, php_http_buffer_t *buffer, unsigned flags, php_http_message_t **message)
{
	char *str = NULL;
	size_t len = 0;
	size_t cut = 0;

	while (buffer->used || !php_http_message_parser_states[php_http_message_parser_state_is(parser)].need_data) {
#if DBG_PARSER
		fprintf(stderr, "#MP: %s (f: %u, t:%d, l:%zu)\n", 
			php_http_message_parser_state_name(php_http_message_parser_state_is(parser)),
			flags, 
			message && *message ? (*message)->type : -1, 
			buffer->used
		);
		_dpf(0, buffer->data, buffer->used);
#endif

		switch (php_http_message_parser_state_pop(parser))
		{
			case PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE:
				return php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE);

			case PHP_HTTP_MESSAGE_PARSER_STATE_START:
			{
				char *ptr = buffer->data;

				while (ptr - buffer->data < buffer->used && PHP_HTTP_IS_CTYPE(space, *ptr)) {
					++ptr;
				}

				php_http_buffer_cut(buffer, 0, ptr - buffer->data);

				if (buffer->used) {
					php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_HEADER);
				}
				break;
			}

			case PHP_HTTP_MESSAGE_PARSER_STATE_HEADER:
			{
				unsigned header_parser_flags = (flags & PHP_HTTP_MESSAGE_PARSER_CLEANUP) ? PHP_HTTP_HEADER_PARSER_CLEANUP : 0;

				switch (php_http_header_parser_parse(&parser->header, buffer, header_parser_flags, *message ? &(*message)->hdrs : NULL, (php_http_info_callback_t) php_http_message_info_callback, message)) {
					case PHP_HTTP_HEADER_PARSER_STATE_FAILURE:
						return PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE;

					case PHP_HTTP_HEADER_PARSER_STATE_DONE:
						php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_HEADER_DONE);
						break;

					default:
						if (buffer->used || !(flags & PHP_HTTP_MESSAGE_PARSER_CLEANUP)) {
							return php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_HEADER);
						} else {
							php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_HEADER_DONE);
						}
				}
				break;
			}

			case PHP_HTTP_MESSAGE_PARSER_STATE_HEADER_DONE:
			{
				zval h, *h_ptr, *h_loc = NULL, *h_con = NULL, *h_ce;
				zend_bool chunked = 0;
				zend_long content_length = -1;
				zend_string *content_range = NULL;

				/* Content-Range has higher precedence than Content-Length,
				 * and content-length denotes the original length of the entity,
				 * so let's *NOT* remove CR/CL, because that would fundamentally
				 * change the meaning of the whole message
				 */
				if ((h_ptr = php_http_message_header(*message, ZEND_STRL("Transfer-Encoding")))) {
					zend_string *zs = zval_get_string(h_ptr);

					chunked = zend_string_equals_literal(zs, "chunked");
					zend_string_release(zs);

					Z_TRY_ADDREF_P(h_ptr);
					zend_hash_str_update(&(*message)->hdrs, "X-Original-Transfer-Encoding", lenof("X-Original-Transfer-Encoding"), h_ptr);
					zend_hash_str_del(&(*message)->hdrs, "Transfer-Encoding", lenof("Transfer-Encoding"));

					/* reset */
					ZVAL_LONG(&h, 0);
					zend_hash_str_update(&(*message)->hdrs, "Content-Length", lenof("Content-Length"), &h);
				} else if ((h_ptr = php_http_message_header(*message, ZEND_STRL("Content-Length")))) {
					content_length = zval_get_long(h_ptr);
					Z_TRY_ADDREF_P(h_ptr);
					zend_hash_str_update(&(*message)->hdrs, "X-Original-Content-Length", lenof("X-Original-Content-Length"), h_ptr);
				}

				if ((content_range = php_http_message_header_string(*message, ZEND_STRL("Content-Range")))) {
					ZVAL_STR_COPY(&h, content_range);
					zend_hash_str_update(&(*message)->hdrs, "Content-Range", lenof("Content-Range"), &h);
				}

				/* so, if curl sees a 3xx code, a Location header and a Connection:close header
				 * it decides not to read the response body.
				 */
				if ((flags & PHP_HTTP_MESSAGE_PARSER_EMPTY_REDIRECTS)
				&&	(*message)->type == PHP_HTTP_RESPONSE
				&&	(*message)->http.info.response.code/100 == 3
				&&	(h_loc = php_http_message_header(*message, ZEND_STRL("Location")))
				&&	(h_con = php_http_message_header(*message, ZEND_STRL("Connection")))
				) {
					zend_string *con = zval_get_string(h_con);

					if (php_http_match(con->val, "close", PHP_HTTP_MATCH_WORD)) {
						zend_string_release(con);
						php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_DONE);
						break;
					}
					zend_string_release(con);
				}

				if ((h_ce = php_http_message_header(*message, ZEND_STRL("Content-Encoding")))) {
					zend_string *ce = zval_get_string(h_ce);

					if (php_http_match(ce->val, "gzip", PHP_HTTP_MATCH_WORD)
					||	php_http_match(ce->val, "x-gzip", PHP_HTTP_MATCH_WORD)
					||	php_http_match(ce->val, "deflate", PHP_HTTP_MATCH_WORD)
					) {
						if (parser->inflate) {
							php_http_encoding_stream_reset(&parser->inflate);
						} else {
							parser->inflate = php_http_encoding_stream_init(NULL, php_http_encoding_stream_get_inflate_ops(), 0);
						}
						Z_TRY_ADDREF_P(h_ce);
						zend_hash_str_update(&(*message)->hdrs, "X-Original-Content-Encoding", lenof("X-Original-Content-Encoding"), h_ce);
						zend_hash_str_del(&(*message)->hdrs, "Content-Encoding", lenof("Content-Encoding"));
					}
					zend_string_release(ce);
				}

				if ((flags & PHP_HTTP_MESSAGE_PARSER_DUMB_BODIES)) {
					php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DUMB);
				} else {
					if (chunked) {
						parser->dechunk = php_http_encoding_stream_init(parser->dechunk, php_http_encoding_stream_get_dechunk_ops(), 0);
						php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_CHUNKED);
						break;
					}

					if (content_range) {
						ulong total = 0, start = 0, end = 0;

						if (!strncasecmp(content_range->val, "bytes", lenof("bytes"))
						&& (	content_range->val[lenof("bytes")] == ':'
							||	content_range->val[lenof("bytes")] == ' '
							||	content_range->val[lenof("bytes")] == '='
							)
						) {
							char *total_at = NULL, *end_at = NULL;
							char *start_at = content_range->val + sizeof("bytes");

							start = strtoul(start_at, &end_at, 10);
							if (end_at) {
								end = strtoul(end_at + 1, &total_at, 10);
								if (total_at && strncmp(total_at + 1, "*", 1)) {
									total = strtoul(total_at + 1, NULL, 10);
								}

								if (end >= start && (!total || end <= total)) {
									parser->body_length = end + 1 - start;
									php_http_message_parser_state_push(parser, 1, !parser->body_length?PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE:PHP_HTTP_MESSAGE_PARSER_STATE_BODY_LENGTH);
									zend_string_release(content_range);
									break;
								}
							}
						}

						zend_string_release(content_range);
					}

					if (content_length >= 0) {
						parser->body_length = content_length;
						php_http_message_parser_state_push(parser, 1, !parser->body_length?PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE:PHP_HTTP_MESSAGE_PARSER_STATE_BODY_LENGTH);
						break;
					}

					if ((*message)->type == PHP_HTTP_REQUEST) {
						php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_DONE);
					} else {
						php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DUMB);
					}
				}
				break;
			}

			case PHP_HTTP_MESSAGE_PARSER_STATE_BODY:
			{
				if (len) {
					if (parser->inflate) {
						char *dec_str = NULL;
						size_t dec_len;

						if (SUCCESS != php_http_encoding_stream_update(parser->inflate, str, len, &dec_str, &dec_len)) {
							return php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE);
						}

						if (str != buffer->data) {
							PTR_FREE(str);
						}
						str = dec_str;
						len = dec_len;
					}

					php_stream_write(php_http_message_body_stream((*message)->body), str, len);
				}

				if (cut) {
					php_http_buffer_cut(buffer, 0, cut);
				}

				if (str != buffer->data) {
					PTR_FREE(str);
				}

				str = NULL;
				len = 0;
				cut = 0;
				break;
			}

			case PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DUMB:
			{
				str = buffer->data;
				len = buffer->used;
				cut = len;

				php_http_message_parser_state_push(parser, 2, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE, PHP_HTTP_MESSAGE_PARSER_STATE_BODY);
				break;
			}

			case PHP_HTTP_MESSAGE_PARSER_STATE_BODY_LENGTH:
			{
				len = MIN(parser->body_length, buffer->used);
				str = buffer->data;
				cut = len;

				parser->body_length -= len;

				php_http_message_parser_state_push(parser, 2, !parser->body_length?PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE:PHP_HTTP_MESSAGE_PARSER_STATE_BODY_LENGTH, PHP_HTTP_MESSAGE_PARSER_STATE_BODY);
				break;
			}

			case PHP_HTTP_MESSAGE_PARSER_STATE_BODY_CHUNKED:
			{
				/*
				 * - pass available data through the dechunk stream
				 * - pass decoded data along
				 * - if stream zeroed:
				 * 	Y:	- cut processed string out of buffer, but leave length of unprocessed dechunk stream data untouched
				 * 		- body done
				 * 	N:	- parse ahaed
				 */
				char *dec_str = NULL;
				size_t dec_len;

				if (SUCCESS != php_http_encoding_stream_update(parser->dechunk, buffer->data, buffer->used, &dec_str, &dec_len)) {
					return PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE;
				}

				str = dec_str;
				len = dec_len;

				if (php_http_encoding_stream_done(parser->dechunk)) {
					cut = buffer->used - PHP_HTTP_BUFFER(parser->dechunk->ctx)->used;
					php_http_message_parser_state_push(parser, 2, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE, PHP_HTTP_MESSAGE_PARSER_STATE_BODY);
				} else {
					cut = buffer->used;
					php_http_message_parser_state_push(parser, 2, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_CHUNKED, PHP_HTTP_MESSAGE_PARSER_STATE_BODY);
				}
				break;
			}

			case PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE:
			{
				php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_DONE);

				if (parser->dechunk && parser->dechunk->ctx) {
					char *dec_str = NULL;
					size_t dec_len;

					if (SUCCESS != php_http_encoding_stream_finish(parser->dechunk, &dec_str, &dec_len)) {
						return php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE);
					}
					php_http_encoding_stream_dtor(parser->dechunk);

					if (dec_str && dec_len) {
						str = dec_str;
						len = dec_len;
						cut = 0;
						php_http_message_parser_state_push(parser, 2, PHP_HTTP_MESSAGE_PARSER_STATE_UPDATE_CL, PHP_HTTP_MESSAGE_PARSER_STATE_BODY);
					}
				}

				break;
			}

			case PHP_HTTP_MESSAGE_PARSER_STATE_UPDATE_CL:
			{
				zval zcl;

				ZVAL_LONG(&zcl, php_http_message_body_size((*message)->body));
				zend_hash_str_update(&(*message)->hdrs, "Content-Length", lenof("Content-Length"), &zcl);
				break;
			}

			case PHP_HTTP_MESSAGE_PARSER_STATE_DONE:
			{
				char *ptr = buffer->data;

				while (ptr - buffer->data < buffer->used && PHP_HTTP_IS_CTYPE(space, *ptr)) {
					++ptr;
				}

				php_http_buffer_cut(buffer, 0, ptr - buffer->data);
				
				if (!(flags & PHP_HTTP_MESSAGE_PARSER_GREEDY)) {
					return PHP_HTTP_MESSAGE_PARSER_STATE_DONE;
				}
				break;
			}
		}
	}

	return php_http_message_parser_state_is(parser);
}
Пример #10
0
PHPAPI int php_stream_xport_unregister(const char *protocol)
{
	return zend_hash_str_del(&xport_hash, protocol, strlen(protocol));
}
Пример #11
0
PHPAPI int php_stream_filter_unregister_factory(const char *filterpattern)
{
	return zend_hash_str_del(&stream_filters_hash, filterpattern, strlen(filterpattern));
}