diff --git a/src/cfml/system/endpoints/ForgeBox.cfc b/src/cfml/system/endpoints/ForgeBox.cfc index 956c74fa..26179927 100644 --- a/src/cfml/system/endpoints/ForgeBox.cfc +++ b/src/cfml/system/endpoints/ForgeBox.cfc @@ -250,6 +250,7 @@ component accessors="true" implements="IEndpointInteractive" { props.changeLogFormat = 'text'; props.APIToken = getAPIToken(); props.forceUpload = arguments.force; + props.binaryHash = boxJSON?.binaryHash ?: ''; // start upload stuff here var upload = boxJSON.location == "forgeboxStorage"; @@ -353,6 +354,7 @@ component accessors="true" implements="IEndpointInteractive" { } consoleLogger.warn( "Uploading package zip [#readableSize#] to #getNamePrefixes()#..." ); var storeURL = forgebox.storeURL( props.slug, props.version, props.APIToken ); + var binary = fileReadBinary( zipPath ); http url="#storeURL#" @@ -364,9 +366,11 @@ component accessors="true" implements="IEndpointInteractive" { proxyPassword="#ConfigService.getSetting( 'proxy.password', '' )#" result="local.storeResult"{ httpparam type="header" name="Content-Type" value="application/zip"; - httpparam type="body" value="#fileReadBinary( zipPath )#"; + httpparam type="body" value="#binary#"; } + props.binaryHash = hash( binary, "MD5" ); + if( fileExists( zipPath ) ){ fileDelete( zipPath ); } @@ -575,6 +579,10 @@ component accessors="true" implements="IEndpointInteractive" { } else { job.addLog( "Deferring to [#endpointData.endpointName#] endpoint for #getNamePrefixes()# entry [#slug#]..." ); + + if( len( satisfyingVersion.binaryHash ) && isInstanceOf( endpointData.endpoint, 'HTTP' ) ) { + endpointData.package = endpointData.package & "##" & satisfyingVersion.binaryHash; + } var packagePath = endpointData.endpoint.resolvePackage( endpointData.package, currentWorkingDirectory, arguments.verbose ); // Cheat for people who set a version, slug, or type in ForgeBox, but didn't put it in their box.json diff --git a/src/cfml/system/endpoints/HTTP.cfc b/src/cfml/system/endpoints/HTTP.cfc index 776eccb1..33b615d1 100644 --- a/src/cfml/system/endpoints/HTTP.cfc +++ b/src/cfml/system/endpoints/HTTP.cfc @@ -41,6 +41,12 @@ component accessors=true implements="IEndpoint" singleton { } public string function resolvePackageZip( required string package, boolean verbose=false ) { + var binaryHash = ''; + // Check if a hash is in the URL and if so, strip it out + if( package contains '##' ) { + binaryHash = package.listLast( '##' ); + package = package.listFirst( '##' ); + } if( configService.getSetting( 'offlineMode', false ) ) { throw( 'Can''t download [#getNamePrefixes()#:#package#], CommandBox is in offline mode. Go online with [config set offlineMode=false].', 'endpointException' ); @@ -73,6 +79,14 @@ component accessors=true implements="IEndpoint" singleton { throw( '#e.message##CR##e.detail#', 'endpointException' ); }; + // Validate the binary hash + if( len( binaryHash ) ) { + var downloadedBinaryHash = hash( fileReadBinary( fullPath ), "MD5" ); + if( binaryHash != downloadedBinaryHash ) { + throw( 'The hash of the downloaded file [#downloadedBinaryHash#] doesn''t match the excepted hash [#binaryHash#] #fullPath#', 'endpointException' ); + } + } + return fullPath; } diff --git a/src/cfml/system/util/ForgeBox.cfc b/src/cfml/system/util/ForgeBox.cfc index 4973b8e6..f537a4df 100644 --- a/src/cfml/system/util/ForgeBox.cfc +++ b/src/cfml/system/util/ForgeBox.cfc @@ -324,7 +324,8 @@ or just add DEBUG to the root logger string changeLogFormat='text', required string APIToken, string zipPath = "", - boolean forceUpload = false + boolean forceUpload = false, + string binaryHash = "" ) { var formFields = { @@ -339,7 +340,8 @@ or just add DEBUG to the root logger installInstructionsFormat = arguments.installInstructionsFormat, changeLog = arguments.changeLog, changeLogFormat = arguments.changeLogFormat, - forceUpload = arguments.forceUpload + forceUpload = arguments.forceUpload, + binaryHash = arguments.binaryHash }; var requestArguments = {