HBOX Wiki

HBox Java Upload codes

2014.02.22 01:17

호스트웨이 조회 수:7617

이 페이지는 Apache common 라이브러리로 HBox에 파일을 업로드하는 방법을 설명합니다.

package hwk;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;

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

import org.apache.commons.codec.binary.Base64;

public class HBoxUpload {
	String baseHost = "hbox.a3c.co.kr";
	
	public InputStream getDownloadStream(String bucket,
			String objectKey,
			String accessKey,
			String secretKey)throws Exception{
		String url = getDownloadUrl(bucket, objectKey, accessKey, secretKey, 30);
		URL downloadUrl = new URL(url);

		URLConnection conn = downloadUrl.openConnection();
		
		return conn.getInputStream();
	}
	
	public String getDownloadUrl(String bucket,
			String objectKey,
			String accessKey,
			String secretKey,
			int expiresInSeconds)throws Exception{
		
		String method = "GET";
		String path = "/"+ bucket +"/"+objectKey ;
		Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
		long secondsSinceEpoch = calendar.getTimeInMillis() / 1000L + expiresInSeconds;
		String expires =Long.toString(secondsSinceEpoch); 
		String canonicalString = getCanonicalString(method, path, null, null, expires, null, null);
		Mac mac = setKey(secretKey);
		String signature = URLEncoder.encode(sign(mac, canonicalString), "UTF8");
		
		StringBuffer url = new StringBuffer();
		url.append("http://").append(bucket).append(".").append(baseHost).append("/").append(objectKey);
		url.append("?Signature=").append(signature).append("&Expires=").append(expires).append("&AWSAccessKeyId=").append(accessKey);
		
		return url.toString();
	}
	
	public void uploadStream(String bucket,
			String objectKey, 
			InputStream stream,
			long streamLength,
			String contentType,
			String method,
			String contentMd5,
			List amzHeaders,
			String accessKey,
			String secretKey)throws Exception{
		String expires = null;
    	String hostName = bucket+"."+baseHost;

    	Mac mac = setKey(secretKey);
    	
    	String url = "/"+objectKey ;
    	
    	
		String fmt = "EEE, dd MMM yyyy HH:mm:ss ";
		SimpleDateFormat df = new SimpleDateFormat(fmt, Locale.US);
		df.setTimeZone(TimeZone.getTimeZone("GMT"));
		
		// Data needed for signature
		String date = df.format(new Date()) + "GMT";
		
		String path = "/"+ bucket +"/"+objectKey ;
		String canonicalString = getCanonicalString(method, path, contentMd5, contentType, expires, date, amzHeaders);

		String signature = sign(mac, canonicalString);
    	
    	Socket socket = new Socket(hostName, 80);
    	OutputStream os = socket.getOutputStream();
    	ByteArrayOutputStream baos = new ByteArrayOutputStream();
    	OutputStreamWriter osw = new OutputStreamWriter(baos);
    	
    	osw.write(method);osw.write(" ");osw.write(url);osw.write(" HTTP/1.1\n");
    	osw.write("Host :");osw.write(hostName);osw.write("\n");
    	if (contentType != null){
    		osw.write("Content-Type :");osw.write(contentType);osw.write("\n");
    	}
    	if (contentMd5 != null){
    		osw.write("Content-MD5 :");osw.write(contentMd5);osw.write("\n");
    		
    	}
    	osw.write("Date :");osw.write(date);osw.write("\n");
    	osw.write("Authorization : AWS ");osw.write(accessKey);osw.write(":");osw.write(signature);osw.write("\n");
    	osw.write("Content-Length :");osw.write(Long.toString(streamLength));osw.write("\n");
    	osw.write("\n");
    	osw.close();
    	
    	os.write(baos.toByteArray());
    	
    	int buflength = 1024;
    	byte[] buffer = new byte[buflength];
    	int nbytethistime = 0;
    	
    	long nbyteleft = streamLength;
    	
    	while(nbyteleft > 0){
    		nbytethistime = stream.read(buffer);
    		
    		if (nbytethistime < 1)
    		{
    			break;    			
    		}
    		nbyteleft -= nbytethistime;
    		os.write(buffer, 0, nbytethistime);
    	}
    	
    	baos = new ByteArrayOutputStream();
    	InputStream is = socket.getInputStream();
    	while((nbytethistime = is.read(buffer)) > 0){
    		baos.write(buffer,0,nbytethistime);
    		
    	}
    	baos.close();
    	is.close();
    	os.close();
    	String response = baos.toString("UTF8");
    	if (response.indexOf("200 OK") < 1){
    		System.out.println(response);
    		throw new Exception("upload error");
    	}
    }

