fluent-plugin-http-ex 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/.gitignore +17 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +13 -0
- data/README.md +279 -0
- data/Rakefile +10 -0
- data/examples/chunked.rb +27 -0
- data/examples/json.rb +23 -0
- data/examples/json_list.rb +12 -0
- data/examples/msgpack.rb +22 -0
- data/examples/msgpack_list.rb +23 -0
- data/examples/nc_chunked.rb +44 -0
- data/examples/sample.conf +11 -0
- data/fluent-plugin-http-ex.gemspec +21 -0
- data/lib/fluent/plugin/in_http_ex.rb +252 -0
- data/test/helper.rb +23 -0
- data/test/in_http_ex_test.rb +100 -0
- data/test/plugin/test_in_http_ex.rb +347 -0
- metadata +91 -0
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            !binary "U0hBMQ==":
         | 
| 3 | 
            +
              metadata.gz: !binary |-
         | 
| 4 | 
            +
                MGZlNmQ3NTVmNDkyNDRjNTMyYjYzMWFkNzJjYzBjZTdkYzNlZDI1Yw==
         | 
| 5 | 
            +
              data.tar.gz: !binary |-
         | 
| 6 | 
            +
                NTFkNjIyN2MyNDgwNmY2ZmRkMDNhMDAxYjZlNmU0ZmRmMTQ0ZmY4Ng==
         | 
| 7 | 
            +
            !binary "U0hBNTEy":
         | 
| 8 | 
            +
              metadata.gz: !binary |-
         | 
| 9 | 
            +
                MjFiNWVjNDI2YTYzNjNkZjZlY2Y5ZDJjMGQ5YzMyYjQ1ZmRjNTExZjBkYmNj
         | 
| 10 | 
            +
                MGRmMDlhNmY3ZDc4ZjE5OTk1ZWVlZTg4MGM2MzBlNjNhZDMyOTQwNGFkZjVj
         | 
| 11 | 
            +
                NTM5MWFkM2RiYjY5YzEyZTE0MDM2YzZjZWY5YzJiNDlkMTEyN2E=
         | 
| 12 | 
            +
              data.tar.gz: !binary |-
         | 
| 13 | 
            +
                MDUwZGEwN2YxZjcyMmMxYmUxYzk0YmJmNzRmOTk2ZDVlY2RiMDNlNjNmMGQz
         | 
| 14 | 
            +
                NDlhZGRiNDNkMGJjZWRhNDlmNjZkMzg4YzMxNTVlNjQxNWY5MDg4ZjRmZTkx
         | 
| 15 | 
            +
                NWUyNjJkODU1NmYyMGZhZGE3ZjIzNThkNGI1M2Q1NGMyMjM2NGI=
         | 
    
        data/.gitignore
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/LICENSE.txt
    ADDED
    
    | @@ -0,0 +1,13 @@ | |
| 1 | 
            +
            Copyright (C) 2013 hiro-su
         | 
| 2 | 
            +
             | 
| 3 | 
            +
               Licensed under the Apache License, Version 2.0 (the "License");
         | 
| 4 | 
            +
               you may not use this file except in compliance with the License.
         | 
| 5 | 
            +
               You may obtain a copy of the License at
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                   http://www.apache.org/licenses/LICENSE-2.0
         | 
| 8 | 
            +
             | 
| 9 | 
            +
               Unless required by applicable law or agreed to in writing, software
         | 
| 10 | 
            +
               distributed under the License is distributed on an "AS IS" BASIS,
         | 
| 11 | 
            +
               WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         | 
| 12 | 
            +
               See the License for the specific language governing permissions and
         | 
| 13 | 
            +
               limitations under the License.
         | 
    
        data/README.md
    ADDED
    
    | @@ -0,0 +1,279 @@ | |
| 1 | 
            +
            # Fluent::Plugin::Http::Ex
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            ## Overview
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            This plugin takes JSON or MessagePack of events as input via a single, list or chunked
         | 
| 6 | 
            +
            HTTP POST request and emits each as an individual event to your output plugins.
         | 
| 7 | 
            +
            If you're sending a lot of events this simplifies your client's code and eliminates
         | 
| 8 | 
            +
            the overhead of creating a lot of brief connections.
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            ## Configuration
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            The ExHttpInput plugin uses the same settings you would use for the standard
         | 
| 13 | 
            +
            HTTP input plugin. Example:
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                <source>
         | 
| 16 | 
            +
                  type http_ex
         | 
| 17 | 
            +
                  port 8888
         | 
| 18 | 
            +
                  bind 0.0.0.0
         | 
| 19 | 
            +
                  body_size_limit 32m
         | 
| 20 | 
            +
                  keepalive_timeout 300s #0s is not timeout
         | 
| 21 | 
            +
                </source>
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            Like the HTTP input plugin, the tag is determined by the URL used, which means 
         | 
| 24 | 
            +
            all events in one request must have the same tag.
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            ## Usage
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            Have your logging system send JSON or Message of events. Example:
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            Base URL
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                http://localhost:8888
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            ### json
         | 
| 35 | 
            +
            ####  case 1
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            resource
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                j or null
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            header
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                Content-type: application/x-www-form-urlencoded
         | 
| 44 | 
            +
             | 
| 45 | 
            +
            body
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                json=<json data>
         | 
| 48 | 
            +
             | 
| 49 | 
            +
            sample
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                $ curl -X POST -d 'json={"action":"login","user":2}' \
         | 
| 52 | 
            +
                    http://localhost:8888/j/test.tag.here;
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                $ curl -X POST -d 'json={"action":"login","user":2}' \
         | 
| 55 | 
            +
                    http://localhost:8888/test.tag.here;
         | 
| 56 | 
            +
             | 
| 57 | 
            +
            #### case 2
         | 
| 58 | 
            +
             | 
| 59 | 
            +
            resource
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                j or null
         | 
| 62 | 
            +
             | 
| 63 | 
            +
            header
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                Content-type: application/json
         | 
| 66 | 
            +
             | 
| 67 | 
            +
            body
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                <json data>
         | 
| 70 | 
            +
             | 
| 71 | 
            +
            sample
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                $ curl -X POST -H 'Content-Type: application/json' -d '{"action":"login","user":2}' \
         | 
| 74 | 
            +
                    http://localhost:8888/j/test.tag.here;
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                $ curl -X POST -H 'Content-Type: application/json' -d '{"action":"login","user":2}' \
         | 
| 77 | 
            +
                    http://localhost:8888/test.tag.here;
         | 
| 78 | 
            +
             | 
| 79 | 
            +
            ### json list
         | 
| 80 | 
            +
            #### case 1
         | 
| 81 | 
            +
             | 
| 82 | 
            +
            resource
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                js
         | 
| 85 | 
            +
             | 
| 86 | 
            +
            header
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                Content-type: application/x-www-form-urlencoded
         | 
| 89 | 
            +
             | 
| 90 | 
            +
            body
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                json=<json list data>
         | 
| 93 | 
            +
             | 
| 94 | 
            +
            sample
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                $ curl -X POST -d 'json=[{"action":"login","user":2},{"action":"login","user":2}]' \
         | 
| 97 | 
            +
                    http://localhost:8888/js/test.tag.here;
         | 
| 98 | 
            +
             | 
| 99 | 
            +
            #### case 2
         | 
| 100 | 
            +
             | 
| 101 | 
            +
            resource
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                js
         | 
| 104 | 
            +
             | 
| 105 | 
            +
            header
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                Content-type: application/json
         | 
| 108 | 
            +
             | 
| 109 | 
            +
            body
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                json=<json list data>
         | 
| 112 | 
            +
             | 
| 113 | 
            +
            sample
         | 
| 114 | 
            +
             | 
| 115 | 
            +
                $ curl -X POST -d '[{"action":"login","user":2},{"action":"login","user":2}]' \
         | 
| 116 | 
            +
                    http://localhost:8888/js/test.tag.here;
         | 
| 117 | 
            +
             | 
| 118 | 
            +
            ### msgpack
         | 
| 119 | 
            +
            #### case 1
         | 
| 120 | 
            +
             | 
| 121 | 
            +
            resource
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                m or null
         | 
| 124 | 
            +
             | 
| 125 | 
            +
            header
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                Content-type: application/x-www-form-urlencoded
         | 
| 128 | 
            +
             | 
| 129 | 
            +
            body
         | 
| 130 | 
            +
             | 
| 131 | 
            +
                msgpack=<hash msgpack data>
         | 
| 132 | 
            +
                         hash.to_msgpack
         | 
| 133 | 
            +
             | 
| 134 | 
            +
            #### case2
         | 
| 135 | 
            +
             | 
| 136 | 
            +
            resource
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                m or null
         | 
| 139 | 
            +
             | 
| 140 | 
            +
            header
         | 
| 141 | 
            +
             | 
| 142 | 
            +
                Content-type: application/x-msgpack
         | 
