about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2013-07-12 02:53:17 +0000
committerEric Wong <normalperson@yhbt.net>2013-07-12 06:44:08 +0000
commit0e5d6c6f4b28a75853d1020f07e493632031a054 (patch)
tree42e6fca7a5ffcaf7dfc1aa4efbab47081dfde0f3
parent1c9fe8380f14e2b67bed99d16ef465db8d379b41 (diff)
downloadcmogstored-0e5d6c6f4b28a75853d1020f07e493632031a054.tar.gz
This is Perlbal functionality which works in Perl mogstored,
so we will also support it here, as it makes upgrading to new
versions easier.
-rw-r--r--cmogstored.h1
-rw-r--r--http_parser.rl5
-rw-r--r--mgmt_parser.rl19
-rw-r--r--svc.c1
-rw-r--r--test/http-parser-1.c4
-rw-r--r--test/mgmt_persist_client.rb64
-rw-r--r--test/ruby.mk2
7 files changed, 91 insertions, 5 deletions
diff --git a/cmogstored.h b/cmogstored.h
index 8bbff90..5b4493b 100644
--- a/cmogstored.h
+++ b/cmogstored.h
@@ -155,6 +155,7 @@ struct mog_svc;
 struct mog_svc {
         int docroot_fd;
         const char *docroot;
+        unsigned persist_client;
         size_t nmogdev;
         size_t user_set_aio_threads; /* only touched by main/notify thread */
         size_t user_req_aio_threads; /* protected by aio_threads_lock */
diff --git a/http_parser.rl b/http_parser.rl
index 0622d62..ef854ba 100644
--- a/http_parser.rl
+++ b/http_parser.rl
@@ -170,6 +170,9 @@ mog_http_parse(struct mog_http *http, char *buf, size_t len)
         assert(p <= pe && "buffer overflow after http parse");
         assert(http->_p.buf_off <= len && "offset longer than len");
 
-        if (http->cs == http_parser_first_final) return MOG_PARSER_DONE;
+        if (http->cs == http_parser_first_final) {
+                http->_p.persistent &= http->svc->persist_client;
+                return MOG_PARSER_DONE;
+        }
         return MOG_PARSER_CONTINUE;
 }
diff --git a/mgmt_parser.rl b/mgmt_parser.rl
index 075a057..e40e82b 100644
--- a/mgmt_parser.rl
+++ b/mgmt_parser.rl
@@ -62,13 +62,30 @@ static void set_prio_fsck(struct mog_mgmt *mgmt)
                 eor > { mgmt->mark[1] = fpc - buf; }
                 @ { mog_mgmt_fn_aio_threads(mgmt, buf); fbreak; }
         );
+
+        true_val = ('1'|'true'|'yes'|'on');
+        false_val = ('0'|'false'|'no'|'off');
+
+        persist_client = (
+                "set mogstored.persist_client"i ' '?'='(' ')?
+                (
+                        (true_val) @ { mgmt->svc->persist_client = true; }
+                        |
+                        (false_val) @ { mgmt->svc->persist_client = false; }
+                )
+                eor
+                @ {
+                        mog_mgmt_fn_blank(mgmt);
+                        fbreak;
+                }
+        );
         blank = [ \t]* eor @ { mog_mgmt_fn_blank(mgmt); fbreak; };
         shutdown = "shutdown" (" "+"graceful")? eor @ {
                 cmogstored_quit();
                 fbreak;
         };
 
