You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

socket.go 1.6KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package irc
  2. import (
  3. "bufio"
  4. "io"
  5. "net"
  6. )
  7. const (
  8. R = '→'
  9. W = '←'
  10. EOF = ""
  11. )
  12. type Socket struct {
  13. conn net.Conn
  14. writer *bufio.Writer
  15. }
  16. func NewSocket(conn net.Conn, commands chan<- Command) *Socket {
  17. socket := &Socket{
  18. conn: conn,
  19. writer: bufio.NewWriter(conn),
  20. }
  21. go socket.readLines(commands)
  22. return socket
  23. }
  24. func (socket *Socket) String() string {
  25. return socket.conn.RemoteAddr().String()
  26. }
  27. func (socket *Socket) Close() {
  28. socket.conn.Close()
  29. Log.debug.Printf("%s closed", socket)
  30. }
  31. func (socket *Socket) readLines(commands chan<- Command) {
  32. commands <- NewProxyCommand(AddrLookupHostname(socket.conn.RemoteAddr()))
  33. scanner := bufio.NewScanner(socket.conn)
  34. for scanner.Scan() {
  35. line := scanner.Text()
  36. if len(line) == 0 {
  37. continue
  38. }
  39. Log.debug.Printf("%s → %s", socket, line)
  40. msg, err := ParseCommand(line)
  41. if err != nil {
  42. // TODO error messaging to client
  43. continue
  44. }
  45. commands <- msg
  46. }
  47. if err := scanner.Err(); err != nil {
  48. Log.debug.Printf("%s error: %s", socket, err)
  49. }
  50. commands <- NewQuitCommand("connection closed")
  51. close(commands)
  52. }
  53. func (socket *Socket) Write(line string) (err error) {
  54. if _, err = socket.writer.WriteString(line); socket.isError(err, W) {
  55. return
  56. }
  57. if _, err = socket.writer.WriteString(CRLF); socket.isError(err, W) {
  58. return
  59. }
  60. go socket.flush()
  61. Log.debug.Printf("%s ← %s", socket, line)
  62. return
  63. }
  64. func (socket *Socket) flush() {
  65. socket.isError(socket.writer.Flush(), W)
  66. }
  67. func (socket *Socket) isError(err error, dir rune) bool {
  68. if err != nil {
  69. if err != io.EOF {
  70. Log.debug.Printf("%s %c error: %s", socket, dir, err)
  71. }
  72. return true
  73. }
  74. return false
  75. }