|
|
|
@ -62,33 +62,46 @@ func (c *conn) Conn() net.Conn {
|
|
|
|
|
|
|
|
|
|
// ReadLine reads a single line and returns the result, or nil and error
|
|
|
|
|
func (c *conn) ReadLine() ([]byte, errors.Error) {
|
|
|
|
|
totalCount, end := 0, -1
|
|
|
|
|
for totalCount < len(c.b) {
|
|
|
|
|
totalCount, end, emptyRead := 0, -1, 0
|
|
|
|
|
for {
|
|
|
|
|
// Perform a single read into the buffer
|
|
|
|
|
count, err := c.c.Read(c.b[totalCount:])
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, ErrConnRead.Wrap(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle empty reads...
|
|
|
|
|
if count < 1 {
|
|
|
|
|
// After too many empty reads just return error
|
|
|
|
|
if !(emptyRead < 100) {
|
|
|
|
|
return nil, ErrConnRead.Wrap(io.ErrNoProgress)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Iterate empty read counter
|
|
|
|
|
emptyRead++
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Only accept up to new-line char
|
|
|
|
|
end = bytes.IndexByte(c.b[totalCount:totalCount+count], '\n')
|
|
|
|
|
if end > 0 {
|
|
|
|
|
// Remove any extra '\r'
|
|
|
|
|
// Drop any extra '\r'
|
|
|
|
|
if c.b[end-1] == '\r' {
|
|
|
|
|
end--
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Iterate total count up to the new-line
|
|
|
|
|
totalCount += end
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Iter total count
|
|
|
|
|
totalCount += count
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If end never reached, return error.
|
|
|
|
|
// Else, return slice up to end
|
|
|
|
|
if end < 0 {
|
|
|
|
|
return nil, ErrInvalidRequest
|
|
|
|
|
// If we have hit read max, return error
|
|
|
|
|
if totalCount >= len(c.b) {
|
|
|
|
|
return nil, ErrInvalidRequest
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return c.b[:totalCount], nil
|
|
|
|
|
}
|
|
|
|
|