Refactor all response messages as NNTPResponse type

This commit is contained in:
ChronosX88 2022-02-05 12:54:41 +03:00
parent 5023c13afd
commit 496fbf2a4f
Signed by: ChronosXYZ
GPG Key ID: 085A69A82C8C511A
5 changed files with 13 additions and 90 deletions

6
go.mod
View File

@ -4,13 +4,11 @@ go 1.17
require (
github.com/BurntSushi/toml v1.0.0
github.com/dlclark/regexp2 v1.4.0
github.com/google/uuid v1.3.0
github.com/jmoiron/sqlx v1.3.4
github.com/mattn/go-sqlite3 v1.14.10
github.com/pressly/goose/v3 v3.5.0
)
require (
github.com/dlclark/regexp2 v1.4.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
)
require github.com/pkg/errors v0.9.1 // indirect

View File

@ -14,68 +14,3 @@ type Article struct {
Body string `db:"body"`
Thread sql.NullString `db:"thread"`
}
//func ParseArticle(lines []string) (Article, error) {
// article := Article{}
// headerBlock := true
// for _, v := range lines {
// if v == "" {
// headerBlock = false
// }
//
// if headerBlock {
// kv := strings.Split(v, ":")
// if len(kv) < 2 {
// return Article{}, fmt.Errorf("invalid header format")
// }
//
// kv[0] = strings.TrimSpace(kv[0])
// kv[1] = strings.TrimSpace(kv[1])
//
// if !protocol.IsMessageHeaderAllowed(kv[0]) {
// return Article{}, fmt.Errorf("invalid header element")
// }
// if kv[1] == "" {
// return Article{}, fmt.Errorf("header value should not be empty")
// }
//
// switch kv[0] {
// case "Archive":
// {
// if kv[1] == "yes" {
// article.Archive = true
// } else {
// article.Archive = false
// }
// }
// case "Injection-Date":
// {
// date, err := mail.ParseDate(kv[1])
// if err != nil {
// return Article{}, err
// }
// article.InjectionDate = date
// }
// case "Date":
// {
// date, err := mail.ParseDate(kv[1])
// if err != nil {
// return Article{}, err
// }
// article.Date = date
// }
// case "Expires":
// {
// date, err := mail.ParseDate(kv[1])
// if err != nil {
// return Article{}, err
// }
// article.Expires = date
// }
// }
//
// } else {
// }
// }
// return article, nil
//}

View File

@ -70,14 +70,3 @@ const (
CapabilityNameImplementation = "IMPLEMENTATION"
CapabilityNameModeReader = "MODE-READER"
)
const (
MessageNNTPServiceReadyPostingProhibited = "201 YANS NNTP Service Ready, posting prohibited"
MessageReaderModePostingProhibited = "201 Reader mode, posting prohibited"
MessageNNTPServiceExitsNormally = "205 NNTP Service exits normally, bye!"
MessageErrorHappened = "403 Failed to process command:"
MessageListOfNewsgroupsFollows = "215 list of newsgroups follows"
MessageNoSuchGroup = "411 No such newsgroup"
MessageInputArticle = "340 Input article; end with <CR-LF>.<CR-LF>"
MessageArticleReceived = "240 Article received OK"
)

View File

