Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/epp/epp.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func main() {
c, err := epp.NewConn(conn)
fatalif(err)
color.Fprintf(os.Stderr, "Logging in as %s...\n", user)
err = c.Login(user, pass, "")
_, err = c.Login(user, pass, "")
fatalif(err)

// Check
Expand Down
9 changes: 1 addition & 8 deletions conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type Conn struct {
// a connection is already opened will have no effect.
Timeout time.Duration

// m protects Greeting and LoginResult.
// m protects Greeting.
m sync.Mutex

// Greeting holds the last received greeting message from the server,
Expand All @@ -38,13 +38,6 @@ type Conn struct {
// Deprecated: This field is written to upon opening a new EPP connection and should not be modified.
Greeting

// LoginResult holds the last received login response message's Result
// from the server, in which some servers might include diagnostics such
// as connection count limits.
//
// Deprecated: this field is written to by the Login method but otherwise is not used by this package.
LoginResult Result

// mRead synchronizes connection reads.
mRead sync.Mutex

Expand Down
14 changes: 4 additions & 10 deletions session.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,16 @@ import (

// Login initializes an authenticated EPP session.
// https://tools.ietf.org/html/rfc5730#section-2.9.1.1
func (c *Conn) Login(user, password, newPassword string) error {
func (c *Conn) Login(user, password, newPassword string) (Result, error) {
err := c.writeLogin(user, password, newPassword)
if err != nil {
return err
return Result{}, err
}
res, err := c.readResponse()
if err != nil {
return err
return Result{}, err
}
// We always have a .Result in our non-pointer, but it might be meaningless.
// We might not have read anything. We think that the worst case is we
// have the same zero values we'd get without the assignment-even-in-error-case.
c.m.Lock()
c.LoginResult = res.Result
c.m.Unlock()
return err
return res.Result, nil
}

func (c *Conn) writeLogin(user, password, newPassword string) error {
Expand Down
47 changes: 47 additions & 0 deletions session_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package epp

import (
"encoding/xml"
"net"
"testing"

"github.com/nbio/st"
Expand Down Expand Up @@ -45,6 +46,52 @@ var (
}
)

func TestLoginReturnsResult(t *testing.T) {
ls, err := newLocalServer()
st.Assert(t, err, nil)
defer ls.teardown()
ls.buildup(func(ls *localServer, ln net.Listener) {
conn, err := ls.Accept()
st.Assert(t, err, nil)
// Send greeting
err = writeDataUnit(conn, []byte(testXMLGreeting))
st.Assert(t, err, nil)
// Read login request
_, err = readDataUnitHeader(conn)
st.Assert(t, err, nil)
// Send login response
err = writeDataUnit(conn, []byte(testXMLLoginResponse))
st.Assert(t, err, nil)
// Read logout request
_, err = readDataUnitHeader(conn)
st.Assert(t, err, nil)
conn.Close()
})
nc, err := net.Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
st.Assert(t, err, nil)
c, err := NewConn(nc)
st.Assert(t, err, nil)

result, err := c.Login("jane", "battery", "")
st.Expect(t, err, nil)
st.Expect(t, result.Code, 1000)
st.Expect(t, result.Message, "Command completed successfully")

c.Close()
}

var testXMLLoginResponse = `<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<response>
<result code="1000">
<msg>Command completed successfully</msg>
</result>
<trID>
<svTRID>12345</svTRID>
</trID>
</response>
</epp>`

func BenchmarkEncodeLogin(b *testing.B) {
for i := 0; i < b.N; i++ {
encodeLogin("jane", "battery", "horse", "1.0", "en", testObjects, testExtensions)
Expand Down