github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/cmd/service/handler/file/file.go (about)

     1  package file
     2  
     3  import (
     4  	"context"
     5  	"io"
     6  	"io/ioutil"
     7  	"os"
     8  	"path/filepath"
     9  	"strings"
    10  
    11  	"github.com/tickoalcantara12/micro/v3/service/errors"
    12  	"github.com/tickoalcantara12/micro/v3/service/proxy"
    13  	"github.com/tickoalcantara12/micro/v3/service/server"
    14  )
    15  
    16  //Proxy for a proxy instance
    17  type Proxy struct {
    18  	options proxy.Options
    19  
    20  	// The file or directory to read from
    21  	Endpoint string
    22  }
    23  
    24  func filePath(eps ...string) string {
    25  	p := filepath.Join(eps...)
    26  	return strings.Replace(p, "../", "", -1)
    27  }
    28  
    29  func getMethod(hdr map[string]string) string {
    30  	switch hdr["Micro-Method"] {
    31  	case "read", "write":
    32  		return hdr["Micro-Method"]
    33  	default:
    34  		return "read"
    35  	}
    36  }
    37  
    38  func getEndpoint(hdr map[string]string) string {
    39  	ep := hdr["Micro-Endpoint"]
    40  	if len(ep) > 0 && ep[0] == '/' {
    41  		return ep
    42  	}
    43  	return ""
    44  }
    45  
    46  func (p *Proxy) ProcessMessage(ctx context.Context, msg server.Message) error {
    47  	return nil
    48  }
    49  
    50  // ServeRequest honours the server.Router interface
    51  func (p *Proxy) ServeRequest(ctx context.Context, req server.Request, rsp server.Response) error {
    52  	if p.Endpoint == "" {
    53  		exe, err := os.Executable()
    54  		if err != nil {
    55  			return err
    56  		}
    57  		// set the endpoint to the current path
    58  		p.Endpoint = filepath.Dir(exe)
    59  	}
    60  
    61  	for {
    62  		// get data
    63  		// Read the body if we're writing the file
    64  		_, err := req.Read()
    65  		if err == io.EOF {
    66  			return nil
    67  		}
    68  		if err != nil {
    69  			return err
    70  		}
    71  
    72  		// get the header
    73  		hdr := req.Header()
    74  
    75  		// get method
    76  		//method := getMethod(hdr)
    77  
    78  		// get endpoint
    79  		endpoint := getEndpoint(hdr)
    80  
    81  		// filepath
    82  		file := filePath(p.Endpoint, endpoint)
    83  
    84  		// lookup the file
    85  		b, err := ioutil.ReadFile(file)
    86  		if err != nil {
    87  			return errors.InternalServerError(req.Service(), err.Error())
    88  		}
    89  
    90  		// write back the header
    91  		rsp.WriteHeader(hdr)
    92  		// write the body
    93  		err = rsp.Write(b)
    94  		if err == io.EOF {
    95  			return nil
    96  		}
    97  		if err != nil {
    98  			return errors.InternalServerError(req.Service(), err.Error())
    99  		}
   100  	}
   101  
   102  }
   103  
   104  func (p *Proxy) String() string {
   105  	return "file"
   106  }
   107  
   108  //NewSingleHostProxy returns a Proxy which stand for a endpoint.
   109  func NewSingleHostProxy(url string) proxy.Proxy {
   110  	return &Proxy{
   111  		Endpoint: url,
   112  	}
   113  }
   114  
   115  // NewProxy returns a new proxy which will route using a http client
   116  func NewProxy(opts ...proxy.Option) proxy.Proxy {
   117  	var options proxy.Options
   118  	for _, o := range opts {
   119  		o(&options)
   120  	}
   121  
   122  	p := new(Proxy)
   123  	p.Endpoint = options.Endpoint
   124  
   125  	return p
   126  }