diff --git a/x-pack/plugins/code/public/components/route.ts b/x-pack/plugins/code/public/components/route.ts index fa20542d6daaa..0c4892b0188dd 100644 --- a/x-pack/plugins/code/public/components/route.ts +++ b/x-pack/plugins/code/public/components/route.ts @@ -7,6 +7,7 @@ import { connect } from 'react-redux'; import { Route as ReactRoute, RouteProps } from 'react-router-dom'; import { Match, routeChange } from '../actions'; +import { decodeRevisionString } from '../utils/url'; interface Props extends RouteProps { routeChange: (match: Match) => void; @@ -14,10 +15,16 @@ interface Props extends RouteProps { class CSRoute extends ReactRoute { // eslint-disable-next-line @typescript-eslint/camelcase public UNSAFE_componentWillMount() { + if (this.state.match && this.state.match.params && this.state.match.params.revision) { + this.state.match.params.revision = decodeRevisionString(this.state.match.params.revision); + } this.props.routeChange({ ...this.state.match, location: this.props.location }); } public componentDidUpdate() { + if (this.state.match && this.state.match.params && this.state.match.params.revision) { + this.state.match.params.revision = decodeRevisionString(this.state.match.params.revision); + } this.props.routeChange({ ...this.state.match, location: this.props.location }); } } diff --git a/x-pack/plugins/code/public/sagas/blame.ts b/x-pack/plugins/code/public/sagas/blame.ts index 4dedbd68c6b22..d79221f9c63ef 100644 --- a/x-pack/plugins/code/public/sagas/blame.ts +++ b/x-pack/plugins/code/public/sagas/blame.ts @@ -12,7 +12,9 @@ import { loadBlame, loadBlameFailed, LoadBlamePayload, loadBlameSuccess } from ' import { blamePattern } from './patterns'; function requestBlame(repoUri: string, revision: string, path: string) { - return kfetch({ pathname: `/api/code/repo/${repoUri}/blame/${revision}/${path}` }); + return kfetch({ + pathname: `/api/code/repo/${repoUri}/blame/${encodeURIComponent(revision)}/${path}`, + }); } function* handleFetchBlame(action: Action) { diff --git a/x-pack/plugins/code/public/sagas/file.ts b/x-pack/plugins/code/public/sagas/file.ts index efa9202813c09..5e8249c491869 100644 --- a/x-pack/plugins/code/public/sagas/file.ts +++ b/x-pack/plugins/code/public/sagas/file.ts @@ -93,7 +93,7 @@ function requestRepoTree({ query.parents = true; } return kfetch({ - pathname: `/api/code/repo/${uri}/tree/${revision}/${path}`, + pathname: `/api/code/repo/${uri}/tree/${encodeURIComponent(revision)}/${path}`, query, }); } @@ -158,7 +158,7 @@ function requestCommits( ) { const pathStr = path ? `/${path}` : ''; const options: any = { - pathname: `/api/code/repo/${uri}/history/${revision}${pathStr}`, + pathname: `/api/code/repo/${uri}/history/${encodeURIComponent(revision)}${pathStr}`, }; if (loadMore) { options.query = { after: 1 }; @@ -174,7 +174,7 @@ export async function requestFile( line?: string ): Promise { const { uri, revision, path } = payload; - const url = `/api/code/repo/${uri}/blob/${revision}/${path}`; + const url = `/api/code/repo/${uri}/blob/${encodeURIComponent(revision)}/${path}`; const query: any = {}; if (line) { query.line = line; diff --git a/x-pack/plugins/code/public/utils/url.ts b/x-pack/plugins/code/public/utils/url.ts index 7a1a25c335177..0208434eeb5df 100644 --- a/x-pack/plugins/code/public/utils/url.ts +++ b/x-pack/plugins/code/public/utils/url.ts @@ -9,3 +9,11 @@ import createHistory from 'history/createHashHistory'; export const history = createHistory(); export const isImportRepositoryURLInvalid = (url: string) => url.trim() === ''; + +export const decodeRevisionString = (revision: string) => { + return revision.replace(':', '/'); +}; + +export const encodeRevisionString = (revision: string) => { + return revision.replace('/', ':'); +}; diff --git a/x-pack/plugins/code/server/routes/file.ts b/x-pack/plugins/code/server/routes/file.ts index 2f8ac4d828674..7f5c586fd6ee2 100644 --- a/x-pack/plugins/code/server/routes/file.ts +++ b/x-pack/plugins/code/server/routes/file.ts @@ -65,7 +65,7 @@ export function fileRoute(server: hapi.Server, options: ServerOptions) { const fileResolver = new GitOperations(options.repoPath); const { uri, path, ref } = req.params; try { - const blob = await fileResolver.fileContent(uri, path, ref); + const blob = await fileResolver.fileContent(uri, path, decodeURIComponent(ref)); if (blob.isBinary()) { const type = fileType(blob.content()); if (type && type.mime && type.mime.startsWith('image/')) { @@ -149,7 +149,7 @@ export function fileRoute(server: hapi.Server, options: ServerOptions) { const after = queries.after !== undefined; try { const repository = await gitOperations.openRepo(uri); - const commit = await gitOperations.getCommit(repository, ref); + const commit = await gitOperations.getCommit(repository, decodeURIComponent(ref)); const walk = repository.createRevWalk(); walk.sorting(Revwalk.SORT.TIME); walk.push(commit.id()); @@ -223,7 +223,7 @@ export function fileRoute(server: hapi.Server, options: ServerOptions) { const gitOperations = new GitOperations(options.repoPath); const { uri, path, revision } = req.params; try { - const blames = await gitOperations.blame(uri, revision, path); + const blames = await gitOperations.blame(uri, decodeURIComponent(revision), path); return blames; } catch (e) { if (e.isBoom) {