bossan 0.1.6 → 0.1.7
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.
- data/.gitignore +23 -0
- data/.travis.yml +4 -0
- data/Gemfile +6 -0
- data/README.md +52 -0
- data/Rakefile +22 -0
- data/bossan.gemspec +20 -0
- data/examples/blog/README.md +19 -0
- data/examples/blog/app.rb +77 -0
- data/examples/blog/config.ru +4 -0
- data/examples/blog/public/style.css +18 -0
- data/examples/blog/views/login.erb +23 -0
- data/examples/blog/views/show_entries.erb +38 -0
- data/examples/config.ru +19 -0
- data/examples/hello.rb +13 -0
- data/examples/sinatra_app.rb +11 -0
- data/examples/views/index.haml +10 -0
- data/examples/views_sample.rb +11 -0
- data/ext/bossan/bossan_ext.c +20 -222
- data/ext/bossan/buffer.c +74 -0
- data/ext/bossan/buffer.h +43 -0
- data/ext/bossan/client.h +35 -0
- data/ext/bossan/extconf.rb +11 -0
- data/ext/bossan/picoev_kqueue.c +209 -0
- data/ext/bossan/request.c +62 -0
- data/ext/bossan/request.h +54 -0
- data/lib/bossan/version.rb +1 -1
- data/lib/rack/handler/bossan.rb +1 -1
- data/test/test_rack_env_query.rb +57 -0
- data/test/test_rack_env_simple.rb +60 -0
- data/test/test_rack_spec.rb +65 -0
- metadata +35 -9
data/.gitignore
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.o
|
19
|
+
*.so
|
20
|
+
Makefile
|
21
|
+
*.log
|
22
|
+
*.db
|
23
|
+
TAGS
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# Bossan
|
2
|
+
|
3
|
+
[](http://travis-ci.org/kubo39/bossan)
|
4
|
+
|
5
|
+
Bossan is a high performance asynchronous ruby's rack-compliant web server.
|
6
|
+
|
7
|
+
## Requirements
|
8
|
+
|
9
|
+
Bossan requires Ruby 1.9.2 or later.
|
10
|
+
|
11
|
+
Bossan supports Linux, FreeBSD and Mac OS X(need gcc>=4.2).
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
from rubygems
|
16
|
+
|
17
|
+
`gem install bossan`
|
18
|
+
|
19
|
+
or from source:
|
20
|
+
|
21
|
+
```
|
22
|
+
git clone git://github.com/kubo39/bossan.git
|
23
|
+
cd bossan
|
24
|
+
rake
|
25
|
+
```
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
simple rack app:
|
30
|
+
|
31
|
+
``` ruby
|
32
|
+
require 'bossan'
|
33
|
+
|
34
|
+
Bossan.run('127.0.0.1', 8000, proc {|env|
|
35
|
+
[
|
36
|
+
200, # Status code
|
37
|
+
{ # Response headers
|
38
|
+
'Content-Type' => 'text/html',
|
39
|
+
'Content-Length' => '13',
|
40
|
+
},
|
41
|
+
['hello, world!'] # Response body
|
42
|
+
]
|
43
|
+
})
|
44
|
+
```
|
45
|
+
|
46
|
+
## Contributing
|
47
|
+
|
48
|
+
1. Fork it
|
49
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
50
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
51
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
52
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
require "rbconfig"
|
4
|
+
|
5
|
+
task :default => [:compile, :clean, :test]
|
6
|
+
|
7
|
+
task :compile do
|
8
|
+
Dir.chdir File.expand_path("../ext/bossan", __FILE__)
|
9
|
+
sh "ruby extconf.rb"
|
10
|
+
sh "make"
|
11
|
+
sh "mv bossan_ext.#{RbConfig::CONFIG['DLEXT']} ../../lib/bossan/"
|
12
|
+
end
|
13
|
+
|
14
|
+
task :clean do
|
15
|
+
Dir.chdir File.expand_path("../ext/bossan", __FILE__)
|
16
|
+
sh "rm -f *.o Makefile"
|
17
|
+
end
|
18
|
+
|
19
|
+
task :test do
|
20
|
+
Dir.chdir File.expand_path("../test", __FILE__)
|
21
|
+
sh "ruby test_rack_spec.rb"
|
22
|
+
end
|
data/bossan.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/bossan/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.name = "bossan"
|
6
|
+
gem.version = Bossan::VERSION
|
7
|
+
gem.authors = ["Hiroki Noda"]
|
8
|
+
gem.email = ["kubo39@gmail.com"]
|
9
|
+
gem.description = %q{high performance asynchronous rack web server}
|
10
|
+
gem.summary = gem.description
|
11
|
+
gem.homepage = "https://github.com/kubo39/bossan"
|
12
|
+
|
13
|
+
gem.files = `git ls-files`.split($/)
|
14
|
+
gem.extensions = ["ext/bossan/extconf.rb"]
|
15
|
+
gem.require_paths = ["lib", "ext"]
|
16
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split($/)
|
17
|
+
|
18
|
+
gem.required_ruby_version = ">= 1.9.2"
|
19
|
+
gem.add_dependency "rack", ["~> 1.2"]
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# This is a simple microblog powered by sqlite.
|
2
|
+
|
3
|
+
### Requirements some extension
|
4
|
+
|
5
|
+
* ActiveRecord (ORM)
|
6
|
+
* eRuby (Template)
|
7
|
+
* SQLite (Database)
|
8
|
+
|
9
|
+
|
10
|
+
#### fire up a irb(pry)
|
11
|
+
|
12
|
+
require './app'; init_db
|
13
|
+
|
14
|
+
|
15
|
+
### Run
|
16
|
+
|
17
|
+
rackup config.ru -s bossan
|
18
|
+
|
19
|
+
visit http://0.0.0.0:9292
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require 'active_record'
|
3
|
+
require 'erb'
|
4
|
+
|
5
|
+
enable :sessions
|
6
|
+
|
7
|
+
DATABASE = './db/sinatr.db'
|
8
|
+
SECRET_KEY = 'development_key'
|
9
|
+
USERNAME = 'admin'
|
10
|
+
PASSWORD = 'default'
|
11
|
+
|
12
|
+
ActiveRecord::Base.establish_connection(
|
13
|
+
:adapter => 'sqlite3',
|
14
|
+
:database => DATABASE
|
15
|
+
)
|
16
|
+
|
17
|
+
get '/' do
|
18
|
+
@entries = Entries.find(:all).map do |row|
|
19
|
+
{:title => row.title,
|
20
|
+
:text => row.text }
|
21
|
+
end
|
22
|
+
@entries ||= []
|
23
|
+
erb :show_entries
|
24
|
+
end
|
25
|
+
|
26
|
+
post '/add' do
|
27
|
+
halt(401) if session.include?([:logged_in])
|
28
|
+
Entries.create(:title => params[:title],
|
29
|
+
:text => params[:text])
|
30
|
+
redirect '/'
|
31
|
+
end
|
32
|
+
|
33
|
+
post '/login' do
|
34
|
+
@err = nil
|
35
|
+
if params[:username] != USERNAME
|
36
|
+
@err = "Invalid username #{params[:username]}"
|
37
|
+
elsif params[:password] != PASSWORD
|
38
|
+
@err = "Invalid password"
|
39
|
+
else
|
40
|
+
session[:logged_in] = params[:username]
|
41
|
+
redirect '/'
|
42
|
+
end
|
43
|
+
erb :login
|
44
|
+
end
|
45
|
+
|
46
|
+
get '/login' do
|
47
|
+
erb :login
|
48
|
+
end
|
49
|
+
|
50
|
+
get '/logout' do
|
51
|
+
session.delete :logged_in
|
52
|
+
erb :show_entries
|
53
|
+
end
|
54
|
+
|
55
|
+
class Schema < ActiveRecord::Migration
|
56
|
+
def self.up
|
57
|
+
create_table :entries do |t|
|
58
|
+
t.column :title, :string, :null => false
|
59
|
+
t.column :text, :string, :null => false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.down
|
64
|
+
drop_table :entries
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class Entries < ActiveRecord::Base
|
69
|
+
end
|
70
|
+
|
71
|
+
def init_db
|
72
|
+
Schema.migrate :up
|
73
|
+
end
|
74
|
+
|
75
|
+
def drop_db
|
76
|
+
Schema.migrate :down
|
77
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
body { font-family: sans-serif; background: #eee; }
|
2
|
+
a, h1, h2 { color: #377BA8; }
|
3
|
+
h1, h2 { font-family: 'Georgia', serif; margin: 0; }
|
4
|
+
h1 { border-bottom: 2px solid #eee; }
|
5
|
+
h2 { font-size: 1.2em; }
|
6
|
+
|
7
|
+
.page { margin: 2em auto; width: 35em; border: 5px solid #ccc;
|
8
|
+
padding: 0.8em; background: white; }
|
9
|
+
.entries { list-style: none; margin: 0; padding: 0; }
|
10
|
+
.entries li { margin: 0.8em 1.2em; }
|
11
|
+
.entries li h2 { margin-left: -1em; }
|
12
|
+
.add-entry { font-size: 0.9em; border-bottom: 1px solid #ccc; }
|
13
|
+
.add-entry dl { font-weight: bold; }
|
14
|
+
.metanav { text-align: right; font-size: 0.8em; padding: 0.3em;
|
15
|
+
margin-bottom: 1em; background: #fafafa; }
|
16
|
+
.flash { background: #CEE5F5; padding: 0.5em;
|
17
|
+
border: 1px solid #AACBE2; }
|
18
|
+
.error { background: #F0D6D6; padding: 0.5em; }
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Sinatr</title>
|
5
|
+
<link rel="stylesheet" type="text/css" href="/static/style.css">
|
6
|
+
</head>
|
7
|
+
<body>
|
8
|
+
<div class="page">
|
9
|
+
<h2>Login</h2>
|
10
|
+
<% if @err %>
|
11
|
+
<p class="error"><h2>Error:</h2>
|
12
|
+
<%= @err %>
|
13
|
+
<% end %>
|
14
|
+
<form action="/login" method="POST">
|
15
|
+
<h3>Username:</h3>
|
16
|
+
<input type="text" name="username">
|
17
|
+
<h3>Password:</h3>
|
18
|
+
<input type="password" name="password">
|
19
|
+
<input type="submit" value="Login">
|
20
|
+
</form>
|
21
|
+
</div>
|
22
|
+
</body>
|
23
|
+
</html>
|
@@ -0,0 +1,38 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Sinatr</title>
|
5
|
+
<link rel="stylesheet" type="text/css" href="/static/style.css"/>
|
6
|
+
</head>
|
7
|
+
<body>
|
8
|
+
<div class="page">
|
9
|
+
<h1>Sinatr</h1>
|
10
|
+
<div class="metanav">
|
11
|
+
<% unless session.include?(:logged_in) %>
|
12
|
+
<a href="/login">log in</a>
|
13
|
+
<% else %>
|
14
|
+
<a href="/logout">log out</a>
|
15
|
+
<% end %>
|
16
|
+
</div>
|
17
|
+
</div>
|
18
|
+
<% if session.include?(:logged_in) %>
|
19
|
+
<form action="/add" method="POST" class="add">
|
20
|
+
|
21
|
+
<h3>Title:</h3>
|
22
|
+
<input type="text" size="30" name="title">
|
23
|
+
<h3>Text:</h3>
|
24
|
+
<textarea name="text" rows="5" cols="40"></textarea>
|
25
|
+
<input type="submit" value="Share">
|
26
|
+
|
27
|
+
</form>
|
28
|
+
<% end %>
|
29
|
+
<ul class="entries">
|
30
|
+
<% unless (@entries == [] || @entries == nil) %>
|
31
|
+
<% @entries.each do |entry| %>
|
32
|
+
<h2><%= entry[:title] %></h2>
|
33
|
+
<%= entry[:text] %>
|
34
|
+
<% end %>
|
35
|
+
<% end %>
|
36
|
+
</ul>
|
37
|
+
</body>
|
38
|
+
<html>
|
data/examples/config.ru
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'bossan'
|
2
|
+
require 'pp'
|
3
|
+
|
4
|
+
class MyApp
|
5
|
+
def call env
|
6
|
+
body = ['hi!']
|
7
|
+
# pp env
|
8
|
+
[
|
9
|
+
200, # Status code
|
10
|
+
{ 'Content-Type' => 'text/html',
|
11
|
+
'Content-Length' => body.join.size.to_s,
|
12
|
+
}, # Reponse headers
|
13
|
+
body # Body of the response
|
14
|
+
]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Rack::Handler::Bossan.run MyApp.new
|
19
|
+
run MyApp.new
|
data/examples/hello.rb
ADDED
data/ext/bossan/bossan_ext.c
CHANGED
@@ -4,10 +4,6 @@
|
|
4
4
|
#include <stddef.h>
|
5
5
|
#include <unistd.h>
|
6
6
|
#include <errno.h>
|
7
|
-
#include <stdio.h>
|
8
|
-
#include <stdlib.h>
|
9
|
-
#include <string.h>
|
10
|
-
#include <inttypes.h>
|
11
7
|
#include <arpa/inet.h>
|
12
8
|
#include <signal.h>
|
13
9
|
#include <sys/socket.h>
|
@@ -24,9 +20,12 @@
|
|
24
20
|
#include <netinet/in.h>
|
25
21
|
#include <netinet/tcp.h>
|
26
22
|
#include <netdb.h>
|
23
|
+
|
27
24
|
#include "time_cache.h"
|
28
25
|
#include "http_parser.h"
|
29
26
|
#include "picoev.h"
|
27
|
+
#include "buffer.h"
|
28
|
+
#include "client.h"
|
30
29
|
|
31
30
|
#define MAX_FDS 1024 * 8
|
32
31
|
#define ACCEPT_TIMEOUT_SECS 1
|
@@ -38,18 +37,8 @@
|
|
38
37
|
#define MAX_BUFSIZE 1024 * 8
|
39
38
|
#define INPUT_BUF_SIZE 1024 * 8
|
40
39
|
|
41
|
-
#define LIMIT_MAX 1024 * 1024 * 1024
|
42
|
-
|
43
40
|
#define LIMIT_SIZE 1024 * 512
|
44
41
|
|
45
|
-
#define LIMIT_PATH 1024 * 4
|
46
|
-
#define LIMIT_FRAGMENT 1024
|
47
|
-
#define LIMIT_URI 1024 * 4
|
48
|
-
#define LIMIT_QUERY_STRING 1024 * 8
|
49
|
-
|
50
|
-
#define LIMIT_REQUEST_FIELDS 30
|
51
|
-
#define LIMIT_REQUEST_FIELD_SIZE 1024 * 8
|
52
|
-
|
53
42
|
#define CRLF "\r\n"
|
54
43
|
#define DELIM ": "
|
55
44
|
|
@@ -61,7 +50,7 @@
|
|
61
50
|
|
62
51
|
#define MSG_413 ("HTTP/1.0 413 Request Entity Too Large\r\nContent-Type: text/html\r\nServer: " SERVER "\r\n\r\n<html><head><title>Request Entity Too Large</title></head><body><p>Request Entity Too Large.</p></body></html>")
|
63
52
|
|
64
|
-
#define SERVER "bossan/0.1.
|
53
|
+
#define SERVER "bossan/0.1.7"
|
65
54
|
|
66
55
|
VALUE server; // Bossan
|
67
56
|
|
@@ -129,74 +118,6 @@ int max_content_length = 1024 * 1024 * 16; //max_content_length
|
|
129
118
|
|
130
119
|
static VALUE StringIO;
|
131
120
|
|
132
|
-
typedef enum {
|
133
|
-
WRITE_OK,
|
134
|
-
MEMORY_ERROR,
|
135
|
-
LIMIT_OVER,
|
136
|
-
} buffer_result;
|
137
|
-
|
138
|
-
typedef struct {
|
139
|
-
char *buf;
|
140
|
-
size_t buf_size;
|
141
|
-
size_t len;
|
142
|
-
size_t limit;
|
143
|
-
} buffer;
|
144
|
-
|
145
|
-
typedef enum {
|
146
|
-
FIELD,
|
147
|
-
VAL,
|
148
|
-
} field_type;
|
149
|
-
|
150
|
-
typedef struct {
|
151
|
-
buffer *field;
|
152
|
-
buffer *value;
|
153
|
-
} header;
|
154
|
-
|
155
|
-
typedef struct {
|
156
|
-
buffer *path;
|
157
|
-
buffer *uri;
|
158
|
-
buffer *query_string;
|
159
|
-
buffer *fragment;
|
160
|
-
header *headers[LIMIT_REQUEST_FIELDS];
|
161
|
-
uint32_t num_headers;
|
162
|
-
field_type last_header_element;
|
163
|
-
} request;
|
164
|
-
|
165
|
-
typedef enum {
|
166
|
-
BODY_TYPE_NONE,
|
167
|
-
BODY_TYPE_TMPFILE,
|
168
|
-
BODY_TYPE_BUFFER
|
169
|
-
} request_body_type;
|
170
|
-
|
171
|
-
typedef struct _client {
|
172
|
-
int fd;
|
173
|
-
char *remote_addr;
|
174
|
-
uint32_t remote_port;
|
175
|
-
uint8_t keep_alive;
|
176
|
-
request *req;
|
177
|
-
uint32_t body_length;
|
178
|
-
int body_readed;
|
179
|
-
void *body;
|
180
|
-
int bad_request_code;
|
181
|
-
request_body_type body_type;
|
182
|
-
uint8_t complete;
|
183
|
-
|
184
|
-
http_parser *http; // http req parser
|
185
|
-
VALUE environ; // rack environ
|
186
|
-
int status_code; // response status code
|
187
|
-
|
188
|
-
VALUE http_status; // response status line
|
189
|
-
VALUE headers; // http response headers
|
190
|
-
uint8_t header_done; // header write status
|
191
|
-
VALUE response; // rack response object
|
192
|
-
VALUE response_iter; // rack response object
|
193
|
-
uint8_t content_length_set; // content_length_set flag
|
194
|
-
uint32_t content_length; // content_length
|
195
|
-
uint32_t write_bytes; // send body length
|
196
|
-
void *bucket; //write_data
|
197
|
-
uint8_t response_closed; //response closed flag
|
198
|
-
} client_t;
|
199
|
-
|
200
121
|
typedef struct iovec iovec_t;
|
201
122
|
|
202
123
|
typedef struct {
|
@@ -209,78 +130,6 @@ typedef struct {
|
|
209
130
|
} write_bucket;
|
210
131
|
|
211
132
|
|
212
|
-
buffer *
|
213
|
-
new_buffer(size_t buf_size, size_t limit)
|
214
|
-
{
|
215
|
-
buffer *buf;
|
216
|
-
buf = ruby_xmalloc(sizeof(buffer));
|
217
|
-
memset(buf, 0, sizeof(buffer));
|
218
|
-
buf->buf = ruby_xmalloc(sizeof(char) * buf_size);
|
219
|
-
buf->buf_size = buf_size;
|
220
|
-
if(limit){
|
221
|
-
buf->limit = limit;
|
222
|
-
}else{
|
223
|
-
buf->limit = LIMIT_MAX;
|
224
|
-
}
|
225
|
-
return buf;
|
226
|
-
}
|
227
|
-
|
228
|
-
|
229
|
-
buffer_result
|
230
|
-
write2buf(buffer *buf, const char *c, size_t l)
|
231
|
-
{
|
232
|
-
size_t newl;
|
233
|
-
char *newbuf;
|
234
|
-
buffer_result ret = WRITE_OK;
|
235
|
-
newl = buf->len + l;
|
236
|
-
|
237
|
-
if (newl >= buf->buf_size) {
|
238
|
-
buf->buf_size *= 2;
|
239
|
-
if(buf->buf_size <= newl) {
|
240
|
-
buf->buf_size = (int)(newl + 1);
|
241
|
-
}
|
242
|
-
if(buf->buf_size > buf->limit){
|
243
|
-
buf->buf_size = buf->limit + 1;
|
244
|
-
}
|
245
|
-
newbuf = (char*)ruby_xrealloc(buf->buf, buf->buf_size);
|
246
|
-
buf->buf = newbuf;
|
247
|
-
}
|
248
|
-
if(newl >= buf->buf_size){
|
249
|
-
l = buf->buf_size - buf->len -1;
|
250
|
-
ret = LIMIT_OVER;
|
251
|
-
}
|
252
|
-
memcpy(buf->buf + buf->len, c , l);
|
253
|
-
buf->len += (int)l;
|
254
|
-
return ret;
|
255
|
-
}
|
256
|
-
|
257
|
-
|
258
|
-
void
|
259
|
-
free_buffer(buffer *buf)
|
260
|
-
{
|
261
|
-
ruby_xfree(buf->buf);
|
262
|
-
ruby_xfree(buf);
|
263
|
-
}
|
264
|
-
|
265
|
-
|
266
|
-
VALUE
|
267
|
-
getRbString(buffer *buf)
|
268
|
-
{
|
269
|
-
VALUE o;
|
270
|
-
o = rb_str_new(buf->buf, buf->len);
|
271
|
-
free_buffer(buf);
|
272
|
-
return o;
|
273
|
-
}
|
274
|
-
|
275
|
-
|
276
|
-
char *
|
277
|
-
getString(buffer *buf)
|
278
|
-
{
|
279
|
-
buf->buf[buf->len] = '\0';
|
280
|
-
return buf->buf;
|
281
|
-
}
|
282
|
-
|
283
|
-
|
284
133
|
int
|
285
134
|
open_log_file(const char *path)
|
286
135
|
{
|
@@ -858,67 +707,6 @@ response_start(client_t *client)
|
|
858
707
|
}
|
859
708
|
|
860
709
|
|
861
|
-
request *
|
862
|
-
new_request(void)
|
863
|
-
{
|
864
|
-
request *req = (request *)ruby_xmalloc(sizeof(request));
|
865
|
-
memset(req, 0, sizeof(request));
|
866
|
-
return req;
|
867
|
-
}
|
868
|
-
|
869
|
-
|
870
|
-
header *
|
871
|
-
new_header(size_t fsize, size_t flimit, size_t vsize, size_t vlimit)
|
872
|
-
{
|
873
|
-
header *h;
|
874
|
-
h = ruby_xmalloc(sizeof(header));
|
875
|
-
h->field = new_buffer(fsize, flimit);
|
876
|
-
h->value = new_buffer(vsize, vlimit);
|
877
|
-
return h;
|
878
|
-
}
|
879
|
-
|
880
|
-
|
881
|
-
void
|
882
|
-
free_header(header *h)
|
883
|
-
{
|
884
|
-
ruby_xfree(h);
|
885
|
-
}
|
886
|
-
|
887
|
-
|
888
|
-
void
|
889
|
-
free_request(request *req)
|
890
|
-
{
|
891
|
-
uint32_t i;
|
892
|
-
header *h;
|
893
|
-
if(req->path){
|
894
|
-
free_buffer(req->path);
|
895
|
-
req->path = NULL;
|
896
|
-
}
|
897
|
-
if(req->uri){
|
898
|
-
free_buffer(req->uri);
|
899
|
-
req->uri = NULL;
|
900
|
-
}
|
901
|
-
if(req->query_string){
|
902
|
-
free_buffer(req->query_string);
|
903
|
-
req->query_string = NULL;
|
904
|
-
}
|
905
|
-
if(req->fragment){
|
906
|
-
free_buffer(req->fragment);
|
907
|
-
req->fragment = NULL;
|
908
|
-
}
|
909
|
-
for(i = 0; i < req->num_headers+1; i++){
|
910
|
-
h = req->headers[i];
|
911
|
-
if(h){
|
912
|
-
free_buffer(h->field);
|
913
|
-
free_buffer(h->value);
|
914
|
-
free_header(h);
|
915
|
-
req->headers[i] = NULL;
|
916
|
-
}
|
917
|
-
}
|
918
|
-
ruby_xfree(req);
|
919
|
-
}
|
920
|
-
|
921
|
-
|
922
710
|
static void
|
923
711
|
key_upper(char *s, const char *key, size_t len)
|
924
712
|
{
|
@@ -955,9 +743,10 @@ write_body2file(client_t *client, const char *buffer, size_t buffer_len)
|
|
955
743
|
static int
|
956
744
|
write_body2mem(client_t *client, const char *buffer, size_t buffer_len)
|
957
745
|
{
|
746
|
+
VALUE obj;
|
958
747
|
/* printf("body2mem called\n"); */
|
959
|
-
|
960
|
-
|
748
|
+
|
749
|
+
rb_funcall((VALUE)client->body, rb_intern("write"), 1, rb_str_new(buffer, buffer_len));
|
961
750
|
client->body_readed += buffer_len;
|
962
751
|
#ifdef DEBUG
|
963
752
|
printf("write_body2mem %d bytes \n", buffer_len);
|
@@ -1234,6 +1023,7 @@ body_cb (http_parser *p, const char *buf, size_t len, char partial)
|
|
1234
1023
|
#ifdef DEBUG
|
1235
1024
|
printf("client->body_length %d \n", client->body_length);
|
1236
1025
|
#endif
|
1026
|
+
client->body = rb_funcall(StringIO, i_new, 1, rb_str_new2(""));
|
1237
1027
|
client->body_type = BODY_TYPE_BUFFER;
|
1238
1028
|
#ifdef DEBUG
|
1239
1029
|
printf("BODY_TYPE_BUFFER \n");
|
@@ -1723,10 +1513,18 @@ prepare_call_rack(client_t *client)
|
|
1723
1513
|
VALUE input, object, c;
|
1724
1514
|
char *val;
|
1725
1515
|
|
1726
|
-
|
1727
|
-
|
1728
|
-
|
1729
|
-
|
1516
|
+
if(client->body_type == BODY_TYPE_BUFFER) {
|
1517
|
+
/* rb_p( rb_funcall((VALUE)client->body, rb_intern("gets"), 0) ); */
|
1518
|
+
rb_p( rb_funcall((VALUE)client->body, rb_intern("seek"), 1, INT2NUM(0)) );
|
1519
|
+
rb_hash_aset(client->environ, rack_input, (VALUE)client->body);
|
1520
|
+
} else {
|
1521
|
+
object = rb_str_new2("");
|
1522
|
+
input = rb_funcall(StringIO, i_new, 1, object);
|
1523
|
+
rb_gc_register_address(&input);
|
1524
|
+
rb_hash_aset(client->environ, rack_input, input);
|
1525
|
+
/* client->body = object; */
|
1526
|
+
client->body = input;
|
1527
|
+
}
|
1730
1528
|
|
1731
1529
|
if(is_keep_alive){
|
1732
1530
|
//support keep-alive
|