Skip to content
This repository has been archived by the owner on Dec 7, 2018. It is now read-only.

New Features : Session Handler and Multipart Parser #233

Open
wants to merge 120 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
120 commits
Select commit Hold shift + click to select a range
1fa7c99
initial structure to visulize working(need refactoring)
pulkit4tech May 29, 2016
ddf813b
small tweak: corrected mixin module name
pulkit4tech May 30, 2016
602c952
added method linking (config,initialize,finalize ..)
pulkit4tech May 30, 2016
cc52519
Merge pull request #1 from pulkit4tech/gsoc16
May 30, 2016
9b112ff
corrected required gem path celluloid/extras/hash
pulkit4tech May 31, 2016
76e6adf
Merge pull request #2 from pulkit4tech/gsoc16
May 31, 2016
872f978
added default config,initial work on intializing session
pulkit4tech May 31, 2016
6ed23a1
Basic Session handling api, corrected namespaces ..
pulkit4tech Jun 3, 2016
5f2504c
removed sessions folder (keeping singular namespace)
pulkit4tech Jun 3, 2016
c3e0522
Merge pull request #3 from pulkit4tech/gsoc16
Jun 3, 2016
0ba6138
using celluloid essentials uuid to generate uuid
pulkit4tech Jun 5, 2016
668f9ef
added initial crypto code
pulkit4tech Jun 5, 2016
edd9463
Merge pull request #4 from pulkit4tech/gsoc16
Jun 6, 2016
86ffa2b
applying encryption/decryption
pulkit4tech Jun 6, 2016
a9282f7
looking possibile way to integrate Session Handler into Reel
pulkit4tech Jun 7, 2016
c3e6622
include request mixin when 'reel/session' required
kenichi Jun 8, 2016
4ef1a76
Merge pull request #5 from kenichi/request_mixin_inclusion
Jun 8, 2016
15d2fbe
change init session behavior
kenichi Jun 8, 2016
e85b9af
alias/wrap Request#respond to finalize session first
kenichi Jun 8, 2016
404d9b8
Merge pull request #6 from kenichi/init_session
Jun 9, 2016
1b77c79
Merge pull request #7 from kenichi/finalize_session
Jun 9, 2016
8f4822d
Merge pull request #8 from pulkit4tech/integration
Jun 9, 2016
e526717
added crypto configuration
pulkit4tech Jun 9, 2016
6a0d253
merge cookie-header properly in finalizing session
pulkit4tech Jun 9, 2016
4df25a0
some minor tweak
pulkit4tech Jun 9, 2016
947c214
filled up save method
pulkit4tech Jun 9, 2016
de41f29
Some tweaks (correction on configuration method,decrypt method)
pulkit4tech Jun 10, 2016
3666fe8
Merge pull request #9 from pulkit4tech/gsoc16
Jun 10, 2016
ad31451
added/updated some TODO things, commented on some bugs to be solved
pulkit4tech Jun 10, 2016
2b6942c
not storing/setting cookie for empty hash
pulkit4tech Jun 13, 2016
febf563
temporarily removing crypto
pulkit4tech Jun 13, 2016
b8d41df
added some check (to remove some bug)
pulkit4tech Jun 13, 2016
d82ea90
added session_spec (incomplete)
pulkit4tech Jun 13, 2016
49c4860
removed uneccessary test
Jun 14, 2016
6ee09ff
improved session test spec
pulkit4tech Jun 14, 2016
4865543
added some more session test spec
pulkit4tech Jun 14, 2016
b4f2c2d
added working crypto encoding (need verification)
pulkit4tech Jun 14, 2016
2061130
Merge pull request #12 from celluloid/master
Jun 15, 2016
fc0a376
Merge pull request #11 from celluloid/master
Jun 15, 2016
ec4967e
some code refactoring
pulkit4tech Jun 16, 2016
4932bab
added utc in session expiry time (Chrome issue)
pulkit4tech Jun 16, 2016
2905675
corrected two times initialization of @cookie_header
pulkit4tech Jun 16, 2016
33d5e8e
added spec related to escaping unsafe character,encrypt/decrypt
pulkit4tech Jun 16, 2016
8006932
updated comments,TODO's and spec improvement
pulkit4tech Jun 16, 2016
e7377ad
made encrypt/decrypt test more appropriate
pulkit4tech Jun 18, 2016
601fc7e
updated way of assigning key,iv => issue: encrypt/decrypt correctly e…
pulkit4tech Jun 18, 2016
b6c9e70
Code Refactoring
pulkit4tech Jun 20, 2016
0180159
added code to delete entry from concurrent hash(need review)
pulkit4tech Jun 20, 2016
bc910f7
Merge pull request #13 from celluloid/master
Jun 21, 2016
7dbc343
added initial tweak for configuration logic
pulkit4tech Jun 21, 2016
b3e8e39
updated deleting_timer logic to make it work
pulkit4tech Jun 22, 2016
dd3e8c0
Merge pull request #14 from pulkit4tech/gsoc16
Jun 22, 2016
7efd6f0
updated Parser patching way to solve connection_spec pipelined reques…
pulkit4tech Jun 24, 2016
fc288d0
merging and resolving conflict from tweaking_configuration
pulkit4tech Jun 21, 2016
0d9a93b
using updated configuration logic
pulkit4tech Jun 24, 2016
209de06
refactored deleting timers
pulkit4tech Jun 24, 2016
c2f2609
refactored deleting timers
pulkit4tech Jun 24, 2016
5b4c6d1
Final Parser patching logic with a small tweak
pulkit4tech Jun 25, 2016
43337d3
merged from pulkit4tech/reel/final_session
pulkit4tech Jun 25, 2016
4788b63
Using server reactor to call after block for deleting session
pulkit4tech Jun 25, 2016
9630f9b
Merge branch 'deleting_session' into tweaking_configuration
pulkit4tech Jun 25, 2016
8d77626
improvement in configuration logic
pulkit4tech Jun 25, 2016
408b142
informing: No header set if uuid is nil(session has no value)
pulkit4tech Jun 27, 2016
a086f5e
some small code refactoring
pulkit4tech Jun 28, 2016
1367379
improved escaping character test (using encrypt from crypto.rb)
pulkit4tech Jun 28, 2016
bc82e18
added deleting timer test (need review)
pulkit4tech Jun 28, 2016
0193fe5
Solved randomly failing deleting timer test (problem => @config was c…
pulkit4tech Jun 28, 2016
54ef175
Merge pull request #18 from pulkit4tech/improving_test
Jun 29, 2016
100ffcb
updated spec and code refactoring
pulkit4tech Jun 29, 2016
15e4f87
changed crypto logic => also send config with value
pulkit4tech Jun 30, 2016
3fb3463
added header error if uuid is nil in Reel Session
pulkit4tech Jun 30, 2016
3f2ba56
corrected/improved failing/slow specs
pulkit4tech Jun 30, 2016
208d5ab
removed header error (this condition will probably never be achieved)
pulkit4tech Jun 30, 2016
8300cf8
small tweaks
pulkit4tech Jun 30, 2016
783b1f5
Merge pull request #19 from pulkit4tech/header_error
Jun 30, 2016
5fc60fa
added test for Session configurations hashes for different mock server
pulkit4tech Jun 30, 2016
887d5ba
Merge pull request #17 from pulkit4tech/tweaking_configuration
Jun 30, 2016
b326052
Merge pull request #20 from pulkit4tech/deleting_session
Jun 30, 2016
e03bf3e
overriding server constructor for to get session config value
pulkit4tech Jul 2, 2016
6629f4b
Merge pull request #21 from pulkit4tech/session_config
Jul 2, 2016
bf32a77
Added few basic Session examples
pulkit4tech Jul 4, 2016
b80a7a9
Removed crypto and updated related test (performance issue)
pulkit4tech Jul 6, 2016
15faae9
Merge pull request #22 from pulkit4tech/examples
Jul 7, 2016
5fabff8
Merge pull request #15 from pulkit4tech/final_sessions
Jul 7, 2016
88d5257
Merge pull request #24 from pulkit4tech/gsoc16
Jul 9, 2016
3f24608
Added intial skeleton for multipart
pulkit4tech Jul 9, 2016
a67f075
filled "multipart?"
pulkit4tech Jul 9, 2016
e6b2d2a
added intialize code(TODO) and decoding/writing multipart body code
pulkit4tech Jul 11, 2016
722d509
refactoring as per code convention
pulkit4tech Jul 11, 2016
1249f28
Warning error with stacktrace instead of informing
pulkit4tech Jul 14, 2016
4f57734
Configured callback to add parsed data into @files
pulkit4tech Jul 16, 2016
c244973
removed unnecessary require
pulkit4tech Jul 18, 2016
5f5caa0
Merge pull request #26 from pulkit4tech/gsoc16
Jul 18, 2016
ea30885
Merge pull request #27 from pulkit4tech/gsoc16
Jul 18, 2016
8ab2d9e
Added some spec related to multipart
pulkit4tech Jul 18, 2016
75cb165
Added :part in our parsed hash to get header and other information
pulkit4tech Jul 19, 2016
127dda2
Added test related to image upload
pulkit4tech Jul 20, 2016
fce8e46
minor code refactoring
pulkit4tech Jul 21, 2016
8fc8592
Added test for parsing error due to wrong boundary value
pulkit4tech Jul 25, 2016
55c5b5f
Added test for parsing data from file upload (missing file name from …
pulkit4tech Jul 25, 2016
c1313c8
Refactoring test
pulkit4tech Jul 26, 2016
3897c8b
Added test to parse file containing semicolon in filename
pulkit4tech Jul 26, 2016
0d3f75b
Added more test and some minor refactoring
pulkit4tech Jul 26, 2016
ed5eea0
replaced `:ended` to `:on_complete`
pulkit4tech Jul 27, 2016
dcafc4c
Using Tempfile in :data and updated test accordingly
pulkit4tech Aug 2, 2016
fd07665
minor refactoring
pulkit4tech Aug 3, 2016
87fdb96
added reel_session_pool example
pulkit4tech Aug 4, 2016
3ced31f
Merge pull request #31 from pulkit4tech/session_example
Aug 4, 2016
544bb47
exposing :multipart? as api without body parameter + updated spec acc…
pulkit4tech Aug 5, 2016
c7b5863
Tempfile : closed => rewind (:data)
pulkit4tech Aug 5, 2016
e63d31e
Replaced :on_complete => :complete
pulkit4tech Aug 5, 2016
2c47e7d
Merge pull request #32 from pulkit4tech/final_sessions
Aug 7, 2016
268aaa8
Updated multipart spec pattern
pulkit4tech Aug 7, 2016
720befe
Merge pull request #33 from pulkit4tech/multipart_spec_pattern
Aug 8, 2016
f0de4ae
Refactored multipart spec + other minor refactoring
pulkit4tech Aug 9, 2016
05cb8d5
Added simple multipart example
pulkit4tech Aug 13, 2016
3bcdf0f
added some comments
pulkit4tech Aug 13, 2016
9f1f852
added runtime dependency for multipart-parser
pulkit4tech Aug 18, 2016
31a94e0
Merge pull request #25 from pulkit4tech/multipart-0.0.1
pulkit4tech Aug 30, 2016
0e4a0df
Different :data for File type(Tempfile object) and non file type(norm…
pulkit4tech Sep 30, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ source 'https://rubygems.org'
gem 'celluloid'
gem 'celluloid-io'
gem 'http'
gem 'multipart-parser', '~> 0.1.1'

gem 'jruby-openssl' if defined? JRUBY_VERSION
gem 'coveralls', require: false
Expand Down
44 changes: 44 additions & 0 deletions examples/custom_session.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/usr/bin/env ruby
# Run with: bundle exec ruby examples/custom_session.rb

require 'rubygems'
require 'bundler/setup'
require 'reel'

require 'reel/session'

puts "*** Starting server on http://127.0.0.1:4567"

# All Session config parameter are optional (default parameter value will be used)
session_config1= {:session_length=>86400,:session_name=>'basic',:secret_key=>'secret'} # session_length = 24hr
Reel::Server::HTTP.new('127.0.0.1', 4567, {:session=>session_config1}) do |connection|
connection.each_request do |request|
# Session value can access using request.session
if request.session[:hi]
puts ":hi found in session: '#{request.session[:hi]}'"
else
request.session[:hi] = 'hello'
end
request.respond :ok, "hello, world!\n"
end

end

puts "*** Starting server on http://127.0.0.1:4568"

# All Session config parameter are optional (default parameter value will be used)
session_config2 = {:session_length=>300,:session_name=>'basic',:secret_key=>'secret'} # session_length = 5min
Reel::Server::HTTP.new('127.0.0.1', 4568, {:session=>session_config2}) do |connection|
connection.each_request do |request|
# Session value can access using request.session
if request.session[:bye]
puts ":bye found in session: '#{request.session[:bye]}'"
else
request.session[:bye] = 'bye'
end
request.respond :ok, "later, world!\n"
end

end

sleep
25 changes: 25 additions & 0 deletions examples/hello_world_multipart.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env ruby
# Run with: bundle exec examples/hello_world_multipart.rb

require 'rubygems'
require 'bundler/setup'
require 'reel'
require 'reel/request/multipart'

addr, port = '127.0.0.1', 1234

puts "*** Starting server on http://#{addr}:#{port}"
Reel::Server::HTTP.run(addr, port) do |connection|
connection.each_request do |request|
if request.multipart?
request.multipart.each do |key,val|
puts File.read(val[:data])
end
request.respond :ok, "Hello world!! Got multipart post!!"
else
request.respond 400, "Expecting Multipart Request!!"
end

end

end
31 changes: 31 additions & 0 deletions examples/hello_world_session.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env ruby
# Run with: bundle exec examples/hello_world_session.rb

require 'rubygems'
require 'bundler/setup'
require 'reel'

require 'reel/session'

addr, port = '127.0.0.1', 1234

puts "*** Starting server with default session config on http://#{addr}:#{port}"
Reel::Server::HTTP.run(addr, port) do |connection|
# For keep-alive support
connection.each_request do |request|
# Ordinarily we'd route the request here, e.g.
# route request.url
# Session value can access using request.session
if request.session[:user_id]
puts "found user: #{request.session[:user_id]}"
else
request.session[:user_id] = "temp"
end
# Updated Session value will be stored in store at response
request.respond :ok, "hello, world!"
end

# Reel takes care of closing the connection for you
# If you would like to hand the connection off to another thread or actor,
# use, connection.detach and then manually call connection.close when done
end
56 changes: 56 additions & 0 deletions examples/multithreaded_reel_with_session.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env ruby
# Run with: bundle exec ruby examples/multithreaded_reel_with_session.rb

require 'rubygems'
require 'bundler/setup'
require 'reel'

require 'reel/session'

class MyConnectionHandler
include Celluloid

def initialize(connection)
@connection = connection
async.run
rescue Reel::SocketError
@connection.close
end

def run
@connection.each_request { |req| handle_request(req) }
end

def handle_request(request)
# Session value can access using request.session
if request.session[:user_id]
puts "found user: #{request.session[:user_id]}"
else
request.session[:user_id] = "temp"
end
request.respond :ok,"hello world!!"
end
end

# Just adding custom session length of 10 sec
session_config = {:session_length=>10}

puts "*** Starting server with custom session on http://127.0.0.1:3000"
Reel::Server::HTTP.new('127.0.0.1', 3000, {:session=>session_config}) do |connection|
# We're handing this connection off to another actor, so
# we detach it first before handing it off
connection.detach

MyConnectionHandler.new(connection)
end

puts "*** Starting server with default session on http://127.0.0.1:3001"
Reel::Server::HTTP.new('127.0.0.1', 3001) do |connection|
# We're handing this connection off to another actor, so
# we detach it first before handing it off
connection.detach

MyConnectionHandler.new(connection)
end

sleep
39 changes: 39 additions & 0 deletions examples/reel_pool_session.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
require 'bundler/setup'
require 'reel'
require 'celluloid/autostart'

require 'reel/session'

class MyConnectionHandler
include Celluloid

def handle_connection(connection)
connection.each_request { |req| handle_request(req) }
rescue Reel::SocketError
connection.close
end

def handle_request(request)
# Session value can access using request.session
if request.session[:user_id]
puts "found user: #{request.session[:user_id]}"
else
request.session[:user_id] = "temp"
end
request.respond :ok,"hello world!!"
end
end

connectionPool = MyConnectionHandler.pool

# Just adding custom session length of 10 sec
session_config = {:session_length=>10}

Reel::Server::HTTP.run('127.0.0.1', 1234, {:session=>session_config}) do |connection|
# We're handing this connection off to another actor, so
# we detach it first before handing it off
connection.detach

# Let a Connection Pool handle the connections for Roflscale Applications
connectionPool.async.handle_connection(connection)
end
1 change: 1 addition & 0 deletions lib/reel.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,5 @@ class UnsupportedMethodError < ArgumentError; end

# wrong state for a given operation
class StateError < RuntimeError; end

end
5 changes: 3 additions & 2 deletions lib/reel/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@ class Connection

# Attempt to read this much data
BUFFER_SIZE = 16384
attr_reader :buffer_size
attr_reader :buffer_size, :server

def initialize(socket, buffer_size = nil)
def initialize(socket, buffer_size = nil, server = nil)
@attached = true
@socket = socket
@keepalive = true
@buffer_size = buffer_size || BUFFER_SIZE
@server = server
@parser = Request::Parser.new(self)
@request_fsm = Request::StateMachine.new(@socket)

Expand Down
4 changes: 2 additions & 2 deletions lib/reel/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Request

def_delegators :@connection, :remote_addr, :respond
def_delegator :@response_writer, :handle_response
attr_reader :body
attr_reader :body, :connection

# request_info is a RequestInfo object including the headers and
# the url, method and http version.
Expand Down Expand Up @@ -112,7 +112,7 @@ def websocket?; @request_info.websocket_request?; end
# the underlying connection
def websocket
@websocket ||= begin
raise StateError, "can't upgrade this request to a websocket" unless websocket?
raise StateError, "can't upgrade this request to a websocket" unless websocket?
WebSocket.new(self, @connection)
end
end
Expand Down
96 changes: 96 additions & 0 deletions lib/reel/request/multipart.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
require 'multipart_parser/parser'
require 'multipart_parser/reader'
require 'tempfile'

module Reel
class Request
include Celluloid::Internals::Logger

CONTENT_TYPE = 'Content-Type'.freeze

# if multipart type
# return Hash :
# {
# key1 => {
# :data => Tempfile object,
# :complete => true/false,
# :part => part object (header info etc)
# },
# key2 => {...}
# }
# if not multipart type
# return nil
def multipart
@multipart.decode if multipart?
end

# utility function to check if Content-Type is a multipart type
# and initializing @multipart
def multipart?
return @multipart.is_a? Reel::Request::Multipart if @multipart
# extract boundary
boundary = extract_boundary self.headers[CONTENT_TYPE]
# initializing Multipart
@multipart = Reel::Request::Multipart.new @body, boundary if boundary
@multipart.is_a? Reel::Request::Multipart
rescue => e
warn e
@multipart = false
end

def extract_boundary(content)
MultipartParser::Reader.extract_boundary_value content
end

class Multipart
extend Forwardable

def initialize(body, boundary)
@files = {}
@body = body
@boundary = boundary
@reader = MultipartParser::Reader.new(@boundary)

# configuring MultipartParser::Reader
@reader.on_part do |part|
# Streaming API So each file blob will contain information
# regarding: data,part (for header and other information) and complete
if part.filename
blob = {:data => Tempfile.new(part.filename), :complete => false, :part => part }
else
blob = {:data => "", :complete => false, :part => part}
end
# adding file blob associating it with part.name
@files[part.name] = blob

# registering callback
part.on_data { |data_chunk| blob[:data] << data_chunk }
part.on_end do
blob[:complete] = true
blob[:data].rewind if blob[:data].is_a? Tempfile
#TODO : expose part information if needed

end
end

@reader.on_error{|msg| warn msg }

end

def_delegators :@reader, :write

def decode
return @files if @files.any?
begin
@body.each { |chunks| write chunks }
rescue => e
warn e
@files = {}
end
@files
end

end

end
end
1 change: 1 addition & 0 deletions lib/reel/request/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ def on_headers_complete(headers)

if @currently_reading
@pending_reads << req
req
else
@currently_reading = req
end
Expand Down
2 changes: 1 addition & 1 deletion lib/reel/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def handle_connection(socket)
socket = Reel::Spy.new(socket, @spy)
end

connection = Connection.new(socket)
connection = Connection.new(socket, nil, self)

begin
@callback.call(connection)
Expand Down
Loading