diff options
author | blundell@chromium.org <blundell@chromium.org> | 2014-09-01 11:02:57 +0000 |
---|---|---|
committer | blundell@chromium.org <blundell@chromium.org> | 2014-09-01 11:02:57 +0000 |
commit | 1335417f9feefd20e5b0e4b1e18e9010edb87043 (patch) | |
tree | 0296d7d860021ec4d7f6dae5d5a58c259038c4b5 /src/client/ios | |
parent | Support for multiple upload files in CrashReportSender/HTTPUpload (diff) | |
download | breakpad-1335417f9feefd20e5b0e4b1e18e9010edb87043.tar.xz |
Adding possibility for client to upload the file
This CL adds three features that will allow the client to upload the report
file.
Three main modifications are made :
- Allow upload url to have a file:// scheme, and write the HTTP request to file
in that case
- Split the request in two parts in case of a file:// scheme, the request
time and the response time. A new API [handleNetworkResponse] is added.
- Give the opportunity to the client to get the configuration NSDictionary
to be able to recreate the breakpad context at response time.
Patch by Olivier Robin <olivierrobin@chromium.org>
Review URL: https://breakpad.appspot.com/2764002/
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1368 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/client/ios')
-rw-r--r-- | src/client/ios/Breakpad.h | 22 | ||||
-rw-r--r-- | src/client/ios/Breakpad.mm | 103 | ||||
-rw-r--r-- | src/client/ios/BreakpadController.h | 14 | ||||
-rw-r--r-- | src/client/ios/BreakpadController.mm | 31 |
4 files changed, 155 insertions, 15 deletions
diff --git a/src/client/ios/Breakpad.h b/src/client/ios/Breakpad.h index 9d212f70..c099ad07 100644 --- a/src/client/ios/Breakpad.h +++ b/src/client/ios/Breakpad.h @@ -199,6 +199,9 @@ void BreakpadRemoveUploadParameter(BreakpadRef ref, NSString *key); // Returns the number of crash reports waiting to send to the server. int BreakpadGetCrashReportCount(BreakpadRef ref); +// Returns the next upload configuration. The report file is deleted. +NSDictionary *BreakpadGetNextReportConfiguration(BreakpadRef ref); + // Upload next report to the server. void BreakpadUploadNextReport(BreakpadRef ref); @@ -207,6 +210,25 @@ void BreakpadUploadNextReport(BreakpadRef ref); void BreakpadUploadNextReportWithParameters(BreakpadRef ref, NSDictionary *server_parameters); +// Upload a report to the server. +// |server_parameters| is additional server parameters to send. +// |configuration| is the configuration of the breakpad report to send. +void BreakpadUploadReportWithParametersAndConfiguration( + BreakpadRef ref, + NSDictionary *server_parameters, + NSDictionary *configuration); + +// Handles the network response of a breakpad upload. This function is needed if +// the actual upload is done by the Breakpad client. +// |configuration| is the configuration of the upload. It must contain the same +// fields as the configuration passed to +// BreakpadUploadReportWithParametersAndConfiguration. +// |data| and |error| contain the network response. +void BreakpadHandleNetworkResponse(BreakpadRef ref, + NSDictionary *configuration, + NSData *data, + NSError *error); + // Upload a file to the server. |data| is the content of the file to sent. // |server_parameters| is additional server parameters to send. void BreakpadUploadData(BreakpadRef ref, NSData *data, NSString *name, diff --git a/src/client/ios/Breakpad.mm b/src/client/ios/Breakpad.mm index 5c4043c4..ca856f8f 100644 --- a/src/client/ios/Breakpad.mm +++ b/src/client/ios/Breakpad.mm @@ -152,9 +152,15 @@ class Breakpad { void RemoveKeyValue(NSString *key); NSArray *CrashReportsToUpload(); NSString *NextCrashReportToUpload(); + NSDictionary *NextCrashReportConfiguration(); void UploadNextReport(NSDictionary *server_parameters); + void UploadReportWithConfiguration(NSDictionary *configuration, + NSDictionary *server_parameters); void UploadData(NSData *data, NSString *name, NSDictionary *server_parameters); + void HandleNetworkResponse(NSDictionary *configuration, + NSData *data, + NSError *error); NSDictionary *GenerateReport(NSDictionary *server_parameters); private: @@ -449,18 +455,38 @@ NSString *Breakpad::NextCrashReportToUpload() { } //============================================================================= +NSDictionary *Breakpad::NextCrashReportConfiguration() { + return [Uploader readConfigurationDataFromFile:NextCrashReportToUpload()]; +} + +//============================================================================= +void Breakpad::HandleNetworkResponse(NSDictionary *configuration, + NSData *data, + NSError *error) { + Uploader *uploader = [[[Uploader alloc] + initWithConfig:configuration] autorelease]; + [uploader handleNetworkResponse:data withError:error]; +} + +//============================================================================= +void Breakpad::UploadReportWithConfiguration(NSDictionary *configuration, + NSDictionary *server_parameters) { + Uploader *uploader = [[[Uploader alloc] + initWithConfig:configuration] autorelease]; + if (!uploader) + return; + for (NSString *key in server_parameters) { + [uploader addServerParameter:[server_parameters objectForKey:key] + forKey:key]; + } + [uploader report]; +} + +//============================================================================= void Breakpad::UploadNextReport(NSDictionary *server_parameters) { - NSString *configFile = NextCrashReportToUpload(); - if (configFile) { - Uploader *uploader = [[[Uploader alloc] - initWithConfigFile:[configFile UTF8String]] autorelease]; - if (uploader) { - for (NSString *key in server_parameters) { - [uploader addServerParameter:[server_parameters objectForKey:key] - forKey:key]; - } - [uploader report]; - } + NSDictionary *configuration = NextCrashReportConfiguration(); + if (configuration) { + return UploadReportWithConfiguration(configuration, server_parameters); } } @@ -795,17 +821,64 @@ void BreakpadUploadNextReport(BreakpadRef ref) { } //============================================================================= +NSDictionary *BreakpadGetNextReportConfiguration(BreakpadRef ref) { + try { + Breakpad *breakpad = (Breakpad *)ref; + if (breakpad) + return breakpad->NextCrashReportConfiguration(); + } catch(...) { // don't let exceptions leave this C API + fprintf(stderr, "BreakpadGetNextReportConfiguration() : error\n"); + } + return nil; +} + +//============================================================================= +void BreakpadUploadReportWithParametersAndConfiguration( + BreakpadRef ref, + NSDictionary *server_parameters, + NSDictionary *configuration) { + try { + Breakpad *breakpad = (Breakpad *)ref; + if (!breakpad || !configuration) + return; + breakpad->UploadReportWithConfiguration(configuration, server_parameters); + } catch(...) { // don't let exceptions leave this C API + fprintf(stderr, + "BreakpadUploadReportWithParametersAndConfiguration() : error\n"); + } + +} + +//============================================================================= void BreakpadUploadNextReportWithParameters(BreakpadRef ref, NSDictionary *server_parameters) { try { + Breakpad *breakpad = (Breakpad *)ref; + if (!breakpad) + return; + NSDictionary *configuration = breakpad->NextCrashReportConfiguration(); + if (!configuration) + return; + return BreakpadUploadReportWithParametersAndConfiguration(ref, + server_parameters, + configuration); + } catch(...) { // don't let exceptions leave this C API + fprintf(stderr, "BreakpadUploadNextReportWithParameters() : error\n"); + } +} + +void BreakpadHandleNetworkResponse(BreakpadRef ref, + NSDictionary *configuration, + NSData *data, + NSError *error) { + try { // Not called at exception time Breakpad *breakpad = (Breakpad *)ref; + if (breakpad && configuration) + breakpad->HandleNetworkResponse(configuration,data, error); - if (breakpad) { - breakpad->UploadNextReport(server_parameters); - } } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, "BreakpadUploadNextReport() : error\n"); + fprintf(stderr, "BreakpadHandleNetworkResponse() : error\n"); } } diff --git a/src/client/ios/BreakpadController.h b/src/client/ios/BreakpadController.h index cf1fa774..13609cb8 100644 --- a/src/client/ios/BreakpadController.h +++ b/src/client/ios/BreakpadController.h @@ -122,6 +122,20 @@ // Get the number of crash reports waiting to upload. - (void)getCrashReportCount:(void(^)(int))callback; +// Get the next report to upload. +// - If upload is disabled, callback will be called with (nil, -1). +// - If a delay is to be waited before sending, callback will be called with +// (nil, n), with n (> 0) being the number of seconds to wait. +// - if no delay is needed, callback will be called with (0, configuration), +// configuration being next report to upload, or nil if none is pending. +- (void)getNextReportConfigurationOrSendDelay: + (void(^)(NSDictionary*, int))callback; + +// Sends synchronously the report specified by |configuration|. This method is +// NOT thread safe and must be called from the breakpad thread. +- (void)threadUnsafeSendReportWithConfiguration:(NSDictionary*)configuration + withBreakpadRef:(BreakpadRef)ref; + @end #endif // CLIENT_IOS_HANDLER_IOS_BREAKPAD_CONTROLLER_H_ diff --git a/src/client/ios/BreakpadController.mm b/src/client/ios/BreakpadController.mm index a85dd68e..dd71cff6 100644 --- a/src/client/ios/BreakpadController.mm +++ b/src/client/ios/BreakpadController.mm @@ -155,6 +155,18 @@ NSString* GetPlatform() { }); } +// This method must be called from the breakpad queue. +- (void)threadUnsafeSendReportWithConfiguration:(NSDictionary*)configuration + withBreakpadRef:(BreakpadRef)ref { + NSAssert(started_, @"The controller must be started before " + "threadUnsafeSendReportWithConfiguration is called"); + if (breakpadRef_) { + BreakpadUploadReportWithParametersAndConfiguration(breakpadRef_, + uploadTimeParameters_, + configuration); + } +} + - (void)setUploadingEnabled:(BOOL)enabled { NSAssert(started_, @"The controller must be started before setUploadingEnabled is called"); @@ -260,6 +272,25 @@ NSString* GetPlatform() { }); } +- (void)getNextReportConfigurationOrSendDelay: + (void(^)(NSDictionary*, int))callback { + NSAssert(started_, @"The controller must be started before " + "getNextReportConfigurationOrSendDelay is called"); + dispatch_async(queue_, ^{ + if (!breakpadRef_) { + callback(nil, -1); + return; + } + int delay = [self sendDelay]; + if (delay != 0) { + callback(nil, delay); + return; + } + [self reportWillBeSent]; + callback(BreakpadGetNextReportConfiguration(breakpadRef_), 0); + }); +} + #pragma mark - - (int)sendDelay { |