summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2015-04-15 16:13:28 +0200
committerYorhel <git@yorhel.nl>2015-04-15 16:13:28 +0200
commit9be26a14f27dedf08d899bca7ce32bfc7b6e8ffa (patch)
tree08fc259d747f8f6f26c86261e48bcedf356f6501
parent6dbe06df5905ab76c070fe829980f61b87e413ca (diff)
vhost2ident + parsetm
-rw-r--r--src/lib.rs38
-rw-r--r--src/parser.rs6
2 files changed, 40 insertions, 4 deletions
diff --git a/src/lib.rs b/src/lib.rs
index e129a5f..aacde83 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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");