Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport NR-234826 #335

Open
wants to merge 9 commits into
base: staging
Choose a base branch
from
87 changes: 87 additions & 0 deletions .github/workflows/branchBuild.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
name: BespokeBuild
on:
workflow_dispatch:
# The input version number (ex: 7.4.0) and branch are required for the bespoke branch build. Branch is an automatically added selector for all github actions.
inputs:
version:
required: true

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
deployS3:
name: DeployS3
# runs-on: will be set to macos-latest when running on actual GHA.
# *** runs-on: ubuntu-latest is used when running via act on mac os. ***
runs-on: macos-latest
outputs:
version: ${{ steps.setOutput.outputs.version }}
steps:
- uses: actions/checkout@v3
with:
submodules: true

- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '15.4'

- name: Install the Apple certificate and provisioning profile
env:
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
# BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
# create variables
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db

# import certificate and provisioning profile from secrets
echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
# echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH

# create temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH

# import certificate to keychain
security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH

# # apply provisioning profile
# mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
# cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles

- name: Update gem
run: bundle update

- name: Install gems
run: bundle install

- name: Build NewRelic.xcframework (using fastlane)
run: bundle exec fastlane buildAndZip

- name: Get name
run: echo "version=$(cat fastlane/build_version)" >> $GITHUB_ENV

- id: setOutput
name: Print name
run: echo "version=${{ env.version }}" >> $GITHUB_OUTPUT

- name: Deploy to staging S3
run: "aws s3 cp NewRelic_XCFramework_Agent_${{ env.version }}.zip s3://nr-downloads-main/ios-v5/"
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }}

- name: Upload build reports
if: failure() && steps.build-step.outcome != 'success'
uses: actions/upload-artifact@v3
with:
name: build-reports
path: /Users/runner/Library/Logs/fastlane/xcbuild/
95 changes: 58 additions & 37 deletions Agent/Instrumentation/NSURLSession/NRMAURLSessionOverride.m
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@

void NRMA__instanceSwizzleIfNotSwizzled(Class clazz, SEL selector, IMP newImplementation);

@interface PayloadHolder : NSObject
@property (nonatomic, retain) NRMAPayloadContainer *cppPayload;
@end

@implementation PayloadHolder
@end

@interface NRMAIMPContainer : NSObject
@property(readonly) IMP imp;
- (instancetype) initWithImp:(IMP)imp;
Expand Down Expand Up @@ -208,13 +215,13 @@ + (void)swizzleURLSessionTask
IMP originalImp = NRMAOriginal__dataTaskWithRequest;

NSMutableURLRequest* mutableRequest = [NRMAHTTPUtilities addCrossProcessIdentifier:request];
NRMAPayloadContainer* payload = [NRMAHTTPUtilities addConnectivityHeader:mutableRequest];

NSURLSessionTask* task = ((id(*)(id,SEL,NSURLRequest*))originalImp)(self,_cmd,request);

objc_setAssociatedObject(task, NRMAHandledRequestKey, @YES, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

NRMAPayloadContainer* payload = [NRMAHTTPUtilities addConnectivityHeader:mutableRequest];
[NRMAHTTPUtilities attachPayload:payload
to:task.originalRequest];

// Try to override the methods of the private class that is returned by this method.
[NRMAURLSessionTaskOverride instrumentConcreteClass:[task class]];

Expand Down Expand Up @@ -243,31 +250,34 @@ + (void)swizzleURLSessionTask
}

NSMutableURLRequest* mutableRequest = [NRMAHTTPUtilities addCrossProcessIdentifier:request];
NRMAPayloadContainer* payload = [NRMAHTTPUtilities addConnectivityHeader:mutableRequest];
__block NSURLSessionTask* task = nil;

