Skip to content

Commit

Permalink
fix(electron-updater): redirect event in electron.net
Browse files Browse the repository at this point in the history
Close #2374
  • Loading branch information
nicholaslee119 authored and develar committed Dec 29, 2017
1 parent 0884299 commit e2ac601
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 12 deletions.
23 changes: 18 additions & 5 deletions packages/builder-util-runtime/src/httpExecutor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export interface DownloadOptions {

readonly cancellationToken: CancellationToken

// noinspection JSUnusedLocalSymbols
onProgress?(progress: ProgressInfo): void
}

Expand Down Expand Up @@ -86,13 +87,18 @@ export abstract class HttpExecutor<REQUEST> {
}
})
this.addErrorAndTimeoutHandlers(request, reject)
this.addRedirectHandlers(request, options, cancellationToken, resolve, reject, redirectCount, requestProcessor)
this.addRedirectHandlers(request, options, reject, redirectCount, options => {
this.doApiRequest(options, cancellationToken, requestProcessor, redirectCount)
.then(resolve)
.catch(reject)
})
requestProcessor(request, reject)
onCancel(() => request.abort())
})
}

protected addRedirectHandlers(request: any, options: RequestOptions, cancellationToken: CancellationToken, resolve: (data?: any) => void, reject: (error: Error) => void, redirectCount: number, requestProcessor: (request: REQUEST, reject: (error: Error) => void) => void) {
// noinspection JSUnusedLocalSymbols
protected addRedirectHandlers(request: any, options: RequestOptions, reject: (error: Error) => void, redirectCount: number, handler: (options: RequestOptions) => void) {
// not required for NodeJS
}

Expand Down Expand Up @@ -131,7 +137,7 @@ Please double check that your authentication token is correct. Due to security r
return
}

this.doApiRequest(this.prepareRedirectUrlOptions(redirectUrl, options), cancellationToken, requestProcessor, redirectCount)
this.doApiRequest(HttpExecutor.prepareRedirectUrlOptions(redirectUrl, options), cancellationToken, requestProcessor, redirectCount)
.then(resolve)
.catch(reject)
return
Expand All @@ -158,6 +164,7 @@ Please double check that your authentication token is correct. Due to security r
})
}

// noinspection JSUnusedLocalSymbols
abstract doRequest(options: any, callback: (response: any) => void): any

protected doDownload(requestOptions: any, destination: string, redirectCount: number, options: DownloadOptions, callback: (error: Error | null) => void, onCancel: (callback: () => void) => void) {
Expand All @@ -170,7 +177,7 @@ Please double check that your authentication token is correct. Due to security r
const redirectUrl = safeGetHeader(response, "location")
if (redirectUrl != null) {
if (redirectCount < this.maxRedirects) {
this.doDownload(this.prepareRedirectUrlOptions(redirectUrl, requestOptions), destination, redirectCount++, options, callback, onCancel)
this.doDownload(HttpExecutor.prepareRedirectUrlOptions(redirectUrl, requestOptions), destination, redirectCount++, options, callback, onCancel)
}
else {
callback(new Error(`Too many redirects (> ${this.maxRedirects})`))
Expand All @@ -181,6 +188,9 @@ Please double check that your authentication token is correct. Due to security r
configurePipes(options, response, destination, callback, options.cancellationToken)
})
this.addErrorAndTimeoutHandlers(request, callback)
this.addRedirectHandlers(request, requestOptions, callback, redirectCount, requestOptions => {
this.doDownload(requestOptions, destination, redirectCount++, options, callback, onCancel)
})
onCancel(() => request.abort())
request.end()
}
Expand All @@ -194,7 +204,7 @@ Please double check that your authentication token is correct. Due to security r
})
}