| 143 | 
            +
             | 
| 144 | 
            +
            body
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                <msgpack data>
         | 
| 147 | 
            +
                 hash.to_msgpack
         | 
| 148 | 
            +
             | 
| 149 | 
            +
            ### msgpack list
         | 
| 150 | 
            +
            #### case 1
         | 
| 151 | 
            +
             | 
| 152 | 
            +
            resource
         | 
| 153 | 
            +
             | 
| 154 | 
            +
                ms
         | 
| 155 | 
            +
             | 
| 156 | 
            +
            header
         | 
| 157 | 
            +
             | 
| 158 | 
            +
                Content-type: application/x-www-form-urlencoded
         | 
| 159 | 
            +
             | 
| 160 | 
            +
            body
         | 
| 161 | 
            +
             | 
| 162 | 
            +
                msgpack=<msgpack list data>
         | 
| 163 | 
            +
                         [hash,hash,hash].to_msgpack
         | 
| 164 | 
            +
             | 
| 165 | 
            +
            #### case 2
         | 
| 166 | 
            +
             | 
| 167 | 
            +
            resource
         | 
| 168 | 
            +
             | 
| 169 | 
            +
                ms
         | 
| 170 | 
            +
             | 
| 171 | 
            +
            header
         | 
| 172 | 
            +
             | 
| 173 | 
            +
                Content-type: application/x-msgpack
         | 
| 174 | 
            +
             | 
| 175 | 
            +
            body
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                msgpack=<msgpack list data>
         | 
| 178 | 
            +
                         [hash,hash,hash].to_msgpack
         | 
| 179 | 
            +
             | 
| 180 | 
            +
            ### msgpack chunked
         | 
| 181 | 
            +
             | 
| 182 | 
            +
            resource
         | 
| 183 | 
            +
             | 
| 184 | 
            +
                ms
         | 
| 185 | 
            +
             | 
| 186 | 
            +
            header
         | 
| 187 | 
            +
             | 
| 188 | 
            +
                Content-type: application/x-msgpack
         | 
| 189 | 
            +
                Transfer-Encoding: chunked
         | 
| 190 | 
            +
             | 
| 191 | 
            +
            body
         | 
| 192 | 
            +
             | 
| 193 | 
            +
                <msgpack chunk data>
         | 
| 194 | 
            +
                 "#{hash.to_msgpack}#{hash.to_msgpack}"...
         | 
| 195 | 
            +
             | 
| 196 | 
            +
             | 
| 197 | 
            +
            Each event in the list will be sent to your output plugins as an individual
         | 
| 198 | 
            +
            event. 
         | 
| 199 | 
            +
             | 
| 200 | 
            +
            ## Performance
         | 
| 201 | 
            +
             | 
| 202 | 
            +
            Comparison of in_http and in_http_ex.
         | 
| 203 | 
            +
            send 10,000 messages.
         | 
| 204 | 
            +
             | 
| 205 | 
            +
             | 
| 206 | 
            +
            machine spec
         | 
| 207 | 
            +
             | 
| 208 | 
            +
                Mac OS X 10.8.2
         | 
| 209 | 
            +
                1.8 GHz Intel Core i5
         | 
| 210 | 
            +
                8 GB 1600 MHz DDR3
         | 
| 211 | 
            +
             | 
| 212 | 
            +
            ### in_http
         | 
| 213 | 
            +
             | 
| 214 | 
            +
            json
         | 
| 215 | 
            +
             | 
| 216 | 
            +
                $ time ruby examples/json.rb
         | 
| 217 | 
            +
                
         | 
| 218 | 
            +
                real    2m27.480s
         | 
| 219 | 
            +
                user    0m7.252s
         | 
| 220 | 
            +
                sys     0m4.438s
         | 
| 221 | 
            +
             | 
| 222 | 
            +
            msgpack
         | 
| 223 | 
            +
             | 
| 224 | 
            +
                $ time ruby examples/msgpack.rb
         | 
| 225 | 
            +
                
         | 
| 226 | 
            +
                real    2m36.408s
         | 
| 227 | 
            +
                user    0m8.249s
         | 
| 228 | 
            +
                sys     0m4.441s
         | 
| 229 | 
            +
             | 
| 230 | 
            +
            ### in_http_ex
         | 
| 231 | 
            +
             | 
| 232 | 
            +
            json
         | 
| 233 | 
            +
             | 
| 234 | 
            +
                $ time ruby examples/json.rb
         | 
| 235 | 
            +
                
         | 
| 236 | 
            +
                real    2m30.639s
         | 
| 237 | 
            +
                user    0m7.195s
         | 
| 238 | 
            +
                sys     0m4.686s
         | 
| 239 | 
            +
             | 
| 240 | 
            +
            msgpack
         | 
| 241 | 
            +
             | 
| 242 | 
            +
                $ time ruby examples/msgpack.rb
         | 
| 243 | 
            +
                
         | 
| 244 | 
            +
                real    2m28.442s
         | 
| 245 | 
            +
                user    0m7.126s
         | 
| 246 | 
            +
                sys     0m4.324s
         | 
| 247 | 
            +
             | 
| 248 | 
            +
            json list
         | 
| 249 | 
            +
             | 
| 250 | 
            +
                $ time ruby examples/json_list.rb
         | 
| 251 | 
            +
                
         | 
| 252 | 
            +
                real    0m18.179s
         | 
| 253 | 
            +
                user    0m0.872s
         | 
| 254 | 
            +
                sys     0m0.477s
         | 
| 255 | 
            +
             | 
| 256 | 
            +
            msgpack list
         | 
| 257 | 
            +
             | 
| 258 | 
            +
                $ time ruby examples/msgpack_list.rb
         | 
| 259 | 
            +
                
         | 
| 260 | 
            +
                real    0m13.787s
         | 
| 261 | 
            +
                user    0m0.908s
         | 
| 262 | 
            +
                sys     0m0.470s
         | 
| 263 | 
            +
             | 
| 264 | 
            +
            msgpack chunked
         | 
| 265 | 
            +
             | 
| 266 | 
            +
                $ time ruby examples/nc_chunked.rb
         | 
| 267 | 
            +
                
         | 
| 268 | 
            +
                real    0m1.584s
         | 
| 269 | 
            +
                user    0m0.244s
         | 
| 270 | 
            +
                sys     0m0.107s
         | 
| 271 | 
            +
             | 
| 272 | 
            +
             | 
| 273 | 
            +
            ## Copyright
         | 
| 274 | 
            +
             | 
| 275 | 
            +
            Copyright (c) 2013 hiro-su.
         | 
| 276 | 
            +
             | 
| 277 | 
            +
            Based on the in_http plugin by FURUHASHI Sadayuki
         | 
| 278 | 
            +
             | 
| 279 | 
            +
             Apache License, Version 2.0
         | 
    
        data/Rakefile
    ADDED
    
    
    
        data/examples/chunked.rb
    ADDED
    
    | @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            require 'net/http'
         | 
| 2 | 
            +
            require 'stringio'
         | 
| 3 | 
            +
            require 'msgpack'
         | 
| 4 | 
            +
            require 'json'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            host, port = 'localhost', 8888
         | 
| 7 | 
            +
            path = "/ms/test.tag"
         | 
| 8 | 
            +
            http = Net::HTTP.new(host, port)
         | 
| 9 | 
            +
            req = Net::HTTP::Post.new(path)
         | 
| 10 | 
            +
            req[ "Content-Type" ] = 'application/x-msgpack'
         | 
| 11 | 
            +
            req[ "Transfer-Encoding" ] = "chunked"
         | 
| 12 | 
            +
            req[ "Connection" ] = "Keep-Alive"
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            io = StringIO.new
         | 
| 15 | 
            +
            DATA.each do |line|
         | 
| 16 | 
            +
              io << JSON.parse(line.chomp).to_msgpack
         | 
| 17 | 
            +
            end
         | 
| 18 | 
            +
            io.rewind
         | 
| 19 | 
            +
            req.body_stream = io
         | 
| 20 | 
            +
            http.request(req).body
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            __END__
         | 
| 23 | 
            +
            {"key1":"value1"}
         | 
| 24 | 
            +
            {"key2":"value2"}
         | 
| 25 | 
            +
            {"key3":"value3"}
         | 
| 26 | 
            +
            {"key4":"value4"}
         | 
| 27 | 
            +
            {"key5":"value5"}
         | 
    
        data/examples/json.rb
    ADDED
    
    | @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            require 'net/http'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # in_http
         | 
| 4 | 
            +
            #host, port = 'localhost', 7777
         | 
| 5 | 
            +
            #path = "/test.tag"
         | 
| 6 | 
            +
            #http = Net::HTTP.new(host, port)
         | 
| 7 | 
            +
            #req = Net::HTTP::Post.new(path)
         | 
| 8 | 
            +
            #req["Content-Type"] = "application/json"
         | 
| 9 | 
            +
            #1.upto(10000) do |i|
         | 
