--- a/irc/irc.go Wed Aug 08 23:02:21 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
- regexNick = regexp.MustCompile(`^[A-Za-z][A-Za-z0-9-[\]\^{}]*`)
-func NickValid(nick string) bool {
- return regexNick.MatchString(nick)
--- a/irc/irc_test.go Wed Aug 08 23:02:21 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
- . "github.com/onsi/gomega"
-func TestNickValid(t *testing.T) {
- tests := map[string]bool{
- for nick, exp := range tests {
- g.Expect(NickValid(nick)).To(Equal(exp))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/irc/types.go Thu Aug 09 01:52:23 2018 -0500
@@ -0,0 +1,65 @@
+ ErrMalformedMessage = errors.New("malformed message") + ErrInvalidNick = errors.New("invalid nick") + regexNick = regexp.MustCompile(`^[A-Za-z][A-Za-z0-9-[\]\^{}]*`) +type Unmarshaler interface { + UnmarshalIRC([]byte) error +type Marshaller interface { + MarshalIRC() ([]byte, error) +// Message represents a message in the IRC protocol. +func (m *Message) UnmarshalIRC(b []byte) error { + if !strings.HasPrefix(s, ":") { + return ErrMalformedMessage +func (m *Message) MarshalIRC() ([]byte, error) { + return []byte(":" + *m), nil +// Nick represents a nick in the IRC protocol. +func (n *Nick) UnmarshalIRC(b []byte) error { + if !regexNick.Match(b) { +func (n *Nick) MarshalNick() ([]byte, error) { + return nil, ErrInvalidNick +func (n *Nick) Valid() bool { + return regexNick.MatchString(string(*n)) --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/irc/types_test.go Thu Aug 09 01:52:23 2018 -0500
@@ -0,0 +1,82 @@
+ . "github.com/onsi/gomega" +func TestMessageMarshal(t *testing.T) { + g.Expect(e).To(BeNil()) + g.Expect(d).To(Equal([]byte(":foo"))) +func TestMessageUnmarshal(t *testing.T) { + e = m.UnmarshalIRC([]byte(":foo")) + g.Expect(e).To(BeNil()) + g.Expect(m).To(Equal(Message("foo"))) + e = m.UnmarshalIRC([]byte("foo")) + g.Expect(e).To(MatchError(ErrMalformedMessage)) + nickTests = map[string]bool{ +func TestNickMarshal(t *testing.T) { + for nick, exp := range nickTests { + var n Nick = Nick(nick) + mn, e := n.MarshalNick() + g.Expect(e).To(BeNil()) + g.Expect(mn).To(Equal([]byte(nick))) + g.Expect(e).To(MatchError(ErrInvalidNick)) +func TestNickUnmarshal(t *testing.T) { + for nick, exp := range nickTests { + err := n.UnmarshalIRC([]byte(nick)) + g.Expect(err).To(BeNil()) + g.Expect(err).To(Not(BeNil())) --- a/main.go Wed Aug 08 23:02:21 2018 -0500
+++ b/main.go Thu Aug 09 01:52:23 2018 -0500
@@ -1,5 +1,21 @@
+ "bitbucket.org/rw_grim/gobnc/server" + s := server.NewServer(cfg) + if err := s.Listen(); err != nil { + fmt.Printf("error: %s\n", err) --- a/server/config.go Wed Aug 08 23:02:21 2018 -0500
+++ b/server/config.go Thu Aug 09 01:52:23 2018 -0500
@@ -9,24 +9,28 @@
// Config handles the configuration data for a server. It may be marshalled to
- ListenAddr string `yaml:"listen-addr"`
- Nick string `yaml:"nick"`
- Password string `yaml:"password"`
+ Addr string `yaml:"addr"` + Nick irc.Nick `yaml:"nick"` + Password string `yaml:"password"` func (c *Config) Valid() error {
- if c.ListenAddr == "" {
- c.ListenAddr = "127.0.0.1"
if c.Port <= 0 || c.Port > 65535 {
return fmt.Errorf("Invalid port %d: must be between 1 and 65535", c.Port)
- if !irc.NickValid(c.Nick) {
return fmt.Errorf("Invalid nick '%s'", c.Nick)
+func (c *Config) ListenAddress() string { + return fmt.Sprintf("%s:%d", c.Addr, c.Port) --- a/server/config_test.go Wed Aug 08 23:02:21 2018 -0500
+++ b/server/config_test.go Thu Aug 09 01:52:23 2018 -0500
@@ -14,7 +14,7 @@
g.Expect(cfg.Valid()).To(BeNil())
- g.Expect(cfg.ListenAddr).To(Equal("127.0.0.1"))
+ g.Expect(cfg.Addr).To(Equal("127.0.0.1")) func TestConfigValidPort(t *testing.T) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/proxy.go Thu Aug 09 01:52:23 2018 -0500
@@ -0,0 +1,32 @@
+func NewProxy(server *Server, conn net.Conn) *Proxy { + msg, err := bufio.NewReader(p.conn).ReadString('\n') + fmt.Printf("error: %s\n", err) + fmt.Printf("msg: %s\n", msg) --- a/server/server.go Wed Aug 08 23:02:21 2018 -0500
+++ b/server/server.go Thu Aug 09 01:52:23 2018 -0500
@@ -1,7 +1,48 @@
+ proxies map[string]*Proxy +func NewServer(cfg *Config) *Server { + proxies: map[string]*Proxy{}, -func (s *Server) Listen() {
+func (s *Server) Listen() error { + return fmt.Errorf("server already listening") + sock, err := net.Listen("tcp", s.cfg.ListenAddress()) + conn, err := s.sock.Accept() + proxy := NewProxy(s, conn)