clogger 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/GNUmakefile CHANGED
@@ -32,6 +32,45 @@ test: test-ext test-pure
32
32
  Manifest.txt:
33
33
  git ls-files > $@+
34
34
  cmp $@+ $@ || mv $@+ $@
35
- $(RM) -f $@+
35
+ $(RM) $@+
36
36
 
37
- .PHONY: test doc Manifest.txt
37
+ VERSION := $(shell git describe 2>/dev/null | sed 's/^v//')
38
+
39
+ ifneq ($(VERSION),)
40
+ v := /^v$(VERSION)$$/
41
+ vPREV := $(shell git tag -l 2>/dev/null | sed -n -e '$(v)!h' -e '$(v){x;p;q}')
42
+ release_notes := release_notes-$(VERSION).txt
43
+ release_changes := release_changes-$(VERSION).txt
44
+ $(release_changes): verify
45
+ git diff --stat $(vPREV) v$(VERSION) > $@+
46
+ echo >> $@+
47
+ git log $(vPREV) v$(VERSION) >> $@+
48
+ $(VISUAL) $@+ && test -s $@+ && mv $@+ $@
49
+ $(release_notes): verify package
50
+ gem spec pkg/clogger-$(VERSION).gem description | sed -ne '/\w/p' > $@+
51
+ git cat-file tag v$(VERSION) | awk 'p>1{print $$0}/^$$/{++p}' >> $@+
52
+ $(VISUAL) $@+ && test -s $@+ && mv $@+ $@
53
+ verify:
54
+ @test -n "$(VERSION)" || { echo >&2 VERSION= not defined; exit 1; }
55
+ git rev-parse --verify refs/tags/v$(VERSION)^{}
56
+ @test -n "$(VISUAL)" || { echo >&2 VISUAL= not defined; exit 1; }
57
+
58
+ package: verify
59
+ git diff-index --quiet HEAD^0
60
+ test `git rev-parse --verify HEAD^0` = \
61
+ `git rev-parse --verify refs/tags/v$(VERSION)^{}`
62
+ $(RM) -r pkg
63
+ unset CLOGGER_EXT; rake package VERSION=$(VERSION)
64
+ CLOGGER_EXT=1 rake package VERSION=$(VERSION)
65
+
66
+ # not using Hoe's release system since we release 2 gems but only one tgz
67
+ release: package Manifest.txt $(release_notes) $(release_changes)
68
+ rubyforge add_release -f -n $(release_notes) -c $(release_changes) \
69
+ clogger clogger $(VERSION) pkg/clogger-$(VERSION).gem
70
+ rubyforge add_file \
71
+ clogger clogger $(VERSION) pkg/clogger-$(VERSION).tgz
72
+ rubyforge add_release -f -n $(release_notes) -c $(release_changes) \
73
+ clogger clogger_ext $(VERSION) pkg/clogger_ext-$(VERSION).gem
74
+ endif
75
+
76
+ .PHONY: test doc Manifest.txt release
data/History.txt CHANGED
@@ -1,3 +1,10 @@
1
+ === 0.0.2 / 2009-08-29
2
+
3
+ * 2 bug fixes
4
+
5
+ * support "$request_uri" as a log variable
6
+ * Log bad/invalid app responses as 500 errors
7
+
1
8
  === 0.0.1 / 2009-08-28
2
9
 
3
10
  * 1 major enhancement
@@ -54,7 +54,8 @@ enum clogger_special {
54
54
  CL_SP_request_length,
55
55
  CL_SP_response_length,
56
56
  CL_SP_ip,
57
- CL_SP_pid
57
+ CL_SP_pid,
58
+ CL_SP_request_uri,
58
59
  };
59
60
 
60
61
  struct clogger {
@@ -92,6 +93,7 @@ static VALUE g_HTTP_X_FORWARDED_FOR;
92
93
  static VALUE g_REMOTE_ADDR;
93
94
  static VALUE g_REQUEST_METHOD;
94
95
  static VALUE g_PATH_INFO;
96
+ static VALUE g_REQUEST_URI;
95
97
  static VALUE g_QUERY_STRING;
96
98
  static VALUE g_HTTP_VERSION;
97
99
  static VALUE g_rack_errors;
@@ -102,6 +104,7 @@ static VALUE g_empty;
102
104
  static VALUE g_space;
103
105
  static VALUE g_question_mark;
104
106
  static VALUE g_rack_request_cookie_hash;
107
+ static VALUE g_bad_app_response;
105
108
 
106
109
  #define LOG_BUF_INIT_SIZE 128
107
110
 
@@ -410,30 +413,44 @@ static void append_time_fmt(struct clogger *c, const VALUE *op)
410
413
  append_tv(c, op, &now);
411
414
  }
412
415
 