protected prepareRedirectUrlOptions(redirectUrl: string, options: RequestOptions): RequestOptions {
static prepareRedirectUrlOptions(redirectUrl: string, options: RequestOptions): RequestOptions {
const newOptions = configureRequestOptionsFromUrl(redirectUrl, {...options})
if (newOptions.headers != null && newOptions.headers.Authorization != null && (newOptions.headers!!.Authorization as string).startsWith("token")) {
const parsedNewUrl = new URL(redirectUrl)
Expand Down Expand Up @@ -227,6 +237,7 @@ export class DigestTransform extends Transform {

private _actual: string

// noinspection JSUnusedGlobalSymbols
get actual() {
return this._actual
}
Expand All @@ -239,11 +250,13 @@ export class DigestTransform extends Transform {
this.digester = createHash(algorithm)
}

// noinspection JSUnusedGlobalSymbols
_transform(chunk: Buffer, encoding: string, callback: any) {
this.digester.update(chunk)
callback(null, chunk)
}

// noinspection JSUnusedGlobalSymbols
_flush(callback: any): void {
this._actual = this.digester.digest(this.encoding)

Expand Down
13 changes: 11 additions & 2 deletions packages/electron-updater/src/MacUpdater.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import BluebirdPromise from "bluebird-lst"
import { CancellationToken, configureRequestOptionsFromUrl, DigestTransform, ProgressCallbackTransform, AllPublishOptions, RequestHeaders, safeGetHeader, UpdateInfo, safeStringifyJson } from "builder-util-runtime"
import { AllPublishOptions, CancellationToken, configureRequestOptionsFromUrl, DigestTransform, ProgressCallbackTransform, RequestHeaders, safeGetHeader, safeStringifyJson, UpdateInfo } from "builder-util-runtime"
import { createServer, IncomingMessage, OutgoingHttpHeaders, ServerResponse } from "http"
import { AppUpdater } from "./AppUpdater"
import { DOWNLOAD_PROGRESS, UPDATE_DOWNLOADED } from "./main"
import AutoUpdater = Electron.AutoUpdater
import { findFile } from "./Provider"
import AutoUpdater = Electron.AutoUpdater

export class MacUpdater extends AppUpdater {
private readonly nativeUpdater: AutoUpdater = require("electron").autoUpdater
Expand Down Expand Up @@ -140,6 +140,15 @@ export class MacUpdater extends AppUpdater {
}
})

downloadRequest.on("redirect", (statusCode: number, method: string, redirectUrl: string) => {
if (headers.Authorization != null && (headers!!.Authorization as string).startsWith("token")) {
const parsedNewUrl = new URL(redirectUrl)
if (parsedNewUrl.hostname.endsWith(".amazonaws.com")) {
delete headers.Authorization
}
}
this.doProxyUpdateFile(nativeResponse, redirectUrl, headers, sha512, cancellationToken, errorHandler)
})
downloadRequest.on("error", errorHandler)
downloadRequest.end()
}
Expand Down
9 changes: 4 additions & 5 deletions packages/electron-updater/src/electronHttpExecutor.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CancellationToken, configureRequestOptionsFromUrl, DownloadOptions, HttpExecutor } from "builder-util-runtime"
import { configureRequestOptionsFromUrl, DownloadOptions, HttpExecutor } from "builder-util-runtime"
import { net } from "electron"
import { ensureDir } from "fs-extra-p"
import { RequestOptions } from "http"
Expand Down Expand Up @@ -46,15 +46,14 @@ export class ElectronHttpExecutor extends HttpExecutor<Electron.ClientRequest> {
}
}

protected addRedirectHandlers(request: any, options: RequestOptions, cancellationToken: CancellationToken, resolve: (data?: any) => void, reject: (error: Error) => void, redirectCount: number, requestProcessor: (request: Electron.ClientRequest, reject: (error: Error) => void) => void) {
protected addRedirectHandlers(request: any, options: RequestOptions, reject: (error: Error) => void, redirectCount: number, handler: (options: RequestOptions) => void) {
request.on("redirect", (statusCode: number, method: string, redirectUrl: string) => {
if (redirectCount > 10) {
reject(new Error("Too many redirects (> 10)"))
return
}
this.doApiRequest(this.prepareRedirectUrlOptions(redirectUrl, options), cancellationToken, requestProcessor, redirectCount)
.then(resolve)
.catch(reject)

handler(HttpExecutor.prepareRedirectUrlOptions(redirectUrl, options))
})
}
}

0 comments on commit e2ac601

Please sign in to comment.