package main import ( "bytes" "crypto/rand" "encoding/json" "fmt" "io/ioutil" "log" "net/http" "sync" "time" ) var ( authCode string peers []string authMutex sync.Mutex authenticated = make(map[string]bool) hostID string ) type Message struct { ID string `json:"id"` Type string `json:"type"` Content string `json:"content"` VisitedNodes []string `json:"visitedNodes"` } type CrawlerConfig struct { ID string Host string Port int AuthCode string } func loadNodeConfig() { config := loadConfig() authCode = config.AuthCode peers = config.Peers } func generateHostID() (string, error) { bytes := make([]byte, 16) _, err := rand.Read(bytes) if err != nil { return "", fmt.Errorf("failed to generate host ID: %v", err) } return fmt.Sprintf("%x", bytes), nil } func sendMessage(serverAddr string, msg Message) error { if serverAddr == "" { return fmt.Errorf("server address is empty") } msgBytes, err := json.Marshal(msg) if err != nil { return fmt.Errorf("failed to marshal message: %v", err) } req, err := http.NewRequest("POST", serverAddr, bytes.NewBuffer(msgBytes)) if err != nil { return fmt.Errorf("failed to create request: %v", err) } req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", authCode) client := &http.Client{ Timeout: time.Second * 10, } resp, err := client.Do(req) if err != nil { return fmt.Errorf("failed to send request: %v", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { body, _ := ioutil.ReadAll(resp.Body) return fmt.Errorf("server error: %s", body) } return nil } func handleNodeRequest(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "Invalid request method", http.StatusMethodNotAllowed) return } auth := r.Header.Get("Authorization") if auth != authCode { http.Error(w, "Unauthorized", http.StatusUnauthorized) return } var msg Message err := json.NewDecoder(r.Body).Decode(&msg) if err != nil { http.Error(w, "Error parsing JSON", http.StatusBadRequest) return } defer r.Body.Close() log.Printf("Received message: %+v\n", msg) w.Write([]byte("Message received")) interpretMessage(msg) } func startNodeClient() { for { for _, peerAddr := range peers { msg := Message{ ID: hostID, Type: "test", Content: "This is a test message from the client node", } err := sendMessage(peerAddr, msg) if err != nil { log.Printf("Error sending message to %s: %v", peerAddr, err) } else { log.Println("Message sent successfully to", peerAddr) } } time.Sleep(10 * time.Second) } } func interpretMessage(msg Message) { switch msg.Type { case "test": fmt.Println("Received test message:", msg.Content) case "update": fmt.Println("Received update message:", msg.Content) go update() case "heartbeat": handleHeartbeat(msg.Content) case "election": handleElection(msg.Content) case "search-text": handleSearchTextMessage(msg) case "search-image": handleSearchImageMessage(msg) case "search-video": handleSearchVideoMessage(msg) case "search-file": handleSearchFileMessage(msg) case "search-forum": handleSearchForumMessage(msg) case "forum-results": handleForumResultsMessage(msg) case "text-results": handleTextResultsMessage(msg) case "image-results": handleImageResultsMessage(msg) case "video-results": handleVideoResultsMessage(msg) case "file-results": handleFileResultsMessage(msg) default: fmt.Println("Received unknown message type:", msg.Type) } }