diff options
author | Yorhel <git@yorhel.nl> | 2015-04-15 16:13:28 +0200 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2015-04-15 16:13:28 +0200 |
commit | 9be26a14f27dedf08d899bca7ce32bfc7b6e8ffa (patch) | |
tree | 08fc259d747f8f6f26c86261e48bcedf356f6501 | |
parent | 6dbe06df5905ab76c070fe829980f61b87e413ca (diff) |
vhost2ident + parsetm
-rw-r--r-- | src/lib.rs | 38 | ||||
-rw-r--r-- | src/parser.rs | 6 |
2 files changed, 40 insertions, 4 deletions
@@ -1,5 +1,6 @@ #![feature(test)] extern crate test; +extern crate time; mod parser; @@ -7,7 +8,7 @@ pub struct Line<'a> { host: &'a str, ident: &'a str, user: &'a str, - date: &'a str, + tm: &'a str, method: &'a str, path: &'a str, proto: &'a str, @@ -22,4 +23,39 @@ impl<'a> Line<'a> { pub fn new(line: &str) -> Result<Line, ()> { parser::Parser::new(line).parse() } + + // Lighttpd by default stores the vhost in the ident field. Some other servers (notably + // varnishncsa) instead store a full URL in the path field. This function normalizes those two + // variations into the Lighttpd version: If the path is a full URL, the ident field will be + // updated to point to the hostname of the URL, and the path field is updated to only list the + // path component. This function does nothing if the path field isn't a full URL. + pub fn vhost2ident(&mut self) { + let start = if self.path.starts_with("http://") { 7 } + else if self.path.starts_with("https://") { 8 } else { return }; + for (i, c) in (&self.path[start..]).char_indices() { + if c == '/' { + self.ident = &self.path[start..i+start]; + self.path = &self.path[i+start..]; + return; + } + } + } + + pub fn parsetm(&self) -> Result<time::Tm, time::ParseError> { + time::strptime(self.tm, "%d/%b/%Y:%H:%M:%S %z") + } +} + + +#[test] +fn test_vhost2ident() { + let mut l = Line::new("host - user [tm] \"method http://blicky.net/ proto\" 200 1").unwrap(); + l.vhost2ident(); + assert_eq!(l.ident, "blicky.net"); + assert_eq!(l.path, "/"); + + let mut l = Line::new("host - user [tm] \"method https://whatever.blicky.net/Longer_path?with_stuff proto\" 200 1").unwrap(); + l.vhost2ident(); + assert_eq!(l.ident, "whatever.blicky.net"); + assert_eq!(l.path, "/Longer_path?with_stuff"); } diff --git a/src/parser.rs b/src/parser.rs index 4230498..faa15da 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -98,7 +98,7 @@ impl<'a> Parser<'a> { host: try!(self.uptochar(32, false)), ident: try!(self.uptochar(32, false)), user: try!(self.uptochar(32, false)), - date: { try!(self.consume(91)); try!(self.uptochar(93, false)) }, + tm: { try!(self.consume(91)); try!(self.uptochar(93, false)) }, method: { try!(self.consume(32)); try!(self.consume(34)); try!(self.uptochar(32, false)) }, path: try!(self.uptochar(32, false)), proto: try!(self.uptochar(34, false)), @@ -120,7 +120,7 @@ fn test_extended() { assert_eq!(line.host, "host"); assert_eq!(line.ident, "ident"); assert_eq!(line.user, "user"); - assert_eq!(line.date, "da te"); + assert_eq!(line.tm, "da te"); assert_eq!(line.method, "method"); assert_eq!(line.path, "path"); assert_eq!(line.proto, "proto"); @@ -140,7 +140,7 @@ fn test_common() { assert_eq!(line.host, "host"); assert_eq!(line.ident, "ident"); assert_eq!(line.user, "user"); - assert_eq!(line.date, "date"); + assert_eq!(line.tm, "date"); assert_eq!(line.method, "method"); assert_eq!(line.path, "path"); assert_eq!(line.proto, "proto"); |