@ -49,11 +49,11 @@ func (h *Handler) handleCapabilities(s *Session, arguments []string, id uint) er
func (h *Handler) handleDate(s *Session, arguments []string, id uint) error {
s.tconn.StartResponse(id)
defer s.tconn.EndResponse(id)
return s.tconn.PrintfLine("111 %s", time.Now().UTC().Format("20060102150405"))
return s.tconn.PrintfLine(protocol.NNTPResponse{Code: 111, Message: time.Now().UTC().Format("20060102150405")}.String())
}
func (h *Handler) handleQuit(s *Session, arguments []string, id uint) error {
s.tconn.PrintfLine(protocol.MessageNNTPServiceExitsNormally)
s.tconn.PrintfLine(protocol.NNTPResponse{Code: 205, Message: "NNTP Service exits normally, bye!"}.String())
s.conn.Close()
return nil
}
@ -85,7 +85,7 @@ func (h *Handler) handleList(s *Session, arguments []string, id uint) error {
if err != nil {
return err
}
sb.Write([]byte(protocol.MessageListOfNewsgroupsFollows + protocol.CRLF))
sb.Write([]byte(protocol.NNTPResponse{Code: 215, Message: "list of newsgroups follows"}.String() + protocol.CRLF))
for _, v := range groups {
// TODO set actual post permission status
c, err := h.backend.GetArticlesCount(&v)
@ -120,7 +120,7 @@ func (h *Handler) handleList(s *Session, arguments []string, id uint) error {
return err
}
sb.Write([]byte(protocol.MessageListOfNewsgroupsFollows + protocol.CRLF))
sb.Write([]byte(protocol.NNTPResponse{Code: 215, Message: "list of newsgroups follows"}.String() + protocol.CRLF))
for _, v := range groups {
desc := ""
if v.Description == nil {
@ -156,7 +156,7 @@ func (h *Handler) handleModeReader(s *Session, arguments []string, id uint) erro
(&s.capabilities).Add(protocol.Capability{Type: protocol.ListCapability, Params: "ACTIVE NEWSGROUPS"})
s.mode = SessionModeReader
return s.tconn.PrintfLine(protocol.MessageReaderModePostingProhibited) // TODO vary on auth status
return s.tconn.PrintfLine(protocol.NNTPResponse{Code: 201, Message: "Reader mode, posting prohibited"}.String()) // TODO vary on auth status
}
func (h *Handler) handleGroup(s *Session, arguments []string, id uint) error {
@ -170,7 +170,7 @@ func (h *Handler) handleGroup(s *Session, arguments []string, id uint) error {
g, err := h.backend.GetGroup(arguments[0])
if err != nil {
if err == sql.ErrNoRows {
return s.tconn.PrintfLine(protocol.MessageNoSuchGroup)
return s.tconn.PrintfLine(protocol.NNTPResponse{Code: 411, Message: "No such newsgroup"}.String())
} else {
return err
}
@ -266,7 +266,7 @@ func (h *Handler) handlePost(s *Session, arguments []string, id uint) error {
return s.tconn.PrintfLine(protocol.ErrSyntaxError.String())
}
if err := s.tconn.PrintfLine(protocol.MessageInputArticle); err != nil {
if err := s.tconn.PrintfLine(protocol.NNTPResponse{Code: 340, Message: "Input article; end with <CR-LF>.<CR-LF>"}.String()); err != nil {
return err
}
@ -324,7 +324,7 @@ func (h *Handler) handlePost(s *Session, arguments []string, id uint) error {
return s.tconn.PrintfLine(protocol.NNTPResponse{Code: 441, Message: err.Error()}.String())
}
return s.tconn.PrintfLine(protocol.MessageArticleReceived)
return s.tconn.PrintfLine(protocol.NNTPResponse{Code: 240, Message: "Article received OK"}.String())
}
func (h *Handler) handleListgroup(s *Session, arguments []string, id uint) error {

View File

@ -2,6 +2,7 @@ package server
import (
"context"
"fmt"
"github.com/ChronosX88/yans/internal/models"
"github.com/ChronosX88/yans/internal/protocol"
"io"
@ -61,7 +62,7 @@ func (s *Session) loop() {
close(s.closed)
}()
err := s.tconn.PrintfLine(protocol.MessageNNTPServiceReadyPostingProhibited) // by default access mode is read-only
err := s.tconn.PrintfLine(protocol.NNTPResponse{Code: 201, Message: "YANS NNTP Service Ready, posting prohibited"}.String()) // by default access mode is read-only
if err != nil {
s.conn.Close()
return
@ -90,7 +91,7 @@ func (s *Session) loop() {
err = s.h.Handle(s, message, id)
if err != nil {
log.Print(err)
s.tconn.PrintfLine("%s %s", protocol.MessageErrorHappened, err.Error())
s.tconn.PrintfLine(protocol.NNTPResponse{Code: 403, Message: fmt.Sprintf("Failed to process command: %s", err.Error())}.String())
s.conn.Close()
return
}