本文整理汇总了Golang中github.com/mbenkmann/golib/bytes.Buffer.Reset方法的典型用法代码示例。如果您正苦于以下问题:Golang Buffer.Reset方法的具体用法?Golang Buffer.Reset怎么用?Golang Buffer.Reset使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类github.com/mbenkmann/golib/bytes.Buffer
的用法示例。
在下文中一共展示了Buffer.Reset方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: GosaDecryptBuffer
// Like GosaDecrypt() but operates in-place on buf.
// Returns true if decryption successful and false if not.
// If false is returned, the buffer contents may be destroyed, but only
// if further decryption attempts with other keys would be pointless anyway,
// because of some fatal condition (such as the data not being a multiple of
// the cipher's block size).
func GosaDecryptBuffer(buf *bytes.Buffer, key string) bool {
buf.TrimSpace()
if buf.Len() < 11 {
return false
} // minimum length of unencrypted <xml></xml>
data := buf.Bytes()
if string(data[0:5]) == "<xml>" {
return true
}
// Fixes the following:
// * gosa-si bug in the following line:
// if( $client_answer =~ s/session_id=(\d+)$// ) {
// This leaves the "." before "session_id" which breaks base64
// * new gosa-si protocol has ";IP:PORT" appended to message
// which also breaks base64
for semicolon_period := 0; semicolon_period < len(data); semicolon_period++ {
if data[semicolon_period] == ';' || data[semicolon_period] == '.' {
buf.Trim(0, semicolon_period)
data = buf.Bytes()
break
}
}
aescipher, _ := aes.NewCipher([]byte(util.Md5sum(key)))
crypter := cipher.NewCBCDecrypter(aescipher, config.InitializationVector)
cryptotest := make([]byte, (((3*aes.BlockSize)+2)/3)<<2)
n := copy(cryptotest, data)
cryptotest = cryptotest[0:n]
cryptotest = util.Base64DecodeInPlace(cryptotest)
n = (len(cryptotest) / aes.BlockSize) * aes.BlockSize
cryptotest = cryptotest[0:n]
crypter.CryptBlocks(cryptotest, cryptotest)
if !strings.Contains(string(cryptotest), "<xml>") {
return false
}
data = util.Base64DecodeInPlace(data)
buf.Trim(0, len(data))
data = buf.Bytes()
if buf.Len()%aes.BlockSize != 0 {
// this condition is fatal => further decryption attempts are pointless
buf.Reset()
return false
}
crypter = cipher.NewCBCDecrypter(aescipher, config.InitializationVector)
crypter.CryptBlocks(data, data)
buf.TrimSpace() // removes 0 padding, too
return true
}
示例2: faiConnection
func faiConnection(conn *net.TCPConn) {
defer conn.Close()
var err error
err = conn.SetKeepAlive(true)
if err != nil {
util.Log(0, "ERROR! SetKeepAlive: %v", err)
}
var buf bytes.Buffer
defer buf.Reset()
readbuf := make([]byte, 4096)
n := 1
for n != 0 {
n, err = conn.Read(readbuf)
if err != nil && err != io.EOF {
util.Log(0, "ERROR! Read: %v", err)
}
if n == 0 && err == nil {
util.Log(0, "ERROR! Read 0 bytes but no error reported")
}
// Find complete lines terminated by '\n' and process them.
for start := 0; ; {
eol := start
for ; eol < n; eol++ {
if readbuf[eol] == '\n' {
break
}
}
// no \n found, append to buf and continue reading
if eol == n {
buf.Write(readbuf[start:n])
break
}
// append to rest of line to buffered contents
buf.Write(readbuf[start:eol])
start = eol + 1
buf.TrimSpace()
util.Log(2, "DEBUG! FAI monitor message from %v: %v", conn.RemoteAddr(), buf.String())
buf.Reset()
}
}
if buf.Len() != 0 {
util.Log(2, "DEBUG! Incomplete FAI monitor message (i.e. not terminated by \"\\n\") from %v: %v", conn.RemoteAddr(), buf.String())
}
}
示例3: main
func main() {
if len(os.Args) != 3 && len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, "USAGE: %v", USAGE)
os.Exit(0)
}
var input bytes.Buffer
defer input.Reset()
if len(os.Args) == 3 {
input.WriteString(os.Args[2])
} else {
buf, err := ioutil.ReadAll(os.Stdin)
if err != nil {
fmt.Fprintf(os.Stderr, "%v", err)
os.Exit(1)
}
input.Write(buf)
}
security.GosaEncryptBuffer(&input, os.Args[1])
fmt.Fprintln(os.Stdout, input.String())
}
示例4: gosa_get_log_file_by_date_and_mac
// Handles the message "gosa_get_log_file_by_date_and_mac".
// xmlmsg: the decrypted and parsed message
// Returns:
// unencrypted reply
func gosa_get_log_file_by_date_and_mac(xmlmsg *xml.Hash) *xml.Hash {
macaddress := xmlmsg.Text("mac")
lmac := strings.ToLower(macaddress)
subdir := xmlmsg.Text("date")
log_file := xmlmsg.Text("log_file")
header := "get_log_file_by_date_and_mac"
x := xml.NewHash("xml", "header", header)
x.Add(header)
x.Add("source", config.ServerSourceAddress)
x.Add("target", "GOSA")
x.Add("session_id", "1")
if !macAddressRegexp.MatchString(macaddress) {
emsg := fmt.Sprintf("Illegal or missing <mac> element in message: %v", xmlmsg)
util.Log(0, "ERROR! %v", emsg)
return ErrorReplyXML(emsg)
}
// As a precaution, make sure subdir and log_file contain no slashes.
subdir = strings.Replace(subdir, "/", "_", -1)
log_file = strings.Replace(log_file, "/", "_", -1)
if subdir == "" {
// When you open the installation logs in GOsa for the first time, GOsa sends
// a broken request that is characterized by an empty <date> and log_file==0.
// If we return an error, GOsa presents it to the user which
// gives a bad experience. So we instead return an empty reply in this special case.
if log_file == "0" {
return x
}
emsg := fmt.Sprintf("Missing or empty <date> element in message: %v", xmlmsg)
util.Log(0, "ERROR! %v", emsg)
return ErrorReplyXML(emsg)
}
if log_file == "" {
emsg := fmt.Sprintf("Missing or empty <log_file> element in message: %v", xmlmsg)
util.Log(0, "ERROR! %v", emsg)
return ErrorReplyXML(emsg)
}
f, err := os.Open(path.Join(config.FAILogPath, lmac, subdir, log_file))
if err != nil {
emsg := fmt.Sprintf("gosa_get_log_file_by_date_and_mac: %v", err)
util.Log(0, "ERROR! %v", emsg)
return ErrorReplyXML(emsg)
}
defer f.Close()
var b bytes.Buffer
defer b.Reset()
buffy := make([]byte, 65536)
for {
n, err := f.Read(buffy)
b.Write(buffy[0:n])
if err == io.EOF {
break
}
if err != nil {
emsg := fmt.Sprintf("gosa_get_log_file_by_date_and_mac: %v", err)
util.Log(0, "ERROR! %v", emsg)
return ErrorReplyXML(emsg)
}
if n == 0 {
util.Log(0, "WARNING! Read returned 0 bytes but no error. Assuming EOF")
break
}
}
idx := (((b.Len() + 2) / 3) << 2) - b.Len()
b.Write0(idx)
data := b.Bytes()
copy(data[idx:], data)
data = util.Base64EncodeInPlace(data, idx)
data_element := x.Add(log_file)
// To reduce memory leak potential, we append in pieces rather than as one large string
end := xml.MaxFragmentLength
for ; end < len(data); end += xml.MaxFragmentLength {
data_element.AppendString(string(data[end-xml.MaxFragmentLength : end]))
}
data_element.AppendString(string(data[end-xml.MaxFragmentLength:]))
return x
}
示例5: LdifToHash
// Converts LDIF data into a Hash. The outermost tag will always be "xml".
// If an error occurs the returned Hash may contain partial data but it
// is never nil.
//
// itemtag: If non-empty, each object in the LDIF will be inside an element
// whose outermosttag is itemtag. If itemtag == "", all objects in the
// LDIF are merged, i.e. all their combined attributes are directly
// inside the surrounding "xml" tag.
// casefold: If true, all attribute names are converted to lowercase.
// If false, they are left exactly as found in the LDIF.
// ldif: A []byte, string, io.Reader or *exec.Cmd that provides the LDIF data.
// Understands all ldapsearch formats with an arbitrary number of "-L" switches.
// elementInfo: If one or more ElementInfo structs are passed, only attributes
// matching one of them will be accepted and the first match in the
// elementInfo list determines how the attribute in the LDIF will be
// converted to an element in the result Hash.
// If casefold==true, matching is done case-insensitive. This requires that
// the LDIFAttributeName fields are all lowercase.
func LdifToHash(itemtag string, casefold bool, ldif interface{}, elementInfo ...*ElementInfo) (xml *Hash, err error) {
x := NewHash("xml")
var xmldata []byte
switch ld := ldif.(type) {
case []byte:
xmldata = ld
case string:
xmldata = []byte(ld)
case io.Reader:
xmldata, err = ioutil.ReadAll(ld)
if err != nil {
return x, err
}
case *exec.Cmd:
var outbuf bytes.Buffer
defer outbuf.Reset()
var errbuf bytes.Buffer
defer errbuf.Reset()
oldout := ld.Stdout
olderr := ld.Stderr
ld.Stdout = &outbuf
ld.Stderr = &errbuf
err := ld.Run()
ld.Stdout = oldout
ld.Stderr = olderr
errstr := errbuf.String()
if errstr != "" {
err = fmt.Errorf(errstr)
}
if err != nil {
return x, err
}
xmldata = outbuf.Bytes()
default:
return x, fmt.Errorf("ldif argument has unsupported type")
}
item := x
var attr *Hash
new_item := true
end := len(xmldata)
b64 := false
var info *ElementInfo = nil
skip := false
i := 0
start := 0
if !match(xmldata, i, "version:") {
goto wait_for_item
}
///////////////////////////////////////////////////////////////////////
skip_line:
///////////////////////////////////////////////////////////////////////
for {
if i == end {
goto end_of_input
}
if xmldata[i] == '\n' {
break
}
i++
}
// Even comments can have line continuations in LDIF, so we need to
// continue skipping if there is a continuation.
i++
if i < end && (xmldata[i] == ' ' || xmldata[i] == '\t') {
goto skip_line
}
///////////////////////////////////////////////////////////////////////
wait_for_item:
///////////////////////////////////////////////////////////////////////
new_item = true
for {
if i == end {
goto end_of_input
}
if ch := xmldata[i]; ch > ' ' {
if match(xmldata, i, "# search result") {
//.........这里部分代码省略.........
示例6: Send_clmsg_save_fai_log
// Executes program and reads from its standard output log files to transfer to
// the target server. See fai-savelog-hook in the manual.
func Send_clmsg_save_fai_log(target string, program string) {
var buffy bytes.Buffer
defer buffy.Reset()
clientpackageskey := config.ModuleKey["[ClientPackages]"]
// If [ClientPackages]/key missing, take the last key in the list
// (We don't take the 1st because that would be "dummy-key").
if clientpackageskey == "" {
clientpackageskey = config.ModuleKeys[len(config.ModuleKeys)-1]
}
util.Log(1, "INFO! Launching fai-savelog-hook %v", program)
start := time.Now()
env := config.HookEnvironment()
cmd := exec.Command(program)
cmd.Env = append(env, os.Environ()...)
out, err := cmd.StdoutPipe()
if err != nil {
util.Log(0, "ERROR! Could not get stdout pipe for %v: %v", program, err)
return
}
defer out.Close()
in, err := cmd.StdinPipe()
if err != nil {
util.Log(0, "ERROR! Could not get stdin pipe for %v: %v", program, err)
return
}
defer in.Close()
err = cmd.Start()
if err != nil {
util.Log(0, "ERROR! Could not launch %v: %v", program, err)
return
}
buffy.WriteString("<xml><header>CLMSG_save_fai_log</header><source>")
buffy.WriteString(config.ServerSourceAddress)
buffy.WriteString("</source>")
buffy.WriteString("<target>")
buffy.WriteString(target)
buffy.WriteString("</target>")
buffy.WriteString("<macaddress>")
buffy.WriteString(config.MAC)
buffy.WriteString("</macaddress>")
buffy.WriteString("<CLMSG_save_fai_log>")
reader := bufio.NewReader(out)
fai_action := ""
for {
line, err := reader.ReadString('\n')
if err != nil {
util.Log(0, "ERROR! Error reading stdout from %v: %v", program, err)
return
}
line = strings.TrimSpace(line)
if line == "install" || line == "softupdate" {
fai_action = line
break
}
buffy.WriteString(line)
}
util.Log(1, "INFO! Received %v bytes in %v from fai-savelog-hook", buffy.Len(), time.Since(start))
buffy.WriteString("</CLMSG_save_fai_log>")
buffy.WriteString("<fai_action>")
buffy.WriteString(fai_action)
buffy.WriteString("</fai_action>")
buffy.WriteString("</xml>")
util.Log(1, "INFO! Sending %v bytes of log files to %v", buffy.Len(), target)
security.SendLnTo(target, buffy.String(), clientpackageskey, false)
in.Write([]byte{'\n'}) // notify hook that transfer is complete
}
示例7: testBuffer
func testBuffer() {
var b bytes.Buffer
check(b.String(), "") // String() on fresh variable
b.Reset() // Reset() on fresh variable
check(b.String(), "") // String() after Reset()
b.Reset() // Reset() after Reset()
check(b.String(), "")
check(b.Len(), 0)
// same tests as above with pointer
b2 := &bytes.Buffer{}
check(b2.String(), "")
b2.Reset()
check(b2.String(), "")
b2.Reset()
check(b2.String(), "")
check(b2.Len(), 0)
b2.WriteString("Dies ist ein Test!")
check(b2.String(), "Dies ist ein Test!")
check(b2.Len(), 18)
n, err := b.Write(nil)
check(n, 0)
check(err, nil)
check(b.String(), "")
n, err = b.Write([]byte{})
check(n, 0)
check(err, nil)
check(b.String(), "")
check(b.Pointer(), nil)
check(b.Capacity(), 0)
check(b.Len(), 0)
func() {
defer func() {
check(recover(), bytes.ErrTooLarge)
}()
b.Grow(-1)
}()
n, err = b.Write([]byte{'a'})
check(n, 1)
check(err, nil)
check(b.String(), "a")
check(b.Capacity() >= 1, true)
check(b.Len(), 1)
check(b.Pointer() != nil, true)
check(b.Grow(11), 1)
check(b.Capacity() >= 12, true)
c := b.Capacity()
p := b.Pointer()
check(b.Grow(11), 1) // should not cause actual growth
check(b.Pointer(), p)
check(b.Capacity(), c)
check(b.Len(), 1)
((*[2]byte)(b.Pointer()))[1] = 'z'
check(b.Contains("z"), false)
n, err = b.WriteString("Hallo")
check(n, 5)
check(err, nil)
check(b.String(), "aHallo")
check(b.Pointer(), p)
check(b.Capacity(), c)
check(b.Len(), 6)
b.Reset()
check(b.String(), "")
check(b.Pointer(), nil)
check(b.Capacity(), 0)
check(b.Contains(""), true)
check(b.Contains("a"), false)
b.WriteString("Hallo")
b.WriteByte(' ')
b.Write([]byte{'d', 'i', 'e', 's'})
b.WriteByte(' ')
b.WriteString("ist ")
b.WriteString("ein ")
b.Write([]byte("Test"))
check(b.String(), "Hallo dies ist ein Test")
check(b.Contains("Hallo dies ist ein Test"), true)
check(b.Contains("Test"), true)
check(b.Contains("Hallo"), true)
check(b.Contains("allo"), true)
check(b.Contains(""), true)
check(b.Split(" "), []string{"Hallo", "dies", "ist", "ein", "Test"})
check(b.Split("X"), []string{"Hallo dies ist ein Test"})
check(b.Split("Hallo dies ist ein Test"), []string{"", ""})
check(b.Split("H"), []string{"", "allo dies ist ein Test"})
check(b.Split("Test"), []string{"Hallo dies ist ein ", ""})
check(b.Split("es"), []string{"Hallo di", " ist ein T", "t"})
b.Reset()
b.WriteString(" \n\t Hallo \t\v\n")
check(b.Len(), 15)
//.........这里部分代码省略.........
示例8: getFile
// Returns the data for the given request. request_re and reply are lists of
// equal length. If request matches request_re[i], then reply[i] specifies the
// data to return for the request. If reply[i] == "",
// then this function returns (nil,nil). If reply[i] starts with the
// character '|', the remainder is taken as the path of a hook to execute
// to generate the data. Otherwise reply[i] is taken as the path of the
// file whose contents to return as data.
//
// When executing a hook, an environment variable called "tftp_request"
// is passed containing the request string. If request_re[i] has a capturing
// group named "macaddress", the captured substring will be converted to
// a MAC address by converting to lowercase, removing all characters
// except 0-9a-f, left-padding to
// length 12 with 0s or truncating to length 12 and inserting ":"s. The
// result will be added to
// the hook environment in a variable named "macaddress" and if there
// is an LDAP object for that macaddress, its attributes will be added
// to the environment, too.
// Other named subexpressions in request_re[i] will be exported to the hook
// verbatim in like-named environment variables.
//
// ATTENTION! Do not forget to call Release() on the returned cacheEntry when you're
// done using it.
func getFile(request string, request_re []*regexp.Regexp, reply []string) (cacheEntry, error) {
for i := range request_re {
if subs := request_re[i].FindStringSubmatch(request); subs != nil {
if reply[i] == "" {
return nil, nil
}
if reply[i][0] != '|' { // plain file
subsidx := request_re[i].FindStringSubmatchIndex(request)
fpath := string(request_re[i].ExpandString(nil, reply[i], request, subsidx))
util.Log(1, "INFO! TFTP mapping \"%v\" => \"%v\"", request, fpath)
// We use fpath as cache key instead of request because
// multiple requests may map to the same fpath and we want to avoid
// caching the same file multiple times.
entry := getCacheEntry(fpath, 60*time.Second)
entry.Mutex.Lock()
defer entry.Mutex.Unlock()
if entry.LoadCount == 0 {
file, err := os.Open(fpath)
entry.Err = err
if err == nil {
defer file.Close()
buffy := make([]byte, 65536)
for {
n, err := file.Read(buffy)
entry.Data.Write(buffy[0:n])
if err == io.EOF {
break
}
if err != nil {
entry.Data.Reset()
entry.Err = err
}
if n == 0 {
util.Log(0, "WARNING! Read returned 0 bytes but no error. Assuming EOF")
break
}
}
}
} else {
util.Log(1, "INFO! TFTP: Serving %v from cache", fpath)
}
entry.LoadCount++
return entry, entry.Err
} else { // hook
hook := reply[i][1:] // cut off '|'
// We need a few seconds afterlife to deal with multiple requests in
// short succession by the same loader due to delayed UDP packets.
entry := getCacheEntry(request, 5*time.Second)
entry.Mutex.Lock()
defer entry.Mutex.Unlock()
if entry.LoadCount == 0 {
util.Log(1, "INFO! TFTP: Calling %v to generate %v", hook, request)
env := config.HookEnvironment()
env = append(env, "tftp_request="+request)
for k, varname := range request_re[i].SubexpNames() {
if varname == "" {
continue
}
value := subs[k]
if varname == "macaddress" {
format_mac := func(r rune) rune {
//.........这里部分代码省略.........
示例9: PackageListHook
// Reads the output from the program config.PackageListHookPath (LDIF) and
// uses it to replace packagedb.
// debconf is passed as PackageListDebconf environment var to the hook.
// See manual section on package-list-hook for more info.
func PackageListHook(debconf string) {
start := time.Now()
timestamp := util.MakeTimestamp(start)
cmd := exec.Command(config.PackageListHookPath)
cmd.Env = append(config.HookEnvironment(), os.Environ()...)
fairepos := []string{}
for repo := FAIServers().First("repository"); repo != nil; repo = repo.Next() {
fairepos = append(fairepos, fmt.Sprintf("%v||%v|%v", repo.Text("server"), repo.Text("repopath"), repo.Text("sections")))
}
package_list_params := []string{"PackageListDebconf=" + debconf, "PackageListCacheDir=" + config.PackageCacheDir, "PackageListFAIrepository=" + strings.Join(fairepos, " ")}
cmd.Env = append(cmd.Env, package_list_params...)
util.Log(1, "INFO! Running package-list-hook: %v %v", strings.Join(package_list_params, " "), config.PackageListHookPath)
var outbuf bytes.Buffer
defer outbuf.Reset()
var errbuf bytes.Buffer
defer errbuf.Reset()
cmd.Stdout = &outbuf
cmd.Stderr = &errbuf
err := cmd.Run()
if err != nil {
util.Log(0, "ERROR! package-list-hook %v: %v (%v)", config.PackageListHookPath, err, errbuf.String())
return
} else if errbuf.Len() != 0 {
// if the command prints to stderr but does not return non-0 exit status (which
// would result in err != nil), we just log a WARNING, but use the stdout data
// anyway.
util.Log(0, "WARNING! package-list-hook %v: %v", config.PackageListHookPath, errbuf.String())
}
plist, err := xml.LdifToHash("pkg", true, outbuf.Bytes(), packageListFormat...)
if err != nil {
util.Log(0, "ERROR! package-list-hook %v: %v", config.PackageListHookPath, err)
return
}
if plist.First("pkg") == nil {
util.Log(0, "ERROR! package-list-hook %v returned no data", config.PackageListHookPath)
return
}
util.Log(1, "INFO! Finished package-list-hook. Running time: %v", time.Since(start))
start = time.Now()
plist.Rename("packagedb")
new_mapRepoPath2FAIrelease := map[string]string{}
accepted := 0
total := 0
for pkg := plist.FirstChild(); pkg != nil; pkg = pkg.Next() {
total++
p := pkg.Element()
release := p.First("distribution") // packageListFormat translates "release" => "distribution"
if release == nil {
util.Log(0, "ERROR! package-list-hook %v returned entry without \"Release\": %v", config.PackageListHookPath, p)
pkg.Remove()
continue
}
for repopath := p.First("repository"); repopath != nil; repopath = repopath.Next() {
new_mapRepoPath2FAIrelease[repopath.Text()] = release.Text()
}
pkgname := p.Get("package")
if len(pkgname) == 0 {
if p.First("repository") == nil { // Release/Repository groups without Package are okay, so only log error if there is no Repository
util.Log(0, "ERROR! package-list-hook %v returned entry without \"Package\": %v", config.PackageListHookPath, p)
}
pkg.Remove()
continue
}
if len(pkgname) > 1 {
util.Log(0, "ERROR! package-list-hook %v returned entry with multiple \"Package\" values: %v", config.PackageListHookPath, p)
pkg.Remove()
continue
}
version := p.First("version")
if version == nil {
util.Log(0, "WARNING! package-list-hook %v returned entry for \"%v\" without \"Version\". Assuming \"1.0\"", config.PackageListHookPath, pkgname[0])
p.Add("version", "1.0")
}
section := p.First("section")
if section == nil {
util.Log(0, "WARNING! package-list-hook %v returned entry for \"%v\" without \"Section\". Assuming \"main\"", config.PackageListHookPath, pkgname[0])
p.Add("section", "main")
}
//.........这里部分代码省略.........
示例10: Util_test
//.........这里部分代码省略.........
panicker := func() {
foobar = "bar"
panic("foo")
}
var buffy bytes.Buffer
util.LoggersSuspend()
util.LoggerAdd(&buffy)
defer util.LoggersRestore()
util.WithPanicHandler(panicker)
time.Sleep(200 * time.Millisecond) // make sure log message is written out
check(foobar, "bar")
check(len(buffy.String()) > 10, true)
listener, err := net.Listen("tcp", "127.0.0.1:39390")
if err != nil {
panic(err)
}
go func() {
r, err := listener.Accept()
if err != nil {
panic(err)
}
buf := make([]byte, 1)
r.Read(buf)
time.Sleep(10 * time.Second)
r.Read(buf)
}()
long := make([]byte, 10000000)
longstr := string(long)
buffy.Reset()
t0 := time.Now()
util.SendLnTo("127.0.0.1:39390", longstr, 5*time.Second)
duration := time.Since(t0)
check(duration > 4*time.Second && duration < 6*time.Second, true)
time.Sleep(200 * time.Millisecond) // make sure log message is written out
check(strings.Contains(buffy.String(), "ERROR"), true)
go func() {
conn, err := listener.Accept()
if err != nil {
panic(err)
}
ioutil.ReadAll(conn)
}()
long = make([]byte, 10000000)
longstr = string(long)
buffy.Reset()
t0 = time.Now()
util.SendLnTo("127.0.0.1:39390", longstr, 5*time.Second)
duration = time.Since(t0)
check(duration < 2*time.Second, true)
time.Sleep(200 * time.Millisecond) // make sure log message is written out
check(buffy.String(), "")
// Test that ReadLn() times out properly
go func() {
_, err := net.Dial("tcp", "127.0.0.1:39390")
if err != nil {
panic(err)
}
}()
conn, err := listener.Accept()
示例11: handle_request
// Handles one or more messages received over conn. Each message is a single
// line terminated by \n. The message may be encrypted as by security.GosaEncrypt().
func handle_request(tcpconn *net.TCPConn) {
defer tcpconn.Close()
defer atomic.AddInt32(&ActiveConnections, -1)
// defer util.Log(2, "DEBUG! Connection to %v closed", tcpconn.RemoteAddr())
// util.Log(2, "DEBUG! Connection from %v", tcpconn.RemoteAddr())
var err error
err = tcpconn.SetKeepAlive(true)
if err != nil {
util.Log(0, "ERROR! SetKeepAlive: %v", err)
}
var buf bytes.Buffer
defer buf.Reset()
readbuf := make([]byte, 4096)
var conn net.Conn
conn = tcpconn
n := 1
if config.TLSServerConfig != nil {
// If TLS is required, we need to see a STARTTLS before the timeout.
// If TLS is optional we need to accept idle connections for backwards compatibility
if config.TLSRequired {
conn.SetDeadline(time.Now().Add(config.TimeoutTLS))
}
for i := range starttls {
n, err = conn.Read(readbuf[0:1])
if n == 0 {
if i != 0 { // Do not log an error for a port scan that just opens a connection and closes it immediately
util.Log(0, "ERROR! Read error while looking for STARTTLS from %v: %v", conn.RemoteAddr(), err)
}
return
}
buf.Write(readbuf[0:1])
if readbuf[0] == '\r' && starttls[i] == '\n' {
// Read the \n that must follow \r (we don't support lone CR line endings)
conn.Read(readbuf[0:1]) // ignore error. It will pop up again further down the line.
}
if readbuf[0] != starttls[i] {
if config.TLSRequired {
util.Log(0, "ERROR! No STARTTLS from %v, but TLS is required", conn.RemoteAddr())
util.WriteAll(conn, []byte(message.ErrorReply("STARTTLS is required to connect")))
return
}
break
}
if readbuf[0] == '\n' {
buf.Reset() // purge STARTTLS\n from buffer
conn = tls.Server(conn, config.TLSServerConfig)
}
}
}
context := security.ContextFor(conn)
if context == nil {
return
}
for n != 0 {
//util.Log(2, "DEBUG! Receiving from %v", conn.RemoteAddr())
n, err = conn.Read(readbuf)
if err != nil && err != io.EOF {
util.Log(0, "ERROR! Read: %v", err)
}
if err == io.EOF {
util.Log(2, "DEBUG! Connection closed by %v", conn.RemoteAddr())
}
if n == 0 && err == nil {
util.Log(0, "ERROR! Read 0 bytes but no error reported")
}
// Find complete lines terminated by '\n' and process them.
for start := 0; ; {
eol := start
for ; eol < n; eol++ {
if readbuf[eol] == '\n' {
break
}
}
// no \n found, append to buf and continue reading
if eol == n {
buf.Write(readbuf[start:n])
break
}
// append to rest of line to buffered contents
buf.Write(readbuf[start:eol])
start = eol + 1
buf.TrimSpace()
// process the message and get a reply (if applicable)
//.........这里部分代码省略.........