    private Mac setKey(String AWSSecretKey)throws Exception
    {
			Mac mac = Mac.getInstance("HmacSHA1");
			byte[] keyBytes = AWSSecretKey.getBytes("UTF8");
			SecretKeySpec signingKey = new SecretKeySpec(keyBytes, "HmacSHA1");
			mac.init(signingKey);
			
			return mac;
    	
    }    
    
    private String getCanonicalString(String method, String path,
            String content_md5 ,
            String content_type,
            String expires,
            String date,
            List amz_headers){
    	
    	
    	StringBuffer canonicalString = new StringBuffer();
	    canonicalString.append( method ).append("\n");
	    if (content_md5 != null){
	        canonicalString.append( content_md5 );
	    }
	    canonicalString.append( "\n" );
	    if (content_type != null){
	    	canonicalString.append( content_type );
	    }
	    canonicalString.append( "\n" );
	    
	    if (expires != null){
	        canonicalString.append( expires );
	    }else if( date != null){
	        canonicalString.append( date );
	    }
	    canonicalString.append( "\n" );
	    
	    if (amz_headers != null){
		    for( String[] kv : amz_headers){
		        canonicalString.append(kv[0]).append(":").append(kv[1]).append("\n");
		    }
	    }        
		    
	    canonicalString.append( path);
    		    
    		    
    	return canonicalString.toString();
    }
    private String sign(Mac mac, String canonicalString)throws Exception 
    {
			// Signed String must be BASE64 encoded.
			byte[] signBytes = mac.doFinal(canonicalString.getBytes("UTF8"));
			String signature = Base64.encodeBase64String(signBytes);
			return signature;
    	
    }
}



이 코드를 사용하는 테스트 코드는 아래와 같습니다.


package hwk;

import static org.junit.Assert.*;

import hwk.HBoxUpload;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.List;

import org.junit.Test;

public class test_HBoxUpload {
	
	@Test
	public void getDownloadUrl()throws Exception{
		String bucket = "bucket4";
		String objectKey = "flazr.tar.gz";
		
		String accessKey = "JJ0Y0DEV7YY9U3QBDY0Y";
		String secretKey = "B4tuiB6H7/hCG4eiwXvUNxoZY6+vk+FxFTTpNF2l";
		
		InputStream is = new HBoxUpload().getDownloadStream(bucket, objectKey, accessKey, secretKey);
		
		byte[] buf = new byte[1024];
		int nbytethistime = 0;
		FileOutputStream fos = new FileOutputStream("/home/hsnam/flazr.tar.gz");
		while((nbytethistime = is.read(buf))> 0){
			fos.write(buf,0, nbytethistime);			
		}
		fos.close();
		is.close();
		
	}

	@Test
	public void uploadStream()throws Exception {
		File source = new File("c:\\test\\flazr.tar.gz");
		String bucket = "bucket4";
		String objectKey = "flazr.tar.gz";
		InputStream stream = new FileInputStream(source);
		long streamLength = source.length();
		String contentType = "image/jpg";
		String method = "PUT";
		String contentMd5 = null;
		List amzHeaders = null;
		String accessKey = "JJ0Y0DEV7YY9U3QBDY0Y";
		String secretKey = "B4tuiB6H7/hCG4eiwXvUNxoZY6+vk+FxFTTpNF2l";	
		
		new HBoxUpload().uploadStream(bucket,
				objectKey, 
				stream,
				streamLength,
				contentType,
				method,
				contentMd5,
				amzHeaders,
				accessKey,
				secretKey);
	}

}