github.com/dbernstein1/tyk@v2.9.0-beta9-dl-apic+incompatible/gateway/coprocess_native.go (about)

     1  // +build coprocess
     2  // +build !grpc
     3  
     4  package gateway
     5  
     6  /*
     7  #cgo python CFLAGS: -DENABLE_PYTHON
     8  #include <stdio.h>
     9  #include <stdlib.h>
    10  
    11  #include "../coprocess/api.h"
    12  
    13  #ifdef ENABLE_PYTHON
    14  #include "../coprocess/python/dispatcher.h"
    15  #include "../coprocess/python/binding.h"
    16  #endif
    17  
    18  */
    19  import "C"
    20  
    21  import (
    22  	"errors"
    23  
    24  	"github.com/golang/protobuf/proto"
    25  
    26  	"github.com/TykTechnologies/tyk/coprocess"
    27  
    28  	"encoding/json"
    29  	"unsafe"
    30  )
    31  
    32  var MessageType int
    33  
    34  // Dispatch prepares a CoProcessMessage, sends it to the GlobalDispatcher and gets a reply.
    35  func (c *CoProcessor) Dispatch(object *coprocess.Object) (*coprocess.Object, error) {
    36  	if GlobalDispatcher == nil {
    37  		return nil, errors.New("Dispatcher not initialized")
    38  	}
    39  
    40  	var objectMsg []byte
    41  	var err error
    42  	switch MessageType {
    43  	case coprocess.ProtobufMessage:
    44  		objectMsg, err = proto.Marshal(object)
    45  	case coprocess.JsonMessage:
    46  		objectMsg, err = json.Marshal(object)
    47  	}
    48  	if err != nil {
    49  		return nil, err
    50  	}
    51  
    52  	objectMsgStr := string(objectMsg)
    53  
    54  	CObjectStr := C.CString(objectMsgStr)
    55  
    56  	objectPtr := (*C.struct_CoProcessMessage)(C.malloc(C.size_t(unsafe.Sizeof(C.struct_CoProcessMessage{}))))
    57  	objectPtr.p_data = unsafe.Pointer(CObjectStr)
    58  	objectPtr.length = C.int(len(objectMsg))
    59  
    60  	newObjectPtr := (*C.struct_CoProcessMessage)(C.malloc(C.size_t(unsafe.Sizeof(C.struct_CoProcessMessage{}))))
    61  
    62  	// Call the dispatcher (objectPtr is freed during this call):
    63  	if err = GlobalDispatcher.Dispatch(unsafe.Pointer(objectPtr), unsafe.Pointer(newObjectPtr)); err != nil {
    64  		return nil, err
    65  	}
    66  	newObjectBytes := C.GoBytes(newObjectPtr.p_data, newObjectPtr.length)
    67  
    68  	newObject := &coprocess.Object{}
    69  
    70  	switch MessageType {
    71  	case coprocess.ProtobufMessage:
    72  		err = proto.Unmarshal(newObjectBytes, newObject)
    73  	case coprocess.JsonMessage:
    74  		err = json.Unmarshal(newObjectBytes, newObject)
    75  	}
    76  	if err != nil {
    77  		return nil, err
    78  	}
    79  
    80  	// Free the returned object memory:
    81  	C.free(unsafe.Pointer(newObjectPtr.p_data))
    82  	C.free(unsafe.Pointer(newObjectPtr))
    83  
    84  	return newObject, nil
    85  }