예제 #1
0
func (cah *connectionAwaitHandshake) readAndDecryptOne() (*capn.Segment, error) {
	if cah.sessionKey == nil {
		return capn.ReadFromStream(cah.socket, nil)
	}
	read, err := cah.socket.Read(cah.inBuff)
	if err != nil {
		return nil, err
	} else if read < len(cah.inBuff) {
		return nil, fmt.Errorf("Only read %v bytes, wanted %v", read, len(cah.inBuff))
	}
	copy(cah.nonceAryIn[16:], cah.inBuff[:8])
	msgLen := binary.BigEndian.Uint64(cah.inBuff[8:16])
	plainLen := msgLen - secretbox.Overhead
	msgBuf := make([]byte, plainLen+msgLen)
	for recvBuf := msgBuf[plainLen:]; len(recvBuf) != 0; {
		read, err = cah.socket.Read(recvBuf)
		if err != nil {
			return nil, err
		} else {
			recvBuf = recvBuf[read:]
		}
	}
	plaintext, ok := secretbox.Open(msgBuf[:0], msgBuf[plainLen:], cah.nonceAryIn, cah.sessionKey)
	if !ok {
		return nil, fmt.Errorf("Unable to decrypt message")
	}
	seg, _, err := capn.ReadFromMemoryZeroCopy(plaintext)
	return seg, err
}
예제 #2
0
/** A function designed to handle BTrDB's response over Cap'n Proto.
You shouldn't ever have to invoke this function. It is used internally by
the constructor function. */
func (dr *DataRequester) handleResponses(connection net.Conn) {
	for dr.alive {
		// Only one goroutine will be reading at a time, so a lock isn't needed
		responseSegment, respErr := capnp.ReadFromStream(connection, nil)

		if respErr != nil {
			if !dr.alive {
				break
			}
			fmt.Printf("Error in receiving response to data or bracket request: %v\n", respErr)
			os.Exit(1)
		}

		responseSeg := cpint.ReadRootResponse(responseSegment)
		id := responseSeg.EchoTag()

		fmt.Printf("Got response to request %v\n", id)

		dr.stateLock.RLock()
		respchan := dr.synchronizers[id]
		dr.stateLock.RUnlock()

		if respchan == nil {
			fmt.Printf("Dropping extraneous response for request %v\n", id)
		} else {
			respchan <- responseSeg
		}
	}
}
예제 #3
0
func (q *quasarDB) receiveStats(conn *tsConn) (common.StatisticalNumbersResponse, error) {
	var sr = common.StatisticalNumbersResponse{}
	seg, err := capn.ReadFromStream(conn, nil)
	if err != nil {
		conn.Close()
		log.Errorf("Error receiving data from Quasar %v", err)
		return sr, err
	}
	resp := qsr.ReadRootResponse(seg)

	//log.Debug("qsr resp %v", resp.Which())
	//log.Debug("status code %v", resp.StatusCode())
	switch resp.Which() {
	case qsr.RESPONSE_VOID:
		if resp.StatusCode() != qsr.STATUSCODE_OK {
			return sr, fmt.Errorf("Received error status code when writing: %v", resp.StatusCode())
		}
	case qsr.RESPONSE_RECORDS:
		if resp.StatusCode() != 0 {
			return sr, fmt.Errorf("Error when reading from Quasar: %v", resp.StatusCode().String())
		}
		sr.Readings = []*common.StatisticalNumberReading{}
		for _, rec := range resp.StatisticalRecords().Values().ToArray() {
			sr.Readings = append(sr.Readings, &common.StatisticalNumberReading{
				Time: uint64(rec.Time()), Count: rec.Count(),
				Min: rec.Min(), Mean: rec.Mean(), Max: rec.Max(),
				UoT: common.UOT_NS})
		}
		return sr, nil
	default:
		return sr, fmt.Errorf("Got unexpected Quasar Error code (%v)", resp.StatusCode().String())
	}
	return sr, nil

}
예제 #4
0
func (cah *connectionAwaitHandshake) start() (bool, error) {
	helloSeg, err := cah.makeHello()
	if err != nil {
		return false, err
	}
	buf := new(bytes.Buffer)
	if _, err := helloSeg.WriteTo(buf); err != nil {
		return false, err
	}
	if err := cah.send(buf.Bytes()); err != nil {
		return false, err
	}

	if seg, err := capn.ReadFromStream(cah.socket, nil); err == nil {
		if hello := msgs.ReadRootHello(seg); cah.verifyHello(&hello) {
			sessionKey := [32]byte{}
			remotePublicKey := [32]byte{}
			copy(remotePublicKey[:], hello.PublicKey())
			box.Precompute(&sessionKey, &remotePublicKey, cah.privateKey)
			cah.sessionKey = &sessionKey
			cah.nonceAryOut[0] = 128
			cah.nonce = 0
			cah.nextState()
		} else {
			return false, fmt.Errorf("Received erroneous hello from server")
		}
	} else {
		return false, err
	}

	return false, nil
}
예제 #5
0
func (s *Iterator) Load(r io.Reader) {
	capMsg, err := capn.ReadFromStream(r, nil)
	if err != nil {
		panic(fmt.Errorf("capn.ReadFromStream error: %s", err))
	}
	z := ReadRootIteratorCapn(capMsg)
	IteratorCapnToGo(z, s)
}
예제 #6
0
func (s *MmapMalloc) Load(r io.Reader) {
	capMsg, err := capn.ReadFromStream(r, nil)
	if err != nil {
		panic(fmt.Errorf("capn.ReadFromStream error: %s", err))
	}
	z := ReadRootMmapMallocCapn(capMsg)
	MmapMallocCapnToGo(z, s)
}
예제 #7
0
func (s *HashTable) Load(r io.Reader) {
	capMsg, err := capn.ReadFromStream(r, nil)
	if err != nil {
		panic(fmt.Errorf("capn.ReadFromStream error: %s", err))
	}
	z := ReadRootHashTableCapn(capMsg)
	HashTableCapnToGo(z, s)
}
예제 #8
0
func (s *AcctId) Load(r io.Reader) {
	capMsg, err := capn.ReadFromStream(r, nil)
	if err != nil {
		panic(fmt.Errorf("capn.ReadFromStream error: %s", err))
	}
	z := ReadRootAcctIdCapn(capMsg)
	AcctIdCapnToGo(z, s)
}
예제 #9
0
func (s *RWTest) Load(r io.Reader) {
	capMsg, err := capn.ReadFromStream(r, nil)
	if err != nil {
		panic(fmt.Errorf("capn.ReadFromStream error: %s", err))
	}
	z := air.ReadRootRWTestCapn(capMsg)
	RWTestCapnToGo(z, s)
}
예제 #10
0
func read(buf bytes.Buffer) error {
	seg, err := C.ReadFromStream(&buf, nil)
	if err != nil {
		log.Print("While decoding")
		return err
	}

	pl := plist.ReadRootPostingList(seg)
	ids := pl.Ids()
	title := pl.Title()
	fmt.Printf("Num ids: [%v] Title: [%v]\n", ids.Len(), title)
	return nil
}
예제 #11
0
func (cah *connectionAwaitHandshake) start() (bool, error) {
	helloSeg, err := cah.makeHello()
	if err != nil {
		return cah.maybeRestartConnection(err)
	}
	if err := cah.send(server.SegToBytes(helloSeg)); err != nil {
		return cah.maybeRestartConnection(err)
	}
	cah.nonce = 0

	if seg, err := capn.ReadFromStream(cah.socket, nil); err == nil {
		hello := msgs.ReadRootHello(seg)
		if cah.verifyHello(&hello) {
			sessionKey := [32]byte{}
			remotePublicKey := [32]byte{}
			copy(remotePublicKey[:], hello.PublicKey())
			box.Precompute(&sessionKey, &remotePublicKey, cah.privateKey)

			if hello.IsClient() {
				cah.Lock()
				cah.isClient = true
				cah.sessionKey = &sessionKey
				cah.Unlock()
				cah.nonceAryIn[0] = 128
				cah.nextState(&cah.connectionAwaitClientHandshake)

			} else {
				extendedKey := make([]byte, 64)
				copy(extendedKey[:32], sessionKey[:])
				copy(extendedKey[32:], cah.connectionManager.passwordHash[:])
				sessionKey = sha256.Sum256(extendedKey)
				cah.Lock()
				cah.isServer = true
				cah.sessionKey = &sessionKey
				cah.Unlock()
				if cah.remoteHost == "" {
					cah.nonceAryIn[0] = 128
				} else {
					cah.nonceAryOut[0] = 128
				}
				cah.nextState(&cah.connectionAwaitServerHandshake)
			}
			return false, nil
		} else {
			return cah.maybeRestartConnection(fmt.Errorf("Received erroneous hello from peer"))
		}
	} else {
		return cah.maybeRestartConnection(err)
	}
}
예제 #12
0
func ExampleReadFromStream() {
	s := capn.NewBuffer(nil)
	d := air.NewRootZdate(s)
	d.SetYear(2004)
	d.SetMonth(12)
	d.SetDay(7)
	buf := bytes.Buffer{}
	s.WriteTo(&buf)

	fmt.Println(hex.EncodeToString(buf.Bytes()))

	// Read
	s, err := capn.ReadFromStream(&buf, nil)
	if err != nil {
		fmt.Printf("read error %v\n", err)
		return
	}
	d = air.ReadRootZdate(s)
	fmt.Printf("year %d, month %d, day %d\n", d.Year(), d.Month(), d.Day())
}
예제 #13
0
파일: gozbus.go 프로젝트: robmurtha/gozbus
func recvZDate(nnzbus *nn.Socket) {

	// Read a Z message that is expected to be a Zdate from nnzbus
	myMsg, err := nnzbus.Recv(0)
	if err != nil {
		log.Fatal(err)
	}

	buf := bytes.NewBuffer(myMsg)
	capMsg, err := capn.ReadFromStream(buf, nil)
	if err != nil {
		log.Fatal(err)
	}

	z := gozbus.ReadRootZ(capMsg)
	mydate := z.Zdate()

	fmt.Printf("[pid %d] recvZDate got ZDate message: year %d, month %d, day %d\n",
		os.Getpid(), mydate.Year(), mydate.Month(), mydate.Day())
}
예제 #14
0
func TestReadFromStreamBackToBack(t *testing.T) {
	const n = 10

	r := zdateReaderNBackToBack(n, false)

	for i := 0; i < n; i++ {
		s, err := capn.ReadFromStream(r, nil)
		if err != nil {
			t.Fatalf("ReadFromStream: %v", err)
		}
		m := air.ReadRootZdate(s)
		if capn.JSON_enabled {
			js, err := m.MarshalJSON()
			if err != nil {
				t.Fatalf("MarshalJSON: %v", err)
			}
			t.Logf("%s", string(js))
		}
	}

}
예제 #15
0
func TestReadFromStream(t *testing.T) {
	const n = 10
	r := zdateReader(n, false)
	s, err := capn.ReadFromStream(r, nil)
	if err != nil {
		t.Fatalf("ReadFromStream: %v", err)
	}
	z := air.ReadRootZ(s)
	if z.Which() != air.Z_ZDATEVEC {
		panic("expected Z_ZDATEVEC in root Z of segment")
	}
	zdatelist := z.Zdatevec()

	if capn.JSON_enabled {
		for i := 0; i < n; i++ {
			zdate := zdatelist.At(i)
			js, err := zdate.MarshalJSON()
			if err != nil {
				t.Fatalf("MarshalJSON: %v", err)
			}
			t.Logf("%s", string(js))
		}
	}
}
예제 #16
0
파일: capnpc-go.go 프로젝트: tpukep/caps
func main() {
	s, err := C.ReadFromStream(os.Stdin, nil)
	assert(err == nil, "%v\n", err)

	req := ReadRootCodeGeneratorRequest(s)
	allfiles := []*node{}

	for _, ni := range req.Nodes().ToArray() {
		n := &node{Node: ni}
		g_nodes[n.Id()] = n

		if n.Which() == NODE_FILE {
			allfiles = append(allfiles, n)
		}
	}

	for _, f := range allfiles {
		for _, a := range f.Annotations().ToArray() {
			if v := a.Value(); v.Which() == VALUE_TEXT {
				switch a.Id() {
				case C.Package:
					f.pkg = v.Text()
				case C.Import:
					f.imp = v.Text()
				}
			}
		}

		for _, nn := range f.NestedNodes().ToArray() {
			if ni := g_nodes[nn.Id()]; ni != nil {
				ni.resolveName("", nn.Name(), f)
			}
		}
	}

	for _, reqf := range req.RequestedFiles().ToArray() {
		f := findNode(reqf.Id())
		buf := bytes.Buffer{}
		g_imported = make(map[string]bool)
		g_segment = C.NewBuffer([]byte{})
		g_bufname = sprintf("x_%x", f.Id())

		for _, n := range f.nodes {
			if n.Which() == NODE_ANNOTATION {
				n.defineAnnotation(&buf)
			}
		}

		defineConstNodes(&buf, f.nodes)

		for _, n := range f.nodes {
			switch n.Which() {
			case NODE_ANNOTATION:
			case NODE_ENUM:
				n.defineEnum(&buf)
				n.defineTypeJsonFuncs(&buf)
				n.defineTypeCaplitFuncs(&buf)
			case NODE_STRUCT:
				if !n.Struct().IsGroup() {
					n.defineStructTypes(&buf, nil)
					n.defineStructEnums(&buf)
					n.defineNewStructFunc(&buf)
					n.defineStructFuncs(&buf)
					n.defineTypeJsonFuncs(&buf)
					n.defineTypeCaplitFuncs(&buf)
					n.defineStructList(&buf)
				}
			}
		}

		assert(f.pkg != "", "missing package annotation for %s", reqf.Filename())

		if dirPath, _ := filepath.Split(reqf.Filename()); dirPath != "" {
			err := os.MkdirAll(dirPath, os.ModePerm)
			assert(err == nil, "%v\n", err)
		}

		file, err := os.Create(reqf.Filename() + ".go")
		assert(err == nil, "%v\n", err)
		fprintf(file, "package %s\n\n", f.pkg)
		fprintf(file, "// AUTO GENERATED - DO NOT EDIT\n\n")

		fprintf(file, "import (\n")
		fprintf(file, "C \"%s\"\n", go_capnproto_import)
		for imp := range g_imported {
			fprintf(file, "%s\n", strconv.Quote(imp))
		}
		fprintf(file, ")\n")

		file.Write(buf.Bytes())

		if len(g_segment.Data) > 0 {
			fprintf(file, "var %s = C.NewBuffer([]byte{", g_bufname)
			for i, b := range g_segment.Data {
				if i%8 == 0 {
					fprintf(file, "\n")
				}
				fprintf(file, "%d,", b)
			}
			fprintf(file, "\n})\n")
		}
		file.Close()

		cmd := exec.Command("gofmt", "-w", reqf.Filename()+".go")
		cmd.Stderr = os.Stderr
		err = cmd.Run()
		assert(err == nil, "%v\n", err)
	}
}
예제 #17
0
// Boy Golly, sure would be nice to put this in router.go, huh?
// well, thanks to go being picky about circular references, you can't.
func (self *Handler) RouteHandler(resp http.ResponseWriter, req *http.Request) {
	var err error
	logWarning := self.logger.ShouldLog(WARNING)
	// get the uaid from the url
	uaid, ok := mux.Vars(req)["uaid"]
	if req.Method != "PUT" {
		http.Error(resp, "", http.StatusMethodNotAllowed)
		self.metrics.Increment("updates.routed.invalid")
		return
	}
	// if uid is not present, or doesn't exist in the known clients...
	if !ok || !self.app.ClientExists(uaid) {
		http.Error(resp, "UID Not Found", http.StatusNotFound)
		self.metrics.Increment("updates.routed.unknown")
		return
	}
	// We know of this one.
	var (
		r        Routable
		chid     string
		timeNano int64
		sentAt   time.Time
	)
	segment, err := capn.ReadFromStream(req.Body, nil)
	if err != nil {
		if logWarning {
			self.logger.Warn("router", "Could not read update body",
				LogFields{"rid": req.Header.Get(HeaderID), "error": err.Error()})
		}
		goto invalidBody
	}
	r = ReadRootRoutable(segment)
	chid = r.ChannelID()
	if len(chid) == 0 {
		if logWarning {
			self.logger.Warn("router", "Missing channel ID",
				LogFields{"rid": req.Header.Get(HeaderID), "uaid": uaid})
		}
		goto invalidBody
	}
	// routed data is already in storage.
	self.metrics.Increment("updates.routed.incoming")
	timeNano = r.Time()
	sentAt = time.Unix(timeNano/1e9, timeNano%1e9)
	if err = self.app.Server().Update(chid, uaid, r.Version(), sentAt); err != nil {
		if logWarning {
			self.logger.Warn("router", "Could not update local user",
				LogFields{"rid": req.Header.Get(HeaderID), "error": err.Error()})
		}
		http.Error(resp, "Server Error", http.StatusInternalServerError)
		self.metrics.Increment("updates.routed.error")
		return
	}
	resp.Write([]byte("Ok"))
	self.metrics.Increment("updates.routed.received")
	return

invalidBody:
	http.Error(resp, "Invalid body", http.StatusNotAcceptable)
	self.metrics.Increment("updates.routed.invalid")
}
예제 #18
0
파일: capnpc-pgo.go 프로젝트: tpukep/caps
func main() {
	s, err := C.ReadFromStream(os.Stdin, nil)
	assert(err == nil, "%v\n", err)

	req := caps.ReadRootCodeGeneratorRequest(s)
	allfiles := []*node{}

	for _, ni := range req.Nodes().ToArray() {
		n := &node{Node: ni, codecs: make(map[uint64]bool)}
		g_nodes[n.Id()] = n

		if n.Which() == caps.NODE_FILE {
			allfiles = append(allfiles, n)
		}
	}

	g_imported = make(map[string]bool)

	for _, f := range allfiles {
		for _, a := range f.Annotations().ToArray() {
			if v := a.Value(); v.Which() == caps.VALUE_TEXT {
				switch a.Id() {
				case C.Package:
					f.pkg = v.Text()
				case C.Import:
					f.imp = v.Text()
				}
			} else {
				switch a.Id() {
				case caps.CodecCapnp:
					enableCodec(f, caps.CodecCapnp)
					g_imported["io"] = true
					g_imported[GO_CAPNP_IMPORT] = true
				case caps.CodecJson:
					enableCodec(f, caps.CodecJson)
				case caps.CodecMsgp:
					enableCodec(f, caps.CodecMsgp)
				}
			}
		}

		for _, nn := range f.NestedNodes().ToArray() {
			if ni := g_nodes[nn.Id()]; ni != nil {
				ni.resolveName("", nn.Name(), f)
			}
		}
	}

	for _, reqf := range req.RequestedFiles().ToArray() {
		x := bam.NewExtractor()
		x.FieldPrefix = "   "
		x.FieldSuffix = "\n"

		f := findNode(reqf.Id())
		buf := bytes.Buffer{}
		g_segment = C.NewBuffer([]byte{})

		defineConstNodes(&buf, f.nodes)

		for _, n := range f.nodes {
			switch n.Which() {
			case caps.NODE_ANNOTATION:
				n.defineAnnotation(&buf)
			case caps.NODE_ENUM:
				n.defineEnum(&buf, x)
			case caps.NODE_STRUCT:
				if !n.Struct().IsGroup() {
					n.defineStructTypes(&buf, nil, x)
					// n.defineStructEnums(&buf)
				}
			}
		}

		// Write translation functions
		if _, found := f.codecs[caps.CodecCapnp]; found {
			_, err = x.WriteToTranslators(&buf)
			assert(err == nil, "%v\n", err)
		}

		assert(f.pkg != "", "missing package annotation for %s", reqf.Filename())
		x.PkgName = f.pkg

		if dirPath, _ := filepath.Split(reqf.Filename()); dirPath != "" {
			err := os.MkdirAll(dirPath, os.ModePerm)
			assert(err == nil, "%v\n", err)
			x.OutDir = dirPath
		}

		// Create output file
		filename := strings.TrimSuffix(reqf.Filename(), ".capnp")

		file, err := os.Create(filename + ".go")
		assert(err == nil, "%v\n", err)

		// Write package
		fmt.Fprintf(file, "package %s\n\n", f.pkg)
		fmt.Fprintf(file, "// AUTO GENERATED - DO NOT EDIT\n\n")

		// Write imports
		f.writeImports(file)

		// Format sources
		clean, err := format.Source(buf.Bytes())
		assert(err == nil, "%v\n", err)
		file.Write(clean)

		defer file.Close()
	}
}
예제 #19
0
func (c *CPInterface) dispatchCommands(q *btrdb.Quasar, conn net.Conn) {
	//This governs the stream
	rmtx := sync.Mutex{}
	wmtx := sync.Mutex{}
	log.Info("cpnp connection")
	for !c.isShuttingDown {
		rmtx.Lock()
		seg, err := capn.ReadFromStream(conn, nil)
		if err != nil {
			log.Warning("ERR (%v) :: %v", conn.RemoteAddr(), err)
			conn.Close()
			break
		}
		rmtx.Unlock()
		go func() {
			seg := seg
			req := ReadRootRequest(seg)
			mkresp := func() (Response, *capn.Segment) {
				rvseg := capn.NewBuffer(nil)
				resp := NewRootResponse(rvseg)
				resp.SetEchoTag(req.EchoTag())
				return resp, rvseg
			}
			sendresp := func(seg *capn.Segment) {
				wmtx.Lock()
				seg.WriteTo(conn)
				wmtx.Unlock()
			}
			switch req.Which() {
			case REQUEST_QUERYSTANDARDVALUES:
				//log.Info("QSV\n")
				st := req.QueryStandardValues().StartTime()
				et := req.QueryStandardValues().EndTime()
				uuid := uuid.UUID(req.QueryStandardValues().Uuid())
				ver := req.QueryStandardValues().Version()
				//log.Info("[REQ=QsV] st=%v, et=%v, uuid=%v, gen=%v", st, et, uuid, ver)
				if ver == 0 {
					ver = btrdb.LatestGeneration
				}
				recordc, errorc, gen := q.QueryValuesStream(uuid, st, et, ver)
				if recordc == nil {
					log.Warning("RESPONDING ERR: %v", err)
					resp, rvseg := mkresp()
					resp.SetStatusCode(STATUSCODE_INTERNALERROR)
					resp.SetFinal(true)
					sendresp(rvseg)
					return
				} else {
					bufarr := make([]qtree.Record, 0, 4096)
					for {
						resp, rvseg := mkresp()
						fail := false
						fin := false
						for {
							select {
							case _, ok := <-errorc:
								if ok {
									fin = true
									fail = true
									goto donestandard
								}
							case r, ok := <-recordc:
								if !ok {
									fin = true
									goto donestandard
								}
								bufarr = append(bufarr, r)
								if len(bufarr) == cap(bufarr) {
									goto donestandard
								}
							}
						}
					donestandard:
						if fail {
							resp.SetStatusCode(STATUSCODE_INTERNALERROR)
							resp.SetFinal(true)
							//consume channels
							go func() {
								for _ = range recordc {
								}
							}()
							go func() {
								for _ = range errorc {
								}
							}()
							sendresp(rvseg)
							return
						}
						records := NewRecords(rvseg)
						rl := NewRecordList(rvseg, len(bufarr))
						rla := rl.ToArray()
						for i, v := range bufarr {
							rla[i].SetTime(v.Time)
							rla[i].SetValue(v.Val)
						}
						records.SetVersion(gen)
						records.SetValues(rl)
						resp.SetRecords(records)
						resp.SetStatusCode(STATUSCODE_OK)
						if fin {
							resp.SetFinal(true)
						}
						sendresp(rvseg)
						bufarr = bufarr[:0]
						if fin {
							return
						}
					}
				}
			case REQUEST_QUERYSTATISTICALVALUES:
				st := req.QueryStatisticalValues().StartTime()
				et := req.QueryStatisticalValues().EndTime()
				uuid := uuid.UUID(req.QueryStatisticalValues().Uuid())
				pw := req.QueryStatisticalValues().PointWidth()
				ver := req.QueryStatisticalValues().Version()
				if ver == 0 {
					ver = btrdb.LatestGeneration
				}
				recordc, errorc, gen := q.QueryStatisticalValuesStream(uuid, st, et, ver, pw)
				if recordc == nil {
					log.Warning("RESPONDING ERR: %v", err)
					resp, rvseg := mkresp()
					resp.SetStatusCode(STATUSCODE_INTERNALERROR)
					resp.SetFinal(true)
					sendresp(rvseg)
					return
				} else {
					bufarr := make([]qtree.StatRecord, 0, 4096)
					for {
						resp, rvseg := mkresp()
						fail := false
						fin := false
						for {
							select {
							case _, ok := <-errorc:
								if ok {
									fin = true
									fail = true
									goto donestat
								}
							case r, ok := <-recordc:
								if !ok {
									fin = true
									goto donestat
								}
								bufarr = append(bufarr, r)
								if len(bufarr) == cap(bufarr) {
									goto donestat
								}
							}
						}
					donestat:
						if fail {
							resp.SetStatusCode(STATUSCODE_INTERNALERROR)
							resp.SetFinal(true)
							//consume channels
							go func() {
								for _ = range recordc {
								}
							}()
							go func() {
								for _ = range errorc {
								}
							}()
							sendresp(rvseg)
							return
						}
						records := NewStatisticalRecords(rvseg)
						rl := NewStatisticalRecordList(rvseg, len(bufarr))
						rla := rl.ToArray()
						for i, v := range bufarr {
							rla[i].SetTime(v.Time)
							rla[i].SetCount(v.Count)
							rla[i].SetMin(v.Min)
							rla[i].SetMean(v.Mean)
							rla[i].SetMax(v.Max)
						}
						records.SetVersion(gen)
						records.SetValues(rl)
						resp.SetStatisticalRecords(records)
						resp.SetStatusCode(STATUSCODE_OK)
						if fin {
							resp.SetFinal(true)
						}
						sendresp(rvseg)
						bufarr = bufarr[:0]
						if fin {
							return
						}
					}
				}
			case REQUEST_QUERYVERSION:
				//ul := req.
				ul := req.QueryVersion().Uuids()
				ull := ul.ToArray()
				resp, rvseg := mkresp()
				rvers := NewVersions(rvseg)
				vlist := rvseg.NewUInt64List(len(ull))
				ulist := rvseg.NewDataList(len(ull))
				for i, v := range ull {
					ver, err := q.QueryGeneration(uuid.UUID(v))
					if err != nil {
						resp.SetStatusCode(STATUSCODE_INTERNALERROR)
						resp.SetFinal(true)
						sendresp(rvseg)
						return
					}
					//I'm not sure that the array that sits behind the uuid slice will stick around
					//so I'm copying it.
					uuid := make([]byte, 16)
					copy(uuid, v)
					vlist.Set(i, ver)
					ulist.Set(i, uuid)
				}
				resp.SetStatusCode(STATUSCODE_OK)
				rvers.SetUuids(ulist)
				rvers.SetVersions(vlist)
				resp.SetVersionList(rvers)
				resp.SetFinal(true)
				sendresp(rvseg)
			case REQUEST_QUERYNEARESTVALUE:
				resp, rvseg := mkresp()
				t := req.QueryNearestValue().Time()
				id := uuid.UUID(req.QueryNearestValue().Uuid())
				ver := req.QueryNearestValue().Version()
				if ver == 0 {
					ver = btrdb.LatestGeneration
				}
				back := req.QueryNearestValue().Backward()
				rv, gen, err := q.QueryNearestValue(id, t, back, ver)
				switch err {
				case nil:
					resp.SetStatusCode(STATUSCODE_OK)
					records := NewRecords(rvseg)
					rl := NewRecordList(rvseg, 1)
					rla := rl.ToArray()
					rla[0].SetTime(rv.Time)
					rla[0].SetValue(rv.Val)
					records.SetVersion(gen)
					records.SetValues(rl)
					resp.SetRecords(records)
				case qtree.ErrNoSuchPoint:
					resp.SetStatusCode(STATUSCODE_NOSUCHPOINT)
				default:
					resp.SetStatusCode(STATUSCODE_INTERNALERROR)
				}
				resp.SetFinal(true)
				sendresp(rvseg)
			case REQUEST_QUERYCHANGEDRANGES:
				resp, rvseg := mkresp()
				id := uuid.UUID(req.QueryChangedRanges().Uuid())
				sgen := req.QueryChangedRanges().FromGeneration()
				egen := req.QueryChangedRanges().ToGeneration()
				if egen == 0 {
					egen = btrdb.LatestGeneration
				}
				resolution := req.QueryChangedRanges().Resolution()
				rv, ver, err := q.QueryChangedRanges(id, sgen, egen, resolution)
				switch err {
				case nil:
					resp.SetStatusCode(STATUSCODE_OK)
					ranges := NewRanges(rvseg)
					ranges.SetVersion(ver)
					crl := NewChangedRangeList(rvseg, len(rv))
					crla := crl.ToArray()
					for i := 0; i < len(rv); i++ {
						crla[i].SetStartTime(rv[i].Start)
						crla[i].SetEndTime(rv[i].End)
					}
					ranges.SetValues(crl)
					resp.SetChangedRngList(ranges)
				default:
					log.Critical("qcr error: ", err)
					resp.SetStatusCode(STATUSCODE_INTERNALERROR)
				}
				resp.SetFinal(true)
				sendresp(rvseg)

			case REQUEST_INSERTVALUES:
				resp, rvseg := mkresp()
				uuid := uuid.UUID(req.InsertValues().Uuid())
				rl := req.InsertValues().Values()
				rla := rl.ToArray()
				if len(rla) != 0 {
					qtr := make([]qtree.Record, len(rla))
					for i, v := range rla {
						qtr[i] = qtree.Record{Time: v.Time(), Val: v.Value()}
					}
					q.InsertValues(uuid, qtr)
				}
				if req.InsertValues().Sync() {
					q.Flush(uuid)
				}
				resp.SetFinal(true)
				resp.SetStatusCode(STATUSCODE_OK)
				sendresp(rvseg)
			case REQUEST_DELETEVALUES:
				resp, rvseg := mkresp()
				id := uuid.UUID(req.DeleteValues().Uuid())
				stime := req.DeleteValues().StartTime()
				etime := req.DeleteValues().EndTime()
				err := q.DeleteRange(id, stime, etime)
				switch err {
				case nil:
					resp.SetStatusCode(STATUSCODE_OK)
				default:
					resp.SetStatusCode(STATUSCODE_INTERNALERROR)
				}
				resp.SetFinal(true)
				sendresp(rvseg)
			default:
				log.Critical("weird segment")
			}
		}()
	}
}
예제 #20
0
func (cah *connectionAwaitHandshake) readOne() (*capn.Segment, error) {
	return capn.ReadFromStream(cah.socket, nil)
}
예제 #21
0
func (r *BroadcastRouter) RouteHandler(resp http.ResponseWriter, req *http.Request) {
	var err error
	logWarning := r.logger.ShouldLog(WARNING)
	// get the uaid from the url
	uaid, ok := mux.Vars(req)["uaid"]
	if req.Method != "PUT" {
		http.Error(resp, "", http.StatusMethodNotAllowed)
		r.metrics.Increment("updates.routed.invalid")
		return
	}
	// if uid is not present, or doesn't exist in the known clients...
	if !ok {
		http.Error(resp, "UID Not Found", http.StatusNotFound)
		r.metrics.Increment("updates.routed.unknown")
		return
	}

	worker, found := r.app.GetWorker(uaid)
	if !found {
		http.Error(resp, "UID Not Found", http.StatusNotFound)
		r.metrics.Increment("updates.routed.unknown")
		return
	}

	// We know of this one.
	var (
		routable   Routable
		chid, data string
	)
	segment, err := capn.ReadFromStream(req.Body, nil)
	if err != nil {
		if logWarning {
			r.logger.Warn("router", "Could not read update body",
				LogFields{"rid": req.Header.Get(HeaderID), "error": err.Error()})
		}
		goto invalidBody
	}
	routable = ReadRootRoutable(segment)
	chid = routable.ChannelID()
	if len(chid) == 0 {
		if logWarning {
			r.logger.Warn("router", "Missing channel ID",
				LogFields{"rid": req.Header.Get(HeaderID), "uaid": uaid})
		}
		goto invalidBody
	}
	r.metrics.Increment("updates.routed.incoming")
	// Never trust external data
	data = routable.Data()
	if len(data) > r.maxDataLen {
		if logWarning {
			r.logger.Warn("router", "Data segment too long, truncating",
				LogFields{"rid": req.Header.Get(HeaderID),
					"uaid": uaid})
		}
		data = data[:r.maxDataLen]
	}
	// routed data is already in storage.
	if err = worker.Send(chid, routable.Version(), data); err != nil {
		if logWarning {
			r.logger.Warn("router", "Could not update local user",
				LogFields{"rid": req.Header.Get(HeaderID), "error": err.Error()})
		}
		http.Error(resp, "Server Error", http.StatusInternalServerError)
		r.metrics.Increment("updates.routed.error")
		return
	}
	resp.Write([]byte("Ok"))
	r.metrics.Increment("updates.routed.received")
	return

invalidBody:
	http.Error(resp, "Invalid body", http.StatusNotAcceptable)
	r.metrics.Increment("updates.routed.invalid")
}