MCPcopy Index your code
hub / github.com/ViBiOh/fibr

github.com/ViBiOh/fibr @v0.26.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.26.0 ↗ · + Follow
677 symbols 2,121 edges 103 files 161 documented · 24%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

fibr

Web File Browser and Manager.

  • Mobile-first interface, with light payload. Dark themed.
  • Thumbnail generation for image, PDF and video (with help of sidecars)
  • Exif extraction and displaying content on a map (with help of sidecars)
  • Works in pure HTML or with very little javascript for improved file upload
  • Support for basic filesystem and storage object
  • Can share directory with ou without password and with or without edit right.
  • Can communicate with sidecars in pure HTTP or AMQP
  • Can send webhooks for different event types to various providers
  • Basic search for files on metadatas without indexation
  • OpenTelemetry and pprof already built-in

Build codecov Quality Gate Status

Thanks to FontAwesome and Lucide for providing awesome svg icons.

I do it mostly for myself, but if you want to support me, you can star this project to give more visibility, that will bring more features =)

Concepts

Fibr aims to provide simple browsing of your filesystem. It's a single static binary with embedded html templates. No Javascript framework. HTTP and HTML have all we need.

Fibr aims to be compatible with the most platforms available, on a best-effort basis. Fibr itself is already compatible with x86_64, arm, arm64 architectures. But sidecars, which depends on system library, are not all ready yet.

Folder

Fibr browses files of given -data option folder (or S3 configuration), called "root folder". For security reason, it's not possible to browse parent.

It aims to be consistent accross all existing filesystem (block storage, object storage, etc.) and thus enforces filenames in lowercase, with no space or special character. At start, it walks every files and reports names that breaks its policy. It doesn't modify existing files unless you set -sanitizeOnStart option.

Fibr creates a .fibr folder in root folder for storing its metadata: shares' configuration, thumbnails and exif. If you want to stop using fibr or start with a fresh installation (e.g. regenerating thumbnails), you can delete this folder.

Sidecars

Fibr generates thumbnails of images, PDF and videos when these mime-types are detected and sidecars are provided. Sidecars are h2non/imaginary, ViBiOh/vith and ViBiOh/exas. Thumbnails are generated in WebP format, in their animated format for video thumbnail.

You can refer to these projects for installing and configuring them and set -thumbnailURL and -exifURL options.

Sidecars may have constraints regarding concurrent work (e.g. HLS conversion is a CPU-intensive task) or rate limit (e.g. geocoding can have rate-limiting). Call to these sidecars can be made with HTTP, which is not fault tolerant but easy to setup, or with an AMQP messaging, which is more resilient but more complex to setup. An easy-to-setup AMQP messaging instance can be done with CloudAMQP (I have no affiliation of any kind to this company, just a happy customer). When AMQP connection URI is provided, Fibr will use it as default communication protocol instead of HTTP.

HTTP Live Streaming

Fibr has a special treatment for videos, that can be very large sometimes. With the help of the vith sidecar, it can convert a video to its HLS version. It keeps the original video as is, and stores streamable version in the metadatas directory. It's a basic conversion into the appropriate format: no resolution, frame-per-second or any quality specifications are changed. Conversion is done where this two requirements are met altogether:

Chunk upload

Fibr supports uploading file by chunks or in one single request. This behavior is managed by the -chunkUpload option. In both cases, the file are written directly to the disk without buffering in memory. If you have a load-balancer in front of your Fibr instances, chunk upload requires that you enable sticky sessions because file are written locally to the -temporaryFolder before being written to the destination folder. On the other hand, when using one single request, you may need to tune the -readTimeout option to ensure that a slow connection with a big file can fullfil the request within the allowed timeout window.

In case of failure, when using one single request, all the upload is started from the beginning. In case of a chunk upload, the upload restarts from the failed chunk.

Security

Authentication is made with Basic Auth, compatible with all browsers and CLI tools such as curl. I strongly recommend configuring HTTPS in order to avoid exposing your credentials in plain text.

You can set -cert and -key options, it uses Golang's standard net/http#ServeTLS under the hood.

You can also configure a reverse proxy with Let's Encrypt to manage encryption, such as Traefik.

Sharing