| 10 | 
            +
            #  req.body = "{\"key#{i}\":\"value#{i}\"}"
         | 
| 11 | 
            +
            #  http.request(req)
         | 
| 12 | 
            +
            #end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            # in_http_ex
         | 
| 15 | 
            +
            host, port = 'localhost', 8888
         | 
| 16 | 
            +
            path = "/j/test.tag"
         | 
| 17 | 
            +
            http = Net::HTTP.new(host, port)
         | 
| 18 | 
            +
            req = Net::HTTP::Post.new(path)
         | 
| 19 | 
            +
            req["Content-Type"] = "application/json"
         | 
| 20 | 
            +
            1.upto(10000) do |i|
         | 
| 21 | 
            +
              req.body = "{\"key#{i}\":\"value#{i}\"}"
         | 
| 22 | 
            +
              http.request(req)
         | 
| 23 | 
            +
            end
         | 
| @@ -0,0 +1,12 @@ | |
| 1 | 
            +
            require 'net/http'
         | 
| 2 | 
            +
            require 'msgpack'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            host, port = 'localhost', 8888
         | 
| 5 | 
            +
            path = "/js/test.tag"
         | 
| 6 | 
            +
            http = Net::HTTP.new(host, port)
         | 
| 7 | 
            +
            req = Net::HTTP::Post.new(path)
         | 
| 8 | 
            +
            req["Content-Type"] = "application/json"
         | 
| 9 | 
            +
            1.upto(1000) do |i|
         | 
| 10 | 
            +
              req.body = "[{\"key#{i}\":\"value#{i}\"},{\"key#{i}\":\"value#{i}\"},{\"key#{i}\":\"value#{i}\"},{\"key#{i}\":\"value#{i}\"},{\"key#{i}\":\"value#{i}\"},{\"key#{i}\":\"value#{i}\"},{\"key#{i}\":\"value#{i}\"},{\"key#{i}\":\"value#{i}\"},{\"key#{i}\":\"value#{i}\"},{\"key#{i}\":\"value#{i}\"}]"
         | 
| 11 | 
            +
              http.request(req)
         | 
| 12 | 
            +
            end
         | 
    
        data/examples/msgpack.rb
    ADDED
    
    | @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            require 'net/http'
         | 
| 2 | 
            +
            require 'msgpack'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            # in_http
         | 
| 5 | 
            +
            #host, port = 'localhost', 7777
         | 
| 6 | 
            +
            #path = "/test.tag"
         | 
| 7 | 
            +
            #http = Net::HTTP.new(host, port)
         | 
| 8 | 
            +
            #1.upto(10000) do |i|
         | 
| 9 | 
            +
            #  record = URI.encode_www_form({"msgpack"=>{"key#{i}"=>"value#{i}"}.to_msgpack})
         | 
| 10 | 
            +
            #  http.post(path, record)
         | 
| 11 | 
            +
            #end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            # in_http_ex
         | 
| 14 | 
            +
            host, port = 'localhost', 8888
         | 
| 15 | 
            +
            path = "/m/test.tag"
         | 
| 16 | 
            +
            http = Net::HTTP.new(host, port)
         | 
| 17 | 
            +
            req = Net::HTTP::Post.new(path)
         | 
| 18 | 
            +
            req["Content-Type"] = "application/x-msgpack"
         | 
| 19 | 
            +
            1.upto(10000) do |i|
         | 
| 20 | 
            +
              req.body = {"key#{i}"=>"value#{i}"}.to_msgpack
         | 
| 21 | 
            +
              http.request(req)
         | 
| 22 | 
            +
            end
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            require 'net/http'
         | 
| 2 | 
            +
            require 'msgpack'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            host, port = 'localhost', 8888
         | 
| 5 | 
            +
            path = "/ms/test.tag"
         | 
| 6 | 
            +
            http = Net::HTTP.new(host, port)
         | 
| 7 | 
            +
            req = Net::HTTP::Post.new(path)
         | 
| 8 | 
            +
            req["Content-Type"] = "application/x-msgpack"
         | 
| 9 | 
            +
            1.upto(1000) do |i|
         | 
| 10 | 
            +
              req.body = [
         | 
| 11 | 
            +
                {"key#{i}"=>"value#{i}"},
         | 
| 12 | 
            +
                {"key#{i}"=>"value#{i}"},
         | 
| 13 | 
            +
                {"key#{i}"=>"value#{i}"},
         | 
| 14 | 
            +
                {"key#{i}"=>"value#{i}"},
         | 
| 15 | 
            +
                {"key#{i}"=>"value#{i}"},
         | 
| 16 | 
            +
                {"key#{i}"=>"value#{i}"},
         | 
| 17 | 
            +
                {"key#{i}"=>"value#{i}"},
         | 
| 18 | 
            +
                {"key#{i}"=>"value#{i}"},
         | 
| 19 | 
            +
                {"key#{i}"=>"value#{i}"},
         | 
| 20 | 
            +
                {"key#{i}"=>"value#{i}"},
         | 
| 21 | 
            +
              ].to_msgpack
         | 
| 22 | 
            +
              http.request(req)
         | 
| 23 | 
            +
            end
         | 
| @@ -0,0 +1,44 @@ | |
| 1 | 
            +
            require 'open3'
         | 
| 2 | 
            +
            require 'msgpack'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class ChunkTest
         | 
| 5 | 
            +
              def initialize(host, port)
         | 
| 6 | 
            +
                @host = host
         | 
| 7 | 
            +
                @port = port
         | 
| 8 | 
            +
                @cmd = "nc"
         | 
| 9 | 
            +
                @term = false
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              def run
         | 
| 13 | 
            +
                Signal.trap(:INT){
         | 
| 14 | 
            +
                  @term = true
         | 
| 15 | 
            +
                }
         | 
| 16 | 
            +
                Open3.popen3("#{@cmd} #{@host} #{@port}") do |stdin, stdout, stderr, wait_thr|
         | 
| 17 | 
            +
                  begin
         | 
| 18 | 
            +
                    i = 0
         | 
| 19 | 
            +
                    loop do
         | 
| 20 | 
            +
                      break if @term
         | 
| 21 | 
            +
                      body = {"key#{i}"=>"value#{i}"}.to_msgpack
         | 
| 22 | 
            +
                      size = body.size
         | 
| 23 | 
            +
                      head = \
         | 
| 24 | 
            +
                        "POST /ms/test.tag HTTP/1.1\r\nUser-Agent: curl/7.28.0\r\nHost: #{@host}:#{@port}\r\nContent-type: application/x-msgpack\r\nTransfer-Encoding: chunked\r\nConnection: Keep-Alive\r\nExpect: 100-continue\r\n\r\n"
         | 
| 25 | 
            +
                      if i == 0
         | 
| 26 | 
            +
                        stdin << head
         | 
| 27 | 
            +
                      elsif i > 10000
         | 
| 28 | 
            +
                        stdin << "0\r\n\r\n"
         | 
| 29 | 
            +
                        break
         | 
| 30 | 
            +
                      else
         | 
| 31 | 
            +
                        chunk = "#{size.to_s(16)}\r\n#{body}\r\n"
         | 
| 32 | 
            +
                        stdin << chunk
         | 
| 33 | 
            +
                      end
         | 
| 34 | 
            +
                      i += 1
         | 
| 35 | 
            +
                    end
         | 
| 36 | 
            +
                  ensure
         | 
| 37 | 
            +
                    stdin.close
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
            end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            chunk = ChunkTest.new('localhost', 8888)
         | 
| 44 | 
            +
            chunk.run
         | 
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
            lib = File.expand_path('../lib', __FILE__)
         | 
| 3 | 
            +
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            Gem::Specification.new do |spec|
         | 
| 6 | 
            +
              spec.name          = "fluent-plugin-http-ex"
         | 
| 7 | 
            +
              spec.version       = "0.0.1"
         | 
| 8 | 
            +
              spec.authors       = ["hiro-su"]
         | 
| 9 | 
            +
              spec.email         = ["h.sugipon@gmail.com"]
         | 
| 10 | 
            +
              spec.description   = %q{fluent plugin to accept multiple json/msgpack events in HTTP request}
         | 
| 11 | 
            +
              spec.summary       = %q{fluent plugin to accept multiple json/msgpack events in HTTP request}
         | 
| 12 | 
            +
              spec.homepage      = "https://github.com/hiro-su/fluent-plugin-http-ex"
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              spec.files         = `git ls-files`.split($/)
         | 
| 15 | 
            +
              spec.executables   = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
         | 
| 16 | 
            +
              spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
         | 
| 17 | 
            +
              spec.require_paths = ["lib"]
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              spec.add_development_dependency "fluentd"
         | 
| 20 | 
            +
              spec.add_runtime_dependency "fluentd"
         | 
| 21 | 
            +
            end
         | 
