private void outputOwnerInfo(XMLStructuredOutput out, String name) { out.beginObject(name); out.property("ID", "initiatorId"); out.property(RESPONSE_DISPLAY_NAME, "initiatorName"); out.endObject(); }
@Override public StructuredOutput beginResult() { return beginOutput("result"); }
@Override public void endResult() { endOutput(); }
out.beginOutput("ListPartsResult"); out.property(RESPONSE_BUCKET, bucket.getName()); out.property("Key", id); out.property("UploadId", uploadId); int maxParts = ctx.get("max-parts").asInt(0); out.property("StorageClass", "STANDARD"); out.property("PartNumberMarker", marker); if ((marker + maxParts) < uploadDir.list().length) { out.property("NextPartNumberMarker", marker + maxParts + 1); out.property("MaxParts", maxParts); out.property("IsTruncated", truncated); out.beginObject("Part"); out.property("PartNumber", part.getName()); out.property("LastModified", RFC822_INSTANT.format(Instant.ofEpochMilli(part.lastModified()))); try { out.property(HTTP_HEADER_NAME_ETAG, Files.hash(part, Hashing.md5()).toString()); } catch (IOException e) { Exceptions.ignore(e); out.property("Size", part.length()); out.endObject(); out.endOutput();
/** * Returns a list of at most the provided number of stored objects * * @param output the xml structured output the list of objects should be written to * @param limit controls the maximum number of objects returned * @param marker the key to start with when listing objects in a bucket * @param prefix limits the response to keys that begin with the specified prefix */ public void outputObjects(XMLStructuredOutput output, int limit, @Nullable String marker, @Nullable String prefix) { ListFileTreeVisitor visitor = new ListFileTreeVisitor(output, limit, marker, prefix); output.beginOutput("ListBucketResult", Attribute.set("xmlns", "http://s3.amazonaws.com/doc/2006-03-01/")); output.property("Name", getName()); output.property("MaxKeys", limit); output.property("Marker", marker); output.property("Prefix", prefix); try { Files.walkFileTree(file.toPath(), visitor); } catch (IOException e) { Exceptions.handle(e); } output.property("IsTruncated", limit > 0 && visitor.getCount() > limit); output.endOutput(); }
structuredOutput.beginOutput("CopyObjectResult"); structuredOutput.beginObject("LastModified"); structuredOutput.text(RFC822_INSTANT.format(object.getLastModifiedInstant())); structuredOutput.endObject(); structuredOutput.beginObject(HTTP_HEADER_NAME_ETAG); structuredOutput.text(etag(etag)); structuredOutput.endObject(); structuredOutput.endOutput(); signalObjectSuccess(ctx);
/** * Starts the output with the given root element and attributes * * @param rootElement the name of the root element of the generated document. * @param attr the attributes for the root element * @return the output itself for fluent method calls */ public StructuredOutput beginOutput(@Nonnull String rootElement, Attribute... attr) { if (opensCalled == 0) { try { hd.startDocument(); } catch (SAXException e) { throw Exceptions.handle(e); } } opensCalled++; beginObject(rootElement, attr); return this; }
/** * Adds a property to the current object. * <p> * This will create a property only if the specified data object is not null. * Else no property is created. * * @param name the name of the property * @param data the value of the property * @return the output itself for fluent method calls */ public StructuredOutput propertyIfFilled(@Nonnull String name, @Nullable Object data) { if (data != null) { property(name, data); } return this; }
/** * Closes the output and this XML document. */ public void endOutput() { endObject(); if (opensCalled-- == 1) { super.endResult(); try { hd.endDocument(); out.close(); } catch (SAXException | IOException e) { throw Exceptions.handle(e); } } }
/** * Can be used to generate the XML request. * * @return the an input which can be used to generate an XML document which is sent to the URL * @throws IOException in case of an IO error while sending the XML document */ public XMLStructuredOutput getOutput() throws IOException { return new XMLStructuredOutput(outcall.getOutput()); }
/** * Creates a {@link AbstractStructuredOutput.TagBuilder} used to fluently create the root element. * * @param rootElement name of the root element * @return a tag builder which can be used to build the root element */ @CheckReturnValue public TagBuilder buildBegin(@Nonnull String rootElement) { if (opensCalled == 0) { try { hd.startDocument(); } catch (SAXException e) { throw Exceptions.handle(e); } } opensCalled++; return buildObject(rootElement); }
/** * GET a list of all buckets * * @param ctx the context describing the current request */ private void listBuckets(WebContext ctx) { HttpMethod method = ctx.getRequest().method(); if (GET == method) { List<Bucket> buckets = storage.getBuckets(); Response response = ctx.respondWith(); response.setHeader(HTTP_HEADER_NAME_CONTENT_TYPE, CONTENT_TYPE_XML); XMLStructuredOutput out = response.xml(); out.beginOutput("ListAllMyBucketsResult", Attribute.set("xmlns", "http://s3.amazonaws.com/doc/2006-03-01/")); out.property("hint", "Goto: " + ctx.getBaseURL() + "/ui to visit the admin UI"); outputOwnerInfo(out, "Owner"); out.beginObject("Buckets"); for (Bucket bucket : buckets) { out.beginObject(RESPONSE_BUCKET); out.property("Name", bucket.getName()); out.property("CreationDate", RFC822_INSTANT.format(Instant.ofEpochMilli(bucket.getFile().lastModified()))); out.endObject(); } out.endObject(); out.endOutput(); } else { throw new IllegalArgumentException(ctx.getRequest().method().name()); } }
/** * Handles POST /bucket/id?uploads * * @param ctx the context describing the current request * @param bucket the bucket containing the object to upload * @param id name of the object to upload */ private void startMultipartUpload(WebContext ctx, Bucket bucket, String id) { Response response = ctx.respondWith(); Map<String, String> properties = Maps.newTreeMap(); for (String name : ctx.getRequest().headers().names()) { String nameLower = name.toLowerCase(); if (nameLower.startsWith("x-amz-meta-") || "content-md5".equals(nameLower) || "content-type".equals( nameLower) || "x-amz-acl".equals(nameLower)) { properties.put(name, ctx.getHeader(name)); response.addHeader(name, ctx.getHeader(name)); } } response.setHeader(HTTP_HEADER_NAME_CONTENT_TYPE, CONTENT_TYPE_XML); String uploadId = String.valueOf(uploadIdCounter.inc()); multipartUploads.add(uploadId); getUploadDir(uploadId).mkdirs(); XMLStructuredOutput out = response.xml(); out.beginOutput("InitiateMultipartUploadResult"); out.property(RESPONSE_BUCKET, bucket.getName()); out.property("Key", id); out.property("UploadId", uploadId); out.endOutput(); }
/** * Starts the output with the given root element. * * @param rootElement the name of the root element of the generated document. * @return the output itself for fluent method calls */ public StructuredOutput beginOutput(@Nonnull String rootElement) { if (opensCalled == 0) { try { hd.startDocument(); } catch (SAXException e) { throw Exceptions.handle(e); } } opensCalled++; beginObject(rootElement); return this; }
long numObjects = objectCount.inc(); if (numObjects <= limit) { output.beginObject("Contents"); output.property("Key", file.getName()); output.property("LastModified", S3Dispatcher.RFC822_INSTANT.format(object.getLastModifiedInstant())); output.property("Size", file.length()); output.property("StorageClass", "STANDARD"); output.property("ETag", getETag(file)); output.endObject(); } else { return FileVisitResult.TERMINATE;
@Override public StructuredOutput beginResult(String name) { return beginOutput(name); }