Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-pages.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamil Trzciński <ayufan@ayufan.eu>2019-02-28 17:46:18 +0300
committerKamil Trzciński <ayufan@ayufan.eu>2019-02-28 17:46:18 +0300
commita6d5eb8ecac9f3f74f156037d200dff620b2fa2c (patch)
treef33757a8c0b2de950c5d4690b236c8da226480f0 /internal/client
parent7254174ea9ee4c611f65329dc7a0603388b3742e (diff)
Fix handling of paths
Diffstat (limited to 'internal/client')
-rw-r--r--internal/client/api.go41
-rw-r--r--internal/client/domain_response.go24
-rw-r--r--internal/client/lookup_path.go75
3 files changed, 99 insertions, 41 deletions
diff --git a/internal/client/api.go b/internal/client/api.go
index 77f5d94a..5566f151 100644
--- a/internal/client/api.go
+++ b/internal/client/api.go
@@ -4,49 +4,8 @@ import (
"encoding/json"
"net/http"
"net/url"
- "strings"
)
-type LookupConfig struct {
- NamespaceProject bool `json:"namespace_project"`
- HTTPSOnly bool `json:"https_only"`
- AccessControl bool `json:"access_control"`
- ProjectID uint64 `json:"id"`
-}
-
-type LookupPath struct {
- LookupConfig
-
- Prefix string `json:"prefix"`
- Path string `json:"path"`
-}
-
-func (lp *LookupPath) Tail(r *http.Request) string {
- if strings.HasPrefix(r.URL.Path, lp.Prefix) {
- return r.URL.Path[len(lp.Path):]
- }
-
- return ""
-}
-
-type DomainResponse struct {
- Domain string `json:"domain"`
- Certificate string `json:"certificate"`
- Key string `json:"certificate_key"`
-
- LookupPath []LookupPath `json:"lookup_paths"`
-}
-
-func (d *DomainResponse) GetPath(r *http.Request) *LookupPath {
- for _, lp := range d.LookupPath {
- if strings.HasPrefix(r.RequestURI, lp.Prefix) {
- return &lp
- }
- }
-
- return nil
-}
-
func RequestDomain(apiUrl, host string) *DomainResponse {
var values url.Values
values.Add("host", host)
diff --git a/internal/client/domain_response.go b/internal/client/domain_response.go
new file mode 100644
index 00000000..77d9b474
--- /dev/null
+++ b/internal/client/domain_response.go
@@ -0,0 +1,24 @@
+package client
+
+import (
+ "net/http"
+ "strings"
+)
+
+type DomainResponse struct {
+ Domain string `json:"domain"`
+ Certificate string `json:"certificate"`
+ Key string `json:"certificate_key"`
+
+ LookupPath []LookupPath `json:"lookup_paths"`
+}
+
+func (d *DomainResponse) GetPath(r *http.Request) *LookupPath {
+ for _, lp := range d.LookupPath {
+ if strings.HasPrefix(r.RequestURI, lp.Prefix) {
+ return &lp
+ }
+ }
+
+ return nil
+}
diff --git a/internal/client/lookup_path.go b/internal/client/lookup_path.go
new file mode 100644
index 00000000..f11dd925
--- /dev/null
+++ b/internal/client/lookup_path.go
@@ -0,0 +1,75 @@
+package client
+
+import (
+ "fmt"
+ "net/http"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "golang.org/x/sys/unix"
+)
+
+type LookupConfig struct {
+ NamespaceProject bool `json:"namespace_project"`
+ HTTPSOnly bool `json:"https_only"`
+ AccessControl bool `json:"access_control"`
+ ProjectID uint64 `json:"id"`
+}
+
+type LookupPath struct {
+ LookupConfig
+
+ Prefix string `json:"prefix"`
+ Path string `json:"path"`
+}
+
+func (lp *LookupPath) Tail(r *http.Request) string {
+ if strings.HasPrefix(r.URL.Path, lp.Prefix) {
+ return r.URL.Path[len(lp.Path):]
+ }
+
+ return ""
+}
+
+func (lp *LookupPath) resolvePath(path string) (string, error) {
+ fullPath := filepath.Join(lp.Path, path)
+ fullPath, err := filepath.EvalSymlinks(fullPath)
+ if err != nil {
+ return "", err
+ }
+
+ // The requested path resolved to somewhere outside of the public/ directory
+ if !strings.HasPrefix(fullPath, lp.Path) {
+ return "", fmt.Errorf("%q should be in %q", fullPath, lp.Path)
+ }
+
+ return fullPath, nil
+}
+
+func (lp *LookupPath) Resolve(path string) (string, error) {
+ fullPath, err := lp.resolvePath(path)
+ if err != nil {
+ return "", err
+ }
+
+ return fullPath[len(lp.Path):], nil
+}
+
+func (lp *LookupPath) Stat(path string) (os.FileInfo, error) {
+ fullPath, err := lp.resolvePath(path)
+ if err != nil {
+ return nil, err
+ }
+
+ return os.Lstat(fullPath)
+}
+
+func (lp *LookupPath) Open(path string) (*os.File, error) {
+ fullPath, err := lp.resolvePath(path)
+ if err != nil {
+ return nil, err
+ }
+
+ return os.OpenFile(fullPath, os.O_RDONLY|unix.O_NOFOLLOW, 0)
+}