Skip to content

Commit

Permalink
Fixed issue with URL encoding.
Browse files Browse the repository at this point in the history
  • Loading branch information
ogubariev committed May 26, 2016
1 parent 12a4805 commit 2288692
Show file tree
Hide file tree
Showing 14 changed files with 182 additions and 79 deletions.
1 change: 1 addition & 0 deletions JaspersoftSDK.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Pod::Spec.new do |s|
#import "JSConstants.h"
#import "JSUtils.h"
#import "NSString+JSURLEncodings.h"
#define _AFNETWORKING_PIN_SSL_CERTIFICATES_
#if __IPHONE_OS_VERSION_MIN_REQUIRED
Expand Down
8 changes: 8 additions & 0 deletions JaspersoftSDK.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@
BD0A8F061C7F646A00C63F44 /* JSMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = BD0A8F041C7F646A00C63F44 /* JSMapping.h */; };
BD0A8F071C7F646A00C63F44 /* JSMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = BD0A8F051C7F646A00C63F44 /* JSMapping.m */; };
BD194F891C75D50100C99DA9 /* JSObjectMappingsProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = BD194F881C75D50100C99DA9 /* JSObjectMappingsProtocol.h */; };
BD991C5A1CF76B5B00859145 /* NSString+JSURLEncodings.h in Headers */ = {isa = PBXBuildFile; fileRef = BD991C581CF76B5B00859145 /* NSString+JSURLEncodings.h */; };
BD991C5B1CF76B5B00859145 /* NSString+JSURLEncodings.m in Sources */ = {isa = PBXBuildFile; fileRef = BD991C591CF76B5B00859145 /* NSString+JSURLEncodings.m */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand Down Expand Up @@ -272,6 +274,8 @@
BD0A8F041C7F646A00C63F44 /* JSMapping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMapping.h; sourceTree = "<group>"; };
BD0A8F051C7F646A00C63F44 /* JSMapping.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSMapping.m; sourceTree = "<group>"; };
BD194F881C75D50100C99DA9 /* JSObjectMappingsProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSObjectMappingsProtocol.h; sourceTree = "<group>"; };
BD991C581CF76B5B00859145 /* NSString+JSURLEncodings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+JSURLEncodings.h"; sourceTree = "<group>"; };
BD991C591CF76B5B00859145 /* NSString+JSURLEncodings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+JSURLEncodings.m"; sourceTree = "<group>"; };
F5758F3D174E301800C355C1 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
F5758F40174E302800C355C1 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
F5758F42174E302E00C355C1 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
Expand Down Expand Up @@ -485,6 +489,8 @@
0849FCE81C2C1D7D008F1064 /* JSUtils.m */,
A1478E5FF766BDE05BFDB838 /* JSDateFormatterFactory.h */,
A1478F2F9E43E7F32310F7FB /* JSDateFormatterFactory.m */,
BD991C581CF76B5B00859145 /* NSString+JSURLEncodings.h */,
BD991C591CF76B5B00859145 /* NSString+JSURLEncodings.m */,
);
path = JSHelper;
sourceTree = "<group>";
Expand Down Expand Up @@ -589,6 +595,7 @@
0849FCD71C2B0A93008F1064 /* KeychainItemWrapper.h in Headers */,
0849FCCF1C2B0A92008F1064 /* JSRESTBase+JSRESTResource.h in Headers */,
0849FC951C2B0A91008F1064 /* JSExportExecutionRequest.h in Headers */,
BD991C5A1CF76B5B00859145 /* NSString+JSURLEncodings.h in Headers */,
0899C4451C2D8FEE00CFBD91 /* JSErrorBuilder.h in Headers */,
0849FCAE1C2B0A91008F1064 /* JSReportParameter.h in Headers */,
0849FCDD1C2B0A93008F1064 /* JSSecurity.h in Headers */,
Expand Down Expand Up @@ -755,6 +762,7 @@
0849FCEE1C2C1D7D008F1064 /* JSUtils.m in Sources */,
0849FCCC1C2B0A92008F1064 /* JSRequest.m in Sources */,
0849FCA31C2B0A91008F1064 /* JSOperationResult.m in Sources */,
BD991C5B1CF76B5B00859145 /* NSString+JSURLEncodings.m in Sources */,
0849FCB71C2B0A91008F1064 /* JSResourceReportUnit.m in Sources */,
0849FCAD1C2B0A91008F1064 /* JSReportOutputResource.m in Sources */,
0849FCAF1C2B0A91008F1064 /* JSReportParameter.m in Sources */,
Expand Down
31 changes: 30 additions & 1 deletion Sources/JSHelper/JSErrorBuilder.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,36 @@
/*
* TIBCO JasperMobile for iOS
* Copyright © 2005-2016 TIBCO Software, Inc. All rights reserved.
* http://community.jaspersoft.com/project/jaspermobile-ios
*
* Unless you have purchased a commercial license agreement from Jaspersoft,
* the following license terms apply:
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/lgpl>.
*/


