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 }