├── test ├── bool.gob ├── int.gob ├── uint.gob ├── bytearray.gob ├── string.gob ├── Makefile ├── jbuild ├── unittest.ml └── generate_examples.go ├── src ├── rpc.ml ├── jbuild └── gob.ml ├── .gitignore ├── pkg └── pkg.ml ├── CHANGES.md ├── Makefile ├── README.md ├── awwcaml.opam └── COPYING /test/bool.gob: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /test/int.gob: -------------------------------------------------------------------------------- 1 | S -------------------------------------------------------------------------------- /test/uint.gob: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /src/rpc.ml: -------------------------------------------------------------------------------- 1 | let () = () 2 | -------------------------------------------------------------------------------- /test/bytearray.gob: -------------------------------------------------------------------------------- 1 |  2 | * % -------------------------------------------------------------------------------- /test/string.gob: -------------------------------------------------------------------------------- 1 |  Hello Caml! -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /_opam/ 2 | /_build/ 3 | *.install 4 | .merlin 5 | -------------------------------------------------------------------------------- /pkg/pkg.ml: -------------------------------------------------------------------------------- 1 | #use "topfind" 2 | #require "topkg-jbuilder.auto" 3 | -------------------------------------------------------------------------------- /test/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: recreate 2 | recreate: 3 | go run generate_examples.go 4 | -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- 1 | * Basic parser for Go Gobs format 2 | * Basic implementation of Go net/rpc 3 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all 2 | all: 3 | jbuilder build --dev 4 | 5 | .PHONY: test 6 | test: 7 | jbuilder runtest --force 8 | -------------------------------------------------------------------------------- /src/jbuild: -------------------------------------------------------------------------------- 1 | (library 2 | ((name awwcaml) 3 | (public_name awwcaml) 4 | (preprocess (pps (bitstring.ppx))) 5 | (libraries (cohttp-async bitstring)))) 6 | -------------------------------------------------------------------------------- /test/jbuild: -------------------------------------------------------------------------------- 1 | (executable 2 | ((name unittest) 3 | (libraries (alcotest)))) 4 | 5 | (alias 6 | ((name runtest) 7 | (deps (unittest.exe)) 8 | (action (run ${<})))) 9 | -------------------------------------------------------------------------------- /test/unittest.ml: -------------------------------------------------------------------------------- 1 | let decode_bool () = 2 | Alcotest.(check bool) "same bool" true true 3 | 4 | let test_gobs = [ 5 | ("Decode bool", `Slow, decode_bool); 6 | ] 7 | 8 | let () = 9 | Alcotest.run "Awwcaml unit tests" [ 10 | ("Gob decoding", test_gobs); 11 | ] 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | awwcaml 2 | ======= 3 | 4 | A library to wrap your OCaml code to work on AWS Lambda. 5 | 6 | How it works 7 | ------------ 8 | 9 | It implements the necessary bits to pretend your binary is a Go binary, thus 10 | speaking `net/rpc` and communicating via the `Gobs` serialization format. 11 | -------------------------------------------------------------------------------- /awwcaml.opam: -------------------------------------------------------------------------------- 1 | opam-version: "1.2" 2 | maintainer: "Marek Kubica " 3 | authors: [ "Marek Kubica " ] 4 | license: "LGPL-3 with OCaml linking exception" 5 | homepage: "https://github.com/Leonidas-from-XIV/awwcaml" 6 | dev-repo: "git@github.com/Leonidas-from-XIV/awwcaml.git" 7 | bug-reports: "https://github.com/Leonidas-from-XIV/awwcaml/issues" 8 | build: [["jbuilder" "build" "-p" name "-j" jobs]] 9 | build-test: [["jbuilder" "runtest" "-p" name "-j" jobs]] 10 | depends: [ 11 | "jbuilder" {build & >= "1.0+beta17"} 12 | "base" {>= "v0.11" & < "v0.12"} 13 | "cohttp-async" {>= "1.1.0" & < "1.2.0"} 14 | "ppx_deriving_yojson" {>= "3.1"} 15 | "bitstring" {>= "3.0"} 16 | "alcotest" {test & >= "0.8.0" & < "0.9.0"} 17 | ] 18 | -------------------------------------------------------------------------------- /test/generate_examples.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "encoding/gob" 6 | "io/ioutil" 7 | "log" 8 | ) 9 | 10 | func main() { 11 | var buf bytes.Buffer 12 | enc := gob.NewEncoder(&buf) 13 | 14 | err := enc.Encode(true) 15 | if err != nil { 16 | log.Fatal("encode error:", err) 17 | } 18 | 19 | err = ioutil.WriteFile("bool.gob", buf.Bytes(), 0644) 20 | if err != nil { 21 | log.Fatal("write error:", err) 22 | } 23 | 24 | buf.Reset() 25 | enc = gob.NewEncoder(&buf) 26 | var ui uint = 23 27 | err = enc.Encode(ui) 28 | if err != nil { 29 | log.Fatal("encode error:", err) 30 | } 31 | 32 | err = ioutil.WriteFile("uint.gob", buf.Bytes(), 0644) 33 | if err != nil { 34 | log.Fatal("write error:", err) 35 | } 36 | 37 | buf.Reset() 38 | enc = gob.NewEncoder(&buf) 39 | var i int = -42 40 | err = enc.Encode(i) 41 | if err != nil { 42 | log.Fatal("encode error:", err) 43 | } 44 | 45 | err = ioutil.WriteFile("int.gob", buf.Bytes(), 0644) 46 | if err != nil { 47 | log.Fatal("write error:", err) 48 | } 49 | 50 | buf.Reset() 51 | enc = gob.NewEncoder(&buf) 52 | err = enc.Encode("Hello Caml!") 53 | if err != nil { 54 | log.Fatal("encode error:", err) 55 | } 56 | 57 | err = ioutil.WriteFile("string.gob", buf.Bytes(), 0644) 58 | if err != nil { 59 | log.Fatal("write error:", err) 60 | } 61 | 62 | buf.Reset() 63 | enc = gob.NewEncoder(&buf) 64 | ba := []byte{24, 42, 13, 37} 65 | err = enc.Encode(ba) 66 | if err != nil { 67 | log.Fatal("encode error:", err) 68 | } 69 | 70 | err = ioutil.WriteFile("bytearray.gob", buf.Bytes(), 0644) 71 | if err != nil { 72 | log.Fatal("write error:", err) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/gob.ml: -------------------------------------------------------------------------------- 1 | module Gob = struct 2 | type t = 3 | | Bool of bool 4 | | Uint of Int64.t 5 | | Int of Int64.t 6 | | Float of float 7 | | Byteslice of bytes 8 | | String of string 9 | end 10 | 11 | let decode_uint 12 | : Bitstring.bitstring -> (Int64.t * Bitstring.bitstring) 13 | = fun bits -> 14 | match%bitstring bits with 15 | | {| value_or_length : 8; 16 | rest : -1 : bitstring |} -> 17 | match (value_or_length < 128, value_or_length) with 18 | | (true, value) -> (Int64.of_int value), rest 19 | | (false, inverted_length) -> 20 | match%bitstring rest with 21 | | {| v : (256 - inverted_length) : bigendian; 22 | rest : -1 : bitstring |} -> v, rest 23 | 24 | let decode_bool bits = 25 | let n, rest = decode_uint bits in 26 | Int64.(n = one), rest 27 | 28 | let decode_int 29 | : Bitstring.bitstring -> (Int64.t * Bitstring.bitstring) 30 | = fun bits -> 31 | let go_uint, bits = decode_uint bits in 32 | let go_uint = match Int64.logand go_uint Int64.one with 33 | | n when n > Int64.zero -> Int64.lognot go_uint 34 | | _ -> go_uint 35 | in 36 | (Int64.shift_right_logical go_uint 1, bits) 37 | 38 | let decode_byte_slice 39 | : Bitstring.bitstring -> (bytes * Bitstring.bitstring) 40 | = fun bits -> 41 | let length, bits = decode_uint bits in 42 | let length = Int64.to_int length in 43 | match%bitstring bits with 44 | | {| byte_slice : length * 8 : string; 45 | rest : -1 : bitstring |} -> 46 | (Bytes.of_string byte_slice, rest) 47 | 48 | let decode_string bits = 49 | let slice, rest = decode_byte_slice bits in 50 | (Bytes.to_string slice, rest) 51 | 52 | let read_segment 53 | : Bitstring.bitstring -> (Bitstring.bitstring * Bitstring.bitstring) 54 | = fun bits -> 55 | let length, buf = decode_uint bits in 56 | let length = Int64.to_int length in 57 | match%bitstring buf with 58 | | {| segment : length * 8 : bitstring; 59 | rest : -1 : bitstring |} -> (segment, rest) 60 | 61 | let decode_value 62 | : int -> Bitstring.bitstring -> (Gob.t * Bitstring.bitstring) 63 | = fun type_id bits -> 64 | match type_id with 65 | | 1 -> 66 | let v, rest = decode_bool bits in 67 | (Gob.Bool v, rest) 68 | | 2 -> 69 | let v, rest = decode_int bits in 70 | (Gob.Int v, rest) 71 | | 3 -> 72 | let v, rest = decode_uint bits in 73 | (Gob.Uint v, rest) 74 | | 4 -> 75 | failwith "Decoding floats unsupported" 76 | | 5 -> 77 | let v, rest = decode_byte_slice bits in 78 | (Gob.Byteslice v, rest) 79 | | 6 -> 80 | let v, rest = decode_string bits in 81 | (Gob.String v, rest) 82 | | _ -> failwith "Not implemented" 83 | 84 | let load 85 | : string -> Gob.t 86 | = fun str -> 87 | let bits = Bitstring.bitstring_of_string str in 88 | let segment, _rest = read_segment bits in 89 | let type_id, segment = decode_int segment in 90 | let type_id = Int64.to_int type_id in 91 | let value, _rest = decode_value type_id segment in 92 | 93 | value 94 | 95 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | This library is free software; you can redistribute it and/or modify 2 | it under the terms of the GNU Lesser General Public License (LGPL) as 3 | published by the Free Software Foundation; either version 3.0 of the 4 | License (see below), or (at your option) any later version. 5 | 6 | As a special exception to the GNU Lesser General Public License, you 7 | may link, statically or dynamically, a "work that uses the Library" 8 | with a publicly distributed version of the Library to produce an 9 | executable file containing portions of the Library, and distribute 10 | that executable file under terms of your choice, without any of the 11 | additional requirements listed in clause 4 of the GNU Lesser General 12 | Public License. By "a publicly distributed version of the Library", 13 | we mean either the unmodified Library as distributed by the copyright 14 | holder, or a modified version of the Library that is distributed under 15 | the conditions defined in clause 2 of the GNU Lesser General Public 16 | License. This exception does not however invalidate any other reasons 17 | why the executable file might be covered by the GNU Lesser General 18 | Public License. 19 | 20 | 21 | GNU LESSER GENERAL PUBLIC LICENSE 22 | Version 3, 29 June 2007 23 | 24 | Copyright (C) 2007 Free Software Foundation, Inc. 25 | Everyone is permitted to copy and distribute verbatim copies 26 | of this license document, but changing it is not allowed. 27 | 28 | 29 | This version of the GNU Lesser General Public License incorporates 30 | the terms and conditions of version 3 of the GNU General Public 31 | License, supplemented by the additional permissions listed below. 32 | 33 | 0. Additional Definitions. 34 | 35 | As used herein, "this License" refers to version 3 of the GNU Lesser 36 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 37 | General Public License. 38 | 39 | "The Library" refers to a covered work governed by this License, 40 | other than an Application or a Combined Work as defined below. 41 | 42 | An "Application" is any work that makes use of an interface provided 43 | by the Library, but which is not otherwise based on the Library. 44 | Defining a subclass of a class defined by the Library is deemed a mode 45 | of using an interface provided by the Library. 46 | 47 | A "Combined Work" is a work produced by combining or linking an 48 | Application with the Library. The particular version of the Library 49 | with which the Combined Work was made is also called the "Linked 50 | Version". 51 | 52 | The "Minimal Corresponding Source" for a Combined Work means the 53 | Corresponding Source for the Combined Work, excluding any source code 54 | for portions of the Combined Work that, considered in isolation, are 55 | based on the Application, and not on the Linked Version. 56 | 57 | The "Corresponding Application Code" for a Combined Work means the 58 | object code and/or source code for the Application, including any data 59 | and utility programs needed for reproducing the Combined Work from the 60 | Application, but excluding the System Libraries of the Combined Work. 61 | 62 | 1. Exception to Section 3 of the GNU GPL. 63 | 64 | You may convey a covered work under sections 3 and 4 of this License 65 | without being bound by section 3 of the GNU GPL. 66 | 67 | 2. Conveying Modified Versions. 68 | 69 | If you modify a copy of the Library, and, in your modifications, a 70 | facility refers to a function or data to be supplied by an Application 71 | that uses the facility (other than as an argument passed when the 72 | facility is invoked), then you may convey a copy of the modified 73 | version: 74 | 75 | a) under this License, provided that you make a good faith effort to 76 | ensure that, in the event an Application does not supply the 77 | function or data, the facility still operates, and performs 78 | whatever part of its purpose remains meaningful, or 79 | 80 | b) under the GNU GPL, with none of the additional permissions of 81 | this License applicable to that copy. 82 | 83 | 3. Object Code Incorporating Material from Library Header Files. 84 | 85 | The object code form of an Application may incorporate material from 86 | a header file that is part of the Library. You may convey such object 87 | code under terms of your choice, provided that, if the incorporated 88 | material is not limited to numerical parameters, data structure 89 | layouts and accessors, or small macros, inline functions and templates 90 | (ten or fewer lines in length), you do both of the following: 91 | 92 | a) Give prominent notice with each copy of the object code that the 93 | Library is used in it and that the Library and its use are 94 | covered by this License. 95 | 96 | b) Accompany the object code with a copy of the GNU GPL and this license 97 | document. 98 | 99 | 4. Combined Works. 100 | 101 | You may convey a Combined Work under terms of your choice that, 102 | taken together, effectively do not restrict modification of the 103 | portions of the Library contained in the Combined Work and reverse 104 | engineering for debugging such modifications, if you also do each of 105 | the following: 106 | 107 | a) Give prominent notice with each copy of the Combined Work that 108 | the Library is used in it and that the Library and its use are 109 | covered by this License. 110 | 111 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 112 | document. 113 | 114 | c) For a Combined Work that displays copyright notices during 115 | execution, include the copyright notice for the Library among 116 | these notices, as well as a reference directing the user to the 117 | copies of the GNU GPL and this license document. 118 | 119 | d) Do one of the following: 120 | 121 | 0) Convey the Minimal Corresponding Source under the terms of this 122 | License, and the Corresponding Application Code in a form 123 | suitable for, and under terms that permit, the user to 124 | recombine or relink the Application with a modified version of 125 | the Linked Version to produce a modified Combined Work, in the 126 | manner specified by section 6 of the GNU GPL for conveying 127 | Corresponding Source. 128 | 129 | 1) Use a suitable shared library mechanism for linking with the 130 | Library. A suitable mechanism is one that (a) uses at run time 131 | a copy of the Library already present on the user's computer 132 | system, and (b) will operate properly with a modified version 133 | of the Library that is interface-compatible with the Linked 134 | Version. 135 | 136 | e) Provide Installation Information, but only if you would otherwise 137 | be required to provide such information under section 6 of the 138 | GNU GPL, and only to the extent that such information is 139 | necessary to install and execute a modified version of the 140 | Combined Work produced by recombining or relinking the 141 | Application with a modified version of the Linked Version. (If 142 | you use option 4d0, the Installation Information must accompany 143 | the Minimal Corresponding Source and Corresponding Application 144 | Code. If you use option 4d1, you must provide the Installation 145 | Information in the manner specified by section 6 of the GNU GPL 146 | for conveying Corresponding Source.) 147 | 148 | 5. Combined Libraries. 149 | 150 | You may place library facilities that are a work based on the 151 | Library side by side in a single library together with other library 152 | facilities that are not Applications and are not covered by this 153 | License, and convey such a combined library under terms of your 154 | choice, if you do both of the following: 155 | 156 | a) Accompany the combined library with a copy of the same work based 157 | on the Library, uncombined with any other library facilities, 158 | conveyed under the terms of this License. 159 | 160 | b) Give prominent notice with the combined library that part of it 161 | is a work based on the Library, and explaining where to find the 162 | accompanying uncombined form of the same work. 163 | 164 | 6. Revised Versions of the GNU Lesser General Public License. 165 | 166 | The Free Software Foundation may publish revised and/or new versions 167 | of the GNU Lesser General Public License from time to time. Such new 168 | versions will be similar in spirit to the present version, but may 169 | differ in detail to address new problems or concerns. 170 | 171 | Each version is given a distinguishing version number. If the 172 | Library as you received it specifies that a certain numbered version 173 | of the GNU Lesser General Public License "or any later version" 174 | applies to it, you have the option of following the terms and 175 | conditions either of that published version or of any later version 176 | published by the Free Software Foundation. If the Library as you 177 | received it does not specify a version number of the GNU Lesser 178 | General Public License, you may choose any version of the GNU Lesser 179 | General Public License ever published by the Free Software Foundation. 180 | 181 | If the Library as you received it specifies that a proxy can decide 182 | whether future versions of the GNU Lesser General Public License shall 183 | apply, that proxy's public statement of acceptance of any version is 184 | permanent authorization for you to choose that version for the 185 | Library. 186 | --------------------------------------------------------------------------------