You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by bc...@apache.org on 2018/08/31 16:52:57 UTC

[trafficserver] branch master updated: Handly tool to decode via header

This is an automated email from the ASF dual-hosted git repository.

bcall pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new 5e4295c  Handly tool to decode via header
5e4295c is described below

commit 5e4295c65dc485abe3d121ac7cfed98799d929f9
Author: Meera Mosale Nataraja <me...@apple.com>
AuthorDate: Fri Jun 8 13:38:38 2018 -0700

    Handly tool to decode via header
---
 tools/traffic_via.pl | 277 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 277 insertions(+)

diff --git a/tools/traffic_via.pl b/tools/traffic_via.pl
new file mode 100755
index 0000000..6eee2a6
--- /dev/null
+++ b/tools/traffic_via.pl
@@ -0,0 +1,277 @@
+#!/usr/bin/env perl
+
+#   Licensed to the Apache Software Foundation (ASF) under one
+#   or more contributor license agreements.  See the NOTICE file
+#   distributed with this work for additional information
+#   regarding copyright ownership.  The ASF licenses this file
+#   to you under the Apache License, Version 2.0 (the
+#   "License"); you may not use this file except in compliance
+#   with the License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+# Script to decode via header
+#
+# @File traffic_via.pl
+# @Author Meera Mosale Nataraja
+#
+# Usage: Use it in 2 ways
+# 1. Pass Via Header with -s option \n";
+#    traffic_via [-s viaheader]";
+#           or
+# 2. Pipe curl output 
+#    curl -v -H "X-Debug: Via" http://ats_server:port 2>&1| ./traffic_via.pl
+# 
+
+use strict;
+use warnings;
+use Data::Dumper qw(Dumper);
+use Getopt::Long;
+
+my $via_header;
+my $help;
+
+#Proxy request header flags and titles
+my @proxy_header_array = (
+    {
+        "Request headers received from client:",
+        { 
+            'I' => "If Modified Since (IMS)",
+            'C' => "cookie",
+            'E' => "error in request",
+            'S' => "simple request (not conditional)",
+            'N' => "no-cache",
+            ' ' => "unknown?",
+        },
+    },
+   {
+        "Result of Traffic Server cache lookup for URL:",
+        {
+                   'A' => "in cache, not acceptable (a cache \"MISS\")",
+                   'H' => "in cache, fresh (a cache \"HIT\")",
+                   'S' => "in cache, stale (a cache \"MISS\")",
+                   'R' => "in cache, fresh Ram hit (a cache \"HIT\")",
+                   'M' => "miss (a cache \"MISS\")",
+                   ' ' => "unknown?",
+        },
+    },
+    {
+        "Response information received from origin server:",
+        {
+                    'E' => "error in response",
+                    ' ' => "no server connection needed",
+                    'S' => "served",
+                    'N'=> "not-modified",
+        }
+    },
+    {
+        "Result of document write-to-cache:",
+        {
+                    'U' => "updated old cache copy",
+                    'D' => "cached copy deleted",
+                    'W' => "written into cache (new copy)",
+                    ' ' => "no cache write performed",
+        },
+    },
+    {
+        "Proxy operation result:",
+        { 
+                    'R' => "origin server revalidated",
+                    ' ' => "unknown?",
+                    'S' => "served",
+                    'N' => "not-modified",
+        },
+    },
+    {
+        "Error codes (if any):",
+        {
+                    'A' => "authorization failure",
+                    'H' => "header syntax unacceptable",
+                    'C' => "connection to server failed",
+                    'T' => "connection timed out",
+                    'S' => "server related error",
+                    'D' => "dns failure",
+                    'N' => "no error",
+                    'F' => "request forbidden",
+        },
+    },
+    {
+        "Tunnel info:",
+        {
+                    ' ' => "no tunneling",
+                    'U' => "tunneling because of url (url suggests dynamic content)",
+                    'M' => "tunneling due to a method (e.g. CONNECT)",
+                    'O' => "tunneling because cache is turned off",
+                    'F' => "tunneling due to a header field (such as presence of If-Range header)",
+        },
+   },
+   {
+        "Cache type:",
+        {
+                    'I' => "icp",
+                    ' ' => "cache miss or no cache lookup",
+                    'C' => "cache",
+        },
+   },
+   {
+        "Cache lookup result:",
+        {
+                    ' ' => "no cache lookup",
+                    'S' => "cache hit, but expired",
+                    'U' => "cache hit, but client forces revalidate (e.g. Pragma: no-cache)",
+                    'D' => "cache hit, but method forces revalidated (e.g. ftp, not anonymous)",
+                    'I' => "conditional miss (client sent conditional, fresh in cache, returned 412)",
+                    'H' => "cache hit",
+                    'M' => "cache miss (url not in cache)",
+                    'C' => "cache hit, but config forces revalidate",
+                    'N' => "conditional hit (client sent conditional, doc fresh in cache, returned 304)",
+        },
+   },
+   {
+        "ICP status:",
+        {
+                    ' ' => "no icp",
+                    'S' => "connection opened successfully",
+                    'F' => "connection open failed",
+        },
+   },
+   {
+        "Parent proxy connection status:",
+        {
+                    ' ' => "no parent proxy",
+                    'S' => "connection opened successfully",
+                    'F' => "connection open failed",
+        },
+    
+   },
+   {
+        "Origin server connection status:",
+        {
+                    ' ' => "no server connection",
+                    'S' => "connection opened successfully",
+                    'F' => "connection open failed",
+        },
+   },
+);
+
+##Print script usage
+sub usage
+{
+    print "\nPass Via Header with -s option \n";
+    print "Usage: traffic_via [-s viaheader]";
+    print "\n        or          \n";
+    print "\nPipe curl command output to this program";
+    print "\nEg: curl xxxx | traffic_via\n";
+    print "\n-h for help\n";
+    exit;
+}
+
+if (@ARGV == 0) {
+    #if passed through standard input
+    my @userinput = <STDIN>;
+    my $via_string;
+
+    for my $element (@userinput) {
+        #Pattern matching for Via
+        if ($element =~ /Via:(.*)\[(.*)\]/) {
+            #Search and grep via header
+            $via_string = $2;    
+            chomp($via_string);
+            print "Via Header is [$via_string]";
+            decode_via_header($via_string);
+        }
+    }
+} else {
+    usage() if (!GetOptions('s=s' => \$via_header,
+                'help|?' => \$help) or
+                defined $help);
+    
+    if (defined $via_header) {
+        #if passed through commandline dashed argument
+        print "Via Header is [$via_header]";
+        decode_via_header($via_header);
+    }
+
+}
+
+#Subroutine to decode via header
+sub decode_via_header {
+    my($header) = @_;
+    my $hdrLength;
+    my $newHeader;
+
+    #Check via header syntax
+    if ($header =~ /([a-zA-Z: ]+)/) {   
+        #Get via header length
+        $hdrLength = length($header);
+        
+        # Valid Via header length is 24 or 6.
+        # When Via header length is 24, it will have both proxy request header result and operational results.
+        if ($hdrLength == 24) {
+            #Split via header: proxy result and operational result
+            $newHeader = join('', split(':', $header));
+        } elsif ($hdrLength == 6) {
+            $newHeader = $header;
+        } elsif ($hdrLength == 5) {
+            # When Via header length is 5, it might be missing last field. Fill it and decode header.
+            my $newHeader = "$header"." ";
+        } else {
+            # Invalid header size, come out.
+            print "\nInvalid VIA header. VIA header length should be 6 or 24 characters\n";
+            return;
+        }
+        convert_header_to_array($newHeader);
+    }
+    
+    
+}
+
+sub convert_header_to_array {
+    my ($viaHeader) = @_;
+    my @ResultArray;
+    #Convert string header into character array
+    while ($viaHeader =~ /(.)/g) {
+            #Only capital letters indicate flags
+            if ($1 !~ m/[a-z]+/) {
+                push(@ResultArray, $1); 
+            }
+    }
+    print "\nVia Header details: \n";
+    for (my $arrayIndex=0; $arrayIndex < scalar(@ResultArray); $arrayIndex++ ) {
+        get_via_header_flags(\@proxy_header_array, $arrayIndex, $ResultArray[$arrayIndex]);
+    }
+}
+
+#Get values from header arrays
+sub get_via_header_flags {
+    my ($arrayName, $inputIndex, $flag) = @_;
+
+    my %flagValues;
+    my @flagKeys;
+    my %flags;
+    my @keys;
+    
+    my @array = @$arrayName;
+            
+    %flagValues = %{$array[$inputIndex]};
+    @flagKeys = keys (%flagValues);
+    
+    foreach my $keyEntry ( @flagKeys )  {
+        printf ("%-55s", $keyEntry);
+        %flags = %{$flagValues{$keyEntry}};
+        @keys = keys (%flags);
+        foreach my $key ( @keys )  {
+            if ($key =~ /$flag/) { 
+                 #print $flags{$key};
+                 printf("%s",$flags{$key});
+                 print "\n";
+            }
+        }
+    }
+}