74 lines
2.8 KiB
Go
74 lines
2.8 KiB
Go
package ICCC
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/SommerEngineering/Ocean/Log"
|
|
LM "github.com/SommerEngineering/Ocean/Log/Meta"
|
|
"github.com/SommerEngineering/Ocean/Tools"
|
|
"net/http"
|
|
"net/url"
|
|
)
|
|
|
|
// The HTTP handler for the local ICCC listeners. Will used in case, that another server
|
|
// want to utelise an listener from this server.
|
|
func ICCCHandler(response http.ResponseWriter, request *http.Request) {
|
|
|
|
// Cannot parse the form?
|
|
if errParse := request.ParseForm(); errParse != nil {
|
|
Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelERROR, LM.SeverityCritical, LM.ImpactCritical, LM.MessageNameNETWORK, `Was not able to parse the HTTP form data from an ICCC message!`)
|
|
http.NotFound(response, request)
|
|
return
|
|
}
|
|
|
|
// Read the data out of the request:
|
|
messageData := map[string][]string(request.PostForm)
|
|
|
|
// The data must contain at least three fields (command, channel & checksum)
|
|
if len(messageData) < 3 {
|
|
Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelERROR, LM.SeverityCritical, LM.ImpactCritical, LM.MessageNameNETWORK, `The ICCC message contains not enough data: At least the channel, command and checksum is required!`)
|
|
http.NotFound(response, request)
|
|
return
|
|
}
|
|
|
|
// Read the meta data:
|
|
channel := messageData[`channel`][0]
|
|
command := messageData[`command`][0]
|
|
receivedChecksum := messageData[`checksum`][0]
|
|
|
|
// Remove the checksum as preparation for the re-hash:
|
|
delete(messageData, `checksum`)
|
|
|
|
// Re-hash the received message:
|
|
receivedMessageHash := signMessage(messageData).Get(`checksum`)
|
|
|
|
// Check the checksums:
|
|
if receivedChecksum != receivedMessageHash {
|
|
Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelSECURITY, LM.SeverityCritical, LM.ImpactNone, LM.MessageNamePASSWORD, `Received a ICCC message with wrong checksum!`, request.RemoteAddr, fmt.Sprintf("channel=%s", channel), fmt.Sprintf("command=%s", command))
|
|
http.NotFound(response, request)
|
|
return
|
|
}
|
|
|
|
// Build the key for the mapping of the listener cache:
|
|
key := fmt.Sprintf(`%s::%s`, channel, command)
|
|
|
|
// Get the matching listener
|
|
listener := listeners[key]
|
|
|
|
if listener == nil {
|
|
// Case: No such listener
|
|
Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelWARN, LM.SeverityCritical, LM.ImpactUnknown, LM.MessageNameCONFIGURATION, `Was not able to find the correct listener for these ICCC message.`, `channel=`+channel, `command=`+command, `hostname=`+Tools.ThisHostname())
|
|
http.NotFound(response, request)
|
|
} else {
|
|
// Case: Everything is fine => deliver the message and read the answer:
|
|
answersData := listener(messageData)
|
|
if answersData != nil {
|
|
// Convert the answer to HTTP form values:
|
|
values := url.Values(answersData)
|
|
answersString := values.Encode()
|
|
|
|
// Write the answer to the other peer:
|
|
fmt.Fprintf(response, "%s", answersString)
|
|
}
|
|
}
|
|
}
|