diff options
| author | Jeff Halter <868228+jhalter@users.noreply.github.com> | 2026-03-15 14:54:44 -0700 |
|---|---|---|
| committer | Jeff Halter <868228+jhalter@users.noreply.github.com> | 2026-03-15 14:54:44 -0700 |
| commit | f78ab940a8c09702be3e0ba310ac56e02fa76701 (patch) | |
| tree | 4b128f55860d1ce7ef9c87861179d97f5732b476 /hotline/server_test.go | |
| parent | 72c6ddc104c349a4798fddeaa8f77dbe139fe104 (diff) | |
Add configurable text encoding for file and folder names
Replace hardcoded Mac Roman encoding globals with a configurable Encoding
field in config.yaml. Servers that exclusively serve modern UTF-8 clients
can now set Encoding: utf8 to disable Mac Roman conversion. The default
remains "macintosh" for backward compatibility.
- Add Encoding field to Config struct (macintosh|utf8)
- Store TextDecoder/TextEncoder on Server, initialized from config
- Add TextDecoder()/TextEncoder() accessors on ClientConn
- Pass decoder/encoder explicitly to ReadPath and GetFileNameList
- Remove package-level txtEncoder/txtDecoder globals
- Add warning log when files are skipped due to encoding errors
- Log and return error replies in HandleGetFileNameList on failure
- Document the new config option in docs/text-encoding.md
Diffstat (limited to 'hotline/server_test.go')
| -rw-r--r-- | hotline/server_test.go | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/hotline/server_test.go b/hotline/server_test.go index db70480..abc2f9a 100644 --- a/hotline/server_test.go +++ b/hotline/server_test.go @@ -13,6 +13,8 @@ import ( "time" "github.com/stretchr/testify/assert" + "golang.org/x/text/encoding" + "golang.org/x/text/encoding/charmap" ) type mockReadWriter struct { @@ -177,6 +179,8 @@ func TestServer_handleFileTransfer(t *testing.T) { Logger: tt.fields.Logger, Stats: tt.fields.Stats, FS: tt.fields.FS, + TextDecoder: charmap.Macintosh.NewDecoder(), + TextEncoder: charmap.Macintosh.NewEncoder(), } tt.wantErr(t, s.handleFileTransfer(tt.args.ctx, tt.args.rwc), fmt.Sprintf("handleFileTransfer(%v, %v)", tt.args.ctx, tt.args.rwc)) @@ -186,6 +190,56 @@ func TestServer_handleFileTransfer(t *testing.T) { } } +func TestNewServer_Encoding(t *testing.T) { + tests := []struct { + name string + encoding string + wantDecoder *encoding.Decoder + wantEncoder *encoding.Encoder + }{ + { + name: "default empty string uses Mac Roman", + encoding: "", + wantDecoder: charmap.Macintosh.NewDecoder(), + wantEncoder: charmap.Macintosh.NewEncoder(), + }, + { + name: "macintosh uses Mac Roman", + encoding: "macintosh", + wantDecoder: charmap.Macintosh.NewDecoder(), + wantEncoder: charmap.Macintosh.NewEncoder(), + }, + { + name: "utf8 uses Nop (pass-through)", + encoding: "utf8", + wantDecoder: encoding.Nop.NewDecoder(), + wantEncoder: encoding.Nop.NewEncoder(), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + srv, err := NewServer(WithConfig(Config{Encoding: tt.encoding})) + assert.NoError(t, err) + + // Verify encoder/decoder behavior by round-tripping a Mac Roman byte. + // 0x8e is Mac Roman for "é". + input := string([]byte{0x8e}) + + gotDec, err := srv.TextDecoder.String(input) + assert.NoError(t, err) + wantDec, err := tt.wantDecoder.String(input) + assert.NoError(t, err) + assert.Equal(t, wantDec, gotDec) + + gotEnc, err := srv.TextEncoder.String("é") + assert.NoError(t, err) + wantEnc, err := tt.wantEncoder.String("é") + assert.NoError(t, err) + assert.Equal(t, wantEnc, gotEnc) + }) + } +} + func TestParseTrackerPassword(t *testing.T) { tests := []struct { name string |