func processConnData(conn *textproto.Conn) response { res := response{Data: make([]string, 0)} for { line, err := conn.ReadLine() if err != nil { res.Err = err break } if line == "OK" { break } match := mpdErrorRegexp.FindStringSubmatch(line) if match != nil { ack, err := strconv.ParseUint(match[1], 0, 0) if err != nil { res.Err = err break } cln, err := strconv.ParseUint(match[2], 0, 0) if err != nil { res.Err = err break } res.MPDErr = &MPDError{uint(ack), uint(cln), match[3], match[4]} break } res.Data = append(res.Data, line) } return res }
func handleAuthInfo(args []string, s *session, c *textproto.Conn) error { if len(args) < 2 { return SyntaxError } if strings.ToLower(args[0]) != "user" { return SyntaxError } if s.backend.Authorized() { return c.PrintfLine("250 authenticated") } c.PrintfLine("350 Continue") a, err := c.ReadLine() parts := strings.SplitN(a, " ", 3) if strings.ToLower(parts[0]) != "authinfo" || strings.ToLower(parts[1]) != "pass" { return SyntaxError } b, err := s.backend.Authenticate(args[1], parts[2]) if err == nil { c.PrintfLine("250 authenticated") if b != nil { s.backend = b } } return err }
func collectLines(c *textproto.Conn) ([]string, error) { var ex error var line string var msg []string var ended bool line, ex = c.ReadLine() if ex != nil { return nil, ex } if !validLine(line) { return nil, ErrShortResponse } msg = append(msg, line) ended = line[3] != '-' for ex == nil && !ended { line, ex = c.ReadLine() if ex != nil { return nil, ex } msg = append(msg, line) ended = line[3] != '-' } return msg, nil }
func read(c *textproto.Conn) (string, error) { s, err := c.ReadLine() if err == io.EOF { return s, err } if err != nil { panic(err) } return s, err }
func NewCommandRequest(c *textproto.Conn) (*CommandRequest, error) { verb, err := c.ReadLine() if err != nil { return nil, err } headers, err := c.ReadMIMEHeader() if err != nil { return nil, err } // read body here return &CommandRequest{ Method: verb, Headers: headers, //Body: body, }, nil }
func (s *server) readRequest(p *textproto.Conn) (*request, error) { line, err := p.ReadLine() if err == io.EOF { return nil, err } if err != nil { log.Printf("reading request failed: %v\n", err) return nil, err } args := parseArgs(line) if len(args) == 0 { return &request{typ: simple, args: args}, nil } switch args[0] { case "command_list_ok_begin": var cmdList [][]string for { line, err := p.ReadLine() if err == io.EOF { return nil, err } if err != nil { log.Printf("reading request failed: %v\n", err) return nil, err } args = parseArgs(line) if len(args) > 0 && args[0] == "command_list_end" { break } cmdList = append(cmdList, args) } return &request{typ: commandListOk, cmdList: cmdList}, nil case "idle": return &request{typ: idle, args: args}, nil case "noidle": return &request{typ: noIdle, args: args}, nil } return &request{typ: simple, args: args}, nil }
func MyreadCodeLine(r *textproto.Conn, expectCode int) (code int, continued bool, message string, err error) { var line string //fmt.Print("read ") line, err = r.ReadLine() if err != nil { return } //fmt.Println(line) // for ( Used disk quota 0 Kbytes, available 1000000 Kbytes) if strings.HasPrefix(line, " ") { line, _ = r.ReadLine() if err != nil { return } //fmt.Printf("1: %s\n", line) line, err = r.ReadLine() if err != nil { return } //fmt.Printf("2: %s\n", line) } code, continued, message, err = parseCodeLine(line, expectCode) return }
// run the mainloop for this connection // stream if true means they support streaming mode // reader if true means they support reader mode func (self nntpConnection) runConnection(daemon NNTPDaemon, inbound, stream, reader bool, preferMode string, conn *textproto.Conn) { var err error var line string var success bool for err == nil { if self.mode == "" { if inbound { // no mode and inbound line, err = conn.ReadLine() log.Println(self.name, line) parts := strings.Split(line, " ") cmd := parts[0] if cmd == "CAPABILITIES" { // write capabilities conn.PrintfLine("101 i support to the following:") dw := conn.DotWriter() caps := []string{"VERSION 2", "READER", "STREAMING", "IMPLEMENTATION srndv2"} for _, cap := range caps { io.WriteString(dw, cap) io.WriteString(dw, "\n") } dw.Close() log.Println(self.name, "sent Capabilities") } else if cmd == "MODE" { if len(parts) == 2 { if parts[1] == "READER" { // set reader mode self.mode = "READER" // posting is not permitted with reader mode conn.PrintfLine("201 Posting not permitted") } else if parts[1] == "STREAM" { // set streaming mode conn.PrintfLine("203 Stream it brah") self.mode = "STREAM" log.Println(self.name, "streaming enabled") go self.startStreaming(daemon, reader, conn) } } } else { // handle a it as a command, we don't have a mode set parts := strings.Split(line, " ") var code64 int64 code64, err = strconv.ParseInt(parts[0], 10, 32) if err == nil { err = self.handleLine(daemon, int(code64), line[4:], conn) } else { err = self.handleLine(daemon, 0, line, conn) } } } else { // no mode and outbound if preferMode == "stream" { // try outbound streaming if stream { success, err = self.modeSwitch("STREAM", conn) self.mode = "STREAM" if success { // start outbound streaming in background go self.startStreaming(daemon, reader, conn) } } } else if reader { // try reader mode success, err = self.modeSwitch("READER", conn) if success { self.mode = "READER" self.startReader(daemon, conn) } } if success { log.Println(self.name, "mode set to", self.mode) } else { // bullshit // we can't do anything so we quit log.Println(self.name, "can't stream or read, wtf?") conn.PrintfLine("QUIT") conn.Close() return } } } else { // we have our mode set line, err = conn.ReadLine() if err == nil { parts := strings.Split(line, " ") var code64 int64 code64, err = strconv.ParseInt(parts[0], 10, 32) if err == nil { err = self.handleLine(daemon, int(code64), line[4:], conn) } else { err = self.handleLine(daemon, 0, line, conn) } } } } log.Println(self.name, "got error", err) if !inbound { // send quit on outbound conn.PrintfLine("QUIT") } conn.Close() }
// run the mainloop for this connection // stream if true means they support streaming mode // reader if true means they support reader mode func (self *nntpConnection) runConnection(daemon *NNTPDaemon, inbound, stream, reader, use_tls bool, preferMode string, nconn net.Conn, conf *FeedConfig) { self.addr = nconn.RemoteAddr() var err error var line string var success bool var conn *textproto.Conn if (conf != nil && !conf.tls_off) && use_tls && daemon.CanTLS() && !inbound { log.Println(self.name, "STARTTLS with", self.hostname) _conn, state, err := SendStartTLS(nconn, daemon.GetTLSConfig(self.hostname)) if err == nil { // we upgraded conn = _conn self.authenticated = state.HandshakeComplete log.Println(self.name, "tls auth", self.authenticated) } else { log.Println(self.name, err) // we didn't upgrade, fall back conn = textproto.NewConn(nconn) } } else { // we are authenticated if we are don't need tls conn = textproto.NewConn(nconn) } if !inbound { if preferMode == "stream" { // try outbound streaming if stream { success, err = self.modeSwitch("STREAM", conn) if success { self.mode = "STREAM" // start outbound streaming in background go self.startStreaming(daemon, reader, conn) } } } else if reader { // try reader mode success, err = self.modeSwitch("READER", conn) if success { self.mode = "READER" self.startReader(daemon, conn) return } } if success { log.Println(self.name, "mode set to", self.mode) } else { // bullshit // we can't do anything so we quit log.Println(self.name, "can't stream or read, wtf?") conn.PrintfLine("QUIT") conn.Close() return } } for err == nil { line, err = conn.ReadLine() if self.mode == "" { if inbound { if len(line) == 0 { conn.Close() return } else if line == "QUIT" { conn.PrintfLine("205 bai") conn.Close() return } parts := strings.Split(line, " ") cmd := parts[0] if cmd == "STARTTLS" { _conn, state, err := HandleStartTLS(nconn, daemon.GetOurTLSConfig()) if err == nil { // we are now tls conn = _conn self.tls_state = state self.authenticated = state.HandshakeComplete log.Println(self.name, "TLS initiated", self.authenticated) } else { log.Println("STARTTLS failed:", err) } } else if cmd == "CAPABILITIES" { // write capabilities conn.PrintfLine("101 i support to the following:") dw := conn.DotWriter() caps := []string{"VERSION 2", "READER", "STREAMING", "IMPLEMENTATION srndv2", "POST", "IHAVE", "AUTHINFO"} if daemon.CanTLS() { caps = append(caps, "STARTTLS") } for _, cap := range caps { io.WriteString(dw, cap) io.WriteString(dw, "\n") } dw.Close() log.Println(self.name, "sent Capabilities") } else if cmd == "MODE" { if len(parts) == 2 { mode := strings.ToUpper(parts[1]) if mode == "READER" { // set reader mode self.mode = "READER" // we'll allow posting for reader conn.PrintfLine("200 Posting is Permitted awee yeh") } else if mode == "STREAM" { if !self.authenticated { conn.PrintfLine("483 Streaming Denied") } else { // set streaming mode conn.PrintfLine("203 Stream it brah") self.mode = "STREAM" log.Println(self.name, "streaming enabled") go self.startStreaming(daemon, reader, conn) } } } } else { // handle a it as a command, we don't have a mode set parts := strings.Split(line, " ") cmd := parts[0] if cmd == "STARTTLS" { _conn, state, err := HandleStartTLS(nconn, daemon.GetOurTLSConfig()) if err == nil { // we are now tls conn = _conn self.tls_state = state self.authenticated = state.HandshakeComplete log.Println("TLS initiated") } else { log.Println("STARTTLS failed:", err) nconn.Close() return } } var code64 int64 code64, err = strconv.ParseInt(parts[0], 10, 32) if err == nil { err = self.handleLine(daemon, int(code64), line[4:], conn) } else { err = self.handleLine(daemon, 0, line, conn) } } } } else { if err == nil { parts := strings.Split(line, " ") var code64 int64 code64, err = strconv.ParseInt(parts[0], 10, 32) if err == nil { err = self.handleLine(daemon, int(code64), line[4:], conn) } else { err = self.handleLine(daemon, 0, line, conn) } } } } if err != io.EOF { log.Println(self.name, "got error", err) if !inbound && conn != nil { // send quit on outbound conn.PrintfLine("QUIT") } } nconn.Close() }