Skip to content

Commit

Permalink
Merge branch 'devel' of https://github.com/wtsi-npg/sqyrrl into devel
Browse files Browse the repository at this point in the history
  • Loading branch information
dkj committed Dec 20, 2024
2 parents 243e1c6 + 8a0a656 commit 321a2a4
Show file tree
Hide file tree
Showing 14 changed files with 919 additions and 235 deletions.
14 changes: 9 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,32 @@ VERSION := $(shell git describe --always --tags --dirty)
ldflags := "-X sqyrrl/server.Version=${VERSION}"
build_args := -a -v -ldflags ${ldflags}

build_path = "build/sqyrrl-${VERSION}"
build_path = build/sqyrrl-${VERSION}

export GOARCH := $(shell go env GOARCH)

CGO_ENABLED := 1
GOARCH := amd64

.PHONY: build build-linux build-darwin build-windows check clean coverage install lint test

all: build

build: build-linux build-darwin build-windows

build-linux: export GOOS = linux
build-linux:
mkdir -p ${build_path}
GOARCH=${GOARCH} GOOS=linux go build ${build_args} -o ${build_path}/sqyrrl-linux-${GOARCH} ./main.go
go build ${build_args} -o ${build_path}/sqyrrl-${GOOS}-${GOARCH} ./main.go

build-darwin: export GOOS = darwin
build-darwin:
mkdir -p ${build_path}
GOARCH=${GOARCH} GOOS=darwin go build ${build_args} -o ${build_path}/sqyrrl-darwin-${GOARCH} ./main.go
go build ${build_args} -o ${build_path}/sqyrrl-${GOOS}-${GOARCH} ./main.go

build-windows: export GOOS = windows
build-windows:
mkdir -p ${build_path}
GOARCH=${GOARCH} GOOS=windows go build ${build_args} -o ${build_path}/sqyrrl-windows-${GOARCH}.exe ./main.go
go build ${build_args} -o ${build_path}/sqyrrl-${GOOS}-${GOARCH}.exe ./main.go

install:
go install ${build_args}
Expand Down
20 changes: 18 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,26 @@
Sqyrrl is an HTTP server which contains an embedded iRODS client and is able to
serve data directly from iRODS.

## Building

In the root directory of the repository run `make` to build Linux, macOS and Windows
executables for the architecture of the machine you are on.

To build for a different architecture, pass a Go architecture argument to make e.g.

```
make GOARCH=amd64 # To build for amd64
make GOARCH=arm # To build for arm
```

You can find all the valid operating system and architecture pairs supported on your
system by running `go tool dist list`

## Installation

Sqyrrl is a available as and `amd64` binary for Linux, macOS and Windows,
or as a Docker image. Copy the file to the desired location and run it.
Sqyrrl runs on Linux, macOS and Windows. Copy the executable file to the desired location
and run it. It is also available as a Docker image.

## Running Sqyrrl

Expand Down
14 changes: 13 additions & 1 deletion cmd/sqyrrl.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ package cmd
import (
"fmt"
"github.com/BurntSushi/toml"
"github.com/alexedwards/scs/v2"
"io"
"net/http"
"os"
"strings"
"time"
Expand Down Expand Up @@ -178,8 +180,18 @@ func startServer(cmd *cobra.Command, args []string) (err error) { // NRV
return err
}

// Server-side storage of session data, keyed on a random session ID exchanged with
// the client
sessManager := scs.New()
sessManager.Cookie.Name = "sqyrrl-session" // Session cookie name
sessManager.Cookie.HttpOnly = true // Don't let JS access the cookie
sessManager.Cookie.Persist = false // Don't allow the session to persist across browser sessions
sessManager.Cookie.SameSite = http.SameSiteLaxMode // Can't use Strict because of the OAuth2 callback
sessManager.Cookie.Secure = true // Require HTTPS because SameSite can't be Strict
sessManager.Lifetime = 10 * time.Minute // Session lifetime

var srv *server.SqyrrlServer
srv, err = server.NewSqyrrlServer(logger, &config)
srv, err = server.NewSqyrrlServer(logger, &config, sessManager)
if err != nil {
return err
}
Expand Down
11 changes: 4 additions & 7 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
services:
irods-server:
container_name: irods-server
image: "ghcr.io/wtsi-npg/ub-16.04-irods-4.2.7:latest"
# image: "ghcr.io/wtsi-npg/ub-22.04-irods-4.3.2:latest"
image: "wsinpg/ub-22.04-irods-4.3.3"
platform: linux/amd64
ports:
- "127.0.0.1:1247:1247"
- "127.0.0.1:20000-20199:20000-20199"
restart: always
restart: on-failure
healthcheck:
test: ["CMD", "nc", "-z", "-v", "127.0.0.1", "1247"]
start_period: 30s
Expand All @@ -25,11 +26,7 @@ services:
# The following environment variables may be set in a .env file (files named .env
# are declared in .gitignore):
#
# If no iRODS auth file is provided:
#
# IRODS_PASSWORD
#
# And if using OIDC:
# If using OIDC:
#
# OIDC_CLIENT_ID
# OIDC_ISSUER_URL
Expand Down
16 changes: 8 additions & 8 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ require (
github.com/BurntSushi/toml v1.4.0
github.com/alexedwards/scs/v2 v2.8.0
github.com/coreos/go-oidc/v3 v3.11.0
github.com/cyverse/go-irodsclient v0.14.4
github.com/cyverse/go-irodsclient v0.15.7-0.20241106203458-0b74740d1c86
github.com/microcosm-cc/bluemonday v1.0.26
github.com/onsi/ginkgo/v2 v2.21.0
github.com/onsi/gomega v1.35.1
github.com/onsi/ginkgo/v2 v2.22.0
github.com/onsi/gomega v1.36.1
github.com/rs/xid v1.6.0
github.com/rs/zerolog v1.33.0
github.com/spf13/cobra v1.8.1
golang.org/x/oauth2 v0.23.0
golang.org/x/term v0.25.0
golang.org/x/oauth2 v0.24.0
golang.org/x/term v0.27.0
)

require (
Expand All @@ -27,6 +27,7 @@ require (
github.com/gorilla/css v1.0.0 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/kelseyhightower/envconfig v1.4.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
Expand All @@ -37,13 +38,12 @@ require (
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/crypto v0.28.0 // indirect
golang.org/x/net v0.30.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/text v0.19.0 // indirect
golang.org/x/tools v0.26.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

// replace github.com/cyverse/go-irodsclient => ../go-irodsclient

replace github.com/cyverse/go-irodsclient => github.com/wtsi-npg/go-irodsclient v0.0.0-20240417120912-4a4dec5bcefb
28 changes: 16 additions & 12 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ github.com/coreos/go-oidc/v3 v3.11.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDh
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cyverse/go-irodsclient v0.15.7-0.20241106203458-0b74740d1c86 h1:/7oP8j3G42YhOSF8bSNQ7MbYNWPSYV53mw+mScymoic=
github.com/cyverse/go-irodsclient v0.15.7-0.20241106203458-0b74740d1c86/go.mod h1:NN+PxHfLDUmsqfqSY84JfmqXS4EYiuiNW6ti6oPGCgk=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk=
Expand All @@ -28,6 +30,8 @@ github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5O
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
Expand All @@ -41,10 +45,10 @@ github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3r
github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg=
github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw=
github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
Expand All @@ -66,22 +70,20 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/wtsi-npg/go-irodsclient v0.0.0-20240417120912-4a4dec5bcefb h1:42Ddz94sqVkcgdZjL2QyC2f0yiORTXaCMZAOqeGOFMU=
github.com/wtsi-npg/go-irodsclient v0.0.0-20240417120912-4a4dec5bcefb/go.mod h1:eBXha3cwfrM0p1ijYVqsrLJQHpRwTfpA4c5dKCQsQFc=
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
Expand All @@ -93,5 +95,7 @@ google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojt
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
84 changes: 57 additions & 27 deletions server/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"encoding/base64"
"io/fs"
"net/http"
"net/http/httputil"
"path"
"time"

Expand Down Expand Up @@ -111,6 +112,9 @@ func HandleLogin(server *SqyrrlServer) http.Handler {
logger := server.logger
logger.Trace().Msg("LoginHandler called")

req, _ := httputil.DumpRequest(r, true)
logger.Trace().Str("request", string(req)).Msg("HandleLogin request")

if !server.sqyrrlConfig.EnableOIDC {
logger.Error().Msg("OIDC is not enabled")
writeErrorResponse(logger, w, http.StatusForbidden)
Expand All @@ -121,10 +125,19 @@ func HandleLogin(server *SqyrrlServer) http.Handler {

state, err := cryptoRandString(16) // Minimum 128 bits required
if err != nil {
logger.Err(err).Msg("Failed to generate a random state")
writeErrorResponse(logger, w, http.StatusInternalServerError)
return
}

// https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Session_Management_Cheat_Sheet.md#renew-the-session-id-after-any-privilege-level-change
err = server.sessionManager.RenewToken(r.Context())
if err != nil {
logger.Err(err).Msg("Failed to renew session token")
writeErrorResponse(logger, w, http.StatusInternalServerError)
return
}
server.sessionManager.Put(r.Context(), sessionKeyState, state)
server.sessionManager.Put(r.Context(), SessionKeyState, state)

authURL := server.oauth2Config.AuthCodeURL(state)
logger.Info().
Expand All @@ -145,13 +158,16 @@ func HandleAuthCallback(server *SqyrrlServer) http.Handler {
logger := server.logger
logger.Trace().Msg("AuthCallbackHandler called")

req, _ := httputil.DumpRequest(r, true)
logger.Trace().Str("request", string(req)).Msg("HandleAuthCallback request")

if !server.sqyrrlConfig.EnableOIDC {
logger.Error().Msg("OIDC is not enabled")
writeErrorResponse(logger, w, http.StatusForbidden)
return
}

state := server.sessionManager.GetString(r.Context(), sessionKeyState)
state := server.sessionManager.GetString(r.Context(), SessionKeyState)
if state == "" {
logger.Error().Msg("Failed to get a state cookie")
writeErrorResponse(logger, w, http.StatusBadRequest)
Expand Down Expand Up @@ -289,19 +305,9 @@ func HandleIRODSGet(server *SqyrrlServer) http.Handler {
objPath := path.Clean(path.Join("/", r.URL.Path))
logger.Debug().Str("path", objPath).Msg("Getting iRODS data object")

var userID string
if server.isAuthenticated(r) {
userID = iRODSUserIDFromEmail(logger, server.getSessionUserEmail(r))
} else {
userID = IRODSPublicUser
}

userZone := server.iRODSAccount.ClientZone

var err error
var rodsFs *ifs.FileSystem
if rodsFs, err = ifs.NewFileSystemWithDefault(server.iRODSAccount,
AppName); err != nil {
if rodsFs, err = ifs.NewFileSystemWithDefault(server.iRODSAccount, AppName); err != nil {
logger.Err(err).Msg("Failed to create an iRODS file system")
writeErrorResponse(logger, w, http.StatusInternalServerError)
return
Expand Down Expand Up @@ -332,22 +338,46 @@ func HandleIRODSGet(server *SqyrrlServer) http.Handler {
return
}

userZone := server.iRODSAccount.ClientZone

var isReadable bool
isReadable, err = isReadableByUser(logger, rodsFs, userZone, userID, objPath)
if err != nil {
logger.Err(err).Msg("Failed to check if the object is readable")
writeErrorResponse(logger, w, http.StatusInternalServerError)
return
}

if !isReadable {
logger.Info().
Str("path", objPath).
Str("id", userID).
Str("zone", userZone).
Msg("Requested path is not readable by this user")
writeErrorResponse(logger, w, http.StatusForbidden)
return
if server.isAuthenticated(r) {
userName := iRODSUsernameFromEmail(logger, server.getSessionUserEmail(r))
logger.Debug().Str("user", userName).Msg("User is authenticated")

isReadable, err = IsReadableByUser(logger, rodsFs, userName, userZone, objPath)
if err != nil {
logger.Err(err).Msg("Failed to check if the object is readable")
writeErrorResponse(logger, w, http.StatusInternalServerError)
return
}

if !isReadable {
logger.Info().
Str("path", objPath).
Str("user", userName).
Str("zone", userZone).
Msg("Requested path is not readable by this user")
writeErrorResponse(logger, w, http.StatusForbidden)
return
}
} else {
logger.Debug().Msg("User is not authenticated")
isReadable, err = IsPublicReadable(logger, rodsFs, userZone, objPath)
if err != nil {
logger.Err(err).Msg("Failed to check if the object is public readable")
writeErrorResponse(logger, w, http.StatusInternalServerError)
return
}

if !isReadable {
logger.Info().
Str("path", objPath).
Msg("Requested path is not public readable")
writeErrorResponse(logger, w, http.StatusForbidden)
return
}
}

getFileRange(rodsLogger, w, r, rodsFs, objPath)
Expand Down
Loading

0 comments on commit 321a2a4

Please sign in to comment.