php_session 0.3.1 → 0.4.0
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 +4 -4
- data/.travis.yml +1 -0
- data/README.md +82 -23
- data/lib/php_session.rb +28 -36
- data/lib/php_session/errors.rb +3 -2
- data/lib/php_session/store_engine/file.rb +55 -0
- data/lib/php_session/version.rb +1 -1
- data/php_session.gemspec +1 -1
- data/spec/php_session_spec.rb +13 -9
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b7b87e7c1e025ed1df45430687998b0f60dacc50
|
4
|
+
data.tar.gz: 2daeb3db468fe3c91db723e2da73d44ac678571b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce3e5b3099257ae86f80dc68b459994d003a95f38ea3e627242237b02947d7769bed8c822dd8dc84b22789a8e93234f3ebb97f7030c569320dcb7474faffa9fe
|
7
|
+
data.tar.gz: 684cc95377949741e0d8d9e642caa77288cac2bfc673d8954e123afa237d7437209578479132ea926c9ed17292ae36bb03518725c861bab90f2b0811ac8bd1bc
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -3,7 +3,9 @@
|
|
3
3
|
[](https://codeclimate.com/github/Shinpeim/ruby_php_session)
|
4
4
|
|
5
5
|
## Description
|
6
|
-
PHPSession is a php session
|
6
|
+
PHPSession is a php session reader/writer.
|
7
|
+
|
8
|
+
### Mapping between ruby and PHP
|
7
9
|
|
8
10
|
When decoding php session data to ruby objects,
|
9
11
|
|
@@ -17,6 +19,56 @@ When encoding ruby objects to php session data,
|
|
17
19
|
* Arrays in ruby is mapped to a associative arrays which's keys are integer in PHP.
|
18
20
|
* Hashes in ruby is mapped to a associative arrays which's keys are string in PHP.
|
19
21
|
|
22
|
+
### Session store engines are pluggable
|
23
|
+
|
24
|
+
By default, PHPSession use file session store, which is compatible with PHP session file.
|
25
|
+
|
26
|
+
You can use your own session store like bellow.
|
27
|
+
|
28
|
+
First, develop your own store_engine.
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
# lib_path/php_session/store_engine/custom.rb
|
32
|
+
class PHPSession
|
33
|
+
module StoreEngine
|
34
|
+
class File
|
35
|
+
def initialize(option)
|
36
|
+
# option passed to PHPSession constractor
|
37
|
+
@option = option
|
38
|
+
end
|
39
|
+
|
40
|
+
def load(session_id)
|
41
|
+
# load php-style serialized session data from your favorite storage
|
42
|
+
# and return that
|
43
|
+
end
|
44
|
+
|
45
|
+
def save(session_id, serialized_session)
|
46
|
+
# save php-style serialized session data to your favorite storage
|
47
|
+
end
|
48
|
+
|
49
|
+
def destroy(session_id)
|
50
|
+
# delete session_data from your favorite storage
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# register store engine name and store engine class
|
57
|
+
PHPSession.register_store_engine(:custom, PHPSession::StoreEngine::Custom)
|
58
|
+
```
|
59
|
+
|
60
|
+
And then, assingn engine name to option[:store_engine] passed to PHPSession constractor
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
option = {
|
64
|
+
:external_encoding => "EUC-JP",
|
65
|
+
:internal_encoding => "UTF-8",
|
66
|
+
:encoding_option => {:undef => :replace},
|
67
|
+
:session_file_dir => @session_file[:dir_name],
|
68
|
+
}
|
69
|
+
session = PHPSession.new(option)
|
70
|
+
```
|
71
|
+
|
20
72
|
### Multibyte support
|
21
73
|
|
22
74
|
Passing option to PHPSession.new, you can handle encodings.
|
@@ -61,28 +113,35 @@ Or install it yourself as:
|
|
61
113
|
$ gem install php_session
|
62
114
|
|
63
115
|
## Usage
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
116
|
+
```ruby
|
117
|
+
# initialize
|
118
|
+
option = {
|
119
|
+
:internal_encoding => "UTF-8", # value will be decoded as UTF-8
|
120
|
+
:external_encoding => "EUC-JP", # encoding of sesion file is EUC-JP
|
121
|
+
:encoding_option => {:undef => :replace} # passed to String#encode
|
122
|
+
|
123
|
+
:store_engine => :file,
|
124
|
+
:session_file_dir => "/path/to/session_file_dir" # needed when the store_engine is :file
|
125
|
+
}
|
126
|
+
# option's default values are
|
127
|
+
# :internal_encoding => Encoding.default_internal_encoding
|
128
|
+
# :external_encoding => Encoding.default_external_encoding
|
129
|
+
# :encoding_option => {}
|
130
|
+
# :store_engine => :file,
|
131
|
+
|
132
|
+
session = PHPSession.new(option)
|
133
|
+
|
134
|
+
# load session data
|
135
|
+
data = session.load(session_id)
|
136
|
+
|
137
|
+
data.is_a? Hash # => true
|
138
|
+
|
139
|
+
# save session
|
140
|
+
session.commit(session_id, data)
|
141
|
+
|
142
|
+
# delete session
|
143
|
+
session.destroy(session_id)
|
144
|
+
```
|
86
145
|
|
87
146
|
## Contributing
|
88
147
|
|
data/lib/php_session.rb
CHANGED
@@ -3,59 +3,51 @@ require "php_session/version"
|
|
3
3
|
require "php_session/errors"
|
4
4
|
require "php_session/decoder"
|
5
5
|
require "php_session/encoder"
|
6
|
+
require "php_session/store_engine/file"
|
6
7
|
|
7
8
|
class PHPSession
|
8
9
|
attr_reader :data
|
9
|
-
|
10
|
+
|
11
|
+
def self.register_store_engine(engine_name, klass)
|
12
|
+
@engines ||= {}
|
13
|
+
@engines[engine_name] = klass
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.store_engine_class_of(engine_name)
|
17
|
+
store_engine = @engines[engine_name]
|
18
|
+
raise PHPSession::Errors, "unknown sotre engine: #{engine_name}" unless store_engine
|
19
|
+
|
20
|
+
store_engine
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(option = {})
|
10
24
|
default_option = {
|
25
|
+
:store_engine => :file,
|
26
|
+
|
11
27
|
:internal_encoding => Encoding.default_internal,
|
12
28
|
:external_encoding => Encoding.default_external,
|
13
29
|
:encoding_option => {},
|
14
30
|
}
|
15
31
|
@option = default_option.merge(option)
|
16
|
-
|
32
|
+
|
33
|
+
store_engine_class = self.class.store_engine_class_of(@option[:store_engine])
|
34
|
+
|
35
|
+
@store_engine = store_engine_class.new(@option)
|
17
36
|
end
|
18
37
|
|
19
38
|
def load(session_id)
|
20
|
-
|
21
|
-
|
22
|
-
f.set_encoding(@option[:external_encoding], nil)
|
23
|
-
Decoder.decode(f.read, @option[:internal_encoding], @option[:encoding_option]) || {}
|
24
|
-
end
|
39
|
+
serialized_session = @store_engine.load(session_id)
|
40
|
+
Decoder.decode(serialized_session, @option[:internal_encoding], @option[:encoding_option]) || {}
|
25
41
|
end
|
26
42
|
|
27
43
|
def destroy(session_id)
|
28
|
-
|
29
|
-
rescue Errno::ENOENT => e
|
30
|
-
# file already deleted
|
44
|
+
@store_engine.destroy(session_id)
|
31
45
|
end
|
32
46
|
|
33
47
|
def save(session_id, data)
|
34
|
-
|
35
|
-
|
36
|
-
f.write(Encoder.encode(data, @option[:external_encoding], @option[:encoding_option]))
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
def with_lock(file_path)
|
43
|
-
File.open(file_path, File::CREAT|File::RDWR) do |f|
|
44
|
-
unless f.flock(File::LOCK_EX)
|
45
|
-
raise PHPSession::Errors, "can't obtain lock of session file"
|
46
|
-
end
|
47
|
-
yield(f)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def set_session_id(session_id)
|
52
|
-
@session_id = session_id
|
53
|
-
raise Errors::SecurityError, "directory traversal detected" unless file_path.index(@session_dir) == 0
|
54
|
-
end
|
55
|
-
|
56
|
-
def file_path(session_id)
|
57
|
-
path = File.expand_path(File.join(@session_dir, "sess_#{session_id}"))
|
58
|
-
raise Errors::SecurityError, "directory traversal detected" unless path.index(@session_dir) == 0
|
59
|
-
path
|
48
|
+
serialized_session = Encoder.encode(data, @option[:external_encoding], @option[:encoding_option])
|
49
|
+
@store_engine.save(session_id, serialized_session)
|
60
50
|
end
|
61
51
|
end
|
52
|
+
|
53
|
+
PHPSession.register_store_engine(:file, PHPSession::StoreEngine::File)
|
data/lib/php_session/errors.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
class PHPSession::Errors < StandardError; end
|
3
|
-
class PHPSession::Errors::
|
4
|
-
class PHPSession::Errors::
|
3
|
+
class PHPSession::Errors::ParameterError < StandardError; end
|
4
|
+
class PHPSession::Errors::ParseError < PHPSession::Errors; end
|
5
|
+
class PHPSession::Errors::EncodeError < PHPSession::Errors; end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
class PHPSession
|
3
|
+
module StoreEngine
|
4
|
+
class File
|
5
|
+
def initialize(option)
|
6
|
+
if ! option[:session_file_dir]
|
7
|
+
raise PHPSession::Errors::ParameterError , "option[:session_dir] is required"
|
8
|
+
end
|
9
|
+
|
10
|
+
@option = option
|
11
|
+
end
|
12
|
+
|
13
|
+
def load(session_id)
|
14
|
+
serialized_session = with_lock(file_path(session_id)) do |f|
|
15
|
+
# set internal_encoding to nil to avoid encoding conversion
|
16
|
+
f.set_encoding(@option[:external_encoding], nil)
|
17
|
+
f.read
|
18
|
+
end
|
19
|
+
|
20
|
+
serialized_session
|
21
|
+
end
|
22
|
+
|
23
|
+
def save(session_id, serialized_session)
|
24
|
+
with_lock(file_path(session_id)) do |f|
|
25
|
+
f.truncate(0)
|
26
|
+
f.write(serialized_session)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def destroy(session_id)
|
31
|
+
::File.delete(file_path(session_id))
|
32
|
+
rescue Errno::ENOENT
|
33
|
+
# file already deleted
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def with_lock(file_path)
|
39
|
+
mode = ::File::CREAT|::File::RDWR
|
40
|
+
::File.open(file_path, mode) do |f|
|
41
|
+
unless f.flock(::File::LOCK_EX)
|
42
|
+
raise PHPSession::Errors, "can't obtain lock of session file"
|
43
|
+
end
|
44
|
+
yield(f)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def file_path(session_id)
|
49
|
+
path = ::File.expand_path(::File.join(@option[:session_file_dir], "sess_#{session_id}"))
|
50
|
+
raise Errors::SecurityError, "directory traversal detected" unless path.index(@option[:session_file_dir]) == 0
|
51
|
+
path
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/php_session/version.rb
CHANGED
data/php_session.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Shinpei Maruyama"]
|
10
10
|
spec.email = ["shinpeim@gmail.com"]
|
11
11
|
spec.description = %q{php session reader/writer}
|
12
|
-
spec.summary = %q{php_session is a php session file reader/writer. Multibyte string
|
12
|
+
spec.summary = %q{php_session is a php session file reader/writer. Multibyte string control is supported}
|
13
13
|
spec.homepage = "https://github.com/Shinpeim/ruby_php_session"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
data/spec/php_session_spec.rb
CHANGED
@@ -12,8 +12,9 @@ describe PHPSession do
|
|
12
12
|
option = {
|
13
13
|
:internal_encoding => nil,
|
14
14
|
:external_encoding => "UTF-8",
|
15
|
+
:session_file_dir => @session_file[:dir_name],
|
15
16
|
}
|
16
|
-
session = PHPSession.new(
|
17
|
+
session = PHPSession.new(option)
|
17
18
|
data = session.load(@session_file[:session_id])
|
18
19
|
expect(data).to eq({"key" => "テスト🍺"})
|
19
20
|
end
|
@@ -22,8 +23,9 @@ describe PHPSession do
|
|
22
23
|
option = {
|
23
24
|
:internal_encoding => "UTF-8",
|
24
25
|
:external_encoding => "UTF-8",
|
26
|
+
:session_file_dir => @session_file[:dir_name],
|
25
27
|
}
|
26
|
-
session = PHPSession.new(
|
28
|
+
session = PHPSession.new(option)
|
27
29
|
data = session.load(@session_file[:session_id])
|
28
30
|
expect(data).to eq({"key" => "テスト🍺"})
|
29
31
|
end
|
@@ -32,9 +34,10 @@ describe PHPSession do
|
|
32
34
|
option = {
|
33
35
|
:internal_encoding => "EUC-JP",
|
34
36
|
:external_encoding => "UTF-8",
|
35
|
-
:encoding_option => {:undef => :replace}
|
37
|
+
:encoding_option => {:undef => :replace},
|
38
|
+
:session_file_dir => @session_file[:dir_name],
|
36
39
|
}
|
37
|
-
session = PHPSession.new(
|
40
|
+
session = PHPSession.new(option)
|
38
41
|
data = session.load(@session_file[:session_id])
|
39
42
|
expect(data).to eq({"key" => "テスト🍺".encode("EUC-JP", {:undef => :replace})})
|
40
43
|
end
|
@@ -50,7 +53,7 @@ describe PHPSession do
|
|
50
53
|
end
|
51
54
|
|
52
55
|
it "should return session data" do
|
53
|
-
session = PHPSession.new(@session_file[:dir_name])
|
56
|
+
session = PHPSession.new(:session_file_dir => @session_file[:dir_name])
|
54
57
|
data = session.load(@session_file[:session_id])
|
55
58
|
expect(data).to eq({"key" => "a"})
|
56
59
|
end
|
@@ -62,7 +65,7 @@ describe PHPSession do
|
|
62
65
|
|
63
66
|
context "when session file dosen't exist" do
|
64
67
|
it "should return new session data" do
|
65
|
-
session = PHPSession.new(Dir.tmpdir)
|
68
|
+
session = PHPSession.new(:session_file_dir => Dir.tmpdir)
|
66
69
|
data = session.load("session_id")
|
67
70
|
expect(data).to eq({})
|
68
71
|
end
|
@@ -78,9 +81,10 @@ describe PHPSession do
|
|
78
81
|
option = {
|
79
82
|
:external_encoding => "EUC-JP",
|
80
83
|
:internal_encoding => "UTF-8",
|
81
|
-
:encoding_option => {:undef => :replace}
|
84
|
+
:encoding_option => {:undef => :replace},
|
85
|
+
:session_file_dir => @session_file[:dir_name],
|
82
86
|
}
|
83
|
-
session = PHPSession.new(
|
87
|
+
session = PHPSession.new(option)
|
84
88
|
data = session.load(@session_file[:session_id])
|
85
89
|
data["key"] = "テスト🍣"
|
86
90
|
session.save(@session_file[:session_id], data)
|
@@ -102,7 +106,7 @@ describe PHPSession do
|
|
102
106
|
end
|
103
107
|
|
104
108
|
it "should delete session file" do
|
105
|
-
session = PHPSession.new(@session_file[:dir_name])
|
109
|
+
session = PHPSession.new(:session_file_dir => @session_file[:dir_name])
|
106
110
|
session.destroy(@session_file[:session_id])
|
107
111
|
expect(File.exists?(@session_file[:file_path])).to eq(false)
|
108
112
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: php_session
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shinpei Maruyama
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-08-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -70,6 +70,7 @@ files:
|
|
70
70
|
- lib/php_session/decoder.rb
|
71
71
|
- lib/php_session/encoder.rb
|
72
72
|
- lib/php_session/errors.rb
|
73
|
+
- lib/php_session/store_engine/file.rb
|
73
74
|
- lib/php_session/version.rb
|
74
75
|
- php_session.gemspec
|
75
76
|
- spec/php_session/decoder_spec.rb
|
@@ -99,8 +100,8 @@ rubyforge_project:
|
|
99
100
|
rubygems_version: 2.2.2
|
100
101
|
signing_key:
|
101
102
|
specification_version: 4
|
102
|
-
summary: php_session is a php session file reader/writer. Multibyte string
|
103
|
-
|
103
|
+
summary: php_session is a php session file reader/writer. Multibyte string control
|
104
|
+
is supported
|
104
105
|
test_files:
|
105
106
|
- spec/php_session/decoder_spec.rb
|
106
107
|
- spec/php_session/encoder_spec.rb
|