AWS S3 Multipart upload - Multipart upload initiation(2)

정호준·2022년 9월 22일
0

AWS

목록 보기
4/4

이번에는 실제 코드로 구현해보자.

Controller

    private final S3uploadService s3uploadService;

    @Autowired
    public S3uploadController(S3uploadService s3uploadService) {
        this.s3uploadService = s3uploadService;
    }

    @PostMapping("/upload")
    private ResponseEntity<String> createMultipartUpload(
            @RequestParam(name = "objectName") String objectName,
            @RequestParam(name = "file") MultipartFile multipartFile) {
        String result = s3uploadService.uploadFile(objectName, multipartFile);
        return ResponseEntity.status(HttpStatus.OK).body(result);
    }

Service

public String uploadFile(String objectName, MultipartFile file){
        String uploadId = createUploadId(objectName);
        String Etag = uploadPart(objectName, file, uploadId);
        String resultMsg = uploadComplete(objectName, uploadId, Etag);
        return resultMsg;
    }
    
private String createUploadId(String objectName) {
        String contentSha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
        String amzDate = createAmzDate();
        URI uri = URI.create("https://"+host+"/"+objectName+"?uploads");

        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", createSignature(contentSha256, amzDate, "POST", uri));
        headers.add("X-Amz-Content-Sha256", contentSha256);
        headers.add("X-Amz-Date", amzDate);

        RequestEntity<String> req = new RequestEntity<>(headers, HttpMethod.POST, uri);

        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> res = restTemplate.exchange(req, String.class);
        Document document;
        try {
           document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(res.getBody())));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        String uploadId = document.getElementsByTagName("UploadId").item(0).getTextContent();

        return uploadId;
    }

uploadFile 함수의 uploadPart와 uploadComplete는 이후에 구현한다.

첫 요청의 body는 공백이기에 checkSum은 공백의 Sha256 해시값인 e3b0... 이 된다.
서명은 오픈소스를 가져와 생성하였으나 S3 공식문서에서 서명 생성 방법을 제공하고 있어 해당 방법으로 해도 무방하다.

private String createSignature(String contentSha256, String amzDate, String method, URI uri){
        return Signer.builder()
                .awsCredentials(new AwsCredentials(accessKey, secretKey))
                .header("Host", host)
                .header("x-amz-content-sha256", contentSha256)
                .header("x-amz-date", amzDate)
                .region("ap-northeast-2")
                .buildS3(new HttpRequest(method, uri), contentSha256)
                .getSignature();
    }

0개의 댓글