github.com/keysonZZZ/kmg@v0.0.0-20151121023212-05317bfd7d39/kmgNet/kmgHttp/command.go (about)

     1  package kmgHttp
     2  
     3  import (
     4  	"errors"
     5  	"flag"
     6  	"fmt"
     7  	"github.com/bronze1man/kmg/kmgCache"
     8  	"github.com/bronze1man/kmg/kmgConsole"
     9  	"github.com/bronze1man/kmg/kmgCrypto"
    10  	"github.com/bronze1man/kmg/kmgErr"
    11  	"github.com/bronze1man/kmg/kmgFile"
    12  	"github.com/bronze1man/kmg/kmgStrings"
    13  	"net/http"
    14  	"os"
    15  	"path/filepath"
    16  	"sync"
    17  )
    18  
    19  func AddCommandList() {
    20  	kmgConsole.AddAction(kmgConsole.Command{
    21  		Name:   "FileHttpServer",
    22  		Runner: runFileHttpServer,
    23  	})
    24  	kmgConsole.AddCommandWithName("HttpGet", func() {
    25  		requestUrl := ""
    26  		key := ""
    27  		flag.StringVar(&requestUrl, "url", "", "")
    28  		flag.StringVar(&key, "key", "", "crypto key use to decrypt respond")
    29  		flag.Parse()
    30  		if requestUrl == "" {
    31  			kmgConsole.ExitOnErr(errors.New("Usage: kmg HttpGet -url http://xxx"))
    32  		}
    33  		b := MustUrlGetContent(requestUrl)
    34  		var err error
    35  		if key != "" {
    36  			b, err = kmgCrypto.CompressAndEncryptBytesDecodeV2(kmgCrypto.Get32PskFromString(key), b)
    37  			if err != nil {
    38  				panic(err)
    39  			}
    40  		}
    41  		fmt.Print(string(b))
    42  	})
    43  }
    44  
    45  var lock *sync.Mutex = &sync.Mutex{}
    46  var cacheFilePathSlice []string = []string{}
    47  var cacheFilePathEncryptMap map[string][]byte = map[string][]byte{}
    48  
    49  func runFileHttpServer() {
    50  	listenAddr := ""
    51  	path := ""
    52  	key := ""
    53  	flag.StringVar(&listenAddr, "l", ":80", "listen address")
    54  	flag.StringVar(&path, "path", "", "root path of the file server")
    55  	flag.StringVar(&key, "key", "", "crypto key use to encrypt all request of this server")
    56  	flag.Parse()
    57  	var err error
    58  	if path == "" {
    59  		path, err = os.Getwd()
    60  		if err != nil {
    61  			fmt.Printf("os.Getwd() fail %s", err)
    62  			return
    63  		}
    64  	} else {
    65  		kmgErr.PanicIfError(os.Chdir(path))
    66  	}
    67  	if key == "" {
    68  		http.Handle("/", http.FileServer(http.Dir(path)))
    69  	}
    70  	if key != "" {
    71  		http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    72  			realPath := filepath.Join(path, r.URL.Path)
    73  			if !kmgFile.MustFileExist(realPath) {
    74  				w.Write([]byte("File Not Exist"))
    75  				return
    76  			}
    77  			if !kmgStrings.IsInSlice(cacheFilePathSlice, realPath) {
    78  				cacheFilePathSlice = append(cacheFilePathSlice, realPath)
    79  			}
    80  			updateCache := func() {
    81  				cacheFilePathEncryptMap[realPath] = kmgCrypto.CompressAndEncryptBytesEncodeV2(
    82  					kmgCrypto.Get32PskFromString(key),
    83  					kmgFile.MustReadFile(realPath),
    84  				)
    85  			}
    86  			checkCache := func() {
    87  				lock.Lock()
    88  				defer lock.Unlock()
    89  				kmgCache.MustMd5FileChangeCache(realPath, []string{realPath}, func() {
    90  					updateCache()
    91  				})
    92  			}
    93  			checkCache()
    94  			//进程重启后,内存中的缓存掉了,但是文件系统的缓存还在
    95  			_, exist := cacheFilePathEncryptMap[realPath]
    96  			if !exist {
    97  				updateCache()
    98  			}
    99  			w.Write(cacheFilePathEncryptMap[realPath])
   100  		})
   101  	}
   102  	fmt.Println("start server at", listenAddr)
   103  	err = http.ListenAndServe(listenAddr, nil)
   104  	if err != nil {
   105  		fmt.Printf("http.ListenAndServe() fail %s", err)
   106  		return
   107  	}
   108  	return
   109  }