@@ -21,15 +21,21 @@ type Manager struct {
2121 sdCacheMu sync.RWMutex
2222}
2323
24- func CreateServer (m * Manager ) * http.Server {
24+ type StreamServer struct {
25+ httpServer http.Server
26+ }
27+
28+ func CreateServer (m * Manager ) StreamServer {
2529 contentServeMux := http .NewServeMux ()
26- contentServeMux .HandleFunc ("/" , m .handleStream )
30+ contentServeMux .HandleFunc ("/stream/{sd_hash} " , m .handleStream )
2731
28- return & http.Server {Handler : contentServeMux }
32+ return StreamServer {
33+ httpServer : http.Server {Handler : contentServeMux },
34+ }
2935}
3036
31- func StartServer (contentServer * http. Server , listener net.Listener ) {
32- err := contentServer .Serve (listener )
37+ func (contentServer StreamServer ) StartServer ( listener net.Listener ) {
38+ err := contentServer .httpServer . Serve (listener )
3339 if err != nil && err != http .ErrServerClosed {
3440 fmt .Println ("Error when starting Stream server." )
3541 }
@@ -43,41 +49,39 @@ func NewManager(dhtNode *dht.Node) *Manager {
4349 }
4450}
4551
46- // GetStreamingURL returns the local streaming URL for a given SD hash.
47- func (m * Manager ) GetStreamingURL (sdHash string , port int ) string {
48- return fmt .Sprintf ("http://localhost:%d/stream/%s" , port , sdHash )
49- }
50-
51- func (m * Manager ) handleStream (w http.ResponseWriter , r * http.Request ) {
52- fmt .Println ("Incoming stream request" )
53-
54- sdHash := strings .TrimPrefix (r .URL .Path , "/stream/" )
55- if sdHash == "" || len (sdHash ) != blob .BlobHashLength {
56- http .Error (w , "invalid sd_hash" , http .StatusBadRequest )
57- return
58- }
59-
52+ func (m * Manager ) handleStream (w http.ResponseWriter , req * http.Request ) {
6053 info , _ := debug .ReadBuildInfo ()
6154
62- // CORS for frontend
63- w .Header ().Set ("Access-Control-Allow-Origin" , "*" )
55+ w .Header ().Set ("Accept-Ranges" , "bytes" )
6456 w .Header ().Set ("Access-Control-Allow-Headers" , "Range" )
65- w .Header ().Set ("Access-Control-Expose-Headers" , "Content-Range, Content-Length, Accept-Ranges" )
57+ w .Header ().Set ("Access-Control-Allow-Origin" , "*" )
58+ w .Header ().Set ("Access-Control-Expose-Headers" , "Accept-Ranges, Content-Length, Content-Range" )
6659 w .Header ().Set ("Server" , "LBRYd/" + info .Main .Version )
6760
68- if r . Method == "OPTIONS" {
61+ if strings . EqualFold ( req . Method , "OPTIONS" ) {
6962 w .WriteHeader (http .StatusNoContent )
7063 return
7164 }
7265
66+ if strings .EqualFold (req .Method , "GET" ) {
67+ sdHash := req .PathValue ("sd_hash" )
68+
69+ m .handleSDHash (w , req , sdHash )
70+ return
71+ }
72+
73+ http .Error (w , "HTTP method not allowed." , http .StatusMethodNotAllowed )
74+ }
75+
76+ func (m * Manager ) handleSDHash (w http.ResponseWriter , req * http.Request , sdHash string ) {
7377 // Get or download stream descriptor
7478 sd , err := m .getDescriptor (sdHash )
7579 if err != nil {
7680 log .Printf ("P2P STREAM: failed to get descriptor %s: %v" , sdHash [:12 ], err )
7781 http .Error (w , "failed to load stream" , http .StatusBadGateway )
7882 return
7983 }
80- log .Printf ("P2P STREAM: serving %s (%s)" , sdHash [:12 ], r .Header .Get ("Range" ))
84+ log .Printf ("P2P STREAM: serving %s (%s)" , sdHash [:12 ], req .Header .Get ("Range" ))
8185
8286 contentBlobs := sd .ContentBlobs ()
8387 if len (contentBlobs ) == 0 {
@@ -95,10 +99,9 @@ func (m *Manager) handleStream(w http.ResponseWriter, r *http.Request) {
9599 // Determine MIME type from file extension
96100 mimeType := guessMIME (sd .SuggestedFileName , sd .StreamName )
97101 w .Header ().Set ("Content-Type" , mimeType )
98- w .Header ().Set ("Accept-Ranges" , "bytes" )
99102
100103 // Parse range header
101- rangeHeader := r .Header .Get ("Range" )
104+ rangeHeader := req .Header .Get ("Range" )
102105 var start , end int64
103106 if rangeHeader != "" && strings .HasPrefix (rangeHeader , "bytes=" ) {
104107 rangeParts := strings .TrimPrefix (rangeHeader , "bytes=" )
0 commit comments