Skip to content

Commit 78102f4

Browse files
author
alor
committed
2 parents 381dbd9 + b96beb4 commit 78102f4

File tree

3 files changed

+85
-8
lines changed

3 files changed

+85
-8
lines changed

ext/rubyhttp.cpp

+33-7
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,30 @@ Statics
172172

173173
VALUE Intern_http_conn;
174174

175+
/********************
176+
t_get_http_connection
177+
********************/
178+
179+
static RubyHttpConnection_t *t_get_http_connection(VALUE self)
180+
{
181+
RubyHttpConnection_t *hc;
182+
VALUE ivar = rb_ivar_get (self, Intern_http_conn);
183+
if (ivar != Qnil)
184+
Data_Get_Struct (ivar, RubyHttpConnection_t, hc);
185+
else
186+
hc = NULL;
187+
return hc;
188+
}
189+
190+
/********************
191+
t_delete_http_connection
192+
********************/
193+
194+
void t_delete_http_connection(RubyHttpConnection_t *hc)
195+
{
196+
delete hc;
197+
}
198+
175199
/***********
176200
t_post_init
177201
***********/
@@ -182,7 +206,12 @@ static VALUE t_post_init (VALUE self)
182206
if (!hc)
183207
throw std::runtime_error ("no http-connection object");
184208

185-
rb_ivar_set (self, Intern_http_conn, LONG2NUM ((long)hc));
209+
/*
210+
HACK: http_connection should be given an actual type. No one should
211+
be touching it from inside ruby, but still
212+
*/
213+
VALUE http_connection = Data_Wrap_Struct(CLASS_OF(self), 0, t_delete_http_connection, hc);
214+
rb_ivar_set (self, Intern_http_conn, http_connection);
186215
return Qnil;
187216
}
188217

@@ -194,7 +223,7 @@ t_receive_data
194223
static VALUE t_receive_data (VALUE self, VALUE data)
195224
{
196225
int length = NUM2INT (rb_funcall (data, rb_intern ("length"), 0));
197-
RubyHttpConnection_t *hc = (RubyHttpConnection_t*)(NUM2LONG (rb_ivar_get (self, Intern_http_conn)));
226+
RubyHttpConnection_t *hc = t_get_http_connection (self);
198227
if (hc)
199228
hc->ConsumeData (StringValuePtr (data), length);
200229
return Qnil;
@@ -216,9 +245,6 @@ t_unbind
216245

217246
static VALUE t_unbind (VALUE self)
218247
{
219-
RubyHttpConnection_t *hc = (RubyHttpConnection_t*)(NUM2LONG (rb_ivar_get (self, Intern_http_conn)));
220-
if (hc)
221-
delete hc;
222248
return Qnil;
223249
}
224250

@@ -240,7 +266,7 @@ t_no_environment_strings
240266

241267
static VALUE t_no_environment_strings (VALUE self)
242268
{
243-
RubyHttpConnection_t *hc = (RubyHttpConnection_t*)(NUM2LONG (rb_ivar_get (self, Intern_http_conn)));
269+
RubyHttpConnection_t *hc = t_get_http_connection (self);
244270
if (hc)
245271
hc->SetNoEnvironmentStrings();
246272
return Qnil;
@@ -252,7 +278,7 @@ t_dont_accumulate_post
252278

253279
static VALUE t_dont_accumulate_post (VALUE self)
254280
{
255-
RubyHttpConnection_t *hc = (RubyHttpConnection_t*)(NUM2LONG (rb_ivar_get (self, Intern_http_conn)));
281+
RubyHttpConnection_t *hc = t_get_http_connection (self);
256282
if (hc)
257283
hc->SetDontAccumulatePost();
258284
return Qnil;

lib/evma_httpserver/response.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def send_response
9898
send_headers
9999
send_body
100100
send_trailer
101-
close_connection_after_writing unless (@keep_connection_open and (@status || 200) == 200)
101+
close_connection_after_writing unless (@keep_connection_open and (@status || 200) < 500)
102102
end
103103

104104
# Send the headers out in alpha-sorted order. This will degrade performance to some

test/test_response.rb

+51
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,57 @@ def test_send_response_no_close
116116
assert( ! a.closed_after_writing )
117117
end
118118

119+
def test_send_response_no_close_with_a_404_response
120+
a = EventMachine::HttpResponse.new
121+
a.status = 404
122+
a.content_type "text/plain"
123+
a.content = "ABC"
124+
a.keep_connection_open
125+
a.send_response
126+
assert_equal([
127+
"HTTP/1.1 404 ...\r\n",
128+
"Content-length: 3\r\n",
129+
"Content-type: text/plain\r\n",
130+
"\r\n",
131+
"ABC"
132+
].join, a.output_data)
133+
assert( ! a.closed_after_writing )
134+
end
135+
136+
def test_send_response_no_close_with_a_201_response
137+
a = EventMachine::HttpResponse.new
138+
a.status = 201
139+
a.content_type "text/plain"
140+
a.content = "ABC"
141+
a.keep_connection_open
142+
a.send_response
143+
assert_equal([
144+
"HTTP/1.1 201 ...\r\n",
145+
"Content-length: 3\r\n",
146+
"Content-type: text/plain\r\n",
147+
"\r\n",
148+
"ABC"
149+
].join, a.output_data)
150+
assert( ! a.closed_after_writing )
151+
end
152+
153+
def test_send_response_no_close_with_a_500_response
154+
a = EventMachine::HttpResponse.new
155+
a.status = 500
156+
a.content_type "text/plain"
157+
a.content = "ABC"
158+
a.keep_connection_open
159+
a.send_response
160+
assert_equal([
161+
"HTTP/1.1 500 ...\r\n",
162+
"Content-length: 3\r\n",
163+
"Content-type: text/plain\r\n",
164+
"\r\n",
165+
"ABC"
166+
].join, a.output_data)
167+
assert( a.closed_after_writing )
168+
end
169+
119170
def test_send_response_multiple_times
120171
a = EventMachine::HttpResponse.new
121172
a.status = 200

0 commit comments

Comments
 (0)