All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.upyun.BaseUploader Maven / Gradle / Ivy

There is a newer version: 4.2.3
Show newest version
package com.upyun;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;

public abstract class BaseUploader {
    static final String AUTHORIZATION = "Authorization";
    final static String BACKSLASH = "/";
    static final int BLOCK_SIZE = 1024 * 1024;

    final String DATE = "Date";

    static final String CONTENT_MD5 = "Content-MD5";
    static final String CONTENT_TYPE = "CContent-Type";
    static final String CONTENT_SECRET = "Content-Secret";
    static final String X_Upyun_Meta_X = "X-Upyun-Meta-X";

    static final String X_UPYUN_MULTI_DISORDER = "X-Upyun-Multi-Disorder";
    static final String X_UPYUN_MULTI_STAGE = "X-Upyun-Multi-Stage";
    static final String X_UPYUN_MULTI_TYPE = "X-Upyun-Multi-Type";
    static final String X_UPYUN_MULTI_LENGTH = "X-Upyun-Multi-Length";
    static final String X_UPYUN_MULTI_UUID = "X-Upyun-Multi-UUID";
    static final String X_UPYUN_PART_ID = "X-Upyun-Part-ID";
    static final String X_UPYUN_NEXT_PART_ID = "X-Upyun-Next-Part-ID";

    static final String HOST = "https://v0.api.upyun.com";

    Map params;

    volatile boolean paused;

    String uuid;
    String uri;
    OkHttpClient mClient;
    File mFile;
    RandomAccessFile randomAccessFile;

    boolean checkMD5;

    // 空间名
    String bucketName;
    // 操作员名
    String userName;
    // 操作员密码
    String password;
    //超时设置(s)
    int timeout = 20;

    String url;

    OnProgressListener onProgressListener;

    int totalBlock;

    /**
     * 初始化 SerialUploader
     *
     * @param bucketName 空间名称
     * @param userName   操作员名称
     * @param password   密码,需要MD5加密
     * @return SerialUploader object
     */
    public BaseUploader(String bucketName, String userName, String password) {
        this.bucketName = bucketName;
        this.userName = userName;
        this.password = UpYunUtils.md5(password);
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    public void pause() {
        this.paused = true;
    }

    void init(String filePath, String uploadPath, Map params) throws FileNotFoundException {

        this.paused = false;

        if (params == null) {
            params = new HashMap();
        }

        this.params = params;

        this.mFile = new File(filePath);

        this.totalBlock = (int) Math.ceil(mFile.length() / (double) BLOCK_SIZE + 2);

        if (uploadPath.startsWith(BACKSLASH)) {
            this.uri = BACKSLASH + bucketName + BACKSLASH + URLEncoder.encode(uploadPath.substring(1));
        } else {
            this.uri = BACKSLASH + bucketName + BACKSLASH + URLEncoder.encode(uploadPath);
        }

        this.url = HOST + uri;

        this.mClient = new OkHttpClient.Builder()
                .connectTimeout(timeout, TimeUnit.SECONDS)
                .readTimeout(timeout, TimeUnit.SECONDS)
                .writeTimeout(timeout, TimeUnit.SECONDS)
                .build();
    }

    /**
     * 获取 uuid
     *
     * @return uuid
     */
    public String getUuid() {
        return uuid;
    }

    /**
     * 设置 uuid
     *
     * @param uuid
     */
    public void setUuid(String uuid) {
        this.uuid = uuid;
    }

    /**
     * 设置是否 MD5 校验
     *
     * @param checkMD5 是否 MD5 校验
     */
    public void setCheckMD5(boolean checkMD5) {
        this.checkMD5 = checkMD5;
    }

    /**
     * 设置上传进度监听
     *
     * @param onProgressListener 上传进度 listener
     */
    public void setOnProgressListener(OnProgressListener onProgressListener) {
        this.onProgressListener = onProgressListener;
    }

    boolean startUpload() throws IOException, UpException {

        if (paused) {
            throw new UpException("upload paused");
        }

        if (uuid == null) {
            RequestBody requestBody = RequestBody.create(null, "");

            String date = getGMTDate();

            String md5 = null;

            if (checkMD5) {
                md5 = UpYunUtils.md5("");
            }

            String sign = UpYunUtils.sign("PUT", date, uri, userName, password, md5).trim();

            Request.Builder builder = new Request.Builder()
                    .url(url)
                    .header(DATE, date)
                    .header(AUTHORIZATION, sign)
                    .header(X_UPYUN_MULTI_STAGE, "initiate")
                    .header(X_UPYUN_MULTI_TYPE, "application/octet-stream")
                    .header(X_UPYUN_MULTI_LENGTH, mFile.length() + "")
                    .header("User-Agent", UpYunUtils.VERSION)
                    .put(requestBody);

            if (params != null) {
                for (Map.Entry entry : params.entrySet()) {
                    builder.header(entry.getKey(), entry.getValue());
                }
            }

            if (md5 != null) {
                builder.header(CONTENT_MD5, md5);
            }
            callRequest(builder.build(), 1);
        }

        if (this.randomAccessFile == null) {
            this.randomAccessFile = new RandomAccessFile(mFile, "r");
        }

        return processUpload();
    }

    abstract boolean processUpload() throws IOException, UpException;

    abstract boolean completeUpload() throws IOException, UpException;

    void completeRequest() throws UpException, IOException {

        if (randomAccessFile != null) {
            randomAccessFile.close();
            randomAccessFile = null;
        }

        RequestBody requestBody = RequestBody.create(null, "");

        String date = getGMTDate();

        String md5 = null;

        if (checkMD5) {
            md5 = UpYunUtils.md5("");
        }

        String sign = UpYunUtils.sign("PUT", date, uri, userName, password, md5).trim();

        Request.Builder builder = new Request.Builder()
                .url(url)
                .header(DATE, date)
                .header(AUTHORIZATION, sign)
                .header(X_UPYUN_MULTI_STAGE, "complete")
                .header(X_UPYUN_MULTI_UUID, uuid)
                .header("User-Agent", UpYunUtils.VERSION)
                .put(requestBody);

        if (md5 != null) {
            builder.header(CONTENT_MD5, md5);
        }

        callRequest(builder.build(), totalBlock);
    }

    Response callRequest(Request request, int index) throws IOException, UpException {

        Response response = mClient.newCall(request).execute();
        if (!response.isSuccessful()) {
            throw new UpException(response.body().string());
        } else {
            if (onProgressListener != null) {
                onProgressListener.onProgress(index, totalBlock);
            }
        }

        uuid = response.header(X_UPYUN_MULTI_UUID, "");

        return response;
    }

    /**
     * 获取 GMT 格式时间戳
     *
     * @return GMT 格式时间戳
     */
    String getGMTDate() {
        SimpleDateFormat formater = new SimpleDateFormat(
                "EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
        formater.setTimeZone(TimeZone.getTimeZone("GMT"));
        return formater.format(new Date());
    }

    byte[] readBlockByIndex(int index) throws IOException {
        byte[] block = new byte[BLOCK_SIZE];
        int readedSize = 0;
        int offset = index * BLOCK_SIZE;
        randomAccessFile.seek(offset);
        readedSize = randomAccessFile.read(block, 0, BLOCK_SIZE);

        // read last block, adjust byte size
        if (readedSize < BLOCK_SIZE) {
            byte[] notFullBlock = new byte[readedSize];
            System.arraycopy(block, 0, notFullBlock, 0, readedSize);
            return notFullBlock;
        }
        return block;
    }

    public interface OnProgressListener {
        void onProgress(int index, int total);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy