diff --git a/go.mod b/go.mod index d5b5bb7..48c20aa 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,7 @@ require ( github.com/unistack-org/micro-proto v0.0.2-0.20210227213711-77c7563bd01e github.com/unistack-org/micro-router-register/v3 v3.2.2 github.com/unistack-org/micro-server-grpc/v3 v3.3.1 - github.com/unistack-org/micro-server-http/v3 v3.3.5 + github.com/unistack-org/micro-server-http/v3 v3.3.6 github.com/unistack-org/micro-server-tcp/v3 v3.3.0 github.com/unistack-org/micro-wrapper-trace-opentracing/v3 v3.2.0 github.com/unistack-org/micro/v3 v3.3.13 @@ -39,6 +39,7 @@ require ( //replace github.com/unistack-org/micro-client-grpc/v3 => ../micro-client-grpc //replace github.com/unistack-org/micro-server-grpc/v3 => ../micro-server-grpc //replace github.com/unistack-org/micro-server-http/v3 => ../micro-server-http + //replace github.com/unistack-org/micro-client-http/v3 => ../micro-client-http //replace github.com/unistack-org/micro/v3 => ../micro //replace github.com/unistack-org/micro-proto => ../micro-proto diff --git a/go.sum b/go.sum index b19e706..8f55a98 100644 --- a/go.sum +++ b/go.sum @@ -483,8 +483,8 @@ github.com/unistack-org/micro-router-register/v3 v3.2.2 h1:lYCymDHkJfhZWYQ4+Sb7F github.com/unistack-org/micro-router-register/v3 v3.2.2/go.mod h1:Y9Qtlg4NHqq5rR6X6Jm+04LoSJMi7/OOCm2mRueZYTE= github.com/unistack-org/micro-server-grpc/v3 v3.3.1 h1:g4d5MwGYv3hbJMUmOcl4Fv0/CSq+IdAJ5o2LZv1idUg= github.com/unistack-org/micro-server-grpc/v3 v3.3.1/go.mod h1:ay3TYYLPb+6cUZ+EG35A3RQCCFFXsNoQXibnbt0wwbI= -github.com/unistack-org/micro-server-http/v3 v3.3.5 h1:PvT8zmV8qZm+CU1mU0/fm1Fei2+WAiv97GPwl165qAA= -github.com/unistack-org/micro-server-http/v3 v3.3.5/go.mod h1:MKTI+9Y/rePLjbET8L0kL6baxeT6k5YIf2/n/4uxdGM= +github.com/unistack-org/micro-server-http/v3 v3.3.6 h1:TM/2Rc1v8R/tviaoeTrNUUCq5nYEvkn0o8rpfBARegM= +github.com/unistack-org/micro-server-http/v3 v3.3.6/go.mod h1:COsR2gYs2F7WGwgOporbIepQ5+YjPQoHo1qFSffmeMA= github.com/unistack-org/micro-server-tcp/v3 v3.3.0 h1:YIj5SvuPm7Q0CTo/L8ALcQFoBHwiGrz33TxvpcPuXYI= github.com/unistack-org/micro-server-tcp/v3 v3.3.0/go.mod h1:3cxrSzkmrHOkWuYvi7dAK+gAsuO6EkxoT9Y0LUNhC3I= github.com/unistack-org/micro-wrapper-trace-opentracing/v3 v3.2.0 h1:PvemkpeCVUWfCoKwt1XmJ8uGK9My/7T29qOVxtYJohw= @@ -596,8 +596,9 @@ golang.org/x/net v0.0.0-20210323141857-08027d57d8cf/go.mod h1:RBQZq4jEuRlivfhVLd golang.org/x/net v0.0.0-20210324051636-2c4c8ecb7826/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210331060903-cb1fcc7394e5/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1 h1:4qWs8cYYH6PoEFy4dfhDFgoMGkwAcETd+MmPdCPMzUc= +golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -656,8 +657,9 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/server/http/http_test.go b/server/http/http_test.go index 7a19ebe..1130ccf 100644 --- a/server/http/http_test.go +++ b/server/http/http_test.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "io/ioutil" + "mime/multipart" "net/http" "net/url" "strings" @@ -32,6 +33,101 @@ type Handler struct { t *testing.T } +func multipartHandler(w http.ResponseWriter, r *http.Request) { + fmt.Printf("%#+v\n", r) +} + +func upload(client *http.Client, url string, values map[string]io.Reader) error { + var err error + b := bytes.NewBuffer(nil) + w := multipart.NewWriter(b) + for key, r := range values { + var fw io.Writer + if x, ok := r.(io.Closer); ok { + defer x.Close() + } + if fw, err = w.CreateFormFile(key, key); err != nil { + return err + } + if _, err = io.Copy(fw, r); err != nil { + return err + } + + } + // Don't forget to close the multipart writer. + // If you don't close it, your request will be missing the terminating boundary. + w.Close() + + // Now that you have a form, you can submit it to your handler. + req, err := http.NewRequest("POST", url, b) + if err != nil { + return err + } + // Don't forget to set the content type, this will contain the boundary. + req.Header.Set("Content-Type", w.FormDataContentType()) + + // Submit the request + res, err := client.Do(req) + if err != nil { + return err + } + + // Check the response + if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusCreated { + err = fmt.Errorf("bad status: %s", res.Status) + } + + return err +} + +func TestMultipart(t *testing.T) { + reg := register.NewRegister() + ctx := context.Background() + + // create server + srv := httpsrv.NewServer( + server.Name("helloworld"), + server.Register(reg), + server.Codec("application/json", jsoncodec.NewCodec()), + httpsrv.PathHandler("/upload", multipartHandler), + ) + + if err := srv.Init(); err != nil { + t.Fatal(err) + } + + h := &Handler{t: t} + pb.RegisterTestServer(srv, h) + + // start server + if err := srv.Start(); err != nil { + t.Fatal(err) + } + + // lookup server + service, err := reg.LookupService(ctx, "helloworld") + if err != nil { + t.Fatal(err) + } + + if len(service) != 1 { + t.Fatalf("Expected 1 service got %d: %+v", len(service), service) + } + + if len(service[0].Nodes) != 1 { + t.Fatalf("Expected 1 node got %d: %+v", len(service[0].Nodes), service[0].Nodes) + } + + t.Logf("test multipart upload") + values := make(map[string]io.Reader, 2) + values["first.txt"] = bytes.NewReader([]byte("first content")) + values["second.txt"] = bytes.NewReader([]byte("second content")) + err = upload(http.DefaultClient, "http://"+service[0].Nodes[0].Address+"/upload", values) + if err != nil { + t.Fatal(err) + } +} + func NewServerHandlerWrapper() server.HandlerWrapper { return func(fn server.HandlerFunc) server.HandlerFunc { return func(ctx context.Context, req server.Request, rsp interface{}) error {