Update interface definitions and wrapper improvements.
Wrapping default behavior can now be overridden.
This commit is contained in:
parent
bd8220a56c
commit
cc83b751a1
|
@ -13,6 +13,10 @@ import (
|
|||
// Protocol), client-to-server (Social API), or both. The Actor represents the
|
||||
// server in either use case.
|
||||
//
|
||||
// An actor can be created by calling NewSocialActor (only the Social Protocol
|
||||
// is supported), NewFederatingActor (only the Federating Protocol is
|
||||
// supported), NewActor (both are supported), or NewCustomActor (neither are).
|
||||
//
|
||||
// Not all Actors have the same behaviors depending on the constructor used to
|
||||
// create them. Refer to the constructor's documentation to determine the exact
|
||||
// behavior of the Actor on an application.
|
||||
|
|
|
@ -124,11 +124,11 @@ func NewActor(c CommonBehavior,
|
|||
// for the Social Protocol, Federating Protocol, or both.
|
||||
//
|
||||
// It still uses the library as a high-level scaffold, which has the benefit of
|
||||
// allowing applications to grow into a custom solution without having to
|
||||
// refactor the code that passes HTTP requests into the Actor.
|
||||
// allowing applications to grow into a custom ActivityPub solution without
|
||||
// having to refactor the code that passes HTTP requests into the Actor.
|
||||
//
|
||||
// It is possible to create a DelegateActor that is not ActivityPub compliant.
|
||||
// Use with care.
|
||||
// Use with due care.
|
||||
func NewCustomActor(delegate DelegateActor,
|
||||
enableSocialProtocol, enableFederatedProtocol bool,
|
||||
clock Clock) Actor {
|
||||
|
|
|
@ -7,6 +7,9 @@ import (
|
|||
|
||||
// Common contains functions required for both the Social API and Federating
|
||||
// Protocol.
|
||||
//
|
||||
// It is passed to the library as a dependency injection from the client
|
||||
// application.
|
||||
type CommonBehavior interface {
|
||||
// AuthenticateGetInbox delegates the authentication of a GET to an
|
||||
// inbox.
|
||||
|
|
|
@ -10,14 +10,17 @@ import (
|
|||
// DelegateActor contains the detailed interface an application must satisfy in
|
||||
// order to implement the ActivityPub specification.
|
||||
//
|
||||
// Note that an implementation of this interface is implicitly provided in the
|
||||
// calls to NewActor, NewSocialActor, and NewFederatingActor.
|
||||
//
|
||||
// Implementing the DelegateActor requires familiarity with the ActivityPub
|
||||
// specification, it does not a strong enough abstraction for the client
|
||||
// specification because it does not a strong enough abstraction for the client
|
||||
// application to ignore the ActivityPub spec. It is very possible to implement
|
||||
// this interface and build a foot-gun that trashes the fediverse without being
|
||||
// ActivityPub compliant. Please use with due consideration.
|
||||
//
|
||||
// Alternatively, build an application that uses the parts of the pub library
|
||||
// that does not require implementing a DelegateActor so that the ActivityPub
|
||||
// that do not require implementing a DelegateActor so that the ActivityPub
|
||||
// implementation is completely provided out of the box.
|
||||
type DelegateActor interface {
|
||||
// AuthenticatePostInbox delegates the authentication of a POST to an
|
||||
|
@ -144,8 +147,8 @@ type DelegateActor interface {
|
|||
//
|
||||
// If an error is returned, it is returned to the caller of PostOutbox.
|
||||
Deliver(c context.Context, outbox *url.URL, activity Activity) error
|
||||
// AuthenticatePostOutbox delegates the authentication of a POST to an
|
||||
// outbox.
|
||||
// AuthenticatePostOutbox delegates the authentication and authorization
|
||||
// of a POST to an outbox.
|
||||
//
|
||||
// Only called if the Social API is enabled.
|
||||
//
|
||||
|
|
|
@ -12,6 +12,9 @@ import (
|
|||
//
|
||||
// It is only required if the client application wants to support the server-to-
|
||||
// server, or federating, protocol.
|
||||
//
|
||||
// It is passed to the library as a dependency injection from the client
|
||||
// application.
|
||||
type FederatingProtocol interface {
|
||||
// AuthenticatePostInbox delegates the authentication of a POST to an
|
||||
// inbox.
|
||||
|
@ -46,12 +49,21 @@ type FederatingProtocol interface {
|
|||
// to be processed.
|
||||
Blocked(c context.Context, actorIRIs []*url.URL) (blocked bool, err error)
|
||||
// Callbacks returns the application logic that handles ActivityStreams
|
||||
// received from federating peers. Note that certain types of callbacks
|
||||
// will be 'wrapped' with default behaviors supported natively by the
|
||||
// library. Other callbacks compatible with streams.TypeResolver can
|
||||
// be specified by 'other'.
|
||||
// received from federating peers.
|
||||
//
|
||||
// Note that the functions in 'wrapped' cannot be provided in 'other'.
|
||||
// Note that certain types of callbacks will be 'wrapped' with default
|
||||
// behaviors supported natively by the library. Other callbacks
|
||||
// compatible with streams.TypeResolver can be specified by 'other'.
|
||||
//
|
||||
// For example, setting the 'Create' field in the
|
||||
// FederatingWrappedCallbacks lets an application dependency inject
|
||||
// additional behaviors they want to take place, including the default
|
||||
// behavior supplied by this library. This is guaranteed to be compliant
|
||||
// with the ActivityPub Social protocol.
|
||||
//
|
||||
// To override the default behavior, instead supply the function in
|
||||
// 'other', which does not guarantee the application will be compliant
|
||||
// with the ActivityPub Social Protocol.
|
||||
Callbacks(c context.Context) (wrapped FederatingWrappedCallbacks, other []interface{})
|
||||
// MaxInboxForwardingRecursionDepth determines how deep to search within
|
||||
// an activity to determine if inbox forwarding needs to occur.
|
||||
|
|
|
@ -135,63 +135,91 @@ type FederatingWrappedCallbacks struct {
|
|||
newTransport func(c context.Context, actorBoxIRI *url.URL, gofedAgent string) (t Transport, err error)
|
||||
}
|
||||
|
||||
// disjoint ensures that the functions given do not share a type signature with
|
||||
// the functions being wrapped in FederatingWrappedCallbacks.
|
||||
func (w FederatingWrappedCallbacks) disjoint(fns []interface{}) error {
|
||||
// TODO: Instead, if provided in "other" it should override this behavior.
|
||||
var s string
|
||||
// callbacks returns the WrappedCallbacks members into a single interface slice
|
||||
// for use in streams.Resolver callbacks.
|
||||
//
|
||||
// If the given functions have a type that collides with the default behavior,
|
||||
// then disable our default behavior
|
||||
func (w FederatingWrappedCallbacks) callbacks(fns []interface{}) []interface{} {
|
||||
enableCreate := true
|
||||
enableUpdate := true
|
||||
enableDelete := true
|
||||
enableFollow := true
|
||||
enableAccept := true
|
||||
enableReject := true
|
||||
enableAdd := true
|
||||
enableRemove := true
|
||||
enableLike := true
|
||||
enableAnnounce := true
|
||||
enableUndo := true
|
||||
enableBlock := true
|
||||
for _, fn := range fns {
|
||||
switch fn.(type) {
|
||||
default:
|
||||
// OK, no collision
|
||||
continue
|
||||
case func(context.Context, vocab.ActivityStreamsCreate) error:
|
||||
s = "Create"
|
||||
enableCreate = false
|
||||
case func(context.Context, vocab.ActivityStreamsUpdate) error:
|
||||
s = "Update"
|
||||
enableUpdate = false
|
||||
case func(context.Context, vocab.ActivityStreamsDelete) error:
|
||||
s = "Delete"
|
||||
enableDelete = false
|
||||
case func(context.Context, vocab.ActivityStreamsFollow) error:
|
||||
s = "Follow"
|
||||
enableFollow = false
|
||||
case func(context.Context, vocab.ActivityStreamsAccept) error:
|
||||
s = "Accept"
|
||||
enableAccept = false
|
||||
case func(context.Context, vocab.ActivityStreamsReject) error:
|
||||
s = "Reject"
|
||||
enableReject = false
|
||||
case func(context.Context, vocab.ActivityStreamsAdd) error:
|
||||
s = "Add"
|
||||
enableAdd = false
|
||||
case func(context.Context, vocab.ActivityStreamsRemove) error:
|
||||
s = "Remove"
|
||||
enableRemove = false
|
||||
case func(context.Context, vocab.ActivityStreamsLike) error:
|
||||
s = "Like"
|
||||
enableLike = false
|
||||
case func(context.Context, vocab.ActivityStreamsAnnounce) error:
|
||||
s = "Announce"
|
||||
enableAnnounce = false
|
||||
case func(context.Context, vocab.ActivityStreamsUndo) error:
|
||||
s = "Undo"
|
||||
enableUndo = false
|
||||
case func(context.Context, vocab.ActivityStreamsBlock) error:
|
||||
s = "Block"
|
||||
enableBlock = false
|
||||
}
|
||||
return fmt.Errorf("callback function handling type %q conflicts with FederatingWrappedCallbacks", s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// callbacks returns the WrappedCallbacks members into a single interface slice
|
||||
// for use in streams.Resolver callbacks.
|
||||
func (w FederatingWrappedCallbacks) callbacks() []interface{} {
|
||||
return []interface{}{
|
||||
w.create,
|
||||
w.update,
|
||||
w.deleteFn,
|
||||
w.follow,
|
||||
w.accept,
|
||||
w.reject,
|
||||
w.add,
|
||||
w.remove,
|
||||
w.like,
|
||||
w.announce,
|
||||
w.undo,
|
||||
w.block,
|
||||
if enableCreate {
|
||||
fns = append(fns, w.create)
|
||||
}
|
||||
if enableUpdate {
|
||||
fns = append(fns, w.update)
|
||||
}
|
||||
if enableDelete {
|
||||
fns = append(fns, w.deleteFn)
|
||||
}
|
||||
if enableFollow {
|
||||
fns = append(fns, w.follow)
|
||||
}
|
||||
if enableAccept {
|
||||
fns = append(fns, w.accept)
|
||||
}
|
||||
if enableReject {
|
||||
fns = append(fns, w.reject)
|
||||
}
|
||||
if enableAdd {
|
||||
fns = append(fns, w.add)
|
||||
}
|
||||
if enableRemove {
|
||||
fns = append(fns, w.remove)
|
||||
}
|
||||
if enableLike {
|
||||
fns = append(fns, w.like)
|
||||
}
|
||||
if enableAnnounce {
|
||||
fns = append(fns, w.announce)
|
||||
}
|
||||
if enableUndo {
|
||||
fns = append(fns, w.undo)
|
||||
}
|
||||
if enableBlock {
|
||||
fns = append(fns, w.block)
|
||||
}
|
||||
return fns
|
||||
}
|
||||
|
||||
// create implements the federating Create activity side effects.
|
||||
|
|
|
@ -5,12 +5,12 @@ import (
|
|||
"net/url"
|
||||
)
|
||||
|
||||
// inReplyToer is an ActivityStreams type with a 'inReplyTo' property
|
||||
// inReplyToer is an ActivityStreams type with an 'inReplyTo' property
|
||||
type inReplyToer interface {
|
||||
GetActivityStreamsInReplyTo() vocab.ActivityStreamsInReplyToProperty
|
||||
}
|
||||
|
||||
// objecter is an ActivityStreams type with a 'object' property
|
||||
// objecter is an ActivityStreams type with an 'object' property
|
||||
type objecter interface {
|
||||
GetActivityStreamsObject() vocab.ActivityStreamsObjectProperty
|
||||
}
|
||||
|
@ -30,13 +30,13 @@ type hrefer interface {
|
|||
GetActivityStreamsHref() vocab.ActivityStreamsHrefProperty
|
||||
}
|
||||
|
||||
// itemser is an ActivityStreams type with a 'items' property
|
||||
// itemser is an ActivityStreams type with an 'items' property
|
||||
type itemser interface {
|
||||
GetActivityStreamsItems() vocab.ActivityStreamsItemsProperty
|
||||
SetActivityStreamsItems(vocab.ActivityStreamsItemsProperty)
|
||||
}
|
||||
|
||||
// orderedItemser is an ActivityStreams type with a 'orderedItems' property
|
||||
// orderedItemser is an ActivityStreams type with an 'orderedItems' property
|
||||
type orderedItemser interface {
|
||||
GetActivityStreamsOrderedItems() vocab.ActivityStreamsOrderedItemsProperty
|
||||
SetActivityStreamsOrderedItems(vocab.ActivityStreamsOrderedItemsProperty)
|
||||
|
@ -47,7 +47,7 @@ type publisheder interface {
|
|||
GetActivityStreamsPublished() vocab.ActivityStreamsPublishedProperty
|
||||
}
|
||||
|
||||
// updateder is an ActivityStreams type with a 'updateder' property
|
||||
// updateder is an ActivityStreams type with an 'updateder' property
|
||||
type updateder interface {
|
||||
GetActivityStreamsUpdated() vocab.ActivityStreamsUpdatedProperty
|
||||
}
|
||||
|
@ -76,18 +76,18 @@ type bccer interface {
|
|||
SetActivityStreamsBcc(i vocab.ActivityStreamsBccProperty)
|
||||
}
|
||||
|
||||
// audiencer is an ActivityStreams type with a 'audience' property
|
||||
// audiencer is an ActivityStreams type with an 'audience' property
|
||||
type audiencer interface {
|
||||
GetActivityStreamsAudience() vocab.ActivityStreamsAudienceProperty
|
||||
SetActivityStreamsAudience(i vocab.ActivityStreamsAudienceProperty)
|
||||
}
|
||||
|
||||
// inboxer is an ActivityStreams type with a 'inbox' property
|
||||
// inboxer is an ActivityStreams type with an 'inbox' property
|
||||
type inboxer interface {
|
||||
GetActivityStreamsInbox() vocab.ActivityStreamsInboxProperty
|
||||
}
|
||||
|
||||
// attributedToer is an ActivityStreams type with a 'attributedTo' property
|
||||
// attributedToer is an ActivityStreams type with an 'attributedTo' property
|
||||
type attributedToer interface {
|
||||
GetActivityStreamsAttributedTo() vocab.ActivityStreamsAttributedToProperty
|
||||
SetActivityStreamsAttributedTo(i vocab.ActivityStreamsAttributedToProperty)
|
||||
|
@ -105,7 +105,7 @@ type shareser interface {
|
|||
SetActivityStreamsShares(i vocab.ActivityStreamsSharesProperty)
|
||||
}
|
||||
|
||||
// actorer is an ActivityStreams type with a 'actor' property
|
||||
// actorer is an ActivityStreams type with an 'actor' property
|
||||
type actorer interface {
|
||||
GetActivityStreamsActor() vocab.ActivityStreamsActorProperty
|
||||
SetActivityStreamsActor(i vocab.ActivityStreamsActorProperty)
|
||||
|
|
|
@ -102,10 +102,7 @@ func (a *sideEffectActor) PostInbox(c context.Context, inboxIRI *url.URL, activi
|
|||
wrapped.db = a.db
|
||||
wrapped.inboxIRI = inboxIRI
|
||||
wrapped.newTransport = a.s2s.NewTransport
|
||||
if err = wrapped.disjoint(other); err != nil {
|
||||
return err
|
||||
}
|
||||
res, err := streams.NewTypeResolver(append(wrapped.callbacks(), other...))
|
||||
res, err := streams.NewTypeResolver(wrapped.callbacks(other))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -283,10 +280,7 @@ func (a *sideEffectActor) PostOutbox(c context.Context, activity Activity, outbo
|
|||
wrapped.rawActivity = rawJSON
|
||||
wrapped.clock = a.clock
|
||||
wrapped.deliverable = &deliverable
|
||||
if e = wrapped.disjoint(other); e != nil {
|
||||
return
|
||||
}
|
||||
res, err := streams.NewTypeResolver(append(wrapped.callbacks(), other...))
|
||||
res, err := streams.NewTypeResolver(wrapped.callbacks(other))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -11,6 +11,9 @@ import (
|
|||
//
|
||||
// It is only required if the client application wants to support the client-to-
|
||||
// server, or social, protocol.
|
||||
//
|
||||
// It is passed to the library as a dependency injection from the client
|
||||
// application.
|
||||
type SocialProtocol interface {
|
||||
// AuthenticatePostOutbox delegates the authentication of a POST to an
|
||||
// outbox.
|
||||
|
@ -32,12 +35,21 @@ type SocialProtocol interface {
|
|||
// to be processed.
|
||||
AuthenticatePostOutbox(c context.Context, w http.ResponseWriter, r *http.Request) (shouldReturn bool, err error)
|
||||
// Callbacks returns the application logic that handles ActivityStreams
|
||||
// received from C2S clients. Note that certain types of callbacks
|
||||
// will be 'wrapped' with default behaviors supported natively by the
|
||||
// library. Other callbacks compatible with streams.TypeResolver can
|
||||
// be specified by 'other'.
|
||||
// received from C2S clients.
|
||||
//
|
||||
// Note that the functions in 'wrapped' cannot be provided in 'other'.
|
||||
// Note that certain types of callbacks will be 'wrapped' with default
|
||||
// behaviors supported natively by the library. Other callbacks
|
||||
// compatible with streams.TypeResolver can be specified by 'other'.
|
||||
//
|
||||
// For example, setting the 'Create' field in the SocialWrappedCallbacks
|
||||
// lets an application dependency inject additional behaviors they want
|
||||
// to take place, including the default behavior supplied by this
|
||||
// library. This is guaranteed to be compliant with the ActivityPub
|
||||
// Social protocol.
|
||||
//
|
||||
// To override the default behavior, instead supply the function in
|
||||
// 'other', which does not guarantee the application will be compliant
|
||||
// with the ActivityPub Social Protocol.
|
||||
Callbacks(c context.Context) (wrapped SocialWrappedCallbacks, other []interface{})
|
||||
// GetOutbox returns the OrderedCollection inbox of the actor for this
|
||||
// context. It is up to the implementation to provide the correct
|
||||
|
|
|
@ -42,22 +42,35 @@ type SocialWrappedCallbacks struct {
|
|||
// Add handles additional side effects for the Add ActivityStreams
|
||||
// type.
|
||||
//
|
||||
// TODO: Describe
|
||||
//
|
||||
// The wrapping function will add the 'object' IRIs to a specific
|
||||
// 'target' collection if the 'target' collection(s) live on this
|
||||
// server.
|
||||
Add func(context.Context, vocab.ActivityStreamsAdd) error
|
||||
// Remove handles additional side effects for the Remove ActivityStreams
|
||||
// type.
|
||||
//
|
||||
// TODO: Describe
|
||||
// The wrapping function will remove all 'object' IRIs from a specific
|
||||
// 'target' collection if the 'target' collection(s) live on this
|
||||
// server.
|
||||
Remove func(context.Context, vocab.ActivityStreamsRemove) error
|
||||
// Like handles additional side effects for the Like ActivityStreams
|
||||
// type.
|
||||
//
|
||||
// TODO: Describe
|
||||
// The wrapping function will add the objects on the activity to the
|
||||
// "liked" collection of this actor.
|
||||
Like func(context.Context, vocab.ActivityStreamsLike) error
|
||||
// Undo handles additional side effects for the Undo ActivityStreams
|
||||
// type.
|
||||
//
|
||||
// TODO: Describe
|
||||
//
|
||||
// The wrapping function ensures the 'actor' on the 'Undo'
|
||||
// is be the same as the 'actor' on all Activities being undone.
|
||||
// It enforces that the actors on the Undo must correspond to all of the
|
||||
// 'object' actors in some manner.
|
||||
//
|
||||
// It is expected that the application will implement the proper
|
||||
// reversal of activities that are being undone.
|
||||
Undo func(context.Context, vocab.ActivityStreamsUndo) error
|
||||
// Block handles additional side effects for the Block ActivityStreams
|
||||
// type.
|
||||
|
@ -89,53 +102,73 @@ type SocialWrappedCallbacks struct {
|
|||
deliverable *bool
|
||||
}
|
||||
|
||||
// disjoint ensures that the functions given do not share a type signature with
|
||||
// the functions being wrapped in SocialWrappedCallbacks.
|
||||
func (w SocialWrappedCallbacks) disjoint(fns []interface{}) error {
|
||||
var s string
|
||||
// callbacks returns the WrappedCallbacks members into a single interface slice
|
||||
// for use in streams.Resolver callbacks.
|
||||
//
|
||||
// If the given functions have a type that collides with the default behavior,
|
||||
// then disable our default behavior
|
||||
func (w SocialWrappedCallbacks) callbacks(fns []interface{}) []interface{} {
|
||||
enableCreate := true
|
||||
enableUpdate := true
|
||||
enableDelete := true
|
||||
enableFollow := true
|
||||
enableAdd := true
|
||||
enableRemove := true
|
||||
enableLike := true
|
||||
enableUndo := true
|
||||
enableBlock := true
|
||||
for _, fn := range fns {
|
||||
switch fn.(type) {
|
||||
default:
|
||||
// OK, no collision
|
||||
continue
|
||||
case func(context.Context, vocab.ActivityStreamsCreate) error:
|
||||
s = "Create"
|
||||
enableCreate = false
|
||||
case func(context.Context, vocab.ActivityStreamsUpdate) error:
|
||||
s = "Update"
|
||||
enableUpdate = false
|
||||
case func(context.Context, vocab.ActivityStreamsDelete) error:
|
||||
s = "Delete"
|
||||
enableDelete = false
|
||||
case func(context.Context, vocab.ActivityStreamsFollow) error:
|
||||
s = "Follow"
|
||||
enableFollow = false
|
||||
case func(context.Context, vocab.ActivityStreamsAdd) error:
|
||||
s = "Add"
|
||||
enableAdd = false
|
||||
case func(context.Context, vocab.ActivityStreamsRemove) error:
|
||||
s = "Remove"
|
||||
enableRemove = false
|
||||
case func(context.Context, vocab.ActivityStreamsLike) error:
|
||||
s = "Like"
|
||||
enableLike = false
|
||||
case func(context.Context, vocab.ActivityStreamsUndo) error:
|
||||
s = "Undo"
|
||||
enableUndo = false
|
||||
case func(context.Context, vocab.ActivityStreamsBlock) error:
|
||||
s = "Block"
|
||||
enableBlock = false
|
||||
}
|
||||
return fmt.Errorf("callback function handling type %q conflicts with SocialWrappedCallbacks", s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// callbacks returns the WrappedCallbacks members into a single interface slice
|
||||
// for use in streams.Resolver callbacks.
|
||||
func (w SocialWrappedCallbacks) callbacks() []interface{} {
|
||||
return []interface{}{
|
||||
w.create,
|
||||
w.update,
|
||||
w.deleteFn,
|
||||
w.follow,
|
||||
w.add,
|
||||
w.remove,
|
||||
w.like,
|
||||
w.undo,
|
||||
w.block,
|
||||
if enableCreate {
|
||||
fns = append(fns, w.create)
|
||||
}
|
||||
if enableUpdate {
|
||||
fns = append(fns, w.update)
|
||||
}
|
||||
if enableDelete {
|
||||
fns = append(fns, w.deleteFn)
|
||||
}
|
||||
if enableFollow {
|
||||
fns = append(fns, w.follow)
|
||||
}
|
||||
if enableAdd {
|
||||
fns = append(fns, w.add)
|
||||
}
|
||||
if enableRemove {
|
||||
fns = append(fns, w.remove)
|
||||
}
|
||||
if enableLike {
|
||||
fns = append(fns, w.like)
|
||||
}
|
||||
if enableUndo {
|
||||
fns = append(fns, w.undo)
|
||||
}
|
||||
if enableBlock {
|
||||
fns = append(fns, w.block)
|
||||
}
|
||||
return fns
|
||||
}
|
||||
|
||||
// create implements the social Create activity side effects.
|
||||
|
|
|
@ -19,8 +19,15 @@ const (
|
|||
acceptHeaderValue = "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""
|
||||
)
|
||||
|
||||
// Transport makes ActivityStreams calls to other servers in order to POST or
|
||||
// GET ActivityStreams data.
|
||||
// Transport makes ActivityStreams calls to other servers in order to send or
|
||||
// receive ActivityStreams data.
|
||||
//
|
||||
// It is responsible for setting the appropriate request headers, signing the
|
||||
// requests if needed, and facilitating the traffic between this server and
|
||||
// another.
|
||||
//
|
||||
// The transport is exclusively used to issue requests on behalf of an actor,
|
||||
// and is never sending requests on behalf of the server in general.
|
||||
//
|
||||
// It may be reused multiple times, but never concurrently.
|
||||
type Transport interface {
|
||||
|
@ -52,10 +59,24 @@ type HttpSigTransport struct {
|
|||
privKey crypto.PrivateKey
|
||||
}
|
||||
|
||||
// NewHttpSigTransport returns a new HttpSigTransport.
|
||||
// NewHttpSigTransport returns a new Transport.
|
||||
//
|
||||
// It sends requests specifically on behalf of a specific actor on this server.
|
||||
// The actor's credentials are used to add an HTTP Signature to requests, which
|
||||
// requires an actor's private key, a unique identifier for their public key,
|
||||
// and an HTTP Signature signing algorithm.
|
||||
//
|
||||
// The client lets users issue requests through any HTTP client, including the
|
||||
// standard library's HTTP client.
|
||||
//
|
||||
// The appAgent uniquely identifies the calling application's requests, so peers
|
||||
// may aid debugging the requests incoming from this server. Note that the
|
||||
// agent string will also include one for go-fed, so at minimum peer servers can
|
||||
// reach out to the go-fed library to aid in notifying implementors of malformed
|
||||
// or unsupported requests.
|
||||
func NewHttpSigTransport(
|
||||
client HttpClient,
|
||||
appAgent, gofedAgent string,
|
||||
appAgent string,
|
||||
clock Clock,
|
||||
signer httpsig.Signer,
|
||||
pubKeyId string,
|
||||
|
@ -63,7 +84,7 @@ func NewHttpSigTransport(
|
|||
return &HttpSigTransport{
|
||||
client: client,
|
||||
appAgent: appAgent,
|
||||
gofedAgent: gofedAgent,
|
||||
gofedAgent: goFedUserAgent(),
|
||||
clock: clock,
|
||||
signer: signer,
|
||||
pubKeyId: pubKeyId,
|
||||
|
@ -71,7 +92,8 @@ func NewHttpSigTransport(
|
|||
}
|
||||
}
|
||||
|
||||
// Dereferences with a request signed with an HTTP Signature.
|
||||
// Dereference sends a GET request signed with an HTTP Signature to obtain an
|
||||
// ActivityStreams value.
|
||||
func (h HttpSigTransport) Dereference(c context.Context, iri *url.URL) ([]byte, error) {
|
||||
req, err := http.NewRequest("GET", iri.String(), nil)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue