Skip to content
This repository has been archived by the owner on Jan 27, 2021. It is now read-only.

Implement dav file preview API like in OC10 #13

Merged
merged 7 commits into from
Mar 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions changelog/unreleased/preview-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Enhancement: implement preview API

Added the API endpoint for file previews.

https://github.com/owncloud/ocis-webdav/pull/13
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ require (
contrib.go.opencensus.io/exporter/ocagent v0.6.0
contrib.go.opencensus.io/exporter/zipkin v0.1.1
github.com/go-chi/chi v4.0.2+incompatible
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d // indirect
github.com/micro/cli/v2 v2.1.1
github.com/micro/go-micro/v2 v2.0.0
github.com/oklog/run v1.0.0
github.com/openzipkin/zipkin-go v0.2.2
github.com/owncloud/ocis-pkg/v2 v2.0.1
github.com/owncloud/ocis-thumbnails v0.0.0-20200318131505-e0ab0b37a5a4
github.com/spf13/afero v1.2.2 // indirect
github.com/spf13/viper v1.5.0
go.opencensus.io v0.22.2
Expand Down
57 changes: 53 additions & 4 deletions go.sum

Large diffs are not rendered by default.

72 changes: 72 additions & 0 deletions pkg/dav/thumbnails/thumbnail.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package thumbnail

import (
"fmt"
"net/http"
"path/filepath"
"strconv"
"strings"

"github.com/go-chi/chi"
)

const (
// DefaultWidth defines the default width of a thumbnail
DefaultWidth = 32
// DefaultHeight defines the default height of a thumbnail
DefaultHeight = 32
)

// Request combines all parameters provided when requesting a thumbnail
type Request struct {
Filepath string
Filetype string
Etag string
Width int
Height int
Authorization string
}

// NewRequest extracts all required parameters from a http request.
func NewRequest(r *http.Request) (Request, error) {
path := extractFilePath(r)
query := r.URL.Query()
width, err := strconv.Atoi(query.Get("x"))
if err != nil {
width = DefaultWidth
}
height, err := strconv.Atoi(query.Get("y"))
if err != nil {
height = DefaultHeight
}

etag := query.Get("c")
if strings.TrimSpace(etag) == "" {
return Request{}, fmt.Errorf("c (etag) is missing in query")
}

authorization := r.Header.Get("Authorization")

tr := Request{
Filepath: path,
Filetype: strings.Replace(filepath.Ext(path), ".", "", 1),
Etag: etag,
Width: width,
Height: height,
Authorization: authorization,
}

return tr, nil
}

// the url looks as followed
//
// /remote.php/dav/files/<user>/<filepath>
//
// User and filepath are dynamic and filepath can contain slashes
// So using the URLParam function is not possible.
func extractFilePath(r *http.Request) string {
user := chi.URLParam(r, "user")
parts := strings.SplitN(r.URL.Path, user, 2)
return parts[1]
}
6 changes: 3 additions & 3 deletions pkg/service/v0/instrument.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (i instrument) ServeHTTP(w http.ResponseWriter, r *http.Request) {
i.next.ServeHTTP(w, r)
}

// Dummy implements the Service interface.
func (i instrument) Dummy(w http.ResponseWriter, r *http.Request) {
i.next.Dummy(w, r)
// Thumbnail implements the Service interface.
func (i instrument) Thumbnail(w http.ResponseWriter, r *http.Request) {
i.next.Thumbnail(w, r)
}
4 changes: 2 additions & 2 deletions pkg/service/v0/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ func (l logging) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}

// Dummy implements the Service interface.
func (l logging) Dummy(w http.ResponseWriter, r *http.Request) {
l.next.Dummy(w, r)
func (l logging) Thumbnail(w http.ResponseWriter, r *http.Request) {
C0rby marked this conversation as resolved.
Show resolved Hide resolved
l.next.Thumbnail(w, r)
}
45 changes: 39 additions & 6 deletions pkg/service/v0/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@ package svc

import (
"net/http"
"strings"

"github.com/go-chi/chi"
"github.com/micro/go-micro/v2/client"
thumbnails "github.com/owncloud/ocis-thumbnails/pkg/proto/v0"
"github.com/owncloud/ocis-webdav/pkg/config"
thumbnail "github.com/owncloud/ocis-webdav/pkg/dav/thumbnails"
)

// Service defines the extension handlers.
type Service interface {
ServeHTTP(http.ResponseWriter, *http.Request)
Dummy(http.ResponseWriter, *http.Request)
Thumbnail(http.ResponseWriter, *http.Request)
}

// NewService returns a service implementation for Service.
Expand All @@ -26,7 +30,7 @@ func NewService(opts ...Option) Service {
}

m.Route(options.Config.HTTP.Root, func(r chi.Router) {
r.Get("/", svc.Dummy)
r.Get("/remote.php/dav/files/{user}/*", svc.Thumbnail)
C0rby marked this conversation as resolved.
Show resolved Hide resolved
})

return svc
Expand All @@ -43,10 +47,39 @@ func (g Webdav) ServeHTTP(w http.ResponseWriter, r *http.Request) {
g.mux.ServeHTTP(w, r)
}

// Dummy implements the Service interface.
func (g Webdav) Dummy(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
// Thumbnail implements the Service interface.
func (g Webdav) Thumbnail(w http.ResponseWriter, r *http.Request) {
tr, err := thumbnail.NewRequest(r)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}

c := thumbnails.NewThumbnailService("com.owncloud.api.thumbnails", client.DefaultClient)
rsp, err := c.GetThumbnail(r.Context(), &thumbnails.GetRequest{
Filepath: strings.TrimLeft(tr.Filepath, "/"),
Filetype: extensionToFiletype(tr.Filetype),
Etag: tr.Etag,
Width: int32(tr.Width),
Height: int32(tr.Height),
Authorization: tr.Authorization,
})
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}

w.Header().Set("Content-Type", rsp.GetMimetype())
w.WriteHeader(http.StatusOK)
w.Write(rsp.Thumbnail)
}

w.Write([]byte(http.StatusText(http.StatusOK)))
func extensionToFiletype(ext string) thumbnails.GetRequest_FileType {
val, ok := thumbnails.GetRequest_FileType_value[strings.ToUpper(ext)]
if !ok {
return thumbnails.GetRequest_FileType(-1)
}
return thumbnails.GetRequest_FileType(val)
}
6 changes: 3 additions & 3 deletions pkg/service/v0/tracing.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func (t tracing) ServeHTTP(w http.ResponseWriter, r *http.Request) {
t.next.ServeHTTP(w, r)
}

// Dummy implements the Service interface.
func (t tracing) Dummy(w http.ResponseWriter, r *http.Request) {
t.next.Dummy(w, r)
// Thumbnail implements the Service interface.
func (t tracing) Thumbnail(w http.ResponseWriter, r *http.Request) {
C0rby marked this conversation as resolved.
Show resolved Hide resolved
t.next.Thumbnail(w, r)
}