-        command = (digest|size|watch|aio_threads|shutdown|blank);
+        command = (digest|size|watch|aio_threads|persist_client|shutdown|blank);
         main := command $! {
                 p = buf;
                 fhold;
diff --git a/svc.c b/svc.c
index 47fb9f7..7d6a6ac 100644
--- a/svc.c
+++ b/svc.c
@@ -99,6 +99,7 @@ struct mog_svc * mog_svc_new(const char *docroot)
                 svc_once();
 
         svc = xzalloc(sizeof(struct mog_svc));
+        svc->persist_client = 1;
         svc->docroot = docroot;
         svc->docroot_fd = fd;
         svc->dir = dir;
diff --git a/test/http-parser-1.c b/test/http-parser-1.c
index 053237a..138dc7f 100644
--- a/test/http-parser-1.c
+++ b/test/http-parser-1.c
@@ -3,7 +3,7 @@
  * License: GPLv3 or later (see COPYING for details)
  */
 #include "check.h"
-
+static struct mog_svc svc = { .persist_client = 1 };
 static struct mog_http xhttp;
 static struct mog_http *http = &xhttp;
 static char *buf;
@@ -21,7 +21,7 @@ static void assert_path_equal(const char *str)
 static void reset(void)
 {
         free(buf);
-        mog_http_init(http, NULL);
+        mog_http_init(http, &svc);
 }
 
 static void buf_set(const char *s)
diff --git a/test/mgmt_persist_client.rb b/test/mgmt_persist_client.rb
new file mode 100644
index 0000000..00c59f7
--- /dev/null
+++ b/test/mgmt_persist_client.rb
@@ -0,0 +1,64 @@
+#!/usr/bin/env ruby
+# -*- encoding: binary -*-
+require 'test/test_helper'
+require 'net/http'
+
+class TestMgmtPersistClient < Test::Unit::TestCase
+  def setup
+    @tmpdir = Dir.mktmpdir('mgmt-persist-client-test')
+    @host = TEST_HOST
+
+    srv = TCPServer.new(@host, 0)
+    @port = srv.addr[1]
+    srv.close
+
+    srv = TCPServer.new(@host, 0)
+    @httpport = srv.addr[1]
+    srv.close
+
+    @pid = nil
+    @to_close = []
+    @err = Tempfile.new("stderr")
+    Dir.mkdir("#@tmpdir/dev666")
+    cmd = [ "cmogstored", "--docroot=#@tmpdir", "--mgmtlisten=#@host:#@port",
+            "--httplisten=#@host:#@httpport",
+            "--maxconns=500" ]
+    vg = ENV["VALGRIND"] and cmd = vg.split(/\s+/).concat(cmd)
+    @pid = fork {
+      $stderr.reopen(@err)
+      @err.close
+      exec(*cmd)
+    }
+    @client = get_client
+  end
+
+  def test_persist_toggle
+    {
+      "off" => "on",
+      "false" => "true",
+      "0" => "1",
+      "no" => "yes",
+    }.each do |f,t|
+      @client.write "SET mogstored.persist_client = #{f}\r\n"
+      assert_equal "\r\n", @client.gets
+      Net::HTTP.start(@host, @httpport) do |http|
+        resp = http.request(Net::HTTP::Head.new('/'))
+        assert_kind_of Net::HTTPOK, resp
+        assert_equal "close", resp["Connection"]
+      end
+
+      @client.write "SET mogstored.persist_client = #{t}\r\n"
+      assert_equal "\r\n", @client.gets
+      Net::HTTP.start(@host, @httpport) do |http|
+        resp = http.request(Net::HTTP::Head.new('/'))
+        assert_kind_of Net::HTTPOK, resp
+        assert_equal "keep-alive", resp["Connection"]
+      end
+    end
+  end
+
+  def teardown
+    @to_close.each { |io| io.close unless io.closed? }
+    FileUtils.rm_rf(@tmpdir)
+  end
+end
diff --git a/test/ruby.mk b/test/ruby.mk
index 5e1a1ca..9280414 100644
--- a/test/ruby.mk
+++ b/test/ruby.mk
@@ -1,6 +1,6 @@
 RB_TESTS_FAST = test/cmogstored-cfg.rb test/http_dav.rb test/http_range.rb \
   test/http_put.rb test/http_getonly.rb test/inherit.rb test/upgrade.rb \
-  test/http_put6_fail.rb test/epoll_enospc.rb
+  test/http_put6_fail.rb test/epoll_enospc.rb test/mgmt_persist_client.rb
 RB_TESTS_SLOW = test/mgmt-usage.rb test/mgmt.rb test/mgmt-iostat.rb \
  test/http.rb test/http_put_slow.rb test/http_chunked_put.rb \
  test/graceful_quit.rb test/http_idle_expire.rb \