mirror of
https://github.com/profullstack/agentbbs.git
synced 2026-08-13 22:37:28 +00:00
Merge remote-tracking branch 'origin/main' into fix/pod-public-html-bind-mount
# Conflicts: # cmd/agentbbs/main.go # internal/hub/hub.go # internal/pods/pods.go
This commit is contained in:
commit
662250af35
33 changed files with 3127 additions and 42 deletions
10
internal/news/nntpd/range_test.go
Normal file
10
internal/news/nntpd/range_test.go
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
package nntpd
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestParseRangeSingleArticle(t *testing.T) {
|
||||
low, high := parseRange("5")
|
||||
if low != 5 || high != 5 {
|
||||
t.Fatalf(`parseRange("5") = %d, %d; want 5, 5`, low, high)
|
||||
}
|
||||
}
|
||||
|
|
@ -142,12 +142,16 @@ func (s *Server) Process(nc net.Conn) {
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
cmd := strings.Split(l, " ")
|
||||
args := []string{}
|
||||
if len(cmd) > 1 {
|
||||
args = cmd[1:]
|
||||
fields := strings.Fields(l)
|
||||
if len(fields) == 0 {
|
||||
err = handleDefault(nil, sess, c)
|
||||
} else {
|
||||
args := []string{}
|
||||
if len(fields) > 1 {
|
||||
args = fields[1:]
|
||||
}
|
||||
err = sess.dispatchCommand(fields[0], args, c)
|
||||
}
|
||||
err = sess.dispatchCommand(cmd[0], args, c)
|
||||
if err != nil {
|
||||
if _, isNNTPError := err.(*NNTPError); err == io.EOF {
|
||||
return
|
||||
|
|
@ -170,8 +174,9 @@ func parseRange(spec string) (low, high int64) {
|
|||
h, err := strconv.ParseInt(parts[0], 10, 64)
|
||||
if err != nil {
|
||||
h = math.MaxInt64
|
||||
return 0, h
|
||||
}
|
||||
return 0, h
|
||||
return h, h
|
||||
}
|
||||
l, _ := strconv.ParseInt(parts[0], 10, 64)
|
||||
h, err := strconv.ParseInt(parts[1], 10, 64)
|
||||
|
|
@ -357,6 +362,9 @@ func handleIHave(args []string, s *session, c *textproto.Conn) error {
|
|||
if !s.backend.AllowPost() {
|
||||
return ErrNotWanted
|
||||
}
|
||||
if len(args) < 1 {
|
||||
return ErrSyntax
|
||||
}
|
||||
article, err := s.backend.GetArticle(nil, args[0])
|
||||
if article != nil {
|
||||
return ErrNotWanted
|
||||
|
|
|
|||
129
internal/news/nntpd/server_test.go
Normal file
129
internal/news/nntpd/server_test.go
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
package nntpd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"net/textproto"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/dustin/go-nntp"
|
||||
)
|
||||
|
||||
type whitespaceBackend struct {
|
||||
group *nntp.Group
|
||||
allowPost bool
|
||||
}
|
||||
|
||||
func (b *whitespaceBackend) ListGroups(max int) ([]*nntp.Group, error) {
|
||||
return []*nntp.Group{b.group}, nil
|
||||
}
|
||||
|
||||
func (b *whitespaceBackend) GetGroup(name string) (*nntp.Group, error) {
|
||||
if name == b.group.Name {
|
||||
return b.group, nil
|
||||
}
|
||||
return nil, ErrNoSuchGroup
|
||||
}
|
||||
|
||||
func (b *whitespaceBackend) GetArticle(group *nntp.Group, id string) (*nntp.Article, error) {
|
||||
return nil, ErrInvalidArticleNumber
|
||||
}
|
||||
|
||||
func (b *whitespaceBackend) GetArticles(group *nntp.Group, from, to int64) ([]NumberedArticle, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (b *whitespaceBackend) Authorized() bool { return true }
|
||||
|
||||
func (b *whitespaceBackend) Authenticate(user, pass string) (Backend, error) {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (b *whitespaceBackend) AllowPost() bool { return b.allowPost }
|
||||
|
||||
func (b *whitespaceBackend) Post(article *nntp.Article) error {
|
||||
return errors.New("posting disabled")
|
||||
}
|
||||
|
||||
func TestProcessCollapsesRepeatedCommandWhitespace(t *testing.T) {
|
||||
backend := &whitespaceBackend{
|
||||
group: &nntp.Group{Name: "pfs.general", Count: 1, Low: 1, High: 1, Posting: nntp.PostingPermitted},
|
||||
}
|
||||
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("GROUP pfs.general"); err != nil {
|
||||
t.Fatalf("send GROUP: %v", err)
|
||||
}
|
||||
if line, err := client.ReadLine(); err != nil || !strings.HasPrefix(line, "211 ") {
|
||||
t.Fatalf("GROUP with repeated spaces = %q, %v; want 211", line, err)
|
||||
}
|
||||
if err := client.PrintfLine("QUIT"); err != nil {
|
||||
t.Fatalf("send QUIT: %v", err)
|
||||
}
|
||||
if line, err := client.ReadLine(); err != nil || !strings.HasPrefix(line, "205 ") {
|
||||
t.Fatalf("QUIT = %q, %v; want 205", line, err)
|
||||
}
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
case <-time.After(time.Second):
|
||||
t.Fatal("server did not close after QUIT")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIHaveWithoutMessageIDReturnsSyntaxError(t *testing.T) {
|
||||
backend := &whitespaceBackend{
|
||||
group: &nntp.Group{Name: "pfs.general", Posting: nntp.PostingPermitted},
|
||||
allowPost: true,
|
||||
}
|
||||
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"); err != nil {
|
||||
t.Fatalf("send IHAVE: %v", err)
|
||||
}
|
||||
if line, err := client.ReadLine(); err != nil || !strings.HasPrefix(line, "501 ") {
|
||||
t.Fatalf("IHAVE without message-id = %q, %v; want 501", line, err)
|
||||
}
|
||||
if err := client.PrintfLine("QUIT"); err != nil {
|
||||
t.Fatalf("send QUIT: %v", err)
|
||||
}
|
||||
if line, err := client.ReadLine(); err != nil || !strings.HasPrefix(line, "205 ") {
|
||||
t.Fatalf("QUIT = %q, %v; want 205", line, err)
|
||||
}
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
case <-time.After(time.Second):
|
||||
t.Fatal("server did not close after QUIT")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue