-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathgohttplib.go
82 lines (72 loc) · 2.05 KB
/
gohttplib.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package main
/*
#include <stdlib.h>
typedef struct Request_
{
const char *Method;
const char *Host;
const char *URL;
const char *Body;
const char *Headers;
} Request;
typedef unsigned int ResponseWriterPtr;
typedef void FuncPtr(ResponseWriterPtr w, Request *r);
extern void Call_HandleFunc(ResponseWriterPtr w, Request *r, FuncPtr *fn);
*/
import "C"
import (
"bytes"
"net/http"
"unsafe"
"context"
)
var cpointers = PtrProxy()
var srv http.Server = http.Server{}
//export ListenAndServe
func ListenAndServe(caddr *C.char) {
addr := C.GoString(caddr)
srv.Addr = addr
srv.ListenAndServe()
}
//export Shutdown
func Shutdown() {
srv.Shutdown(context.Background())
}
//export HandleFunc
func HandleFunc(cpattern *C.char, cfn *C.FuncPtr) {
// C-friendly wrapping for our http.HandleFunc call.
pattern := C.GoString(cpattern)
http.HandleFunc(pattern, func(w http.ResponseWriter, req *http.Request) {
// Convert the headers to a String
headerBuffer := new(bytes.Buffer)
req.Header.Write(headerBuffer)
headersString := headerBuffer.String()
// Convert the request body to a String
bodyBuffer := new(bytes.Buffer)
bodyBuffer.ReadFrom(req.Body)
bodyString := bodyBuffer.String()
// Wrap relevant request fields in a C-friendly datastructure.
creq := C.Request{
Method: C.CString(req.Method),
Host: C.CString(req.Host),
URL: C.CString(req.URL.String()),
Body: C.CString(bodyString),
Headers: C.CString(headersString),
}
// Convert the ResponseWriter interface instance to an opaque C integer
// that we can safely pass along.
wPtr := cpointers.Ref(unsafe.Pointer(&w))
// Call our C function pointer using our C shim.
C.Call_HandleFunc(C.ResponseWriterPtr(wPtr), &creq, cfn)
// release the C memory
C.free(unsafe.Pointer(creq.Method))
C.free(unsafe.Pointer(creq.Host))
C.free(unsafe.Pointer(creq.URL))
C.free(unsafe.Pointer(creq.Body))
C.free(unsafe.Pointer(creq.Headers))
// Release the ResponseWriter from the registry since we're done with
// this response.
cpointers.Free(wPtr)
})
}
func main() {}