You can share folders or just one file: it generates a short link that gain access to shared object and is considered as "root folder" with no parent escalation.

It can be password-protected: user has to enter password to see content (login is not used, you can leave it blank).

It can be read-only or with edit right. With edit-right, user can do anything as you, uploading, deleting, renaming, except generating new shares.

It can be created with expiration duration.

It's really useful for sharing files with friends. You don't need account at Google, Dropbox, iCloud or a mobile-app: a link and everyone can see and share content!

This is the main reason I've started to develop this app.

Webhook

You can register webhook listeners on folders and receive an HTTP notification when one of these event occurs:

  • create occurs when a directory is created
  • upload occurs when an item is uploaded
  • rename occurs when an item is renamed
  • delete occurs when an item is deleted
  • start occurs when fibr start and do something on an item
  • access occurs when content is accessed (directory browsing or just one file)
  • description occurs when a description is written on the story mode

The request sent is a POST with 15s timeout with the given payload structure:

{
  "time": "2021-02-25:12:32.244914+01:00",
  "url": "/eventual_share_id/path/to/payload.json",
  "item": {
    "date": "2021-08-10T19:31:28.952325533Z",
    "name": "payload.json",
    "pathname": "/path/to/payload.json",
    "isDir": false,
    "size": 177
  },
  "metadata": {
    "description": "content"
  },
  "type": "upload"
}

It will contains an extra key new with the same structure of item in case of a rename event, and a metadata map in case of access event, that contains a dump of HTTP Header (except Authorization).

The webhook can be recursive (all children folders will be notified too) for event choosen.

Security

Webhooks can be sent with an HTTP Signature if you configure the webhookSecret. It adds an Authorization header to the sent request that serves as an authentification mechanism for the receiver: if the signature is not valid, you should not trust the caller.

I've implemented a very simple function you can add to your receiver for checking it.

SEO

Fibr provides OpenGraph metadatas to have nice preview of link when shared. These metadatas don't leak any password-protected datas.

Users

You can start fibr with no user, with the -noAuth option. Although available, I don't recommend using it in public Internet. Anybody has access to the root folder for viewing, uploading, deleting or sharing content with anybody.

Users are set with the -authUsers option and are in the form [id]:[login]:[argon encoded has].

  • id is used to add profile to your user
  • login is the user for Basic Auth prompt
  • argon encoded hash is the password for Basic Auth prompt, encoded hash with argon2id

You can easily hash your password value with my own argon CLI or online

argon password

In order to work, your user must have admin profile sets with the -authProfiles option.

Metadatas

With help of different sidecars, Fibr can generate image, video and PDF thumbnails. These sidecars can be self hosted with ease. It can also extract and enrich content displayed by looking at EXIF Data, also with the help of a little sidecar. These behaviours are opt-out (if you remove the url of the service, Fibr will do nothing).

For the last mile, Fibr can try to reverse geocoding the GPS data found in EXIF, using Open Street Map. Self-hosting this kind of service can be complicated and calling a third-party party with such sensible datas is an opt-in decision.

Metrics

Fibr exposes a lot of metrics via OpenTelemetry gRPC mode. Common metrics are exposed: Golang statistics, HTTP statuses and response time, AMQP statuses and sidecars/metadatas actions.

Getting started

As a binary, without authentification

This is for local purpose with simple and hassle-free sharing in a private network.

go install github.com/ViBiOh/fibr/cmd/fibr@latest
fibr \
  -noAuth \
  -storageFileSystemDirectory "$(pwd)" \
  -thumbnailURL "" \
  -exifURL ""

As a single Docker container, with admin/password user

For long-living sharing with password and self-contained app in Docker, with no thumbnail generation or exif, configured with environment variables.

docker run -d \
  --publish 1080:1080/tcp \
  --name fibr \
  --volume ${PWD}:/data/ \
  --env FIBR_AUTH_USERS="1:$(htpasswd -nBb login password)" \
  --env FIBR_THUMBNAIL_URL="" \
  --env FIBR_EXIF_URL="" \
  vibioh/fibr

As a docker-compose / k8s stack

For prod-ready run with thumbnails generation of image, PDF and videos, this is the recommended approach.

