...

Source file src/github.com/qri-io/jsonschema/util.go

Documentation: github.com/qri-io/jsonschema

     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  // schemaDebug provides a logging interface
    17  // which is off by defauly but can be activated
    18  // for debuging purposes
    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  // SafeResolveURL resolves a string url against the current context url
    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  // IsLocalSchemaID validates if a given id is a local id
    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  // FetchSchema downloads and loads a schema from a remote location
    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  	// TODO(arqu): support other schemas like file or ipfs
    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