| @@ -0,0 +1,252 @@ | |
| 1 | 
            +
            module Fluent
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class ExHttpInput < HttpInput
         | 
| 4 | 
            +
              Plugin.register_input('http_ex', self)
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              config_param :port, :integer, :default => 8888
         | 
| 7 | 
            +
              config_param :bind, :string, :default => '0.0.0.0'
         | 
| 8 | 
            +
              config_param :body_size_limit, :size, :default => 32*1024*1024
         | 
| 9 | 
            +
              config_param :keepalive_timeout, :time, :default => 30
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              class KeepaliveManager < Coolio::TimerWatcher
         | 
| 12 | 
            +
                class TimerValue
         | 
| 13 | 
            +
                  def initialize
         | 
| 14 | 
            +
                    @value = 0
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                  attr_accessor :value
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def initialize(timeout)
         | 
| 20 | 
            +
                  super(1, true)
         | 
| 21 | 
            +
                  @cons = {}
         | 
| 22 | 
            +
                  @timeout = timeout.to_i
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def add(sock)
         | 
| 26 | 
            +
                  @cons[sock] = sock
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def delete(sock)
         | 
| 30 | 
            +
                  @cons.delete(sock)
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                def on_timer
         | 
| 34 | 
            +
                  @cons.each_pair {|sock,val|
         | 
| 35 | 
            +
                    if sock.step_idle > @timeout
         | 
| 36 | 
            +
                      sock.close unless @timeout == 0
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
                  }
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
              def start
         | 
| 43 | 
            +
                $log.debug "listening http on #{@bind}:#{@port}"
         | 
| 44 | 
            +
                lsock = TCPServer.new(@bind, @port)
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                detach_multi_process do
         | 
| 47 | 
            +
                  Input.new.start
         | 
| 48 | 
            +
                  @km = KeepaliveManager.new(@keepalive_timeout)
         | 
| 49 | 
            +
                  @lsock = Coolio::TCPServer.new(lsock, nil, ExHandler, @km, method(:on_request), @body_size_limit)
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  @loop = Coolio::Loop.new
         | 
| 52 | 
            +
                  @loop.attach(@km)
         | 
| 53 | 
            +
                  @loop.attach(@lsock)
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  @thread = Thread.new(&method(:run))
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
              end
         | 
| 58 | 
            +
              
         | 
| 59 | 
            +
              def on_request(path_info, params)
         | 
| 60 | 
            +
                $log.debug "remote_addr: #{params["REMOTE_ADDR"]}, path_info: #{path_info}"
         | 
| 61 | 
            +
                begin
         | 
| 62 | 
            +
                  path = path_info[1..-1] # remove /
         | 
| 63 | 
            +
                  resource, tag = path.split('/')
         | 
| 64 | 
            +
                  tag ||= resource
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                  if chunk = params['chunked']
         | 
| 67 | 
            +
                    record = chunk 
         | 
| 68 | 
            +
                    
         | 
| 69 | 
            +
                  elsif js = params['json']
         | 
| 70 | 
            +
                    record = JSON.parse(js)
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                  elsif ms = params['x-msgpack'] || ms = params['msgpack']
         | 
| 73 | 
            +
                    record = MessagePack::unpack(ms)
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                  else
         | 
| 76 | 
            +
                    raise "'json' or 'msgpack' parameter is required"
         | 
| 77 | 
            +
                  end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                  time = params['time']
         | 
| 80 | 
            +
                  time = time.to_i
         | 
| 81 | 
            +
                  if time == 0
         | 
| 82 | 
            +
                    time = Engine.now
         | 
| 83 | 
            +
                  end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                rescue
         | 
| 86 | 
            +
                  return ["400 Bad Request", {'Content-type'=>'text/plain'}, "400 Bad Request\n#{$!}\n"]
         | 
| 87 | 
            +
                end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                # TODO server error
         | 
| 90 | 
            +
                begin
         | 
| 91 | 
            +
                  case params["resource"]
         | 
| 92 | 
            +
                  when :js
         | 
| 93 | 
            +
                    record.each do |v|
         | 
| 94 | 
            +
                      line = begin
         | 
| 95 | 
            +
                        JSON.parse(v)
         | 
| 96 | 
            +
                      rescue TypeError
         | 
| 97 | 
            +
                        v #hash
         | 
| 98 | 
            +
                      end
         | 
| 99 | 
            +
                      Engine.emit(tag, time, line)
         | 
| 100 | 
            +
                    end
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                  when :ms
         | 
| 103 | 
            +
                    record.each {|line| Engine.emit(tag, time, line) }
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                  else
         | 
| 106 | 
            +
                    Engine.emit(tag, time, record)
         | 
| 107 | 
            +
                  end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                rescue
         | 
| 110 | 
            +
                  return ["500 Internal Server Error", {'Content-type'=>'text/plain'}, "500 Internal Server Error\n#{$!}\n"]
         | 
| 111 | 
            +
                end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                return ["200 OK", {'Content-type'=>'text/plain'}, ""]
         | 
| 114 | 
            +
              end
         | 
| 115 | 
            +
             | 
| 116 | 
            +
              class ExHandler < Handler
         | 
| 117 | 
            +
                def on_close
         | 
| 118 | 
            +
                  $log.debug "close #{@remote_addr}:#{@remote_port}"
         | 
| 119 | 
            +
                  super
         | 
| 120 | 
            +
                end
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                def on_headers_complete(headers)
         | 
| 123 | 
            +
                  expect = nil
         | 
| 124 | 
            +
                  size = nil
         | 
| 125 | 
            +
                  if @parser.http_version == [1, 1]
         | 
| 126 | 
            +
                    @keep_alive = true
         | 
| 127 | 
            +
                  else
         | 
| 128 | 
            +
                    @keep_alive = false
         | 
| 129 | 
            +
                  end
         | 
| 130 | 
            +
                  @env = {}
         | 
| 131 | 
            +
                  headers.each_pair {|k,v|
         | 
| 132 | 
            +
                    @env["HTTP_#{k.gsub('-','_').upcase}"] = v
         | 
| 133 | 
            +
                    case k
         | 
| 134 | 
            +
                    when /Expect/i
         | 
| 135 | 
            +
                      expect = v
         | 
| 136 | 
            +
                    when /Content-Length/i
         | 
| 137 | 
            +
                      size = v.to_i
         | 
| 138 | 
            +
                    when /Content-Type/i
         | 
| 139 | 
            +
                      @content_type = v
         | 
| 140 | 
            +
                    when /Connection/i
         | 
| 141 | 
            +
                      if v =~ /close/i
         | 
| 142 | 
            +
                        @keep_alive = false
         | 
| 143 | 
            +
                      elsif v =~ /Keep-alive/i
         | 
| 144 | 
            +
                        @keep_alive = true
         | 
| 145 | 
            +
                      end
         | 
| 146 | 
            +
                    when /Transfer-Encoding/i
         | 
| 147 | 
            +
                      if v =~ /chunked/i
         | 
| 148 | 
            +
                        @chunked = true
         | 
| 149 | 
            +
                      end
         | 
| 150 | 
            +
                    end
         | 
| 151 | 
            +
                  }
         | 
| 152 | 
            +
                  if expect
         | 
| 153 | 
            +
                    if expect == '100-continue'
         | 
| 154 | 
            +
                      if !size || size < @body_size_limit
         | 
| 155 | 
            +
                        send_response_nobody("100 Continue", {})
         | 
| 156 | 
            +
                      else
         | 
| 157 | 
            +
                        send_response_and_close("413 Request Entity Too Large", {}, "Too large")
         | 
| 158 | 
            +
                      end
         | 
| 159 | 
            +
                    else
         | 
| 160 | 
            +
                      send_response_and_close("417 Expectation Failed", {}, "")
         | 
| 161 | 
            +
                    end
         | 
| 162 | 
            +
                  end
         | 
| 163 | 
            +
                end
         | 
| 164 | 
            +
             | 
| 165 | 
            +
                def on_body(chunk)
         | 
| 166 | 
            +
                  if @chunked && @content_type =~ /application\/x-msgpack/i
         | 
| 167 | 
            +
                    m = method(:on_read_msgpack)
         | 
| 168 | 
            +
                    @u = MessagePack::Unpacker.new
         | 
| 169 | 
            +
                    (class << self; self; end).module_eval do
         | 
| 170 | 
            +
                      define_method(:on_body, m)
         | 
| 171 | 
            +
                    end
         | 
| 172 | 
            +
                    m.call(chunk)
         | 
| 173 | 
            +
                  else
         | 
| 174 | 
            +
                    if @body.bytesize + chunk.bytesize > @body_size_limit
         | 
| 175 | 
            +
                      unless closing?
         | 
| 176 | 
            +
                        send_response_and_close("413 Request Entity Too Large", {}, "Too large")
         | 
| 177 | 
            +
                      end
         | 
| 178 | 
            +
                      return
         | 
| 179 | 
            +
                    end
         | 
