You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
3.1 KiB
103 lines
3.1 KiB
package server |
|
|
|
import ( |
|
"context" |
|
"fmt" |
|
"net/http" |
|
"os" |
|
"os/signal" |
|
"syscall" |
|
"time" |
|
|
|
gonostr "github.com/nbd-wtf/go-nostr" |
|
|
|
"gitcitadel-online/internal/cache" |
|
"gitcitadel-online/internal/generator" |
|
"gitcitadel-online/internal/logger" |
|
"gitcitadel-online/internal/nostr" |
|
) |
|
|
|
// Server represents the HTTP server |
|
type Server struct { |
|
httpServer *http.Server |
|
cache *cache.Cache |
|
feedCache *cache.FeedCache |
|
mediaCache *cache.MediaCache |
|
port int |
|
issueService IssueServiceInterface |
|
repoAnnouncement string |
|
htmlGenerator HTMLGeneratorInterface |
|
nostrClient *nostr.Client |
|
siteURL string |
|
} |
|
|
|
// IssueServiceInterface defines the interface for issue service |
|
type IssueServiceInterface interface { |
|
FetchRepoAnnouncement(ctx context.Context, repoNaddr string) (*nostr.RepoAnnouncement, error) |
|
PublishIssue(ctx context.Context, repoAnnouncement *nostr.RepoAnnouncement, req *nostr.IssueRequest, privateKey string) (string, error) |
|
PublishSignedIssue(ctx context.Context, signedEvent *gonostr.Event) (string, error) |
|
} |
|
|
|
// HTMLGeneratorInterface defines the interface for HTML generator |
|
type HTMLGeneratorInterface interface { |
|
GenerateContactPage(success bool, errorMsg string, eventID string, formData map[string]string, repoAnnouncement *nostr.RepoAnnouncement, feedItems []generator.FeedItemInfo, profile *nostr.Profile) (string, error) |
|
GenerateErrorPage(statusCode int, feedItems []generator.FeedItemInfo) (string, error) |
|
} |
|
|
|
// NewServer creates a new HTTP server |
|
func NewServer(port int, pageCache *cache.Cache, feedCache *cache.FeedCache, mediaCache *cache.MediaCache, issueService IssueServiceInterface, repoAnnouncement string, htmlGenerator HTMLGeneratorInterface, nostrClient *nostr.Client, siteURL string) *Server { |
|
s := &Server{ |
|
cache: pageCache, |
|
feedCache: feedCache, |
|
mediaCache: mediaCache, |
|
port: port, |
|
issueService: issueService, |
|
repoAnnouncement: repoAnnouncement, |
|
htmlGenerator: htmlGenerator, |
|
nostrClient: nostrClient, |
|
siteURL: siteURL, |
|
} |
|
|
|
mux := http.NewServeMux() |
|
|
|
// Setup routes |
|
s.setupRoutes(mux) |
|
|
|
s.httpServer = &http.Server{ |
|
Addr: fmt.Sprintf(":%d", port), |
|
Handler: s.middleware(mux), |
|
ReadTimeout: 15 * time.Second, |
|
WriteTimeout: 15 * time.Second, |
|
IdleTimeout: 60 * time.Second, |
|
} |
|
|
|
return s |
|
} |
|
|
|
// Start starts the HTTP server |
|
func (s *Server) Start() error { |
|
logger.Infof("Starting server on port %d", s.port) |
|
return s.httpServer.ListenAndServe() |
|
} |
|
|
|
// Shutdown gracefully shuts down the server |
|
func (s *Server) Shutdown(ctx context.Context) error { |
|
return s.httpServer.Shutdown(ctx) |
|
} |
|
|
|
// WaitForShutdown waits for shutdown signals |
|
func (s *Server) WaitForShutdown() { |
|
quit := make(chan os.Signal, 1) |
|
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) |
|
<-quit |
|
logger.Info("Shutting down server...") |
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) |
|
defer cancel() |
|
|
|
if err := s.Shutdown(ctx); err != nil { |
|
logger.Fatal("Server forced to shutdown:", err) |
|
} |
|
|
|
logger.Info("Server exited") |
|
}
|
|
|