//
// Created by Aleksandr Dakhno on 10/16/15.
// JSErrorBuilder.h
// TIBCO JasperMobile
//

/**
@author Aleksandr Dakhno [email protected]
@since 2.3
*/

#import <Foundation/Foundation.h>
#import "JSConstants.h"

Expand Down
26 changes: 25 additions & 1 deletion Sources/JSHelper/JSErrorBuilder.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
/*
* TIBCO JasperMobile for iOS
* Copyright © 2005-2016 TIBCO Software, Inc. All rights reserved.
* http://community.jaspersoft.com/project/jaspermobile-ios
*
* Unless you have purchased a commercial license agreement from Jaspersoft,
* the following license terms apply:
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/lgpl>.
*/


//
// Created by Aleksandr Dakhno on 10/16/15.
// JSErrorBuilder.m
// TIBCO JasperMobile
//

#import "JSErrorBuilder.h"
Expand Down
3 changes: 2 additions & 1 deletion Sources/JSHelper/JSHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@
#import "JSUtils.h"
#import "JSConstants.h"
#import "JSErrorBuilder.h"
#import "JSDateFormatterFactory.h"
#import "JSDateFormatterFactory.h"
#import "NSString+JSURLEncodings.h"
41 changes: 41 additions & 0 deletions Sources/JSHelper/NSString+JSURLEncodings.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* TIBCO JasperMobile for iOS
* Copyright © 2005-2016 TIBCO Software, Inc. All rights reserved.
* http://community.jaspersoft.com/project/jaspermobile-ios
*
* Unless you have purchased a commercial license agreement from Jaspersoft,
* the following license terms apply:
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/lgpl>.
*/


//
// NSString(JSURLEncodings).h
// TIBCO JasperMobile
//

/**
@author Alexey Gubarev [email protected]
@since 2.5
*/

#import <Foundation/Foundation.h>

@interface NSString(JSURLEncodings)

- (nonnull NSString *)hostEncodedString;

- (nonnull NSString *)queryEncodedString;
@end
50 changes: 50 additions & 0 deletions Sources/JSHelper/NSString+JSURLEncodings.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* TIBCO JasperMobile for iOS
* Copyright © 2005-2016 TIBCO Software, Inc. All rights reserved.
* http://community.jaspersoft.com/project/jaspermobile-ios
*
* Unless you have purchased a commercial license agreement from Jaspersoft,
* the following license terms apply:
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/lgpl>.
*/


//
// NSString(JSURLEncodings).m
// TIBCO JasperMobile
//

#import "NSString+JSURLEncodings.h"

@implementation NSString(JSURLEncodings)

- (nonnull NSString *)hostEncodedString {
NSArray *components = [self componentsSeparatedByString:@"/"];
NSMutableArray *encodedComponentsArray = [NSMutableArray array];
for (NSString *component in components) {
[encodedComponentsArray addObject:[component encodedStringWithCharSet:[NSCharacterSet URLHostAllowedCharacterSet]]];
}
return [encodedComponentsArray componentsJoinedByString:@"/"];
}

- (nonnull NSString *)queryEncodedString {
return [self encodedStringWithCharSet:[NSCharacterSet URLQueryAllowedCharacterSet]];
}

- (NSString *)encodedStringWithCharSet:(NSCharacterSet *)characterSet {
return [self stringByAddingPercentEncodingWithAllowedCharacters:characterSet];
}

@end
7 changes: 3 additions & 4 deletions Sources/JSRestClient/JSRESTBase+JSRESTDashboard.m
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,13 @@
#import "JSInputControlDescriptor.h"
#import "JSReportParameter.h"


@implementation JSRESTBase (JSRESTDashboard)

#pragma mark - Components
- (void)fetchDashboardComponentsWithURI:(NSString *)dashboardURI
completion:(nullable JSRequestCompletionBlock)block
{
NSString *fullURL = [NSString stringWithFormat:@"%@%@_files/%@", kJS_REST_RESOURCES_URI, dashboardURI, @"components"];
NSString *fullURL = [NSString stringWithFormat:@"%@%@_files/%@", kJS_REST_RESOURCES_URI, dashboardURI.hostEncodedString, @"components"];
JSRequest *request = [[JSRequest alloc] initWithUri:fullURL];
request.objectMapping = [JSMapping mappingWithObjectMapping:[JSDashboardComponent objectMappingForServerProfile:self.serverProfile] keyPath:nil];
request.restVersion = JSRESTVersion_2;
Expand Down Expand Up @@ -134,12 +133,12 @@ - (NSString *)constructFullURIWithDashboardURI:(NSString *)uri
inputControls:(NSArray <NSString *> *)dependencies
initialValuesOnly:(BOOL)initialValuesOnly
{
NSString *fullReportsUri = [NSString stringWithFormat:@"%@%@%@", kJS_REST_REPORTS_URI, (uri ?: @""), kJS_REST_INPUT_CONTROLS_URI];
NSString *fullReportsUri = [NSString stringWithFormat:@"%@%@%@", kJS_REST_REPORTS_URI, (uri.hostEncodedString ?: @""), kJS_REST_INPUT_CONTROLS_URI];

if (dependencies && dependencies.count) {
NSMutableString *dependenciesUriPart = [[NSMutableString alloc] initWithString:@"/"];
for (NSString *dependency in dependencies) {
[dependenciesUriPart appendFormat:@"%@;", dependency];
[dependenciesUriPart appendFormat:@"%@;", dependency.hostEncodedString];
}
fullReportsUri = [fullReportsUri stringByAppendingString:dependenciesUriPart];
}
Expand Down
51 changes: 12 additions & 39 deletions Sources/JSRestClient/JSRESTBase+JSRESTReport.m
Original file line number Diff line number Diff line change
Expand Up @@ -41,35 +41,24 @@
#import "AFURLRequestSerialization.h"
#import "JSReportComponent.h"

// Report query used for setting output format (i.e PDF, HTML, etc.)
// and path for images (current dir) when exporting report in HTML
static NSString * const _baseReportQueryImagesParam = @"IMAGES_URI";
static NSString * const _baseReportQueryOutputFormatParam = @"RUN_OUTPUT_FORMAT";


@interface JSRESTBase (PrivateAPI)
- (void) addReportParametersToRequest:(JSRequest *)request withSelectedValues:(NSArray *)selectedValues;

- (NSString *)fullReportExecutionUri:(NSString *)requestId;

- (NSString *)fullDownloadReportFileUri:(NSString *)uuid;

- (NSString *)fullRunReportUri:(NSString *)uri;

- (NSString *)fullReportsUriForIC:(NSString *)uri withInputControls:(NSArray <NSString *> *)dependencies initialValuesOnly:(BOOL)initialValuesOnly;

- (NSString *)fullExportExecutionUri:(NSString *)requestId;

- (NSDictionary *)runReportQueryParams:(NSString *)format;

- (NSString *)encodeAttachmentsPrefix:(NSString *)exportOutput;
@end

@implementation JSRESTBase (JSRESTReportOptions)

- (void)inputControlsForReport:(NSString *)reportUri selectedValues:(NSArray <JSReportParameter *> *)selectedValues
completionBlock:(JSRequestCompletionBlock)block {
JSRequest *request = [[JSRequest alloc] initWithUri:[NSString stringWithFormat:@"%@%@%@", kJS_REST_REPORTS_URI, (reportUri ?: @""), kJS_REST_INPUT_CONTROLS_URI]];
JSRequest *request = [[JSRequest alloc] initWithUri:[NSString stringWithFormat:@"%@%@%@", kJS_REST_REPORTS_URI, (reportUri.hostEncodedString ?: @""), kJS_REST_INPUT_CONTROLS_URI]];
request.objectMapping = [JSMapping mappingWithObjectMapping:[JSInputControlDescriptor objectMappingForServerProfile:self.serverProfile] keyPath:@"inputControl"];
request.restVersion = JSRESTVersion_2;
request.method = ([selectedValues count]) ? JSRequestHTTPMethodPOST : JSRequestHTTPMethodGET;
Expand All @@ -90,7 +79,7 @@ - (void)updatedInputControlsValues:(NSString *)reportUri ids:(NSArray <NSString
}

- (void)reportOptionsForReportURI:(NSString *)reportURI completion:(JSRequestCompletionBlock)block {
NSString *uri = [NSString stringWithFormat:@"%@%@%@", kJS_REST_REPORTS_URI, reportURI, kJS_REST_REPORT_OPTIONS_URI];
NSString *uri = [NSString stringWithFormat:@"%@%@%@", kJS_REST_REPORTS_URI, reportURI.hostEncodedString, kJS_REST_REPORT_OPTIONS_URI];
JSRequest *request = [[JSRequest alloc] initWithUri:uri];
request.objectMapping = [JSMapping mappingWithObjectMapping:[JSReportOption objectMappingForServerProfile:self.serverProfile] keyPath:@"reportOptionsSummary"];
request.restVersion = JSRESTVersion_2;
Expand All @@ -103,9 +92,9 @@ - (void)deleteReportOption:(JSReportOption *)reportOption
completion:(JSRequestCompletionBlock)completion {
NSString *requestURIString = [NSString stringWithFormat:@"%@%@%@/%@",
kJS_REST_REPORTS_URI,
reportURI,
reportURI.hostEncodedString,
kJS_REST_REPORT_OPTIONS_URI,
reportOption.identifier];
reportOption.identifier.hostEncodedString];
JSRequest *request = [[JSRequest alloc] initWithUri:requestURIString];
request.restVersion = JSRESTVersion_2;
request.method = JSRequestHTTPMethodDELETE;
Expand All @@ -119,8 +108,8 @@ - (void)createReportOptionWithReportURI:(NSString *)reportURI
completion:(JSRequestCompletionBlock)completion {
NSString *requestURIString = [NSString stringWithFormat:@"%@%@%@?label=%@&overwrite=%@",
kJS_REST_REPORTS_URI,
reportURI,
kJS_REST_REPORT_OPTIONS_URI, [self encodeString:optionLabel], [JSUtils stringFromBOOL:YES]];
reportURI.hostEncodedString,
kJS_REST_REPORT_OPTIONS_URI, optionLabel.queryEncodedString, [JSUtils stringFromBOOL:YES]];

JSRequest *request = [[JSRequest alloc] initWithUri:requestURIString];
request.objectMapping = [JSMapping mappingWithObjectMapping:[JSReportOption objectMappingForServerProfile:self.serverProfile] keyPath:nil];
Expand Down Expand Up @@ -155,7 +144,7 @@ - (NSString *)generateReportUrl:(NSString *)uri reportParams:(NSArray <JSReportP
}

NSString *urlString = [NSString stringWithFormat:@"%@/%@%@%@.%@", self.serverProfile.serverUrl,
kJS_REST_SERVICES_V2_URI, kJS_REST_REPORTS_URI, uri, format];
kJS_REST_SERVICES_V2_URI, kJS_REST_REPORTS_URI, uri.hostEncodedString, format.hostEncodedString];


AFHTTPRequestSerializer *urlSerializer = [AFHTTPRequestSerializer new];
Expand Down Expand Up @@ -389,27 +378,17 @@ - (void) addReportParametersToRequest:(JSRequest *)request withSelectedValues:(N
}

- (NSString *)fullReportExecutionUri:(NSString *)requestId {
NSString *reportExecutionUri = kJS_REST_REPORT_EXECUTION_URI;

if (!requestId.length) return reportExecutionUri;
return [NSString stringWithFormat:@"%@/%@", reportExecutionUri, requestId];
}

- (NSString *)fullDownloadReportFileUri:(NSString *)uuid {
return [NSString stringWithFormat:@"%@/%@", kJS_REST_REPORT_URI, uuid];
}

- (NSString *)fullRunReportUri:(NSString *)uri {
return [NSString stringWithFormat:@"%@%@", kJS_REST_REPORT_URI, (uri ?: @"")];
if (!requestId.length) return kJS_REST_REPORT_EXECUTION_URI;
return [NSString stringWithFormat:@"%@/%@", kJS_REST_REPORT_EXECUTION_URI, requestId];
}

- (NSString *)fullReportsUriForIC:(NSString *)uri withInputControls:(NSArray <NSString *> *)dependencies initialValuesOnly:(BOOL)initialValuesOnly {
NSString *fullReportsUri = [NSString stringWithFormat:@"%@%@%@", kJS_REST_REPORTS_URI, (uri ?: @""), kJS_REST_INPUT_CONTROLS_URI];
NSString *fullReportsUri = [NSString stringWithFormat:@"%@%@%@", kJS_REST_REPORTS_URI, (uri.hostEncodedString ?: @""), kJS_REST_INPUT_CONTROLS_URI];

if (dependencies && dependencies.count) {
NSMutableString *dependenciesUriPart = [[NSMutableString alloc] initWithString:@"/"];
for (NSString *dependency in dependencies) {
[dependenciesUriPart appendFormat:@"%@;", dependency];
[dependenciesUriPart appendFormat:@"%@;", dependency.hostEncodedString];
}
fullReportsUri = [fullReportsUri stringByAppendingString:dependenciesUriPart];
}
Expand All @@ -425,11 +404,6 @@ - (NSString *)fullExportExecutionUri:(NSString *)requestId {
return [NSString stringWithFormat:@"%@/%@%@", kJS_REST_REPORT_EXECUTION_URI, requestId, kJS_REST_EXPORT_EXECUTION_URI];
}

- (NSDictionary *)runReportQueryParams:(NSString *)format {
return [NSDictionary dictionaryWithObjectsAndKeys:@"./", _baseReportQueryImagesParam,
format, _baseReportQueryOutputFormatParam, nil];
}

- (NSString *)encodeAttachmentsPrefix:(NSString *)exportOutput {
NSRange prefixRange = [exportOutput rangeOfString:@"attachmentsPrefix="];

Expand All @@ -438,8 +412,7 @@ - (NSString *)encodeAttachmentsPrefix:(NSString *)exportOutput {
NSRange valueRange = NSMakeRange(location, exportOutput.length - location);
NSString *value = [exportOutput substringWithRange:valueRange];
if (value.length) {
value = [self encodeString:value];
exportOutput = [exportOutput stringByReplacingCharactersInRange:valueRange withString:value];
exportOutput = [exportOutput stringByReplacingCharactersInRange:valueRange withString:value.queryEncodedString];
}
}

Expand Down
Loading

0 comments on commit 2288692

Please sign in to comment.