@revopush/react-native-code-push 1.5.0 → 2.5.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CodePush.js +8 -5
- package/CodePush.podspec +9 -0
- package/android/build.gradle +53 -40
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +3 -1
- package/android/gradle.properties +1 -1
- package/android/settings.gradle +31 -0
- package/android/src/main/java/com/microsoft/codepush/react/CodePush.java +8 -4
- package/android/src/main/java/com/microsoft/codepush/react/CodePushConstants.java +11 -7
- package/android/src/main/java/com/microsoft/codepush/react/CodePushNativeModule.java +48 -41
- package/android/src/main/java/com/microsoft/codepush/react/CodePushUpdateManager.java +67 -175
- package/android/src/main/java/com/microsoft/codepush/react/CodePushUpdateUtils.java +7 -244
- package/android/src/main/java/com/microsoft/codepush/react/CodePushUtils.java +16 -51
- package/android/src/main/java/com/microsoft/codepush/react/FileUtils.java +1 -130
- package/ios/CodePush/CodePush.h +1 -30
- package/ios/CodePush/CodePush.m +23 -7
- package/ios/CodePush/CodePushPackage.m +363 -294
- package/ios/CodePush/CodePushUpdateUtils.m +77 -28
- package/ios/CodePush.xcodeproj/project.pbxproj +0 -18
- package/ios/Frameworks/DiffUpdates.xcframework/Info.plist +44 -0
- package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64/DiffUpdates.framework/DiffUpdates +0 -0
- package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64/DiffUpdates.framework/Headers/DiffUpdates.h +61 -0
- package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64/DiffUpdates.framework/Info.plist +0 -0
- package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64/DiffUpdates.framework/Modules/module.modulemap +6 -0
- package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64_x86_64-simulator/DiffUpdates.framework/DiffUpdates +0 -0
- package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64_x86_64-simulator/DiffUpdates.framework/Headers/DiffUpdates.h +61 -0
- package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64_x86_64-simulator/DiffUpdates.framework/Info.plist +0 -0
- package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64_x86_64-simulator/DiffUpdates.framework/Modules/module.modulemap +6 -0
- package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64_x86_64-simulator/DiffUpdates.framework/_CodeSignature/CodeDirectory +0 -0
- package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64_x86_64-simulator/DiffUpdates.framework/_CodeSignature/CodeRequirements +0 -0
- package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64_x86_64-simulator/DiffUpdates.framework/_CodeSignature/CodeRequirements-1 +0 -0
- package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64_x86_64-simulator/DiffUpdates.framework/_CodeSignature/CodeResources +132 -0
- package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64_x86_64-simulator/DiffUpdates.framework/_CodeSignature/CodeSignature +0 -0
- package/package.json +2 -2
- package/request-fetch-adapter.js +2 -2
- package/scripts/generateBundledResourcesHash.js +102 -65
- package/android/src/main/java/com/microsoft/codepush/react/TLSSocketFactory.java +0 -72
- package/ios/CodePush/CodePushDownloadHandler.m +0 -130
- package/ios/CodePush/CodePushErrorUtils.m +0 -20
- package/ios/CodePush/CodePushUtils.m +0 -9
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>files</key>
|
|
6
|
+
<dict>
|
|
7
|
+
<key>Headers/DiffUpdates.h</key>
|
|
8
|
+
<data>
|
|
9
|
+
obtyjOKZntpytQhuejpfeMN0BoI=
|
|
10
|
+
</data>
|
|
11
|
+
<key>Info.plist</key>
|
|
12
|
+
<data>
|
|
13
|
+
1nTR8o5HkR4SUcF0Z6umqipQPHI=
|
|
14
|
+
</data>
|
|
15
|
+
<key>Modules/module.modulemap</key>
|
|
16
|
+
<data>
|
|
17
|
+
MdjndwGRSccoMYmOwMDjozLG1jc=
|
|
18
|
+
</data>
|
|
19
|
+
</dict>
|
|
20
|
+
<key>files2</key>
|
|
21
|
+
<dict>
|
|
22
|
+
<key>Headers/DiffUpdates.h</key>
|
|
23
|
+
<dict>
|
|
24
|
+
<key>hash</key>
|
|
25
|
+
<data>
|
|
26
|
+
obtyjOKZntpytQhuejpfeMN0BoI=
|
|
27
|
+
</data>
|
|
28
|
+
<key>hash2</key>
|
|
29
|
+
<data>
|
|
30
|
+
DdvTO8aHHON6ybR/EQTihMgOY9j/pmVw7sekeFl71N4=
|
|
31
|
+
</data>
|
|
32
|
+
</dict>
|
|
33
|
+
<key>Modules/module.modulemap</key>
|
|
34
|
+
<dict>
|
|
35
|
+
<key>hash</key>
|
|
36
|
+
<data>
|
|
37
|
+
MdjndwGRSccoMYmOwMDjozLG1jc=
|
|
38
|
+
</data>
|
|
39
|
+
<key>hash2</key>
|
|
40
|
+
<data>
|
|
41
|
+
TkYpCqgNFTGwSnC7+iZu51GEITzi1EHKvjZj4HupKms=
|
|
42
|
+
</data>
|
|
43
|
+
</dict>
|
|
44
|
+
</dict>
|
|
45
|
+
<key>rules</key>
|
|
46
|
+
<dict>
|
|
47
|
+
<key>^.*</key>
|
|
48
|
+
<true/>
|
|
49
|
+
<key>^.*\.lproj/</key>
|
|
50
|
+
<dict>
|
|
51
|
+
<key>optional</key>
|
|
52
|
+
<true/>
|
|
53
|
+
<key>weight</key>
|
|
54
|
+
<real>1000</real>
|
|
55
|
+
</dict>
|
|
56
|
+
<key>^.*\.lproj/locversion.plist$</key>
|
|
57
|
+
<dict>
|
|
58
|
+
<key>omit</key>
|
|
59
|
+
<true/>
|
|
60
|
+
<key>weight</key>
|
|
61
|
+
<real>1100</real>
|
|
62
|
+
</dict>
|
|
63
|
+
<key>^Base\.lproj/</key>
|
|
64
|
+
<dict>
|
|
65
|
+
<key>weight</key>
|
|
66
|
+
<real>1010</real>
|
|
67
|
+
</dict>
|
|
68
|
+
<key>^version.plist$</key>
|
|
69
|
+
<true/>
|
|
70
|
+
</dict>
|
|
71
|
+
<key>rules2</key>
|
|
72
|
+
<dict>
|
|
73
|
+
<key>.*\.dSYM($|/)</key>
|
|
74
|
+
<dict>
|
|
75
|
+
<key>weight</key>
|
|
76
|
+
<real>11</real>
|
|
77
|
+
</dict>
|
|
78
|
+
<key>^(.*/)?\.DS_Store$</key>
|
|
79
|
+
<dict>
|
|
80
|
+
<key>omit</key>
|
|
81
|
+
<true/>
|
|
82
|
+
<key>weight</key>
|
|
83
|
+
<real>2000</real>
|
|
84
|
+
</dict>
|
|
85
|
+
<key>^.*</key>
|
|
86
|
+
<true/>
|
|
87
|
+
<key>^.*\.lproj/</key>
|
|
88
|
+
<dict>
|
|
89
|
+
<key>optional</key>
|
|
90
|
+
<true/>
|
|
91
|
+
<key>weight</key>
|
|
92
|
+
<real>1000</real>
|
|
93
|
+
</dict>
|
|
94
|
+
<key>^.*\.lproj/locversion.plist$</key>
|
|
95
|
+
<dict>
|
|
96
|
+
<key>omit</key>
|
|
97
|
+
<true/>
|
|
98
|
+
<key>weight</key>
|
|
99
|
+
<real>1100</real>
|
|
100
|
+
</dict>
|
|
101
|
+
<key>^Base\.lproj/</key>
|
|
102
|
+
<dict>
|
|
103
|
+
<key>weight</key>
|
|
104
|
+
<real>1010</real>
|
|
105
|
+
</dict>
|
|
106
|
+
<key>^Info\.plist$</key>
|
|
107
|
+
<dict>
|
|
108
|
+
<key>omit</key>
|
|
109
|
+
<true/>
|
|
110
|
+
<key>weight</key>
|
|
111
|
+
<real>20</real>
|
|
112
|
+
</dict>
|
|
113
|
+
<key>^PkgInfo$</key>
|
|
114
|
+
<dict>
|
|
115
|
+
<key>omit</key>
|
|
116
|
+
<true/>
|
|
117
|
+
<key>weight</key>
|
|
118
|
+
<real>20</real>
|
|
119
|
+
</dict>
|
|
120
|
+
<key>^embedded\.provisionprofile$</key>
|
|
121
|
+
<dict>
|
|
122
|
+
<key>weight</key>
|
|
123
|
+
<real>20</real>
|
|
124
|
+
</dict>
|
|
125
|
+
<key>^version\.plist$</key>
|
|
126
|
+
<dict>
|
|
127
|
+
<key>weight</key>
|
|
128
|
+
<real>20</real>
|
|
129
|
+
</dict>
|
|
130
|
+
</dict>
|
|
131
|
+
</dict>
|
|
132
|
+
</plist>
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@revopush/react-native-code-push",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.5.0-rc.1",
|
|
4
4
|
"description": "React Native plugin for the CodePush service",
|
|
5
5
|
"main": "CodePush.js",
|
|
6
6
|
"typings": "typings/react-native-code-push.d.ts",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"url": "https://github.com/revopush/react-native-code-push"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"code-push": "4.
|
|
40
|
+
"@revopush/code-push": "4.3.0",
|
|
41
41
|
"glob": "^7.1.7",
|
|
42
42
|
"hoist-non-react-statics": "^3.3.2",
|
|
43
43
|
"inquirer": "^8.1.5",
|
package/request-fetch-adapter.js
CHANGED
|
@@ -12,7 +12,7 @@ module.exports = {
|
|
|
12
12
|
"Content-Type": "application/json",
|
|
13
13
|
"X-CodePush-Plugin-Name": packageJson.name,
|
|
14
14
|
"X-CodePush-Plugin-Version": packageJson.version,
|
|
15
|
-
"X-CodePush-SDK-Version": packageJson.dependencies["code-push"]
|
|
15
|
+
"X-CodePush-SDK-Version": packageJson.dependencies["@revopush/code-push"]
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
if (requestBody && typeof requestBody === "object") {
|
|
@@ -49,4 +49,4 @@ function getHttpMethodName(verb) {
|
|
|
49
49
|
"CONNECT",
|
|
50
50
|
"PATCH"
|
|
51
51
|
][verb];
|
|
52
|
-
}
|
|
52
|
+
}
|
|
@@ -17,10 +17,14 @@ var path = require("path");
|
|
|
17
17
|
|
|
18
18
|
var getFilesInFolder = require("./getFilesInFolder");
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
const CODE_PUSH_FOLDER_PREFIX = "CodePush";
|
|
21
|
+
const CODE_PUSH_HASH_FILE_NAME = "CodePushHash";
|
|
22
|
+
const CODE_PUSH_METADATA_FILE_NAME = "CodePushMetadata";
|
|
23
|
+
const CODE_PUSH_PACKAGE_HASH = "packageHash"
|
|
24
|
+
const CODE_PUSH_BUNDLE_HASH = "bundleHash"
|
|
25
|
+
const CODE_PUSH_ASSET_HASH = "assetHash"
|
|
26
|
+
const CODE_PUSH_HASH_OLD_FILE_NAME = "CodePushHash.json";
|
|
27
|
+
const HASH_ALGORITHM = "sha256";
|
|
24
28
|
|
|
25
29
|
var resourcesDir = process.argv[2];
|
|
26
30
|
var jsBundleFilePath = process.argv[3];
|
|
@@ -30,96 +34,129 @@ var tempFileName = process.argv[5];
|
|
|
30
34
|
var oldFileToModifiedTimeMap = {};
|
|
31
35
|
var tempFileLocalPath = null;
|
|
32
36
|
if (tempFileName) {
|
|
33
|
-
|
|
34
|
-
|
|
37
|
+
tempFileLocalPath = path.join(require("os").tmpdir(), tempFileName);
|
|
38
|
+
oldFileToModifiedTimeMap = require(tempFileLocalPath);
|
|
35
39
|
}
|
|
36
40
|
var resourceFiles = [];
|
|
37
41
|
|
|
38
42
|
getFilesInFolder(resourcesDir, resourceFiles);
|
|
39
43
|
|
|
44
|
+
function getBundleResourceEntries(resourcesDir, assetsDir) {
|
|
45
|
+
const resourceFiles = [];
|
|
46
|
+
const assetFiles = [];
|
|
47
|
+
getFilesInFolder(resourcesDir, resourceFiles);
|
|
48
|
+
getFilesInFolder(assetsDir, assetFiles);
|
|
49
|
+
let resourceFilesRelative = resourceFiles.map((it) => path.relative(resourcesDir, it.path));
|
|
50
|
+
let assetsFilesRelative = assetFiles.map((it) => path.relative(assetsDir, it.path));
|
|
51
|
+
|
|
52
|
+
const normalizePath = (it) => path.join(CODE_PUSH_FOLDER_PREFIX, it).replace(/\\/g, "/")
|
|
53
|
+
return {
|
|
54
|
+
resources: Object.fromEntries(resourceFilesRelative.map((it) => [path.parse(it).name, normalizePath(it)])),
|
|
55
|
+
assets: Object.fromEntries(assetsFilesRelative.map((it) => [it.replace(/\\/g, "/"), normalizePath(it)]))
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
40
59
|
var newFileToModifiedTimeMap = {};
|
|
41
60
|
|
|
42
|
-
resourceFiles.forEach(function(resourceFile) {
|
|
43
|
-
|
|
61
|
+
resourceFiles.forEach(function (resourceFile) {
|
|
62
|
+
newFileToModifiedTimeMap[resourceFile.path.substring(resourcesDir.length)] = resourceFile.mtime;
|
|
44
63
|
});
|
|
45
64
|
|
|
46
65
|
var bundleGeneratedAssetFiles = [];
|
|
47
66
|
|
|
48
67
|
for (var newFilePath in newFileToModifiedTimeMap) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
68
|
+
if (!oldFileToModifiedTimeMap[newFilePath] || oldFileToModifiedTimeMap[newFilePath] < newFileToModifiedTimeMap[newFilePath].getTime()) {
|
|
69
|
+
bundleGeneratedAssetFiles.push(newFilePath);
|
|
70
|
+
}
|
|
52
71
|
}
|
|
53
72
|
|
|
54
73
|
var manifest = [];
|
|
55
74
|
|
|
56
75
|
if (bundleGeneratedAssetFiles.length) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
});
|
|
76
|
+
bundleGeneratedAssetFiles.forEach(function (assetFile) {
|
|
77
|
+
// Generate hash for each asset file
|
|
78
|
+
addFileToManifest(resourcesDir, assetFile, manifest, function () {
|
|
79
|
+
if (manifest.length === bundleGeneratedAssetFiles.length) {
|
|
80
|
+
addJsBundleAndMetaToManifest();
|
|
81
|
+
}
|
|
64
82
|
});
|
|
83
|
+
});
|
|
65
84
|
} else {
|
|
66
|
-
|
|
85
|
+
addJsBundleAndMetaToManifest();
|
|
67
86
|
}
|
|
68
87
|
|
|
69
88
|
function addJsBundleAndMetaToManifest() {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
addFileToManifest(path.dirname(jsBundleFilePath), path.basename(jsBundleFilePath), manifest, function (jsBundleFileHash) {
|
|
90
|
+
var jsBundleMetaFilePath = jsBundleFilePath + ".meta";
|
|
91
|
+
addFileToManifest(path.dirname(jsBundleMetaFilePath), path.basename(jsBundleMetaFilePath), manifest, function () {
|
|
92
|
+
manifest = manifest.sort();
|
|
93
|
+
const finalHash = crypto.createHash(HASH_ALGORITHM)
|
|
94
|
+
.update(JSON.stringify(manifest))
|
|
95
|
+
.digest("hex");
|
|
96
|
+
|
|
97
|
+
const bundleHashDada = path.join(CODE_PUSH_FOLDER_PREFIX, path.basename(jsBundleFilePath)).replace(/\\/g, "/") + ":" + jsBundleFileHash;
|
|
98
|
+
const bundleHash = crypto.createHash(HASH_ALGORITHM)
|
|
99
|
+
.update(JSON.stringify([bundleHashDada]))
|
|
100
|
+
.digest("hex");
|
|
101
|
+
|
|
102
|
+
const assetHash = crypto.createHash(HASH_ALGORITHM)
|
|
103
|
+
.update(JSON.stringify([...manifest].filter(it => it !== bundleHashDada).sort()))
|
|
104
|
+
.digest("hex");
|
|
105
|
+
|
|
106
|
+
const manifestMetadata = {
|
|
107
|
+
[CODE_PUSH_PACKAGE_HASH]: finalHash,
|
|
108
|
+
[CODE_PUSH_BUNDLE_HASH]: bundleHash,
|
|
109
|
+
[CODE_PUSH_ASSET_HASH]: assetHash, ...(getBundleResourceEntries(resourcesDir, assetsDir))
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
console.log(finalHash);
|
|
113
|
+
|
|
114
|
+
fs.writeFileSync(path.join(assetsDir, CODE_PUSH_HASH_FILE_NAME), finalHash);
|
|
115
|
+
fs.writeFileSync(path.join(assetsDir, CODE_PUSH_METADATA_FILE_NAME), JSON.stringify(manifestMetadata));
|
|
116
|
+
|
|
117
|
+
// "CodePushHash.json" file name breaks flow type checking.
|
|
118
|
+
// To fix the issue we need to delete "CodePushHash.json" file and
|
|
119
|
+
// use "CodePushHash" file name instead to store the hash value.
|
|
120
|
+
// Relates to https://github.com/microsoft/react-native-code-push/issues/577
|
|
121
|
+
var oldSavedResourcesManifestPath = assetsDir + "/" + CODE_PUSH_HASH_OLD_FILE_NAME;
|
|
122
|
+
if (fs.existsSync(oldSavedResourcesManifestPath)) {
|
|
123
|
+
fs.unlinkSync(oldSavedResourcesManifestPath);
|
|
124
|
+
}
|
|
92
125
|
});
|
|
126
|
+
});
|
|
93
127
|
}
|
|
94
128
|
|
|
95
129
|
function addFileToManifest(folder, assetFile, manifest, done) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
130
|
+
var fullFilePath = path.join(folder, assetFile);
|
|
131
|
+
if (!fileExists(fullFilePath)) {
|
|
132
|
+
done(undefined);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
var readStream = fs.createReadStream(path.join(folder, assetFile));
|
|
137
|
+
var hashStream = crypto.createHash(HASH_ALGORITHM);
|
|
138
|
+
|
|
139
|
+
readStream.pipe(hashStream)
|
|
140
|
+
.on("error", function (error) {
|
|
141
|
+
throw error;
|
|
142
|
+
})
|
|
143
|
+
.on("finish", function () {
|
|
144
|
+
hashStream.end();
|
|
145
|
+
var buffer = hashStream.read();
|
|
146
|
+
var fileHash = buffer.toString("hex");
|
|
147
|
+
manifest.push(path.join(CODE_PUSH_FOLDER_PREFIX, assetFile).replace(/\\/g, "/") + ":" + fileHash);
|
|
148
|
+
done(fileHash);
|
|
149
|
+
});
|
|
116
150
|
}
|
|
117
151
|
|
|
118
152
|
function fileExists(file) {
|
|
119
|
-
|
|
120
|
-
|
|
153
|
+
try {
|
|
154
|
+
return fs.statSync(file).isFile();
|
|
155
|
+
} catch (e) {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
121
158
|
}
|
|
122
159
|
|
|
123
160
|
if (tempFileLocalPath) {
|
|
124
|
-
|
|
125
|
-
}
|
|
161
|
+
fs.unlinkSync(tempFileLocalPath);
|
|
162
|
+
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
package com.microsoft.codepush.react;
|
|
2
|
-
|
|
3
|
-
import java.io.IOException;
|
|
4
|
-
import java.net.InetAddress;
|
|
5
|
-
import java.net.Socket;
|
|
6
|
-
import java.net.UnknownHostException;
|
|
7
|
-
import java.security.KeyManagementException;
|
|
8
|
-
import java.security.NoSuchAlgorithmException;
|
|
9
|
-
|
|
10
|
-
import javax.net.ssl.SSLContext;
|
|
11
|
-
import javax.net.ssl.SSLSocket;
|
|
12
|
-
import javax.net.ssl.SSLSocketFactory;
|
|
13
|
-
|
|
14
|
-
public class TLSSocketFactory extends SSLSocketFactory {
|
|
15
|
-
|
|
16
|
-
private SSLSocketFactory delegate;
|
|
17
|
-
|
|
18
|
-
public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
|
|
19
|
-
SSLContext context = SSLContext.getInstance("TLS");
|
|
20
|
-
context.init(null, null, null);
|
|
21
|
-
delegate = context.getSocketFactory();
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
@Override
|
|
25
|
-
public String[] getDefaultCipherSuites() {
|
|
26
|
-
return delegate.getDefaultCipherSuites();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
@Override
|
|
30
|
-
public String[] getSupportedCipherSuites() {
|
|
31
|
-
return delegate.getSupportedCipherSuites();
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
@Override
|
|
35
|
-
public Socket createSocket() throws IOException {
|
|
36
|
-
return enableTLSOnSocket(delegate.createSocket());
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
@Override
|
|
40
|
-
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
|
|
41
|
-
return enableTLSOnSocket(delegate.createSocket(s, host, port, autoClose));
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
@Override
|
|
45
|
-
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
|
|
46
|
-
return enableTLSOnSocket(delegate.createSocket(host, port));
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
@Override
|
|
50
|
-
public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
|
|
51
|
-
throws IOException, UnknownHostException {
|
|
52
|
-
return enableTLSOnSocket(delegate.createSocket(host, port, localHost, localPort));
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
@Override
|
|
56
|
-
public Socket createSocket(InetAddress host, int port) throws IOException {
|
|
57
|
-
return enableTLSOnSocket(delegate.createSocket(host, port));
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
@Override
|
|
61
|
-
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)
|
|
62
|
-
throws IOException {
|
|
63
|
-
return enableTLSOnSocket(delegate.createSocket(address, port, localAddress, localPort));
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
private Socket enableTLSOnSocket(Socket socket) {
|
|
67
|
-
if (socket != null && (socket instanceof SSLSocket)) {
|
|
68
|
-
((SSLSocket) socket).setEnabledProtocols(new String[] { "TLSv1.1", "TLSv1.2" });
|
|
69
|
-
}
|
|
70
|
-
return socket;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
#import "CodePush.h"
|
|
2
|
-
|
|
3
|
-
@implementation CodePushDownloadHandler {
|
|
4
|
-
// Header chars used to determine if the file is a zip.
|
|
5
|
-
char _header[4];
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
- (id)init:(NSString *)downloadFilePath
|
|
9
|
-
operationQueue:(dispatch_queue_t)operationQueue
|
|
10
|
-
progressCallback:(void (^)(long long, long long))progressCallback
|
|
11
|
-
doneCallback:(void (^)(BOOL))doneCallback
|
|
12
|
-
failCallback:(void (^)(NSError *err))failCallback {
|
|
13
|
-
self.outputFileStream = [NSOutputStream outputStreamToFileAtPath:downloadFilePath
|
|
14
|
-
append:NO];
|
|
15
|
-
self.receivedContentLength = 0;
|
|
16
|
-
self.operationQueue = operationQueue;
|
|
17
|
-
self.progressCallback = progressCallback;
|
|
18
|
-
self.doneCallback = doneCallback;
|
|
19
|
-
self.failCallback = failCallback;
|
|
20
|
-
return self;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
- (void)download:(NSString *)url {
|
|
24
|
-
self.downloadUrl = url;
|
|
25
|
-
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]
|
|
26
|
-
cachePolicy:NSURLRequestUseProtocolCachePolicy
|
|
27
|
-
timeoutInterval:60.0];
|
|
28
|
-
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request
|
|
29
|
-
delegate:self
|
|
30
|
-
startImmediately:NO];
|
|
31
|
-
if ([NSOperationQueue instancesRespondToSelector:@selector(setUnderlyingQueue:)]) {
|
|
32
|
-
NSOperationQueue *delegateQueue = [NSOperationQueue new];
|
|
33
|
-
delegateQueue.underlyingQueue = self.operationQueue;
|
|
34
|
-
[connection setDelegateQueue:delegateQueue];
|
|
35
|
-
} else {
|
|
36
|
-
[connection scheduleInRunLoop:[NSRunLoop mainRunLoop]
|
|
37
|
-
forMode:NSDefaultRunLoopMode];
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
[connection start];
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
#pragma mark NSURLConnection Delegate Methods
|
|
44
|
-
|
|
45
|
-
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
|
|
46
|
-
willCacheResponse:(NSCachedURLResponse*)cachedResponse {
|
|
47
|
-
// Return nil to indicate not necessary to store a cached response for this connection
|
|
48
|
-
return nil;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
|
|
52
|
-
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
|
|
53
|
-
NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
|
|
54
|
-
if (statusCode >= 400) {
|
|
55
|
-
[self.outputFileStream close];
|
|
56
|
-
[connection cancel];
|
|
57
|
-
NSError *err = [CodePushErrorUtils errorWithMessage:[NSString stringWithFormat: @"Received %ld response from %@", (long)statusCode, self.downloadUrl]];
|
|
58
|
-
self.failCallback(err);
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
self.expectedContentLength = response.expectedContentLength;
|
|
64
|
-
[self.outputFileStream open];
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
|
|
68
|
-
if (self.receivedContentLength < 4) {
|
|
69
|
-
for (int i = 0; i < [data length]; i++) {
|
|
70
|
-
int headerOffset = (int)self.receivedContentLength + i;
|
|
71
|
-
if (headerOffset >= 4) {
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const char *bytes = [data bytes];
|
|
76
|
-
_header[headerOffset] = bytes[i];
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
self.receivedContentLength = self.receivedContentLength + [data length];
|
|
81
|
-
|
|
82
|
-
NSInteger bytesLeft = [data length];
|
|
83
|
-
|
|
84
|
-
do {
|
|
85
|
-
NSInteger bytesWritten = [self.outputFileStream write:[data bytes]
|
|
86
|
-
maxLength:bytesLeft];
|
|
87
|
-
if (bytesWritten == -1) {
|
|
88
|
-
break;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
bytesLeft -= bytesWritten;
|
|
92
|
-
} while (bytesLeft > 0);
|
|
93
|
-
|
|
94
|
-
self.progressCallback(self.expectedContentLength, self.receivedContentLength);
|
|
95
|
-
|
|
96
|
-
// bytesLeft should not be negative.
|
|
97
|
-
assert(bytesLeft >= 0);
|
|
98
|
-
|
|
99
|
-
if (bytesLeft) {
|
|
100
|
-
[self.outputFileStream close];
|
|
101
|
-
[connection cancel];
|
|
102
|
-
self.failCallback([self.outputFileStream streamError]);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
|
|
107
|
-
{
|
|
108
|
-
[self.outputFileStream close];
|
|
109
|
-
self.failCallback(error);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
|
|
113
|
-
[self.outputFileStream close];
|
|
114
|
-
if (self.receivedContentLength < 1) {
|
|
115
|
-
NSError *err = [CodePushErrorUtils errorWithMessage:[NSString stringWithFormat:@"Received empty response from %@", self.downloadUrl]];
|
|
116
|
-
self.failCallback(err);
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// expectedContentLength might be -1 when NSURLConnection don't know the length(e.g. response encode with gzip)
|
|
121
|
-
if (self.expectedContentLength > 0) {
|
|
122
|
-
// We should have received all of the bytes if this is called.
|
|
123
|
-
assert(self.receivedContentLength == self.expectedContentLength);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
BOOL isZip = _header[0] == 'P' && _header[1] == 'K' && _header[2] == 3 && _header[3] == 4;
|
|
127
|
-
self.doneCallback(isZip);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
@end
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
#import "CodePush.h"
|
|
2
|
-
|
|
3
|
-
@implementation CodePushErrorUtils
|
|
4
|
-
|
|
5
|
-
static NSString *const CodePushErrorDomain = @"CodePushError";
|
|
6
|
-
static const int CodePushErrorCode = -1;
|
|
7
|
-
|
|
8
|
-
+ (NSError *)errorWithMessage:(NSString *)errorMessage
|
|
9
|
-
{
|
|
10
|
-
return [NSError errorWithDomain:CodePushErrorDomain
|
|
11
|
-
code:CodePushErrorCode
|
|
12
|
-
userInfo:@{ NSLocalizedDescriptionKey: NSLocalizedString(errorMessage, nil) }];
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
+ (BOOL)isCodePushError:(NSError *)err
|
|
16
|
-
{
|
|
17
|
-
return err != nil && [CodePushErrorDomain isEqualToString:err.domain];
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
@end
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
#import "CodePush.h"
|
|
2
|
-
|
|
3
|
-
void CPLog(NSString *formatString, ...) {
|
|
4
|
-
va_list args;
|
|
5
|
-
va_start(args, formatString);
|
|
6
|
-
NSString *prependedFormatString = [NSString stringWithFormat:@"\n[CodePush] %@", formatString];
|
|
7
|
-
NSLogv(prependedFormatString, args);
|
|
8
|
-
va_end(args);
|
|
9
|
-
}
|