S 3特性試験

17528 ワード

package amazons3;

import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.lang.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.FileEntity;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.cookie.DateUtils;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

/**
 * S3 client with apache httpclient 4.x
 * 
 * @author zhangpu
 * 
 */
public class S3HttpClient {

	private static final Logger logger = Logger.getLogger(S3HttpClient.class);

	static String accessKey = "AKIAJC2MNN5XZWLRB4UQ";
	static String secretKey = "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";
	static String bucket = "zhangpu";

	public static void main(String[] args) throws Exception {
		File localFile = new File("D:/temp/s3testfile.txt");
		String objectName = localFile.getName() + "1";
		// postObject(bucket, objectName, localFile, null, false, null, null);
		Map<String, String> protocols = new TreeMap<String, String>();
		Map<String, String> metas = new TreeMap<String, String>();
		metas.put("x-amz-meta-name", "zhangpu");
		metas.put("x-amz-meta-type", "type");
		putObject(bucket, objectName, localFile, "text/plant", false, null, metas);
		getObject(bucket, objectName, null, null, null, null);
		protocols.clear();
		protocols.put(HttpHeaders.IF_NONE_MATCH, "3e89d34c93742d0a92d4dce69a857e2f");
		protocols.put(HttpHeaders.CONTENT_ENCODING, "gzip");
		getObject(bucket, objectName, null, protocols, null, null);
		headObject(bucket, objectName, null, null);
		deleteObject(bucket, objectName, null);
	}