You can inspire yourself from the docker-compose.yaml file I personnaly used. Beware of -authUsers option: hashed passwords contain dollar sign, which docker-compose tries to resolve as a shell variable, you must escape it.

make config-compose
docker compose --env-file ".env.compose" up

You'll find a Kubernetes exemple in the infra/ folder, using my app chart. My personnal k8s runs on arm64 and thumbnail converters are not yet ready for this architecture, so I use a mix of helm and docker-compose.yaml.

Endpoints

Usage

Fibr can be configured by passing CLI args described below or their equivalent as environment variable. If both the CLI and environment variable are defined, the CLI value is used.

Be careful when using the CLI, if someone list the processes on the system, they will appear in plain-text. I recommend passing secrets by environment variables: it's less easily visible.

```bash Usage of fibr: --address string [server] Listen address ${FIBR_ADDRESS} --amqpExifExchange string [amqpExif] Exchange name ${FIBR_AMQP_EXIF_EXCHANGE} (default "fibr") --amqpExifExclusive [amqpExif] Queue exclusive mode (for fanout exchange) ${FIBR_AMQP_EXIF_EXCLUSIVE} (default false) --amqpExifInactiveTimeout duration [amqpExif] When inactive during the given timeout, stop listening ${FIBR_AMQP_EXIF_INACTIVE_TIMEOUT} (default 0s) --amqpExifMaxRetry uint [amqpExif] Max send retries ${FIBR_AMQP_EXIF_MAX_RETRY} (default 3) --amqpExifQueue string [amqpExif] Queue name ${FIBR_AMQP_EXIF_QUEUE} (default "fibr.exif") --amqpExifRetryInterval duration [amqpExif] Interval duration when send fails ${FIBR_AMQP_EXIF_RETRY_INTERVAL} (default 1h0m0s) --amqpExifRoutingKey string [amqpExif] RoutingKey name ${FIBR_AMQP_EXIF_ROUTING_KEY} (default "exif_output") --amqpPrefetch int [amqp] Prefetch count for QoS ${FIBR_AMQP_PREFETCH} (default 1) --amqpThumbnailExchange string [amqpThumbnail] Exch

Extension points exported contracts — how you extend this code

WebhookManager (Interface)
(no doc) [6 implementers]
pkg/provider/interfaces.go
Starter (Interface)
(no doc) [4 implementers]
cmd/fibr/background.go
Renamer (Interface)
(no doc) [1 implementers]
pkg/sanitizer/sanitizer.go
SearchesOption (FuncType)
(no doc)
pkg/search/crud.go
GetNow (FuncType)
(no doc)
pkg/share/share.go
Crud (Interface)
go:generate mockgen -destination ../mocks/storage.go -package mocks -mock_names Storage=Storage github.com/ViBiOh/absto/ [3 …
pkg/provider/interfaces.go
MetadataManager (Interface)
(no doc) [3 implementers]
pkg/provider/metadata.go
ShareManager (Interface)
(no doc) [3 implementers]
pkg/provider/interfaces.go

Core symbols most depended-on inside this repo

error
called by 79
pkg/crud/crud.go
Get
called by 46
pkg/provider/interfaces.go
Name
called by 30
pkg/mocks/storage.go
Add
called by 22
pkg/search/crud.go
IsZero
called by 20
pkg/crud/model.go
Stat
called by 19
pkg/mocks/storage.go
String
called by 19
pkg/provider/share.go
List
called by 16
pkg/provider/interfaces.go

Shape

Method 377
Function 217
Struct 61
TypeAlias 9
Interface 7
FuncType 6

Languages

Go91%
TypeScript9%

Modules by API surface

pkg/mocks/interfaces.go46 symbols
pkg/mocks/redis_client.go42 symbols
pkg/mocks/storage.go32 symbols
pkg/provider/event.go31 symbols
cmd/fibr/static/scripts/index.min.js31 symbols
pkg/provider/request.go25 symbols
pkg/provider/storage.go21 symbols
pkg/provider/interfaces.go19 symbols
pkg/mocks/metadata.go18 symbols
pkg/provider/metadata.go15 symbols
cmd/fibr/static/scripts/upload.js15 symbols
pkg/provider/util.go14 symbols

For agents

$ claude mcp add fibr \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact