/** @see com.amazonaws.http.HttpResponseHandler#handle(com.amazonaws.http.HttpResponse) */ public AmazonWebServiceResponse<S3Object> handle(HttpResponse response) throws Exception { /* * TODO: It'd be nice to set the bucket name and key here, but the * information isn't easy to pull out of the response/request * currently. */ S3Object object = new S3Object(); AmazonWebServiceResponse<S3Object> awsResponse = parseResponseMetadata(response); if (response.getHeaders().get(Headers.REDIRECT_LOCATION) != null) { object.setRedirectLocation(response.getHeaders().get(Headers.REDIRECT_LOCATION)); } ObjectMetadata metadata = object.getObjectMetadata(); populateObjectMetadata(response, metadata); boolean hasServerSideCalculatedChecksum = !ServiceUtils.isMultipartUploadETag(metadata.getETag()); boolean responseContainsEntireObject = response.getHeaders().get("Content-Range") == null; if (hasServerSideCalculatedChecksum && responseContainsEntireObject) { byte[] expectedChecksum = BinaryUtils.fromHex(metadata.getETag()); object.setObjectContent( new S3ObjectInputStream( new ChecksumValidatingInputStream( response.getContent(), expectedChecksum, object.getBucketName() + "/" + object.getKey()), response.getHttpRequest())); } else { object.setObjectContent( new S3ObjectInputStream(response.getContent(), response.getHttpRequest())); } awsResponse.setResult(object); return awsResponse; }
/* (non-Javadoc) * @see com.amazonaws.http.HttpResponseHandler#handle(com.amazonaws.http.HttpResponse) */ public AmazonWebServiceResponse<String> handle(HttpResponse response) throws Exception { AmazonWebServiceResponse<String> awsResponse = parseResponseMetadata(response); int bytesRead; byte[] buffer = new byte[1024]; StringBuilder builder = new StringBuilder(); InputStream content = response.getContent(); while ((bytesRead = content.read(buffer)) > 0) { builder.append(new String(buffer, 0, bytesRead)); } awsResponse.setResult(builder.toString()); return awsResponse; }
@Override public AmazonServiceException handle(HttpResponse httpResponse) throws XMLStreamException { final InputStream is = httpResponse.getContent(); String xmlContent = null; /* * We don't always get an error response body back from S3. When we send * a HEAD request, we don't receive a body, so we'll have to just return * what we can. */ if (is == null || httpResponse.getRequest().getHttpMethod() == HttpMethodName.HEAD) { return createExceptionFromHeaders(httpResponse, null); } String content = null; try { content = IOUtils.toString(is); } catch (IOException ioe) { if (log.isDebugEnabled()) log.debug("Failed in parsing the error response : ", ioe); return createExceptionFromHeaders(httpResponse, null); } /* * XMLInputFactory is not thread safe and hence it is synchronized. * Reference : * http://itdoc.hitachi.co.jp/manuals/3020/30203Y2210e/EY220140.HTM */ XMLStreamReader reader; synchronized (xmlInputFactory) { reader = xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(content.getBytes(UTF8))); } try { /* * target depth is to determine if the XML Error response from the * server has any element inside <Error> tag have child tags. * Parsing such tags is not supported now. target depth is * incremented for every start tag and decremented after every end * tag is encountered. */ int targetDepth = 0; final AmazonS3ExceptionBuilder exceptionBuilder = new AmazonS3ExceptionBuilder(); exceptionBuilder.setErrorResponseXml(content); exceptionBuilder.setStatusCode(httpResponse.getStatusCode()); boolean hasErrorTagVisited = false; while (reader.hasNext()) { int event = reader.next(); switch (event) { case XMLStreamConstants.START_ELEMENT: targetDepth++; String tagName = reader.getLocalName(); if (targetDepth == 1 && !S3ErrorTags.Error.toString().equals(tagName)) return createExceptionFromHeaders( httpResponse, "Unable to parse error response. Error XML Not in proper format." + content); if (S3ErrorTags.Error.toString().equals(tagName)) { hasErrorTagVisited = true; } continue; case XMLStreamConstants.CHARACTERS: xmlContent = reader.getText(); if (xmlContent != null) xmlContent = xmlContent.trim(); continue; case XMLStreamConstants.END_ELEMENT: tagName = reader.getLocalName(); targetDepth--; if (!(hasErrorTagVisited) || targetDepth > 1) { return createExceptionFromHeaders( httpResponse, "Unable to parse error response. Error XML Not in proper format." + content); } if (S3ErrorTags.Message.toString().equals(tagName)) { exceptionBuilder.setErrorMessage(xmlContent); } else if (S3ErrorTags.Code.toString().equals(tagName)) { exceptionBuilder.setErrorCode(xmlContent); } else if (S3ErrorTags.RequestId.toString().equals(tagName)) { exceptionBuilder.setRequestId(xmlContent); } else if (S3ErrorTags.HostId.toString().equals(tagName)) { exceptionBuilder.setExtendedRequestId(xmlContent); } else { exceptionBuilder.addAdditionalDetail(tagName, xmlContent); } continue; case XMLStreamConstants.END_DOCUMENT: return exceptionBuilder.build(); } } } catch (Exception e) { if (log.isDebugEnabled()) log.debug("Failed in parsing the error response : " + content, e); } return createExceptionFromHeaders(httpResponse, content); }