github.imxd.top/rafael-santiago/cherry@v0.0.0-20161214151746-8ea42c6e9670/src/cherry.go (about)

     1  /*
     2  Package main.
     3  --
     4   *                               Copyright (C) 2015 by Rafael Santiago
     5   *
     6   * This is a free software. You can redistribute it and/or modify under
     7   * the terms of the GNU General Public License version 2.
     8   *
     9  */
    10  package main
    11  
    12  import (
    13  	"crypto/tls"
    14  	"fmt"
    15  	"net"
    16  	"os"
    17  	"os/signal"
    18  	"pkg/config"
    19  	"pkg/config/parser"
    20  	"pkg/html"
    21  	"pkg/messageplexer"
    22  	"pkg/reqtraps"
    23  	"strconv"
    24  	"strings"
    25  	"syscall"
    26  )
    27  
    28  const cherryVersion = "1.2"
    29  
    30  func processNewConnection(newConn net.Conn, roomName string, rooms *config.CherryRooms) {
    31  	buf := make([]byte, 4096)
    32  	bufLen, err := newConn.Read(buf)
    33  	if err == nil {
    34  		preprocessor := html.NewHTMLPreprocessor(rooms)
    35  		httpPayload := string(buf[:bufLen])
    36  		var trap reqtraps.RequestTrap
    37  		trap = reqtraps.GetRequestTrap(httpPayload)
    38  		trap().Handle(newConn, roomName, httpPayload, rooms, preprocessor)
    39  	} else {
    40  		newConn.Close()
    41  	}
    42  }
    43  
    44  func getListenPeer(c *config.CherryRooms, port string) (net.Listener, error) {
    45  	var listenConn net.Listener
    46  	var listenError error
    47  	if c.GetCertificatePath() != "" && c.GetPrivateKeyPath() != "" {
    48  		cert, err := tls.LoadX509KeyPair(c.GetCertificatePath(), c.GetPrivateKeyPath())
    49  		if err != nil {
    50  			return nil, err
    51  		}
    52  		secParams := &tls.Config{Certificates: []tls.Certificate{cert}}
    53  		listenConn, listenError = tls.Listen("tcp", c.GetServerName()+":"+port, secParams)
    54  	} else {
    55  		listenConn, listenError = net.Listen("tcp", c.GetServerName()+":"+port)
    56  	}
    57  	return listenConn, listenError
    58  }
    59  
    60  func peer(roomName string, c *config.CherryRooms) {
    61  	port := c.GetListenPort(roomName)
    62  	var portNum int64
    63  	portNum, _ = strconv.ParseInt(port, 10, 16)
    64  	var err error
    65  	var room *config.RoomConfig
    66  	room = c.GetRoomByPort(int16(portNum))
    67  	//room.MainPeer, err = net.Listen("tcp", c.GetServerName()+":"+port)
    68  	room.MainPeer, err = getListenPeer(c, port)
    69  	if err != nil {
    70  		fmt.Println("ERROR: " + err.Error())
    71  		os.Exit(1)
    72  	}
    73  	defer room.MainPeer.Close()
    74  	for {
    75  		conn, err := room.MainPeer.Accept()
    76  		if err != nil {
    77  			fmt.Println(err.Error())
    78  			continue
    79  		}
    80  		go processNewConnection(conn, roomName, c)
    81  	}
    82  }
    83  
    84  func getOption(option, defaultValue string, flagOption ...bool) string {
    85  	isFlagOption := false
    86  	if len(flagOption) > 0 {
    87  		isFlagOption = flagOption[0]
    88  	}
    89  	for _, arg := range os.Args {
    90  		if !isFlagOption {
    91  			if strings.HasPrefix(arg, "--"+option+"=") {
    92  				return arg[len(option)+3:]
    93  			}
    94  		} else if strings.HasPrefix(arg, "--"+option) {
    95  			return "1"
    96  		}
    97  	}
    98  	return defaultValue
    99  }
   100  
   101  func cleanup() {
   102  	fmt.Println("INFO: Aborting signal received. Now your Cherry tree is being uprooted...  ;) Goodbye!!")
   103  }
   104  
   105  func announceVersion() {
   106  	fmt.Println("cherry-" + cherryVersion)
   107  }
   108  
   109  func offerHelp() {
   110  	fmt.Println("usage: cherry [--config=<cherry config filepath> | --help | --version]")
   111  }
   112  
   113  func openRooms(configPath string) {
   114  	var cherryRooms *config.CherryRooms
   115  	var err *parser.CherryFileError
   116  	cherryRooms, err = parser.ParseCherryFile(configPath)
   117  	if err != nil {
   118  		fmt.Println(err.Error())
   119  		os.Exit(1)
   120  	} else {
   121  		rooms := cherryRooms.GetRooms()
   122  		for _, r := range rooms {
   123  			go messageplexer.RoomMessagePlexer(r, cherryRooms)
   124  			go peer(r, cherryRooms)
   125  		}
   126  	}
   127  	sigintWatchdog := make(chan os.Signal, 1)
   128  	signal.Notify(sigintWatchdog, os.Interrupt)
   129  	signal.Notify(sigintWatchdog, syscall.SIGINT|syscall.SIGTERM)
   130  	<-sigintWatchdog
   131  	cleanup()
   132  }
   133  
   134  func main() {
   135  	versionInfo := getOption("version", "", true)
   136  	if len(versionInfo) > 0 {
   137  		announceVersion()
   138  		os.Exit(0)
   139  	}
   140  	help := getOption("help", "", true)
   141  	if len(help) > 0 {
   142  		offerHelp()
   143  		os.Exit(0)
   144  	}
   145  	configPath := getOption("config", "")
   146  	if len(configPath) == 0 {
   147  		offerHelp()
   148  		os.Exit(1)
   149  	}
   150  	openRooms(configPath)
   151  }