if (completionHandler == nil) {
PayloadHolder *payloadHolder = [[PayloadHolder alloc] init];
payloadHolder.cppPayload = ([NRMAHTTPUtilities addConnectivityHeader:mutableRequest]);

NSURLSessionDataTask* task = ((id(*)(id,SEL,NSURLRequest*,void(^)(NSData*,NSURLResponse*,NSError*)))originalImp)(self,_cmd,mutableRequest,completionHandler);
if (completionHandler == nil) {
task = ((id(*)(id,SEL,NSURLRequest*,void(^)(NSData*,NSURLResponse*,NSError*)))originalImp)(self,_cmd,mutableRequest,completionHandler);
objc_setAssociatedObject(task, NRMAHandledRequestKey, @YES, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

[NRMAHTTPUtilities attachPayload:payload
to:task.originalRequest];
[NRMAHTTPUtilities attachPayload:payloadHolder.cppPayload to:task.originalRequest];

[NRMAURLSessionTaskOverride instrumentConcreteClass:[task class]];
return task;
}

__block NSURLSessionTask* task = nil;

task = ((id(*)(id,SEL,NSURLRequest*,void(^)(NSData*,NSURLResponse*,NSError*)))originalImp)(self,_cmd,mutableRequest,^(NSData* data, NSURLResponse* response, NSError* error){

[NRMAHTTPUtilities attachPayload:payload
to:task.originalRequest];
[NRMAHTTPUtilities attachPayload:payloadHolder.cppPayload to:task.originalRequest];

// NSLog(@"NRMA__recordTask called from NRMAOverride__dataTaskWithRequest_completionHandler");

NRMA__recordTask(task,data,response,error);

completionHandler(data,response,error);
});

objc_setAssociatedObject(task, NRMAHandledRequestKey, @YES, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

// Try to override the methods of the private class that is returned by this method.
[NRMAURLSessionTaskOverride instrumentConcreteClass:[task class]];

Expand All @@ -286,7 +296,8 @@ + (void)swizzleURLSessionTask
}

NSURLSessionTask* task = ((id(*)(id,SEL,NSURL*))originalImp)(self,_cmd,url);

objc_setAssociatedObject(task, NRMAHandledRequestKey, @YES, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

// Try to override the methods of the private class that is returned by this method.
[NRMAURLSessionTaskOverride instrumentConcreteClass:[task class]];
return task;
Expand All @@ -306,9 +317,10 @@ + (void)swizzleURLSessionTask
}

NSMutableURLRequest* mutableRequest = [NRMAHTTPUtilities addCrossProcessIdentifier:request];
NRMAPayloadContainer* payload = [NRMAHTTPUtilities addConnectivityHeader:mutableRequest];
NSURLSessionTask* task = ((NSURLSessionTask*(*)(id,SEL,NSURLRequest*,NSURL*))originalImp)(self,_cmd,mutableRequest,fileURL);
objc_setAssociatedObject(task, NRMAHandledRequestKey, @YES, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

NRMAPayloadContainer* payload = [NRMAHTTPUtilities addConnectivityHeader:mutableRequest];
[NRMAHTTPUtilities attachPayload:payload
to:task.originalRequest];

Expand All @@ -329,11 +341,10 @@ + (void)swizzleURLSessionTask
}

NSMutableURLRequest* mutableRequest = [NRMAHTTPUtilities addCrossProcessIdentifier:request];

NRMAPayloadContainer* payload = [NRMAHTTPUtilities addConnectivityHeader:mutableRequest];

NSURLSessionTask* task = ((NSURLSessionTask*(*)(id,SEL,NSURLRequest*,NSData*))originalImp)(self, _cmd, mutableRequest, data);
objc_setAssociatedObject(task, NRMAHandledRequestKey, @YES, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

NRMAPayloadContainer* payload = [NRMAHTTPUtilities addConnectivityHeader:mutableRequest];
[NRMAHTTPUtilities attachPayload:payload to:task.originalRequest];

[NRMAURLSessionTaskOverride instrumentConcreteClass:[task class]];
Expand All @@ -353,7 +364,8 @@ + (void)swizzleURLSessionTask
}

NSURLSessionTask* task = ((NSURLSessionTask*(*)(id,SEL,NSURLRequest*))originalImp)(self, _cmd,request);

objc_setAssociatedObject(task, NRMAHandledRequestKey, @YES, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

[NRMAURLSessionTaskOverride instrumentConcreteClass:[task class]];

return task;
Expand All @@ -370,29 +382,33 @@ + (void)swizzleURLSessionTask
}

NSMutableURLRequest* mutableRequest = [NRMAHTTPUtilities addCrossProcessIdentifier:request];
NRMAPayloadContainer* payload = [NRMAHTTPUtilities addConnectivityHeader:mutableRequest];
__block NSURLSessionUploadTask* task = nil;
PayloadHolder *payloadHolder = [[PayloadHolder alloc] init];

payloadHolder.cppPayload = ([NRMAHTTPUtilities addConnectivityHeader:mutableRequest]);

if (completionHandler == nil) {
NSURLSessionUploadTask* task = ((NSURLSessionUploadTask*(*)(id,SEL,NSURLRequest*,NSURL*,void(^)(NSData*,NSURLResponse*,NSError*)))originalIMP)(self,_cmd,mutableRequest,fileURL,completionHandler);
task = ((NSURLSessionUploadTask*(*)(id,SEL,NSURLRequest*,NSURL*,void(^)(NSData*,NSURLResponse*,NSError*)))originalIMP)(self,_cmd,mutableRequest,fileURL,completionHandler);

[NRMAHTTPUtilities attachPayload:payloadHolder.cppPayload to:task.originalRequest];

[NRMAURLSessionTaskOverride instrumentConcreteClass:[task class]];
[NRMAHTTPUtilities attachPayload:payload
to:task.originalRequest];
return task;
}

__block NSURLSessionUploadTask* task = nil;

task = ((NSURLSessionUploadTask*(*)(id,SEL,NSURLRequest*,NSURL*,void(^)(NSData*,NSURLResponse*,NSError*)))originalIMP)(self,_cmd,mutableRequest,fileURL,^(NSData* data,
NSURLResponse* response,
NSError* error){
[NRMAHTTPUtilities attachPayload:payloadHolder.cppPayload to:task.originalRequest];

[NRMAHTTPUtilities attachPayload:payload
to:task.originalRequest];
// NSLog(@"NRMA__recordTask called from NRMAOverride__uploadTaskWithRequest_fromFile_completionHandler");

NRMA__recordTask(task,data,response,error);

completionHandler(data,response,error);
});

objc_setAssociatedObject(task, NRMAHandledRequestKey, @YES, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

// Try to override the methods of the private class that is returned by this method.
[NRMAURLSessionTaskOverride instrumentConcreteClass:[task class]];
return task;
Expand All @@ -410,28 +426,33 @@ + (void)swizzleURLSessionTask
}

NSMutableURLRequest* mutableRequest = [NRMAHTTPUtilities addCrossProcessIdentifier:request];
NRMAPayloadContainer* payload = [NRMAHTTPUtilities addConnectivityHeader:mutableRequest];
__block NSURLSessionUploadTask* task = nil;

PayloadHolder *payloadHolder = [[PayloadHolder alloc] init];

payloadHolder.cppPayload = ([NRMAHTTPUtilities addConnectivityHeader:mutableRequest]);

if (completionHandler == nil) {
NSURLSessionUploadTask* task = ((NSURLSessionUploadTask*(*)(id,SEL,NSURLRequest*,NSData*,void(^)(NSData*,NSURLResponse*,NSError*)))originalIMP)(self,_cmd,mutableRequest,bodyData,completionHandler);
task = ((NSURLSessionUploadTask*(*)(id,SEL,NSURLRequest*,NSData*,void(^)(NSData*,NSURLResponse*,NSError*)))originalIMP)(self,_cmd,mutableRequest,bodyData,completionHandler);

[NRMAHTTPUtilities attachPayload:payload
to:task.originalRequest];
[NRMAHTTPUtilities attachPayload:payloadHolder.cppPayload to:task.originalRequest];

[NRMAURLSessionTaskOverride instrumentConcreteClass:[task class]];
return task;
}

__block NSURLSessionUploadTask* task = nil;

task = ((NSURLSessionUploadTask*(*)(id,SEL,NSURLRequest*,NSData*,void(^)(NSData*,NSURLResponse*,NSError*)))originalIMP)(self,_cmd,mutableRequest,bodyData,^(NSData* data, NSURLResponse* response, NSError* error){

[NRMAHTTPUtilities attachPayload:payload
to:task.originalRequest];
[NRMAHTTPUtilities attachPayload:payloadHolder.cppPayload to:task.originalRequest];

// NSLog(@"NRMA__recordTask called from NRMAOverride__uploadTaskWithRequest_fromFile_completionHandler");

NRMA__recordTask(task,data,response,error);

completionHandler(data,response,error);
});

objc_setAssociatedObject(task, NRMAHandledRequestKey, @YES, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

// Try to override the methods of the private class that is returned by this method.
[NRMAURLSessionTaskOverride instrumentConcreteClass:[task class]];
return task;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#import <Foundation/Foundation.h>
#import "NRTimer.h"
void NRMAOverride__resume(id self, SEL _cmd);
void NRMAOverride__urlSessionTask_SetState(NSURLSessionTask *sessionTask, SEL _cmd, NSURLSessionTaskState *newState);
void NRMAOverride__urlSessionTask_SetState(NSURLSessionTask *sessionTask, SEL _cmd, NSURLSessionTaskState newState);

@interface NRMAURLSessionTaskOverride : NSObject

Expand Down
50 changes: 35 additions & 15 deletions Agent/Instrumentation/NSURLSession/NRMAURLSessionTaskOverride.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#import "NRMAHTTPUtilities.h"
#import "NRMANetworkFacade.h"
#import "NRMAFlags.h"
#import "NRConstants.h"

static IMP NRMAOriginal__resume;
static IMP NRMAOriginal__urlSessionTask_SetState;
Expand Down Expand Up @@ -85,10 +86,6 @@ + (void) deinstrument
}
}

+ (NSInteger) statusCode:(NSURLResponse*)response {
return [response isKindOfClass:[NSHTTPURLResponse class]] ? [((NSHTTPURLResponse*)response) statusCode] : -1;
}

// Currently we support NSURLSessionDataTask, NSURLSessionDownloadTask, and NSURLSessionUploadTask.
+ (bool) isSupportedTaskType:(NSURLSessionTask*) task {
return [task isKindOfClass:[NSURLSessionDataTask class]] || [task isKindOfClass:[NSURLSessionDownloadTask class]] || [task isKindOfClass:[NSURLSessionUploadTask class]];
Expand All @@ -112,24 +109,47 @@ void NRMAOverride__resume(id self, SEL _cmd)
}

// This is the only way we have right now to record an swift async await web request.
void NRMAOverride__urlSessionTask_SetState(NSURLSessionTask* task, SEL _cmd, NSURLSessionTaskState *newState)
void NRMAOverride__urlSessionTask_SetState(NSURLSessionTask* task, SEL _cmd, NSURLSessionTaskState newState)
{
@synchronized(lock) {
@synchronized(task) {
if ([NRMAURLSessionTaskOverride isSupportedTaskType: task]) {
// Checking for NEW_RELIC_CROSS_PROCESS_ID_HEADER_KEY in the headers here. The data usually isn't link to the task yet here so, if that header exists we are handling the task elsewhere and have a better chance of getting the data so we don't need to record it here.

NSNumber *isHandled = objc_getAssociatedObject(task, NRMAHandledRequestKey);

if (isHandled != nil && [isHandled boolValue]) {
if (NRMAOriginal__urlSessionTask_SetState!= nil) {
// Call original setState function.
((void(*)(NSURLSessionTask *,SEL,NSURLSessionTaskState))NRMAOriginal__urlSessionTask_SetState)(task, _cmd, newState);
}
return;
}


NSURLRequest *currentRequest = task.currentRequest;
if(currentRequest != nil && [currentRequest valueForHTTPHeaderField:NEW_RELIC_CROSS_PROCESS_ID_HEADER_KEY] != nil) {

if(currentRequest == nil) {
return;
}

NSURL *url = [currentRequest URL];
if (url != nil &&
newState != NSURLSessionTaskStateRunning && task.state == NSURLSessionTaskStateRunning) {
// get response code
NSUInteger responseCode = [NRMAURLSessionTaskOverride statusCode:task.response];
if (responseCode != -1) {
NSData *data = NRMA__getDataForSessionTask(task);
if (url != nil) {
// Added this section to add Distributed Tracing traceId\trace.id, guid,id and payload.
//1
NSMutableURLRequest* mutableRequest = [NRMAHTTPUtilities addCrossProcessIdentifier:currentRequest];
mutableRequest = [NRMAHTTPUtilities addConnectivityHeaderAndPayload:mutableRequest];

NRMAPayloadContainer* payload = [NRMAHTTPUtilities addConnectivityHeader:mutableRequest];
[NRMAHTTPUtilities attachPayload:payload to:task.originalRequest];

NSData *data = NRMA__getDataForSessionTask(task);

// log the task and data that we will record
//NSLog(@"NRMAOverride__urlSessionTask_SetState newState: %ld, taskState:%ld task: %@ data: %@", (long) newState, (long)task.state, task, data);

if (newState == NSURLSessionTaskStateCompleted) {
// NSLog(@"NRMAOverride NRMA__recordTask called because newState == NSURLSessionTaskStateCompleted newState: %ld, taskState:%ld task: %@ data: %@", (long) newState, (long)task.state, task, data);

NRMA__recordTask(task, data, task.response, task.error);
}
}
Expand All @@ -138,7 +158,7 @@ void NRMAOverride__urlSessionTask_SetState(NSURLSessionTask* task, SEL _cmd, NSU
}
if (NRMAOriginal__urlSessionTask_SetState!= nil) {
// Call original setState function.
((void(*)(NSURLSessionTask *,SEL,NSURLSessionTaskState *))NRMAOriginal__urlSessionTask_SetState)(task, _cmd, newState);
((void(*)(NSURLSessionTask *,SEL,NSURLSessionTaskState))NRMAOriginal__urlSessionTask_SetState)(task, _cmd, newState);
}
}

Expand Down
Loading
Loading