@@ -3,187 +3,9 @@ package server
33import (
44 "context"
55 "net/http"
6- "net/url"
7- "strings"
8- "time"
96)
107
118// HTTPContextFunc is a function that takes an existing context and the current
129// request and returns a potentially modified context based on the request
1310// content. This can be used to inject context values from headers, for example.
1411type HTTPContextFunc func (ctx context.Context , r * http.Request ) context.Context
15-
16- // httpTransportConfigurable is an internal interface for shared HTTP transport configuration.
17- type httpTransportConfigurable interface {
18- setBasePath (string )
19- setDynamicBasePath (DynamicBasePathFunc )
20- setKeepAliveInterval (time.Duration )
21- setKeepAlive (bool )
22- setContextFunc (HTTPContextFunc )
23- setHTTPServer (* http.Server )
24- setBaseURL (string )
25- }
26-
27- // HTTPTransportOption is a function that configures an httpTransportConfigurable.
28- type HTTPTransportOption func (httpTransportConfigurable )
29-
30- // Option interfaces and wrappers for server configuration
31- // Base option interface
32- type HTTPServerOption interface {
33- isHTTPServerOption ()
34- }
35-
36- // SSE-specific option interface
37- type SSEOption interface {
38- HTTPServerOption
39- applyToSSE (* SSEServer )
40- }
41-
42- // StreamableHTTP-specific option interface
43- type StreamableHTTPOption interface {
44- HTTPServerOption
45- applyToStreamableHTTP (* StreamableHTTPServer )
46- }
47-
48- // Common options that work with both server types
49- type CommonHTTPServerOption interface {
50- SSEOption
51- StreamableHTTPOption
52- }
53-
54- // Wrapper for SSE-specific functional options
55- type sseOption func (* SSEServer )
56-
57- func (o sseOption ) isHTTPServerOption () {}
58- func (o sseOption ) applyToSSE (s * SSEServer ) { o (s ) }
59-
60- // Wrapper for StreamableHTTP-specific functional options
61- type streamableHTTPOption func (* StreamableHTTPServer )
62-
63- func (o streamableHTTPOption ) isHTTPServerOption () {}
64- func (o streamableHTTPOption ) applyToStreamableHTTP (s * StreamableHTTPServer ) { o (s ) }
65-
66- // Refactor commonOption to use a single apply func(httpTransportConfigurable)
67- type commonOption struct {
68- apply func (httpTransportConfigurable )
69- }
70-
71- func (o commonOption ) isHTTPServerOption () {}
72- func (o commonOption ) applyToSSE (s * SSEServer ) { o .apply (s ) }
73- func (o commonOption ) applyToStreamableHTTP (s * StreamableHTTPServer ) { o .apply (s ) }
74-
75- // TODO: This is a stub implementation of StreamableHTTPServer just to show how
76- // to use it with the new options interfaces.
77- type StreamableHTTPServer struct {}
78-
79- // Add stub methods to satisfy httpTransportConfigurable
80-
81- func (s * StreamableHTTPServer ) setBasePath (string ) {}
82- func (s * StreamableHTTPServer ) setDynamicBasePath (DynamicBasePathFunc ) {}
83- func (s * StreamableHTTPServer ) setKeepAliveInterval (time.Duration ) {}
84- func (s * StreamableHTTPServer ) setKeepAlive (bool ) {}
85- func (s * StreamableHTTPServer ) setContextFunc (HTTPContextFunc ) {}
86- func (s * StreamableHTTPServer ) setHTTPServer (srv * http.Server ) {}
87- func (s * StreamableHTTPServer ) setBaseURL (baseURL string ) {}
88-
89- // Ensure the option types implement the correct interfaces
90- var (
91- _ httpTransportConfigurable = (* StreamableHTTPServer )(nil )
92- _ SSEOption = sseOption (nil )
93- _ StreamableHTTPOption = streamableHTTPOption (nil )
94- _ CommonHTTPServerOption = commonOption {}
95- )
96-
97- // WithStaticBasePath adds a new option for setting a static base path.
98- // This is useful for mounting the server at a known, fixed path.
99- func WithStaticBasePath (basePath string ) CommonHTTPServerOption {
100- return commonOption {
101- apply : func (c httpTransportConfigurable ) {
102- c .setBasePath (basePath )
103- },
104- }
105- }
106-
107- // DynamicBasePathFunc allows the user to provide a function to generate the
108- // base path for a given request and sessionID. This is useful for cases where
109- // the base path is not known at the time of SSE server creation, such as when
110- // using a reverse proxy or when the base path is dynamically generated. The
111- // function should return the base path (e.g., "/mcp/tenant123").
112- type DynamicBasePathFunc func (r * http.Request , sessionID string ) string
113-
114- // WithDynamicBasePath accepts a function for generating the base path.
115- // This is useful for cases where the base path is not known at the time of server creation,
116- // such as when using a reverse proxy or when the server is mounted at a dynamic path.
117- func WithDynamicBasePath (fn DynamicBasePathFunc ) CommonHTTPServerOption {
118- return commonOption {
119- apply : func (c httpTransportConfigurable ) {
120- c .setDynamicBasePath (fn )
121- },
122- }
123- }
124-
125- // WithKeepAliveInterval sets the keep-alive interval for the transport.
126- // When enabled, the server will periodically send ping events to keep the connection alive.
127- func WithKeepAliveInterval (interval time.Duration ) CommonHTTPServerOption {
128- return commonOption {
129- apply : func (c httpTransportConfigurable ) {
130- c .setKeepAliveInterval (interval )
131- },
132- }
133- }
134-
135- // WithKeepAlive enables or disables keep-alive for the transport.
136- // When enabled, the server will send periodic keep-alive events to clients.
137- func WithKeepAlive (keepAlive bool ) CommonHTTPServerOption {
138- return commonOption {
139- apply : func (c httpTransportConfigurable ) {
140- c .setKeepAlive (keepAlive )
141- },
142- }
143- }
144-
145- // WithHTTPContextFunc sets a function that will be called to customize the context
146- // for the server using the incoming request. This is useful for injecting
147- // context values from headers or other request properties.
148- func WithHTTPContextFunc (fn HTTPContextFunc ) CommonHTTPServerOption {
149- return commonOption {
150- apply : func (c httpTransportConfigurable ) {
151- c .setContextFunc (fn )
152- },
153- }
154- }
155-
156- // WithBaseURL sets the base URL for the HTTP transport server.
157- // This is useful for configuring the externally visible base URL for clients.
158- func WithBaseURL (baseURL string ) CommonHTTPServerOption {
159- return commonOption {
160- apply : func (c httpTransportConfigurable ) {
161- if baseURL != "" {
162- u , err := url .Parse (baseURL )
163- if err != nil {
164- return
165- }
166- if u .Scheme != "http" && u .Scheme != "https" {
167- return
168- }
169- if u .Host == "" || strings .HasPrefix (u .Host , ":" ) {
170- return
171- }
172- if len (u .Query ()) > 0 {
173- return
174- }
175- }
176- c .setBaseURL (strings .TrimSuffix (baseURL , "/" ))
177- },
178- }
179- }
180-
181- // WithHTTPServer sets the HTTP server instance for the transport.
182- // This is useful for advanced scenarios where you want to provide your own http.Server.
183- func WithHTTPServer (srv * http.Server ) CommonHTTPServerOption {
184- return commonOption {
185- apply : func (c httpTransportConfigurable ) {
186- c .setHTTPServer (srv )
187- },
188- }
189- }
0 commit comments