416
+ static void append_request_uri(struct clogger *c)
417
+ {
418
+ VALUE tmp;
419
+
420
+ tmp = rb_hash_aref(c->env, g_REQUEST_URI);
421
+ if (NIL_P(tmp)) {
422
+ tmp = rb_hash_aref(c->env, g_PATH_INFO);
423
+ if (!NIL_P(tmp))
424
+ rb_str_buf_append(c->log_buf, byte_xs(tmp));
425
+ tmp = rb_hash_aref(c->env, g_QUERY_STRING);
426
+ if (!NIL_P(tmp) && RSTRING_LEN(tmp) != 0) {
427
+ rb_str_buf_append(c->log_buf, g_question_mark);
428
+ rb_str_buf_append(c->log_buf, byte_xs(tmp));
429
+ }
430
+ } else {
431
+ rb_str_buf_append(c->log_buf, byte_xs(tmp));
432
+ }
433
+ }
434
+
413
435
  static void append_request(struct clogger *c)
414
436
  {
415
437
  VALUE tmp;
416
- VALUE env = c->env;
417
438
 
418
439
  /* REQUEST_METHOD doesn't need escaping, Rack::Lint governs it */
419
- tmp = rb_hash_aref(env, g_REQUEST_METHOD);
420
- rb_str_buf_append(c->log_buf, NIL_P(tmp) ? g_empty : tmp);
440
+ tmp = rb_hash_aref(c->env, g_REQUEST_METHOD);
441
+ if (!NIL_P(tmp))
442
+ rb_str_buf_append(c->log_buf, tmp);
443
+
421
444
  rb_str_buf_append(c->log_buf, g_space);
422
445
 
423
- /* broken clients can send " and other questionable URIs */
424
- tmp = rb_hash_aref(env, g_PATH_INFO);
425
- rb_str_buf_append(c->log_buf, NIL_P(tmp) ? g_empty : byte_xs(tmp));
446
+ append_request_uri(c);
426
447
 
427
- tmp = rb_hash_aref(env, g_QUERY_STRING);
428
- if (RSTRING_LEN(tmp) != 0) {
429
- rb_str_buf_append(c->log_buf, g_question_mark);
430
- rb_str_buf_append(c->log_buf, byte_xs(tmp));
431
- }
432
448
  rb_str_buf_append(c->log_buf, g_space);
433
449
 
434
450
  /* HTTP_VERSION can be injected by malicious clients */
435
- tmp = rb_hash_aref(env, g_HTTP_VERSION);
436
- rb_str_buf_append(c->log_buf, NIL_P(tmp) ? g_empty : byte_xs(tmp));
451
+ tmp = rb_hash_aref(c->env, g_HTTP_VERSION);
452
+ if (!NIL_P(tmp))
453
+ rb_str_buf_append(c->log_buf, byte_xs(tmp));
437
454
  }
438
455
 
439
456
  static void append_request_length(struct clogger *c)
@@ -538,6 +555,9 @@ static void special_var(struct clogger *c, enum clogger_special var)
538
555
  break;
539
556
  case CL_SP_pid:
540
557
  append_pid(c);
558
+ break;
559
+ case CL_SP_request_uri:
560
+ append_request_uri(c);
541
561
  }
542
562
  }
543
563
 
@@ -703,10 +723,21 @@ static VALUE clogger_fileno(VALUE self)
703
723
 
704
724
  static void ccall(struct clogger *c, VALUE env)
705
725
  {
726
+ VALUE rv;
727
+
706
728
  gettimeofday(&c->tv_start, NULL);
707
729
  c->env = env;
708
730
  c->cookies = Qfalse;
709
- c->response = rb_funcall(c->app, call_id, 1, env);
731
+ rv = rb_funcall(c->app, call_id, 1, env);
732
+ if (TYPE(rv) == T_ARRAY && RARRAY_LEN(rv) == 3) {
733
+ c->response = rv;
734
+ } else {
735
+ c->response = g_bad_app_response;
736
+ cwrite(c);
737
+ rb_raise(rb_eTypeError,
738
+ "app response not a 3 element Array: %s",
739
+ RSTRING_PTR(rb_inspect(rv)));
740
+ }
710
741
  }
711
742
 
