github.com/coreos/goproxy@v0.0.0-20190513173959-f8dc2d7ba04e/examples/goproxy-yui-minify/yui.go (about)

     1  // This example would minify standalone Javascript files (identified by their content type)
     2  // using the command line utility YUI compressor http://yui.github.io/yuicompressor/
     3  // Example usage:
     4  //
     5  //    ./yui -java /usr/local/bin/java -yuicompressor ~/Downloads/yuicompressor-2.4.8.jar
     6  //    $ curl -vx localhost:8080  http://golang.org/lib/godoc/godocs.js
     7  //    (function(){function g(){var u=$("#search");if(u.length===0){return}function t(){if(....
     8  //    $ curl http://golang.org/lib/godoc/godocs.js | head -n 3
     9  //    // Copyright 2012 The Go Authors. All rights reserved.
    10  //    // Use of this source code is governed by a BSD-style
    11  //    // license that can be found in the LICENSE file.
    12  package main
    13  
    14  import (
    15  	"flag"
    16  	"io"
    17  	"io/ioutil"
    18  	"log"
    19  	"net/http"
    20  	"os"
    21  	"os/exec"
    22  	"path"
    23  	"strings"
    24  
    25  	"github.com/elazarl/goproxy"
    26  )
    27  
    28  func main() {
    29  	verbose := flag.Bool("v", false, "should every proxy request be logged to stdout")
    30  	addr := flag.String("addr", ":8080", "proxy listen address")
    31  	java := flag.String("javapath", "java", "where the Java executable is located")
    32  	yuicompressor := flag.String("yuicompressor", "", "where the yuicompressor is located, assumed to be in CWD")
    33  	yuicompressordir := flag.String("yuicompressordir", ".", "a folder to search yuicompressor in, will be ignored if yuicompressor is set")
    34  	flag.Parse()
    35  	if *yuicompressor == "" {
    36  		files, err := ioutil.ReadDir(*yuicompressordir)
    37  		if err != nil {
    38  			log.Fatal("Cannot find yuicompressor jar")
    39  		}
    40  		for _, file := range files {
    41  			if strings.HasPrefix(file.Name(), "yuicompressor") && strings.HasSuffix(file.Name(), ".jar") {
    42  				c := path.Join(*yuicompressordir, file.Name())
    43  				yuicompressor = &c
    44  				break
    45  			}
    46  		}
    47  	}
    48  	if *yuicompressor == "" {
    49  		log.Fatal("Can't find yuicompressor jar, searched yuicompressor*.jar in dir ", *yuicompressordir)
    50  	}
    51  	if _, err := os.Stat(*yuicompressor); os.IsNotExist(err) {
    52  		log.Fatal("Can't find yuicompressor jar specified ", *yuicompressor)
    53  	}
    54  	proxy := goproxy.NewProxyHttpServer()
    55  	proxy.Verbose = *verbose
    56  	proxy.OnResponse().DoFunc(func(resp *http.Response, ctx *goproxy.ProxyCtx) *http.Response {
    57  		contentType := resp.Header.Get("Content-Type")
    58  		if contentType == "application/javascript" || contentType == "application/x-javascript" {
    59  			// in real code, response should be streamed as well
    60  			var err error
    61  			cmd := exec.Command(*java, "-jar", *yuicompressor, "--type", "js")
    62  			cmd.Stdin = resp.Body
    63  			resp.Body, err = cmd.StdoutPipe()
    64  			if err != nil {
    65  				ctx.Warnf("Cannot minify content in %v: %v", ctx.Req.URL, err)
    66  				return goproxy.TextResponse(ctx.Req, "Error getting stdout pipe")
    67  			}
    68  			stderr, err := cmd.StderrPipe()
    69  			if err != nil {
    70  				ctx.Logf("Error obtaining stderr from yuicompress: %s", err)
    71  				return goproxy.TextResponse(ctx.Req, "Error getting stderr pipe")
    72  			}
    73  			if err := cmd.Start(); err != nil {
    74  				ctx.Warnf("Cannot minify content in %v: %v", ctx.Req.URL, err)
    75  			}
    76  			go func() {
    77  				defer stderr.Close()
    78  				const kb = 1024
    79  				msg, err := ioutil.ReadAll(&io.LimitedReader{stderr, 50 * kb})
    80  				if len(msg) != 0 {
    81  					ctx.Logf("Error executing yuicompress: %s", string(msg))
    82  				}
    83  				if err != nil {
    84  					ctx.Logf("Error reading stderr from yuicompress: %s", string(msg))
    85  				}
    86  			}()
    87  		}
    88  		return resp
    89  	})
    90  	log.Fatal(http.ListenAndServe(*addr, proxy))
    91  }