mirror of
https://github.com/profullstack/agentbbs.git
synced 2026-08-13 22:37:28 +00:00
fix(news): stop IHAVE when duplicate lookup fails (#89)
Co-authored-by: SabFabDev <SabFabDev@users.noreply.github.com>
This commit is contained in:
parent
c2a06f1cdf
commit
21630c2d17
3 changed files with 49 additions and 4 deletions
|
|
@ -88,7 +88,6 @@ type Server struct {
|
||||||
// ErrLog, when non-nil, receives connection-level errors. Protocol verbs
|
// ErrLog, when non-nil, receives connection-level errors. Protocol verbs
|
||||||
// are never logged (a public server should not log every command).
|
// are never logged (a public server should not log every command).
|
||||||
ErrLog *log.Logger
|
ErrLog *log.Logger
|
||||||
group *nntp.Group
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewServer builds a server bound to a backend.
|
// NewServer builds a server bound to a backend.
|
||||||
|
|
@ -371,6 +370,9 @@ func handleIHave(args []string, s *session, c *textproto.Conn) error {
|
||||||
return ErrSyntax
|
return ErrSyntax
|
||||||
}
|
}
|
||||||
article, err := s.backend.GetArticle(nil, args[0])
|
article, err := s.backend.GetArticle(nil, args[0])
|
||||||
|
if err != nil && err != ErrInvalidMessageID && err != ErrInvalidArticleNumber {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if article != nil {
|
if article != nil {
|
||||||
return ErrNotWanted
|
return ErrNotWanted
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type whitespaceBackend struct {
|
type whitespaceBackend struct {
|
||||||
group *nntp.Group
|
group *nntp.Group
|
||||||
allowPost bool
|
allowPost bool
|
||||||
|
articleErr error
|
||||||
|
postCalls int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *whitespaceBackend) ListGroups(max int) ([]*nntp.Group, error) {
|
func (b *whitespaceBackend) ListGroups(max int) ([]*nntp.Group, error) {
|
||||||
|
|
@ -28,6 +30,9 @@ func (b *whitespaceBackend) GetGroup(name string) (*nntp.Group, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *whitespaceBackend) GetArticle(group *nntp.Group, id string) (*nntp.Article, error) {
|
func (b *whitespaceBackend) GetArticle(group *nntp.Group, id string) (*nntp.Article, error) {
|
||||||
|
if b.articleErr != nil {
|
||||||
|
return nil, b.articleErr
|
||||||
|
}
|
||||||
return nil, ErrInvalidArticleNumber
|
return nil, ErrInvalidArticleNumber
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -44,6 +49,7 @@ func (b *whitespaceBackend) Authenticate(user, pass string) (Backend, error) {
|
||||||
func (b *whitespaceBackend) AllowPost() bool { return b.allowPost }
|
func (b *whitespaceBackend) AllowPost() bool { return b.allowPost }
|
||||||
|
|
||||||
func (b *whitespaceBackend) Post(article *nntp.Article) error {
|
func (b *whitespaceBackend) Post(article *nntp.Article) error {
|
||||||
|
b.postCalls++
|
||||||
return errors.New("posting disabled")
|
return errors.New("posting disabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -127,3 +133,41 @@ func TestIHaveWithoutMessageIDReturnsSyntaxError(t *testing.T) {
|
||||||
t.Fatal("server did not close after QUIT")
|
t.Fatal("server did not close after QUIT")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIHaveStopsWhenDuplicateCheckFails(t *testing.T) {
|
||||||
|
backend := &whitespaceBackend{
|
||||||
|
group: &nntp.Group{Name: "pfs.general", Posting: nntp.PostingPermitted},
|
||||||
|
allowPost: true,
|
||||||
|
articleErr: errors.New("backend unavailable"),
|
||||||
|
}
|
||||||
|
server := NewServer(backend)
|
||||||
|
clientConn, serverConn := net.Pipe()
|
||||||
|
defer clientConn.Close()
|
||||||
|
|
||||||
|
done := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
server.Process(serverConn)
|
||||||
|
close(done)
|
||||||
|
}()
|
||||||
|
|
||||||
|
client := textproto.NewConn(clientConn)
|
||||||
|
defer client.Close()
|
||||||
|
if line, err := client.ReadLine(); err != nil || !strings.HasPrefix(line, "200 ") {
|
||||||
|
t.Fatalf("greeting = %q, %v", line, err)
|
||||||
|
}
|
||||||
|
if err := client.PrintfLine("IHAVE <new@example.test>"); err != nil {
|
||||||
|
t.Fatalf("send IHAVE: %v", err)
|
||||||
|
}
|
||||||
|
if line, err := client.ReadLine(); err == nil {
|
||||||
|
t.Fatalf("IHAVE duplicate-check failure returned %q; want connection close", line)
|
||||||
|
}
|
||||||
|
if backend.postCalls != 0 {
|
||||||
|
t.Fatalf("Post called %d times after duplicate-check failure; want 0", backend.postCalls)
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-done:
|
||||||
|
case <-time.After(time.Second):
|
||||||
|
t.Fatal("server did not close after duplicate-check failure")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ var (
|
||||||
nSel = lipgloss.NewStyle().Foreground(lipgloss.Color("#0b1020")).Background(ui.Cyan)
|
nSel = lipgloss.NewStyle().Foreground(lipgloss.Color("#0b1020")).Background(ui.Cyan)
|
||||||
nMeta = ui.Dim
|
nMeta = ui.Dim
|
||||||
nFrom = lipgloss.NewStyle().Foreground(ui.Green)
|
nFrom = lipgloss.NewStyle().Foreground(ui.Green)
|
||||||
nErr = ui.Danger
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// RunReader connects the member to the loopback NNTP server and drives the
|
// RunReader connects the member to the loopback NNTP server and drives the
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue