commit - de59b21200a5aa169b2dc799bca29b8f75c8e231
commit + ba988fd4461e70f94f59ed0790095bfd4b2eef1c
blob - 986166c75750032eb3c68b01d704d36055641c2b
blob + 3d07cce51101dcc008d1f0806b065ebcd30c8852
--- examples/server/exampleserver.go
+++ examples/server/exampleserver.go
"strings"
"github.com/dustin/go-nntp"
- "github.com/dustin/go-nntp/server"
+ nntpserver "github.com/dustin/go-nntp/server"
)
const maxArticles = 100
}
if group == nil {
- return nil, nntpserver.ErrNoSuchGroup
+ return nil, nntp.ErrNoSuchGroup
}
return group, nil
a = tb.articles[msgID]
if a == nil {
- return nil, nntpserver.ErrInvalidMessageID
+ return nil, nntp.ErrInvalidMessageID
}
return mkArticle(a), nil
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)
msgID := a.headers.Get("Message-Id")
if _, ok := tb.articles[msgID]; ok {
- return nntpserver.ErrPostingFailed
+ return nntp.ErrPostingFailed
}
for _, g := range article.Header["Newsgroups"] {
if a.refcount > 0 {
tb.articles[msgID] = &a
} else {
- return nntpserver.ErrPostingFailed
+ return nntp.ErrPostingFailed
}
return nil
}
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
+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
"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
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) {
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, " ")
}
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
}
}
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)
}
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 {
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])
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])
}
func handlePost(args []string, s *session, c *textproto.Conn) error {
if !s.backend.AllowPost() {
- return ErrPostingNotPermitted
+ return nntp.ErrPostingNotPermitted
}
c.PrintfLine("340 Go ahead")
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)
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)
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() {
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 {