712
743
  /*
@@ -763,6 +794,16 @@ static VALUE clogger_init_copy(VALUE clone, VALUE orig)
763
794
 
764
795
  #define CONST_GLOBAL_STR(val) CONST_GLOBAL_STR2(val, #val)
765
796
 
797
+ static void init_bad_response(void)
798
+ {
799
+ g_bad_app_response = rb_ary_new();
800
+ rb_ary_store(g_bad_app_response, 0, INT2NUM(500));
801
+ rb_ary_store(g_bad_app_response, 1, rb_obj_freeze(rb_hash_new()));
802
+ rb_ary_store(g_bad_app_response, 2, rb_obj_freeze(rb_ary_new()));
803
+ rb_obj_freeze(g_bad_app_response);
804
+ rb_global_variable(&g_bad_app_response);
805
+ }
806
+
766
807
  void Init_clogger_ext(void)
767
808
  {
768
809
  ltlt_id = rb_intern("<<");
@@ -788,6 +829,7 @@ void Init_clogger_ext(void)
788
829
  CONST_GLOBAL_STR(REQUEST_METHOD);
789
830
  CONST_GLOBAL_STR(PATH_INFO);
790
831
  CONST_GLOBAL_STR(QUERY_STRING);
832
+ CONST_GLOBAL_STR(REQUEST_URI);
791
833
  CONST_GLOBAL_STR(HTTP_VERSION);
792
834
  CONST_GLOBAL_STR2(rack_errors, "rack.errors");
793
835
  CONST_GLOBAL_STR2(rack_input, "rack.input");
@@ -797,4 +839,5 @@ void Init_clogger_ext(void)
797
839
  CONST_GLOBAL_STR2(space, " ");
798
840
  CONST_GLOBAL_STR2(question_mark, "?");
799
841
  CONST_GLOBAL_STR2(rack_request_cookie_hash, "rack.request.cookie_hash");
842
+ init_bad_response();
800
843
  }
data/lib/clogger.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: binary -*-
2
2
  class Clogger
3
- VERSION = '0.0.1'
3
+ VERSION = '0.0.2'
4
4
 
5
5
  OP_LITERAL = 0
6
6
  OP_REQUEST = 1
@@ -29,6 +29,7 @@ class Clogger
29
29
  :response_length => 4, # like body_bytes_sent, except "-" instead of "0"
30
30
  :ip => 5, # HTTP_X_FORWARDED_FOR || REMOTE_ADDR || -
31
31
  :pid => 6, # getpid()
32
+ :request_uri => 7
32
33
  }
33
34
 
34
35
  private
data/lib/clogger/pure.rb CHANGED
@@ -16,7 +16,12 @@ class Clogger
16
16
 
17
17
  def call(env)
18
18
  @start = Time.now
19
- status, headers, body = @app.call(env)
19
+ resp = @app.call(env)
20
+ unless resp.instance_of?(Array) && resp.size == 3
21
+ log(env, 500, {})
22
+ raise TypeError, "app response not a 3 element Array: #{resp.inspect}"
23
+ end
24
+ status, headers, body = resp
20
25
  if wrap_body?
21
26
  @reentrant = env['rack.multithread']
22
27
  @env, @status, @headers, @body = env, status, headers, body
@@ -63,6 +68,13 @@ private
63
68
 
64
69
  SPECIAL_RMAP = SPECIAL_VARS.inject([]) { |ary, (k,v)| ary[v] = k; ary }
65
70
 
71
+ def request_uri(env)
72
+ ru = env['REQUEST_URI'] and return byte_xs(ru)
73
+ qs = env['QUERY_STRING']
74
+ qs.empty? or qs = "?#{byte_xs(qs)}"
75
+ "#{byte_xs(env['PATH_INFO'])}#{qs}"
76
+ end
77
+
66
78
  def special_var(special_nr, env, status, headers)
67
79
  case SPECIAL_RMAP[special_nr]
68
80
  when :body_bytes_sent
@@ -74,8 +86,10 @@ private
74
86
  qs = env['QUERY_STRING']
75
87
  qs.empty? or qs = "?#{byte_xs(qs)}"
76
88
  "#{env['REQUEST_METHOD']} " \
77
- "#{byte_xs(env['PATH_INFO'])}#{qs} " \
89
+ "#{request_uri(env)} " \
78
90
  "#{byte_xs(env['HTTP_VERSION'])}"
91
+ when :request_uri
92
+ request_uri(env)
79
93
  when :request_length
80
94
  env['rack.input'].size.to_s
81
95
  when :response_length
data/test/test_clogger.rb CHANGED
@@ -333,6 +333,22 @@ class TestClogger < Test::Unit::TestCase
333
333
  assert_equal expect, str.string
334
334
  end
335
335
 
336
+ def test_request_uri_fallback
337
+ str = StringIO.new
338
+ app = lambda { |env| [ 200, {}, [] ] }
339
+ cl = Clogger.new(app, :logger => str, :format => '$request_uri')
340
+ status, headers, body = cl.call(@req)
341
+ assert_equal "/hello?goodbye=true\n", str.string
342
+ end
343
+
344
+ def test_request_uri_set
345
+ str = StringIO.new
346
+ app = lambda { |env| [ 200, {}, [] ] }
347
+ cl = Clogger.new(app, :logger => str, :format => '$request_uri')
348
+ status, headers, body = cl.call(@req.merge("REQUEST_URI" => '/zzz'))
349
+ assert_equal "/zzz\n", str.string
350
+ end
351
+
336
352
  def test_cookies
337
353
  str = StringIO.new
338
354
  app = lambda { |env|
@@ -346,4 +362,15 @@ class TestClogger < Test::Unit::TestCase
346
362
  status, headers, body = cl.call(req)
347
363
  assert_equal "bar h&m\n", str.string
348
364
  end
365
+
366
+ def test_bogus_app_response
367
+ str = StringIO.new
368
+ app = lambda { |env| 302 }
369
+ cl = Clogger.new(app, :logger => str)
370
+ assert_raise(TypeError) { cl.call(@req) }
371
+ str = str.string
372
+ e = Regexp.quote " \"GET /hello?goodbye=true HTTP/1.0\" 500 -"
373
+ assert_match %r{#{e}$}m, str
374
+ end
375
+
349
376
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clogger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Wong
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-08-28 00:00:00 -07:00
12
+ date: 2009-08-29 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency