prepare_v4 #199
							
								
								
									
										24
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								go.mod
									
									
									
									
									
								
							| @@ -1,14 +1,13 @@ | ||||
| module go.unistack.org/micro-server-http/v3 | ||||
|  | ||||
| go 1.22.0 | ||||
| module go.unistack.org/micro-server-http/v4 | ||||
|  | ||||
| go 1.23.0 | ||||
|  | ||||
| require ( | ||||
| 	go.unistack.org/micro-client-http/v3 v3.9.15 | ||||
| 	go.unistack.org/micro-codec-yaml/v3 v3.10.3 | ||||
| 	go.unistack.org/micro-proto/v3 v3.4.1 | ||||
| 	go.unistack.org/micro/v3 v3.11.30 | ||||
| 	golang.org/x/net v0.33.0 | ||||
| 	go.unistack.org/micro-client-http/v4 v4.1.0 | ||||
| 	go.unistack.org/micro-codec-yaml/v4 v4.1.0 | ||||
| 	go.unistack.org/micro-proto/v4 v4.1.0 | ||||
| 	go.unistack.org/micro/v4 v4.1.2 | ||||
| 	golang.org/x/net v0.35.0 | ||||
| ) | ||||
|  | ||||
| require ( | ||||
| @@ -17,9 +16,10 @@ require ( | ||||
| 	github.com/google/gnostic-models v0.6.9 // indirect | ||||
| 	github.com/google/uuid v1.6.0 // indirect | ||||
| 	github.com/matoous/go-nanoid v1.5.1 // indirect | ||||
| 	golang.org/x/sys v0.28.0 // indirect | ||||
| 	google.golang.org/genproto/googleapis/rpc v0.0.0-20241223144023-3abc09e42ca8 // indirect | ||||
| 	google.golang.org/grpc v1.69.2 // indirect | ||||
| 	google.golang.org/protobuf v1.36.1 // indirect | ||||
| 	github.com/spf13/cast v1.7.1 // indirect | ||||
| 	golang.org/x/sys v0.30.0 // indirect | ||||
| 	google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e // indirect | ||||
| 	google.golang.org/grpc v1.70.0 // indirect | ||||
| 	google.golang.org/protobuf v1.36.5 // indirect | ||||
| 	gopkg.in/yaml.v3 v3.0.1 // indirect | ||||
| ) | ||||
|   | ||||
							
								
								
									
										44
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								go.sum
									
									
									
									
									
								
							| @@ -657,6 +657,8 @@ github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0+ | ||||
| github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= | ||||
| github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= | ||||
| github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= | ||||
| github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= | ||||
| github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= | ||||
| github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= | ||||
| github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= | ||||
| github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= | ||||
| @@ -837,6 +839,8 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO | ||||
| github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= | ||||
| github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= | ||||
| github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= | ||||
| github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= | ||||
| github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= | ||||
| github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= | ||||
| github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||
| github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= | ||||
| @@ -872,14 +876,14 @@ go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= | ||||
| go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= | ||||
| go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= | ||||
| go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= | ||||
| go.unistack.org/micro-client-http/v3 v3.9.15 h1:d2t/8P0FrvZwIpdqwHwn9+7rP5zcDa4DKXgBfTCZTeo= | ||||
| go.unistack.org/micro-client-http/v3 v3.9.15/go.mod h1:KS6qxpxGDQmcszBaJpidc1KOr528QflEKoGopl0qYJ8= | ||||
| go.unistack.org/micro-codec-yaml/v3 v3.10.3 h1:H0jM4wCSReHzEc1hnKYgXjzg171+tUE6IHxdxvgq/cQ= | ||||
| go.unistack.org/micro-codec-yaml/v3 v3.10.3/go.mod h1:pruYGvCULoHa6Tfah1UnTrwCzQhy0KT6D4UXEMgf+tk= | ||||
| go.unistack.org/micro-proto/v3 v3.4.1 h1:UTjLSRz2YZuaHk9iSlVqqsA50JQNAEK2ZFboGqtEa9Q= | ||||
| go.unistack.org/micro-proto/v3 v3.4.1/go.mod h1:okx/cnOhzuCX0ggl/vToatbCupi0O44diiiLLsZ93Zo= | ||||
| go.unistack.org/micro/v3 v3.11.30 h1:XTLgZubSGzQL85IUMp1pTJnS1lP4eFwTZyelV/SzOMc= | ||||
| go.unistack.org/micro/v3 v3.11.30/go.mod h1:fvOkXKs3wKHToWH6Mxy+aovEiDl2q4UlOCdVfJdziBU= | ||||
| go.unistack.org/micro-client-http/v4 v4.1.0 h1:u1YwMmhPaQn0T0m6OSC6MBijHshDpwiNWMNib7KmSj8= | ||||
| go.unistack.org/micro-client-http/v4 v4.1.0/go.mod h1:RtddTKxsN5Zc6bzEON6CqpDL/Svfo13QoGXbIO1x3Os= | ||||
| go.unistack.org/micro-codec-yaml/v4 v4.1.0 h1:9utR2ka47CDEShbuF7QBAfv0lAFp06pXh77e2Byrt2s= | ||||
| go.unistack.org/micro-codec-yaml/v4 v4.1.0/go.mod h1:aMd5xKrJiUMvh6PNdYbO3G59JZfjSHRXdmNA4RCr8Mw= | ||||
| go.unistack.org/micro-proto/v4 v4.1.0 h1:qPwL2n/oqh9RE3RTTDgt28XK3QzV597VugQPaw9lKUk= | ||||
| go.unistack.org/micro-proto/v4 v4.1.0/go.mod h1:ArmK7o+uFvxSY3dbJhKBBX4Pm1rhWdLEFf3LxBrMtec= | ||||
| go.unistack.org/micro/v4 v4.1.2 h1:9SOlPYyPNNFpg1A7BsvhDyQm3gysLH1AhWbDCp1hyoY= | ||||
| go.unistack.org/micro/v4 v4.1.2/go.mod h1:lr3oYED8Ay1vjK68QqRw30QOtdk/ffpZqMFDasOUhKw= | ||||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||
| golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||
| golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||
| @@ -1001,8 +1005,8 @@ golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= | ||||
| golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= | ||||
| golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= | ||||
| golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= | ||||
| golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= | ||||
| golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= | ||||
| golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= | ||||
| golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= | ||||
| 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= | ||||
| @@ -1122,8 +1126,8 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= | ||||
| golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= | ||||
| golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= | ||||
| golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= | ||||
| golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||||
| golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= | ||||
| golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= | ||||
| @@ -1145,8 +1149,8 @@ golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= | ||||
| golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= | ||||
| golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= | ||||
| golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= | ||||
| golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= | ||||
| golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= | ||||
| golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= | ||||
| golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= | ||||
| 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= | ||||
| golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= | ||||
| @@ -1430,8 +1434,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go. | ||||
| google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= | ||||
| google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc= | ||||
| google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= | ||||
| google.golang.org/genproto/googleapis/rpc v0.0.0-20241223144023-3abc09e42ca8 h1:TqExAhdPaB60Ux47Cn0oLV07rGnxZzIsaRhQaqS666A= | ||||
| google.golang.org/genproto/googleapis/rpc v0.0.0-20241223144023-3abc09e42ca8/go.mod h1:lcTa1sDdWEIHMWlITnIczmw5w60CF9ffkb8Z+DVmmjA= | ||||
| google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e h1:YA5lmSs3zc/5w+xsRcHqpETkaYyK63ivEPzNTcUUlSA= | ||||
| google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= | ||||
| google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= | ||||
| google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= | ||||
| google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= | ||||
| @@ -1471,8 +1475,8 @@ google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCD | ||||
| google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= | ||||
| google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= | ||||
| google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= | ||||
| google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU= | ||||
| google.golang.org/grpc v1.69.2/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= | ||||
| google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= | ||||
| google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= | ||||
| google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= | ||||
| google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= | ||||
| google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= | ||||
| @@ -1491,8 +1495,8 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw | ||||
| google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= | ||||
| google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= | ||||
| google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= | ||||
| google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= | ||||
| google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= | ||||
| google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= | ||||
| google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= | ||||
| gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= | ||||
|   | ||||
							
								
								
									
										132
									
								
								handler.go
									
									
									
									
									
								
							
							
						
						
									
										132
									
								
								handler.go
									
									
									
									
									
								
							| @@ -12,16 +12,16 @@ import ( | ||||
| 	"sync" | ||||
| 	"time" | ||||
|  | ||||
| 	"go.unistack.org/micro/v3/errors" | ||||
| 	"go.unistack.org/micro/v3/logger" | ||||
| 	"go.unistack.org/micro/v3/metadata" | ||||
| 	"go.unistack.org/micro/v3/meter" | ||||
| 	"go.unistack.org/micro/v3/options" | ||||
| 	"go.unistack.org/micro/v3/semconv" | ||||
| 	"go.unistack.org/micro/v3/server" | ||||
| 	"go.unistack.org/micro/v3/tracer" | ||||
| 	rhttp "go.unistack.org/micro/v3/util/http" | ||||
| 	rflutil "go.unistack.org/micro/v3/util/reflect" | ||||
| 	"go.unistack.org/micro/v4/errors" | ||||
| 	"go.unistack.org/micro/v4/logger" | ||||
| 	"go.unistack.org/micro/v4/metadata" | ||||
| 	"go.unistack.org/micro/v4/meter" | ||||
| 	"go.unistack.org/micro/v4/options" | ||||
| 	"go.unistack.org/micro/v4/semconv" | ||||
| 	"go.unistack.org/micro/v4/server" | ||||
| 	"go.unistack.org/micro/v4/tracer" | ||||
| 	rhttp "go.unistack.org/micro/v4/util/http" | ||||
| 	rflutil "go.unistack.org/micro/v4/util/reflect" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| @@ -110,20 +110,21 @@ func (h *Server) HTTPHandlerFunc(handler interface{}) (http.HandlerFunc, error) | ||||
| 			md = metadata.New(len(r.Header) + 8) | ||||
| 		} | ||||
| 		for k, v := range r.Header { | ||||
| 			md[k] = strings.Join(v, ", ") | ||||
| 			md[k] = append(md[k], v...) | ||||
| 		} | ||||
| 		md["RemoteAddr"] = r.RemoteAddr | ||||
| 		md["Method"] = r.Method | ||||
| 		md["URL"] = r.URL.String() | ||||
| 		md["Proto"] = r.Proto | ||||
| 		md["Content-Length"] = fmt.Sprintf("%d", r.ContentLength) | ||||
| 		md["Transfer-Encoding"] = strings.Join(r.TransferEncoding, ",") | ||||
| 		md["Host"] = r.Host | ||||
| 		md["RequestURI"] = r.RequestURI | ||||
|  | ||||
| 		md["RemoteAddr"] = append(md["RemoteAddr"], r.RemoteAddr) | ||||
| 		md["Method"] = append(md["Method"], r.Method) | ||||
| 		md["URL"] = append(md["URL"], r.URL.String()) | ||||
| 		md["Proto"] = append(md["Proto"], r.Proto) | ||||
| 		md["Content-Length"] = append(md["Content-Length"], fmt.Sprintf("%d", r.ContentLength)) | ||||
| 		md["Transfer-Encoding"] = append(md["Transfer-Encoding"], r.TransferEncoding...) | ||||
| 		md["Host"] = append(md["Host"], r.Host) | ||||
| 		md["RequestURI"] = append(md["RequestURI"], r.RequestURI) | ||||
| 		if r.TLS != nil { | ||||
| 			md["TLS"] = "true" | ||||
| 			md["TLS-ALPN"] = r.TLS.NegotiatedProtocol | ||||
| 			md["TLS-ServerName"] = r.TLS.ServerName | ||||
| 			md["TLS"] = append(md["TLS"], "true") | ||||
| 			md["TLS-ALPN"] = append(md["TLS-ALPN"], r.TLS.NegotiatedProtocol) | ||||
| 			md["TLS-ServerName"] = append(md["TLS-ServerName"], r.TLS.ServerName) | ||||
| 		} | ||||
|  | ||||
| 		ctx = metadata.NewIncomingContext(ctx, md) | ||||
| @@ -160,18 +161,20 @@ func (h *Server) HTTPHandlerFunc(handler interface{}) (http.HandlerFunc, error) | ||||
| 		if !match && h.registerRPC { | ||||
| 			microMethod, mok := md.Get(metadata.HeaderEndpoint) | ||||
| 			if mok { | ||||
| 				serviceMethod := strings.Split(microMethod, ".") | ||||
| 				if len(serviceMethod) == 2 { | ||||
| 					if shdlr, ok := h.handlers[serviceMethod[0]]; ok { | ||||
| 						hdlr := shdlr.(*httpHandler) | ||||
| 						fh, mp, err := hdlr.handlers.Search(http.MethodPost, "/"+microMethod) | ||||
| 						if err == nil { | ||||
| 							// match = true | ||||
| 							for k, v := range mp { | ||||
| 								matches[k] = v | ||||
| 				for i := range microMethod { | ||||
| 					serviceMethod := strings.Split(microMethod[i], ".") | ||||
| 					if len(serviceMethod) == 2 { | ||||
| 						if shdlr, ok := h.handlers[serviceMethod[0]]; ok { | ||||
| 							hdlr := shdlr.(*httpHandler) | ||||
| 							fh, mp, err := hdlr.handlers.Search(http.MethodPost, "/"+microMethod[i]) | ||||
| 							if err == nil { | ||||
| 								// match = true | ||||
| 								for k, v := range mp { | ||||
| 									matches[k] = v | ||||
| 								} | ||||
| 								hldr = fh.(*patHandler) | ||||
| 								handler = hdlr | ||||
| 							} | ||||
| 							hldr = fh.(*patHandler) | ||||
| 							handler = hdlr | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| @@ -263,10 +266,10 @@ func (h *Server) HTTPHandlerFunc(handler interface{}) (http.HandlerFunc, error) | ||||
| 			} | ||||
| 			if nmd, ok := metadata.FromOutgoingContext(fctx); ok { | ||||
| 				for k, v := range nmd { | ||||
| 					md.Set(k, v) | ||||
| 					md[k] = append(md[k], v...) | ||||
| 				} | ||||
| 			} | ||||
| 			metadata.SetOutgoingContext(ctx, md) | ||||
| 			ctx = metadata.NewOutgoingContext(ctx, md) | ||||
|  | ||||
| 			return err | ||||
| 		} | ||||
| @@ -293,7 +296,9 @@ func (h *Server) HTTPHandlerFunc(handler interface{}) (http.HandlerFunc, error) | ||||
| 		w.Header().Set(metadata.HeaderContentType, ct) | ||||
| 		if md, ok := metadata.FromOutgoingContext(ctx); ok { | ||||
| 			for k, v := range md { | ||||
| 				w.Header().Set(k, v) | ||||
| 				for i := range v { | ||||
| 					w.Header().Set(k, v[i]) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		if md := getRspHeader(ctx); md != nil { | ||||
| @@ -357,23 +362,24 @@ func (h *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||||
| 		md = metadata.New(len(r.Header) + 8) | ||||
| 	} | ||||
| 	for k, v := range r.Header { | ||||
| 		md[k] = strings.Join(v, ", ") | ||||
| 		md[k] = append(md[k], v...) | ||||
| 	} | ||||
| 	md["RemoteAddr"] = r.RemoteAddr | ||||
|  | ||||
| 	md["RemoteAddr"] = append(md["RemoteAddr"], r.RemoteAddr) | ||||
| 	if r.TLS != nil { | ||||
| 		md["Scheme"] = "https" | ||||
| 		md["Scheme"] = append(md["Scheme"], "https") | ||||
| 	} else { | ||||
| 		md["Scheme"] = "http" | ||||
| 		md["Scheme"] = append(md["Scheme"], "http") | ||||
| 	} | ||||
| 	md["Method"] = r.Method | ||||
| 	md["URL"] = r.URL.String() | ||||
| 	md["Proto"] = r.Proto | ||||
| 	md["ContentLength"] = fmt.Sprintf("%d", r.ContentLength) | ||||
| 	md["Method"] = append(md["Method"], r.Method) | ||||
| 	md["URL"] = append(md["URL"], r.URL.String()) | ||||
| 	md["Proto"] = append(md["Proto"], r.Proto) | ||||
| 	md["Content-Length"] = append(md["Content-Length"], fmt.Sprintf("%d", r.ContentLength)) | ||||
| 	if len(r.TransferEncoding) > 0 { | ||||
| 		md["TransferEncoding"] = strings.Join(r.TransferEncoding, ",") | ||||
| 		md["TransferEncoding"] = append(md["Content-Length"], r.TransferEncoding...) | ||||
| 	} | ||||
| 	md["Host"] = r.Host | ||||
| 	md["RequestURI"] = r.RequestURI | ||||
| 	md["Host"] = append(md["Host"], r.Host) | ||||
| 	md["RequestURI"] = append(md["RequestURI"], r.RequestURI) | ||||
| 	ctx = metadata.NewIncomingContext(ctx, md) | ||||
| 	ctx = metadata.NewOutgoingContext(ctx, metadata.New(0)) | ||||
|  | ||||
| @@ -409,18 +415,20 @@ func (h *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||||
| 	if !match && h.registerRPC { | ||||
| 		microMethod, mok := md.Get(metadata.HeaderEndpoint) | ||||
| 		if mok { | ||||
| 			serviceMethod := strings.Split(microMethod, ".") | ||||
| 			if len(serviceMethod) == 2 { | ||||
| 				if shdlr, ok := h.handlers[serviceMethod[0]]; ok { | ||||
| 					hdlr := shdlr.(*httpHandler) | ||||
| 					fh, mp, err := hdlr.handlers.Search(http.MethodPost, "/"+microMethod) | ||||
| 					if err == nil { | ||||
| 						match = true | ||||
| 						for k, v := range mp { | ||||
| 							matches[k] = v | ||||
| 			for i := range microMethod { | ||||
| 				serviceMethod := strings.Split(microMethod[i], ".") | ||||
| 				if len(serviceMethod) == 2 { | ||||
| 					if shdlr, ok := h.handlers[serviceMethod[0]]; ok { | ||||
| 						hdlr := shdlr.(*httpHandler) | ||||
| 						fh, mp, err := hdlr.handlers.Search(http.MethodPost, "/"+microMethod[i]) | ||||
| 						if err == nil { | ||||
| 							match = true | ||||
| 							for k, v := range mp { | ||||
| 								matches[k] = v | ||||
| 							} | ||||
| 							hldr = fh.(*patHandler) | ||||
| 							handler = hdlr | ||||
| 						} | ||||
| 						hldr = fh.(*patHandler) | ||||
| 						handler = hdlr | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| @@ -628,10 +636,10 @@ func (h *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||||
| 		} | ||||
| 		if nmd, ok := metadata.FromOutgoingContext(fctx); ok { | ||||
| 			for k, v := range nmd { | ||||
| 				md.Set(k, v) | ||||
| 				md[k] = append(md[k], v...) | ||||
| 			} | ||||
| 		} | ||||
| 		metadata.SetOutgoingContext(ctx, md) | ||||
| 		ctx = metadata.NewOutgoingContext(ctx, md) | ||||
|  | ||||
| 		if err != nil && sp != nil { | ||||
| 			sp.SetStatus(tracer.SpanStatusError, err.Error()) | ||||
| @@ -661,7 +669,9 @@ func (h *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||||
| 	w.Header().Set(metadata.HeaderContentType, ct) | ||||
| 	if md, ok := metadata.FromOutgoingContext(ctx); ok { | ||||
| 		for k, v := range md { | ||||
| 			w.Header().Set(k, v) | ||||
| 			for i := range v { | ||||
| 				w.Header().Set(k, v[i]) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	if md := getRspHeader(ctx); md != nil { | ||||
|   | ||||
| @@ -2,11 +2,11 @@ package handler | ||||
|  | ||||
| import ( | ||||
| 	// import required packages | ||||
| 	_ "go.unistack.org/micro-proto/v3/openapiv3" | ||||
| 	_ "go.unistack.org/micro-proto/v4/openapiv3" | ||||
| ) | ||||
|  | ||||
| //go:generate sh -c "curl -L https://github.com/swagger-api/swagger-ui/archive/refs/tags/v4.18.3.zip -o - | bsdtar -C swagger-ui --strip-components=2 -xv swagger-ui-4.18.3/dist && rm swagger-ui/*.map swagger-ui/*-es-*.js swagger-ui/swagger-ui.js swagger-ui/swagger-initializer.js" | ||||
|  | ||||
| //go:generate sh -c "protoc -I./ -I$(go list -f '{{ .Dir }}' -m go.unistack.org/micro-proto/v3) --go-micro_out='components=micro|http|server',standalone=false,debug=true,paths=source_relative:./ ./meter/meter.proto" | ||||
| //go:generate sh -c "protoc -I./ -I$(go list -f '{{ .Dir }}' -m go.unistack.org/micro-proto/v4) --go-micro_out='components=micro|http|server',standalone=false,debug=true,paths=source_relative:./ ./meter/meter.proto" | ||||
|  | ||||
| //go:generate sh -c "protoc -I./ -I$(go list -f '{{ .Dir }}' -m go.unistack.org/micro-proto/v3) --go-micro_out='components=micro|http|server',standalone=false,debug=true,paths=source_relative:./ ./health/health.proto" | ||||
| //go:generate sh -c "protoc -I./ -I$(go list -f '{{ .Dir }}' -m go.unistack.org/micro-proto/v4) --go-micro_out='components=micro|http|server',standalone=false,debug=true,paths=source_relative:./ ./health/health.proto" | ||||
|   | ||||
| @@ -7,8 +7,8 @@ import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/99designs/gqlgen/graphql" | ||||
| 	"go.unistack.org/micro/v3/logger" | ||||
| 	"go.unistack.org/micro/v3/store" | ||||
| 	"go.unistack.org/micro/v4/logger" | ||||
| 	"go.unistack.org/micro/v4/store" | ||||
| ) | ||||
|  | ||||
| var _ graphql.Cache = (*cacheWrapper)(nil) | ||||
|   | ||||
| @@ -3,8 +3,8 @@ package health_handler | ||||
| import ( | ||||
| 	"context" | ||||
|  | ||||
| 	codecpb "go.unistack.org/micro-proto/v3/codec" | ||||
| 	"go.unistack.org/micro/v3/errors" | ||||
| 	codecpb "go.unistack.org/micro-proto/v4/codec" | ||||
| 	"go.unistack.org/micro/v4/errors" | ||||
| ) | ||||
|  | ||||
| var _ HealthServiceServer = &Handler{} | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| syntax = "proto3"; | ||||
|  | ||||
| package micro.server.http.v3.handler.health; | ||||
| option go_package = "go.unistack.org/micro-server-http/v3/handler/health;health_handler"; | ||||
| package micro.server.http.v4.handler.health; | ||||
| option go_package = "go.unistack.org/micro-server-http/v4/handler/health;health_handler"; | ||||
|  | ||||
| import "api/annotations.proto"; | ||||
| import "openapiv3/annotations.proto"; | ||||
|   | ||||
| @@ -1,15 +1,15 @@ | ||||
| // Code generated by protoc-gen-go-micro. DO NOT EDIT. | ||||
| // versions: | ||||
| // - protoc-gen-go-micro v3.10.4 | ||||
| // - protoc              v5.28.3 | ||||
| // - protoc-gen-go-micro v4.1.0 | ||||
| // - protoc              v5.29.3 | ||||
| // source: health/health.proto | ||||
|  | ||||
| package health_handler | ||||
|  | ||||
| import ( | ||||
| 	context "context" | ||||
| 	codec "go.unistack.org/micro-proto/v3/codec" | ||||
| 	client "go.unistack.org/micro/v3/client" | ||||
| 	codec "go.unistack.org/micro-proto/v4/codec" | ||||
| 	client "go.unistack.org/micro/v4/client" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
|   | ||||
| @@ -1,21 +1,21 @@ | ||||
| // Code generated by protoc-gen-go-micro. DO NOT EDIT. | ||||
| // protoc-gen-go-micro version: v3.10.4 | ||||
| // protoc-gen-go-micro version: v4.1.0 | ||||
| // source: health/health.proto | ||||
|  | ||||
| package health_handler | ||||
|  | ||||
| import ( | ||||
| 	context "context" | ||||
| 	v31 "go.unistack.org/micro-client-http/v3" | ||||
| 	codec "go.unistack.org/micro-proto/v3/codec" | ||||
| 	v3 "go.unistack.org/micro-server-http/v3" | ||||
| 	client "go.unistack.org/micro/v3/client" | ||||
| 	server "go.unistack.org/micro/v3/server" | ||||
| 	v41 "go.unistack.org/micro-client-http/v4" | ||||
| 	codec "go.unistack.org/micro-proto/v4/codec" | ||||
| 	v4 "go.unistack.org/micro-server-http/v4" | ||||
| 	client "go.unistack.org/micro/v4/client" | ||||
| 	server "go.unistack.org/micro/v4/server" | ||||
| 	http "net/http" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	HealthServiceServerEndpoints = []v3.EndpointMetadata{ | ||||
| 	HealthServiceServerEndpoints = []v4.EndpointMetadata{ | ||||
| 		{ | ||||
| 			Name:   "HealthService.Healthy", | ||||
| 			Path:   "/health", | ||||
| @@ -81,11 +81,11 @@ func (c *healthServiceClient) Healthy(ctx context.Context, req *codec.Frame, opt | ||||
| 	errmap := make(map[string]interface{}, 1) | ||||
| 	errmap["default"] = &codec.Frame{} | ||||
| 	opts = append(opts, | ||||
| 		v31.ErrorMap(errmap), | ||||
| 		v41.ErrorMap(errmap), | ||||
| 	) | ||||
| 	opts = append(opts, | ||||
| 		v31.Method(http.MethodGet), | ||||
| 		v31.Path("/health"), | ||||
| 		v41.Method(http.MethodGet), | ||||
| 		v41.Path("/health"), | ||||
| 	) | ||||
| 	rsp := &codec.Frame{} | ||||
| 	err := c.c.Call(ctx, c.c.NewRequest(c.name, "HealthService.Healthy", req), rsp, opts...) | ||||
| @@ -99,11 +99,11 @@ func (c *healthServiceClient) Live(ctx context.Context, req *codec.Frame, opts . | ||||
| 	errmap := make(map[string]interface{}, 1) | ||||
| 	errmap["default"] = &codec.Frame{} | ||||
| 	opts = append(opts, | ||||
| 		v31.ErrorMap(errmap), | ||||
| 		v41.ErrorMap(errmap), | ||||
| 	) | ||||
| 	opts = append(opts, | ||||
| 		v31.Method(http.MethodGet), | ||||
| 		v31.Path("/live"), | ||||
| 		v41.Method(http.MethodGet), | ||||
| 		v41.Path("/live"), | ||||
| 	) | ||||
| 	rsp := &codec.Frame{} | ||||
| 	err := c.c.Call(ctx, c.c.NewRequest(c.name, "HealthService.Live", req), rsp, opts...) | ||||
| @@ -117,11 +117,11 @@ func (c *healthServiceClient) Ready(ctx context.Context, req *codec.Frame, opts | ||||
| 	errmap := make(map[string]interface{}, 1) | ||||
| 	errmap["default"] = &codec.Frame{} | ||||
| 	opts = append(opts, | ||||
| 		v31.ErrorMap(errmap), | ||||
| 		v41.ErrorMap(errmap), | ||||
| 	) | ||||
| 	opts = append(opts, | ||||
| 		v31.Method(http.MethodGet), | ||||
| 		v31.Path("/ready"), | ||||
| 		v41.Method(http.MethodGet), | ||||
| 		v41.Path("/ready"), | ||||
| 	) | ||||
| 	rsp := &codec.Frame{} | ||||
| 	err := c.c.Call(ctx, c.c.NewRequest(c.name, "HealthService.Ready", req), rsp, opts...) | ||||
| @@ -135,11 +135,11 @@ func (c *healthServiceClient) Version(ctx context.Context, req *codec.Frame, opt | ||||
| 	errmap := make(map[string]interface{}, 1) | ||||
| 	errmap["default"] = &codec.Frame{} | ||||
| 	opts = append(opts, | ||||
| 		v31.ErrorMap(errmap), | ||||
| 		v41.ErrorMap(errmap), | ||||
| 	) | ||||
| 	opts = append(opts, | ||||
| 		v31.Method(http.MethodGet), | ||||
| 		v31.Path("/version"), | ||||
| 		v41.Method(http.MethodGet), | ||||
| 		v41.Path("/version"), | ||||
| 	) | ||||
| 	rsp := &codec.Frame{} | ||||
| 	err := c.c.Call(ctx, c.c.NewRequest(c.name, "HealthService.Version", req), rsp, opts...) | ||||
| @@ -180,7 +180,6 @@ func RegisterHealthServiceServer(s server.Server, sh HealthServiceServer, opts . | ||||
| 		healthService | ||||
| 	} | ||||
| 	h := &healthServiceServer{sh} | ||||
| 	var nopts []server.HandlerOption | ||||
| 	nopts = append(nopts, v3.HandlerEndpoints(HealthServiceServerEndpoints)) | ||||
| 	return s.Handle(s.NewHandler(&HealthService{h}, append(nopts, opts...)...)) | ||||
| 	opts = append(opts, v4.HandlerEndpoints(HealthServiceServerEndpoints)) | ||||
| 	return s.Handle(s.NewHandler(&HealthService{h}, opts...)) | ||||
| } | ||||
|   | ||||
| @@ -8,10 +8,10 @@ import ( | ||||
| 	"strings" | ||||
| 	"sync" | ||||
|  | ||||
| 	codecpb "go.unistack.org/micro-proto/v3/codec" | ||||
| 	"go.unistack.org/micro/v3/logger" | ||||
| 	"go.unistack.org/micro/v3/metadata" | ||||
| 	"go.unistack.org/micro/v3/meter" | ||||
| 	codecpb "go.unistack.org/micro-proto/v4/codec" | ||||
| 	"go.unistack.org/micro/v4/logger" | ||||
| 	"go.unistack.org/micro/v4/metadata" | ||||
| 	"go.unistack.org/micro/v4/meter" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| @@ -125,8 +125,11 @@ func gzipAccepted(md metadata.Metadata) bool { | ||||
| 	if !ok { | ||||
| 		return false | ||||
| 	} | ||||
| 	if strings.Contains(a, "gzip") { | ||||
| 		return true | ||||
| 	for i := range a { | ||||
| 		if strings.Contains(a[i], "gzip") { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return false | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| syntax = "proto3"; | ||||
|  | ||||
| package micro.server.http.v3.handler.meter; | ||||
| option go_package = "go.unistack.org/micro-server-http/v3/handler/meter;meter_handler"; | ||||
| option go_package = "go.unistack.org/micro-server-http/v4/handler/meter;meter_handler"; | ||||
|  | ||||
| import "api/annotations.proto"; | ||||
| import "openapiv3/annotations.proto"; | ||||
|   | ||||
| @@ -1,15 +1,15 @@ | ||||
| // Code generated by protoc-gen-go-micro. DO NOT EDIT. | ||||
| // versions: | ||||
| // - protoc-gen-go-micro v3.10.4 | ||||
| // - protoc              v5.28.3 | ||||
| // - protoc-gen-go-micro v4.1.0 | ||||
| // - protoc              v5.29.3 | ||||
| // source: meter/meter.proto | ||||
|  | ||||
| package meter_handler | ||||
|  | ||||
| import ( | ||||
| 	context "context" | ||||
| 	codec "go.unistack.org/micro-proto/v3/codec" | ||||
| 	client "go.unistack.org/micro/v3/client" | ||||
| 	codec "go.unistack.org/micro-proto/v4/codec" | ||||
| 	client "go.unistack.org/micro/v4/client" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
|   | ||||
| @@ -1,21 +1,21 @@ | ||||
| // Code generated by protoc-gen-go-micro. DO NOT EDIT. | ||||
| // protoc-gen-go-micro version: v3.10.4 | ||||
| // protoc-gen-go-micro version: v4.1.0 | ||||
| // source: meter/meter.proto | ||||
|  | ||||
| package meter_handler | ||||
|  | ||||
| import ( | ||||
| 	context "context" | ||||
| 	v31 "go.unistack.org/micro-client-http/v3" | ||||
| 	codec "go.unistack.org/micro-proto/v3/codec" | ||||
| 	v3 "go.unistack.org/micro-server-http/v3" | ||||
| 	client "go.unistack.org/micro/v3/client" | ||||
| 	server "go.unistack.org/micro/v3/server" | ||||
| 	v41 "go.unistack.org/micro-client-http/v4" | ||||
| 	codec "go.unistack.org/micro-proto/v4/codec" | ||||
| 	v4 "go.unistack.org/micro-server-http/v4" | ||||
| 	client "go.unistack.org/micro/v4/client" | ||||
| 	server "go.unistack.org/micro/v4/server" | ||||
| 	http "net/http" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	MeterServiceServerEndpoints = []v3.EndpointMetadata{ | ||||
| 	MeterServiceServerEndpoints = []v4.EndpointMetadata{ | ||||
| 		{ | ||||
| 			Name:   "MeterService.Metrics", | ||||
| 			Path:   "/metrics", | ||||
| @@ -39,11 +39,11 @@ func (c *meterServiceClient) Metrics(ctx context.Context, req *codec.Frame, opts | ||||
| 	errmap := make(map[string]interface{}, 1) | ||||
| 	errmap["default"] = &codec.Frame{} | ||||
| 	opts = append(opts, | ||||
| 		v31.ErrorMap(errmap), | ||||
| 		v41.ErrorMap(errmap), | ||||
| 	) | ||||
| 	opts = append(opts, | ||||
| 		v31.Method(http.MethodGet), | ||||
| 		v31.Path("/metrics"), | ||||
| 		v41.Method(http.MethodGet), | ||||
| 		v41.Path("/metrics"), | ||||
| 	) | ||||
| 	rsp := &codec.Frame{} | ||||
| 	err := c.c.Call(ctx, c.c.NewRequest(c.name, "MeterService.Metrics", req), rsp, opts...) | ||||
| @@ -69,7 +69,6 @@ func RegisterMeterServiceServer(s server.Server, sh MeterServiceServer, opts ... | ||||
| 		meterService | ||||
| 	} | ||||
| 	h := &meterServiceServer{sh} | ||||
| 	var nopts []server.HandlerOption | ||||
| 	nopts = append(nopts, v3.HandlerEndpoints(MeterServiceServerEndpoints)) | ||||
| 	return s.Handle(s.NewHandler(&MeterService{h}, append(nopts, opts...)...)) | ||||
| 	opts = append(opts, v4.HandlerEndpoints(MeterServiceServerEndpoints)) | ||||
| 	return s.Handle(s.NewHandler(&MeterService{h}, opts...)) | ||||
| } | ||||
|   | ||||
| @@ -4,8 +4,8 @@ import ( | ||||
| 	"io/fs" | ||||
| 	"net/http" | ||||
|  | ||||
| 	yamlcodec "go.unistack.org/micro-codec-yaml/v3" | ||||
| 	rutil "go.unistack.org/micro/v3/util/reflect" | ||||
| 	yamlcodec "go.unistack.org/micro-codec-yaml/v4" | ||||
| 	rutil "go.unistack.org/micro/v4/util/reflect" | ||||
| ) | ||||
|  | ||||
| // Handler append to generated swagger data from dst map[string]interface{} | ||||
|   | ||||
							
								
								
									
										124
									
								
								http.go
									
									
									
									
									
								
							
							
						
						
									
										124
									
								
								http.go
									
									
									
									
									
								
							| @@ -9,18 +9,16 @@ import ( | ||||
| 	"net" | ||||
| 	"net/http" | ||||
| 	"reflect" | ||||
| 	"sort" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| 	"sync/atomic" | ||||
| 	"time" | ||||
|  | ||||
| 	"go.unistack.org/micro/v3/broker" | ||||
| 	"go.unistack.org/micro/v3/codec" | ||||
| 	"go.unistack.org/micro/v3/logger" | ||||
| 	"go.unistack.org/micro/v3/register" | ||||
| 	"go.unistack.org/micro/v3/server" | ||||
| 	rhttp "go.unistack.org/micro/v3/util/http" | ||||
| 	"go.unistack.org/micro/v4/codec" | ||||
| 	"go.unistack.org/micro/v4/logger" | ||||
| 	"go.unistack.org/micro/v4/register" | ||||
| 	"go.unistack.org/micro/v4/server" | ||||
| 	rhttp "go.unistack.org/micro/v4/util/http" | ||||
| 	"golang.org/x/net/netutil" | ||||
| ) | ||||
|  | ||||
| @@ -31,7 +29,6 @@ type Server struct { | ||||
| 	rsvc         *register.Service | ||||
| 	handlers     map[string]server.Handler | ||||
| 	exit         chan chan error | ||||
| 	subscribers  map[*httpSubscriber][]broker.Subscriber | ||||
| 	errorHandler func(context.Context, server.Handler, http.ResponseWriter, *http.Request, error, int) | ||||
| 	pathHandlers *rhttp.Trie | ||||
| 	opts         server.Options | ||||
| @@ -172,17 +169,6 @@ func (h *Server) NewHandler(handler interface{}, opts ...server.HandlerOption) s | ||||
|  | ||||
| 	tp := reflect.TypeOf(handler) | ||||
|  | ||||
| 	/* | ||||
| 		if len(options.Metadata) == 0 { | ||||
| 			if h.registerRPC { | ||||
| 				h.opts.Logger.Infof(h.opts.Context, "register rpc handler for http.MethodPost %s /%s", hn, hn) | ||||
| 				if err := hdlr.handlers.Insert([]string{http.MethodPost}, "/"+hn, pth); err != nil { | ||||
| 					h.opts.Logger.Errorf(h.opts.Context, "cant add rpc handler for http.MethodPost %s /%s", hn, hn) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	*/ | ||||
|  | ||||
| 	registerCORS := false | ||||
| 	if v, ok := options.Context.Value(registerCORSHandlerKey{}).(bool); ok && v { | ||||
| 		registerCORS = true | ||||
| @@ -220,13 +206,16 @@ func (h *Server) NewHandler(handler interface{}, opts ...server.HandlerOption) s | ||||
| 		pth := &patHandler{mtype: mtype, name: name, rcvr: rcvr} | ||||
| 		hdlr.name = name | ||||
|  | ||||
| 		methods := []string{md["Method"]} | ||||
| 		methods := md["Method"] | ||||
| 		if registerCORS { | ||||
| 			methods = append(methods, http.MethodOptions) | ||||
| 		} | ||||
|  | ||||
| 		if err := hdlr.handlers.Insert(methods, md["Path"], pth); err != nil { | ||||
| 			h.opts.Logger.Error(h.opts.Context, fmt.Sprintf("cant add handler for %v %s", methods, md["Path"])) | ||||
| 		pattern := md["Path"] | ||||
| 		for i := len(pattern) - 1; i >= 0; i-- { | ||||
| 			if err := hdlr.handlers.Insert(methods, pattern[i], pth); err != nil { | ||||
| 				h.opts.Logger.Error(h.opts.Context, fmt.Sprintf("cant add handler for %v %s: index %d", methods, md["Path"], i)) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if h.registerRPC { | ||||
| @@ -304,35 +293,6 @@ func (h *Server) NewHandler(handler interface{}, opts ...server.HandlerOption) s | ||||
| 	return hdlr | ||||
| } | ||||
|  | ||||
| func (h *Server) NewSubscriber(topic string, handler interface{}, opts ...server.SubscriberOption) server.Subscriber { | ||||
| 	return newSubscriber(topic, handler, opts...) | ||||
| } | ||||
|  | ||||
| func (h *Server) Subscribe(sb server.Subscriber) error { | ||||
| 	sub, ok := sb.(*httpSubscriber) | ||||
| 	if !ok { | ||||
| 		return fmt.Errorf("invalid subscriber: expected *httpSubscriber") | ||||
| 	} | ||||
| 	if len(sub.handlers) == 0 { | ||||
| 		return fmt.Errorf("invalid subscriber: no handler functions") | ||||
| 	} | ||||
|  | ||||
| 	if err := server.ValidateSubscriber(sb); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	h.RLock() | ||||
| 	_, ok = h.subscribers[sub] | ||||
| 	h.RUnlock() | ||||
| 	if ok { | ||||
| 		return fmt.Errorf("subscriber %v already exists", h) | ||||
| 	} | ||||
| 	h.Lock() | ||||
| 	h.subscribers[sub] = nil | ||||
| 	h.Unlock() | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (h *Server) Register() error { | ||||
| 	h.RLock() | ||||
| 	rsvc := h.rsvc | ||||
| @@ -352,18 +312,6 @@ func (h *Server) Register() error { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	h.Lock() | ||||
| 	subscriberList := make([]*httpSubscriber, 0, len(h.subscribers)) | ||||
| 	for e := range h.subscribers { | ||||
| 		// Only advertise non internal subscribers | ||||
| 		subscriberList = append(subscriberList, e) | ||||
| 	} | ||||
| 	sort.Slice(subscriberList, func(i, j int) bool { | ||||
| 		return subscriberList[i].topic > subscriberList[j].topic | ||||
| 	}) | ||||
|  | ||||
| 	h.Unlock() | ||||
|  | ||||
| 	h.RLock() | ||||
| 	registered := h.registered | ||||
| 	h.RUnlock() | ||||
| @@ -393,35 +341,6 @@ func (h *Server) Register() error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (h *Server) subscribe() error { | ||||
| 	config := h.opts | ||||
|  | ||||
| 	for sb := range h.subscribers { | ||||
| 		handler := h.createSubHandler(sb, config) | ||||
| 		var opts []broker.SubscribeOption | ||||
| 		if queue := sb.Options().Queue; len(queue) > 0 { | ||||
| 			opts = append(opts, broker.SubscribeGroup(queue)) | ||||
| 		} | ||||
|  | ||||
| 		subCtx := config.Context | ||||
| 		if cx := sb.Options().Context; cx != nil { | ||||
| 			subCtx = cx | ||||
| 		} | ||||
| 		opts = append(opts, broker.SubscribeContext(subCtx)) | ||||
| 		opts = append(opts, broker.SubscribeAutoAck(sb.Options().AutoAck)) | ||||
| 		opts = append(opts, broker.SubscribeBodyOnly(sb.Options().BodyOnly)) | ||||
|  | ||||
| 		sub, err := config.Broker.Subscribe(subCtx, sb.Topic(), handler, opts...) | ||||
| 		if err != nil { | ||||
| 			h.Unlock() | ||||
| 			return err | ||||
| 		} | ||||
| 		h.subscribers[sb] = []broker.Subscriber{sub} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (h *Server) Deregister() error { | ||||
| 	h.RLock() | ||||
| 	config := h.opts | ||||
| @@ -450,22 +369,6 @@ func (h *Server) Deregister() error { | ||||
|  | ||||
| 	h.registered = false | ||||
|  | ||||
| 	subCtx := h.opts.Context | ||||
| 	for sb, subs := range h.subscribers { | ||||
| 		if cx := sb.Options().Context; cx != nil { | ||||
| 			subCtx = cx | ||||
| 		} | ||||
|  | ||||
| 		for _, sub := range subs { | ||||
| 			config.Logger.Info(config.Context, "Unsubscribing from topic: "+sub.Topic()) | ||||
| 			if err := sub.Unsubscribe(subCtx); err != nil { | ||||
| 				h.Unlock() | ||||
| 				config.Logger.Error(config.Context, fmt.Sprintf("failed to unsubscribe topic: %s, error", sb.Topic()), err) | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
| 		h.subscribers[sb] = nil | ||||
| 	} | ||||
| 	h.Unlock() | ||||
| 	return nil | ||||
| } | ||||
| @@ -552,10 +455,6 @@ func (h *Server) Start() error { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if err := h.subscribe(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	fn := handler | ||||
|  | ||||
| 	var hs *http.Server | ||||
| @@ -701,7 +600,6 @@ func NewServer(opts ...server.Option) *Server { | ||||
| 		stateHealth:  &atomic.Uint32{}, | ||||
| 		opts:         options, | ||||
| 		exit:         make(chan chan error), | ||||
| 		subscribers:  make(map[*httpSubscriber][]broker.Subscriber), | ||||
| 		errorHandler: eh, | ||||
| 		pathHandlers: rhttp.NewTrie(), | ||||
| 	} | ||||
|   | ||||
							
								
								
									
										34
									
								
								message.go
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								message.go
									
									
									
									
									
								
							| @@ -1,34 +0,0 @@ | ||||
| package http | ||||
|  | ||||
| import ( | ||||
| 	"go.unistack.org/micro/v3/codec" | ||||
| 	"go.unistack.org/micro/v3/metadata" | ||||
| ) | ||||
|  | ||||
| type httpMessage struct { | ||||
| 	payload     interface{} | ||||
| 	codec       codec.Codec | ||||
| 	header      metadata.Metadata | ||||
| 	topic       string | ||||
| 	contentType string | ||||
| } | ||||
|  | ||||
| func (r *httpMessage) Topic() string { | ||||
| 	return r.topic | ||||
| } | ||||
|  | ||||
| func (r *httpMessage) ContentType() string { | ||||
| 	return r.contentType | ||||
| } | ||||
|  | ||||
| func (r *httpMessage) Header() metadata.Metadata { | ||||
| 	return r.header | ||||
| } | ||||
|  | ||||
| func (r *httpMessage) Body() interface{} { | ||||
| 	return r.payload | ||||
| } | ||||
|  | ||||
| func (r *httpMessage) Codec() codec.Codec { | ||||
| 	return r.codec | ||||
| } | ||||
| @@ -5,7 +5,7 @@ import ( | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
|  | ||||
| 	"go.unistack.org/micro/v3/server" | ||||
| 	"go.unistack.org/micro/v4/server" | ||||
| ) | ||||
|  | ||||
| // SetError pass error to caller | ||||
|   | ||||
							
								
								
									
										39
									
								
								request.go
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								request.go
									
									
									
									
									
								
							| @@ -1,15 +1,12 @@ | ||||
| package http | ||||
|  | ||||
| import ( | ||||
| 	"go.unistack.org/micro/v3/codec" | ||||
| 	"go.unistack.org/micro/v3/metadata" | ||||
| 	"go.unistack.org/micro/v3/server" | ||||
| 	"go.unistack.org/micro/v4/codec" | ||||
| 	"go.unistack.org/micro/v4/metadata" | ||||
| 	"go.unistack.org/micro/v4/server" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	_ server.Request = &rpcRequest{} | ||||
| 	_ server.Message = &rpcMessage{} | ||||
| ) | ||||
| var _ server.Request = &rpcRequest{} | ||||
|  | ||||
| type rpcRequest struct { | ||||
| 	// rw          io.ReadWriter | ||||
| @@ -23,14 +20,6 @@ type rpcRequest struct { | ||||
| 	stream      bool | ||||
| } | ||||
|  | ||||
| type rpcMessage struct { | ||||
| 	payload     interface{} | ||||
| 	codec       codec.Codec | ||||
| 	header      metadata.Metadata | ||||
| 	topic       string | ||||
| 	contentType string | ||||
| } | ||||
|  | ||||
| func (r *rpcRequest) ContentType() string { | ||||
| 	return r.contentType | ||||
| } | ||||
| @@ -66,23 +55,3 @@ func (r *rpcRequest) Stream() bool { | ||||
| func (r *rpcRequest) Body() interface{} { | ||||
| 	return r.payload | ||||
| } | ||||
|  | ||||
| func (r *rpcMessage) ContentType() string { | ||||
| 	return r.contentType | ||||
| } | ||||
|  | ||||
| func (r *rpcMessage) Topic() string { | ||||
| 	return r.topic | ||||
| } | ||||
|  | ||||
| func (r *rpcMessage) Body() interface{} { | ||||
| 	return r.payload | ||||
| } | ||||
|  | ||||
| func (r *rpcMessage) Header() metadata.Metadata { | ||||
| 	return r.header | ||||
| } | ||||
|  | ||||
| func (r *rpcMessage) Codec() codec.Codec { | ||||
| 	return r.codec | ||||
| } | ||||
|   | ||||
| @@ -7,9 +7,11 @@ import ( | ||||
| 	"unicode" | ||||
| 	"unicode/utf8" | ||||
|  | ||||
| 	"go.unistack.org/micro/v3/server" | ||||
| 	"go.unistack.org/micro/v4/server" | ||||
| ) | ||||
|  | ||||
| var typeOfError = reflect.TypeOf((*error)(nil)).Elem() | ||||
|  | ||||
| type methodType struct { | ||||
| 	ArgType     reflect.Type | ||||
| 	ReplyType   reflect.Type | ||||
|   | ||||
							
								
								
									
										175
									
								
								subscriber.go
									
									
									
									
									
								
							
							
						
						
									
										175
									
								
								subscriber.go
									
									
									
									
									
								
							| @@ -1,175 +0,0 @@ | ||||
| package http | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| 	"strings" | ||||
|  | ||||
| 	"go.unistack.org/micro/v3/broker" | ||||
| 	"go.unistack.org/micro/v3/metadata" | ||||
| 	"go.unistack.org/micro/v3/options" | ||||
| 	"go.unistack.org/micro/v3/server" | ||||
| ) | ||||
|  | ||||
| var typeOfError = reflect.TypeOf((*error)(nil)).Elem() | ||||
|  | ||||
| type handler struct { | ||||
| 	reqType reflect.Type | ||||
| 	ctxType reflect.Type | ||||
| 	method  reflect.Value | ||||
| } | ||||
|  | ||||
| type httpSubscriber struct { | ||||
| 	topic      string | ||||
| 	rcvr       reflect.Value | ||||
| 	typ        reflect.Type | ||||
| 	subscriber interface{} | ||||
| 	handlers   []*handler | ||||
| 	opts       server.SubscriberOptions | ||||
| } | ||||
|  | ||||
| func newSubscriber(topic string, sub interface{}, opts ...server.SubscriberOption) server.Subscriber { | ||||
| 	options := server.NewSubscriberOptions(opts...) | ||||
|  | ||||
| 	var handlers []*handler | ||||
|  | ||||
| 	if typ := reflect.TypeOf(sub); typ.Kind() == reflect.Func { | ||||
| 		h := &handler{ | ||||
| 			method: reflect.ValueOf(sub), | ||||
| 		} | ||||
|  | ||||
| 		switch typ.NumIn() { | ||||
| 		case 1: | ||||
| 			h.reqType = typ.In(0) | ||||
| 		case 2: | ||||
| 			h.ctxType = typ.In(0) | ||||
| 			h.reqType = typ.In(1) | ||||
| 		} | ||||
|  | ||||
| 		handlers = append(handlers, h) | ||||
| 	} else { | ||||
| 		for m := 0; m < typ.NumMethod(); m++ { | ||||
| 			method := typ.Method(m) | ||||
| 			h := &handler{ | ||||
| 				method: method.Func, | ||||
| 			} | ||||
|  | ||||
| 			switch method.Type.NumIn() { | ||||
| 			case 2: | ||||
| 				h.reqType = method.Type.In(1) | ||||
| 			case 3: | ||||
| 				h.ctxType = method.Type.In(1) | ||||
| 				h.reqType = method.Type.In(2) | ||||
| 			} | ||||
|  | ||||
| 			handlers = append(handlers, h) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return &httpSubscriber{ | ||||
| 		rcvr:       reflect.ValueOf(sub), | ||||
| 		typ:        reflect.TypeOf(sub), | ||||
| 		topic:      topic, | ||||
| 		subscriber: sub, | ||||
| 		handlers:   handlers, | ||||
| 		opts:       options, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (s *Server) createSubHandler(sb *httpSubscriber, opts server.Options) broker.Handler { | ||||
| 	return func(p broker.Event) error { | ||||
| 		msg := p.Message() | ||||
| 		ct := msg.Header["Content-Type"] | ||||
| 		cf, err := s.newCodec(ct) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		hdr := metadata.Copy(msg.Header) | ||||
| 		ctx := metadata.NewIncomingContext(context.Background(), hdr) | ||||
|  | ||||
| 		results := make(chan error, len(sb.handlers)) | ||||
|  | ||||
| 		for i := 0; i < len(sb.handlers); i++ { | ||||
| 			handler := sb.handlers[i] | ||||
|  | ||||
| 			var isVal bool | ||||
| 			var req reflect.Value | ||||
|  | ||||
| 			if handler.reqType.Kind() == reflect.Ptr { | ||||
| 				req = reflect.New(handler.reqType.Elem()) | ||||
| 			} else { | ||||
| 				req = reflect.New(handler.reqType) | ||||
| 				isVal = true | ||||
| 			} | ||||
| 			if isVal { | ||||
| 				req = req.Elem() | ||||
| 			} | ||||
|  | ||||
| 			if err := cf.Unmarshal(msg.Body, req.Interface()); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
|  | ||||
| 			fn := func(ctx context.Context, msg server.Message) error { | ||||
| 				var vals []reflect.Value | ||||
| 				if sb.typ.Kind() != reflect.Func { | ||||
| 					vals = append(vals, sb.rcvr) | ||||
| 				} | ||||
| 				if handler.ctxType != nil { | ||||
| 					vals = append(vals, reflect.ValueOf(ctx)) | ||||
| 				} | ||||
|  | ||||
| 				vals = append(vals, reflect.ValueOf(msg.Body())) | ||||
|  | ||||
| 				returnValues := handler.method.Call(vals) | ||||
| 				if err := returnValues[0].Interface(); err != nil { | ||||
| 					return err.(error) | ||||
| 				} | ||||
| 				return nil | ||||
| 			} | ||||
|  | ||||
| 			opts.Hooks.EachPrev(func(hook options.Hook) { | ||||
| 				if h, ok := hook.(server.HookSubHandler); ok { | ||||
| 					fn = h(fn) | ||||
| 				} | ||||
| 			}) | ||||
|  | ||||
| 			go func() { | ||||
| 				results <- fn(ctx, &httpMessage{ | ||||
| 					topic:       sb.topic, | ||||
| 					contentType: ct, | ||||
| 					payload:     req.Interface(), | ||||
| 					header:      msg.Header, | ||||
| 					codec:       cf, | ||||
| 				}) | ||||
| 			}() | ||||
| 		} | ||||
|  | ||||
| 		var errors []string | ||||
|  | ||||
| 		for i := 0; i < len(sb.handlers); i++ { | ||||
| 			if err := <-results; err != nil { | ||||
| 				errors = append(errors, err.Error()) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if len(errors) > 0 { | ||||
| 			return fmt.Errorf("subscriber error: %s", strings.Join(errors, "\n")) | ||||
| 		} | ||||
|  | ||||
| 		return nil | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (s *httpSubscriber) Topic() string { | ||||
| 	return s.topic | ||||
| } | ||||
|  | ||||
| func (s *httpSubscriber) Subscriber() interface{} { | ||||
| 	return s.subscriber | ||||
| } | ||||
|  | ||||
| func (s *httpSubscriber) Options() server.SubscriberOptions { | ||||
| 	return s.opts | ||||
| } | ||||
							
								
								
									
										55
									
								
								util.go
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								util.go
									
									
									
									
									
								
							| @@ -5,8 +5,8 @@ import ( | ||||
| 	"net/http" | ||||
| 	"strings" | ||||
|  | ||||
| 	"go.unistack.org/micro/v3/metadata" | ||||
| 	rutil "go.unistack.org/micro/v3/util/reflect" | ||||
| 	"go.unistack.org/micro/v4/metadata" | ||||
| 	rutil "go.unistack.org/micro/v4/util/reflect" | ||||
| ) | ||||
|  | ||||
| func FillRequest(ctx context.Context, req interface{}, opts ...FillRequestOption) error { | ||||
| @@ -15,39 +15,52 @@ func FillRequest(ctx context.Context, req interface{}, opts ...FillRequestOption | ||||
| 	for _, o := range opts { | ||||
| 		o(&options) | ||||
| 	} | ||||
|  | ||||
| 	md, ok := metadata.FromIncomingContext(ctx) | ||||
| 	if !ok { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	for idx := 0; idx < len(options.headers)/2; idx += 2 { | ||||
| 		k := http.CanonicalHeaderKey(options.headers[idx]) | ||||
| 		v, ok := md[k] | ||||
| 		k := options.headers[idx] | ||||
| 		v, ok := md.Get(k) | ||||
| 		if !ok { | ||||
| 			continue | ||||
| 		} | ||||
| 		if err = rutil.SetFieldByPath(req, v, k); err != nil { | ||||
|  | ||||
| 		if len(v) == 1 { | ||||
| 			err = rutil.SetFieldByPath(req, v[0], k) | ||||
| 		} else { | ||||
| 			err = rutil.SetFieldByPath(req, v, k) | ||||
| 		} | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	cookies := strings.Split(md["Cookie"], ";") | ||||
| 	cmd := make(map[string]string, len(cookies)) | ||||
| 	for _, cookie := range cookies { | ||||
| 		kv := strings.Split(cookie, "=") | ||||
| 		if len(kv) != 2 { | ||||
| 			continue | ||||
| 	cookieVals, _ := md.Get("Cookie") | ||||
| 	for i := range cookieVals { | ||||
| 		cookies := strings.Split(cookieVals[i], ";") | ||||
| 		cmd := make(map[string]string, len(cookies)) | ||||
| 		for _, cookie := range cookies { | ||||
| 			kv := strings.Split(cookie, "=") | ||||
| 			if len(kv) != 2 { | ||||
| 				continue | ||||
| 			} | ||||
| 			cmd[strings.TrimSpace(kv[0])] = strings.TrimSpace(kv[1]) | ||||
| 		} | ||||
| 		cmd[strings.TrimSpace(kv[0])] = strings.TrimSpace(kv[1]) | ||||
| 	} | ||||
| 	for idx := 0; idx < len(options.cookies)/2; idx += 2 { | ||||
| 		k := http.CanonicalHeaderKey(options.cookies[idx]) | ||||
| 		v, ok := cmd[k] | ||||
| 		if !ok { | ||||
| 			continue | ||||
| 		} | ||||
| 		if err = rutil.SetFieldByPath(req, v, k); err != nil { | ||||
| 			return err | ||||
| 		for idx := 0; idx < len(options.cookies)/2; idx += 2 { | ||||
| 			k := http.CanonicalHeaderKey(options.cookies[idx]) | ||||
| 			v, ok := cmd[k] | ||||
|  | ||||
| 			if !ok { | ||||
| 				continue | ||||
| 			} | ||||
|  | ||||
| 			err = rutil.SetFieldByPath(req, v, k) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -7,9 +7,9 @@ import ( | ||||
| 	"strings" | ||||
| 	"testing" | ||||
|  | ||||
| 	"go.unistack.org/micro/v3/metadata" | ||||
| 	"go.unistack.org/micro/v3/options" | ||||
| 	"go.unistack.org/micro/v3/server" | ||||
| 	"go.unistack.org/micro/v4/metadata" | ||||
| 	"go.unistack.org/micro/v4/options" | ||||
| 	"go.unistack.org/micro/v4/server" | ||||
| ) | ||||
|  | ||||
| func Test_Hook(t *testing.T) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user