Commit Diff


commit - de59b21200a5aa169b2dc799bca29b8f75c8e231
commit + ba988fd4461e70f94f59ed0790095bfd4b2eef1c
blob - 986166c75750032eb3c68b01d704d36055641c2b
blob + 3d07cce51101dcc008d1f0806b065ebcd30c8852
--- examples/server/exampleserver.go
+++ examples/server/exampleserver.go
@@ -12,7 +12,7 @@ import (
 	"strings"
 
 	"github.com/dustin/go-nntp"
-	"github.com/dustin/go-nntp/server"
+	nntpserver "github.com/dustin/go-nntp/server"
 )
 
 const maxArticles = 100
@@ -85,7 +85,7 @@ func (tb *testBackendType) GetGroup(name string) (*nnt
 	}
 
 	if group == nil {
-		return nil, nntpserver.ErrNoSuchGroup
+		return nil, nntp.ErrNoSuchGroup
 	}
 
 	return group, nil
@@ -138,7 +138,7 @@ func (tb *testBackendType) GetArticle(group *nntp.Grou
 
 	a = tb.articles[msgID]
 	if a == nil {
-		return nil, nntpserver.ErrInvalidMessageID
+		return nil, nntp.ErrInvalidMessageID
 	}
 
 	return mkArticle(a), nil
@@ -164,7 +164,7 @@ func (tb *testBackendType) GetArticles(group *nntp.Gro
 
 	gs, ok := tb.groups[group.Name]
 	if !ok {
-		return nil, nntpserver.ErrNoSuchGroup
+		return nil, nntp.ErrNoSuchGroup
 	}
 
 	log.Printf("Getting articles from %d to %d", from, to)
@@ -225,7 +225,7 @@ func (tb *testBackendType) Post(article *nntp.Article)
 	msgID := a.headers.Get("Message-Id")
 
 	if _, ok := tb.articles[msgID]; ok {
-		return nntpserver.ErrPostingFailed
+		return nntp.ErrPostingFailed
 	}
 
 	for _, g := range article.Header["Newsgroups"] {
@@ -254,7 +254,7 @@ func (tb *testBackendType) Post(article *nntp.Article)
 	if a.refcount > 0 {
 		tb.articles[msgID] = &a
 	} else {
-		return nntpserver.ErrPostingFailed
+		return nntp.ErrPostingFailed
 	}
 
 	return nil
@@ -265,7 +265,7 @@ func (tb *testBackendType) Authorized() bool {
 }
 
 func (tb *testBackendType) Authenticate(user, pass string) (nntpserver.Backend, error) {
-	return nil, nntpserver.ErrAuthRejected
+	return nil, nntp.ErrAuthRejected
 }
 
 func maybefatal(err error, f string, a ...interface{}) {
blob - /dev/null
blob + aa319ede4dac0b44e0e93bc27e3368768113f529 (mode 644)
--- /dev/null
+++ error.go
@@ -0,0 +1,58 @@
+package nntp
+
+import "fmt"
+
+// An NNTPError is a coded NNTP error message.
+type Error struct {
+	Code int
+	Msg  string
+}
+
+func (e *Error) Error() string {
+	return fmt.Sprintf("%d %s", e.Code, e.Msg)
+}
+
+// ErrNoSuchGroup is returned for a request for a group that can't be found.
+var ErrNoSuchGroup = &Error{411, "No such newsgroup"}
+
+// ErrNoSuchGroup is returned for a request that requires a current
+// group when none has been selected.
+var ErrNoGroupSelected = &Error{412, "No newsgroup selected"}
+
+// ErrInvalidMessageID is returned when a message is requested that can't be found.
+var ErrInvalidMessageID = &Error{430, "No article with that message-id"}
+
+// ErrInvalidArticleNumber is returned when an article is requested that can't be found.
+var ErrInvalidArticleNumber = &Error{423, "No article with that number"}
+
+// ErrNoCurrentArticle is returned when a command is executed that
+// requires a current article when one has not been selected.
+var ErrNoCurrentArticle = &Error{420, "Current article number is invalid"}
+
+// ErrUnknownCommand is returned for unknown comands.
+var ErrUnknownCommand = &Error{500, "Unknown command"}
+
+// ErrSyntax is returned when a command can't be parsed.
+var ErrSyntax = &Error{501, "not supported, or syntax error"}
+
+// ErrPostingNotPermitted is returned as the response to an attempt to
+// post an article where posting is not permitted.
+var ErrPostingNotPermitted = &Error{440, "posting not permitted"}
+
+// ErrPostingFailed is returned when an attempt to post an article fails.
+var ErrPostingFailed = &Error{441, "posting failed"}
+
+// ErrNotWanted is returned when an attempt to post an article is
+// rejected due the server not wanting the article.
+var ErrNotWanted = &Error{435, "Article not wanted"}
+
+// ErrAuthRequired is returned to indicate authentication is required
+// to proceed.
+var ErrAuthRequired = &Error{450, "authorization required"}
+
+// ErrAuthRejected is returned for invalid authentication.
+var ErrAuthRejected = &Error{452, "authorization rejected"}
+
+// ErrNotAuthenticated is returned when a command is issued that requires
+// authentication, but authentication was not provided.
+var ErrNotAuthenticated = &Error{480, "authentication required"}
blob - 4c249503a10c86d5b80142da1f95f02c833d54c5
blob + 3f5fbb77ebe31a1bb210cdb48e37043595f04711
--- server/server.go
+++ server/server.go
@@ -13,58 +13,7 @@ import (
 
 	"github.com/dustin/go-nntp"
 )
-
-// An NNTPError is a coded NNTP error message.
-type NNTPError struct {
-	Code int
-	Msg  string
-}
-
-// ErrNoSuchGroup is returned for a request for a group that can't be found.
-var ErrNoSuchGroup = &NNTPError{411, "No such newsgroup"}
-
-// ErrNoSuchGroup is returned for a request that requires a current
-// group when none has been selected.
-var ErrNoGroupSelected = &NNTPError{412, "No newsgroup selected"}
-
-// ErrInvalidMessageID is returned when a message is requested that can't be found.
-var ErrInvalidMessageID = &NNTPError{430, "No article with that message-id"}
-
-// ErrInvalidArticleNumber is returned when an article is requested that can't be found.
-var ErrInvalidArticleNumber = &NNTPError{423, "No article with that number"}
-
-// ErrNoCurrentArticle is returned when a command is executed that
-// requires a current article when one has not been selected.
-var ErrNoCurrentArticle = &NNTPError{420, "Current article number is invalid"}
-
-// ErrUnknownCommand is returned for unknown comands.
-var ErrUnknownCommand = &NNTPError{500, "Unknown command"}
-
-// ErrSyntax is returned when a command can't be parsed.
-var ErrSyntax = &NNTPError{501, "not supported, or syntax error"}
-
-// ErrPostingNotPermitted is returned as the response to an attempt to
-// post an article where posting is not permitted.
-var ErrPostingNotPermitted = &NNTPError{440, "Posting not permitted"}
-
-// ErrPostingFailed is returned when an attempt to post an article fails.
-var ErrPostingFailed = &NNTPError{441, "posting failed"}
-
-// ErrNotWanted is returned when an attempt to post an article is
-// rejected due the server not wanting the article.
-var ErrNotWanted = &NNTPError{435, "Article not wanted"}
-
-// ErrAuthRequired is returned to indicate authentication is required
-// to proceed.
-var ErrAuthRequired = &NNTPError{450, "authorization required"}
-
-// ErrAuthRejected is returned for invalid authentication.
-var ErrAuthRejected = &NNTPError{452, "authorization rejected"}
 
-// ErrNotAuthenticated is returned when a command is issued that requires
-// authentication, but authentication was not provided.
-var ErrNotAuthenticated = &NNTPError{480, "authentication required"}
-
 // Handler is a low-level protocol handler
 type Handler func(args []string, s *session, c *textproto.Conn) error
 
@@ -129,10 +78,6 @@ func NewServer(backend Backend) *Server {
 	return &rv
 }
 
-func (e *NNTPError) Error() string {
-	return fmt.Sprintf("%d %s", e.Code, e.Msg)
-}
-
 func (s *session) dispatchCommand(cmd string, args []string,
 	c *textproto.Conn) (err error) {
 
@@ -161,7 +106,7 @@ func (s *Server) Process(nc net.Conn) {
 	for {
 		l, err := c.ReadLine()
 		if err != nil {
-			log.Printf("Error reading from client, dropping conn: %v", err)
+			log.Printf("nntp.Error reading from client, dropping conn: %v", err)
 			return
 		}
 		cmd := strings.Split(l, " ")
@@ -172,16 +117,15 @@ func (s *Server) Process(nc net.Conn) {
 		}
 		err = sess.dispatchCommand(cmd[0], args, c)
 		if err != nil {
-			_, isNNTPError := err.(*NNTPError)
+			_, ok := err.(*nntp.Error)
 			switch {
 			case err == io.EOF:
 				// Drop this connection silently. They hung up
 				return
-			case isNNTPError:
+			case ok:
 				c.PrintfLine(err.Error())
 			default:
-				log.Printf("Error dispatching command, dropping conn: %v",
-					err)
+				log.Printf("nntp.Error dispatching command, dropping conn: %v", err)
 				return
 			}
 		}
@@ -221,7 +165,7 @@ func parseRange(spec string) (low, high int64) {
 
 func handleOver(args []string, s *session, c *textproto.Conn) error {
 	if s.group == nil {
-		return ErrNoGroupSelected
+		return nntp.ErrNoGroupSelected
 	}
 	from, to := parseRange(args[0])
 	articles, err := s.backend.GetArticles(s.group, from, to)
@@ -297,7 +241,7 @@ func handleNewGroups(args []string, s *session, c *tex
 }
 
 func handleDefault(args []string, s *session, c *textproto.Conn) error {
-	return ErrUnknownCommand
+	return nntp.ErrUnknownCommand
 }
 
 func handleQuit(args []string, s *session, c *textproto.Conn) error {
@@ -307,7 +251,7 @@ func handleQuit(args []string, s *session, c *textprot
 
 func handleGroup(args []string, s *session, c *textproto.Conn) error {
 	if len(args) < 1 {
-		return ErrNoSuchGroup
+		return nntp.ErrNoSuchGroup
 	}
 
 	group, err := s.backend.GetGroup(args[0])
@@ -324,7 +268,7 @@ func handleGroup(args []string, s *session, c *textpro
 
 func (s *session) getArticle(args []string) (*nntp.Article, error) {
 	if s.group == nil {
-		return nil, ErrNoGroupSelected
+		return nil, nntp.ErrNoGroupSelected
 	}
 	return s.backend.GetArticle(s.group, args[0])
 }
@@ -469,7 +413,7 @@ func handleArticle(args []string, s *session, c *textp
 
 func handlePost(args []string, s *session, c *textproto.Conn) error {
 	if !s.backend.AllowPost() {
-		return ErrPostingNotPermitted
+		return nntp.ErrPostingNotPermitted
 	}
 
 	c.PrintfLine("340 Go ahead")
@@ -477,7 +421,7 @@ func handlePost(args []string, s *session, c *textprot
 	var article nntp.Article
 	article.Header, err = c.ReadMIMEHeader()
 	if err != nil {
-		return ErrPostingFailed
+		return nntp.ErrPostingFailed
 	}
 	article.Body = c.DotReader()
 	err = s.backend.Post(&article)
@@ -490,20 +434,20 @@ func handlePost(args []string, s *session, c *textprot
 
 func handleIHave(args []string, s *session, c *textproto.Conn) error {
 	if !s.backend.AllowPost() {
-		return ErrNotWanted
+		return nntp.ErrNotWanted
 	}
 
 	// XXX:  See if we have it.
 	article, err := s.backend.GetArticle(nil, args[0])
 	if article != nil {
-		return ErrNotWanted
+		return nntp.ErrNotWanted
 	}
 
 	c.PrintfLine("335 send it")
 	article = &nntp.Article{}
 	article.Header, err = c.ReadMIMEHeader()
 	if err != nil {
-		return ErrPostingFailed
+		return nntp.ErrPostingFailed
 	}
 	article.Body = c.DotReader()
 	err = s.backend.Post(article)
@@ -542,10 +486,10 @@ func handleMode(args []string, s *session, c *textprot
 
 func handleAuthInfo(args []string, s *session, c *textproto.Conn) error {
 	if len(args) < 2 {
-		return ErrSyntax
+		return nntp.ErrSyntax
 	}
 	if strings.ToLower(args[0]) != "user" {
-		return ErrSyntax
+		return nntp.ErrSyntax
 	}
 
 	if s.backend.Authorized() {
@@ -556,7 +500,7 @@ func handleAuthInfo(args []string, s *session, c *text
 	a, err := c.ReadLine()
 	parts := strings.SplitN(a, " ", 3)
 	if strings.ToLower(parts[0]) != "authinfo" || strings.ToLower(parts[1]) != "pass" {
-		return ErrSyntax
+		return nntp.ErrSyntax
 	}
 	b, err := s.backend.Authenticate(args[1], parts[2])
 	if err == nil {