Commit 990acc30 authored by Wandenberg's avatar Wandenberg

change padding on eventsource mode to be a comment instead of a CRLF

parent 5c80c3f4
...@@ -242,6 +242,7 @@ struct ngx_http_push_stream_shm_data_s { ...@@ -242,6 +242,7 @@ struct ngx_http_push_stream_shm_data_s {
ngx_shm_zone_t *ngx_http_push_stream_global_shm_zone = NULL; ngx_shm_zone_t *ngx_http_push_stream_global_shm_zone = NULL;
ngx_str_t **ngx_http_push_stream_module_paddings_chunks = NULL; ngx_str_t **ngx_http_push_stream_module_paddings_chunks = NULL;
ngx_str_t **ngx_http_push_stream_module_paddings_chunks_for_eventsource = NULL;
// channel // channel
static ngx_int_t ngx_http_push_stream_send_response_all_channels_info_summarized(ngx_http_request_t *r); static ngx_int_t ngx_http_push_stream_send_response_all_channels_info_summarized(ngx_http_request_t *r);
......
require 'spec_helper' require 'spec_helper'
describe "Subscriber Padding by user agent" do describe "Subscriber Padding by user agent" do
let(:config) do let(:default_config) do
{ {
:padding_by_user_agent => "[T|t]est 1,1024,508:[T|t]est 2,4097,0", :padding_by_user_agent => "[T|t]est 1,0,508",
:user_agent => nil, :user_agent => nil,
:subscriber_connection_ttl => '1s', :subscriber_connection_ttl => '1s',
:header_template => nil, :header_template => nil,
...@@ -12,128 +12,139 @@ describe "Subscriber Padding by user agent" do ...@@ -12,128 +12,139 @@ describe "Subscriber Padding by user agent" do
} }
end end
it "should apply a padding to the header" do shared_examples_for "apply padding" do
channel = 'ch_test_header_padding' it "should apply a padding to the header" do
channel = 'ch_test_header_padding'
nginx_run_server(config.merge(:header_template => "0123456789")) do |conf| nginx_run_server(config.merge(:header_template => "0123456789", :padding_by_user_agent => "[T|t]est 1,1024,508:[T|t]est 2,4097,0")) do |conf|
EventMachine.run do EventMachine.run do
sub_1 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 1") expected_size = conf.header_template.size + header_delta
sub_1.callback do
sub_1.should be_http_status(200)
sub_1.response.size.should eql(1100 + conf.header_template.size)
sub_2 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 2") sub_1 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 1")
sub_2.callback do sub_1.callback do
sub_2.should be_http_status(200) sub_1.should be_http_status(200)
sub_2.response.size.should eql(4097 + conf.header_template.size) sub_1.response.size.should eql(1100 + expected_size)
sub_1.response.should match padding_pattern
sub_3 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 3") sub_2 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 2")
sub_3.callback do sub_2.callback do
sub_3.should be_http_status(200) sub_2.should be_http_status(200)
sub_3.response.size.should eql(conf.header_template.size) sub_2.response.size.should eql(4097 + expected_size)
EventMachine.stop sub_3 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 3")
sub_3.callback do
sub_3.should be_http_status(200)
sub_3.response.size.should eql(expected_size)
EventMachine.stop
end
end end
end end
end end
end end
end end
end
it "should apply a padding to the message" do
channel = 'ch_test_message_padding'
body = "0123456789" it "should apply a padding to the message" do
channel = 'ch_test_message_padding'
nginx_run_server(config) do |conf| body = "0123456789"
EventMachine.run do
sub_1 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 1")
sub_1.callback {
sub_1.should be_http_status(200)
sub_1.response.size.should eql(500 + body.size)
sub_2 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 2") nginx_run_server(config) do |conf|
sub_2.callback { EventMachine.run do
sub_2.should be_http_status(200) expected_size = body.size + header_delta + body_delta
sub_2.response.size.should eql(body.size)
sub_3 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 3") sub_1 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 1")
sub_3.callback { sub_1.callback {
sub_3.should be_http_status(200) sub_1.should be_http_status(200)
sub_3.response.size.should eql(body.size) sub_1.response.size.should eql(500 + expected_size)
sub_1.response.should match padding_pattern
EventMachine.stop
sub_2 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 2")
sub_2.callback {
sub_2.should be_http_status(200)
sub_2.response.size.should eql(expected_size)
sub_3 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 3")
sub_3.callback {
sub_3.should be_http_status(200)
sub_3.response.size.should eql(expected_size)
EventMachine.stop
}
publish_message_inline(channel, headers, body)
} }
publish_message_inline(channel, headers, body) publish_message_inline(channel, headers, body)
} }
publish_message_inline(channel, headers, body) publish_message_inline(channel, headers, body)
} end
publish_message_inline(channel, headers, body)
end end
end end
end
it "should apply a padding to the message with different sizes" do
channel = 'ch_test_message_padding_with_different_sizes'
nginx_run_server(config.merge(:padding_by_user_agent => "[T|t]est 1,0,545"), :timeout => 10) do |conf| it "should apply a padding to the message with different sizes" do
EventMachine.run do channel = 'ch_test_message_padding_with_different_sizes'
i = 1
expected_padding = 545
sub_1 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 1") nginx_run_server(config.merge(:padding_by_user_agent => "[T|t]est 1,0,545"), :timeout => 10) do |conf|
sub_1.callback do EventMachine.run do
sub_1.should be_http_status(200) i = 1
sub_1.response.size.should eql(expected_padding + i) expected_padding = 545
expected_size = header_delta + body_delta
i = 105
expected_padding = 600 - ((i/100).to_i * 100)
sub_1 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 1") sub_1 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 1")
sub_1.callback do sub_1.callback do
sub_1.should be_http_status(200) sub_1.should be_http_status(200)
sub_1.response.size.should eql(expected_padding + i) sub_1.response.size.should eql(expected_padding + i + expected_size)
sub_1.response.should match padding_pattern
i = 221 i = 105
expected_padding = 600 - ((i/100).to_i * 100) expected_padding = 600 - ((i/100).to_i * 100)
sub_1 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 1") sub_1 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 1")
sub_1.callback do sub_1.callback do
sub_1.should be_http_status(200) sub_1.should be_http_status(200)
sub_1.response.size.should eql(expected_padding + i) sub_1.response.size.should eql(expected_padding + i + expected_size)
i = 331 i = 221
expected_padding = 600 - ((i/100).to_i * 100) expected_padding = 600 - ((i/100).to_i * 100)
sub_1 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 1") sub_1 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 1")
sub_1.callback do sub_1.callback do
sub_1.should be_http_status(200) sub_1.should be_http_status(200)
sub_1.response.size.should eql(expected_padding + i) sub_1.response.size.should eql(expected_padding + i + expected_size)
i = 435 i = 331
expected_padding = 600 - ((i/100).to_i * 100) expected_padding = 600 - ((i/100).to_i * 100)
sub_1 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 1") sub_1 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 1")
sub_1.callback do sub_1.callback do
sub_1.should be_http_status(200) sub_1.should be_http_status(200)
sub_1.response.size.should eql(expected_padding + i) sub_1.response.size.should eql(expected_padding + i + expected_size)
i = 502 i = 435
expected_padding = 600 - ((i/100).to_i * 100) expected_padding = 600 - ((i/100).to_i * 100)
sub_1 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 1") sub_1 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 1")
sub_1.callback do sub_1.callback do
sub_1.should be_http_status(200) sub_1.should be_http_status(200)
sub_1.response.size.should eql(expected_padding + i) sub_1.response.size.should eql(expected_padding + i + expected_size)
i = 550 i = 502
expected_padding = 600 - ((i/100).to_i * 100)
sub_1 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 1") sub_1 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 1")
sub_1.callback do sub_1.callback do
sub_1.should be_http_status(200) sub_1.should be_http_status(200)
sub_1.response.size.should eql(i) sub_1.response.size.should eql(expected_padding + i + expected_size)
i = 550
EventMachine.stop sub_1 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s).get :head => headers.merge("User-Agent" => "Test 1")
sub_1.callback do
sub_1.should be_http_status(200)
sub_1.response.size.should eql(i + expected_size)
EventMachine.stop
end
publish_message_inline(channel, headers, "_" * i)
end end
publish_message_inline(channel, headers, "_" * i) publish_message_inline(channel, headers, "_" * i)
end end
...@@ -147,30 +158,50 @@ describe "Subscriber Padding by user agent" do ...@@ -147,30 +158,50 @@ describe "Subscriber Padding by user agent" do
end end
publish_message_inline(channel, headers, "_" * i) publish_message_inline(channel, headers, "_" * i)
end end
publish_message_inline(channel, headers, "_" * i)
end end
end end
end
it "should accept the user agent set by a complex value" do it "should accept the user agent set by a complex value" do
channel = 'ch_test_user_agent_by_complex_value' channel = 'ch_test_user_agent_by_complex_value'
nginx_run_server(config.merge(:padding_by_user_agent => "[T|t]est 1,1024,512", :user_agent => "$arg_ua", :header_template => "0123456789"), :timeout => 10) do |conf| nginx_run_server(config.merge(:padding_by_user_agent => "[T|t]est 1,1024,512", :user_agent => "$arg_ua", :header_template => "0123456789"), :timeout => 10) do |conf|
EventMachine.run do EventMachine.run do
sub_1 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s + '?ua=test 1').get :head => headers expected_size = conf.header_template.size + header_delta
sub_1.callback do
sub_1.should be_http_status(200)
sub_1.response.size.should eql(1024 + conf.header_template.size)
sub_2 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s + '?ua=test 2').get :head => headers sub_1 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s + '?ua=test 1').get :head => headers
sub_2.callback do sub_1.callback do
sub_2.should be_http_status(200) sub_1.should be_http_status(200)
sub_2.response.size.should eql(conf.header_template.size) sub_1.response.size.should eql(1024 + expected_size)
sub_1.response.should match padding_pattern
EventMachine.stop sub_2 = EventMachine::HttpRequest.new(nginx_address + '/sub/' + channel.to_s + '?ua=test 2').get :head => headers
sub_2.callback do
sub_2.should be_http_status(200)
sub_2.response.size.should eql(expected_size)
EventMachine.stop
end
end end
end end
end end
end end
end end
describe "for non EventSource mode" do
let(:config) { default_config }
let(:padding_pattern) { /(\r\n)+\r\n\r\n\r\n$/ }
let(:header_delta) { 0 }
let(:body_delta) { 0 }
it_should_behave_like "apply padding"
end
describe "for EventSource mode" do
let(:config) { default_config.merge(:subscriber_mode => "eventsource") }
let(:padding_pattern) { /(:::)+\r\n$/ }
let(:header_delta) { 4 }
let(:body_delta) { 10 }
it_should_behave_like "apply padding"
end
end end
...@@ -380,7 +380,38 @@ ngx_http_push_stream_postconfig(ngx_conf_t *cf) ...@@ -380,7 +380,38 @@ ngx_http_push_stream_postconfig(ngx_conf_t *cf)
ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "push stream module: unable to allocate memory to create padding messages"); ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "push stream module: unable to allocate memory to create padding messages");
return NGX_ERROR; return NGX_ERROR;
} }
padding->data = aux->data; padding->data = &aux->data[aux->len - len];
padding->len = len;
len = i * 100;
}
}
if ((ngx_http_push_stream_padding_max_len > 0) && (ngx_http_push_stream_module_paddings_chunks_for_eventsource == NULL)) {
ngx_uint_t steps = ngx_http_push_stream_padding_max_len / 100;
if ((ngx_http_push_stream_module_paddings_chunks_for_eventsource = ngx_palloc(cf->pool, sizeof(ngx_str_t) * (steps + 1))) == NULL) {
ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "push stream module: unable to allocate memory to create padding messages for eventsource");
return NGX_ERROR;
}
u_int padding_max_len = ngx_http_push_stream_padding_max_len + ((ngx_http_push_stream_padding_max_len % 2) ? 1 : 0);
ngx_str_t *aux = ngx_http_push_stream_create_str(cf->pool, padding_max_len);
if (aux == NULL) {
ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "push stream module: unable to allocate memory to create padding messages value");
return NGX_ERROR;
}
ngx_memset(aux->data, ':', padding_max_len);
padding_max_len -= 2;
ngx_memcpy(aux->data + padding_max_len, CRLF, 2);
ngx_int_t i, len = ngx_http_push_stream_padding_max_len;
for (i = steps; i >= 0; i--) {
ngx_str_t *padding = ngx_pcalloc(cf->pool, sizeof(ngx_str_t));
if ((*(ngx_http_push_stream_module_paddings_chunks_for_eventsource + i) = padding) == NULL) {
ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "push stream module: unable to allocate memory to create padding messages");
return NGX_ERROR;
}
padding->data = &aux->data[aux->len - len];
padding->len = len; padding->len = len;
len = i * 100; len = i * 100;
} }
......
...@@ -648,11 +648,14 @@ static ngx_int_t ...@@ -648,11 +648,14 @@ static ngx_int_t
ngx_http_push_stream_send_response_padding(ngx_http_request_t *r, size_t len, ngx_flag_t sending_header) ngx_http_push_stream_send_response_padding(ngx_http_request_t *r, size_t len, ngx_flag_t sending_header)
{ {
ngx_http_push_stream_module_ctx_t *ctx = ngx_http_get_module_ctx(r, ngx_http_push_stream_module); ngx_http_push_stream_module_ctx_t *ctx = ngx_http_get_module_ctx(r, ngx_http_push_stream_module);
ngx_http_push_stream_loc_conf_t *pslcf = ngx_http_get_module_loc_conf(r, ngx_http_push_stream_module);
ngx_flag_t eventsource = (pslcf->location_type == NGX_HTTP_PUSH_STREAM_SUBSCRIBER_MODE_EVENTSOURCE);
if (ctx->padding != NULL) { if (ctx->padding != NULL) {
ngx_int_t diff = ((sending_header) ? ctx->padding->header_min_len : ctx->padding->message_min_len) - len; ngx_int_t diff = ((sending_header) ? ctx->padding->header_min_len : ctx->padding->message_min_len) - len;
if (diff > 0) { if (diff > 0) {
ngx_str_t *padding = *(ngx_http_push_stream_module_paddings_chunks + diff / 100); ngx_int_t padding_index = diff / 100;
ngx_str_t *padding = eventsource ? ngx_http_push_stream_module_paddings_chunks_for_eventsource[padding_index] : ngx_http_push_stream_module_paddings_chunks[padding_index];
ngx_http_push_stream_send_response_text(r, padding->data, padding->len, 0); ngx_http_push_stream_send_response_text(r, padding->data, padding->len, 0);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment