github.com/google/martian/v3@v3.3.3/cmd/marbl/viewer.go (about)

     1  // Copyright 2018 Google Inc. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Command-line tool to view .marbl files. This tool reads all headers from provided .marbl
    16  // file and prints them to stdout. Bodies of request/response are not printed to stdout,
    17  // instead they are saved into individual files in form of "marbl_ID_TYPE" where
    18  // ID is the ID of request or response and TYPE is "request" or "response".
    19  //
    20  // Command line arguments:
    21  //   --file  Path to the .marbl file to view.
    22  //   --out   Optional, folder where this tool will save request/response bodies.
    23  //           uses current folder by default.
    24  package main
    25  
    26  import (
    27  	"flag"
    28  	"fmt"
    29  	"io"
    30  	"log"
    31  	"os"
    32  
    33  	"github.com/google/martian/v3/marbl"
    34  )
    35  
    36  var (
    37  	file = flag.String("file", "", ".marbl file to show contents of")
    38  	out  = flag.String("out", "", "folder to write request/response bodies to. Folder must exist.")
    39  )
    40  
    41  func main() {
    42  	flag.Parse()
    43  
    44  	if *file == "" {
    45  		fmt.Println("--file flag is required")
    46  		return
    47  	}
    48  
    49  	file, err := os.Open(*file)
    50  	if err != nil {
    51  		log.Fatal(err)
    52  	}
    53  
    54  	reader := marbl.NewReader(file)
    55  
    56  	// Iterate through all frames in .marbl file.
    57  	for {
    58  		frame, err := reader.ReadFrame()
    59  		if frame == nil && err == io.EOF {
    60  			break
    61  		}
    62  		if err != nil {
    63  			log.Fatalf("reader.ReadFrame(): got %v, want no error or io.EOF\n", err)
    64  			break
    65  		}
    66  
    67  		// Print current frame to stdout.
    68  		if frame.FrameType() == marbl.HeaderFrame {
    69  			fmt.Print("Header ")
    70  		} else {
    71  			fmt.Print("Data ")
    72  		}
    73  		fmt.Println(frame.String())
    74  
    75  		// If frame is Data then we write it into separate
    76  		// file that can be inspected later.
    77  		if frame.FrameType() == marbl.DataFrame {
    78  			df := frame.(marbl.Data)
    79  			var t string
    80  			if df.MessageType == marbl.Request {
    81  				t = "request"
    82  			} else if df.MessageType == marbl.Response {
    83  				t = "response"
    84  			} else {
    85  				t = fmt.Sprintf("unknown_%d", df.MessageType)
    86  			}
    87  			fout := fmt.Sprintf("marbl_%s_%s", df.ID, t)
    88  			if *out != "" {
    89  				fout = *out + "/" + fout
    90  			}
    91  			fmt.Printf("Appending data to file %s\n", fout)
    92  
    93  			// Append data to the file. Note that body can be split
    94  			// into multiple frames so we have to append and not overwrite.
    95  			f, err := os.OpenFile(fout, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
    96  			if err != nil {
    97  				log.Fatal(err)
    98  			}
    99  			if _, err := f.Write(df.Data); err != nil {
   100  				log.Fatal(err)
   101  			}
   102  			if err := f.Close(); err != nil {
   103  				log.Fatal(err)
   104  			}
   105  		}
   106  	}
   107  }