Example #1
0
func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	flag.Parse()
	logger := log.New(os.Stderr, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile)

	pcap, err := pcap.OpenOffline(*pcapFile)
	if err != nil {
		fmt.Fprintln(os.Stderr, "error opening pcap file:", err)
		os.Exit(1)
	}
	h := mongocaputils.NewPacketHandler(pcap)
	m := mongocaputils.NewMongoOpStream(*packetBufSize)

	ch := make(chan struct{})
	go func() {
		defer close(ch)
		for op := range m.Ops {
			// TODO: add other op types
			if opQuery, ok := op.Op.(*mongoproto.OpQuery); ok {
				fbOp := map[string]interface{}{}
				fbOp["ns"] = opQuery.FullCollectionName
				fbOp["ntoskip"] = opQuery.NumberToSkip
				fbOp["ntoreturn"] = opQuery.NumberToReturn
				fbOp["ts"] = json.Date(op.Seen.Unix())
				query, err := rawBSONToJSON(opQuery.Query)
				if err != nil {
					logger.Println(err)
					if !*continueOnError {
						os.Exit(1)
					}
				}
				if strings.HasSuffix(opQuery.FullCollectionName, ".$cmd") {
					fbOp["op"] = "command"
					fbOp["command"] = query
				} else {
					fbOp["op"] = "query"
					fbOp["query"] = query
				}
				fbOpStr, err := json.Marshal(fbOp)
				if err != nil {
					logger.Println(err)
					if !*continueOnError {
						os.Exit(1)
					}
				}
				fmt.Println(string(fbOpStr))
			}
		}
	}()

	if err := h.Handle(m, -1); err != nil {
		fmt.Fprintln(os.Stderr, "pcap_converter: error handling packet stream:", err)
	}
	<-ch
}
Example #2
0
// GetBSONValueAsJSON is equivalent to ConvertBSONValueToJSON, but does not mutate its argument.
func GetBSONValueAsJSON(x interface{}) (interface{}, error) {
	switch v := x.(type) {
	case nil:
		return nil, nil
	case bool:
		return v, nil

	case *bson.M: // document
		doc, err := getConvertedKeys(*v)
		if err != nil {
			return nil, err
		}
		return doc, err
	case bson.M: // document
		return getConvertedKeys(v)
	case map[string]interface{}:
		return getConvertedKeys(v)
	case bson.D:
		out := bson.D{}
		for _, value := range v {
			jsonValue, err := GetBSONValueAsJSON(value.Value)
			if err != nil {
				return nil, err
			}
			out = append(out, bson.DocElem{
				Name:  value.Name,
				Value: jsonValue,
			})
		}
		return MarshalD(out), nil
	case MarshalD:
		out, err := GetBSONValueAsJSON(bson.D(v))
		if err != nil {
			return nil, err
		}
		return MarshalD(out.(bson.D)), nil
	case []interface{}: // array
		out := []interface{}{}
		for _, value := range v {
			jsonValue, err := GetBSONValueAsJSON(value)
			if err != nil {
				return nil, err
			}
			out = append(out, jsonValue)
		}
		return out, nil

	case string:
		return v, nil // require no conversion

	case int:
		return json.NumberInt(v), nil

	case bson.ObjectId: // ObjectId
		return json.ObjectId(v.Hex()), nil

	case bson.Decimal128:
		return json.Decimal128{v}, nil

	case time.Time: // Date
		return json.Date(v.Unix()*1000 + int64(v.Nanosecond()/1e6)), nil

	case int64: // NumberLong
		return json.NumberLong(v), nil

	case int32: // NumberInt
		return json.NumberInt(v), nil

	case float64:
		return json.NumberFloat(v), nil

	case float32:
		return json.NumberFloat(float64(v)), nil

	case []byte: // BinData (with generic type)
		data := base64.StdEncoding.EncodeToString(v)
		return json.BinData{0x00, data}, nil

	case bson.Binary: // BinData
		data := base64.StdEncoding.EncodeToString(v.Data)
		return json.BinData{v.Kind, data}, nil

	case mgo.DBRef: // DBRef
		return json.DBRef{v.Collection, v.Id, v.Database}, nil

	case bson.DBPointer: // DBPointer
		return json.DBPointer{v.Namespace, v.Id}, nil

	case bson.RegEx: // RegExp
		return json.RegExp{v.Pattern, v.Options}, nil

	case bson.MongoTimestamp: // Timestamp
		timestamp := int64(v)
		return json.Timestamp{
			Seconds:   uint32(timestamp >> 32),
			Increment: uint32(timestamp),
		}, nil

	case bson.JavaScript: // JavaScript
		var scope interface{}
		var err error
		if v.Scope != nil {
			scope, err = GetBSONValueAsJSON(v.Scope)
			if err != nil {
				return nil, err
			}
		}
		return json.JavaScript{v.Code, scope}, nil

	default:
		switch x {
		case bson.MinKey: // MinKey
			return json.MinKey{}, nil

		case bson.MaxKey: // MaxKey
			return json.MaxKey{}, nil

		case bson.Undefined: // undefined
			return json.Undefined{}, nil
		}
	}

	return nil, fmt.Errorf("conversion of BSON value '%v' of type '%T' not supported", x, x)
}
Example #3
0
func (d *LogDoc) Date(value string) mongo_json.Date {
	n, _ := strconv.Atoi(value)
	return mongo_json.Date(n)
}
Example #4
0
func TestDateValue(t *testing.T) {

	Convey("When converting JSON with Date values", t, func() {

		Convey("works for Date object", func() {
			key := "key"
			jsonMap := map[string]interface{}{
				key: json.Date(100),
			}

			err := ConvertJSONDocumentToBSON(jsonMap)
			So(err, ShouldBeNil)

			jsonValue, ok := jsonMap[key].(time.Time)
			So(ok, ShouldBeTrue)
			So(jsonValue.Equal(time.Unix(0, int64(100*time.Millisecond))), ShouldBeTrue)
		})

		Convey("works for Date document", func() {

			dates := []string{
				"2006-01-02T15:04:05.000Z",
				"2006-01-02T15:04:05.000-0700",
				"2006-01-02T15:04:05Z",
				"2006-01-02T15:04:05-0700",
				"2006-01-02T15:04Z",
				"2006-01-02T15:04-0700",
			}

			for _, dateString := range dates {
				example := fmt.Sprintf(`{ "$date": "%v" }`, dateString)
				Convey(fmt.Sprintf("of string ('%v')", example), func() {
					key := "key"
					jsonMap := map[string]interface{}{
						key: map[string]interface{}{
							"$date": dateString,
						},
					}

					err := ConvertJSONDocumentToBSON(jsonMap)
					So(err, ShouldBeNil)

					// dateString is a valid time format string
					date, err := time.Parse(dateString, dateString)
					So(err, ShouldBeNil)

					jsonValue, ok := jsonMap[key].(time.Time)
					So(ok, ShouldBeTrue)
					So(jsonValue.Equal(date), ShouldBeTrue)
				})
			}

			date := time.Unix(0, int64(time.Duration(1136214245000)*time.Millisecond))

			Convey(`of $numberLong ('{ "$date": { "$numberLong": "1136214245000" } }')`, func() {
				key := "key"
				jsonMap := map[string]interface{}{
					key: map[string]interface{}{
						"$date": map[string]interface{}{
							"$numberLong": "1136214245000",
						},
					},
				}

				err := ConvertJSONDocumentToBSON(jsonMap)
				So(err, ShouldBeNil)

				jsonValue, ok := jsonMap[key].(time.Time)
				So(ok, ShouldBeTrue)
				So(jsonValue.Equal(date), ShouldBeTrue)
			})

			Convey(`of json.Number ('{ "$date": 1136214245000 }')`, func() {
				key := "key"
				jsonMap := map[string]interface{}{
					key: map[string]interface{}{
						"$date": json.Number("1136214245000"),
					},
				}

				err := ConvertJSONDocumentToBSON(jsonMap)
				So(err, ShouldBeNil)

				jsonValue, ok := jsonMap[key].(time.Time)
				So(ok, ShouldBeTrue)
				So(jsonValue.Equal(date), ShouldBeTrue)
			})

			Convey(`of numeric int64 ('{ "$date": 1136214245000 }')`, func() {
				key := "key"
				jsonMap := map[string]interface{}{
					key: map[string]interface{}{
						"$date": int64(1136214245000),
					},
				}

				err := ConvertJSONDocumentToBSON(jsonMap)
				So(err, ShouldBeNil)

				jsonValue, ok := jsonMap[key].(time.Time)
				So(ok, ShouldBeTrue)
				So(jsonValue.Equal(date), ShouldBeTrue)
			})

			Convey(`of numeric float64 ('{ "$date": 1136214245000 }')`, func() {
				key := "key"
				jsonMap := map[string]interface{}{
					key: map[string]interface{}{
						"$date": float64(1136214245000),
					},
				}

				err := ConvertJSONDocumentToBSON(jsonMap)
				So(err, ShouldBeNil)

				jsonValue, ok := jsonMap[key].(time.Time)
				So(ok, ShouldBeTrue)
				So(jsonValue.Equal(date), ShouldBeTrue)
			})
		})
	})
}
Example #5
0
// ConvertBSONValueToJSON walks through a document or an array and
// replaces any BSON value with its corresponding extended JSON type.
func ConvertBSONValueToJSON(x interface{}) (interface{}, error) {
	switch v := x.(type) {
	case nil:
		return nil, nil
	case bool:
		return v, nil
	case *bson.M: // document
		doc, err := convertKeys(*v)
		if err != nil {
			return nil, err
		}
		return doc, err
	case bson.M: // document
		return convertKeys(v)
	case []interface{}: // array
		for i, value := range v {
			jsonValue, err := ConvertBSONValueToJSON(value)
			if err != nil {
				return nil, err
			}
			v[i] = jsonValue
		}
		return v, nil

	case string, float64:
		return v, nil // require no conversion

	case int:
		return json.NumberInt(v), nil

	case bson.ObjectId: // ObjectId
		return json.ObjectId(v.Hex()), nil

	case time.Time: // Date
		return json.Date(v.Unix()*1000 + int64(v.Nanosecond()/1e6)), nil

	case int64: // NumberLong
		return json.NumberLong(v), nil

	case int32: // NumberInt
		return json.NumberInt(v), nil

	case []byte: // BinData (with generic type)
		data := base64.StdEncoding.EncodeToString(v)
		return json.BinData{0x00, data}, nil

	case bson.Binary: // BinData
		data := base64.StdEncoding.EncodeToString(v.Data)
		return json.BinData{v.Kind, data}, nil

	case mgo.DBRef: // DBRef
		return json.DBRef{v.Collection, v.Id, v.Database}, nil

	case bson.RegEx: // RegExp
		return json.RegExp{v.Pattern, v.Options}, nil

	case bson.MongoTimestamp: // Timestamp
		inc := uint32(int64(v) & 0xffff)
		secs := uint32((int64(v) & (0xffff << 32)) >> 32)
		return json.Timestamp{secs, inc}, nil

	default:
		switch x {
		case bson.MinKey: // MinKey
			return json.MinKey{}, nil

		case bson.MaxKey: // MaxKey
			return json.MaxKey{}, nil

		case bson.Undefined: // undefined
			return json.Undefined{}, nil
		}
	}

	return nil, fmt.Errorf("Conversion of BSON type '%v' not supported %v", reflect.TypeOf(x), x)
}
Example #6
0
// ConvertBSONValueToJSON walks through a document or an array and
// converts any BSON value to its corresponding extended JSON type.
// It returns the converted JSON document and any error encountered.
func ConvertBSONValueToJSON(x interface{}) (interface{}, error) {
	switch v := x.(type) {
	case nil:
		return nil, nil
	case bool:
		return v, nil

	case *bson.M: // document
		doc, err := convertKeys(*v)
		if err != nil {
			return nil, err
		}
		return doc, err
	case bson.M: // document
		return convertKeys(v)
	case map[string]interface{}:
		return convertKeys(v)
	case bson.D:
		for i, value := range v {
			jsonValue, err := ConvertBSONValueToJSON(value.Value)
			if err != nil {
				return nil, err
			}
			v[i].Value = jsonValue
		}
		return MarshalD(v), nil
	case MarshalD:
		return v, nil
	case []interface{}: // array
		for i, value := range v {
			jsonValue, err := ConvertBSONValueToJSON(value)
			if err != nil {
				return nil, err
			}
			v[i] = jsonValue
		}
		return v, nil

	case string:
		return v, nil // require no conversion

	case int:
		return json.NumberInt(v), nil

	case bson.ObjectId: // ObjectId
		return json.ObjectId(v.Hex()), nil

	case time.Time: // Date
		return json.Date(v.Unix()*1000 + int64(v.Nanosecond()/1e6)), nil

	case int64: // NumberLong
		return json.NumberLong(v), nil

	case int32: // NumberInt
		return json.NumberInt(v), nil

	case float64:
		return json.NumberFloat(v), nil

	case float32:
		return json.NumberFloat(float64(v)), nil

	case []byte: // BinData (with generic type)
		data := base64.StdEncoding.EncodeToString(v)
		return json.BinData{0x00, data}, nil

	case bson.Binary: // BinData
		data := base64.StdEncoding.EncodeToString(v.Data)
		return json.BinData{v.Kind, data}, nil

	case mgo.DBRef: // DBRef
		return json.DBRef{v.Collection, v.Id, v.Database}, nil

	case bson.DBPointer: // DBPointer
		return json.DBPointer{v.Namespace, v.Id}, nil

	case bson.RegEx: // RegExp
		return json.RegExp{v.Pattern, v.Options}, nil

	case bson.MongoTimestamp: // Timestamp
		timestamp := int64(v)
		return json.Timestamp{
			Seconds:   uint32(timestamp >> 32),
			Increment: uint32(timestamp),
		}, nil

	case bson.JavaScript: // JavaScript
		var scope interface{}
		var err error
		if v.Scope != nil {
			scope, err = ConvertBSONValueToJSON(v.Scope)
			if err != nil {
				return nil, err
			}
		}
		return json.JavaScript{v.Code, scope}, nil

	default:
		switch x {
		case bson.MinKey: // MinKey
			return json.MinKey{}, nil

		case bson.MaxKey: // MaxKey
			return json.MaxKey{}, nil

		case bson.Undefined: // undefined
			return json.Undefined{}, nil
		}
	}

	return nil, fmt.Errorf("conversion of BSON type '%v' not supported %v", reflect.TypeOf(x), x)
}
Example #7
0
// ConvertBSONValueToJSON walks through a document or an array and converts any
// BSON value to its corresponding extended JSON type. It returns the converted
// JSON document and any error encountered.
func ConvertBSONValueToJSON(x interface{}) (interface{}, error) {
	switch v := x.(type) {
	case nil:
		return nil, nil
	case bool:
		return v, nil
	case *bson.M: // document
		doc, err := convertKeys(*v)
		if err != nil {
			return nil, err
		}
		return doc, err
	case bson.M: // document
		return convertKeys(v)
	case map[string]interface{}:
		return convertKeys(v)
	case []bson.Raw:
		out := make([]interface{}, len(v))
		for i, value := range v {
			out[i] = value
		}
		return ConvertBSONValueToJSON(out)
	case bson.Raw:
		// Unmarshal the raw into a bson.D, then process that.
		convertedFromRaw := bson.D{}
		err := v.Unmarshal(&convertedFromRaw)
		if err != nil {
			return nil, err
		}
		return ConvertBSONValueToJSON(convertedFromRaw)
	case (*bson.Raw):
		return ConvertBSONValueToJSON(*v)
	case (*bson.D):
		return ConvertBSONValueToJSON(*v)
	case bson.D:
		for i, value := range v {
			jsonValue, err := ConvertBSONValueToJSON(value.Value)
			if err != nil {
				return nil, err
			}
			v[i].Value = jsonValue
		}
		return v.Map(), nil
	case []bson.D:
		out := make([]interface{}, len(v))
		for i, value := range v {
			out[i] = value
		}
		return ConvertBSONValueToJSON(out)
	case []interface{}: // array
		for i, value := range v {
			jsonValue, err := ConvertBSONValueToJSON(value)
			if err != nil {
				return nil, err
			}
			v[i] = jsonValue
		}
		return v, nil
	case string:
		return v, nil // require no conversion

	case int:
		return json.NumberInt(v), nil

	case bson.ObjectId: // ObjectId
		return json.ObjectId(v.Hex()), nil

	case time.Time: // Date
		return json.Date(v.Unix()*1000 + int64(v.Nanosecond()/1e6)), nil

	case int64: // NumberLong
		return json.NumberLong(v), nil

	case int32: // NumberInt
		return json.NumberInt(v), nil

	case float64:
		return json.NumberFloat(v), nil

	case float32:
		return json.NumberFloat(float64(v)), nil

	case []byte: // BinData (with generic type)
		data := base64.StdEncoding.EncodeToString(v)
		return json.BinData{0x00, data}, nil

	case bson.Binary: // BinData
		data := base64.StdEncoding.EncodeToString(v.Data)
		return json.BinData{v.Kind, data}, nil

	case mgo.DBRef: // DBRef
		return map[string]interface{}{"$ref": v.Collection, "$id": v.Id}, nil

	//case bson.DBPointer: // DBPointer
	//return json.DBPointer{v.Namespace, v.Id}, nil

	case bson.RegEx: // RegExp
		return json.RegExp{v.Pattern, v.Options}, nil

	case bson.MongoTimestamp: // Timestamp
		timestamp := int64(v)
		return json.Timestamp{
			Seconds:   uint32(timestamp >> 32),
			Increment: uint32(timestamp),
		}, nil

	case bson.JavaScript: // JavaScript
		var scope interface{}
		var err error
		if v.Scope != nil {
			scope, err = ConvertBSONValueToJSON(v.Scope)
			if err != nil {
				return nil, err
			}
		}
		return json.JavaScript{v.Code, scope}, nil

	default:
		switch x {
		case bson.MinKey: // MinKey
			return json.MinKey{}, nil

		case bson.MaxKey: // MaxKey
			return json.MaxKey{}, nil

		case bson.Undefined: // undefined
			return json.Undefined{}, nil
		}
	}

	if valueOfX := reflect.ValueOf(x); valueOfX.Kind() == reflect.Slice || valueOfX.Kind() == reflect.Array {
		result := make([]interface{}, 0, valueOfX.Len())
		for i := 0; i < (valueOfX.Len()); i++ {
			v := valueOfX.Index(i).Interface()
			jsonResult, err := ConvertBSONValueToJSON(v)
			if err != nil {
				return nil, err
			}
			result = append(result, jsonResult)
		}
		return result, nil

	}

	return nil, fmt.Errorf("conversion of BSON type '%v' not supported %v", reflect.TypeOf(x), x)
}