Skip to content

Commit

Permalink
Add downloading from url payload type
Browse files Browse the repository at this point in the history
Summary:
Adds a payload type for downloading from a url. This can take advantage of `bsdtar`s archive detection, which means that it's easy to bridge a data stream task to the same way we'd stream data over grpc.

This does require that the companion-side has access to the url, but failure still occurs if the extract fails for any reason, for instance a garbage input, or 404

Reviewed By: zeyadsalloum

Differential Revision: D15117099

fbshipit-source-id: 97d6b6f03783c4d76f2a85a2bbcdb8f5e969ed5d
  • Loading branch information
lawrencelomax authored and facebook-github-bot committed Apr 29, 2019
1 parent 2130564 commit 7d630bb
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 0 deletions.
15 changes: 15 additions & 0 deletions idb_companion/Server/FBIDBServiceHandler.mm
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#import <FBSimulatorControl/FBSimulatorControl.h>

#import "FBBundleStorageManager.h"
#import "FBDataDownloadInput.h"
#import "FBIDBCommandExecutor.h"
#import "FBIDBPortsConfiguration.h"
#import "FBIDBServiceHandler.h"
Expand Down Expand Up @@ -479,6 +480,20 @@ static void fill_crash_log_response(idb::CrashLogResponse *response, const NSArr
return nil;
}
}
case idb::Payload::kUrl: {
NSURL *url = [NSURL URLWithString:[NSString stringWithCString:payload.url().c_str() encoding:NSUTF8StringEncoding]];
FBDataDownloadInput *download = [FBDataDownloadInput dataDownloadWithURL:url logger:_target.logger];
switch (destination) {
case idb::InstallRequest_Destination::InstallRequest_Destination_APP:
return [_commandExecutor install_stream:download.input];
case idb::InstallRequest_Destination::InstallRequest_Destination_XCTEST:
return [_commandExecutor xctest_install_stream:download.input];
case idb::InstallRequest_Destination::InstallRequest_Destination_DYLIB:
return [_commandExecutor install_dylib_stream:download.input name:name];
default:
return nil;
}
}
case idb::Payload::kFilePath: {
NSString *filePath = nsstring_from_c_string(payload.file_path());
switch (destination) {
Expand Down
39 changes: 39 additions & 0 deletions idb_companion/Utility/FBDataDownloadInput.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#import <Foundation/Foundation.h>

#import <FBControlCore/FBControlCore.h>

NS_ASSUME_NONNULL_BEGIN

/**
Converts a data download into the input of a process
*/
@interface FBDataDownloadInput : NSObject

#pragma mark Initializers

/**
The Designated Initializer.
@param url the url to download
@param logger the logger to use.
@return a data download instance.
*/
+ (instancetype)dataDownloadWithURL:(NSURL *)url logger:(id<FBControlCoreLogger>)logger;

#pragma mark Properties

/**
The process input that will be bridged.
*/
@property (nonatomic, strong, readonly) FBProcessInput<id<FBDataConsumer>> *input;

@end

NS_ASSUME_NONNULL_END
59 changes: 59 additions & 0 deletions idb_companion/Utility/FBDataDownloadInput.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#import "FBDataDownloadInput.h"

@interface FBDataDownloadInput () <NSURLSessionDataDelegate>

@property (nonatomic, strong, readonly) NSURLSessionTask *task;
@property (nonatomic, strong, readonly) id<FBControlCoreLogger> logger;

@end

@implementation FBDataDownloadInput

#pragma mark Initializers

+ (instancetype)dataDownloadWithURL:(NSURL *)url logger:(id<FBControlCoreLogger>)logger
{
FBDataDownloadInput *download = [[self alloc] initWithURL:url logger:logger];
[download.task resume];
return download;
}

- (instancetype)initWithURL:(NSURL *)url logger:(id<FBControlCoreLogger>)logger
{
self = [super init];
if (!self) {
return nil;
}

_logger = logger;
NSURLSessionConfiguration *configuration = NSURLSessionConfiguration.defaultSessionConfiguration;
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:NSOperationQueue.new];
_input = FBProcessInput.inputFromConsumer;
_task = [session dataTaskWithURL:url];

return self;
}

#pragma mark NSURLSessionDelegate

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
[self.input.contents consumeData:data];
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
if (error) {
[self.logger.error logFormat:@"Download task %@ failed with error %@", task, error];
}
[self.input.contents consumeEndOfFile];
}

@end
1 change: 1 addition & 0 deletions proto/idb.proto
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ message Payload {
oneof source {
string file_path = 1;
bytes data = 2;
string url = 3;
}
}

Expand Down

0 comments on commit 7d630bb

Please sign in to comment.