| 180 | 
            +
                    @body << chunk
         | 
| 181 | 
            +
                  end
         | 
| 182 | 
            +
                end
         | 
| 183 | 
            +
             | 
| 184 | 
            +
                def on_read_msgpack(data)
         | 
| 185 | 
            +
                  params = WEBrick::HTTPUtils.parse_query(@parser.query_string)
         | 
| 186 | 
            +
                  path_info = @parser.request_path
         | 
| 187 | 
            +
                  @u.feed_each(data) do |obj|
         | 
| 188 | 
            +
                    params["chunked"] = obj
         | 
| 189 | 
            +
                    params["REMOTE_ADDR"] = @remote_addr
         | 
| 190 | 
            +
                    @callback.call(path_info, params)
         | 
| 191 | 
            +
                  end
         | 
| 192 | 
            +
                rescue
         | 
| 193 | 
            +
                  $log.error "on_read_msgpack error: #{$!.to_s}"
         | 
| 194 | 
            +
                  $log.error_backtrace
         | 
| 195 | 
            +
                  close
         | 
| 196 | 
            +
                end
         | 
| 197 | 
            +
             | 
| 198 | 
            +
                def on_message_complete
         | 
| 199 | 
            +
                  return if closing?
         | 
| 200 | 
            +
             | 
| 201 | 
            +
                  @env['REMOTE_ADDR'] = @remote_addr
         | 
| 202 | 
            +
             | 
| 203 | 
            +
                  params = WEBrick::HTTPUtils.parse_query(@parser.query_string)
         | 
| 204 | 
            +
                  path_info = @parser.request_path
         | 
| 205 | 
            +
             | 
| 206 | 
            +
                  params = check_content_type(params, @content_type, @body, path_info)
         | 
| 207 | 
            +
                  params.merge!(@env)
         | 
| 208 | 
            +
                  @env.clear
         | 
| 209 | 
            +
             | 
| 210 | 
            +
                  unless @chunked
         | 
| 211 | 
            +
                    code, header, body = *@callback.call(path_info, params)
         | 
| 212 | 
            +
                    body = body.to_s
         | 
| 213 | 
            +
             | 
| 214 | 
            +
                    if @keep_alive
         | 
| 215 | 
            +
                      header['Connection'] = 'Keep-Alive'
         | 
| 216 | 
            +
                      send_response(code, header, body)
         | 
| 217 | 
            +
                    else
         | 
| 218 | 
            +
                      send_response_and_close(code, header, body)
         | 
| 219 | 
            +
                    end
         | 
| 220 | 
            +
                  else
         | 
| 221 | 
            +
                    send_response("200 OK", {'Content-type'=>'text/plain', 'Connection'=>'Keep-Alive'}, "")
         | 
| 222 | 
            +
                  end
         | 
| 223 | 
            +
                end
         | 
| 224 | 
            +
             | 
| 225 | 
            +
                def check_content_type(params, content_type, body, path_info)
         | 
| 226 | 
            +
                  path = path_info[1..-1] # remove /
         | 
| 227 | 
            +
                  resource, _ = path.split('/')
         | 
| 228 | 
            +
                  case resource
         | 
| 229 | 
            +
                  when /^js$/
         | 
| 230 | 
            +
                    params["resource"] = :js
         | 
| 231 | 
            +
                  when /^ms$/
         | 
| 232 | 
            +
                    params["resource"] = :ms
         | 
| 233 | 
            +
                  end
         | 
| 234 | 
            +
             | 
| 235 | 
            +
                  if content_type =~ /^application\/x-www-form-urlencoded/
         | 
| 236 | 
            +
                    params.update WEBrick::HTTPUtils.parse_query(body)
         | 
| 237 | 
            +
                  elsif content_type =~ /^multipart\/form-data; boundary=(.+)/
         | 
| 238 | 
            +
                    boundary = WEBrick::HTTPUtils.dequote($1)
         | 
| 239 | 
            +
                    params.update WEBrick::HTTPUtils.parse_form_data(body, boundary)
         | 
| 240 | 
            +
                  elsif content_type =~ /^application\/(json|x-msgpack)/
         | 
| 241 | 
            +
                    params[$1] = body
         | 
| 242 | 
            +
                  end
         | 
| 243 | 
            +
             | 
| 244 | 
            +
                  params
         | 
| 245 | 
            +
                rescue => ex
         | 
| 246 | 
            +
                  $log.error ex
         | 
| 247 | 
            +
                  $log.error ex.backtrace * "\n"
         | 
| 248 | 
            +
                end
         | 
| 249 | 
            +
              end
         | 
| 250 | 
            +
            end
         | 
| 251 | 
            +
             | 
| 252 | 
            +
            end
         | 
    
        data/test/helper.rb
    ADDED
    
    | @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            require 'test/unit'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
         | 
| 4 | 
            +
            $LOAD_PATH.unshift(File.dirname(__FILE__))
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            require 'fluent/test'
         | 
| 7 | 
            +
            require 'in_http_ex_test'
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            unless ENV.has_key?('VERBOSE')
         | 
| 10 | 
            +
              nulllogger = Object.new
         | 
| 11 | 
            +
              nulllogger.instance_eval {|obj|
         | 
| 12 | 
            +
                def method_missing(method, *args)
         | 
| 13 | 
            +
                  # pass
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              }
         | 
| 16 | 
            +
              $log = nulllogger
         | 
| 17 | 
            +
            end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            require 'fluent/plugin/in_http'
         | 
| 20 | 
            +
            require 'fluent/plugin/in_http_ex'
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            class Test::Unit::TestCase
         | 
| 23 | 
            +
            end
         | 
| @@ -0,0 +1,100 @@ | |
| 1 | 
            +
            #
         | 
| 2 | 
            +
            # Fluent
         | 
| 3 | 
            +
            #
         | 
| 4 | 
            +
            # Copyright (C) 2011 FURUHASHI Sadayuki
         | 
| 5 | 
            +
            #
         | 
| 6 | 
            +
            #    Licensed under the Apache License, Version 2.0 (the "License");
         | 
| 7 | 
            +
            #    you may not use this file except in compliance with the License.
         | 
| 8 | 
            +
            #    You may obtain a copy of the License at
         | 
| 9 | 
            +
            #
         | 
| 10 | 
            +
            #        http://www.apache.org/licenses/LICENSE-2.0
         | 
| 11 | 
            +
            #
         | 
| 12 | 
            +
            #    Unless required by applicable law or agreed to in writing, software
         | 
| 13 | 
            +
            #    distributed under the License is distributed on an "AS IS" BASIS,
         | 
| 14 | 
            +
            #    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         | 
| 15 | 
            +
            #    See the License for the specific language governing permissions and
         | 
| 16 | 
            +
            #    limitations under the License.
         | 
| 17 | 
            +
            #
         | 
| 18 | 
            +
            module Fluent
         | 
| 19 | 
            +
            module Test
         | 
| 20 | 
            +
             | 
| 21 | 
            +
             | 
| 22 | 
            +
            class ExHttpInputTestDriver < TestDriver
         | 
| 23 | 
            +
              def initialize(klass, &block)
         | 
| 24 | 
            +
                super(klass, &block)
         | 
| 25 | 
            +
                @emit_streams = []
         | 
| 26 | 
            +
                @expects = nil
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              def expect_emit(tag, time, record)
         | 
| 30 | 
            +
                (@expects ||= []) << [tag, time, record]
         | 
| 31 | 
            +
                self
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              def expected_emits
         | 
| 35 | 
            +
                @expects ||= []
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              attr_reader :emit_streams
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              def emits
         | 
| 41 | 
            +
                all = []
         | 
| 42 | 
            +
                @emit_streams.each {|tag,events|
         | 
| 43 | 
            +
                  events.each {|time,record|
         | 
| 44 | 
            +
                    all << [tag, time, record]
         | 
| 45 | 
            +
                  }
         | 
| 46 | 
            +
                }
         | 
| 47 | 
            +
                all
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              def events
         | 
| 51 | 
            +
                all = []
         | 
| 52 | 
            +
                @emit_streams.each {|tag,events|
         | 
| 53 | 
            +
                  all.concat events
         | 
| 54 | 
            +
                }
         | 
| 55 | 
            +
                all
         | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
              def records
         | 
| 59 | 
            +
                all = []
         | 
| 60 | 
            +
                @emit_streams.each {|tag,events|
         | 
| 61 | 
            +
                  events.each {|time,record|
         | 
| 62 | 
            +
                    all << record
         | 
| 63 | 
            +
                  }
         | 
| 64 | 
            +
                }
         | 
| 65 | 
            +
                all
         | 
| 66 | 
            +
              end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
              def run(&block)
         | 
| 69 | 
            +
                m = method(:emit_stream)
         | 
