12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598 |
- package guerrilla
- import (
- "bufio"
- "errors"
- "fmt"
- "io/ioutil"
- "net"
- "os"
- "strings"
- "testing"
- "time"
- "github.com/flashmob/go-guerrilla/backends"
- _ "github.com/flashmob/go-guerrilla/chunk"
- "github.com/flashmob/go-guerrilla/log"
- "github.com/flashmob/go-guerrilla/mail"
- "github.com/flashmob/go-guerrilla/response"
- )
- // Test Starting smtp without setting up logger / backend
- func TestSMTP(t *testing.T) {
- done := make(chan bool)
- go func() {
- select {
- case <-time.After(time.Second * 40):
- t.Error("timeout")
- return
- case <-done:
- return
- }
- }()
- d := Daemon{}
- err := d.Start()
- if err != nil {
- t.Error(err)
- }
- // it should set to stderr automatically
- if d.Config.LogFile != log.OutputStderr.String() {
- t.Error("smtp.config.LogFile is not", log.OutputStderr.String())
- }
- if len(d.Config.AllowedHosts) == 0 {
- t.Error("smtp.config.AllowedHosts len should be 1, not 0", d.Config.AllowedHosts)
- }
- if d.Config.LogLevel != "debug" {
- t.Error("smtp.config.LogLevel expected'debug', it is", d.Config.LogLevel)
- }
- if len(d.Config.Servers) != 1 {
- t.Error("len(smtp.config.Servers) should be 1, got", len(d.Config.Servers))
- }
- time.Sleep(time.Second * 2)
- d.Shutdown()
- done <- true
- }
- // Suppressing log output
- func TestSMTPNoLog(t *testing.T) {
- // configure a default server with no log output
- cfg := &AppConfig{LogFile: log.OutputOff.String()}
- d := Daemon{Config: cfg}
- err := d.Start()
- if err != nil {
- t.Error(err)
- }
- time.Sleep(time.Second * 2)
- d.Shutdown()
- }
- // our custom server
- func TestSMTPCustomServer(t *testing.T) {
- cfg := &AppConfig{LogFile: log.OutputOff.String()}
- sc := ServerConfig{
- ListenInterface: "127.0.0.1:2526",
- IsEnabled: true,
- }
- cfg.Servers = append(cfg.Servers, sc)
- d := Daemon{Config: cfg}
- err := d.Start()
- if err != nil {
- t.Error("start error", err)
- } else {
- time.Sleep(time.Second * 2)
- d.Shutdown()
- }
- }
- // with a backend config
- func TestSMTPCustomBackend(t *testing.T) {
- cfg := &AppConfig{LogFile: log.OutputOff.String()}
- sc := ServerConfig{
- ListenInterface: "127.0.0.1:2526",
- IsEnabled: true,
- }
- cfg.Servers = append(cfg.Servers, sc)
- bcfg := backends.BackendConfig{
- backends.ConfigProcessors: {
- "debugger": {
- "log_received_mails": true,
- },
- "header": {
- "primary_mail_host": "example.com",
- },
- },
- backends.ConfigGateways: {
- "default": {
- "save_workers_size": 3,
- "save_process": "HeadersParser|Header|Hasher|Debugger",
- },
- },
- }
- cfg.BackendConfig = bcfg
- d := Daemon{Config: cfg}
- err := d.Start()
- if err != nil {
- t.Error("start error", err)
- } else {
- time.Sleep(time.Second * 2)
- d.Shutdown()
- }
- }
- // with a config from a json file
- func TestSMTPLoadFile(t *testing.T) {
- json := `{
- "log_file" : "./tests/testlog",
- "log_level" : "debug",
- "pid_file" : "tests/go-guerrilla.pid",
- "allowed_hosts": ["spam4.me","grr.la"],
- "backend" : {
- "processors" : {
- "debugger" : {
- "log_received_mails" : true
- }
- },
- "gateways" : {
- "default" : {
- "save_workers_size" : 3,
- "save_process": "HeadersParser|Header|Hasher|Debugger"
- }
- }
- },
- "servers" : [
- {
- "is_enabled" : true,
- "host_name":"mail.guerrillamail.com",
- "max_size": 100017,
- "timeout":160,
- "listen_interface":"127.0.0.1:2526",
- "max_clients": 2,
- "tls" : {
- "private_key_file":"config_test.go",
- "public_key_file":"config_test.go",
- "start_tls_on":false,
- "tls_always_on":false
- }
- }
- ]
- }
- `
- json2 := `{
- "log_file" : "./tests/testlog2",
- "log_level" : "debug",
- "pid_file" : "tests/go-guerrilla2.pid",
- "allowed_hosts": ["spam4.me","grr.la"],
- "backend" : {
- "processors" : {
- "debugger" : {
- "log_received_mails" : true
- }
- },
- "gateways" : {
- "default" : {
- "save_workers_size" : 3,
- "save_process": "HeadersParser|Header|Hasher|Debugger"
- }
- }
- },
- "servers" : [
- {
- "is_enabled" : true,
- "host_name":"mail.guerrillamail.com",
- "max_size": 100017,
- "timeout":160,
- "listen_interface":"127.0.0.1:2526",
- "max_clients": 2,
- "tls" : {
- "private_key_file":"config_test.go",
- "public_key_file":"config_test.go",
- "start_tls_on":false,
- "tls_always_on":false
- }
- }
- ]
- }
- `
- err := ioutil.WriteFile("goguerrilla.conf.api", []byte(json), 0644)
- if err != nil {
- t.Error("could not write guerrilla.conf.api", err)
- return
- }
- d := Daemon{}
- _, err = d.LoadConfig("goguerrilla.conf.api")
- if err != nil {
- t.Error("ReadConfig error", err)
- return
- }
- err = d.Start()
- if err != nil {
- t.Error("start error", err)
- return
- } else {
- time.Sleep(time.Second * 2)
- if d.Config.LogFile != "./tests/testlog" {
- t.Error("d.Config.LogFile != \"./tests/testlog\"")
- }
- if d.Config.PidFile != "tests/go-guerrilla.pid" {
- t.Error("d.Config.LogFile != tests/go-guerrilla.pid")
- }
- err := ioutil.WriteFile("goguerrilla.conf.api", []byte(json2), 0644)
- if err != nil {
- t.Error("could not write guerrilla.conf.api", err)
- return
- }
- if err = d.ReloadConfigFile("goguerrilla.conf.api"); err != nil {
- t.Error(err)
- }
- if d.Config.LogFile != "./tests/testlog2" {
- t.Error("d.Config.LogFile != \"./tests/testlog\"")
- }
- if d.Config.PidFile != "tests/go-guerrilla2.pid" {
- t.Error("d.Config.LogFile != \"go-guerrilla.pid\"")
- }
- d.Shutdown()
- }
- }
- // test re-opening the main log
- func TestReopenLog(t *testing.T) {
- if err := os.Truncate("tests/testlog", 0); err != nil {
- t.Error(err)
- }
- cfg := &AppConfig{LogFile: "tests/testlog"}
- sc := ServerConfig{
- ListenInterface: "127.0.0.1:2526",
- IsEnabled: true,
- }
- cfg.Servers = append(cfg.Servers, sc)
- d := Daemon{Config: cfg}
- err := d.Start()
- if err != nil {
- t.Error("start error", err)
- } else {
- if err = d.ReopenLogs(); err != nil {
- t.Error(err)
- }
- time.Sleep(time.Second * 2)
- d.Shutdown()
- }
- b, err := ioutil.ReadFile("tests/testlog")
- if err != nil {
- t.Error("could not read logfile")
- return
- }
- if !strings.Contains(string(b), "re-opened log file") {
- t.Error("Server log did not re-opened, expecting \"re-opened log file\"")
- }
- if !strings.Contains(string(b), "re-opened main log file") {
- t.Error("Main log did not re-opened, expecting \"re-opened main log file\"")
- }
- }
- const testServerLog = "tests/testlog-server.log"
- // test re-opening the individual server log
- func TestReopenServerLog(t *testing.T) {
- if err := os.Truncate("tests/testlog", 0); err != nil {
- t.Error(err)
- }
- defer func() {
- if _, err := os.Stat(testServerLog); err == nil {
- if err = os.Remove(testServerLog); err != nil {
- t.Error(err)
- }
- }
- }()
- cfg := &AppConfig{LogFile: "tests/testlog", LogLevel: log.DebugLevel.String(), AllowedHosts: []string{"grr.la"}}
- sc := ServerConfig{
- ListenInterface: "127.0.0.1:2526",
- IsEnabled: true,
- LogFile: testServerLog,
- }
- cfg.Servers = append(cfg.Servers, sc)
- d := Daemon{Config: cfg}
- err := d.Start()
- if err != nil {
- t.Error("start error", err)
- } else {
- if err := talkToServer("127.0.0.1:2526", ""); err != nil {
- t.Error(err)
- }
- if err = d.ReopenLogs(); err != nil {
- t.Error(err)
- }
- time.Sleep(time.Second * 2)
- if err := talkToServer("127.0.0.1:2526", ""); err != nil {
- t.Error(err)
- }
- d.Shutdown()
- }
- b, err := ioutil.ReadFile("tests/testlog")
- if err != nil {
- t.Error("could not read logfile")
- return
- }
- if !strings.Contains(string(b), "re-opened log file") {
- t.Error("Server log did not re-opened, expecting \"re-opened log file\"")
- }
- if !strings.Contains(string(b), "re-opened main log file") {
- t.Error("Main log did not re-opened, expecting \"re-opened main log file\"")
- }
- b, err = ioutil.ReadFile(testServerLog)
- if err != nil {
- t.Error("could not read logfile")
- return
- }
- if !strings.Contains(string(b), "handle client") {
- t.Error("server log does not contain \"handle client\"")
- }
- }
- func TestSetConfig(t *testing.T) {
- if err := os.Truncate("tests/testlog", 0); err != nil {
- t.Error(err)
- }
- cfg := AppConfig{LogFile: "tests/testlog"}
- sc := ServerConfig{
- ListenInterface: "127.0.0.1:2526",
- IsEnabled: true,
- }
- cfg.Servers = append(cfg.Servers, sc)
- d := Daemon{Config: &cfg}
- // lets add a new server
- sc.ListenInterface = "127.0.0.1:2527"
- cfg.Servers = append(cfg.Servers, sc)
- err := d.SetConfig(cfg)
- if err != nil {
- t.Error("SetConfig returned an error:", err)
- return
- }
- err = d.Start()
- if err != nil {
- t.Error("start error", err)
- } else {
- time.Sleep(time.Second * 2)
- d.Shutdown()
- }
- b, err := ioutil.ReadFile("tests/testlog")
- if err != nil {
- t.Error("could not read logfile")
- return
- }
- //fmt.Println(string(b))
- // has 127.0.0.1:2527 started?
- if !strings.Contains(string(b), "127.0.0.1:2527") {
- t.Error("expecting 127.0.0.1:2527 to start")
- }
- }
- func TestSetConfigError(t *testing.T) {
- if err := os.Truncate("tests/testlog", 0); err != nil {
- t.Error(err)
- }
- cfg := AppConfig{LogFile: "tests/testlog"}
- sc := ServerConfig{
- ListenInterface: "127.0.0.1:2526",
- IsEnabled: true,
- }
- cfg.Servers = append(cfg.Servers, sc)
- d := Daemon{Config: &cfg}
- // lets add a new server with bad TLS
- sc.ListenInterface = "127.0.0.1:2527"
- sc.TLS.StartTLSOn = true
- sc.TLS.PublicKeyFile = "tests/testlog" // totally wrong :->
- sc.TLS.PrivateKeyFile = "tests/testlog" // totally wrong :->
- cfg.Servers = append(cfg.Servers, sc)
- err := d.SetConfig(cfg)
- if err == nil {
- t.Error("SetConfig should have returned an error complaining about bad tls settings")
- return
- }
- }
- var funkyLogger = func() backends.Decorator {
- backends.Svc.AddInitializer(
- backends.InitializeWith(
- func(backendConfig backends.BackendConfig) error {
- backends.Log().Info("Funky logger is up & down to funk!")
- return nil
- }),
- )
- backends.Svc.AddShutdowner(
- backends.ShutdownWith(
- func() error {
- backends.Log().Info("The funk has been stopped!")
- return nil
- }),
- )
- return func(p backends.Processor) backends.Processor {
- return backends.ProcessWith(
- func(e *mail.Envelope, task backends.SelectTask) (backends.Result, error) {
- if task == backends.TaskValidateRcpt {
- // log the last recipient appended to e.Rcpt
- backends.Log().Fields("recipient", e.RcptTo[len(e.RcptTo)-1]).Info(
- "another funky recipient")
- // if valid then forward call to the next processor in the chain
- return p.Process(e, task)
- } else if task == backends.TaskSaveMail {
- backends.Log().Info("Another funky email!")
- }
- return p.Process(e, task)
- })
- }
- }
- // How about a custom processor?
- func TestSetAddProcessor(t *testing.T) {
- if err := os.Truncate("tests/testlog", 0); err != nil {
- t.Error(err)
- }
- cfg := &AppConfig{
- LogFile: "tests/testlog",
- AllowedHosts: []string{"grr.la"},
- BackendConfig: backends.BackendConfig{
- backends.ConfigGateways: {
- "default": {
- "save_process": "HeadersParser|Debugger|FunkyLogger",
- "validate_process": "FunkyLogger",
- },
- },
- },
- }
- d := Daemon{Config: cfg}
- d.AddProcessor("FunkyLogger", funkyLogger)
- if err := d.Start(); err != nil {
- t.Error(err)
- }
- // lets have a talk with the server
- if err := talkToServer("127.0.0.1:2525", ""); err != nil {
- t.Error(err)
- }
- d.Shutdown()
- b, err := ioutil.ReadFile("tests/testlog")
- if err != nil {
- t.Error("could not read logfile")
- return
- }
- // lets check for fingerprints
- if !strings.Contains(string(b), "another funky recipient") {
- t.Error("did not log: another funky recipient")
- }
- if !strings.Contains(string(b), "Another funky email!") {
- t.Error("Did not log: Another funky email!")
- }
- if !strings.Contains(string(b), "Funky logger is up & down to funk") {
- t.Error("Did not log: Funky logger is up & down to funk")
- }
- if !strings.Contains(string(b), "The funk has been stopped!") {
- t.Error("Did not log:The funk has been stopped!")
- }
- }
- func talkToServer(address string, body string) (err error) {
- conn, err := net.Dial("tcp", address)
- if err != nil {
- return
- }
- in := bufio.NewReader(conn)
- str, err := in.ReadString('\n')
- if err != nil {
- return err
- }
- _, err = fmt.Fprint(conn, "HELO maildiranasaurustester\r\n")
- if err != nil {
- return err
- }
- str, err = in.ReadString('\n')
- if err != nil {
- return err
- }
- _, err = fmt.Fprint(conn, "MAIL FROM:<[email protected]> BODY=8BITMIME\r\n")
- if err != nil {
- return err
- }
- str, err = in.ReadString('\n')
- if err != nil {
- return err
- }
- _, err = fmt.Fprint(conn, "RCPT TO:<[email protected]>\r\n")
- if err != nil {
- return err
- }
- str, err = in.ReadString('\n')
- if err != nil {
- return err
- }
- _, err = fmt.Fprint(conn, "DATA\r\n")
- if err != nil {
- return err
- }
- str, err = in.ReadString('\n')
- if err != nil {
- return err
- }
- if body == "" {
- _, err = fmt.Fprint(conn, "Subject: Test subject\r\n")
- if err != nil {
- return err
- }
- _, err = fmt.Fprint(conn, "\r\n")
- if err != nil {
- return err
- }
- _, err = fmt.Fprint(conn, "A an email body\r\n")
- if err != nil {
- return err
- }
- _, err = fmt.Fprint(conn, ".\r\n")
- if err != nil {
- return err
- }
- } else {
- _, err = fmt.Fprint(conn, body)
- if err != nil {
- return err
- }
- _, err = fmt.Fprint(conn, ".\r\n")
- if err != nil {
- return err
- }
- }
- str, err = in.ReadString('\n')
- if err != nil {
- return err
- }
- _, err = fmt.Fprint(conn, "QUIT\r\n")
- if err != nil {
- return err
- }
- _ = str
- return nil
- }
- // Test hot config reload
- // Here we forgot to add FunkyLogger so backend will fail to init
- // it will log to stderr at the beginning, but then change to tests/testlog
- func TestReloadConfig(t *testing.T) {
- if err := os.Truncate("tests/testlog", 0); err != nil {
- t.Error(err)
- }
- d := Daemon{}
- if err := d.Start(); err != nil {
- t.Error(err)
- }
- defer d.Shutdown()
- cfg := AppConfig{
- LogFile: "tests/testlog",
- AllowedHosts: []string{"grr.la"},
- BackendConfig: backends.BackendConfig{
- backends.ConfigGateways: {
- "default": {
- "save_process": "HeadersParser|Debugger|FunkyLogger",
- "validate_process": "FunkyLogger",
- },
- },
- },
- }
- // Look mom, reloading the config without shutting down!
- if err := d.ReloadConfig(cfg); err != nil {
- t.Error(err)
- }
- }
- func TestPubSubAPI(t *testing.T) {
- if err := truncateIfExists("tests/testlog"); err != nil {
- t.Error(err)
- }
- if err := truncateIfExists("tests/pidfilex.pid"); err != nil {
- t.Error(err)
- }
- d := Daemon{Config: &AppConfig{LogFile: "tests/testlog"}}
- if err := d.Start(); err != nil {
- t.Error(err)
- }
- defer d.Shutdown()
- // new config
- cfg := AppConfig{
- PidFile: "tests/pidfilex.pid",
- LogFile: "tests/testlog",
- AllowedHosts: []string{"grr.la"},
- BackendConfig: backends.BackendConfig{
- backends.ConfigGateways: {
- "default": {
- "save_process": "HeadersParser|Debugger|FunkyLogger",
- "validate_process": "FunkyLogger",
- },
- },
- },
- }
- var i = 0
- pidEvHandler := func(c *AppConfig) {
- i++
- if i > 1 {
- t.Error("number > 1, it means d.Unsubscribe didn't work")
- }
- d.Logger.Info("number", i)
- }
- if err := d.Subscribe(EventConfigPidFile, pidEvHandler); err != nil {
- t.Error(err)
- }
- if err := d.ReloadConfig(cfg); err != nil {
- t.Error(err)
- }
- if err := d.Unsubscribe(EventConfigPidFile, pidEvHandler); err != nil {
- t.Error(err)
- }
- cfg.PidFile = "tests/pidfile2.pid"
- d.Publish(EventConfigPidFile, &cfg)
- if err := d.ReloadConfig(cfg); err != nil {
- t.Error(err)
- }
- b, err := ioutil.ReadFile("tests/testlog")
- if err != nil {
- t.Error("could not read logfile")
- return
- }
- // lets interrogate the log
- if !strings.Contains(string(b), "number1") {
- t.Error("it lools like d.ReloadConfig(cfg) did not fire EventConfigPidFile, pidEvHandler not called")
- }
- }
- func TestAPILog(t *testing.T) {
- if err := os.Truncate("tests/testlog", 0); err != nil {
- t.Error(err)
- }
- d := Daemon{}
- l := d.Log()
- l.Info("logtest1") // to stderr
- if l.GetLevel() != log.InfoLevel.String() {
- t.Error("Log level does not eq info, it is ", l.GetLevel())
- }
- d.Logger = nil
- d.Config = &AppConfig{LogFile: "tests/testlog"}
- l = d.Log()
- l.Info("logtest1") // to tests/testlog
- //
- l = d.Log()
- if l.GetLogDest() != "tests/testlog" {
- t.Error("log dest is not tests/testlog, it was ", l.GetLogDest())
- }
- b, err := ioutil.ReadFile("tests/testlog")
- if err != nil {
- t.Error("could not read logfile")
- return
- }
- // lets interrogate the log
- if !strings.Contains(string(b), "logtest1") {
- t.Error("hai was not found in the log, it should have been in tests/testlog")
- }
- }
- // Test the allowed_hosts config option with a single entry of ".", which will allow all hosts.
- func TestSkipAllowsHost(t *testing.T) {
- d := Daemon{}
- defer d.Shutdown()
- // setting the allowed hosts to a single entry with a dot will let any host through
- d.Config = &AppConfig{AllowedHosts: []string{"."}, LogFile: "off"}
- if err := d.Start(); err != nil {
- t.Error(err)
- }
- conn, err := net.Dial("tcp", d.Config.Servers[0].ListenInterface)
- if err != nil {
- t.Error(t)
- return
- }
- in := bufio.NewReader(conn)
- if _, err := fmt.Fprint(conn, "HELO test\r\n"); err != nil {
- t.Error(err)
- }
- if _, err := fmt.Fprint(conn, "RCPT TO:<[email protected]>\r\n"); err != nil {
- t.Error(err)
- }
- if _, err := in.ReadString('\n'); err != nil {
- t.Error(err)
- }
- if _, err := in.ReadString('\n'); err != nil {
- t.Error(err)
- }
- str, _ := in.ReadString('\n')
- if strings.Index(str, "250") != 0 {
- t.Error("expected 250 reply, got:", str)
- }
- }
- var customBackend2 = func() backends.Decorator {
- return func(p backends.Processor) backends.Processor {
- return backends.ProcessWith(
- func(e *mail.Envelope, task backends.SelectTask) (backends.Result, error) {
- if task == backends.TaskValidateRcpt {
- return p.Process(e, task)
- } else if task == backends.TaskSaveMail {
- backends.Log().Info("Another funky email!")
- err := errors.New("system shock")
- return backends.NewResult(response.Canned.FailReadErrorDataCmd, response.SP, err), err
- }
- return p.Process(e, task)
- })
- }
- }
- // Test a custom backend response
- func TestCustomBackendResult(t *testing.T) {
- if err := os.Truncate("tests/testlog", 0); err != nil {
- t.Error(err)
- }
- cfg := &AppConfig{
- LogFile: "tests/testlog",
- AllowedHosts: []string{"grr.la"},
- BackendConfig: backends.BackendConfig{
- backends.ConfigGateways: {
- "default": {
- "save_process": "HeadersParser|Debugger|Custom",
- "validate_process": "Custom",
- },
- },
- },
- }
- d := Daemon{Config: cfg}
- d.AddProcessor("Custom", customBackend2)
- if err := d.Start(); err != nil {
- t.Error(err)
- return
- }
- // lets have a talk with the server
- if err := talkToServer("127.0.0.1:2525", ""); err != nil {
- t.Error(err)
- }
- d.Shutdown()
- b, err := ioutil.ReadFile("tests/testlog")
- if err != nil {
- t.Error("could not read logfile")
- return
- }
- // lets check for fingerprints
- if !strings.Contains(string(b), "451 4.3.0 Error") {
- t.Error("did not log: 451 4.3.0 Error")
- }
- if !strings.Contains(string(b), "system shock") {
- t.Error("did not log: system shock")
- }
- }
- // Test a backends removed, 2 new backends added added
- func TestBackendAddRemove(t *testing.T) {
- if err := os.Truncate("tests/testlog", 0); err != nil {
- t.Error(err)
- }
- servers := []ServerConfig{
- 0: {
- IsEnabled: true,
- Hostname: "mail.guerrillamail.com",
- MaxSize: 100017,
- Timeout: 160,
- ListenInterface: "127.0.0.1:2526",
- MaxClients: 2,
- TLS: ServerTLSConfig{
- PrivateKeyFile: "",
- PublicKeyFile: "",
- StartTLSOn: false,
- AlwaysOn: false,
- },
- },
- }
- cfg := &AppConfig{
- LogFile: "tests/testlog",
- PidFile: "tests/go-guerrilla.pid",
- AllowedHosts: []string{"grr.la", "spam4.me"},
- BackendConfig: backends.BackendConfig{
- backends.ConfigGateways: {
- "default": {
- "save_process": "HeadersParser|Debugger|Custom",
- "validate_process": "Custom",
- },
- "temp": {
- "save_process": "HeadersParser|Debugger|Custom",
- "validate_process": "Custom",
- },
- },
- },
- Servers: servers,
- }
- d := Daemon{Config: cfg}
- d.AddProcessor("Custom", customBackend2)
- if err := d.Start(); err != nil {
- t.Error(err)
- return
- }
- cfg2 := *cfg
- cfg2.BackendConfig = backends.BackendConfig{
- backends.ConfigGateways: {
- "client1": {
- "save_process": "HeadersParser|Debugger|Custom",
- "validate_process": "Custom",
- },
- "client2": {
- "save_process": "HeadersParser|Debugger",
- "validate_process": "Custom",
- },
- },
- }
- eventFiredAdded := false
- _ = d.Subscribe(EventConfigBackendConfigAdded, backendEvent(func(appConfig *AppConfig, name string) {
- eventFiredAdded = true
- }))
- eventFiredRemoved := false
- _ = d.Subscribe(EventConfigBackendConfigRemoved, backendEvent(func(appConfig *AppConfig, name string) {
- eventFiredRemoved = true
- }))
- // default changed, temp removed, client1 and client2 added
- if err := d.ReloadConfig(cfg2); err != nil {
- t.Error(err)
- return
- }
- d.Shutdown()
- if eventFiredAdded == false {
- t.Error("EventConfigBackendConfigAdded did not fired")
- }
- if eventFiredRemoved == false {
- t.Error("EventConfigBackendConfigRemoved did not get fired")
- }
- }
- func TestStreamProcessorConfig(t *testing.T) {
- if err := os.Truncate("tests/testlog", 0); err != nil {
- t.Error(err)
- }
- servers := []ServerConfig{
- 0: {
- IsEnabled: true,
- Hostname: "mail.guerrillamail.com",
- MaxSize: 100017,
- Timeout: 160,
- ListenInterface: "127.0.0.1:2526",
- MaxClients: 2,
- TLS: ServerTLSConfig{
- PrivateKeyFile: "",
- PublicKeyFile: "",
- StartTLSOn: false,
- AlwaysOn: false,
- },
- },
- }
- cfg := &AppConfig{
- LogFile: "tests/testlog",
- PidFile: "tests/go-guerrilla.pid",
- AllowedHosts: []string{"grr.la", "spam4.me"},
- BackendConfig: backends.BackendConfig{
- backends.ConfigStreamProcessors: {
- "chunkSaver": { // note mixed case
- "chunk_size": 8000,
- "storage_engine": "memory",
- "compress_level": 0,
- },
- "test:chunksaver": {
- "chunk_size": 8000,
- "storage_engine": "memory",
- "compress_level": 0,
- },
- "debug": {
- "sleep_seconds": 2,
- "log_reads": true,
- },
- },
- backends.ConfigGateways: {
- "default": {
- "save_stream": "mimeanalyzer|chunksaver|test|debug",
- },
- },
- },
- Servers: servers,
- }
- d := Daemon{Config: cfg}
- if err := d.Start(); err != nil {
- t.Error(err)
- return
- }
- d.Shutdown()
- }
- func TestStreamProcessor(t *testing.T) {
- if err := os.Truncate("tests/testlog", 0); err != nil {
- t.Error(err)
- }
- cfg := &AppConfig{
- LogFile: "tests/testlog",
- AllowedHosts: []string{"grr.la"},
- BackendConfig: backends.BackendConfig{
- backends.ConfigStreamProcessors: {
- "debug": {
- "log_reads": true,
- },
- },
- backends.ConfigGateways: {
- "default": {
- "save_process": "HeadersParser|Debugger",
- "save_stream": "Header|headersparser|compress|Decompress|debug",
- "post_process": "Header|headersparser|compress|Decompress|debug",
- },
- },
- },
- }
- d := Daemon{Config: cfg}
- if err := d.Start(); err != nil {
- t.Error(err)
- }
- body := "Subject: Test subject\r\n" +
- //"\r\n" +
- "A an email body.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n"
- // lets have a talk with the server
- if err := talkToServer("127.0.0.1:2525", body); err != nil {
- t.Error(err)
- }
- d.Shutdown()
- b, err := ioutil.ReadFile("tests/testlog")
- if err != nil {
- t.Error("could not read logfile")
- return
- }
- // lets check for fingerprints
- if strings.Index(string(b), "debug stream") < 0 {
- t.Error("did not log: Debug stream")
- }
- if strings.Index(string(b), "Error") != -1 {
- t.Error("There was an error", string(b))
- }
- }
- func TestStreamProcessorBackground(t *testing.T) {
- if err := os.Truncate("tests/testlog", 0); err != nil {
- t.Error(err)
- }
- cfg := &AppConfig{
- LogFile: "tests/testlog",
- AllowedHosts: []string{"grr.la"},
- BackendConfig: backends.BackendConfig{
- backends.ConfigStreamProcessors: {
- "debug": {
- "log_reads": true,
- },
- "moo:chunksaver": {
- "chunk_size": 8000,
- "storage_engine": "memory",
- "compress_level": 0,
- },
- },
- backends.ConfigGateways: {
- "default": {
- "save_process": "",
- "save_stream": "mimeanalyzer|moo",
- "post_process_consumer": "Header|headersparser|compress|Decompress|debug",
- "post_process_producer": "moo",
- "post_process_size": 100,
- "stream_buffer_size": 1024,
- "save_workers_size": 8,
- "save_timeout": "20s",
- "val_rcpt_timeout": "2s",
- },
- },
- },
- }
- d := Daemon{Config: cfg}
- if err := d.Start(); err != nil {
- t.Error(err)
- }
- body := "Subject: Test subject\r\n" +
- "\r\n" +
- "A an email body.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n" +
- "Header|headersparser|compress|Decompress|debug Header|headersparser|compress|Decompress|debug.\r\n"
- // lets have a talk with the server
- if err := talkToServer("127.0.0.1:2525", body); err != nil {
- t.Error(err)
- }
- d.Shutdown()
- b, err := ioutil.ReadFile("tests/testlog")
- if err != nil {
- t.Error("could not read logfile")
- return
- }
- time.Sleep(time.Second * 2)
- // lets check for fingerprints
- if strings.Index(string(b), "debug stream") < 0 {
- t.Error("did not log: Debug stream")
- }
- if strings.Index(string(b), "background process done") < 0 {
- t.Error("did not log: background process done")
- }
- if strings.Index(string(b), "Error") != -1 {
- t.Error("There was an error", string(b))
- }
- }
- var mime0 = `MIME-Version: 1.0
- X-Mailer: MailBee.NET 8.0.4.428
- Subject: test
- subject
- To: [email protected]
- Content-Type: multipart/mixed;
- boundary="XXXXboundary text"
- --XXXXboundary text
- Content-Type: multipart/alternative;
- boundary="XXXXboundary text"
- --XXXXboundary text
- Content-Type: text/plain;
- charset="utf-8"
- Content-Transfer-Encoding: quoted-printable
- This is the body text of a sample message.
- --XXXXboundary text
- Content-Type: text/html;
- charset="utf-8"
- Content-Transfer-Encoding: quoted-printable
- <pre>This is the body text of a sample message.</pre>
- --XXXXboundary text
- Content-Type: text/plain;
- name="log_attachment.txt"
- Content-Disposition: attachment;
- filename="log_attachment.txt"
- Content-Transfer-Encoding: base64
- TUlNRS1WZXJzaW9uOiAxLjANClgtTWFpbGVyOiBNYWlsQmVlLk5FVCA4LjAuNC40MjgNClN1Ympl
- Y3Q6IHRlc3Qgc3ViamVjdA0KVG86IGtldmlubUBkYXRhbW90aW9uLmNvbQ0KQ29udGVudC1UeXBl
- OiBtdWx0aXBhcnQvYWx0ZXJuYXRpdmU7DQoJYm91bmRhcnk9Ii0tLS09X05leHRQYXJ0XzAwMF9B
- RTZCXzcyNUUwOUFGLjg4QjdGOTM0Ig0KDQoNCi0tLS0tLT1fTmV4dFBhcnRfMDAwX0FFNkJfNzI1
- RTA5QUYuODhCN0Y5MzQNCkNvbnRlbnQtVHlwZTogdGV4dC9wbGFpbjsNCgljaGFyc2V0PSJ1dGYt
- OCINCkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IHF1b3RlZC1wcmludGFibGUNCg0KdGVzdCBi
- b2R5DQotLS0tLS09X05leHRQYXJ0XzAwMF9BRTZCXzcyNUUwOUFGLjg4QjdGOTM0DQpDb250ZW50
- LVR5cGU6IHRleHQvaHRtbDsNCgljaGFyc2V0PSJ1dGYtOCINCkNvbnRlbnQtVHJhbnNmZXItRW5j
- b2Rpbmc6IHF1b3RlZC1wcmludGFibGUNCg0KPHByZT50ZXN0IGJvZHk8L3ByZT4NCi0tLS0tLT1f
- TmV4dFBhcnRfMDAwX0FFNkJfNzI1RTA5QUYuODhCN0Y5MzQtLQ0K
- --XXXXboundary text--
- `
- var mime2 = `From: [email protected]
- Content-Type: multipart/mixed;
- boundary="----_=_NextPart_001_01CBE273.65A0E7AA"
- To: [email protected]
- This is a multi-part message in MIME format.
- ------_=_NextPart_001_01CBE273.65A0E7AA
- Content-Type: multipart/alternative;
- boundary="----_=_NextPart_002_01CBE273.65A0E7AA"
- ------_=_NextPart_002_01CBE273.65A0E7AA
- Content-Type: text/plain;
- charset="UTF-8"
- Content-Transfer-Encoding: base64
- [base64-content]
- ------_=_NextPart_002_01CBE273.65A0E7AA
- Content-Type: text/html;
- charset="UTF-8"
- Content-Transfer-Encoding: base64
- [base64-content]
- ------_=_NextPart_002_01CBE273.65A0E7AA--
- ------_=_NextPart_001_01CBE273.65A0E7AA
- Content-Type: message/rfc822
- Content-Transfer-Encoding: 7bit
- X-MimeOLE: Produced By Microsoft Exchange V6.5
- Content-class: urn:content-classes:message
- MIME-Version: 1.0
- Content-Type: multipart/mixed;
- boundary="----_=_NextPart_003_01CBE272.13692C80"
- From: [email protected]
- To: [email protected]
- This is a multi-part message in MIME format.
- ------_=_NextPart_003_01CBE272.13692C80
- Content-Type: multipart/alternative;
- boundary="----_=_NextPart_004_01CBE272.13692C80"
- ------_=_NextPart_004_01CBE272.13692C80
- Content-Type: text/plain;
- charset="iso-8859-1"
- Content-Transfer-Encoding: quoted-printable
- =20
- Viele Gr=FC=DFe
- ------_=_NextPart_004_01CBE272.13692C80
- Content-Type: text/html;
- charset="iso-8859-1"
- Content-Transfer-Encoding: quoted-printable
- <html>...</html>
- ------_=_NextPart_004_01CBE272.13692C80--
- ------_=_NextPart_003_01CBE272.13692C80
- Content-Type: application/x-zip-compressed;
- name="abc.zip"
- Content-Transfer-Encoding: base64
- Content-Disposition: attachment;
- filename="abc.zip"
- [base64-content]
- ------_=_NextPart_003_01CBE272.13692C80--
- ------_=_NextPart_001_01CBE273.65A0E7AA--
- `
- var mime3 = `From [email protected] Mon Feb 19 22:24:21 2001
- Received: from [137.154.210.66] by hotmail.com (3.2) with ESMTP id MHotMailBC5B58230039400431D5899AD24289FA0; Mon Feb 19 22:22:29 2001
- Received: from lancelot.cit.nepean.uws.edu.au (lancelot.cit.uws.edu.au [137.154.148.30])
- by day.uws.edu.au (8.11.1/8.11.1) with ESMTP id f1K6MN404936;
- Tue, 20 Feb 2001 17:22:24 +1100 (EST)
- Received: from hotmail.com (law2-f35.hotmail.com [216.32.181.35])
- by lancelot.cit.nepean.uws.edu.au (8.10.0.Beta10/8.10.0.Beta10) with ESMTP id f1K6MJb13619;
- Tue, 20 Feb 2001 17:22:19 +1100 (EST)
- Received: from mail pickup service by hotmail.com with Microsoft SMTPSVC;
- Mon, 19 Feb 2001 22:21:44 -0800
- Received: from 203.54.221.89 by lw2fd.hotmail.msn.com with HTTP; Tue, 20 Feb 2001 06:21:44 GMT
- X-Originating-IP: [203.54.221.89]
- From: "lara devine" <[email protected]>
- To: [email protected], [email protected],
- [email protected], [email protected],
- [email protected], [email protected],
- [email protected], [email protected],
- [email protected]
- Subject: Fwd: Goldfish
- Date: Tue, 20 Feb 2001 06:21:44
- Mime-Version: 1.0
- Content-Type: text/plain; format=flowed
- Message-ID: <[email protected]>
- X-OriginalArrivalTime: 20 Feb 2001 06:21:44.0718 (UTC) FILETIME=[658BDAE0:01C09B05]
- >> >Two builders (Chris and James) are seated either side of a table in a
- > > >rough
- > > >pub when a well-dressed man enters, orders beer and sits on a stool at
- > > >the bar.
- > > >The two builders start to speculate about the occupation of the suit.
- > > >
- > > >Chris: - I reckon he's an accountant.
- > > >
- > > >James: - No way - he's a stockbroker.
- > > >
- > > >Chris: - He ain't no stockbroker! A stockbroker wouldn't come in here!
- > > >
- > > >The argument repeats itself for some time until the volume of beer gets
- > > >the better of Chris and he makes for the toilet. On entering the toilet
- > > >he
- > > >sees that the suit is standing at a urinal. Curiosity and the several
- > > >beers
- > > >get the better of the builder...
- > > >
- > > >Chris: - 'scuse me.... no offence meant, but me and me mate were
- > > wondering
- > > >
- > > > what you do for a living?
- > > >
- > > >Suit: - No offence taken! I'm a Logical Scientist by profession!
- > > >
- > > >Chris: - Oh! What's that then?
- > > >
- > > >Suit:- I'll try to explain by example... Do you have a goldfish at
- >home?
- > > >
- > > >Chris:- Er...mmm... well yeah, I do as it happens!
- > > >
- > > >Suit: - Well, it's logical to follow that you keep it in a bowl or in a
- > > >pond. Which is it?
- > > >
- > > >Chris: - It's in a pond!
- > > >
- > > >Suit: - Well then it's reasonable to suppose that you have a large
- > > >garden
- > > >then?
- > > >
- > > >Chris: - As it happens, yes I have got a big garden!
- > > >
- > > >Suit: - Well then it's logical to assume that in this town that if you
- > > >have a large garden that you have a large house?
- > > >
- > > >Chris: - As it happens I've got a five bedroom house... built it
- >myself!
- > > >
- > > >Suit: - Well given that you've built a five-bedroom house it is logical
- > > >to asume that you haven't built it just for yourself and that you are
- > > >quite
- > > >probably married?
- > > >
- > > >Chris: - Yes I am married, I live with my wife and three children!
- > > >
- > > >Suit: - Well then it is logical to assume that you are sexually active
- > > >with your wife on a regular basis?
- > > >
- > > >Chris:- Yep! Four nights a week!
- > > >
- > > >Suit: - Well then it is logical to suggest that you do not masturbate
- > > >very often?
- > > >
- > > >Chris: - Me? Never.
- > > >
- > > >Suit: - Well there you are! That's logical science at work!
- > > >
- > > >Chris:- How's that then?
- > > >
- > > >Suit: - Well from finding out that you had a goldfish, I've told you
- > > >about the size of garden you have, size of house, your family and your
- > > >sex
- > > >life!
- > > >
- > > >Chris: - I see! That's pretty impressive... thanks mate!
- > > >
- > > >Both leave the toilet and Chris returns to his mate.
- > > >
- > > >James: - I see the suit was in there. Did you ask him what he does?
- > > >
- > > >Chris: - Yep! He's a logical scientist!
- > > >
- > > >James: What's a logical Scientist?
- > > >
- > > >Chris: - I'll try and explain. Do you have a goldfish?
- > > >
- > > >James: - Nope.
- > > >
- > > >Chris: - Well then, you're a wanker.
- >
- _________________________________________________________________________
- Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com.
- `
- /*
- 1 0 166 1514
- 1.1 186 260 259
- 1.2 280 374 416
- 1.3 437 530 584
- 1.4 605 769 1514
- */
- func TestStreamMimeProcessor(t *testing.T) {
- if err := os.Truncate("tests/testlog", 0); err != nil {
- t.Error(err)
- }
- cfg := &AppConfig{
- LogFile: "tests/testlog",
- AllowedHosts: []string{"grr.la"},
- BackendConfig: backends.BackendConfig{
- backends.ConfigStreamProcessors: {
- "debug": {
- "log_reads": true,
- },
- },
- backends.ConfigGateways: {
- "default": {
- "save_process": "HeadersParser|Debugger",
- "save_stream": "mimeanalyzer|headersparser|compress|Decompress|debug",
- },
- },
- },
- }
- d := Daemon{Config: cfg}
- if err := d.Start(); err != nil {
- t.Error(err)
- }
- go func() {
- time.Sleep(time.Second * 15)
- // for debugging deadlocks
- //pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
- //os.Exit(1)
- }()
- // change \n to \r\n
- mime0 = strings.Replace(mime2, "\n", "\r\n", -1)
- // lets have a talk with the server
- if err := talkToServer("127.0.0.1:2525", mime0); err != nil {
- t.Error(err)
- }
- d.Shutdown()
- b, err := ioutil.ReadFile("tests/testlog")
- if err != nil {
- t.Error("could not read logfile")
- return
- }
- // lets check for fingerprints
- if strings.Index(string(b), "debug stream") < 0 {
- t.Error("did not log: Debug stream")
- }
- if strings.Index(string(b), "Error") != -1 {
- t.Error("There was an error", string(b))
- }
- }
- var email = `From: Al Gore <[email protected]>
- To: White House Transportation Coordinator <[email protected]>
- Subject: [Fwd: Map of Argentina with Description]
- MIME-Version: 1.0
- DKIM-Signature: v=1; a=rsa-sha256; c=relaxed; s=ncr424; d=reliancegeneral.co.in;
- h=List-Unsubscribe:MIME-Version:From:To:Reply-To:Date:Subject:Content-Type:Content-Transfer-Encoding:Message-ID; [email protected];
- bh=F4UQPGEkpmh54C7v3DL8mm2db1QhZU4gRHR1jDqffG8=;
- b=MVltcq6/I9b218a370fuNFLNinR9zQcdBSmzttFkZ7TvV2mOsGrzrwORT8PKYq4KNJNOLBahswXf
- GwaMjDKT/5TXzegdX/L3f/X4bMAEO1einn+nUkVGLK4zVQus+KGqm4oP7uVXjqp70PWXScyWWkbT
- 1PGUwRfPd/HTJG5IUqs=
- Content-Type: multipart/mixed;
- boundary="D7F------------D7FD5A0B8AB9C65CCDBFA872"
- This is a multi-part message in MIME format.
- --D7F------------D7FD5A0B8AB9C65CCDBFA872
- Content-Type: text/plain; charset=us-ascii
- Content-Transfer-Encoding: 7bit
- Fred,
- Fire up Air Force One! We're going South!
- Thanks,
- Al
- --D7F------------D7FD5A0B8AB9C65CCDBFA872
- Content-Type: message/rfc822
- Content-Transfer-Encoding: 7bit
- Content-Disposition: inline
- Return-Path: <[email protected]>
- Received: from mailhost.whitehouse.gov ([192.168.51.200])
- by heartbeat.whitehouse.gov (8.8.8/8.8.8) with ESMTP id SAA22453
- for <[email protected]>;
- Mon, 13 Aug 1998 l8:14:23 +1000
- Received: from the_big_box.whitehouse.gov ([192.168.51.50])
- by mailhost.whitehouse.gov (8.8.8/8.8.7) with ESMTP id RAA20366
- for [email protected]; Mon, 13 Aug 1998 17:42:41 +1000
- Date: Mon, 13 Aug 1998 17:42:41 +1000
- Message-Id: <[email protected]>
- From: Bill Clinton <[email protected]>
- To: A1 (The Enforcer) Gore <[email protected]>
- Subject: Map of Argentina with Description
- MIME-Version: 1.0
- Content-Type: multipart/mixed;
- boundary="DC8------------DC8638F443D87A7F0726DEF7"
- This is a multi-part message in MIME format.
- --DC8------------DC8638F443D87A7F0726DEF7
- Content-Type: text/plain; charset=us-ascii
- Content-Transfer-Encoding: 7bit
- Hi A1,
- I finally figured out this MIME thing. Pretty cool. I'll send you
- some sax music in .au files next week!
- Anyway, the attached image is really too small to get a good look at
- Argentina. Try this for a much better map:
- http://www.1one1yp1anet.com/dest/sam/graphics/map-arg.htm
- Then again, shouldn't the CIA have something like that?
- Bill
- --DC8------------DC8638F443D87A7F0726DEF7
- Content-Type: image/gif; name="map_of_Argentina.gif"
- Content-Transfer-Encoding: base64
- Content-Disposition: inline; filename="map_of_Argentina.gif"
- R01GOD1hJQA1AKIAAP/////78P/omn19fQAAAAAAAAAAAAAAACwAAAAAJQA1AAAD7Qi63P5w
- wEmjBCLrnQnhYCgM1wh+pkgqqeC9XrutmBm7hAK3tP31gFcAiFKVQrGFR6kscnonTe7FAAad
- GugmRu3CmiBt57fsVq3Y0VFKnpYdxPC6M7Ze4crnnHum4oN6LFJ1bn5NXTN7OF5fQkN5WYow
- BEN2dkGQGWJtSzqGTICJgnQuTJN/WJsojad9qXMuhIWdjXKjY4tenjo6tjVssk2gaWq3uGNX
- U6ZGxseyk8SasGw3J9GRzdTQky1iHNvcPNNI4TLeKdfMvy0vMqLrItvuxfDW8ubjueDtJufz
- 7itICBxISKDBgwgTKjyYAAA7
- --DC8------------DC8638F443D87A7F0726DEF7--
- --D7F------------D7FD5A0B8AB9C65CCDBFA872--
- `
- func TestStreamChunkSaver(t *testing.T) {
- if err := os.Truncate("tests/testlog", 0); err != nil {
- t.Error(err)
- }
- go func() {
- time.Sleep(time.Second * 15)
- // for debugging deadlocks
- //pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
- //os.Exit(1)
- }()
- cfg := &AppConfig{
- LogFile: "tests/testlog",
- AllowedHosts: []string{"grr.la"},
- BackendConfig: backends.BackendConfig{
- backends.ConfigStreamProcessors: {
- "chunksaver": {
- "chunk_size": 1024 * 32,
- "stream_buffer_size": 1024 * 16,
- "storage_engine": "memory",
- },
- },
- backends.ConfigGateways: {
- "default": {
- "save_process": "HeadersParser|Debugger",
- "save_stream": "mimeanalyzer|chunksaver",
- "save_timeout": "5",
- },
- },
- },
- }
- d := Daemon{Config: cfg}
- if err := d.Start(); err != nil {
- t.Error(err)
- }
- // change \n to \r\n
- email = strings.Replace(email, "\n", "\r\n", -1)
- // lets have a talk with the server
- if err := talkToServer("127.0.0.1:2525", email); err != nil {
- t.Error(err)
- }
- time.Sleep(time.Second * 1)
- d.Shutdown()
- b, err := ioutil.ReadFile("tests/testlog")
- if err != nil {
- t.Error("could not read logfile")
- return
- }
- fmt.Println(string(b))
- // lets check for fingerprints
- if strings.Index(string(b), "Debug stream") < 0 {
- // t.Error("did not log: Debug stream")
- }
- }
|