Skip to content

Commit b997dc7

Browse files
authoredDec 16, 2024··
Add mobile toolkit v3 URL helper (#139)
1 parent 812faa3 commit b997dc7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+2986
-1455
lines changed
 

‎cmd/rwp/cmd/serve/api.go

+29-35
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/readium/go-toolkit/pkg/manifest"
2525
"github.com/readium/go-toolkit/pkg/pub"
2626
"github.com/readium/go-toolkit/pkg/streamer"
27+
"github.com/readium/go-toolkit/pkg/util/url"
2728
"github.com/zeebo/xxh3"
2829
)
2930

@@ -67,32 +68,6 @@ func (s *Server) getPublication(filename string) (*pub.Publication, error) {
6768
return nil, errors.Wrap(err, "failed opening "+cp)
6869
}
6970

70-
// TODO: Remove this after we make links relative in the go-toolkit
71-
for i, link := range pub.Manifest.Links {
72-
pub.Manifest.Links[i] = makeRelative(link)
73-
}
74-
for i, link := range pub.Manifest.Resources {
75-
pub.Manifest.Resources[i] = makeRelative(link)
76-
}
77-
for i, link := range pub.Manifest.ReadingOrder {
78-
pub.Manifest.ReadingOrder[i] = makeRelative(link)
79-
}
80-
for i, link := range pub.Manifest.TableOfContents {
81-
pub.Manifest.TableOfContents[i] = makeRelative(link)
82-
}
83-
var makeCollectionRelative func(mp manifest.PublicationCollectionMap)
84-
makeCollectionRelative = func(mp manifest.PublicationCollectionMap) {
85-
for i := range mp {
86-
for j := range mp[i] {
87-
for k := range mp[i][j].Links {
88-
mp[i][j].Links[k] = makeRelative(mp[i][j].Links[k])
89-
}
90-
makeCollectionRelative(mp[i][j].Subcollections)
91-
}
92-
}
93-
}
94-
makeCollectionRelative(pub.Manifest.Subcollections)
95-
9671
// Cache the publication
9772
encPub := &cache.CachedPublication{Publication: pub}
9873
s.lfu.Set(cp, encPub)
@@ -122,10 +97,19 @@ func (s *Server) getManifest(w http.ResponseWriter, req *http.Request) {
12297
scheme = "https://"
12398
}
12499
rPath, _ := s.router.Get("manifest").URLPath("path", vars["path"])
100+
conformsTo := conformsToAsMimetype(publication.Manifest.Metadata.ConformsTo)
101+
102+
selfUrl, err := url.AbsoluteURLFromString(scheme + req.Host + rPath.String())
103+
if err != nil {
104+
slog.Error("failed creating self URL", "error", err)
105+
w.WriteHeader(500)
106+
return
107+
}
108+
125109
selfLink := &manifest.Link{
126-
Rels: manifest.Strings{"self"},
127-
Type: conformsToAsMimetype(publication.Manifest.Metadata.ConformsTo),
128-
Href: scheme + req.Host + rPath.String(),
110+
Rels: manifest.Strings{"self"},
111+
MediaType: &conformsTo,
112+
Href: manifest.NewHREF(selfUrl),
129113
}
130114

131115
// Marshal the manifest
@@ -155,7 +139,7 @@ func (s *Server) getManifest(w http.ResponseWriter, req *http.Request) {
155139
}
156140

157141
// Add headers
158-
w.Header().Set("content-type", conformsToAsMimetype(publication.Manifest.Metadata.ConformsTo)+"; charset=utf-8")
142+
w.Header().Set("content-type", conformsTo.String()+"; charset=utf-8")
159143
w.Header().Set("cache-control", "private, must-revalidate")
160144
w.Header().Set("access-control-allow-origin", "*") // TODO: provide options?
161145

@@ -190,18 +174,28 @@ func (s *Server) getAsset(w http.ResponseWriter, r *http.Request) {
190174
return
191175
}
192176

177+
// Parse asset path from mux vars
178+
href, err := url.URLFromDecodedPath(path.Clean(vars["asset"]))
179+
if err != nil {
180+
slog.Error("failed parsing asset path as URL", "error", err)
181+
w.WriteHeader(400)
182+
return
183+
}
184+
rawHref := href.Raw()
185+
rawHref.RawQuery = r.URL.Query().Encode() // Add the query parameters of the URL
186+
href, _ = url.RelativeURLFromGo(rawHref) // Turn it back into a go-toolkit relative URL
187+
193188
// Make sure the asset exists in the publication
194-
href := path.Clean(vars["asset"])
195-
link := publication.Find(href)
189+
link := publication.LinkWithHref(href)
196190
if link == nil {
197191
w.WriteHeader(http.StatusNotFound)
198192
return
199193
}
200194
finalLink := *link
201195

202196
// Expand templated links to include URL query parameters
203-
if finalLink.Templated {
204-
finalLink = finalLink.ExpandTemplate(convertURLValuesToMap(r.URL.Query()))
197+
if finalLink.Href.IsTemplated() {
198+
finalLink.Href = manifest.NewHREF(finalLink.URL(nil, convertURLValuesToMap(r.URL.Query())))
205199
}
206200

207201
// Get the asset from the publication
@@ -217,7 +211,7 @@ func (s *Server) getAsset(w http.ResponseWriter, r *http.Request) {
217211
}
218212

219213
// Patch mimetype where necessary
220-
contentType := link.MediaType().String()
214+
contentType := link.MediaType.String()
221215
if sub, ok := mimeSubstitutions[contentType]; ok {
222216
contentType = sub
223217
}

‎cmd/rwp/cmd/serve/helpers.go

+4-12
Original file line numberDiff line numberDiff line change
@@ -51,21 +51,13 @@ var compressableMimes = []string{
5151
"application/vnd.ms-fontobject",
5252
}
5353

54-
func makeRelative(link manifest.Link) manifest.Link {
55-
link.Href = strings.TrimPrefix(link.Href, "/")
56-
for i, alt := range link.Alternates {
57-
link.Alternates[i].Href = strings.TrimPrefix(alt.Href, "/")
58-
}
59-
return link
60-
}
61-
62-
func conformsToAsMimetype(conformsTo manifest.Profiles) string {
63-
mime := mediatype.ReadiumWebpubManifest.String()
54+
func conformsToAsMimetype(conformsTo manifest.Profiles) mediatype.MediaType {
55+
mime := mediatype.ReadiumWebpubManifest
6456
for _, profile := range conformsTo {
6557
if profile == manifest.ProfileDivina {
66-
mime = mediatype.ReadiumDivinaManifest.String()
58+
mime = mediatype.ReadiumDivinaManifest
6759
} else if profile == manifest.ProfileAudiobook {
68-
mime = mediatype.ReadiumAudiobookManifest.String()
60+
mime = mediatype.ReadiumAudiobookManifest
6961
} else {
7062
continue
7163
}

0 commit comments

Comments
 (0)
Please sign in to comment.