	/**
	 * POST 
	 * 
	 * @param bucket
	 * @param objectName
	 * @param localFile
	 * @param contentType
	 * @param checkDigest
	 * @param protocols
	 * @param metas
	 * @return
	 * @throws Exception
	 */
	public static Header[] postObject(String bucket, String objectName, File localFile, String contentType, boolean checkDigest, Map<String, String> protocols,
			Map<String, String> metas) throws Exception {

		HttpClient httpClient = new DefaultHttpClient();
		if (StringUtils.isBlank(objectName)) {
			objectName = localFile.getName();
		}
		String url = "http://" + bucket + ".s3.amazonaws.com/" + objectName;
		String resource = "/" + bucket + "/" + objectName;
		HttpPost request = new HttpPost(url);

		Charset charset = Charset.forName("UTF-8");
		MultipartEntity mpEntity = new MultipartEntity();
		mpEntity.addPart("key", new StringBody("/user/${filename}", charset));
		if (StringUtils.isNotBlank(contentType)) {
			mpEntity.addPart("Content-Type", new StringBody(contentType, charset));
		}

		if (metas != null && metas.size() > 0) {
			for (Map.Entry<String, String> entry : metas.entrySet()) {
				mpEntity.addPart(entry.getKey(), new StringBody(entry.getValue(), charset));
			}
		}
		mpEntity.addPart("AWSAccessKeyId", new StringBody(accessKey, charset));
		String Signature = SignUtils.hmac(accessKey, secretKey, "POST", "", contentType, "", resource, protocols, metas);
		mpEntity.addPart("Signature", new StringBody(Signature, charset));

		ContentBody fileBody = new FileBody(localFile);
		mpEntity.addPart("file", fileBody);

		request.setEntity(mpEntity);
		printRequest(request);

		HttpResponse response = httpClient.execute(request);
		printResponse(response);
		HttpEntity entity = response.getEntity();
		if (entity != null && entity.getContentLength() > 0) {
			logger.info("entity:
" + EntityUtils.toString(response.getEntity())); } logger.info(""); logger.info(""); return null; } /** * * * @param bucket * @param objectName * @param localFile * @param contentType * @param md5 * @param protocols * @param metas */ public static void putObject(String bucket, String objectName, File localFile, String contentType, boolean checkDigest, Map<String, String> protocols, Map<String, String> metas) throws Exception { HttpClient httpClient = new DefaultHttpClient(); if (StringUtils.isBlank(objectName)) { objectName = localFile.getName(); } String url = "http://" + bucket + ".s3.amazonaws.com/" + objectName; String resource = "/" + bucket + "/" + objectName; HttpPut request = new HttpPut(url); String contentMD5 = ""; if (checkDigest) { contentMD5 = SignUtils.md5file(localFile); } Date date = new Date(); String dateString = DateUtils.formatDate(date, DateUtils.PATTERN_RFC1036); String authorization = SignUtils.sign(accessKey, secretKey, "PUT", contentMD5, contentType, dateString, resource, protocols, metas); request.addHeader("Date", dateString); request.addHeader("Authorization", authorization); if (StringUtils.isNotBlank(contentMD5)) { request.addHeader("Content-MD5", contentMD5); } if (StringUtils.isNotBlank(contentType)) { request.addHeader("Content-Type", contentType); } marshallProtocol(request, protocols); marshallProtocol(request, metas); printRequest(request); FileEntity fileEntity = new FileEntity(localFile, contentType); request.setEntity(fileEntity); HttpResponse response = httpClient.execute(request); printResponse(response); HttpEntity entity = response.getEntity(); if (entity != null && entity.getContentLength() > 0) { logger.info("entity:
" + EntityUtils.toString(response.getEntity())); } logger.info(""); logger.info(""); } /** * * * @param bucket * @param objectName * @param versionId * @param protocols * @param metas * @throws IOException */ public static void getObject(String bucket, String objectName, String versionId, Map<String, String> protocols, Map<String, String> metas, Map<String, String> queries) throws IOException { HttpClient httpClient = new DefaultHttpClient(); String query = marshallQuery(queries); String url = "http://" + bucket + ".s3.amazonaws.com/" + objectName + query; HttpGet request = new HttpGet(url); Date date = new Date(); String dateString = DateUtils.formatDate(date, DateUtils.PATTERN_RFC1036); String resource = "/" + bucket + "/" + objectName + query; String authorization = SignUtils.sign(accessKey, secretKey, "GET", "", "", dateString, resource, protocols, metas); request.addHeader("Date", dateString); request.addHeader("Authorization", authorization); marshallProtocol(request, protocols); marshallProtocol(request, metas); printRequest(request); HttpResponse response = httpClient.execute(request); printResponse(response); HttpEntity entity = response.getEntity(); if (entity != null && entity.getContentLength() > 0) { logger.info("entity:
" + EntityUtils.toString(response.getEntity())); } logger.info(""); } public static void headObject(String bucket, String objectName, String versionId, Map<String, String> protocols) throws IOException { HttpClient httpClient = new DefaultHttpClient(); String url = "http://" + bucket + ".s3.amazonaws.com/" + objectName; HttpHead request = new HttpHead(url); Date date = new Date(); String dateString = DateUtils.formatDate(date, DateUtils.PATTERN_RFC1036); String authorization = SignUtils.sign(accessKey, secretKey, "HEAD", "", "", dateString, "/" + bucket + "/" + objectName, null, null); request.addHeader("Date", dateString); request.addHeader("Authorization", authorization); marshallProtocol(request, protocols); printRequest(request); HttpResponse response = httpClient.execute(request); printResponse(response); HttpEntity entity = response.getEntity(); if (entity != null && entity.getContentLength() > 0) { logger.info("entity:" + EntityUtils.toString(response.getEntity())); } } /** * * * @param bucket * @param objectName * @param versionId * @throws Exception */ public static void deleteObject(String bucket, String objectName, String versionId) throws Exception { HttpClient httpClient = new DefaultHttpClient(); String url = "http://" + bucket + ".s3.amazonaws.com/" + URLEncoder.encode(objectName, "UTF-8"); String resource = "/" + bucket + "/" + objectName; if (StringUtils.isNotBlank(versionId)) { url += "?versionId=" + versionId; resource += "?versionId=" + versionId; } HttpDelete request = new HttpDelete(url); Date date = new Date(); String dateString = DateUtils.formatDate(date, DateUtils.PATTERN_RFC1036); String authorization = SignUtils.sign(accessKey, secretKey, "DELETE", "", "", dateString, resource, null, null); request.addHeader("Date", dateString); request.addHeader("Authorization", authorization); printRequest(request); HttpResponse response = httpClient.execute(request); printResponse(response); HttpEntity entity = response.getEntity(); if (entity != null && entity.getContentLength() > 0) { logger.info("entity:" + EntityUtils.toString(response.getEntity())); } } /** * * * @param request */ private static void printRequest(HttpRequest request) { logger.info(request.getRequestLine()); printHeader(request.getAllHeaders()); logger.info(""); } /** * * * @param response */ private static void printResponse(HttpResponse response) { logger.info(response.getStatusLine()); printHeader(response.getAllHeaders()); } /** * HTTP * * @param headers */ private static void printHeader(Header[] headers) { for (Header header : headers) { logger.info(header); } } /** * query * * @param queries * @return */ private static String marshallQuery(Map<String, String> queries) { String query = ""; if (queries != null) { boolean first = true; for (Map.Entry<String, String> entry : queries.entrySet()) { query += (first ? "?" : "&") + entry.getKey() + "=" + entry.getValue(); first = false; } } return query; } /** * * * @param request * @param protocols */ private static void marshallProtocol(HttpRequest request, Map<String, String> protocols) { if (protocols != null) { for (Map.Entry<String, String> entry : protocols.entrySet()) { request.addHeader(entry.getKey(), entry.getValue()); } } } }

 
 
package amazons3;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;

import sun.misc.BASE64Encoder;

public final class SignUtils {

	/**
	 * MD5 
	 * 
	 * @param file
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws IOException
	 */
	public static String md5file(File file) throws NoSuchAlgorithmException, IOException {
		MessageDigest messageDigest = MessageDigest.getInstance("MD5");
		BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
		byte[] buf = new byte[1024 * 100];
		int p = 0;
		while ((p = in.read(buf)) != -1) {
			messageDigest.update(buf, 0, p);
		}
		in.close();
		byte[] digest = messageDigest.digest();

		BASE64Encoder encoder = new BASE64Encoder();
		return encoder.encode(digest);
	}

	public static String simpleMd5File(File file) throws IOException {
		return DigestUtils.md5Hex(FileUtils.readFileToByteArray(file));
	}

	/**
	 *  
	 * 
	 * @param httpVerb
	 * @param contentMD5
	 * @param contentType
	 * @param date
	 * @param resource
	 * @param metas
	 * @return
	 */
	public static String sign(String accessKey, String secretKey, String httpVerb, String contentMD5, String contentType, String date, String resource,
			Map<String, String> protocols, Map<String, String> metas) {
		return "AWS" + " " + accessKey + ":" + hmac(accessKey, secretKey, httpVerb, contentMD5, contentType, date, resource, protocols, metas);
	}

	public static String hmac(String accessKey, String secretKey, String httpVerb, String contentMD5, String contentType, String date, String resource,
			Map<String, String> protocols, Map<String, String> metas) {

		String stringToSign = httpVerb + "
" + StringUtils.trimToEmpty(contentMD5) + "
" + StringUtils.trimToEmpty(contentType) + "
" + StringUtils.trimToEmpty(date) + "
"; if (metas != null) { for (Map.Entry<String, String> entity : metas.entrySet()) { stringToSign += StringUtils.trimToEmpty(entity.getKey()) + ":" + StringUtils.trimToEmpty(entity.getValue()) + "
"; } } if (protocols != null) { for (Map.Entry<String, String> entity : protocols.entrySet()) { if (entity.getKey().startsWith("x-amz-")) { stringToSign += StringUtils.trimToEmpty(entity.getKey()) + ":" + StringUtils.trimToEmpty(entity.getValue()) + "
"; } } } stringToSign += resource; try { Mac mac = Mac.getInstance("HmacSHA1"); byte[] keyBytes = secretKey.getBytes("UTF8"); SecretKeySpec signingKey = new SecretKeySpec(keyBytes, "HmacSHA1"); mac.init(signingKey); byte[] signBytes = mac.doFinal(stringToSign.getBytes("UTF8")); String signature = encodeBase64(signBytes); return signature; } catch (Exception e) { throw new RuntimeException("MAC CALC FAILED."); } } public static String encodeBase64(byte[] data) { String base64 = new String(Base64.encodeBase64(data)); if (base64.endsWith("\r
")) base64 = base64.substring(0, base64.length() - 2); if (base64.endsWith("
")) base64 = base64.substring(0, base64.length() - 1); return base64; } }