...
1 package jsonschema
2
3 import (
4 "context"
5 "encoding/json"
6 "fmt"
7 "io/ioutil"
8 "net/http"
9 "net/url"
10 "os"
11 "strings"
12 )
13
14 var showDebug = os.Getenv("JSON_SCHEMA_DEBUG") == "1"
15
16
17
18
19 func schemaDebug(message string, args ...interface{}) {
20 if showDebug {
21 if message[len(message)-1] != '\n' {
22 message += "\n"
23 }
24 fmt.Printf(message, args...)
25 }
26 }
27
28
29 func SafeResolveURL(ctxURL, resURL string) (string, error) {
30 cu, err := url.Parse(ctxURL)
31 if err != nil {
32 return "", err
33 }
34 u, err := url.Parse(resURL)
35 if err != nil {
36 return "", err
37 }
38 resolvedURL := cu.ResolveReference(u)
39 if resolvedURL.Scheme == "file" && cu.Scheme != "file" {
40 return "", fmt.Errorf("cannot access file resources from network context")
41 }
42 resolvedURLString := resolvedURL.String()
43 return resolvedURLString, nil
44 }
45
46
47 func IsLocalSchemaID(id string) bool {
48 splitID := strings.Split(id, "#")
49 if len(splitID) > 1 && len(splitID[0]) > 0 && splitID[0][0] != '#' {
50 return false
51 }
52 return id != "#" && !strings.HasPrefix(id, "#/") && strings.Contains(id, "#")
53 }
54
55
56 func FetchSchema(ctx context.Context, uri string, schema *Schema) error {
57 schemaDebug(fmt.Sprintf("[FetchSchema] Fetching: %s", uri))
58 u, err := url.Parse(uri)
59 if err != nil {
60 return err
61 }
62
63 if u.Scheme == "http" || u.Scheme == "https" {
64 var req *http.Request
65 if ctx != nil {
66 req, _ = http.NewRequestWithContext(ctx, "GET", u.String(), nil)
67 } else {
68 req, _ = http.NewRequest("GET", u.String(), nil)
69 }
70 client := &http.Client{}
71 res, err := client.Do(req)
72 if err != nil {
73 return err
74 }
75 body, err := ioutil.ReadAll(res.Body)
76 if err != nil {
77 return err
78 }
79 if schema == nil {
80 schema = &Schema{}
81 }
82 return json.Unmarshal(body, schema)
83 }
84 return fmt.Errorf("URI scheme %s is not supported for uri: %s", u.Scheme, uri)
85 }
86
View as plain text