| 70 | 
            +
                super {
         | 
| 71 | 
            +
                  Engine.define_singleton_method(:emit_stream) {|tag,es|
         | 
| 72 | 
            +
                    m.call(tag, es)
         | 
| 73 | 
            +
                  }
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                  block.call if block
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                  if @expects && @emit_streams.size < 2
         | 
| 78 | 
            +
                    i = 0
         | 
| 79 | 
            +
                    @emit_streams.each {|tag,events|
         | 
| 80 | 
            +
                      events.each {|time,record|
         | 
| 81 | 
            +
                        assert_equal(@expects[i], [tag, time, record])
         | 
| 82 | 
            +
                      }
         | 
| 83 | 
            +
                    }
         | 
| 84 | 
            +
                    assert_equal @expects.length, i
         | 
| 85 | 
            +
                  elsif @expects
         | 
| 86 | 
            +
                    return [@expects, @emit_streams]
         | 
| 87 | 
            +
                  end
         | 
| 88 | 
            +
                }
         | 
| 89 | 
            +
                self
         | 
| 90 | 
            +
              end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
              private
         | 
| 93 | 
            +
              def emit_stream(tag, es)
         | 
| 94 | 
            +
                @emit_streams << [tag, es.to_a]
         | 
| 95 | 
            +
              end
         | 
| 96 | 
            +
            end
         | 
| 97 | 
            +
             | 
| 98 | 
            +
             | 
| 99 | 
            +
            end
         | 
| 100 | 
            +
            end
         | 
| @@ -0,0 +1,347 @@ | |
| 1 | 
            +
            require 'helper'
         | 
| 2 | 
            +
            require 'net/http'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class ExHttpInputTest < Test::Unit::TestCase
         | 
| 5 | 
            +
              def setup
         | 
| 6 | 
            +
                Fluent::Test.setup
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              CONFIG = %[
         | 
| 10 | 
            +
            port 9911
         | 
| 11 | 
            +
            bind 127.0.0.1
         | 
| 12 | 
            +
            body_size_limit 10m
         | 
| 13 | 
            +
            keepalive_timeout 5
         | 
| 14 | 
            +
            ]
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              def create_driver(conf=CONFIG)
         | 
| 17 | 
            +
                Fluent::Test::ExHttpInputTestDriver.new(Fluent::ExHttpInput).configure(conf)
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              def test_configure
         | 
| 21 | 
            +
                d = create_driver
         | 
| 22 | 
            +
                assert_equal 9911, d.instance.port
         | 
| 23 | 
            +
                assert_equal '127.0.0.1', d.instance.bind
         | 
| 24 | 
            +
                assert_equal 10*1024*1024, d.instance.body_size_limit
         | 
| 25 | 
            +
                assert_equal 5, d.instance.keepalive_timeout
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              def test_time
         | 
| 29 | 
            +
                d = create_driver
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                time = Time.parse("2011-01-02 13:14:15 UTC").to_i
         | 
| 32 | 
            +
                Fluent::Engine.now = time
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                d.expect_emit "tag1", time, {"a"=>1}
         | 
| 35 | 
            +
                d.expect_emit "tag2", time, {"a"=>2}
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                d.run do
         | 
| 38 | 
            +
                  d.expected_emits.each {|tag,time,record|
         | 
| 39 | 
            +
                    res = post("/#{tag}", {"json"=>record.to_json})
         | 
| 40 | 
            +
                    assert_equal "200", res.code
         | 
| 41 | 
            +
                  }
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
              def test_json
         | 
| 46 | 
            +
                d = create_driver
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                time = Time.parse("2011-01-02 13:14:15 UTC").to_i
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                d.expect_emit "tag1", time, {"a"=>1}
         | 
| 51 | 
            +
                d.expect_emit "tag2", time, {"a"=>2}
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                d.run do
         | 
| 54 | 
            +
                  d.expected_emits.each {|tag,time,record|
         | 
| 55 | 
            +
                    res = post("/#{tag}", {"json"=>record.to_json, "time"=>time.to_s})
         | 
| 56 | 
            +
                    assert_equal "200", res.code
         | 
| 57 | 
            +
                  }
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
              end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
              def test_application_json
         | 
| 62 | 
            +
                d = create_driver
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                time = Time.parse("2011-01-02 13:14:15 UTC").to_i
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                d.expect_emit "tag1", time, {"a"=>1}
         | 
| 67 | 
            +
                d.expect_emit "tag2", time, {"a"=>2}
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                d.run do
         | 
| 70 | 
            +
                  d.expected_emits.each {|tag,time,record|
         | 
| 71 | 
            +
                    http = Net::HTTP.new("127.0.0.1", 9911)
         | 
| 72 | 
            +
                    req = Net::HTTP::Post.new("/#{tag}?time=#{time.to_s}", {"content-type"=>"application/json; charset=utf-8"})
         | 
| 73 | 
            +
                    req.body = record.to_json
         | 
| 74 | 
            +
                    res = http.request(req)
         | 
| 75 | 
            +
                    assert_equal "200", res.code
         | 
| 76 | 
            +
                  }
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
              end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
              def test_resource_json
         | 
| 81 | 
            +
                d = create_driver
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                time = Time.parse("2011-01-02 13:14:15 UTC").to_i
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                d.expect_emit "tag1", time, {"a"=>1}
         | 
| 86 | 
            +
                d.expect_emit "tag2", time, {"a"=>2}
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                d.run do
         | 
| 89 | 
            +
                  d.expected_emits.each {|tag,time,record|
         | 
| 90 | 
            +
                    res = post("/j/#{tag}", {"json"=>record.to_json, "time"=>time.to_s})
         | 
| 91 | 
            +
                    assert_equal "200", res.code
         | 
| 92 | 
            +
                  }
         | 
| 93 | 
            +
                end
         | 
| 94 | 
            +
              end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
              def test_application_resource_json
         | 
| 97 | 
            +
                d = create_driver
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                time = Time.parse("2011-01-02 13:14:15 UTC").to_i
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                d.expect_emit "tag1", time, {"a"=>1}
         | 
| 102 | 
            +
                d.expect_emit "tag2", time, {"a"=>2}
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                d.run do
         | 
| 105 | 
            +
                  d.expected_emits.each {|tag,time,record|
         | 
| 106 | 
            +
                    http = Net::HTTP.new("127.0.0.1", 9911)
         | 
| 107 | 
            +
                    req = Net::HTTP::Post.new("/j/#{tag}?time=#{time.to_s}", {"content-type"=>"application/json; charset=utf-8"})
         | 
| 108 | 
            +
                    req.body = record.to_json
         | 
| 109 | 
            +
                    res = http.request(req)
         | 
| 110 | 
            +
                    assert_equal "200", res.code
         | 
| 111 | 
            +
                  }
         | 
| 112 | 
            +
                end
         | 
| 113 | 
            +
              end
         | 
| 114 | 
            +
             | 
| 115 | 
            +
              def test_resource_json_list
         | 
| 116 | 
            +
                d = create_driver
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                time = Time.parse("2011-01-02 13:14:15 UTC").to_i
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                d.expect_emit "tag1", time, {"a"=>1}
         | 
| 121 | 
            +
                d.expect_emit "tag2", time, {"a"=>2}
         | 
| 122 | 
            +
                d.expect_emit "tag3", time, {"a"=>3}
         | 
| 123 | 
            +
                
         | 
| 124 | 
            +
                rs = d.run do
         | 
| 125 | 
            +
                  d.expected_emits.each {|tag,time,record|
         | 
| 126 | 
            +
                    res = post("/js/#{tag}", {"json"=>"[#{record.to_json},#{record.to_json},#{record.to_json}]", "time"=>time.to_s})
         | 
| 127 | 
            +
                    assert_equal "200", res.code
         | 
| 128 | 
            +
                  }
         | 
| 129 | 
            +
                end
         | 
| 130 | 
            +
             | 
| 131 | 
            +
                expects, results = rs
         | 
| 132 | 
            +
                i, c = 0, 0
         | 
| 133 | 
            +
                results.each {|tag,es|
         | 
| 134 | 
            +
                  es.each {|time,record|
         | 
| 135 | 
            +
                    assert_equal(expects[i], [tag, time, record])
         | 
| 136 | 
            +
                    c += 1
         | 
| 137 | 
            +
                    i += 1 if c % 3 == 0
         | 
| 138 | 
            +
                  }
         | 
| 139 | 
            +
                }
         | 
| 140 | 
            +
              end
         | 
| 141 | 
            +
             | 
| 142 | 
            +
              def test_application_resource_json_list
         | 
| 143 | 
            +
                d = create_driver
         | 
| 144 | 
            +
             | 
| 145 | 
            +
                time = Time.parse("2011-01-02 13:14:15 UTC").to_i
         | 
| 146 | 
            +
             | 
| 147 | 
            +
                d.expect_emit "tag1", time, {"a"=>1}
         | 
| 148 | 
            +
                d.expect_emit "tag2", time, {"a"=>2}
         | 
