From 1e897aa3c307df14bdbec1d5b690e8c187a88544 Mon Sep 17 00:00:00 2001
From: Nikita Zinkevich <n.zinkevich@yadro.com>
Date: Fri, 6 Dec 2024 15:01:16 +0300
Subject: [PATCH] [#170] Updated docs and configuration of archive section

Signed-off-by: Nikita Zinkevich <n.zinkevich@yadro.com>
---
 docs/api.md                      | 37 +++++++++++++++++---------------
 internal/handler/download.go     |  4 ++--
 internal/handler/handler.go      |  2 +-
 internal/handler/handler_test.go |  2 +-
 4 files changed, 24 insertions(+), 21 deletions(-)

diff --git a/docs/api.md b/docs/api.md
index e59956a..d099915 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -1,11 +1,11 @@
 # HTTP Gateway Specification
 
-| Route                                           | Description                                  |
-|-------------------------------------------------|----------------------------------------------|
-| `/upload/{cid}`                                 | [Put object](#put-object)                    |
-| `/get/{cid}/{oid}`                              | [Get object](#get-object)                    |
-| `/get_by_attribute/{cid}/{attr_key}/{attr_val}` | [Search object](#search-object)              |
-| `/zip/{cid}/{prefix}`                           | [Download objects in archive](#download-zip) |
+| Route                                           | Description                                      |
+|-------------------------------------------------|--------------------------------------------------|
+| `/upload/{cid}`                                 | [Put object](#put-object)                        |
+| `/get/{cid}/{oid}`                              | [Get object](#get-object)                        |
+| `/get_by_attribute/{cid}/{attr_key}/{attr_val}` | [Search object](#search-object)                  |
+| `/zip/{cid}/{prefix}`, `/tar/{cid}/{prefix}`    | [Download objects in archive](#download-archive) |
 
 **Note:** `cid` parameter can be base58 encoded container ID or container name
 (the name must be registered in NNS, see appropriate section in [nns.md](./nns.md)).
@@ -56,12 +56,14 @@ Upload file as object with attributes to FrostFS.
 
 ###### Headers
 
-| Header                 | Description                                                                                                                                        |
-|------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------|
-| Common headers         | See [bearer token](#bearer-token).                                                                                                                 |
-| `X-Attribute-System-*` | Used to set system FrostFS object attributes <br/> (e.g. use "X-Attribute-System-Expiration-Epoch" to set `__SYSTEM__EXPIRATION_EPOCH` attribute). |
-| `X-Attribute-*`        | Used to set regular object attributes <br/> (e.g. use "X-Attribute-My-Tag" to set `My-Tag` attribute).                                             |
-| `Date`                 | This header is used to calculate the right `__SYSTEM__EXPIRATION` attribute for object. If the header is missing, the current server time is used. |
+| Header                 | Description                                                                                                                                                                                                                                                                                                                 |
+|------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| Common headers         | See [bearer token](#bearer-token).                                                                                                                                                                                                                                                                                          |
+| `X-Attribute-System-*` | Used to set system FrostFS object attributes <br/> (e.g. use "X-Attribute-System-Expiration-Epoch" to set `__SYSTEM__EXPIRATION_EPOCH` attribute).                                                                                                                                                                          |
+| `X-Attribute-*`        | Used to set regular object attributes <br/> (e.g. use "X-Attribute-My-Tag" to set `My-Tag` attribute).                                                                                                                                                                                                                      |
+| `X-Explode-Archive`    | If set, gate tries to read files from uploading `tar` archive and creates an object for each file in it. Uploading `tar` could be compressed via Gzip by setting a `Content-Encoding` header. Sets a `FilePath` attribute as a relative path from archive root and a `FileName` as the last path element of the `FilePath`. |
+| `Content-Encoding`     | If set and value is `gzip`, gate will handle uploading file as a `Gzip` compressed `tar` file.                                                                                                                                                                                                                              |
+| `Date`                 | This header is used to calculate the right `__SYSTEM__EXPIRATION` attribute for object. If the header is missing, the current server time is used.                                                                                                                                                                          |
 
 There are some reserved headers type of `X-Attribute-FROSTFS-*` (headers are arranged in descending order of priority):
 
@@ -269,9 +271,9 @@ If more than one object is found, an arbitrary one will be used to get attribute
 | 400    | Some error occurred during operation. |
 | 404    | Container or object not found.        |
 
-## Download zip
+## Download archive
 
-Route: `/zip/{cid}/{prefix}`
+Route: `/zip/{cid}/{prefix}`, `/tar/{cid}/{prefix}`
 
 | Route parameter | Type      | Description                                             |
 |-----------------|-----------|---------------------------------------------------------|
@@ -282,12 +284,13 @@ Route: `/zip/{cid}/{prefix}`
 
 #### GET
 
-Find objects by prefix for `FilePath` attributes. Return found objects in zip archive.
+Find objects by prefix for `FilePath` attributes. Return found objects in zip or tar archive.
 Name of files in archive sets to `FilePath` attribute of objects.
 Time of files sets to time when object has started downloading.
-You can download all files in container that have `FilePath` attribute by `/zip/{cid}/` route.
+You can download all files in container that have `FilePath` attribute by `/zip/{cid}/` or
+`/tar/{cid}/` route.
 
-Archive can be compressed (see http-gw [configuration](gate-configuration.md#zip-section)).
+Archive can be compressed (see http-gw [configuration](gate-configuration.md#archive-section)).
 
 ##### Request
 
diff --git a/internal/handler/download.go b/internal/handler/download.go
index 4641052..d5fac23 100644
--- a/internal/handler/download.go
+++ b/internal/handler/download.go
@@ -134,7 +134,7 @@ func (h *Handler) getZipResponseWriter(ctx context.Context, log *zap.Logger, res
 
 func (h *Handler) createZipFile(zw *zip.Writer, obj *object.Object) (io.Writer, error) {
 	method := zip.Store
-	if h.config.ZipCompression() {
+	if h.config.ArchiveCompression() {
 		method = zip.Deflate
 	}
 
@@ -177,7 +177,7 @@ func (h *Handler) getTarResponseWriter(ctx context.Context, log *zap.Logger, res
 		defer resSearch.Close()
 
 		compressionLevel := gzip.NoCompression
-		if h.config.ZipCompression() {
+		if h.config.ArchiveCompression() {
 			compressionLevel = gzip.DefaultCompression
 		}
 
diff --git a/internal/handler/handler.go b/internal/handler/handler.go
index 3d2b95d..4e23c3b 100644
--- a/internal/handler/handler.go
+++ b/internal/handler/handler.go
@@ -28,7 +28,7 @@ import (
 
 type Config interface {
 	DefaultTimestamp() bool
-	ZipCompression() bool
+	ArchiveCompression() bool
 	ClientCut() bool
 	IndexPageEnabled() bool
 	IndexPageTemplate() string
diff --git a/internal/handler/handler_test.go b/internal/handler/handler_test.go
index 4784708..53c9739 100644
--- a/internal/handler/handler_test.go
+++ b/internal/handler/handler_test.go
@@ -66,7 +66,7 @@ func (c *configMock) DefaultTimestamp() bool {
 	return false
 }
 
-func (c *configMock) ZipCompression() bool {
+func (c *configMock) ArchiveCompression() bool {
 	return false
 }