2014-04-26 09:18:56 +00:00
package ICCC
2014-10-19 17:19:11 +00:00
import (
"fmt"
"github.com/SommerEngineering/Ocean/Log"
LM "github.com/SommerEngineering/Ocean/Log/Meta"
"github.com/SommerEngineering/Ocean/Tools"
"net/http"
2015-06-21 18:18:23 +00:00
"net/url"
2014-10-19 17:19:11 +00:00
)
2014-04-26 09:18:56 +00:00
2015-07-10 19:06:44 +00:00
// The HTTP handler for the local ICCC listeners. Will used in case, that another server
// want to utelise an listener from this server.
2014-04-26 09:18:56 +00:00
func ICCCHandler ( response http . ResponseWriter , request * http . Request ) {
2015-06-17 15:44:52 +00:00
// Cannot parse the form?
2014-04-26 09:18:56 +00:00
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
}
2015-06-17 15:44:52 +00:00
// Read the data out of the request:
2014-04-26 09:18:56 +00:00
messageData := map [ string ] [ ] string ( request . PostForm )
2014-06-08 09:35:01 +00:00
2015-07-10 19:06:44 +00:00
// The data must contain at least three fields (command, channel & checksum)
2014-06-08 09:35:01 +00:00
if len ( messageData ) < 3 {
2015-07-10 19:06:44 +00:00
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! ` )
2014-06-08 09:35:01 +00:00
http . NotFound ( response , request )
return
}
2015-06-17 15:44:52 +00:00
// Read the meta data:
2014-04-26 09:18:56 +00:00
channel := messageData [ ` channel ` ] [ 0 ]
command := messageData [ ` command ` ] [ 0 ]
2015-07-10 19:06:44 +00:00
receivedChecksum := messageData [ ` checksum ` ] [ 0 ]
2014-04-26 09:18:56 +00:00
2015-07-10 19:06:44 +00:00
// 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 ) )
2014-04-26 09:18:56 +00:00
http . NotFound ( response , request )
return
}
2015-06-17 15:44:52 +00:00
// Build the key for the mapping of the listener cache:
2014-04-26 09:18:56 +00:00
key := fmt . Sprintf ( ` %s::%s ` , channel , command )
2015-06-17 15:44:52 +00:00
// Get the matching listener
2014-04-26 09:18:56 +00:00
listener := listeners [ key ]
2015-06-17 15:44:52 +00:00
2014-04-26 09:18:56 +00:00
if listener == nil {
2015-06-17 15:44:52 +00:00
// Case: No such listener
2015-07-16 16:51:59 +00:00
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 ( ) )
2015-06-21 18:18:23 +00:00
http . NotFound ( response , request )
2014-04-26 09:18:56 +00:00
} else {
2015-06-21 18:18:23 +00:00
// 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 )
}
2014-04-26 09:18:56 +00:00
}
}