| 149 | 
            +
                d.expect_emit "tag3", time, {"a"=>3}
         | 
| 150 | 
            +
             | 
| 151 | 
            +
                rs = d.run do
         | 
| 152 | 
            +
                  d.expected_emits.each {|tag,time,record|
         | 
| 153 | 
            +
                    http = Net::HTTP.new("127.0.0.1", 9911)
         | 
| 154 | 
            +
                    req = Net::HTTP::Post.new("/js/#{tag}?time=#{time.to_s}", {"content-type"=>"application/json; charset=utf-8"})
         | 
| 155 | 
            +
                    req.body = "[#{record.to_json},#{record.to_json},#{record.to_json}]"
         | 
| 156 | 
            +
                    res = http.request(req)
         | 
| 157 | 
            +
                    assert_equal "200", res.code
         | 
| 158 | 
            +
                  }
         | 
| 159 | 
            +
                end
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                expects, results = rs
         | 
| 162 | 
            +
                i, c = 0, 0
         | 
| 163 | 
            +
                results.each {|tag,es|
         | 
| 164 | 
            +
                  es.each {|time,record|
         | 
| 165 | 
            +
                    assert_equal(expects[i], [tag, time, record])
         | 
| 166 | 
            +
                    c += 1
         | 
| 167 | 
            +
                    i += 1 if c % 3 == 0
         | 
| 168 | 
            +
                  }
         | 
| 169 | 
            +
                }
         | 
| 170 | 
            +
              end
         | 
| 171 | 
            +
             | 
| 172 | 
            +
              def test_msgpack
         | 
| 173 | 
            +
                d = create_driver
         | 
| 174 | 
            +
             | 
| 175 | 
            +
                time = Time.parse("2011-01-02 13:14:15 UTC").to_i
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                d.expect_emit "tag1", time, {"a"=>1}
         | 
| 178 | 
            +
                d.expect_emit "tag2", time, {"a"=>2}
         | 
| 179 | 
            +
             | 
| 180 | 
            +
                d.run do
         | 
| 181 | 
            +
                  d.expected_emits.each {|tag,time,record|
         | 
| 182 | 
            +
                    res = post("/#{tag}", {"msgpack"=>record.to_msgpack, "time"=>time.to_s})
         | 
| 183 | 
            +
                    assert_equal "200", res.code
         | 
| 184 | 
            +
                  }
         | 
| 185 | 
            +
                end
         | 
| 186 | 
            +
              end
         | 
| 187 | 
            +
             | 
| 188 | 
            +
              def test_application_msgpack
         | 
| 189 | 
            +
                d = create_driver
         | 
| 190 | 
            +
             | 
| 191 | 
            +
                time = Time.parse("2011-01-02 13:14:15 UTC").to_i
         | 
| 192 | 
            +
             | 
| 193 | 
            +
                d.expect_emit "tag1", time, {"a"=>1}
         | 
| 194 | 
            +
                d.expect_emit "tag2", time, {"a"=>2}
         | 
| 195 | 
            +
             | 
| 196 | 
            +
                d.run do
         | 
| 197 | 
            +
                  d.expected_emits.each {|tag,time,record|
         | 
| 198 | 
            +
                    http = Net::HTTP.new("127.0.0.1", 9911)
         | 
| 199 | 
            +
                    req = Net::HTTP::Post.new("/#{tag}?time=#{time.to_s}", {"content-type"=>"application/x-msgpack; charset=utf-8"})
         | 
| 200 | 
            +
                    req.body = record.to_msgpack
         | 
| 201 | 
            +
                    res = http.request(req)
         | 
| 202 | 
            +
                    assert_equal "200", res.code
         | 
| 203 | 
            +
                  }
         | 
| 204 | 
            +
                end
         | 
| 205 | 
            +
              end
         | 
| 206 | 
            +
             | 
| 207 | 
            +
              def test_resource_msgpack
         | 
| 208 | 
            +
                d = create_driver
         | 
| 209 | 
            +
             | 
| 210 | 
            +
                time = Time.parse("2011-01-02 13:14:15 UTC").to_i
         | 
| 211 | 
            +
             | 
| 212 | 
            +
                d.expect_emit "tag1", time, {"a"=>1}
         | 
| 213 | 
            +
                d.expect_emit "tag2", time, {"a"=>2}
         | 
| 214 | 
            +
             | 
| 215 | 
            +
                d.run do
         | 
| 216 | 
            +
                  d.expected_emits.each {|tag,time,record|
         | 
| 217 | 
            +
                    res = post("/m/#{tag}", {"msgpack"=>record.to_msgpack, "time"=>time.to_s})
         | 
| 218 | 
            +
                    assert_equal "200", res.code
         | 
| 219 | 
            +
                  }
         | 
| 220 | 
            +
                end
         | 
| 221 | 
            +
              end
         | 
| 222 | 
            +
             | 
| 223 | 
            +
              def test_application_resource_msgpack
         | 
| 224 | 
            +
                d = create_driver
         | 
| 225 | 
            +
             | 
| 226 | 
            +
                time = Time.parse("2011-01-02 13:14:15 UTC").to_i
         | 
| 227 | 
            +
             | 
| 228 | 
            +
                d.expect_emit "tag1", time, {"a"=>1}
         | 
| 229 | 
            +
                d.expect_emit "tag2", time, {"a"=>2}
         | 
| 230 | 
            +
             | 
| 231 | 
            +
                d.run do
         | 
| 232 | 
            +
                  d.expected_emits.each {|tag,time,record|
         | 
| 233 | 
            +
                    http = Net::HTTP.new("127.0.0.1", 9911)
         | 
| 234 | 
            +
                    req = Net::HTTP::Post.new("/m/#{tag}?time=#{time.to_s}", {"content-type"=>"application/x-msgpack; charset=utf-8"})
         | 
| 235 | 
            +
                    req.body = record.to_msgpack
         | 
| 236 | 
            +
                    res = http.request(req)
         | 
| 237 | 
            +
                    assert_equal "200", res.code
         | 
| 238 | 
            +
                  }
         | 
| 239 | 
            +
                end
         | 
| 240 | 
            +
              end
         | 
| 241 | 
            +
             | 
| 242 | 
            +
              def test_resource_msgpack_list
         | 
| 243 | 
            +
                d = create_driver
         | 
| 244 | 
            +
             | 
| 245 | 
            +
                time = Time.parse("2011-01-02 13:14:15 UTC").to_i
         | 
| 246 | 
            +
             | 
| 247 | 
            +
                d.expect_emit "tag1", time, {"a"=>1}
         | 
| 248 | 
            +
                d.expect_emit "tag2", time, {"a"=>2}
         | 
| 249 | 
            +
                d.expect_emit "tag3", time, {"a"=>3}
         | 
| 250 | 
            +
                
         | 
| 251 | 
            +
                rs = d.run do
         | 
| 252 | 
            +
                  d.expected_emits.each {|tag,time,record|
         | 
| 253 | 
            +
                    res = post("/ms/#{tag}", {"msgpack"=>[record,record,record].to_msgpack, "time"=>time.to_s})
         | 
| 254 | 
            +
                    assert_equal "200", res.code
         | 
| 255 | 
            +
                  }
         | 
| 256 | 
            +
                end
         | 
| 257 | 
            +
             | 
| 258 | 
            +
                expects, results = rs
         | 
| 259 | 
            +
                i, c = 0, 0
         | 
| 260 | 
            +
                results.each {|tag,es|
         | 
| 261 | 
            +
                  es.each {|time,record|
         | 
| 262 | 
            +
                    assert_equal(expects[i], [tag, time, record])
         | 
| 263 | 
            +
                    c += 1
         | 
| 264 | 
            +
                    i += 1 if c % 3 == 0
         | 
| 265 | 
            +
                  }
         | 
| 266 | 
            +
                }
         | 
| 267 | 
            +
              end
         | 
| 268 | 
            +
             | 
| 269 | 
            +
              def test_application_resource_msgpack_list
         | 
| 270 | 
            +
                d = create_driver
         | 
| 271 | 
            +
             | 
| 272 | 
            +
                time = Time.parse("2011-01-02 13:14:15 UTC").to_i
         | 
| 273 | 
            +
             | 
| 274 | 
            +
                d.expect_emit "tag1", time, {"a"=>1}
         | 
| 275 | 
            +
                d.expect_emit "tag2", time, {"a"=>2}
         | 
| 276 | 
            +
                d.expect_emit "tag3", time, {"a"=>3}
         | 
| 277 | 
            +
             | 
| 278 | 
            +
                rs = d.run do
         | 
| 279 | 
            +
                  d.expected_emits.each {|tag,time,record|
         | 
| 280 | 
            +
                    http = Net::HTTP.new("127.0.0.1", 9911)
         | 
| 281 | 
            +
                    req = Net::HTTP::Post.new("/ms/#{tag}?time=#{time.to_s}", {"content-type"=>"application/x-msgpack; charset=utf-8"})
         | 
| 282 | 
            +
                    req.body = [record,record,record].to_msgpack
         | 
| 283 | 
            +
                    res = http.request(req)
         | 
| 284 | 
            +
                    assert_equal "200", res.code
         | 
| 285 | 
            +
                  }
         | 
