Skip to content

Commit 687e42d

Browse files
authored
Merge pull request #925 from newrelic/dev
Release 10.22
2 parents ddc5230 + 5154931 commit 687e42d

21 files changed

+361
-264
lines changed

VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
10.21.0
1+
10.22.0

agent/fw_drupal.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,9 @@ NR_PHP_WRAPPER(nr_drupal_http_request_before) {
265265
* fcall_end is able to properly dispatch to the after wrapper, as
266266
* this new segment is now at the top of the segment stack.
267267
*/
268-
NRPRG(drupal_http_request_segment)->wraprec = auto_segment->wraprec;
268+
if (NULL != NRPRG(drupal_http_request_segment)) {
269+
NRPRG(drupal_http_request_segment)->wraprec = auto_segment->wraprec;
270+
}
269271
}
270272
}
271273
NR_PHP_WRAPPER_END

agent/fw_slim.c

+68-9
Original file line numberDiff line numberDiff line change
@@ -81,28 +81,65 @@ NR_PHP_WRAPPER(nr_slim2_route_dispatch) {
8181
NR_PHP_WRAPPER_END
8282

8383
/*
84-
* Wrap the \Slim\Route::run method, which is the happy path for Slim routing.
84+
* Wrap the Slim 3\Slim\Route::run method
85+
* and
86+
* Slim 4 Slim\\Routing\\Route::run
87+
* which are the happy paths for Slim 3/4 routing.
8588
* i.e. The router has succesfully matched the URL and dispatched the request
8689
* to a route.
8790
*
88-
* In this case, `nr_txn_set_path` is called after `NR_PHP_WRAPPER_CALL` with
89-
* `NR_OK_TO_OVERWRITE` and as this corresponds to calling the wrapped function
90-
* in func_end no change is needed to ensure OAPI compatibility as it will use
91-
* the default func_end after callback. This entails that the first wrapped
92-
* function call of this type gets to name the txn.
91+
* In this case, `nr_txn_set_path` is called before `NR_PHP_WRAPPER_CALL` with
92+
* `NR_OK_TO_OVERWRITE` and as this corresponds to calling the last wrapped
93+
* function call of this type gets to name the txn; therefore needs a before
94+
* call for OAPI.
9395
*/
9496
NR_PHP_WRAPPER(nr_slim3_4_route_run) {
9597
zval* this_var = NULL;
9698
char* txn_name = NULL;
9799

98100
(void)wraprec;
101+
99102
NR_PHP_WRAPPER_REQUIRE_FRAMEWORK(NR_FW_SLIM);
100103

101104
this_var = nr_php_scope_get(NR_EXECUTE_ORIG_ARGS TSRMLS_CC);
102105
txn_name = nr_slim_path_from_route(this_var TSRMLS_CC);
103106
nr_php_scope_release(&this_var);
104107

108+
if (txn_name) {
109+
nr_txn_set_path("Slim", NRPRG(txn), txn_name, NR_PATH_TYPE_ACTION,
110+
NR_OK_TO_OVERWRITE);
111+
nr_free(txn_name);
112+
}
113+
105114
NR_PHP_WRAPPER_CALL;
115+
}
116+
NR_PHP_WRAPPER_END
117+
118+
/*
119+
* public function dispatch(string $method, string $uri): RoutingResults
120+
* This is fallback naming mechanism for Slim 4 routing when the Slim 4
121+
* Slim\\Routing\\Route::run does not run due middlware intervening on
122+
* certain errors.
123+
* In this case, `nr_txn_set_path` is called before `NR_PHP_WRAPPER_CALL` with
124+
* `NR_NOT_OK_TO_OVERWRITE` and as this corresponds to calling the first wrapped
125+
* function in func_begin.
126+
*/
127+
NR_PHP_WRAPPER(nr_slim4_route_dispatch) {
128+
char* txn_name = NULL;
129+
zval* route_name = NULL;
130+
131+
(void)wraprec;
132+
133+
NR_PHP_WRAPPER_REQUIRE_FRAMEWORK(NR_FW_SLIM);
134+
135+
/* Get the route name. The first arg is the method, 2nd arg is routename. */
136+
route_name = nr_php_arg_get(2, NR_EXECUTE_ORIG_ARGS);
137+
138+
if (nr_php_is_zval_valid_string(route_name)) {
139+
txn_name = nr_strndup(Z_STRVAL_P(route_name), Z_STRLEN_P(route_name));
140+
}
141+
142+
nr_php_arg_release(&route_name);
106143

107144
if (txn_name) {
108145
nr_txn_set_path("Slim", NRPRG(txn), txn_name, NR_PATH_TYPE_ACTION,
@@ -120,7 +157,7 @@ NR_PHP_WRAPPER(nr_slim_application_construct) {
120157
(void)wraprec;
121158

122159
version = nr_php_get_object_constant(this_var, "VERSION");
123-
160+
124161
if (NRINI(vulnerability_management_package_detection_enabled)) {
125162
// Add php package to transaction
126163
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME, version);
@@ -139,12 +176,34 @@ void nr_slim_enable(TSRMLS_D) {
139176

140177
nr_php_wrap_user_function(NR_PSTR("Slim\\Route::dispatch"),
141178
nr_slim2_route_dispatch TSRMLS_CC);
179+
180+
#if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO \
181+
&& !defined OVERWRITE_ZEND_EXECUTE_DATA
182+
142183
/* Slim 3 */
143-
nr_php_wrap_user_function(NR_PSTR("Slim\\Route::run"),
144-
nr_slim3_4_route_run TSRMLS_CC);
184+
nr_php_wrap_user_function_before_after_clean(
185+
NR_PSTR("Slim\\Route::run"), nr_slim3_4_route_run, NULL, NULL);
186+
145187
/* Slim 4 */
188+
nr_php_wrap_user_function_before_after_clean(
189+
NR_PSTR("Slim\\Routing\\Route::run"), nr_slim3_4_route_run, NULL, NULL);
190+
191+
/* Slim 4 */
192+
nr_php_wrap_user_function_before_after_clean(
193+
NR_PSTR("Slim\\Routing\\Dispatcher::dispatch"), nr_slim4_route_dispatch,
194+
NULL, NULL);
195+
#else
196+
/* Slim 4*/
146197
nr_php_wrap_user_function(NR_PSTR("Slim\\Routing\\Route::run"),
147198
nr_slim3_4_route_run TSRMLS_CC);
199+
/* Slim 4 */
200+
nr_php_wrap_user_function(NR_PSTR("Slim\\Routing\\Dispatcher::dispatch"),
201+
nr_slim4_route_dispatch TSRMLS_CC);
202+
203+
/* Slim 3 */
204+
nr_php_wrap_user_function(NR_PSTR("Slim\\Route::run"),
205+
nr_slim3_4_route_run TSRMLS_CC);
206+
#endif
148207

149208
/* Slim 2 does not have the same path as Slim 3/4 which is why
150209
we need to separate these*/

agent/lib_guzzle6.c

+9-3
Original file line numberDiff line numberDiff line change
@@ -352,14 +352,20 @@ NR_PHP_WRAPPER_START(nr_guzzle6_client_construct) {
352352
zval* this_var = nr_php_scope_get(NR_EXECUTE_ORIG_ARGS);
353353

354354
char* version = nr_php_get_object_constant(this_var, "VERSION");
355-
if (NULL == version) {
356-
version = nr_php_get_object_constant(this_var, "MAJOR_VERSION");
357-
}
358355

359356
if (NRINI(vulnerability_management_package_detection_enabled)) {
360357
// Add php package to transaction
361358
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME, version);
362359
}
360+
361+
/*
362+
* If we were unable to get the full version before, at least we can extract
363+
* the major version to send to the supportability metric.
364+
* This is relevant to guzzle7+ which no longer supplies full version.
365+
*/
366+
if (NULL == version) {
367+
version = nr_php_get_object_constant(this_var, "MAJOR_VERSION");
368+
}
363369
nr_fw_support_add_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
364370
version);
365371
nr_free(version);

agent/lib_mongodb.c

+172-1
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ void nr_mongodb_get_host_and_port_path_or_id(zval* server,
108108
}
109109
}
110110

111+
#if ZEND_MODULE_API_NO < ZEND_8_0_X_API_NO \
112+
|| defined OVERWRITE_ZEND_EXECUTE_DATA
111113
NR_PHP_WRAPPER(nr_mongodb_operation) {
112114
const char* this_klass = "MongoDB\\Operation\\Executable";
113115
zval* collection = NULL;
@@ -173,7 +175,174 @@ NR_PHP_WRAPPER(nr_mongodb_operation) {
173175
}
174176
NR_PHP_WRAPPER_END
175177

176-
void nr_mongodb_enable(TSRMLS_D) {
178+
#else
179+
180+
NR_PHP_WRAPPER(nr_mongodb_operation_before) {
181+
(void)wraprec;
182+
nr_segment_t* segment = NULL;
183+
segment = nr_segment_start(NRPRG(txn), NULL, NULL);
184+
if (NULL != segment) {
185+
segment->wraprec = auto_segment->wraprec;
186+
}
187+
}
188+
NR_PHP_WRAPPER_END
189+
190+
NR_PHP_WRAPPER(nr_mongodb_operation_after) {
191+
const char* this_klass = "MongoDB\\Operation\\Executable";
192+
zval* collection = NULL;
193+
zval* database = NULL;
194+
zval* server = NULL;
195+
zval* this_var = NULL;
196+
bool discard_segment = false;
197+
nr_datastore_instance_t instance = {
198+
.host = NULL,
199+
.port_path_or_id = NULL,
200+
.database_name = NULL,
201+
};
202+
203+
// tell the compiler to ignore the cast from const char * to char *
204+
// to save having to do a strdup operation
205+
#pragma GCC diagnostic push
206+
#pragma GCC diagnostic ignored "-Wcast-qual"
207+
nr_segment_datastore_params_t params = {
208+
.collection = NULL,
209+
.datastore = {
210+
.type = NR_DATASTORE_MONGODB,
211+
},
212+
.operation = (char *)wraprec->extra,
213+
.instance = &instance,
214+
.callbacks = {
215+
.backtrace = nr_php_backtrace_callback,
216+
},
217+
};
218+
#pragma GCC diagnostic pop
219+
/*
220+
* We check for the interface all Collection operations extend, rather than
221+
* their specific class. Not all operations have the properties we need but
222+
* the ones we hook do (as of mongo-php-library v.1.1).
223+
*/
224+
this_var = nr_php_scope_get(NR_EXECUTE_ORIG_ARGS);
225+
if (!nr_php_object_instanceof_class(this_var, this_klass)) {
226+
nrl_verbosedebug(NRL_FRAMEWORK, "%s: operation is not %s", __func__,
227+
this_klass);
228+
discard_segment = true;
229+
goto leave;
230+
}
231+
232+
collection = nr_php_get_zval_object_property(this_var, "collectionName");
233+
if (nr_php_is_zval_valid_string(collection)) {
234+
params.collection = Z_STRVAL_P(collection);
235+
}
236+
237+
database = nr_php_get_zval_object_property(this_var, "databaseName");
238+
if (nr_php_is_zval_valid_string(database)) {
239+
instance.database_name = Z_STRVAL_P(database);
240+
}
241+
242+
server = nr_php_arg_get(1, NR_EXECUTE_ORIG_ARGS);
243+
nr_mongodb_get_host_and_port_path_or_id(server, &instance.host,
244+
&instance.port_path_or_id);
245+
246+
leave:
247+
if (discard_segment) {
248+
nr_segment_discard(&auto_segment);
249+
} else {
250+
nr_segment_datastore_end(&auto_segment, &params);
251+
}
252+
nr_php_arg_release(&server);
253+
nr_php_scope_release(&this_var);
254+
nr_free(instance.host);
255+
nr_free(instance.port_path_or_id);
256+
}
257+
NR_PHP_WRAPPER_END
258+
259+
#endif /* OAPI */
260+
261+
void nr_mongodb_enable() {
262+
#if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO \
263+
&& !defined OVERWRITE_ZEND_EXECUTE_DATA
264+
265+
nr_php_wrap_user_function_before_after_clean_extra(
266+
NR_PSTR("MongoDB\\Operation\\Aggregate::execute"),
267+
nr_mongodb_operation_before, nr_mongodb_operation_after,
268+
nr_mongodb_operation_after, "aggregate");
269+
270+
nr_php_wrap_user_function_before_after_clean_extra(
271+
NR_PSTR("MongoDB\\Operation\\BulkWrite::execute"),
272+
nr_mongodb_operation_before, nr_mongodb_operation_after,
273+
nr_mongodb_operation_after, "bulkWrite");
274+
275+
nr_php_wrap_user_function_before_after_clean_extra(
276+
NR_PSTR("MongoDB\\Operation\\Count::execute"),
277+
nr_mongodb_operation_before, nr_mongodb_operation_after,
278+
nr_mongodb_operation_after, "count");
279+
280+
nr_php_wrap_user_function_before_after_clean_extra(
281+
NR_PSTR("MongoDB\\Operation\\CountDocuments::execute"),
282+
nr_mongodb_operation_before, nr_mongodb_operation_after,
283+
nr_mongodb_operation_after, "countDocuments");
284+
285+
nr_php_wrap_user_function_before_after_clean_extra(
286+
NR_PSTR("MongoDB\\Operation\\CreateIndexes::execute"),
287+
nr_mongodb_operation_before, nr_mongodb_operation_after,
288+
nr_mongodb_operation_after, "createIndexes");
289+
290+
nr_php_wrap_user_function_before_after_clean_extra(
291+
NR_PSTR("MongoDB\\Operation\\Delete::execute"),
292+
nr_mongodb_operation_before, nr_mongodb_operation_after,
293+
nr_mongodb_operation_after, "delete");
294+
295+
nr_php_wrap_user_function_before_after_clean_extra(
296+
NR_PSTR("MongoDB\\Operation\\Distinct::execute"),
297+
nr_mongodb_operation_before, nr_mongodb_operation_after,
298+
nr_mongodb_operation_after, "distinct");
299+
300+
nr_php_wrap_user_function_before_after_clean_extra(
301+
NR_PSTR("MongoDB\\Operation\\DropCollection::execute"),
302+
nr_mongodb_operation_before, nr_mongodb_operation_after,
303+
nr_mongodb_operation_after, "dropCollection");
304+
305+
nr_php_wrap_user_function_before_after_clean_extra(
306+
NR_PSTR("MongoDB\\Operation\\DropIndexes::execute"),
307+
nr_mongodb_operation_before, nr_mongodb_operation_after,
308+
nr_mongodb_operation_after, "dropIndexes");
309+
310+
nr_php_wrap_user_function_before_after_clean_extra(
311+
NR_PSTR("MongoDB\\Operation\\Find::execute"), nr_mongodb_operation_before,
312+
nr_mongodb_operation_after, nr_mongodb_operation_after, "find");
313+
314+
nr_php_wrap_user_function_before_after_clean_extra(
315+
NR_PSTR("MongoDB\\Operation\\FindAndModify::execute"),
316+
nr_mongodb_operation_before, nr_mongodb_operation_after,
317+
nr_mongodb_operation_after, "findAndModify");
318+
319+
nr_php_wrap_user_function_before_after_clean_extra(
320+
NR_PSTR("MongoDB\\Operation\\InsertMany::execute"),
321+
nr_mongodb_operation_before, nr_mongodb_operation_after,
322+
nr_mongodb_operation_after, "insertMany");
323+
324+
nr_php_wrap_user_function_before_after_clean_extra(
325+
NR_PSTR("MongoDB\\Operation\\InsertOne::execute"),
326+
nr_mongodb_operation_before, nr_mongodb_operation_after,
327+
nr_mongodb_operation_after, "insertOne");
328+
329+
nr_php_wrap_user_function_before_after_clean_extra(
330+
NR_PSTR("MongoDB\\Operation\\ListIndexes::execute"),
331+
nr_mongodb_operation_before, nr_mongodb_operation_after,
332+
nr_mongodb_operation_after, "listIndexes");
333+
334+
nr_php_wrap_user_function_before_after_clean_extra(
335+
NR_PSTR("MongoDB\\Operation\\Update::execute"),
336+
nr_mongodb_operation_before, nr_mongodb_operation_after,
337+
nr_mongodb_operation_after, "update");
338+
339+
nr_php_wrap_user_function_before_after_clean_extra(
340+
NR_PSTR("MongoDB\\Operation\\DatabaseCommand::execute"),
341+
nr_mongodb_operation_before, nr_mongodb_operation_after,
342+
nr_mongodb_operation_after, "databaseCommand");
343+
344+
#else /* Non-OAPI */
345+
177346
/*
178347
* We instrument interesting methods on the MongoDB\Collection class via their
179348
* associated MongoDB\Operation classes.
@@ -265,6 +434,8 @@ void nr_mongodb_enable(TSRMLS_D) {
265434
NR_PSTR("MongoDB\\Operation\\DatabaseCommand::execute"),
266435
nr_mongodb_operation, "databaseCommand" TSRMLS_CC);
267436

437+
#endif /* OAPI */
438+
268439
if (NRINI(vulnerability_management_package_detection_enabled)) {
269440
nr_txn_add_php_package(NRPRG(txn), "mongodb/mongodb",
270441
PHP_PACKAGE_VERSION_UNKNOWN);

agent/lib_predis.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,9 @@ NR_PHP_WRAPPER(nr_predis_webdisconnection_executeCommand_before) {
764764

765765
nr_segment_t* segment = NULL;
766766
segment = nr_segment_start(NRPRG(txn), NULL, NULL);
767-
segment->wraprec = auto_segment->wraprec;
767+
if (NULL != segment) {
768+
segment->wraprec = auto_segment->wraprec;
769+
}
768770
}
769771
NR_PHP_WRAPPER_END
770772

@@ -894,5 +896,4 @@ void nr_predis_enable(TSRMLS_D) {
894896
NR_PSTR("Predis\\Connection\\WebdisConnection::executeCommand"),
895897
nr_predis_webdisconnection_executeCommand TSRMLS_CC);
896898
#endif /* OAPI */
897-
898899
}

0 commit comments

Comments
 (0)