<commit_before>package petrel

// Copyright (c) 2014-2016 <NAME> <<EMAIL>>. All
// rights reserved.  Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Socket code for petrel

import (
	"bytes"
	"encoding/binary"
	"io"
	"net"
	"time"

	"firepear.net/qsplit"
)

// sockAccept monitors the listener socket and spawns connections for
// clients.
func (h *Server) sockAccept() {
	defer h.w.Done()
	var cn uint
	for cn = 1; true; cn++ {
		c, err := h.l.Accept()
		if err != nil {
			select {
			case <-h.q:
				// h.Quit() was invoked; close up shop
				h.genMsg(0, 0, perrs["quit"], "", nil)
				return
			default:
				// we've had a networking error
				h.genMsg(0, 0, perrs["listenerfail"], "", err)
				return
			}
		}
		// we have a new client
		h.w.Add(1)
		go h.connServer(c, cn)
	}
}

// connServer dispatches commands from, and sends reponses to, a client. It
// is launched, per-connection, from sockAccept().
func (h *Server) connServer(c net.Conn, cn uint) {
	defer h.w.Done()
	defer c.Close()
	// request counter for this connection
	var reqnum uint

	if h.li {
		h.genMsg(cn, reqnum, perrs["connect"], c.RemoteAddr().String(), nil)
	} else {
		h.genMsg(cn, reqnum, perrs["connect"], "", nil)
	}

	for {
		reqnum++
		// read the request
		req, perr, xtra, err := h.connRead(c, cn, reqnum)
		if perr != "" {
			h.genMsg(cn, reqnum, perrs[perr], xtra, err)
			if perrs[perr].xmit != nil {
				err = h.send(c, cn, reqnum, perrs[perr].xmit)
				if err != nil {
					return
				}
			}
			//TODO send "you've been disconnected" msg
			return
		}
		if len(req) == 0 {
			h.genMsg(cn, reqnum, perrs["nilreq"], "", nil)
			err = h.send(c, cn, reqnum, perrs["nilreq"].xmit)
			if err != nil {
				return
			}
			continue
		}

		// dispatch the request and get the reply
		reply, perr, xtra, err := h.reqDispatch(c, cn, reqnum, req)
		if perr != "" {
			h.genMsg(cn, reqnum, perrs[perr], xtra, err)
			if perrs[perr].xmit != nil {
				err = h.send(c, cn, reqnum, perrs[perr].xmit)
				if err != nil {
					return
				}
			}
			continue
		}

		// send reply
		err = h.send(c, cn, reqnum, reply)
		if err != nil {
			return
		}
		h.genMsg(cn, reqnum, perrs["success"], "", nil)
	}
}

// connRead does all network reads and assembles the request. If it
// returns an error, then the connection terminates because the state
// of the connection cannot be known.
func (h *Server) connRead(c net.Conn, cn, reqnum uint) ([]byte, string, string, error) {
	// buffer 0 holds the message length
	b0 := make([]byte, 4)
	// buffer 1: network reads go here, 128B at a time
	b1 := make([]byte, 128)
	// buffer 2: data accumulates here; requests pulled from here
	var b2 []byte
	// message length<commit_msg>network generalization: connection id and reqnum were needlessly being passed to Server.connRead<commit_after>package petrel

// Copyright (c) 2014-2016 <NAME> <<EMAIL>>. All
// rights reserved.  Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Socket code for petrel

import (
	"bytes"
	//"crypto/hmac"
	"encoding/binary"
	"io"
	"net"
	"time"

	"firepear.net/qsplit"
)

// sockAccept monitors the listener socket and spawns connections for
// clients.
func (h *Server) sockAccept() {
	defer h.w.Done()
	var cn uint
	for cn = 1; true; cn++ {
		c, err := h.l.Accept()
		if err != nil {
			select {
			case <-h.q:
				// h.Quit() was invoked; close up shop
				h.genMsg(0, 0, perrs["quit"], "", nil)
				return
			default:
				// we've had a networking error
				h.genMsg(0, 0, perrs["listenerfail"], "", err)
				return
			}
		}
		// we have a new client
		h.w.Add(1)
		go h.connServer(c, cn)
	}
}

// connServer dispatches commands from, and sends reponses to, a client. It
// is launched, per-connection, from sockAccept().
func (h *Server) connServer(c net.Conn, cn uint) {
	defer h.w.Done()
	defer c.Close()
	// request counter for this connection
	var reqnum uint

	if h.li {
		h.genMsg(cn, reqnum, perrs["connect"], c.RemoteAddr().String(), nil)
	} else {
		h.genMsg(cn, reqnum, perrs["connect"], "", nil)
	}

	for {
		reqnum++
		// read the request
		req, perr, xtra, err := h.connRead(c)
		if perr != "" {
			h.genMsg(cn, reqnum, perrs[perr], xtra, err)
			if perrs[perr].xmit != nil {
				err = h.send(c, cn, reqnum, perrs[perr].xmit)
				if err != nil {
					return
				}
			}
			//TODO send "you've been disconnected" msg
			return
		}
		if len(req) == 0 {
			h.genMsg(cn, reqnum, perrs["nilreq"], "", nil)
			err = h.send(c, cn, reqnum, perrs["nilreq"].xmit)
			if err != nil {
				return
			}
			continue
		}

		// dispatch the request and get the reply
		reply, perr, xtra, err := h.reqDispatch(c, cn, reqnum, req)
		if perr != "" {
			h.genMsg(cn, reqnum, perrs[perr], xtra, err)
			if perrs[perr].xmit != nil {
				err = h.send(c, cn, reqnum, perrs[perr].xmit)
				if err != nil {
					return
				}
			}
			continue
		}

		// send reply
		err = h.send(c, cn, reqnum, reply)
		if err != nil {
			return
		}
		h.genMsg(cn, reqnum, perrs["success"], "", nil)
	}
}

// connRead does all network reads and assembles the request. If it
// returns an error, then the connection terminates because the state
// of the connection cannot be known.
func (h *Server) connRead(c net.Conn) ([]byte, string, string, error) {
	// buffer 0 holds the message length
	b0 := make([]byte, 4)
	// buffer 1: network reads go here, 128B at a time
	b1 := make([]byte, 128)
	// buffer 2: data accumulates here; requests pulled from here
	var b2 []byte
	// message length
{'fraction_non_alphanumeric': 0.14912754092462674, 'fraction_numerical': 0.010073754272351142, 'mean_word_length': 2.837129054520359, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5849151', 'n_tokens_mistral': 2339, 'n_tokens_neox': 2059, 'n_words': 670}