| 286 | 
            +
                end
         | 
| 287 | 
            +
             | 
| 288 | 
            +
                expects, results = rs
         | 
| 289 | 
            +
                i, c = 0, 0
         | 
| 290 | 
            +
                results.each {|tag,es|
         | 
| 291 | 
            +
                  es.each {|time,record|
         | 
| 292 | 
            +
                    assert_equal(expects[i], [tag, time, record])
         | 
| 293 | 
            +
                    c += 1
         | 
| 294 | 
            +
                    i += 1 if c % 3 == 0
         | 
| 295 | 
            +
                  }
         | 
| 296 | 
            +
                }
         | 
| 297 | 
            +
              end
         | 
| 298 | 
            +
             | 
| 299 | 
            +
              def test_msgpack_chunked
         | 
| 300 | 
            +
                require 'stringio'
         | 
| 301 | 
            +
             | 
| 302 | 
            +
                d = create_driver
         | 
| 303 | 
            +
             | 
| 304 | 
            +
                time = Time.parse("2011-01-02 13:14:15 UTC").to_i
         | 
| 305 | 
            +
             | 
| 306 | 
            +
                d.expect_emit "tag1", time, {"a"=>1}
         | 
| 307 | 
            +
                d.expect_emit "tag1", time, {"a"=>2}
         | 
| 308 | 
            +
                d.expect_emit "tag1", time, {"a"=>3}
         | 
| 309 | 
            +
             | 
| 310 | 
            +
                http = Net::HTTP.new("127.0.0.1", 9911)
         | 
| 311 | 
            +
             | 
| 312 | 
            +
                rs = d.run do
         | 
| 313 | 
            +
                  io = StringIO.new
         | 
| 314 | 
            +
                  req = ""
         | 
| 315 | 
            +
                  d.expected_emits.each {|tag,time,record|
         | 
| 316 | 
            +
                    req = Net::HTTP::Post.new("/ms/#{tag}?time=#{time.to_s}")
         | 
| 317 | 
            +
                    req["Content-Type"] = "application/x-msgpack"
         | 
| 318 | 
            +
                    req["Transfer-Encoding"] = "chunked"
         | 
| 319 | 
            +
                    io << record.to_msgpack
         | 
| 320 | 
            +
                    io << record.to_msgpack
         | 
| 321 | 
            +
                    io << record.to_msgpack
         | 
| 322 | 
            +
                  }
         | 
| 323 | 
            +
                  io.rewind
         | 
| 324 | 
            +
                  req.body_stream = io
         | 
| 325 | 
            +
                  res = http.request(req)
         | 
| 326 | 
            +
                  assert_equal "200", res.code
         | 
| 327 | 
            +
                end
         | 
| 328 | 
            +
             | 
| 329 | 
            +
                expects, results = rs
         | 
| 330 | 
            +
                i, c = 0, 0
         | 
| 331 | 
            +
                results.each {|tag,es|
         | 
| 332 | 
            +
                  es.each {|time,record|
         | 
| 333 | 
            +
                    assert_equal(expects[i], [tag, time, record])
         | 
| 334 | 
            +
                    c += 1
         | 
| 335 | 
            +
                    i += 1 if c % 3 == 0
         | 
| 336 | 
            +
                  }
         | 
| 337 | 
            +
                }
         | 
| 338 | 
            +
              end
         | 
| 339 | 
            +
             | 
| 340 | 
            +
              def post(path, params)
         | 
| 341 | 
            +
                http = Net::HTTP.new("127.0.0.1", 9911)
         | 
| 342 | 
            +
                req = Net::HTTP::Post.new(path, {})
         | 
| 343 | 
            +
                req.set_form_data(params)
         | 
| 344 | 
            +
                http.request(req)
         | 
| 345 | 
            +
              end
         | 
| 346 | 
            +
             | 
| 347 | 
            +
            end
         | 
    
        metadata
    ADDED
    
    | @@ -0,0 +1,91 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification
         | 
| 2 | 
            +
            name: fluent-plugin-http-ex
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: 0.0.1
         | 
| 5 | 
            +
            platform: ruby
         | 
| 6 | 
            +
            authors:
         | 
| 7 | 
            +
            - hiro-su
         | 
| 8 | 
            +
            autorequire: 
         | 
| 9 | 
            +
            bindir: bin
         | 
| 10 | 
            +
            cert_chain: []
         | 
| 11 | 
            +
            date: 2013-08-07 00:00:00.000000000 Z
         | 
| 12 | 
            +
            dependencies:
         | 
| 13 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            +
              name: fluentd
         | 
| 15 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 | 
            +
                requirements:
         | 
| 17 | 
            +
                - - ! '>='
         | 
| 18 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            +
                    version: '0'
         | 
| 20 | 
            +
              type: :development
         | 
| 21 | 
            +
              prerelease: false
         | 
| 22 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 | 
            +
                requirements:
         | 
| 24 | 
            +
                - - ! '>='
         | 
| 25 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            +
                    version: '0'
         | 
| 27 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 28 | 
            +
              name: fluentd
         | 
| 29 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 | 
            +
                requirements:
         | 
| 31 | 
            +
                - - ! '>='
         | 
| 32 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            +
                    version: '0'
         | 
| 34 | 
            +
              type: :runtime
         | 
| 35 | 
            +
              prerelease: false
         | 
| 36 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 | 
            +
                requirements:
         | 
| 38 | 
            +
                - - ! '>='
         | 
| 39 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            +
                    version: '0'
         | 
| 41 | 
            +
            description: fluent plugin to accept multiple json/msgpack events in HTTP request
         | 
| 42 | 
            +
            email:
         | 
| 43 | 
            +
            - h.sugipon@gmail.com
         | 
| 44 | 
            +
            executables: []
         | 
| 45 | 
            +
            extensions: []
         | 
| 46 | 
            +
            extra_rdoc_files: []
         | 
| 47 | 
            +
            files:
         | 
| 48 | 
            +
            - .gitignore
         | 
| 49 | 
            +
            - Gemfile
         | 
| 50 | 
            +
            - LICENSE.txt
         | 
| 51 | 
            +
            - README.md
         | 
| 52 | 
            +
            - Rakefile
         | 
| 53 | 
            +
            - examples/chunked.rb
         | 
| 54 | 
            +
            - examples/json.rb
         | 
| 55 | 
            +
            - examples/json_list.rb
         | 
| 56 | 
            +
            - examples/msgpack.rb
         | 
| 57 | 
            +
            - examples/msgpack_list.rb
         | 
| 58 | 
            +
            - examples/nc_chunked.rb
         | 
| 59 | 
            +
            - examples/sample.conf
         | 
| 60 | 
            +
            - fluent-plugin-http-ex.gemspec
         | 
| 61 | 
            +
            - lib/fluent/plugin/in_http_ex.rb
         | 
| 62 | 
            +
            - test/helper.rb
         | 
| 63 | 
            +
            - test/in_http_ex_test.rb
         | 
| 64 | 
            +
            - test/plugin/test_in_http_ex.rb
         | 
| 65 | 
            +
            homepage: https://github.com/hiro-su/fluent-plugin-http-ex
         | 
| 66 | 
            +
            licenses: []
         | 
| 67 | 
            +
            metadata: {}
         | 
| 68 | 
            +
            post_install_message: 
         | 
| 69 | 
            +
            rdoc_options: []
         | 
| 70 | 
            +
            require_paths:
         | 
| 71 | 
            +
            - lib
         | 
| 72 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 73 | 
            +
              requirements:
         | 
| 74 | 
            +
              - - ! '>='
         | 
| 75 | 
            +
                - !ruby/object:Gem::Version
         | 
| 76 | 
            +
                  version: '0'
         | 
| 77 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 78 | 
            +
              requirements:
         | 
| 79 | 
            +
              - - ! '>='
         | 
| 80 | 
            +
                - !ruby/object:Gem::Version
         | 
| 81 | 
            +
                  version: '0'
         | 
| 82 | 
            +
            requirements: []
         | 
| 83 | 
            +
            rubyforge_project: 
         | 
| 84 | 
            +
            rubygems_version: 2.0.3
         | 
| 85 | 
            +
            signing_key: 
         | 
| 86 | 
            +
            specification_version: 4
         | 
| 87 | 
            +
            summary: fluent plugin to accept multiple json/msgpack events in HTTP request
         | 
| 88 | 
            +
            test_files:
         | 
| 89 | 
            +
            - test/helper.rb
         | 
| 90 | 
            +
            - test/in_http_ex_test.rb
         | 
| 91 | 
            +
            - test/plugin/test_in_http_ex.rb
         |