/* * Minio Cloud Storage (C) 2018 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import Moment from "moment" import storage from "local-storage-fallback" import * as alertActions from "../alert/actions" import * as objectsActions from "../objects/actions" import { getCurrentBucket } from "../buckets/selectors" import { getCurrentPrefix } from "../objects/selectors" import { minioBrowserPrefix } from "../constants" export const ADD = "uploads/ADD" export const UPDATE_PROGRESS = "uploads/UPDATE_PROGRESS" export const STOP = "uploads/STOP" export const SHOW_ABORT_MODAL = "uploads/SHOW_ABORT_MODAL" export const add = (slug, size, name) => ({ type: ADD, slug, size, name }) export const updateProgress = (slug, loaded) => ({ type: UPDATE_PROGRESS, slug, loaded }) export const stop = slug => ({ type: STOP, slug }) export const showAbortModal = () => ({ type: SHOW_ABORT_MODAL, show: true }) export const hideAbortModal = () => ({ type: SHOW_ABORT_MODAL, show: false }) let requests = {} export const addUpload = (xhr, slug, size, name) => { return function(dispatch) { requests[slug] = xhr dispatch(add(slug, size, name)) } } export const abortUpload = slug => { return function(dispatch) { const xhr = requests[slug] if (xhr) { xhr.abort() } dispatch(stop(slug)) dispatch(hideAbortModal()) } } export const uploadFile = file => { return function(dispatch, getState) { const state = getState() const currentBucket = getCurrentBucket(state) if (!currentBucket) { dispatch( alertActions.set({ type: "danger", message: "Please choose a bucket before trying to upload files." }) ) return } const currentPrefix = getCurrentPrefix(state) const objectName = `${currentPrefix}${file.name}` const uploadUrl = `${ window.location.origin }${minioBrowserPrefix}/upload/${currentBucket}/${objectName}` const slug = `${currentBucket}-${currentPrefix}-${file.name}` let xhr = new XMLHttpRequest() xhr.open("PUT", uploadUrl, true) xhr.withCredentials = false const token = storage.getItem("token") if (token) { xhr.setRequestHeader( "Authorization", "Bearer " + storage.getItem("token") ) } xhr.setRequestHeader( "x-amz-date", Moment() .utc() .format("YYYYMMDDTHHmmss") + "Z" ) dispatch(addUpload(xhr, slug, file.size, file.name)) xhr.onload = function(event) { if (xhr.status == 401 || xhr.status == 403) { dispatch(hideAbortModal()) dispatch(stop(slug)) dispatch( alertActions.set({ type: "danger", message: "Unauthorized request." }) ) } if (xhr.status == 500) { dispatch(hideAbortModal()) dispatch(stop(slug)) dispatch( alertActions.set({ type: "danger", message: xhr.responseText }) ) } if (xhr.status == 200) { dispatch(hideAbortModal()) dispatch(stop(slug)) dispatch( alertActions.set({ type: "success", message: "File '" + file.name + "' uploaded successfully." }) ) dispatch(objectsActions.selectPrefix(currentPrefix)) } } xhr.upload.addEventListener("error", event => { dispatch(stop(slug)) dispatch( alertActions.set({ type: "danger", message: "Error occurred uploading '" + file.name + "'." }) ) }) xhr.upload.addEventListener("progress", event => { if (event.lengthComputable) { let loaded = event.loaded let total = event.total // Update the counter dispatch(updateProgress(slug, loaded)) } }) xhr.send(file) } }