Documentation
¶
Index ¶
- Constants
- func Join(authority string, id string, query string, fragment string) string
- func JoinUnencrypted(authority string, id string, query string, fragment string) string
- func Normalize(uri string) string
- func NormalizeAuthority(authority string) string
- func NormalizeID(id string) string
- func Resolve(uri string, requestType string) (string, error)
- func ResolveID(id string) string
- func Split(uri string) (host string, id string, query string, fragment string, err error)
- func SplitAndNormalize(uri string) (authority string, id string, query string, fragment string, err error)
- func SplitAndNormalizeAndValidate(uri string) (authority string, id string, query string, fragment string, err error)
- func Validate(uri string) error
- func ValidateAuthority(authority string) error
- func ValidateID(id string) error
- func ValidatePrefix(uri string) error
- func ValidateScheme(uri string) error
- type URL
Examples ¶
Constants ¶
const ( RequestTypeExecute string = "execute" // an alternative name for "procedure" so that all the request-types can be a verb. RequestTypeProcedure string = "procedure" RequestTypeQuery string = "query" RequestTypeSubscribe string = "subscribe" )
Variables ¶
This section is empty.
Functions ¶
func Join ¶
Example ¶
package main
import (
"fmt"
"net/url"
"github.com/reiver/go-xrpcuri"
)
func main() {
var authority string = "public.api.bsky.app"
var id string = "app.bsky.actor.getProfile"
var actor string = "reiver.bsky.social"
query := "actor=" + url.QueryEscape(actor)
uri := xrpcuri.Join(authority, id, query, "")
fmt.Printf("authority: %s\n", authority)
fmt.Printf("id: %s\n", id)
fmt.Printf("actor: %s\n", actor)
fmt.Println()
fmt.Printf("query: %s\n", query)
fmt.Println()
fmt.Printf("uri: %s\n", uri)
}
Output: authority: public.api.bsky.app id: app.bsky.actor.getProfile actor: reiver.bsky.social query: actor=reiver.bsky.social uri: xrpc://public.api.bsky.app/app.bsky.actor.getProfile?actor=reiver.bsky.social
func JoinUnencrypted ¶
func Normalize ¶
Normalize returns the normalized form of an XRPC-URI or an XRPC-unencrypted-URI.
Normalize does NOT validate the XRPC-URI or XRPC-unencrypted-URI. To validate, call Validate.
An example of a non-normalized XRPC-URI would be:
xrpc://VIDEO.archive.ORG/COM.Example.fooBar
Normalizing that non-normalized XRPC-URI would result in:
xrpc://video.archive.org/com.example.fooBar
Example ¶
package main
import (
"fmt"
"github.com/reiver/go-xrpcuri"
)
func main() {
var id string = "xrpcuri://Host.EXAMPLE/COM.Example.fooBar"
normalizedID := xrpcuri.NormalizeID(id)
fmt.Printf("original xrpc-uri: %s\n", id)
fmt.Printf("normalized xrpc-uri: %s\n", normalizedID)
}
Output: original xrpc-uri: xrpcuri://Host.EXAMPLE/COM.Example.fooBar normalized xrpc-uri: xrpcuri://host.example/com.example.fooBar
func NormalizeAuthority ¶
NormalizeAuthority returns the normalized form of an XRPC-URI 'authority'.
The XRPC-URI 'authority' (such as "example.com") is part of an XRPC-URI (such as "xrpc://example.com").
In simple language, you can think of an XRPC-URI 'authority' as being either an Internet domain-name (ex: "example.com").
An example of a non-normalized XRPC-URI 'authority' would be "Example.COM". Normalizing that non-normalized XRPC-URI 'authority' would result in "example.com".
NormalizeAuthority will leave any potential 'userinfo' in the 'authority' as is.
Note that if you want to normalize a whole XRPC-URI rather than just an 'authority', then instead use Normalize.
Example ¶
package main
import (
"fmt"
"github.com/reiver/go-xrpcuri"
)
func main() {
var authority string = "Example.COM"
normalizedAuthority := xrpcuri.NormalizeAuthority(authority)
fmt.Printf("original authority: %s\n", authority)
fmt.Printf("normalized authority: %s\n", normalizedAuthority)
}
Output: original authority: Example.COM normalized authority: example.com
func NormalizeID ¶
NormalizeID returns the normalized form of an XRPC-URI 'id', as defined in: https://atproto.com/specs/xrpc
An XRPC-URI 'id' is an NSID, as defined at: https://atproto.com/specs/nsid
The XRPC-URI 'id' (such as "com.example.fooBar") is part of an XRPC-URI (such as "xrpc://archive.org/com.example.fooBar").
An example of a non-normalized XRPC-URI 'id' would be "COM.Example.fooBar". Normalizing that non-normalized XRPC-URI 'id' would result in "com.example.fooBar".
Note that if you want to normalize a whole XRPC-URI rather than just a 'id', then instead use Normalize.
Example ¶
package main
import (
"fmt"
"github.com/reiver/go-xrpcuri"
)
func main() {
var id string = "COM.Example.fooBar"
normalizedID := xrpcuri.NormalizeID(id)
fmt.Printf("original id: %s\n", id)
fmt.Printf("normalized id: %s\n", normalizedID)
}
Output: original id: COM.Example.fooBar normalized id: com.example.fooBar
func Resolve ¶
Resolve turns an XRPC-URI into an HTTP-URI.
For example:
"xrpc://public.api.bsky.app/app.bsky.actor.getProfile" -> "https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile" "xrpc://example.com/com.example.fooBar" -> "https://example.com/xrpc/com.example.fooBar" "xrpc-unencrypted://example.com/com.example.fooBar" -> "http://example.com/xrpc/com.example.fooBar"
Example ¶
package main
import (
"fmt"
"github.com/reiver/go-xrpcuri"
)
func main() {
var xrpcURI string = "xrpc://example.com/com.atproto.repo.listRecords"
httpURI, err := xrpcuri.Resolve(xrpcURI, "query")
if nil != err {
fmt.Printf("ERROR: could not resolve XRPC-URI %q: %s\n", xrpcURI, err)
return
}
fmt.Printf("http-uri: %s\n", httpURI)
}
Output: http-uri: https://example.com/xrpc/com.atproto.repo.listRecords
func ResolveID ¶
ResolveID resolves the 'id' (which is expected to be an NSID) into an HTTP path.
If `id` is "" then it returns "".
Example ¶
package main
import (
"fmt"
"github.com/reiver/go-xrpcuri"
)
func main() {
var id string = "app.bsky.actor.getProfile"
path := xrpcuri.ResolveID(id)
fmt.Printf("id: %s\n", id)
fmt.Printf("path: %s\n", path)
}
Output: id: app.bsky.actor.getProfile path: /xrpc/app.bsky.actor.getProfile
func Split ¶
Split returns the 'host', 'id', 'query', and 'fragment' of at XRPC-URI or a XRPC-unencrypted-URI.
The 'id' should be an NSID (Namespaced Identifier).
For example:
var uri string = "xrpc://public.api.bsky.app/app.bsky.actor.getProfile?actor=reiver.bsky.social"
host, id, query, fragment, err := xrpcuri.Split(uri)
if nil != err {
return err
}
// host == "public.api.bsky.app"
// id == "app.bsky.actor.getProfile"
// query == "actor=reiver.bsky.social"
// fragment == ""
Split does NOT normalize the returned values.
If you are not sure whether to use Split or [SpliAndNormalize], use SplitAndNormalize.
func SplitAndNormalize ¶
func SplitAndNormalize(uri string) (authority string, id string, query string, fragment string, err error)
SplitAndNormalize returns the 'authority', 'id', 'query', and 'fragment' of an XRPC-URI or XRPC-unencrypted-URI.
An 'id' is an NSID (Namespaced Identifier).
For example:
var uri string = "at://Host.EXAMPLE/COM.Example.foorBar"
authority, id, query, fragment, err := xrpcuri.SplitAndNormalize(uri)
if nil != err {
return err
}
// authority == "host.example"
// id == "com.example.foorBar"
// query == ""
// fragment == ""
SplitAndNormalize normalizes the returned values. If you are not sure whether to use Split or SpliAndNormalize, use SplitAndNormalize.
func SplitAndNormalizeAndValidate ¶
func SplitAndNormalizeAndValidate(uri string) (authority string, id string, query string, fragment string, err error)
SplitAndNormalizeAndValidate returns the 'authority', 'id', 'query', and 'fragment' of an XRPC-URI or XRPC-unencrypted-URI.
An 'id' is an NSID (Namespaced Identifier).
For example:
var uri string = "at://Host.EXAMPLE/COM.Example.foorBar"
authority, id, query, fragment, err := xrpcuri.SplitAndNormalizeAndValidate(uri)
if nil != err {
return err
}
// authority == "host.example"
// id == "com.example.foorBar"
// query == ""
// fragment == ""
SplitAndNormalizeAndValidate normalizes the returned values.
If you are not sure whether to use Split or [SpliAndNormalize] or SplitAndNormalizeAndValidate, use SplitAndNormalizeAndValidate.
func Validate ¶
Validate returns an error if the XRPC-URI or XRPC-unencrypted-URI is invalid. It returns nil if the XRPC-URI is valid.
To validate a potential XRPC-URI or XRPC-unencrypted-URI more liberally, use one of the following: ValidatePrefix, ValidateScheme.
Example ¶
package main
import (
"fmt"
"github.com/reiver/go-xrpcuri"
)
func main() {
var xrpcURI string = "xrpc://archive.org/COM.Example.fooBar?actor=JoeBlow"
err := xrpcuri.Validate(xrpcURI)
fmt.Printf("XRPC-URI: %s\n", xrpcURI)
fmt.Printf("validation error: %s\n", err)
}
Output: XRPC-URI: xrpc://archive.org/COM.Example.fooBar?actor=JoeBlow validation error: xrpcuri: XRPC-URI "xrpc://archive.org/COM.Example.fooBar?actor=JoeBlow" has an id "COM.Example.fooBar" that is not a valid NSID: nsid: character №0 ('C') (U+0043) of domain-authority part №0 ("COM") of domain-authority ("COM.Example") of nsid ("COM.Example.fooBar") is not a digit ('0'-'9'), lower-case letter ('a'-'z'), or a hyphen ('-')
func ValidateAuthority ¶
ValidateAuthority returns an error if the XRPC-URI 'authority' is invalid. It returns nil if the XRPC-URI authority is valid.
NOTE THAT THIS IS NOT VALIDATING AN XRPC-URI, BUT IS INSTEAD VALIDATING AN XRPC-URI 'authority'.
Example ¶
package main
import (
"fmt"
"github.com/reiver/go-xrpcuri"
)
func main() {
var authority string = "user:pass@archive.org"
err := xrpcuri.ValidateAuthority(authority)
fmt.Printf("authority: %s\n", authority)
fmt.Printf("validation error: %s\n", err)
}
Output: authority: user:pass@archive.org validation error: xrpcuri: authority may not have an "@" in it
func ValidateID ¶
ValidateID returns an error if the XRPC-URI 'id' is invalid. It returns nil if the XRPC-URI id is valid.
NOTE THAT THIS IS NOT VALIDATING AN XRPC-URI, BUT IS INSTEAD VALIDATING AN XRPC-URI 'id'.
An XRPC-URI 'id' must be an NSID, and its validation rules are defined at: https://atproto.com/specs/nsid
Example ¶
package main
import (
"fmt"
"github.com/reiver/go-xrpcuri"
)
func main() {
var id string = "COM.Example.fooBar"
err := xrpcuri.ValidateID(id)
fmt.Printf("id (i.e., NSID): %s\n", id)
fmt.Printf("validation error: %s\n", err)
}
Output: id (i.e., NSID): COM.Example.fooBar validation error: nsid: character №0 ('C') (U+0043) of domain-authority part №0 ("COM") of domain-authority ("COM.Example") of nsid ("COM.Example.fooBar") is not a digit ('0'-'9'), lower-case letter ('a'-'z'), or a hyphen ('-')
func ValidatePrefix ¶
ValidatePrefix only validates the prefix (i.e., "xrpc://" or "xrpc-unencrypted://") of a potential XRPC-URI or XRPC-unencrypted-URI.
So, it checks to see if the URI starts with "xrpc://" or "xrpc-unencrypted://". And, that is it.
You would use ValidatePrefix if you wanted to be very liberal in what you accept as a valid XRPC-URI or XRPC-unencrypted-URI, including accepting an empty 'authority' / 'host'. I.e., this does a bit more than ValidatePrefix.
ValidatePrefix calls ValidateScheme internally.
For a more thorough validation of the whole XRPC-URI or XRPC-unencrypted-URI instead use Validate.
Example ¶
package main
import (
"fmt"
"github.com/reiver/go-xrpcuri"
)
func main() {
var uri string = "xrpc:example.com"
err := xrpcuri.ValidatePrefix(uri)
fmt.Printf("error: %s\n", err)
}
Output: error: xrpcuri: URI "xrpc:example.com" is not an XRPC-URI or an XRPC-unencrypted-URI because it does not begin with "xrpc://" or "xrpc-unencrypted://"
func ValidateScheme ¶
ValidateScheme only validates the scheme of a potential XRPC-URI or XRPC-unencrypted-URI.
So, it checks to see if the URI starts with "xrpc:" or "xrpc-unencrypted:". And, that is it.
You would use ValidateScheme if you wanted to be very liberal in what you accept as a valid XRPC-URI or XRPC-unencrypted-URI, including not caring if the XRPC-URI or XRPC-unencrypted-URI has a 'authority' / 'host' or not. I.e., this is the minimum amount of validation you can do to validate an XRPC-URI or an XRPC-unencrypted-URI.
Note that you are passing ValidateScheme the whole URI, and not just the scheme.
For a more thorough validation of the whole XRPC-URI pr XRPC-unencrypted-URI instead use Validate.
Alternatively, to validate a bit more than ValidateScheme, without being as thorough as Validate, instead use ValidatePrefix.
Example ¶
package main
import (
"fmt"
"github.com/reiver/go-xrpcuri"
)
func main() {
var uri string = "http://example.com/once/twice/thrice/fource.html"
err := xrpcuri.ValidateScheme(uri)
fmt.Printf("error: %s\n", err)
}
Output: error: xrpcuri: URI "http://example.com/once/twice/thrice/fource.html" is not an XRPC-URI or an XRPC-unencrypted-URI because it does not begin with "xrpc:" or "xrpc-unencrypted:"
Types ¶
type URL ¶
URL represents an 'xrpc' and 'xrpc-unencrypted' URL.
For example:
xrpc://public.api.bsky.app/app.bsky.actor.getProfile?actor=reiver.bsky.social xrpc://example.com/com.example.fooBar xrpc-unencrypted://example.com/com.example.fooBar
func ConstructURL ¶
ConstructURL constructs an XRPC URL (i.e., "xrpc://...") from a 'host', an 'nsid', and a 'query'.
The 'query' can be an empty string.
func ConstructUnencryptedURL ¶
ConstructURL constructs an XRPC URL (i.e., "xrpc-unencrypted://...") from a 'host', an 'nsid', and a 'query'.
The 'query' can be an empty string.
func MustParseURL ¶
MustParseURL is similar to ParseURL except that it panic()s if there is an error (rather than returning it, like how ParseURL does).
func (URL) MustResolve ¶
MustResolve is similar to Resolve except that it panic()s if there is an error (rather than returning it, like how Resolve does).
func (URL) Resolve ¶
Resolve turns an XRPC URL into an HTTP URL.
For example:
"xrpc://public.api.bsky.app/app.bsky.actor.getProfile" -> "https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile" "xrpc://example.com/com.example.fooBar" -> "https://example.com/xrpc/com.example.fooBar" "xrpc-unencrypted://example.com/com.example.fooBar" -> "http://example.com/xrpc/com.example.fooBar"