Skip to content

BlackGlory/refile

Repository files navigation

Refile

提供基于HTTP的文件管理服务, 受到IPFS启发.

Refile的文件管理是基于内容寻址和引用计数进行的, 通过Refile上传的文件会失去它的文件名和MIME类型.

Quickstart

docker run \
  --detach \
  --publish 8080:8080 \
  blackglory

Install

从源代码运行

git clone https://github.com/BlackGlory
cd log
yarn install
yarn build
yarn bundle
yarn --silent start

从源代码构建

git clone https://github.com/BlackGlory
cd refile
yarn install
yarn docker:build

Recipes

docker-compose.yml

version: '3.8'

services:
  refile:
    image: 'blackglory'
    restart: always
    volumes:
      - 'refile-database:/database'
      - 'reifle-storage:/storage'
    ports:
      - '8080:8080'

volumes:
  refile-database:
  refile-storage:

API

所有API中的namespace和id都需要满足此正则表达式: ^[a-zA-Z0-9\.\-_]{0,255}$

upload file

PUT /files/<hash>

上传文件.

上传文件时需要提供三个参数:

  • file: 需要上传的二进制文件, 由FormData的file字段提供. 一次只能上传一个文件, 表单的编码必须为multipart/form-data.
  • hashList: 分段hash列表, 由ForumData的多个名为hashList的同名字段提供. 将文件按512KiB为切割点进行分段, 计算出每段内容的SHA-256, 将其16进制字符串形式保存为有序数组, 该数组即为文件的hashList.
  • hash: 文件的最终hash, 在URL里提供. 将hashList的字符串连接起来, 计算其SHA-256, 其16进制字符串形式即为文件的最终hash.

被上传的文件必须先通过set reference建立相应的引用关系. 如果文件的引用数为零, 上传会被拒绝. 上传参数设计得如此复杂是为了能够尽早拒绝错误和重复的文件.

上传的文件原本不存在时, 返回HTTP状态码201. 上传的文件原本就已经存在时, 返回HTTP状态码204. 上传的文件的hash校验错误时, 返回HTTP状态码409.

get file info

GET /files/<hash>

获取与资源相关的信息.

返回JSON:

{
  hash: string
  location: string | null // 未上传时, location为null
  references: number
}

Example

curl
curl "http://localhost:8080/files/$hash"
JavaScript
await fetch(`http://localhost:8080/files/${hash}`)
  .then(res => res.json())

get file location

GET /files/<hash>/location

通过hash获取文件的location. 它与get file info的功能重合, 但性能更好.

如果location存在, 返回HTTP状态码200, 以文本形式返回location. 如果location不存在, 返回HTTP状态码404.

Example

curl
curl "http://localhost:8080/files/$hash/location"
JavaScript
await fetch(`http://localhost:8080/files/${hash}/location`)
  .then(res => res.text())

set reference

PUT /namespaces/<namespace>/items/<id>/files/<hash>

设置文件hash与引用的关系.

Example

curl
curl \
  --request PUT \
  "http://localhost:8080/namespaces/$namespace/items/$id/files/$hash"
JavaScript
await fetch(`http://localhost:8080/namespaces/${namespace}/items/${id}/files/${hash}`)

remove reference

DELETE /namespaces/<namespace>/items/<id>/files/<hash>

移除文件hash与引用的关系.

Example

curl
curl \
  --request DELETE \
  "http://localhost:8080/namespaces/$namespace/items/$id/files/$hash"
JavaScript
await fetch(`http://localhost:8080/namespaces/${namespace}/items/${id}/files/${hash}`, {
  method: 'DELETE'
})

remove references by item id

DELETE /namespaces/<namespace>/items/<id>

移除特定项目的全部引用.

Example

curl
curl \
  --request DELETE \
  "http://localhost:8080/namespaces/$namespace/items/$id"
JavaScript
await fetch(`http://localhost:8080/namespaces/${namespace}/items/${id}`, {
  method: 'DELETE'
})

remove references by namespace

DELETE /namespaces/<namespace>

删除特定命名空间下的全部引用.

Example

curl
curl \
  --request DELETE \
  "http://localhost:8080/namespaces/$namespace"
JavaScript
await fetch(`http://localhost:8080/namespaces/${namespace}`, {
  method: 'DELETE'
})

get all namespaces

GET /namespaces

获取所有命名空间.

返回JSON:

string[]

Example

curl
curl 'http://localhost:8080/namespaces'
JavaScript
await fetch('http://localhost:8080/namespaces')
  .then(res => res.json())

get all item ids

GET /namespaces/<namespace>/items

获取特定命名空间下的所有项目id列表.

返回JSON:

string[]

Example

curl
curl "http://localhost:8080/namespaces/$namespace/items"
JavaScript
await fetch(`http://localhost:8080/namespaces/${namespace}/items`)
  .then(res => res.json())

get file hashes by item id

GET /namespaces/<namespace>/items/<id>/files

获取与特定引用相关联的文件hash列表.

返回JSON:

string[]

Example

curl
curl "http://localhost:8080/namespaces/$namespace/items/$id/files"
JavaScript
await fetch(`http://localhost:8080/namespace/${namespace}/items/${id}/files`)
  .then(res => res.json())

get item ids by file hash

GET /files/<hash>/namespaces/<namespace>/items

获取特定命名空间下与特定文件相关的项目id列表.

返回JSON:

string[]

Example

curl
curl "http://localhost:8080/files/$hash/namespaces/$namespace/items"
JavaScript
await fetch(`http://localhost:8080/files/${hash}/namespaces/${namespace}/items`)
  .then(res => res.json())

collect garbage

POST /collect-garbage

执行垃圾回收, 将引用数为0的文件从存储中删除.

Example

curl
curl 'http://localhost:8080/collect-garbage'
JavaScript
await fetch('http://localhost:8080/collect-garbage', {
  method: 'POST'
})

环境变量

REFILE_HOST, REFILE_PORT

通过环境变量REFILE_HOSTREFILE_PORT决定服务器监听的地址和端口, 默认值为localhost8080.

客户端