Browse code

Update containerd to cf554d59dd96e459544748290eb91

This bumps containerd to cf554d59dd96e459544748290eb9167f4bcde509 and
includes various fixes and updates the grpc package and types generated
for use.

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>

Michael Crosby authored on 2016/06/08 06:30:43
Showing 67 changed files
... ...
@@ -244,7 +244,7 @@ RUN set -x \
244 244
 	&& rm -rf "$GOPATH"
245 245
 
246 246
 # Install containerd
247
-ENV CONTAINERD_COMMIT 57b7c3da915ebe943bd304c00890959b191e5264
247
+ENV CONTAINERD_COMMIT cf554d59dd96e459544748290eb9167f4bcde509
248 248
 RUN set -x \
249 249
 	&& export GOPATH="$(mktemp -d)" \
250 250
 	&& git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
... ...
@@ -191,7 +191,7 @@ RUN set -x \
191 191
 	&& rm -rf "$GOPATH"
192 192
 
193 193
 # Install containerd
194
-ENV CONTAINERD_COMMIT 57b7c3da915ebe943bd304c00890959b191e5264
194
+ENV CONTAINERD_COMMIT cf554d59dd96e459544748290eb9167f4bcde509
195 195
 RUN set -x \
196 196
 	&& export GOPATH="$(mktemp -d)" \
197 197
 	&& git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
... ...
@@ -200,7 +200,7 @@ RUN set -x \
200 200
 	&& rm -rf "$GOPATH"
201 201
 
202 202
 # Install containerd
203
-ENV CONTAINERD_COMMIT 57b7c3da915ebe943bd304c00890959b191e5264
203
+ENV CONTAINERD_COMMIT cf554d59dd96e459544748290eb9167f4bcde509
204 204
 RUN set -x \
205 205
 	&& export GOPATH="$(mktemp -d)" \
206 206
 	&& git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
... ...
@@ -85,7 +85,7 @@ RUN set -x \
85 85
 	&& rm -rf "$GOPATH"
86 86
 
87 87
 # Install containerd
88
-ENV CONTAINERD_COMMIT 57b7c3da915ebe943bd304c00890959b191e5264
88
+ENV CONTAINERD_COMMIT cf554d59dd96e459544748290eb9167f4bcde509
89 89
 RUN set -x \
90 90
 	&& export GOPATH="$(mktemp -d)" \
91 91
 	&& git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
... ...
@@ -215,7 +215,7 @@ RUN set -x \
215 215
 	&& rm -rf "$GOPATH"
216 216
 
217 217
 # Install containerd
218
-ENV CONTAINERD_COMMIT 57b7c3da915ebe943bd304c00890959b191e5264
218
+ENV CONTAINERD_COMMIT cf554d59dd96e459544748290eb9167f4bcde509
219 219
 RUN set -x \
220 220
 	&& export GOPATH="$(mktemp -d)" \
221 221
 	&& git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
... ...
@@ -208,7 +208,7 @@ RUN set -x \
208 208
 	&& rm -rf "$GOPATH"
209 209
 
210 210
 # Install containerd
211
-ENV CONTAINERD_COMMIT 57b7c3da915ebe943bd304c00890959b191e5264
211
+ENV CONTAINERD_COMMIT cf554d59dd96e459544748290eb9167f4bcde509
212 212
 RUN set -x \
213 213
 	&& export GOPATH="$(mktemp -d)" \
214 214
 	&& git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
... ...
@@ -68,7 +68,7 @@ RUN set -x \
68 68
 	&& rm -rf "$GOPATH"
69 69
 
70 70
 # Install containerd
71
-ENV CONTAINERD_COMMIT 57b7c3da915ebe943bd304c00890959b191e5264
71
+ENV CONTAINERD_COMMIT cf554d59dd96e459544748290eb9167f4bcde509
72 72
 RUN set -x \
73 73
 	&& export GOPATH="$(mktemp -d)" \
74 74
 	&& git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
... ...
@@ -56,7 +56,7 @@ clone git github.com/mattn/go-sqlite3 v1.1.0
56 56
 clone git github.com/tchap/go-patricia v2.1.0
57 57
 clone git github.com/vdemeester/shakers 24d7f1d6a71aa5d9cbe7390e4afb66b7eef9e1b3
58 58
 # forked golang.org/x/net package includes a patch for lazy loading trace templates
59
-clone git golang.org/x/net 78cb2c067747f08b343f20614155233ab4ea2ad3 https://github.com/tonistiigi/net.git
59
+clone git golang.org/x/net 2beffdc2e92c8a3027590f898fe88f69af48a3f8 https://github.com/tonistiigi/net.git
60 60
 clone git golang.org/x/sys eb2c74142fd19a79b3f237334c7384d5167b1b46 https://github.com/golang/sys.git
61 61
 clone git github.com/docker/go-units 651fc226e7441360384da338d0fd37f2440ffbe3
62 62
 clone git github.com/docker/go-connections v0.2.0
... ...
@@ -97,7 +97,7 @@ clone git github.com/pborman/uuid v1.0
97 97
 # get desired notary commit, might also need to be updated in Dockerfile
98 98
 clone git github.com/docker/notary v0.3.0
99 99
 
100
-clone git google.golang.org/grpc a22b6611561e9f0a3e0919690dd2caf48f14c517 https://github.com/grpc/grpc-go.git
100
+clone git google.golang.org/grpc ab0be5212fb225475f2087566eded7da5d727960 https://github.com/grpc/grpc-go.git
101 101
 clone git github.com/miekg/pkcs11 df8ae6ca730422dba20c768ff38ef7d79077a59f
102 102
 clone git github.com/docker/go v1.5.1-1-1-gbaf439e
103 103
 clone git github.com/agl/ed25519 d2b94fd789ea21d12fac1a4443dd3a3f79cda72c
... ...
@@ -109,7 +109,7 @@ clone git github.com/seccomp/libseccomp-golang 60c9953736798c4a04e90d0f3da2f933d
109 109
 clone git github.com/coreos/go-systemd v4
110 110
 clone git github.com/godbus/dbus v4.0.0
111 111
 clone git github.com/syndtr/gocapability 2c00daeb6c3b45114c80ac44119e7b8801fdd852
112
-clone git github.com/golang/protobuf 8d92cf5fc15a4382f8964b08e1f42a75c0591aa3
112
+clone git github.com/golang/protobuf 3c84672111d91bb5ac31719e112f9f7126a0e26e
113 113
 
114 114
 # gelf logging driver deps
115 115
 clone git github.com/Graylog2/go-gelf aab2f594e4585d43468ac57287b0dece9d806883
... ...
@@ -136,7 +136,7 @@ clone git google.golang.org/cloud dae7e3d993bc3812a2185af60552bb6b847e52a0 https
136 136
 clone git github.com/docker/docker-credential-helpers v0.3.0
137 137
 
138 138
 # containerd
139
-clone git github.com/docker/containerd 57b7c3da915ebe943bd304c00890959b191e5264
139
+clone git github.com/docker/containerd cf554d59dd96e459544748290eb9167f4bcde509
140 140
 
141 141
 # cli
142 142
 clone git github.com/spf13/cobra 75205f23b3ea70dc7ae5e900d074e010c23c37e9 https://github.com/dnephin/cobra.git
... ...
@@ -115,14 +115,17 @@ func (*UpdateProcessResponse) ProtoMessage()               {}
115 115
 func (*UpdateProcessResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
116 116
 
117 117
 type CreateContainerRequest struct {
118
-	Id          string   `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
119
-	BundlePath  string   `protobuf:"bytes,2,opt,name=bundlePath" json:"bundlePath,omitempty"`
120
-	Checkpoint  string   `protobuf:"bytes,3,opt,name=checkpoint" json:"checkpoint,omitempty"`
121
-	Stdin       string   `protobuf:"bytes,4,opt,name=stdin" json:"stdin,omitempty"`
122
-	Stdout      string   `protobuf:"bytes,5,opt,name=stdout" json:"stdout,omitempty"`
123
-	Stderr      string   `protobuf:"bytes,6,opt,name=stderr" json:"stderr,omitempty"`
124
-	Labels      []string `protobuf:"bytes,7,rep,name=labels" json:"labels,omitempty"`
125
-	NoPivotRoot bool     `protobuf:"varint,8,opt,name=noPivotRoot" json:"noPivotRoot,omitempty"`
118
+	Id            string   `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
119
+	BundlePath    string   `protobuf:"bytes,2,opt,name=bundlePath" json:"bundlePath,omitempty"`
120
+	Checkpoint    string   `protobuf:"bytes,3,opt,name=checkpoint" json:"checkpoint,omitempty"`
121
+	Stdin         string   `protobuf:"bytes,4,opt,name=stdin" json:"stdin,omitempty"`
122
+	Stdout        string   `protobuf:"bytes,5,opt,name=stdout" json:"stdout,omitempty"`
123
+	Stderr        string   `protobuf:"bytes,6,opt,name=stderr" json:"stderr,omitempty"`
124
+	Labels        []string `protobuf:"bytes,7,rep,name=labels" json:"labels,omitempty"`
125
+	NoPivotRoot   bool     `protobuf:"varint,8,opt,name=noPivotRoot" json:"noPivotRoot,omitempty"`
126
+	Runtime       string   `protobuf:"bytes,9,opt,name=runtime" json:"runtime,omitempty"`
127
+	RuntimeArgs   []string `protobuf:"bytes,10,rep,name=runtimeArgs" json:"runtimeArgs,omitempty"`
128
+	CheckpointDir string   `protobuf:"bytes,11,opt,name=checkpointDir" json:"checkpointDir,omitempty"`
126 129
 }
127 130
 
128 131
 func (m *CreateContainerRequest) Reset()                    { *m = CreateContainerRequest{} }
... ...
@@ -233,8 +236,9 @@ func (*AddProcessResponse) ProtoMessage()               {}
233 233
 func (*AddProcessResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
234 234
 
235 235
 type CreateCheckpointRequest struct {
236
-	Id         string      `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
237
-	Checkpoint *Checkpoint `protobuf:"bytes,2,opt,name=checkpoint" json:"checkpoint,omitempty"`
236
+	Id            string      `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
237
+	Checkpoint    *Checkpoint `protobuf:"bytes,2,opt,name=checkpoint" json:"checkpoint,omitempty"`
238
+	CheckpointDir string      `protobuf:"bytes,3,opt,name=checkpointDir" json:"checkpointDir,omitempty"`
238 239
 }
239 240
 
240 241
 func (m *CreateCheckpointRequest) Reset()                    { *m = CreateCheckpointRequest{} }
... ...
@@ -258,8 +262,9 @@ func (*CreateCheckpointResponse) ProtoMessage()               {}
258 258
 func (*CreateCheckpointResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
259 259
 
260 260
 type DeleteCheckpointRequest struct {
261
-	Id   string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
262
-	Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
261
+	Id            string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
262
+	Name          string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
263
+	CheckpointDir string `protobuf:"bytes,3,opt,name=checkpointDir" json:"checkpointDir,omitempty"`
263 264
 }
264 265
 
265 266
 func (m *DeleteCheckpointRequest) Reset()                    { *m = DeleteCheckpointRequest{} }
... ...
@@ -276,7 +281,8 @@ func (*DeleteCheckpointResponse) ProtoMessage()               {}
276 276
 func (*DeleteCheckpointResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} }
277 277
 
278 278
 type ListCheckpointRequest struct {
279
-	Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
279
+	Id            string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
280
+	CheckpointDir string `protobuf:"bytes,2,opt,name=checkpointDir" json:"checkpointDir,omitempty"`
280 281
 }
281 282
 
282 283
 func (m *ListCheckpointRequest) Reset()                    { *m = ListCheckpointRequest{} }
... ...
@@ -446,16 +452,17 @@ func (m *UpdateContainerRequest) GetResources() *UpdateResource {
446 446
 }
447 447
 
448 448
 type UpdateResource struct {
449
-	BlkioWeight       uint32 `protobuf:"varint,1,opt,name=blkioWeight" json:"blkioWeight,omitempty"`
450
-	CpuShares         uint32 `protobuf:"varint,2,opt,name=cpuShares" json:"cpuShares,omitempty"`
451
-	CpuPeriod         uint32 `protobuf:"varint,3,opt,name=cpuPeriod" json:"cpuPeriod,omitempty"`
452
-	CpuQuota          uint32 `protobuf:"varint,4,opt,name=cpuQuota" json:"cpuQuota,omitempty"`
453
-	CpusetCpus        string `protobuf:"bytes,5,opt,name=cpusetCpus" json:"cpusetCpus,omitempty"`
454
-	CpusetMems        string `protobuf:"bytes,6,opt,name=cpusetMems" json:"cpusetMems,omitempty"`
455
-	MemoryLimit       uint32 `protobuf:"varint,7,opt,name=memoryLimit" json:"memoryLimit,omitempty"`
456
-	MemorySwap        uint32 `protobuf:"varint,8,opt,name=memorySwap" json:"memorySwap,omitempty"`
457
-	MemoryReservation uint32 `protobuf:"varint,9,opt,name=memoryReservation" json:"memoryReservation,omitempty"`
458
-	KernelMemoryLimit uint32 `protobuf:"varint,10,opt,name=kernelMemoryLimit" json:"kernelMemoryLimit,omitempty"`
449
+	BlkioWeight          uint32 `protobuf:"varint,1,opt,name=blkioWeight" json:"blkioWeight,omitempty"`
450
+	CpuShares            uint32 `protobuf:"varint,2,opt,name=cpuShares" json:"cpuShares,omitempty"`
451
+	CpuPeriod            uint32 `protobuf:"varint,3,opt,name=cpuPeriod" json:"cpuPeriod,omitempty"`
452
+	CpuQuota             uint32 `protobuf:"varint,4,opt,name=cpuQuota" json:"cpuQuota,omitempty"`
453
+	CpusetCpus           string `protobuf:"bytes,5,opt,name=cpusetCpus" json:"cpusetCpus,omitempty"`
454
+	CpusetMems           string `protobuf:"bytes,6,opt,name=cpusetMems" json:"cpusetMems,omitempty"`
455
+	MemoryLimit          uint32 `protobuf:"varint,7,opt,name=memoryLimit" json:"memoryLimit,omitempty"`
456
+	MemorySwap           uint32 `protobuf:"varint,8,opt,name=memorySwap" json:"memorySwap,omitempty"`
457
+	MemoryReservation    uint32 `protobuf:"varint,9,opt,name=memoryReservation" json:"memoryReservation,omitempty"`
458
+	KernelMemoryLimit    uint32 `protobuf:"varint,10,opt,name=kernelMemoryLimit" json:"kernelMemoryLimit,omitempty"`
459
+	KernelTCPMemoryLimit uint32 `protobuf:"varint,11,opt,name=kernelTCPMemoryLimit" json:"kernelTCPMemoryLimit,omitempty"`
459 460
 }
460 461
 
461 462
 func (m *UpdateResource) Reset()                    { *m = UpdateResource{} }
... ...
@@ -495,14 +502,14 @@ func (*Event) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{29} }
495 495
 
496 496
 type NetworkStats struct {
497 497
 	Name       string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
498
-	RxBytes    uint64 `protobuf:"varint,2,opt,name=rx_bytes" json:"rx_bytes,omitempty"`
499
-	Rx_Packets uint64 `protobuf:"varint,3,opt,name=rx_Packets" json:"rx_Packets,omitempty"`
500
-	RxErrors   uint64 `protobuf:"varint,4,opt,name=Rx_errors" json:"Rx_errors,omitempty"`
501
-	RxDropped  uint64 `protobuf:"varint,5,opt,name=Rx_dropped" json:"Rx_dropped,omitempty"`
502
-	TxBytes    uint64 `protobuf:"varint,6,opt,name=Tx_bytes" json:"Tx_bytes,omitempty"`
503
-	TxPackets  uint64 `protobuf:"varint,7,opt,name=Tx_packets" json:"Tx_packets,omitempty"`
504
-	TxErrors   uint64 `protobuf:"varint,8,opt,name=Tx_errors" json:"Tx_errors,omitempty"`
505
-	TxDropped  uint64 `protobuf:"varint,9,opt,name=Tx_dropped" json:"Tx_dropped,omitempty"`
498
+	RxBytes    uint64 `protobuf:"varint,2,opt,name=rx_bytes,json=rxBytes" json:"rx_bytes,omitempty"`
499
+	Rx_Packets uint64 `protobuf:"varint,3,opt,name=rx_Packets,json=rxPackets" json:"rx_Packets,omitempty"`
500
+	RxErrors   uint64 `protobuf:"varint,4,opt,name=Rx_errors,json=rxErrors" json:"Rx_errors,omitempty"`
501
+	RxDropped  uint64 `protobuf:"varint,5,opt,name=Rx_dropped,json=rxDropped" json:"Rx_dropped,omitempty"`
502
+	TxBytes    uint64 `protobuf:"varint,6,opt,name=Tx_bytes,json=txBytes" json:"Tx_bytes,omitempty"`
503
+	TxPackets  uint64 `protobuf:"varint,7,opt,name=Tx_packets,json=txPackets" json:"Tx_packets,omitempty"`
504
+	TxErrors   uint64 `protobuf:"varint,8,opt,name=Tx_errors,json=txErrors" json:"Tx_errors,omitempty"`
505
+	TxDropped  uint64 `protobuf:"varint,9,opt,name=Tx_dropped,json=txDropped" json:"Tx_dropped,omitempty"`
506 506
 }
507 507
 
508 508
 func (m *NetworkStats) Reset()                    { *m = NetworkStats{} }
... ...
@@ -511,10 +518,10 @@ func (*NetworkStats) ProtoMessage()               {}
511 511
 func (*NetworkStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{30} }
512 512
 
513 513
 type CpuUsage struct {
514
-	TotalUsage        uint64   `protobuf:"varint,1,opt,name=total_usage" json:"total_usage,omitempty"`
515
-	PercpuUsage       []uint64 `protobuf:"varint,2,rep,name=percpu_usage" json:"percpu_usage,omitempty"`
516
-	UsageInKernelmode uint64   `protobuf:"varint,3,opt,name=usage_in_kernelmode" json:"usage_in_kernelmode,omitempty"`
517
-	UsageInUsermode   uint64   `protobuf:"varint,4,opt,name=usage_in_usermode" json:"usage_in_usermode,omitempty"`
514
+	TotalUsage        uint64   `protobuf:"varint,1,opt,name=total_usage,json=totalUsage" json:"total_usage,omitempty"`
515
+	PercpuUsage       []uint64 `protobuf:"varint,2,rep,name=percpu_usage,json=percpuUsage" json:"percpu_usage,omitempty"`
516
+	UsageInKernelmode uint64   `protobuf:"varint,3,opt,name=usage_in_kernelmode,json=usageInKernelmode" json:"usage_in_kernelmode,omitempty"`
517
+	UsageInUsermode   uint64   `protobuf:"varint,4,opt,name=usage_in_usermode,json=usageInUsermode" json:"usage_in_usermode,omitempty"`
518 518
 }
519 519
 
520 520
 func (m *CpuUsage) Reset()                    { *m = CpuUsage{} }
... ...
@@ -524,8 +531,8 @@ func (*CpuUsage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{31
524 524
 
525 525
 type ThrottlingData struct {
526 526
 	Periods          uint64 `protobuf:"varint,1,opt,name=periods" json:"periods,omitempty"`
527
-	ThrottledPeriods uint64 `protobuf:"varint,2,opt,name=throttled_periods" json:"throttled_periods,omitempty"`
528
-	ThrottledTime    uint64 `protobuf:"varint,3,opt,name=throttled_time" json:"throttled_time,omitempty"`
527
+	ThrottledPeriods uint64 `protobuf:"varint,2,opt,name=throttled_periods,json=throttledPeriods" json:"throttled_periods,omitempty"`
528
+	ThrottledTime    uint64 `protobuf:"varint,3,opt,name=throttled_time,json=throttledTime" json:"throttled_time,omitempty"`
529 529
 }
530 530
 
531 531
 func (m *ThrottlingData) Reset()                    { *m = ThrottlingData{} }
... ...
@@ -534,9 +541,9 @@ func (*ThrottlingData) ProtoMessage()               {}
534 534
 func (*ThrottlingData) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{32} }
535 535
 
536 536
 type CpuStats struct {
537
-	CpuUsage       *CpuUsage       `protobuf:"bytes,1,opt,name=cpu_usage" json:"cpu_usage,omitempty"`
538
-	ThrottlingData *ThrottlingData `protobuf:"bytes,2,opt,name=throttling_data" json:"throttling_data,omitempty"`
539
-	SystemUsage    uint64          `protobuf:"varint,3,opt,name=system_usage" json:"system_usage,omitempty"`
537
+	CpuUsage       *CpuUsage       `protobuf:"bytes,1,opt,name=cpu_usage,json=cpuUsage" json:"cpu_usage,omitempty"`
538
+	ThrottlingData *ThrottlingData `protobuf:"bytes,2,opt,name=throttling_data,json=throttlingData" json:"throttling_data,omitempty"`
539
+	SystemUsage    uint64          `protobuf:"varint,3,opt,name=system_usage,json=systemUsage" json:"system_usage,omitempty"`
540 540
 }
541 541
 
542 542
 func (m *CpuStats) Reset()                    { *m = CpuStats{} }
... ...
@@ -570,7 +577,7 @@ func (*PidsStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3
570 570
 
571 571
 type MemoryData struct {
572 572
 	Usage    uint64 `protobuf:"varint,1,opt,name=usage" json:"usage,omitempty"`
573
-	MaxUsage uint64 `protobuf:"varint,2,opt,name=max_usage" json:"max_usage,omitempty"`
573
+	MaxUsage uint64 `protobuf:"varint,2,opt,name=max_usage,json=maxUsage" json:"max_usage,omitempty"`
574 574
 	Failcnt  uint64 `protobuf:"varint,3,opt,name=failcnt" json:"failcnt,omitempty"`
575 575
 	Limit    uint64 `protobuf:"varint,4,opt,name=limit" json:"limit,omitempty"`
576 576
 }
... ...
@@ -583,8 +590,8 @@ func (*MemoryData) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{
583 583
 type MemoryStats struct {
584 584
 	Cache       uint64            `protobuf:"varint,1,opt,name=cache" json:"cache,omitempty"`
585 585
 	Usage       *MemoryData       `protobuf:"bytes,2,opt,name=usage" json:"usage,omitempty"`
586
-	SwapUsage   *MemoryData       `protobuf:"bytes,3,opt,name=swap_usage" json:"swap_usage,omitempty"`
587
-	KernelUsage *MemoryData       `protobuf:"bytes,4,opt,name=kernel_usage" json:"kernel_usage,omitempty"`
586
+	SwapUsage   *MemoryData       `protobuf:"bytes,3,opt,name=swap_usage,json=swapUsage" json:"swap_usage,omitempty"`
587
+	KernelUsage *MemoryData       `protobuf:"bytes,4,opt,name=kernel_usage,json=kernelUsage" json:"kernel_usage,omitempty"`
588 588
 	Stats       map[string]uint64 `protobuf:"bytes,5,rep,name=stats" json:"stats,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
589 589
 }
590 590
 
... ...
@@ -634,14 +641,14 @@ func (*BlkioStatsEntry) ProtoMessage()               {}
634 634
 func (*BlkioStatsEntry) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{37} }
635 635
 
636 636
 type BlkioStats struct {
637
-	IoServiceBytesRecursive []*BlkioStatsEntry `protobuf:"bytes,1,rep,name=io_service_bytes_recursive" json:"io_service_bytes_recursive,omitempty"`
638
-	IoServicedRecursive     []*BlkioStatsEntry `protobuf:"bytes,2,rep,name=io_serviced_recursive" json:"io_serviced_recursive,omitempty"`
639
-	IoQueuedRecursive       []*BlkioStatsEntry `protobuf:"bytes,3,rep,name=io_queued_recursive" json:"io_queued_recursive,omitempty"`
640
-	IoServiceTimeRecursive  []*BlkioStatsEntry `protobuf:"bytes,4,rep,name=io_service_time_recursive" json:"io_service_time_recursive,omitempty"`
641
-	IoWaitTimeRecursive     []*BlkioStatsEntry `protobuf:"bytes,5,rep,name=io_wait_time_recursive" json:"io_wait_time_recursive,omitempty"`
642
-	IoMergedRecursive       []*BlkioStatsEntry `protobuf:"bytes,6,rep,name=io_merged_recursive" json:"io_merged_recursive,omitempty"`
643
-	IoTimeRecursive         []*BlkioStatsEntry `protobuf:"bytes,7,rep,name=io_time_recursive" json:"io_time_recursive,omitempty"`
644
-	SectorsRecursive        []*BlkioStatsEntry `protobuf:"bytes,8,rep,name=sectors_recursive" json:"sectors_recursive,omitempty"`
637
+	IoServiceBytesRecursive []*BlkioStatsEntry `protobuf:"bytes,1,rep,name=io_service_bytes_recursive,json=ioServiceBytesRecursive" json:"io_service_bytes_recursive,omitempty"`
638
+	IoServicedRecursive     []*BlkioStatsEntry `protobuf:"bytes,2,rep,name=io_serviced_recursive,json=ioServicedRecursive" json:"io_serviced_recursive,omitempty"`
639
+	IoQueuedRecursive       []*BlkioStatsEntry `protobuf:"bytes,3,rep,name=io_queued_recursive,json=ioQueuedRecursive" json:"io_queued_recursive,omitempty"`
640
+	IoServiceTimeRecursive  []*BlkioStatsEntry `protobuf:"bytes,4,rep,name=io_service_time_recursive,json=ioServiceTimeRecursive" json:"io_service_time_recursive,omitempty"`
641
+	IoWaitTimeRecursive     []*BlkioStatsEntry `protobuf:"bytes,5,rep,name=io_wait_time_recursive,json=ioWaitTimeRecursive" json:"io_wait_time_recursive,omitempty"`
642
+	IoMergedRecursive       []*BlkioStatsEntry `protobuf:"bytes,6,rep,name=io_merged_recursive,json=ioMergedRecursive" json:"io_merged_recursive,omitempty"`
643
+	IoTimeRecursive         []*BlkioStatsEntry `protobuf:"bytes,7,rep,name=io_time_recursive,json=ioTimeRecursive" json:"io_time_recursive,omitempty"`
644
+	SectorsRecursive        []*BlkioStatsEntry `protobuf:"bytes,8,rep,name=sectors_recursive,json=sectorsRecursive" json:"sectors_recursive,omitempty"`
645 645
 }
646 646
 
647 647
 func (m *BlkioStats) Reset()                    { *m = BlkioStats{} }
... ...
@@ -707,7 +714,7 @@ func (m *BlkioStats) GetSectorsRecursive() []*BlkioStatsEntry {
707 707
 
708 708
 type HugetlbStats struct {
709 709
 	Usage    uint64 `protobuf:"varint,1,opt,name=usage" json:"usage,omitempty"`
710
-	MaxUsage uint64 `protobuf:"varint,2,opt,name=max_usage" json:"max_usage,omitempty"`
710
+	MaxUsage uint64 `protobuf:"varint,2,opt,name=max_usage,json=maxUsage" json:"max_usage,omitempty"`
711 711
 	Failcnt  uint64 `protobuf:"varint,3,opt,name=failcnt" json:"failcnt,omitempty"`
712 712
 	Limit    uint64 `protobuf:"varint,4,opt,name=limit" json:"limit,omitempty"`
713 713
 }
... ...
@@ -718,11 +725,11 @@ func (*HugetlbStats) ProtoMessage()               {}
718 718
 func (*HugetlbStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{39} }
719 719
 
720 720
 type CgroupStats struct {
721
-	CpuStats     *CpuStats                `protobuf:"bytes,1,opt,name=cpu_stats" json:"cpu_stats,omitempty"`
722
-	MemoryStats  *MemoryStats             `protobuf:"bytes,2,opt,name=memory_stats" json:"memory_stats,omitempty"`
723
-	BlkioStats   *BlkioStats              `protobuf:"bytes,3,opt,name=blkio_stats" json:"blkio_stats,omitempty"`
724
-	HugetlbStats map[string]*HugetlbStats `protobuf:"bytes,4,rep,name=hugetlb_stats" json:"hugetlb_stats,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
725
-	PidsStats    *PidsStats               `protobuf:"bytes,5,opt,name=pids_stats" json:"pids_stats,omitempty"`
721
+	CpuStats     *CpuStats                `protobuf:"bytes,1,opt,name=cpu_stats,json=cpuStats" json:"cpu_stats,omitempty"`
722
+	MemoryStats  *MemoryStats             `protobuf:"bytes,2,opt,name=memory_stats,json=memoryStats" json:"memory_stats,omitempty"`
723
+	BlkioStats   *BlkioStats              `protobuf:"bytes,3,opt,name=blkio_stats,json=blkioStats" json:"blkio_stats,omitempty"`
724
+	HugetlbStats map[string]*HugetlbStats `protobuf:"bytes,4,rep,name=hugetlb_stats,json=hugetlbStats" json:"hugetlb_stats,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
725
+	PidsStats    *PidsStats               `protobuf:"bytes,5,opt,name=pids_stats,json=pidsStats" json:"pids_stats,omitempty"`
726 726
 }
727 727
 
728 728
 func (m *CgroupStats) Reset()                    { *m = CgroupStats{} }
... ...
@@ -766,8 +773,8 @@ func (m *CgroupStats) GetPidsStats() *PidsStats {
766 766
 }
767 767
 
768 768
 type StatsResponse struct {
769
-	NetworkStats []*NetworkStats `protobuf:"bytes,1,rep,name=network_stats" json:"network_stats,omitempty"`
770
-	CgroupStats  *CgroupStats    `protobuf:"bytes,2,opt,name=cgroup_stats" json:"cgroup_stats,omitempty"`
769
+	NetworkStats []*NetworkStats `protobuf:"bytes,1,rep,name=network_stats,json=networkStats" json:"network_stats,omitempty"`
770
+	CgroupStats  *CgroupStats    `protobuf:"bytes,2,opt,name=cgroup_stats,json=cgroupStats" json:"cgroup_stats,omitempty"`
771 771
 	Timestamp    uint64          `protobuf:"varint,3,opt,name=timestamp" json:"timestamp,omitempty"`
772 772
 }
773 773
 
... ...
@@ -849,6 +856,10 @@ func init() {
849 849
 var _ context.Context
850 850
 var _ grpc.ClientConn
851 851
 
852
+// This is a compile-time assertion to ensure that this generated file
853
+// is compatible with the grpc package it is being compiled against.
854
+const _ = grpc.SupportPackageIsVersion2
855
+
852 856
 // Client API for API service
853 857
 
854 858
 type APIClient interface {
... ...
@@ -1026,124 +1037,184 @@ func RegisterAPIServer(s *grpc.Server, srv APIServer) {
1026 1026
 	s.RegisterService(&_API_serviceDesc, srv)
1027 1027
 }
1028 1028
 
1029
-func _API_GetServerVersion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) {
1029
+func _API_GetServerVersion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
1030 1030
 	in := new(GetServerVersionRequest)
1031 1031
 	if err := dec(in); err != nil {
1032 1032
 		return nil, err
1033 1033
 	}
1034
-	out, err := srv.(APIServer).GetServerVersion(ctx, in)
1035
-	if err != nil {
1036
-		return nil, err
1034
+	if interceptor == nil {
1035
+		return srv.(APIServer).GetServerVersion(ctx, in)
1037 1036
 	}
1038
-	return out, nil
1037
+	info := &grpc.UnaryServerInfo{
1038
+		Server:     srv,
1039
+		FullMethod: "/types.API/GetServerVersion",
1040
+	}
1041
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
1042
+		return srv.(APIServer).GetServerVersion(ctx, req.(*GetServerVersionRequest))
1043
+	}
1044
+	return interceptor(ctx, in, info, handler)
1039 1045
 }
1040 1046
 
1041
-func _API_CreateContainer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) {
1047
+func _API_CreateContainer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
1042 1048
 	in := new(CreateContainerRequest)
1043 1049
 	if err := dec(in); err != nil {
1044 1050
 		return nil, err
1045 1051
 	}
1046
-	out, err := srv.(APIServer).CreateContainer(ctx, in)
1047
-	if err != nil {
1048
-		return nil, err
1052
+	if interceptor == nil {
1053
+		return srv.(APIServer).CreateContainer(ctx, in)
1049 1054
 	}
1050
-	return out, nil
1055
+	info := &grpc.UnaryServerInfo{
1056
+		Server:     srv,
1057
+		FullMethod: "/types.API/CreateContainer",
1058
+	}
1059
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
1060
+		return srv.(APIServer).CreateContainer(ctx, req.(*CreateContainerRequest))
1061
+	}
1062
+	return interceptor(ctx, in, info, handler)
1051 1063
 }
1052 1064
 
1053
-func _API_UpdateContainer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) {
1065
+func _API_UpdateContainer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
1054 1066
 	in := new(UpdateContainerRequest)
1055 1067
 	if err := dec(in); err != nil {
1056 1068
 		return nil, err
1057 1069
 	}
1058
-	out, err := srv.(APIServer).UpdateContainer(ctx, in)
1059
-	if err != nil {
1060
-		return nil, err
1070
+	if interceptor == nil {
1071
+		return srv.(APIServer).UpdateContainer(ctx, in)
1061 1072
 	}
1062
-	return out, nil
1073
+	info := &grpc.UnaryServerInfo{
1074
+		Server:     srv,
1075
+		FullMethod: "/types.API/UpdateContainer",
1076
+	}
1077
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
1078
+		return srv.(APIServer).UpdateContainer(ctx, req.(*UpdateContainerRequest))
1079
+	}
1080
+	return interceptor(ctx, in, info, handler)
1063 1081
 }
1064 1082
 
1065
-func _API_Signal_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) {
1083
+func _API_Signal_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
1066 1084
 	in := new(SignalRequest)
1067 1085
 	if err := dec(in); err != nil {
1068 1086
 		return nil, err
1069 1087
 	}
1070
-	out, err := srv.(APIServer).Signal(ctx, in)
1071
-	if err != nil {
1072
-		return nil, err
1088
+	if interceptor == nil {
1089
+		return srv.(APIServer).Signal(ctx, in)
1073 1090
 	}
1074
-	return out, nil
1091
+	info := &grpc.UnaryServerInfo{
1092
+		Server:     srv,
1093
+		FullMethod: "/types.API/Signal",
1094
+	}
1095
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
1096
+		return srv.(APIServer).Signal(ctx, req.(*SignalRequest))
1097
+	}
1098
+	return interceptor(ctx, in, info, handler)
1075 1099
 }
1076 1100
 
1077
-func _API_UpdateProcess_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) {
1101
+func _API_UpdateProcess_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
1078 1102
 	in := new(UpdateProcessRequest)
1079 1103
 	if err := dec(in); err != nil {
1080 1104
 		return nil, err
1081 1105
 	}
1082
-	out, err := srv.(APIServer).UpdateProcess(ctx, in)
1083
-	if err != nil {
1084
-		return nil, err
1106
+	if interceptor == nil {
1107
+		return srv.(APIServer).UpdateProcess(ctx, in)
1085 1108
 	}
1086
-	return out, nil
1109
+	info := &grpc.UnaryServerInfo{
1110
+		Server:     srv,
1111
+		FullMethod: "/types.API/UpdateProcess",
1112
+	}
1113
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
1114
+		return srv.(APIServer).UpdateProcess(ctx, req.(*UpdateProcessRequest))
1115
+	}
1116
+	return interceptor(ctx, in, info, handler)
1087 1117
 }
1088 1118
 
1089
-func _API_AddProcess_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) {
1119
+func _API_AddProcess_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
1090 1120
 	in := new(AddProcessRequest)
1091 1121
 	if err := dec(in); err != nil {
1092 1122
 		return nil, err
1093 1123
 	}
1094
-	out, err := srv.(APIServer).AddProcess(ctx, in)
1095
-	if err != nil {
1096
-		return nil, err
1124
+	if interceptor == nil {
1125
+		return srv.(APIServer).AddProcess(ctx, in)
1097 1126
 	}
1098
-	return out, nil
1127
+	info := &grpc.UnaryServerInfo{
1128
+		Server:     srv,
1129
+		FullMethod: "/types.API/AddProcess",
1130
+	}
1131
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
1132
+		return srv.(APIServer).AddProcess(ctx, req.(*AddProcessRequest))
1133
+	}
1134
+	return interceptor(ctx, in, info, handler)
1099 1135
 }
1100 1136
 
1101
-func _API_CreateCheckpoint_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) {
1137
+func _API_CreateCheckpoint_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
1102 1138
 	in := new(CreateCheckpointRequest)
1103 1139
 	if err := dec(in); err != nil {
1104 1140
 		return nil, err
1105 1141
 	}
1106
-	out, err := srv.(APIServer).CreateCheckpoint(ctx, in)
1107
-	if err != nil {
1108
-		return nil, err
1142
+	if interceptor == nil {
1143
+		return srv.(APIServer).CreateCheckpoint(ctx, in)
1109 1144
 	}
1110
-	return out, nil
1145
+	info := &grpc.UnaryServerInfo{
1146
+		Server:     srv,
1147
+		FullMethod: "/types.API/CreateCheckpoint",
1148
+	}
1149
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
1150
+		return srv.(APIServer).CreateCheckpoint(ctx, req.(*CreateCheckpointRequest))
1151
+	}
1152
+	return interceptor(ctx, in, info, handler)
1111 1153
 }
1112 1154
 
1113
-func _API_DeleteCheckpoint_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) {
1155
+func _API_DeleteCheckpoint_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
1114 1156
 	in := new(DeleteCheckpointRequest)
1115 1157
 	if err := dec(in); err != nil {
1116 1158
 		return nil, err
1117 1159
 	}
1118
-	out, err := srv.(APIServer).DeleteCheckpoint(ctx, in)
1119
-	if err != nil {
1120
-		return nil, err
1160
+	if interceptor == nil {
1161
+		return srv.(APIServer).DeleteCheckpoint(ctx, in)
1121 1162
 	}
1122
-	return out, nil
1163
+	info := &grpc.UnaryServerInfo{
1164
+		Server:     srv,
1165
+		FullMethod: "/types.API/DeleteCheckpoint",
1166
+	}
1167
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
1168
+		return srv.(APIServer).DeleteCheckpoint(ctx, req.(*DeleteCheckpointRequest))
1169
+	}
1170
+	return interceptor(ctx, in, info, handler)
1123 1171
 }
1124 1172
 
1125
-func _API_ListCheckpoint_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) {
1173
+func _API_ListCheckpoint_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
1126 1174
 	in := new(ListCheckpointRequest)
1127 1175
 	if err := dec(in); err != nil {
1128 1176
 		return nil, err
1129 1177
 	}
1130
-	out, err := srv.(APIServer).ListCheckpoint(ctx, in)
1131
-	if err != nil {
1132
-		return nil, err
1178
+	if interceptor == nil {
1179
+		return srv.(APIServer).ListCheckpoint(ctx, in)
1133 1180
 	}
1134
-	return out, nil
1181
+	info := &grpc.UnaryServerInfo{
1182
+		Server:     srv,
1183
+		FullMethod: "/types.API/ListCheckpoint",
1184
+	}
1185
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
1186
+		return srv.(APIServer).ListCheckpoint(ctx, req.(*ListCheckpointRequest))
1187
+	}
1188
+	return interceptor(ctx, in, info, handler)
1135 1189
 }
1136 1190
 
1137
-func _API_State_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) {
1191
+func _API_State_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
1138 1192
 	in := new(StateRequest)
1139 1193
 	if err := dec(in); err != nil {
1140 1194
 		return nil, err
1141 1195
 	}
1142
-	out, err := srv.(APIServer).State(ctx, in)
1143
-	if err != nil {
1144
-		return nil, err
1196
+	if interceptor == nil {
1197
+		return srv.(APIServer).State(ctx, in)
1145 1198
 	}
1146
-	return out, nil
1199
+	info := &grpc.UnaryServerInfo{
1200
+		Server:     srv,
1201
+		FullMethod: "/types.API/State",
1202
+	}
1203
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
1204
+		return srv.(APIServer).State(ctx, req.(*StateRequest))
1205
+	}
1206
+	return interceptor(ctx, in, info, handler)
1147 1207
 }
1148 1208
 
1149 1209
 func _API_Events_Handler(srv interface{}, stream grpc.ServerStream) error {
... ...
@@ -1167,16 +1238,22 @@ func (x *aPIEventsServer) Send(m *Event) error {
1167 1167
 	return x.ServerStream.SendMsg(m)
1168 1168
 }
1169 1169
 
1170
-func _API_Stats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) {
1170
+func _API_Stats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
1171 1171
 	in := new(StatsRequest)
1172 1172
 	if err := dec(in); err != nil {
1173 1173
 		return nil, err
1174 1174
 	}
1175
-	out, err := srv.(APIServer).Stats(ctx, in)
1176
-	if err != nil {
1177
-		return nil, err
1175
+	if interceptor == nil {
1176
+		return srv.(APIServer).Stats(ctx, in)
1178 1177
 	}
1179
-	return out, nil
1178
+	info := &grpc.UnaryServerInfo{
1179
+		Server:     srv,
1180
+		FullMethod: "/types.API/Stats",
1181
+	}
1182
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
1183
+		return srv.(APIServer).Stats(ctx, req.(*StatsRequest))
1184
+	}
1185
+	return interceptor(ctx, in, info, handler)
1180 1186
 }
1181 1187
 
1182 1188
 var _API_serviceDesc = grpc.ServiceDesc{
... ...
@@ -1238,148 +1315,152 @@ var _API_serviceDesc = grpc.ServiceDesc{
1238 1238
 }
1239 1239
 
1240 1240
 var fileDescriptor0 = []byte{
1241
-	// 2285 bytes of a gzipped FileDescriptorProto
1242
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xec, 0x19, 0xcb, 0x72, 0x1c, 0x49,
1243
-	0xd1, 0xf3, 0x94, 0x26, 0xe7, 0x21, 0xa9, 0xfd, 0xd0, 0x78, 0x76, 0xed, 0x35, 0x1d, 0xc0, 0x1a,
1244
-	0x58, 0x84, 0x91, 0x77, 0x03, 0x07, 0x04, 0x44, 0xac, 0x65, 0xb3, 0x98, 0xb5, 0x16, 0xb9, 0x25,
1245
-	0xb1, 0x17, 0x22, 0x26, 0x5a, 0x33, 0xe5, 0x99, 0x46, 0x33, 0xdd, 0xbd, 0xdd, 0x35, 0xd2, 0xe8,
1246
-	0xc2, 0x11, 0x6e, 0xfc, 0x00, 0x11, 0x5c, 0xb8, 0x71, 0xe7, 0xc0, 0x17, 0xf0, 0x27, 0xc4, 0x5e,
1247
-	0xb8, 0x73, 0x24, 0xab, 0x32, 0xbb, 0xba, 0x7a, 0x1e, 0xd2, 0x72, 0x20, 0xb8, 0xec, 0x65, 0xa2,
1248
-	0x32, 0x2b, 0x2b, 0x33, 0x2b, 0xdf, 0x5d, 0x03, 0x0d, 0x3f, 0x0e, 0xf6, 0xe2, 0x24, 0x92, 0x91,
1249
-	0x53, 0x93, 0x57, 0xb1, 0x48, 0xdd, 0xfb, 0xb0, 0xfb, 0x89, 0x90, 0xc7, 0x22, 0xb9, 0x10, 0xc9,
1250
-	0xaf, 0x45, 0x92, 0x06, 0x51, 0xe8, 0x89, 0x2f, 0x66, 0x22, 0x95, 0xee, 0x1c, 0xba, 0xcb, 0x5b,
1251
-	0x69, 0x1c, 0x85, 0xa9, 0x70, 0xee, 0x40, 0x6d, 0xea, 0xff, 0x36, 0x4a, 0xba, 0xa5, 0x47, 0xa5,
1252
-	0xc7, 0x6d, 0x8f, 0x00, 0x8d, 0x0d, 0x42, 0xc4, 0x96, 0x19, 0xab, 0x00, 0x85, 0x8d, 0x7d, 0x39,
1253
-	0x18, 0x77, 0x2b, 0x84, 0xd5, 0x80, 0xd3, 0x83, 0xcd, 0x44, 0x5c, 0x04, 0x8a, 0x6b, 0xb7, 0x8a,
1254
-	0x1b, 0x0d, 0xcf, 0xc0, 0xee, 0xef, 0x4b, 0x70, 0xe7, 0x34, 0x1e, 0xfa, 0x52, 0x1c, 0x25, 0xd1,
1255
-	0x40, 0xa4, 0x29, 0xab, 0xe4, 0x74, 0xa0, 0x1c, 0x0c, 0xb5, 0xcc, 0x86, 0x87, 0x2b, 0x67, 0x1b,
1256
-	0x2a, 0x31, 0x22, 0xca, 0x1a, 0xa1, 0x96, 0xce, 0x43, 0x80, 0xc1, 0x24, 0x4a, 0xc5, 0xb1, 0x1c,
1257
-	0x06, 0xa1, 0x96, 0xb8, 0xe9, 0x59, 0x18, 0xa5, 0xcc, 0x65, 0x30, 0x94, 0x63, 0x2d, 0x13, 0x95,
1258
-	0xd1, 0x80, 0x73, 0x0f, 0xea, 0x63, 0x11, 0x8c, 0xc6, 0xb2, 0x5b, 0xd3, 0x68, 0x86, 0xdc, 0x5d,
1259
-	0xb8, 0xbb, 0xa0, 0x07, 0xdd, 0xdf, 0xfd, 0xb2, 0x04, 0xf7, 0x0e, 0x12, 0x81, 0x3b, 0x07, 0x51,
1260
-	0x28, 0xfd, 0x20, 0x14, 0xc9, 0x3a, 0x1d, 0x51, 0xa3, 0xb3, 0x59, 0x38, 0x9c, 0x88, 0x23, 0x1f,
1261
-	0xc5, 0x92, 0xaa, 0x16, 0x46, 0x6b, 0x3c, 0x16, 0x83, 0xf3, 0x38, 0x0a, 0x42, 0xa9, 0x35, 0xc6,
1262
-	0xfd, 0x1c, 0xa3, 0x34, 0x4e, 0xf5, 0x65, 0xc8, 0x4a, 0x04, 0x28, 0x8d, 0x71, 0x11, 0xcd, 0x48,
1263
-	0xe3, 0x86, 0xc7, 0x10, 0xe3, 0x45, 0x92, 0x74, 0xeb, 0x06, 0x8f, 0x90, 0xc2, 0x4f, 0xfc, 0x33,
1264
-	0x31, 0x49, 0xbb, 0x1b, 0x8f, 0x2a, 0x0a, 0x4f, 0x90, 0xf3, 0x08, 0x9a, 0x61, 0x74, 0x14, 0x5c,
1265
-	0x44, 0xd2, 0x8b, 0x22, 0xd9, 0xdd, 0xd4, 0x06, 0xb3, 0x51, 0xee, 0x2b, 0xd8, 0x5d, 0xba, 0x29,
1266
-	0x47, 0xc1, 0x1e, 0x34, 0x06, 0x19, 0x52, 0xdf, 0xb8, 0xb9, 0xbf, 0xbd, 0xa7, 0xe3, 0x6a, 0x2f,
1267
-	0x27, 0xce, 0x49, 0x90, 0x55, 0xfb, 0x38, 0x18, 0x85, 0xfe, 0xe4, 0xab, 0xfb, 0x53, 0xdd, 0x47,
1268
-	0x1f, 0xe1, 0xe8, 0x61, 0xc8, 0xdd, 0x86, 0x4e, 0xc6, 0x8a, 0x5d, 0xf2, 0xb7, 0x0a, 0xec, 0x7c,
1269
-	0x3c, 0x1c, 0xde, 0x10, 0x31, 0x18, 0x76, 0x52, 0x24, 0x18, 0x98, 0xc8, 0xb1, 0xac, 0x2f, 0x6b,
1270
-	0x60, 0xe7, 0x3d, 0xa8, 0xce, 0x52, 0xbc, 0x49, 0x45, 0xdf, 0xa4, 0xc9, 0x37, 0x39, 0x45, 0x94,
1271
-	0xa7, 0x37, 0x1c, 0x07, 0xaa, 0x7e, 0x32, 0x4a, 0xd1, 0x13, 0xca, 0x84, 0x7a, 0xad, 0x54, 0x16,
1272
-	0xe1, 0x05, 0x7a, 0x41, 0xa1, 0xd4, 0x52, 0x61, 0x06, 0x97, 0x43, 0xb6, 0xbf, 0x5a, 0x66, 0xd7,
1273
-	0xda, 0xc8, 0xaf, 0x65, 0x9c, 0xba, 0xb9, 0xda, 0xa9, 0x8d, 0x35, 0x4e, 0x85, 0x82, 0x53, 0x5d,
1274
-	0x68, 0x0d, 0xfc, 0xd8, 0x3f, 0x0b, 0x26, 0x81, 0x0c, 0x44, 0xda, 0x6d, 0x6a, 0x25, 0x0a, 0x38,
1275
-	0xe7, 0x31, 0x6c, 0xf9, 0x71, 0xec, 0x27, 0xd3, 0x28, 0x41, 0xd3, 0xbc, 0x0d, 0x26, 0xa2, 0xdb,
1276
-	0xd2, 0x4c, 0x16, 0xd1, 0x8a, 0x5b, 0x2a, 0x26, 0x41, 0x38, 0x9b, 0xbf, 0x56, 0xb1, 0xd1, 0x6d,
1277
-	0x6b, 0xb2, 0x02, 0x4e, 0x71, 0x0b, 0xa3, 0xcf, 0xc4, 0xe5, 0x51, 0x12, 0x5c, 0xe0, 0x99, 0x11,
1278
-	0x0a, 0xed, 0x68, 0x2b, 0x2e, 0xa2, 0x9d, 0xf7, 0x61, 0x23, 0x99, 0x04, 0xd3, 0x40, 0xa6, 0xdd,
1279
-	0x2d, 0x54, 0xab, 0xb9, 0xdf, 0x66, 0x7b, 0x7a, 0x1a, 0xeb, 0x65, 0xbb, 0xee, 0x0b, 0xa8, 0x13,
1280
-	0x4a, 0x99, 0x57, 0x91, 0xb0, 0xb7, 0xf4, 0x5a, 0xe1, 0xd2, 0xe8, 0xad, 0xd4, 0xbe, 0xaa, 0x7a,
1281
-	0x7a, 0xad, 0x70, 0x63, 0x3f, 0x19, 0x6a, 0x3f, 0x21, 0x4e, 0xad, 0x5d, 0x0f, 0xaa, 0xca, 0x51,
1282
-	0xca, 0xd4, 0x33, 0x76, 0x78, 0xdb, 0x53, 0x4b, 0x85, 0x19, 0x71, 0x4c, 0x21, 0x06, 0x97, 0xce,
1283
-	0xb7, 0xa1, 0xe3, 0x0f, 0x87, 0x68, 0x9e, 0x08, 0xbd, 0xfe, 0x49, 0x30, 0x4c, 0x91, 0x53, 0x05,
1284
-	0x37, 0x17, 0xb0, 0xee, 0x1d, 0x70, 0xec, 0x80, 0xe2, 0x38, 0xfb, 0x8d, 0xc9, 0x07, 0x93, 0xa3,
1285
-	0xeb, 0x82, 0xed, 0x87, 0x85, 0xd4, 0x2e, 0xeb, 0xb0, 0xda, 0xc9, 0x12, 0x24, 0x3f, 0x6d, 0x11,
1286
-	0xb9, 0x3d, 0xe8, 0x2e, 0x73, 0x67, 0xc9, 0x3f, 0x85, 0xdd, 0x17, 0x62, 0x22, 0xbe, 0x8a, 0x64,
1287
-	0x34, 0x51, 0xe8, 0x4f, 0x05, 0x67, 0x92, 0x5e, 0x2b, 0xd6, 0xcb, 0xc7, 0x99, 0xf5, 0xfb, 0x70,
1288
-	0xf7, 0x75, 0x90, 0xca, 0x1b, 0x19, 0xbb, 0xbf, 0x03, 0xc8, 0x89, 0x8c, 0x98, 0x52, 0x2e, 0x46,
1289
-	0xe1, 0xc4, 0x3c, 0x90, 0x9c, 0x5d, 0x7a, 0xad, 0x7c, 0x20, 0x07, 0x31, 0x97, 0x63, 0xb5, 0x54,
1290
-	0x75, 0x67, 0x16, 0x06, 0xf3, 0xe3, 0x68, 0x70, 0x2e, 0x64, 0xaa, 0x6b, 0x1b, 0xd6, 0x1d, 0x0b,
1291
-	0xa5, 0x53, 0x64, 0x2c, 0x26, 0x13, 0x5d, 0xe0, 0x36, 0x3d, 0x02, 0xdc, 0x43, 0xb8, 0xb7, 0xa8,
1292
-	0x28, 0x17, 0xa3, 0xa7, 0xd0, 0xcc, 0xed, 0x98, 0xa2, 0x4a, 0x95, 0xd5, 0xd6, 0xb6, 0xa9, 0xdc,
1293
-	0x87, 0xd0, 0x3a, 0x96, 0x68, 0xed, 0x75, 0xd7, 0x7d, 0x0c, 0x1d, 0x53, 0xc9, 0x34, 0x21, 0xe5,
1294
-	0xa2, 0x2f, 0x67, 0x29, 0x53, 0x31, 0xe4, 0xfe, 0xbd, 0x02, 0x1b, 0x1c, 0x2a, 0x59, 0xbe, 0x97,
1295
-	0xf2, 0x7c, 0xff, 0xbf, 0x94, 0x9d, 0x77, 0xa1, 0x91, 0x5e, 0xa5, 0x52, 0x4c, 0x8f, 0xb8, 0xf8,
1296
-	0xb4, 0xbd, 0x1c, 0xf1, 0x75, 0x09, 0xca, 0x4b, 0xd0, 0x3f, 0x4a, 0xd0, 0x30, 0x6e, 0xfe, 0xaf,
1297
-	0x1b, 0xf8, 0x07, 0xd0, 0x88, 0xc9, 0xf1, 0x82, 0x2a, 0x49, 0x73, 0xbf, 0xc3, 0x82, 0xb2, 0xda,
1298
-	0x91, 0x13, 0x58, 0xf1, 0x53, 0xb5, 0xe3, 0xc7, 0x6a, 0xd0, 0xb5, 0x42, 0x83, 0x46, 0xe7, 0xc7,
1299
-	0xaa, 0x44, 0xd5, 0x75, 0x89, 0xd2, 0x6b, 0xa7, 0x8b, 0x17, 0x9b, 0x85, 0x32, 0xc0, 0xcc, 0xa3,
1300
-	0x9e, 0x92, 0x81, 0xee, 0x47, 0xb0, 0x71, 0xe8, 0x0f, 0xc6, 0x78, 0x0f, 0x75, 0x70, 0x10, 0x73,
1301
-	0x98, 0xe2, 0x41, 0xb5, 0x56, 0x42, 0xa6, 0x02, 0xed, 0x7d, 0xc5, 0xf5, 0x94, 0x21, 0xf7, 0x1c,
1302
-	0x1b, 0x33, 0xa5, 0x01, 0x27, 0xd3, 0x13, 0xac, 0x5c, 0x99, 0x41, 0xb2, 0x5c, 0x5a, 0x6e, 0xed,
1303
-	0x16, 0x0d, 0xba, 0x65, 0x63, 0x4a, 0x92, 0xb9, 0xd0, 0x65, 0x36, 0x60, 0x7d, 0xbc, 0x6c, 0xdb,
1304
-	0xfd, 0x03, 0xce, 0x4e, 0x34, 0x55, 0xdd, 0x38, 0x3b, 0xad, 0x9e, 0x07, 0xc8, 0x7c, 0x95, 0x82,
1305
-	0xf9, 0x9e, 0x42, 0x23, 0x11, 0x69, 0x34, 0x4b, 0xd0, 0xcc, 0xda, 0xb2, 0xcd, 0xfd, 0xbb, 0x59,
1306
-	0x26, 0x69, 0x59, 0x1e, 0xef, 0x7a, 0x39, 0x9d, 0xfb, 0x65, 0x19, 0x3a, 0xc5, 0x5d, 0x55, 0x97,
1307
-	0xce, 0x26, 0xe7, 0x41, 0xf4, 0x39, 0x8d, 0x83, 0x64, 0x3c, 0x1b, 0xa5, 0xb2, 0x0a, 0x6d, 0x79,
1308
-	0x8c, 0x5d, 0x07, 0x25, 0x51, 0x57, 0xc9, 0x11, 0xbc, 0x7b, 0x24, 0x92, 0x20, 0x1a, 0xf2, 0xc8,
1309
-	0x92, 0x23, 0x54, 0x19, 0x40, 0xe0, 0xcd, 0x2c, 0x92, 0x3e, 0x0f, 0xa0, 0x06, 0xd6, 0x73, 0x20,
1310
-	0xfa, 0x48, 0xc8, 0x03, 0xe5, 0xb5, 0x1a, 0xcf, 0x81, 0x06, 0x93, 0xef, 0x1f, 0x8a, 0x69, 0xca,
1311
-	0x69, 0x6e, 0x61, 0x94, 0xe6, 0xe4, 0xcd, 0xd7, 0x2a, 0xa8, 0x39, 0xdf, 0x6d, 0x94, 0xe2, 0x40,
1312
-	0xe0, 0xf1, 0xa5, 0x1f, 0xeb, 0xb4, 0x6f, 0x7b, 0x16, 0x06, 0x03, 0x79, 0x87, 0x20, 0xb4, 0x06,
1313
-	0x4e, 0xfd, 0xbe, 0x6a, 0x85, 0xba, 0x0c, 0xb4, 0xbd, 0xe5, 0x0d, 0x45, 0x7d, 0x2e, 0x92, 0x50,
1314
-	0x4c, 0x0e, 0x2d, 0xa9, 0x40, 0xd4, 0x4b, 0x1b, 0xea, 0x3b, 0x63, 0xc9, 0xe7, 0xdc, 0x7b, 0xbe,
1315
-	0x0f, 0xed, 0x97, 0x17, 0x02, 0xab, 0x71, 0x16, 0x05, 0x68, 0x43, 0x15, 0xcc, 0xe8, 0xd9, 0x69,
1316
-	0xac, 0x3d, 0x50, 0xf5, 0x72, 0x84, 0x9b, 0x42, 0x4d, 0x93, 0xaf, 0x1c, 0x17, 0x28, 0x80, 0xca,
1317
-	0x26, 0x80, 0x8a, 0xe1, 0xd2, 0x36, 0xe1, 0xc2, 0x81, 0x55, 0xcd, 0x03, 0xab, 0x20, 0xb4, 0xb6,
1318
-	0x28, 0xf4, 0x8f, 0x65, 0x68, 0x7d, 0x26, 0xe4, 0x65, 0x94, 0x9c, 0xab, 0x44, 0x49, 0x57, 0x76,
1319
-	0xbe, 0xfb, 0xf8, 0x49, 0x33, 0xef, 0x9f, 0x5d, 0x49, 0x0e, 0x8c, 0x2a, 0xe6, 0xe5, 0xfc, 0xb9,
1320
-	0x02, 0x9d, 0x07, 0x00, 0xb8, 0x75, 0xe4, 0x53, 0xb7, 0xa3, 0xc1, 0xa5, 0x91, 0xcc, 0x19, 0xe1,
1321
-	0xbc, 0x03, 0x0d, 0x6f, 0xde, 0xc7, 0x7a, 0x1a, 0x25, 0x14, 0xbd, 0x55, 0xfc, 0x1a, 0x9a, 0xbf,
1322
-	0xd4, 0xb0, 0x3a, 0x8b, 0x9b, 0xc3, 0x24, 0x8a, 0x63, 0x31, 0xcc, 0x54, 0x4b, 0xe6, 0x2f, 0x08,
1323
-	0xa1, 0xa4, 0x9e, 0x64, 0x52, 0xeb, 0x24, 0x55, 0xe6, 0x52, 0x71, 0x2b, 0x66, 0xa9, 0x1b, 0x7c,
1324
-	0x29, 0x5b, 0xea, 0x89, 0x91, 0xba, 0x49, 0x52, 0xa5, 0x25, 0xf5, 0x24, 0x97, 0xda, 0xc8, 0xce,
1325
-	0xb2, 0x54, 0xf7, 0xaf, 0x25, 0xd8, 0xc4, 0xb0, 0x3c, 0x4d, 0xfd, 0x91, 0xc0, 0x0e, 0xd6, 0x94,
1326
-	0x18, 0xc2, 0x93, 0xfe, 0x4c, 0x81, 0xec, 0x32, 0xd0, 0x28, 0x22, 0xf8, 0x06, 0xb4, 0x62, 0x91,
1327
-	0x60, 0xb0, 0x32, 0x45, 0x19, 0x0b, 0x4a, 0xd5, 0x6b, 0x12, 0x8e, 0x48, 0xf6, 0xe0, 0xb6, 0xde,
1328
-	0xeb, 0x07, 0x61, 0x9f, 0xc2, 0x67, 0x1a, 0x0d, 0x05, 0x9b, 0x6a, 0x47, 0x6f, 0xbd, 0x0a, 0x3f,
1329
-	0x35, 0x1b, 0xce, 0x77, 0x61, 0xc7, 0xd0, 0xab, 0x2e, 0xa9, 0xa9, 0xc9, 0x74, 0x5b, 0x4c, 0x7d,
1330
-	0xca, 0x68, 0x1c, 0x5a, 0x3a, 0x27, 0x63, 0xfc, 0xea, 0x95, 0xd8, 0x46, 0x46, 0x2f, 0x7c, 0x4c,
1331
-	0x36, 0xac, 0xa0, 0xb1, 0x4e, 0xc9, 0x94, 0xb5, 0xcd, 0x40, 0xe7, 0x7b, 0xb0, 0x23, 0x89, 0x56,
1332
-	0x0c, 0xfb, 0x19, 0x0d, 0x79, 0x73, 0xdb, 0x6c, 0x1c, 0x31, 0xf1, 0xb7, 0xa0, 0x93, 0x13, 0xeb,
1333
-	0x7a, 0x4c, 0xfa, 0xb6, 0x0d, 0xf6, 0x44, 0x55, 0xe5, 0x3f, 0x91, 0xb1, 0x28, 0x72, 0x3e, 0xd0,
1334
-	0x15, 0xc2, 0x32, 0x55, 0x73, 0x7f, 0x2b, 0xab, 0xac, 0x6c, 0x0c, 0x5d, 0x15, 0xc8, 0x2c, 0x3f,
1335
-	0x83, 0x2d, 0x69, 0x54, 0xef, 0x63, 0x02, 0xf9, 0x5c, 0x5e, 0xb3, 0xea, 0x56, 0xbc, 0x98, 0xd7,
1336
-	0x91, 0xc5, 0x8b, 0xa2, 0xe5, 0xa9, 0xe5, 0xb3, 0x40, 0xd2, 0xaf, 0x49, 0x38, 0x2d, 0xc2, 0xfd,
1337
-	0x09, 0x34, 0x70, 0x1e, 0x48, 0x49, 0x3b, 0x34, 0xcc, 0x60, 0x96, 0x24, 0x98, 0x5f, 0x99, 0x61,
1338
-	0x18, 0x54, 0xf3, 0x82, 0x6e, 0x97, 0x6c, 0x0c, 0x02, 0xdc, 0x08, 0x80, 0xd2, 0x5c, 0x4b, 0x43,
1339
-	0x1a, 0x3b, 0x04, 0x08, 0x50, 0x71, 0x36, 0xf5, 0xe7, 0xc6, 0xf5, 0x3a, 0xce, 0x10, 0x41, 0x17,
1340
-	0x44, 0x81, 0x6f, 0xfd, 0x60, 0x32, 0xe0, 0x6f, 0x5f, 0x14, 0xc8, 0x60, 0x2e, 0xb0, 0x6a, 0x0b,
1341
-	0xfc, 0x4b, 0x19, 0x9a, 0x24, 0x91, 0x14, 0x46, 0xaa, 0x01, 0x36, 0x16, 0x23, 0x52, 0x03, 0xd8,
1342
-	0xfa, 0x6b, 0xb9, 0xb8, 0x7c, 0x0c, 0xcc, 0x55, 0xcd, 0x74, 0xc3, 0x46, 0x97, 0x62, 0xed, 0xb3,
1343
-	0xac, 0xb3, 0x92, 0xba, 0xa1, 0x88, 0x48, 0xe1, 0x0f, 0xa1, 0x45, 0xf1, 0xc9, 0x67, 0xaa, 0xeb,
1344
-	0xce, 0x34, 0x89, 0x8c, 0x4e, 0x3d, 0x55, 0xd3, 0x16, 0xea, 0xab, 0xbb, 0x7b, 0x73, 0xff, 0x41,
1345
-	0x81, 0x5c, 0xdf, 0x64, 0x4f, 0xff, 0xbe, 0x0c, 0x25, 0x96, 0x59, 0xa2, 0xed, 0x3d, 0x03, 0xc8,
1346
-	0x91, 0xaa, 0x66, 0x9d, 0x8b, 0xab, 0x6c, 0xaa, 0xc4, 0xa5, 0xba, 0xfb, 0x85, 0x3f, 0x99, 0x65,
1347
-	0x46, 0x25, 0xe0, 0xc7, 0xe5, 0x67, 0x25, 0x77, 0x00, 0x5b, 0xcf, 0x55, 0xcf, 0xb2, 0x8e, 0x17,
1348
-	0x9e, 0x6c, 0xaa, 0x2b, 0x9f, 0x6c, 0xaa, 0xd9, 0x93, 0x0d, 0x96, 0xd1, 0x28, 0xe6, 0x0e, 0x8b,
1349
-	0xab, 0x5c, 0x50, 0xd5, 0x12, 0xe4, 0xfe, 0xb3, 0x0a, 0x90, 0x4b, 0x71, 0x8e, 0xa1, 0x17, 0x44,
1350
-	0x7d, 0xd5, 0x20, 0x82, 0x81, 0xa0, 0x82, 0xd4, 0x4f, 0x04, 0x86, 0x4f, 0x1a, 0x5c, 0x08, 0x9e,
1351
-	0x21, 0xee, 0xf1, 0xbd, 0x17, 0x94, 0xf3, 0x76, 0x11, 0xa2, 0x83, 0xba, 0x72, 0x79, 0xd9, 0x31,
1352
-	0xe7, 0x97, 0x70, 0x37, 0x67, 0x3a, 0xb4, 0xf8, 0x95, 0xaf, 0xe5, 0x77, 0xdb, 0xf0, 0x1b, 0xe6,
1353
-	0xbc, 0x7e, 0x0e, 0x88, 0xee, 0x63, 0x8f, 0x99, 0x15, 0x38, 0x55, 0xae, 0xe5, 0xb4, 0x13, 0x44,
1354
-	0x6f, 0xf4, 0x89, 0x9c, 0xcf, 0x1b, 0xb8, 0x6f, 0x5d, 0x54, 0xa5, 0xbd, 0xc5, 0xad, 0x7a, 0x2d,
1355
-	0xb7, 0x7b, 0x46, 0x2f, 0x55, 0x18, 0x72, 0x96, 0x9f, 0x02, 0xee, 0xf4, 0x2f, 0xfd, 0x40, 0x2e,
1356
-	0xf2, 0xab, 0xdd, 0x74, 0xcf, 0xcf, 0xf1, 0x50, 0x91, 0x19, 0xdd, 0x73, 0x2a, 0x92, 0x51, 0xe1,
1357
-	0x9e, 0xf5, 0x9b, 0xee, 0x79, 0xa8, 0x4f, 0xe4, 0x7c, 0x9e, 0x03, 0x22, 0x17, 0xf5, 0xd9, 0xb8,
1358
-	0x96, 0xcb, 0x56, 0x10, 0x15, 0x75, 0x39, 0x80, 0x9d, 0x54, 0x0c, 0x24, 0x76, 0x14, 0x8b, 0xc7,
1359
-	0xe6, 0xb5, 0x3c, 0xb6, 0xf9, 0x80, 0x61, 0xe2, 0x7e, 0x01, 0xad, 0x5f, 0xcc, 0x46, 0x42, 0x4e,
1360
-	0xce, 0x4c, 0xce, 0xff, 0xaf, 0xcb, 0xcc, 0xbf, 0xb1, 0xcc, 0x1c, 0x8c, 0x92, 0x68, 0x16, 0x17,
1361
-	0xaa, 0x36, 0xe5, 0xf0, 0x52, 0xd5, 0xd6, 0x34, 0xba, 0x6a, 0x13, 0xf5, 0x47, 0xd0, 0xa2, 0x81,
1362
-	0x89, 0x0f, 0x50, 0x15, 0x72, 0x96, 0x93, 0x3e, 0x1b, 0xd0, 0xe8, 0xd8, 0x3e, 0x0f, 0x9f, 0x7c,
1363
-	0xaa, 0x58, 0x8d, 0x72, 0x33, 0xe1, 0xd7, 0x47, 0x9e, 0x75, 0xaf, 0xa0, 0x3d, 0x26, 0xdb, 0xf0,
1364
-	0x29, 0x0a, 0xc0, 0x6f, 0x66, 0xca, 0xe5, 0x77, 0xd8, 0xb3, 0x6d, 0x48, 0xa6, 0x6e, 0x8d, 0x6d,
1365
-	0xb3, 0xfe, 0x00, 0x40, 0x7d, 0x5e, 0xf4, 0xb3, 0x42, 0x65, 0xbf, 0xe7, 0x99, 0x0e, 0x81, 0xdf,
1366
-	0x32, 0xd9, 0xb2, 0x77, 0x02, 0x3b, 0x4b, 0x3c, 0x57, 0x94, 0xa9, 0xef, 0xd8, 0x65, 0xaa, 0xb9,
1367
-	0x7f, 0x9b, 0x59, 0xda, 0x47, 0xed, 0xda, 0xf5, 0xe7, 0x12, 0x7d, 0x8d, 0x98, 0x27, 0x17, 0xe7,
1368
-	0x19, 0xb4, 0x43, 0x1a, 0xbe, 0x8c, 0x03, 0x2a, 0x16, 0x23, 0x7b, 0x30, 0xf3, 0x5a, 0xa1, 0x3d,
1369
-	0xa6, 0xa1, 0x23, 0x06, 0xda, 0x02, 0x2b, 0x1d, 0x61, 0x19, 0xc7, 0x6b, 0x0e, 0x2c, 0x6f, 0x17,
1370
-	0x86, 0xc1, 0xca, 0xe2, 0x30, 0xc8, 0x8f, 0x06, 0xeb, 0xde, 0x18, 0xf7, 0xff, 0x55, 0x87, 0xca,
1371
-	0xc7, 0x47, 0xaf, 0x9c, 0x53, 0xd8, 0x5e, 0x7c, 0x40, 0x77, 0x1e, 0xb2, 0xe8, 0x35, 0x8f, 0xee,
1372
-	0xbd, 0xf7, 0xd6, 0xee, 0xf3, 0xb4, 0x7c, 0xcb, 0xf1, 0x60, 0x6b, 0xe1, 0x41, 0xd6, 0xc9, 0xda,
1373
-	0xc9, 0xea, 0x27, 0xe9, 0xde, 0xc3, 0x75, 0xdb, 0x36, 0xcf, 0x85, 0xf1, 0xdc, 0xf0, 0x5c, 0xfd,
1374
-	0xa9, 0x66, 0x78, 0xae, 0x9b, 0xea, 0x6f, 0x39, 0x3f, 0x82, 0x3a, 0x3d, 0xd1, 0x3a, 0x77, 0x98,
1375
-	0xb6, 0xf0, 0xf8, 0xdb, 0xbb, 0xbb, 0x80, 0x35, 0x07, 0x5f, 0x43, 0xbb, 0xf0, 0xea, 0xee, 0xbc,
1376
-	0x53, 0x90, 0x55, 0x7c, 0xe1, 0xed, 0xbd, 0xbb, 0x7a, 0xd3, 0x70, 0x3b, 0x00, 0xc8, 0x5f, 0xf1,
1377
-	0x9c, 0x2e, 0x53, 0x2f, 0xbd, 0x14, 0xf7, 0xee, 0xaf, 0xd8, 0x31, 0x4c, 0xd0, 0x95, 0x8b, 0xcf,
1378
-	0x72, 0xce, 0x82, 0x55, 0x17, 0x9f, 0xce, 0x8c, 0x2b, 0xd7, 0xbe, 0xe7, 0x69, 0xb6, 0x8b, 0x4f,
1379
-	0x72, 0x86, 0xed, 0x9a, 0xa7, 0x3e, 0xc3, 0x76, 0xed, 0x5b, 0xde, 0x2d, 0xe7, 0x57, 0xd0, 0x29,
1380
-	0x3e, 0x92, 0x39, 0x99, 0x91, 0x56, 0x3e, 0xf2, 0xf5, 0x1e, 0xac, 0xd9, 0x35, 0x0c, 0x3f, 0x84,
1381
-	0x1a, 0xbd, 0x7e, 0x65, 0x29, 0x67, 0x3f, 0x9a, 0xf5, 0xee, 0x14, 0x91, 0xe6, 0xd4, 0x13, 0xa8,
1382
-	0xd3, 0x87, 0x9d, 0x09, 0x80, 0xc2, 0x77, 0x5e, 0xaf, 0x65, 0x63, 0xdd, 0x5b, 0x4f, 0x4a, 0x99,
1383
-	0x9c, 0xb4, 0x20, 0x27, 0x5d, 0x25, 0xc7, 0x72, 0xce, 0x59, 0x5d, 0xff, 0xa3, 0xf5, 0xf4, 0x3f,
1384
-	0x01, 0x00, 0x00, 0xff, 0xff, 0xf0, 0xa3, 0xf6, 0xb8, 0xde, 0x1a, 0x00, 0x00,
1241
+	// 2348 bytes of a gzipped FileDescriptorProto
1242
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xec, 0x59, 0x4b, 0x73, 0x1c, 0x49,
1243
+	0x11, 0xf6, 0x3c, 0xa5, 0xc9, 0x79, 0x48, 0xea, 0xd5, 0x63, 0x3c, 0xbb, 0xf6, 0x9a, 0x8e, 0x05,
1244
+	0x0c, 0x2c, 0xc2, 0x8c, 0x77, 0x03, 0x07, 0x44, 0x10, 0x61, 0x4b, 0x66, 0x31, 0x6b, 0x2d, 0xe3,
1245
+	0x96, 0xc4, 0x1e, 0x27, 0x5a, 0xdd, 0xe5, 0x99, 0x46, 0x33, 0xdd, 0xbd, 0xdd, 0x35, 0xd2, 0xe8,
1246
+	0xc2, 0x81, 0x03, 0xdc, 0xf8, 0x03, 0x10, 0x5c, 0xb8, 0x71, 0xe7, 0xc0, 0x2f, 0x20, 0x82, 0x1f,
1247
+	0xc2, 0x8d, 0x3b, 0x47, 0xb2, 0xaa, 0xb2, 0xab, 0xab, 0xe7, 0x21, 0x99, 0x03, 0xc1, 0x85, 0xcb,
1248
+	0x44, 0xd5, 0x57, 0x59, 0x99, 0x59, 0xf9, 0xaa, 0xec, 0x1a, 0x68, 0xb8, 0x71, 0x70, 0x18, 0x27,
1249
+	0x11, 0x8f, 0xac, 0x1a, 0xbf, 0x89, 0x59, 0x6a, 0xdf, 0x87, 0x83, 0xcf, 0x18, 0x3f, 0x65, 0xc9,
1250
+	0x15, 0x4b, 0x7e, 0xc1, 0x92, 0x34, 0x88, 0x42, 0x87, 0x7d, 0x35, 0x63, 0x29, 0xb7, 0xe7, 0xd0,
1251
+	0x5d, 0x5e, 0x4a, 0xe3, 0x28, 0x4c, 0x99, 0xb5, 0x0b, 0xb5, 0xa9, 0xfb, 0xcb, 0x28, 0xe9, 0x96,
1252
+	0x1e, 0x95, 0x1e, 0xb7, 0x1d, 0x35, 0x91, 0x68, 0x10, 0x22, 0x5a, 0x26, 0x54, 0x4c, 0x04, 0x1a,
1253
+	0xbb, 0xdc, 0x1b, 0x77, 0x2b, 0x0a, 0x95, 0x13, 0xab, 0x07, 0x9b, 0x09, 0xbb, 0x0a, 0x04, 0xd7,
1254
+	0x6e, 0x15, 0x17, 0x1a, 0x8e, 0x9e, 0xdb, 0xbf, 0x29, 0xc1, 0xee, 0x79, 0xec, 0xbb, 0x9c, 0x0d,
1255
+	0x92, 0xc8, 0x63, 0x69, 0x4a, 0x2a, 0x59, 0x1d, 0x28, 0x07, 0xbe, 0x94, 0xd9, 0x70, 0x70, 0x64,
1256
+	0x6d, 0x43, 0x25, 0x46, 0xa0, 0x2c, 0x01, 0x31, 0xb4, 0x1e, 0x02, 0x78, 0x93, 0x28, 0x65, 0xa7,
1257
+	0xdc, 0x0f, 0x42, 0x29, 0x71, 0xd3, 0x31, 0x10, 0xa1, 0xcc, 0x75, 0xe0, 0xf3, 0xb1, 0x94, 0x89,
1258
+	0xca, 0xc8, 0x89, 0xb5, 0x0f, 0xf5, 0x31, 0x0b, 0x46, 0x63, 0xde, 0xad, 0x49, 0x98, 0x66, 0xf6,
1259
+	0x01, 0xec, 0x2d, 0xe8, 0xa1, 0xce, 0x6f, 0xff, 0xbd, 0x0c, 0xfb, 0x47, 0x09, 0xc3, 0x95, 0xa3,
1260
+	0x28, 0xe4, 0x6e, 0x10, 0xb2, 0x64, 0x9d, 0x8e, 0xa8, 0xd1, 0xc5, 0x2c, 0xf4, 0x27, 0x6c, 0xe0,
1261
+	0xa2, 0x58, 0xa5, 0xaa, 0x81, 0x48, 0x8d, 0xc7, 0xcc, 0xbb, 0x8c, 0xa3, 0x20, 0xe4, 0x52, 0x63,
1262
+	0x5c, 0xcf, 0x11, 0xa1, 0x71, 0x2a, 0x0f, 0xa3, 0xac, 0xa4, 0x26, 0x42, 0x63, 0x1c, 0x44, 0x33,
1263
+	0xa5, 0x71, 0xc3, 0xa1, 0x19, 0xe1, 0x2c, 0x49, 0xba, 0x75, 0x8d, 0xe3, 0x4c, 0xe0, 0x13, 0xf7,
1264
+	0x82, 0x4d, 0xd2, 0xee, 0xc6, 0xa3, 0x8a, 0xc0, 0xd5, 0xcc, 0x7a, 0x04, 0xcd, 0x30, 0x1a, 0x04,
1265
+	0x57, 0x11, 0x77, 0xa2, 0x88, 0x77, 0x37, 0xa5, 0xc1, 0x4c, 0xc8, 0xea, 0xc2, 0x46, 0x32, 0x0b,
1266
+	0x79, 0x30, 0x65, 0xdd, 0x86, 0x64, 0x99, 0x4d, 0xc5, 0x5e, 0x1a, 0x3e, 0x4f, 0x46, 0x69, 0x17,
1267
+	0x24, 0x63, 0x13, 0xb2, 0x3e, 0x82, 0x76, 0x7e, 0x92, 0xe3, 0x20, 0xe9, 0x36, 0x25, 0x87, 0x22,
1268
+	0x68, 0xbf, 0x82, 0x83, 0x25, 0x5b, 0x52, 0x9c, 0x1d, 0x42, 0xc3, 0xcb, 0x40, 0x69, 0xd3, 0x66,
1269
+	0x7f, 0xfb, 0x50, 0x46, 0xee, 0x61, 0x4e, 0x9c, 0x93, 0x20, 0xab, 0xf6, 0x69, 0x30, 0x0a, 0xdd,
1270
+	0xc9, 0xbb, 0x47, 0x8c, 0xb0, 0x98, 0xdc, 0x42, 0xf1, 0x49, 0x33, 0x7b, 0x1b, 0x3a, 0x19, 0x2b,
1271
+	0x72, 0xfa, 0x5f, 0x2a, 0xb0, 0xf3, 0xdc, 0xf7, 0xef, 0x88, 0x49, 0x0c, 0x6c, 0xce, 0x12, 0x0c,
1272
+	0x7d, 0xe4, 0x58, 0x96, 0xe6, 0xd4, 0x73, 0xeb, 0x43, 0xa8, 0xce, 0x52, 0x3c, 0x49, 0x45, 0x9e,
1273
+	0xa4, 0x49, 0x27, 0x39, 0x47, 0xc8, 0x91, 0x0b, 0x96, 0x05, 0x55, 0x57, 0xd8, 0xb2, 0x2a, 0x6d,
1274
+	0x29, 0xc7, 0x42, 0x65, 0x16, 0x5e, 0xa1, 0x9f, 0x05, 0x24, 0x86, 0x02, 0xf1, 0xae, 0x7d, 0xf2,
1275
+	0xb0, 0x18, 0x66, 0xc7, 0xda, 0xc8, 0x8f, 0xa5, 0xc3, 0x66, 0x73, 0x75, 0xd8, 0x34, 0xd6, 0x84,
1276
+	0x0d, 0x14, 0xc2, 0xc6, 0x86, 0x96, 0xe7, 0xc6, 0xee, 0x45, 0x30, 0x09, 0x78, 0xc0, 0x52, 0xf4,
1277
+	0x9f, 0x50, 0xa2, 0x80, 0x59, 0x8f, 0x61, 0xcb, 0x8d, 0x63, 0x37, 0x99, 0x46, 0x09, 0x9a, 0xe6,
1278
+	0x6d, 0x30, 0x61, 0xdd, 0x96, 0x64, 0xb2, 0x08, 0x0b, 0x6e, 0x29, 0x9b, 0x04, 0xe1, 0x6c, 0xfe,
1279
+	0x5a, 0x44, 0x5f, 0xb7, 0x2d, 0xc9, 0x0a, 0x98, 0xe0, 0x16, 0x46, 0x5f, 0xb0, 0xeb, 0x41, 0x12,
1280
+	0x5c, 0xe1, 0x9e, 0x11, 0x0a, 0xed, 0x48, 0x2b, 0x2e, 0xc2, 0xd6, 0x37, 0x31, 0x30, 0x27, 0xc1,
1281
+	0x34, 0xe0, 0x69, 0x77, 0x0b, 0xd5, 0x6a, 0xf6, 0xdb, 0x64, 0x4f, 0x47, 0xa2, 0x4e, 0xb6, 0x6a,
1282
+	0x1f, 0x43, 0x5d, 0x41, 0xc2, 0xbc, 0x82, 0x84, 0xbc, 0x25, 0xc7, 0x02, 0x4b, 0xa3, 0xb7, 0x5c,
1283
+	0xfa, 0xaa, 0xea, 0xc8, 0xb1, 0xc0, 0xc6, 0x6e, 0xe2, 0x4b, 0x3f, 0x21, 0x26, 0xc6, 0xb6, 0x03,
1284
+	0x55, 0xe1, 0x28, 0x61, 0xea, 0x19, 0x39, 0xbc, 0xed, 0x88, 0xa1, 0x40, 0x46, 0x14, 0x53, 0x88,
1285
+	0xe0, 0xd0, 0xfa, 0x06, 0x74, 0x5c, 0xdf, 0x47, 0xf3, 0x44, 0xe8, 0xf5, 0xcf, 0x02, 0x3f, 0x45,
1286
+	0x4e, 0x15, 0x5c, 0x5c, 0x40, 0xed, 0x5d, 0xb0, 0xcc, 0x80, 0xa2, 0x38, 0xfb, 0x75, 0x49, 0x27,
1287
+	0x84, 0xce, 0x93, 0x75, 0xd1, 0xf6, 0xfd, 0x42, 0xf5, 0x28, 0xcb, 0xb8, 0xda, 0xc9, 0x32, 0x24,
1288
+	0xdf, 0x6d, 0x16, 0x94, 0xa5, 0xa4, 0xac, 0xac, 0x4a, 0xca, 0x1e, 0x74, 0x97, 0x75, 0x20, 0x05,
1289
+	0x3d, 0x38, 0x38, 0x66, 0x13, 0xf6, 0x2e, 0xfa, 0xa1, 0x25, 0x43, 0x17, 0x4b, 0x87, 0x4a, 0x38,
1290
+	0x39, 0x7e, 0x77, 0x05, 0x96, 0x85, 0x90, 0x02, 0x27, 0xb0, 0xf7, 0x3a, 0x48, 0xf9, 0xdd, 0xe2,
1291
+	0x97, 0x44, 0x95, 0x57, 0x89, 0xfa, 0x15, 0x40, 0xce, 0x4a, 0xab, 0x5c, 0x32, 0x54, 0x46, 0x8c,
1292
+	0xcd, 0x03, 0x4e, 0x09, 0x2d, 0xc7, 0xc2, 0xed, 0xdc, 0x8b, 0xe9, 0x8e, 0x11, 0x43, 0x51, 0x10,
1293
+	0x67, 0x61, 0x30, 0x3f, 0x8d, 0xbc, 0x4b, 0xc6, 0x53, 0x59, 0xb0, 0xb1, 0x98, 0x1a, 0x90, 0xcc,
1294
+	0xca, 0x31, 0x9b, 0x4c, 0x64, 0xd5, 0xde, 0x74, 0xd4, 0x04, 0x8f, 0xb3, 0xbf, 0x78, 0x1c, 0xaa,
1295
+	0x7f, 0x4f, 0xa1, 0x99, 0xab, 0x9a, 0xa2, 0x4a, 0x95, 0xd5, 0xfe, 0x35, 0xa9, 0xec, 0x87, 0xd0,
1296
+	0x3a, 0xe5, 0xe8, 0xb9, 0x35, 0x46, 0xb1, 0x1f, 0x43, 0x47, 0x17, 0x4f, 0x49, 0xa8, 0xd2, 0xdf,
1297
+	0xe5, 0xb3, 0x94, 0xa8, 0x68, 0x66, 0xff, 0xb5, 0x02, 0x1b, 0x14, 0x9d, 0x59, 0x89, 0x29, 0xe5,
1298
+	0x25, 0xe6, 0x7f, 0x52, 0xe9, 0x3e, 0x80, 0x46, 0x7a, 0x93, 0x72, 0x36, 0x1d, 0x50, 0xbd, 0x6b,
1299
+	0x3b, 0x39, 0xf0, 0xff, 0xaa, 0x97, 0x57, 0xbd, 0xbf, 0x95, 0xa0, 0xa1, 0xdd, 0xfc, 0x1f, 0x77,
1300
+	0x25, 0x1f, 0x43, 0x23, 0x56, 0x8e, 0x67, 0xaa, 0x78, 0x35, 0xfb, 0x1d, 0x12, 0x94, 0x95, 0xab,
1301
+	0x9c, 0xc0, 0x88, 0x9f, 0xaa, 0x19, 0x3f, 0x46, 0xd7, 0x51, 0x2b, 0x74, 0x1d, 0xe8, 0xfc, 0x58,
1302
+	0x54, 0xc5, 0xba, 0xac, 0x8a, 0x72, 0x6c, 0xf6, 0x19, 0x1b, 0x85, 0x3e, 0xc3, 0xfe, 0x14, 0x36,
1303
+	0x4e, 0x5c, 0x6f, 0x8c, 0xe7, 0x10, 0x1b, 0xbd, 0x98, 0xc2, 0x14, 0x37, 0x8a, 0xb1, 0x10, 0x32,
1304
+	0x65, 0x68, 0xef, 0x1b, 0x2a, 0xe1, 0x34, 0xb3, 0x2f, 0xb1, 0x17, 0x50, 0x69, 0x40, 0xc9, 0xf4,
1305
+	0x04, 0x6b, 0x65, 0x66, 0x90, 0x2c, 0x97, 0x96, 0xbb, 0x09, 0x83, 0x06, 0xdd, 0xb2, 0x31, 0x55,
1306
+	0x92, 0xa9, 0xb4, 0x66, 0x36, 0x20, 0x7d, 0x9c, 0x6c, 0xd9, 0xfe, 0x6d, 0x09, 0xf6, 0x55, 0xab,
1307
+	0x78, 0x67, 0x43, 0xb8, 0xba, 0x05, 0x51, 0xe6, 0xab, 0x14, 0xcc, 0xf7, 0x14, 0x1a, 0x09, 0x4b,
1308
+	0xa3, 0x59, 0x82, 0x66, 0x96, 0x96, 0x6d, 0xf6, 0xf7, 0xb2, 0x4c, 0x92, 0xb2, 0x1c, 0x5a, 0x75,
1309
+	0x72, 0x3a, 0xfb, 0x0f, 0x15, 0xe8, 0x14, 0x57, 0x45, 0x5d, 0xba, 0x98, 0x5c, 0x06, 0xd1, 0x97,
1310
+	0xaa, 0xc7, 0x55, 0xc6, 0x33, 0x21, 0x91, 0x55, 0x68, 0xcb, 0x53, 0xbc, 0xe8, 0x50, 0x92, 0xba,
1311
+	0xc8, 0x72, 0x80, 0x56, 0x07, 0x2c, 0x09, 0x22, 0x9f, 0xba, 0xa4, 0x1c, 0x10, 0x65, 0x00, 0x27,
1312
+	0x6f, 0x66, 0x11, 0x77, 0xa9, 0xab, 0xd6, 0x73, 0xd9, 0xdc, 0xa2, 0x8f, 0x18, 0x3f, 0x12, 0x5e,
1313
+	0xab, 0x51, 0x73, 0xab, 0x91, 0x7c, 0xfd, 0x84, 0x4d, 0x53, 0x4a, 0x73, 0x03, 0x11, 0x9a, 0x2b,
1314
+	0x6f, 0xbe, 0x16, 0x41, 0x4d, 0xf9, 0x6e, 0x42, 0x82, 0x83, 0x9a, 0x9e, 0x5e, 0xbb, 0xb1, 0x4c,
1315
+	0xfb, 0xb6, 0x63, 0x20, 0x18, 0xc8, 0x3b, 0x6a, 0x86, 0xd6, 0xc0, 0x4f, 0x19, 0x57, 0xdc, 0xbe,
1316
+	0xb2, 0x0c, 0xb4, 0x9d, 0xe5, 0x05, 0x41, 0x7d, 0xc9, 0x92, 0x90, 0x4d, 0x4e, 0x0c, 0xa9, 0xa0,
1317
+	0xa8, 0x97, 0x16, 0xac, 0x3e, 0xec, 0x2a, 0xf0, 0xec, 0x68, 0x60, 0x6e, 0x68, 0xca, 0x0d, 0x2b,
1318
+	0xd7, 0xc4, 0x07, 0xd7, 0x52, 0x9c, 0xd0, 0xad, 0xf6, 0x5d, 0x68, 0xbf, 0xbc, 0x62, 0x58, 0xc1,
1319
+	0xb3, 0xc8, 0x41, 0xbb, 0x8b, 0x04, 0xc0, 0x68, 0x98, 0xc6, 0xd2, 0x6b, 0x55, 0x27, 0x07, 0xec,
1320
+	0x14, 0x6a, 0x92, 0x7c, 0x65, 0x57, 0xa3, 0x82, 0xae, 0xac, 0x83, 0xae, 0x18, 0x62, 0x6d, 0x1d,
1321
+	0x62, 0x14, 0x8c, 0xd5, 0x3c, 0x18, 0x0b, 0x42, 0x6b, 0x8b, 0x42, 0x7f, 0x57, 0x86, 0xd6, 0x17,
1322
+	0x8c, 0x5f, 0x47, 0xc9, 0xa5, 0x48, 0xae, 0x74, 0xe5, 0x6d, 0x79, 0x1f, 0xbf, 0xed, 0xe6, 0xc3,
1323
+	0x8b, 0x1b, 0x4e, 0xc1, 0x54, 0xc5, 0x5c, 0x9e, 0xbf, 0x10, 0x53, 0xeb, 0x01, 0x00, 0x2e, 0x0d,
1324
+	0x5c, 0x75, 0x43, 0xaa, 0xfe, 0xaa, 0x91, 0xcc, 0x09, 0xb0, 0xde, 0x87, 0x86, 0x33, 0x1f, 0x62,
1325
+	0x0d, 0x8e, 0x12, 0x15, 0xf1, 0x55, 0xfc, 0x2c, 0x9c, 0xbf, 0x94, 0x73, 0xb1, 0x17, 0x17, 0xfd,
1326
+	0x24, 0x8a, 0x63, 0xe6, 0x67, 0xaa, 0x25, 0xf3, 0x63, 0x05, 0x08, 0xa9, 0x67, 0x99, 0xd4, 0xba,
1327
+	0x92, 0xca, 0x73, 0xa9, 0xb8, 0x14, 0x93, 0xd4, 0x0d, 0x3a, 0x94, 0x29, 0xf5, 0x4c, 0x4b, 0xdd,
1328
+	0x54, 0x52, 0xb9, 0x21, 0xf5, 0x2c, 0x97, 0xda, 0xc8, 0xf6, 0x92, 0x54, 0xfb, 0xcf, 0x25, 0xd8,
1329
+	0xc4, 0x50, 0x3e, 0x4f, 0xdd, 0x11, 0xc3, 0x5b, 0xaf, 0xc9, 0x31, 0xec, 0x27, 0xc3, 0x99, 0x98,
1330
+	0x92, 0xcb, 0x40, 0x42, 0x8a, 0xe0, 0x6b, 0xd0, 0x8a, 0x59, 0x82, 0x01, 0x4e, 0x14, 0x65, 0x2c,
1331
+	0x42, 0x55, 0xa7, 0xa9, 0x30, 0x45, 0x72, 0x08, 0xef, 0xc9, 0xb5, 0x61, 0x10, 0x0e, 0x55, 0x04,
1332
+	0x4d, 0x23, 0x9f, 0x91, 0xa9, 0x76, 0xe4, 0xd2, 0xab, 0xf0, 0x73, 0xbd, 0x60, 0x7d, 0x1b, 0x76,
1333
+	0x34, 0xbd, 0xb8, 0x59, 0x25, 0xb5, 0x32, 0xdd, 0x16, 0x51, 0x9f, 0x13, 0x8c, 0x8d, 0x4e, 0xe7,
1334
+	0x6c, 0x8c, 0x9f, 0xff, 0x1c, 0xaf, 0x9e, 0xd1, 0xb1, 0x8b, 0x09, 0x8a, 0x55, 0x37, 0x96, 0x69,
1335
+	0x9c, 0x92, 0xb6, 0xd9, 0xd4, 0xfa, 0x0e, 0xec, 0x70, 0x45, 0xcb, 0xfc, 0x61, 0x46, 0xa3, 0xbc,
1336
+	0xb9, 0xad, 0x17, 0x06, 0x44, 0xfc, 0x75, 0xe8, 0xe4, 0xc4, 0xb2, 0x86, 0x2b, 0x7d, 0xdb, 0x1a,
1337
+	0x3d, 0x13, 0x95, 0xfc, 0xf7, 0xca, 0x58, 0x2a, 0x72, 0x3e, 0x96, 0x55, 0xc5, 0x30, 0x55, 0xb3,
1338
+	0xbf, 0x95, 0x55, 0x63, 0x32, 0x86, 0xac, 0x24, 0xca, 0x2c, 0x3f, 0x86, 0x2d, 0xae, 0x55, 0x1f,
1339
+	0x62, 0x02, 0xb9, 0x54, 0x92, 0xb3, 0x8a, 0x58, 0x3c, 0x98, 0xd3, 0xe1, 0xc5, 0x83, 0xa2, 0xe5,
1340
+	0x55, 0x9b, 0x40, 0x02, 0x95, 0x7e, 0x4d, 0x85, 0x49, 0x11, 0xf6, 0x8f, 0xa0, 0x81, 0x3d, 0x44,
1341
+	0xaa, 0xb4, 0x43, 0xc3, 0x78, 0xb3, 0x24, 0xc1, 0xfc, 0xca, 0x0c, 0x43, 0x53, 0xd1, 0x63, 0xc8,
1342
+	0x2b, 0x96, 0x8c, 0xa1, 0x26, 0x76, 0x04, 0xa0, 0xd2, 0x5c, 0x4a, 0x43, 0x1a, 0x33, 0x04, 0xd4,
1343
+	0x44, 0xc4, 0xd9, 0xd4, 0x9d, 0x6b, 0xd7, 0xcb, 0x38, 0x43, 0x40, 0x1d, 0x10, 0x05, 0xbe, 0x75,
1344
+	0x83, 0x89, 0x47, 0x8f, 0x00, 0x28, 0x90, 0xa6, 0xb9, 0xc0, 0xaa, 0x29, 0xf0, 0x4f, 0x65, 0x68,
1345
+	0x2a, 0x89, 0x4a, 0x61, 0xa4, 0xf2, 0xf0, 0x32, 0xd2, 0x22, 0xe5, 0x04, 0xdb, 0x85, 0x5a, 0x2e,
1346
+	0x2e, 0x6f, 0x1d, 0x73, 0x55, 0x33, 0xdd, 0xf0, 0x72, 0x4c, 0xb1, 0x5e, 0x1a, 0xd6, 0x59, 0x49,
1347
+	0xdd, 0x10, 0x44, 0x4a, 0xe1, 0x4f, 0xa0, 0xa5, 0xe2, 0x93, 0xf6, 0x54, 0xd7, 0xed, 0x69, 0x2a,
1348
+	0x32, 0xb5, 0xeb, 0xa9, 0xe8, 0xd0, 0x50, 0x5f, 0xd9, 0x11, 0x34, 0xfb, 0x0f, 0x0a, 0xe4, 0xf2,
1349
+	0x24, 0x87, 0xf2, 0xf7, 0x65, 0xc8, 0xb1, 0x34, 0x2b, 0xda, 0xde, 0x33, 0x80, 0x1c, 0x14, 0x35,
1350
+	0xeb, 0x92, 0xdd, 0x64, 0x9d, 0x28, 0x0e, 0xc5, 0xd9, 0xaf, 0xdc, 0xc9, 0x2c, 0x33, 0xaa, 0x9a,
1351
+	0xfc, 0xb0, 0xfc, 0xac, 0x84, 0x9f, 0x2a, 0x5b, 0x2f, 0xc4, 0x3d, 0x67, 0x6c, 0x2f, 0xbc, 0x5d,
1352
+	0x55, 0x57, 0xbe, 0x5d, 0x55, 0xb3, 0xb7, 0x2b, 0x2c, 0xa3, 0x51, 0x4c, 0xb7, 0x32, 0x8e, 0x72,
1353
+	0x41, 0x55, 0x43, 0x90, 0xfd, 0x8f, 0x2a, 0x40, 0x2e, 0xc5, 0x3a, 0x85, 0x5e, 0x10, 0x0d, 0xc5,
1354
+	0xa5, 0x12, 0x78, 0x4c, 0x15, 0xa4, 0x61, 0xc2, 0x30, 0x7c, 0xd2, 0xe0, 0x8a, 0x51, 0xdf, 0xb1,
1355
+	0x4f, 0xe7, 0x5e, 0x50, 0xce, 0x39, 0xc0, 0x99, 0xda, 0x28, 0x2b, 0x97, 0x93, 0x6d, 0xb3, 0x7e,
1356
+	0x06, 0x7b, 0x39, 0x53, 0xdf, 0xe0, 0x57, 0xbe, 0x95, 0xdf, 0x7b, 0x9a, 0x9f, 0x9f, 0xf3, 0xfa,
1357
+	0x09, 0x20, 0x3c, 0xc4, 0x3b, 0x66, 0x56, 0xe0, 0x54, 0xb9, 0x95, 0xd3, 0x4e, 0x10, 0xbd, 0x91,
1358
+	0x3b, 0x72, 0x3e, 0x6f, 0xe0, 0xbe, 0x71, 0x50, 0x91, 0xf6, 0x06, 0xb7, 0xea, 0xad, 0xdc, 0xf6,
1359
+	0xb5, 0x5e, 0xa2, 0x30, 0xe4, 0x2c, 0x3f, 0x07, 0x5c, 0x19, 0x5e, 0xbb, 0x01, 0x5f, 0xe4, 0x57,
1360
+	0xbb, 0xeb, 0x9c, 0x5f, 0xe2, 0xa6, 0x22, 0x33, 0x75, 0xce, 0x29, 0x4b, 0x46, 0x85, 0x73, 0xd6,
1361
+	0xef, 0x3a, 0xe7, 0x89, 0xdc, 0x91, 0xf3, 0x79, 0x01, 0x08, 0x2e, 0xea, 0xb3, 0x71, 0x2b, 0x97,
1362
+	0xad, 0x20, 0x2a, 0xea, 0x72, 0x04, 0x3b, 0x29, 0xf3, 0x38, 0xde, 0x28, 0x06, 0x8f, 0xcd, 0x5b,
1363
+	0x79, 0x6c, 0xd3, 0x06, 0xcd, 0xc4, 0xfe, 0x0a, 0x5a, 0x3f, 0x9d, 0x8d, 0x18, 0x9f, 0x5c, 0xe8,
1364
+	0x9c, 0xff, 0x6f, 0x97, 0x99, 0x7f, 0x61, 0x99, 0x39, 0x1a, 0x25, 0xd1, 0x2c, 0x2e, 0x54, 0x6d,
1365
+	0x95, 0xc3, 0x4b, 0x55, 0x5b, 0xd2, 0xc8, 0xaa, 0xad, 0xa8, 0x3f, 0x85, 0x96, 0x6a, 0xb2, 0x68,
1366
+	0x83, 0xaa, 0x42, 0xd6, 0x72, 0xd2, 0x67, 0x4d, 0x9d, 0xda, 0xd6, 0xa7, 0x86, 0x95, 0x76, 0x15,
1367
+	0xab, 0x51, 0x6e, 0x26, 0xfc, 0x62, 0xc9, 0xb3, 0xee, 0x15, 0xb4, 0xc7, 0xca, 0x36, 0xb4, 0x4b,
1368
+	0x05, 0xe0, 0x47, 0x99, 0x72, 0xf9, 0x19, 0x0e, 0x4d, 0x1b, 0x2a, 0x53, 0xb7, 0xc6, 0xa6, 0x59,
1369
+	0xbf, 0x07, 0x20, 0x3e, 0x49, 0x86, 0x59, 0xa1, 0x32, 0x9f, 0x1d, 0xf5, 0x0d, 0x81, 0xdf, 0x3f,
1370
+	0xd9, 0xb0, 0x77, 0x06, 0x3b, 0x4b, 0x3c, 0x57, 0x94, 0xa9, 0x6f, 0x99, 0x65, 0xaa, 0xd9, 0x7f,
1371
+	0x8f, 0x58, 0x9a, 0x5b, 0xcd, 0xda, 0xf5, 0xc7, 0x92, 0xfa, 0x82, 0xd1, 0x2f, 0x43, 0xd6, 0x33,
1372
+	0x68, 0x87, 0xaa, 0xf9, 0xd2, 0x0e, 0xa8, 0x18, 0x8c, 0xcc, 0xc6, 0xcc, 0x69, 0x85, 0x66, 0x9b,
1373
+	0x86, 0x8e, 0xf0, 0xa4, 0x05, 0x56, 0x3a, 0xc2, 0x30, 0x8e, 0xd3, 0xf4, 0x0c, 0x6f, 0x17, 0x9a,
1374
+	0xc1, 0xca, 0x62, 0x33, 0x48, 0x0f, 0x0d, 0xeb, 0x9e, 0x42, 0xfb, 0xff, 0xac, 0x43, 0xe5, 0xf9,
1375
+	0xe0, 0x95, 0x75, 0x0e, 0xdb, 0x8b, 0xff, 0x24, 0x58, 0x0f, 0x49, 0xf4, 0x9a, 0x7f, 0x1f, 0x7a,
1376
+	0x1f, 0xae, 0x5d, 0xa7, 0x6e, 0xf9, 0x9e, 0xe5, 0xc0, 0xd6, 0xc2, 0xbb, 0xb1, 0x95, 0x5d, 0x27,
1377
+	0xab, 0xdf, 0xe6, 0x7b, 0x0f, 0xd7, 0x2d, 0x9b, 0x3c, 0x17, 0xda, 0x73, 0xcd, 0x73, 0xf5, 0xe7,
1378
+	0x9d, 0xe6, 0xb9, 0xae, 0xab, 0xbf, 0x67, 0xfd, 0x00, 0xea, 0xea, 0x25, 0xd9, 0xda, 0x25, 0xda,
1379
+	0xc2, 0x1b, 0x75, 0x6f, 0x6f, 0x01, 0xd5, 0x1b, 0x5f, 0x43, 0xbb, 0xf0, 0xf7, 0x83, 0xf5, 0x7e,
1380
+	0x41, 0x56, 0xf1, 0x21, 0xba, 0xf7, 0xc1, 0xea, 0x45, 0xcd, 0xed, 0x08, 0x20, 0x7f, 0x6c, 0xb4,
1381
+	0xba, 0x44, 0xbd, 0xf4, 0xa0, 0xdd, 0xbb, 0xbf, 0x62, 0x45, 0x33, 0x41, 0x57, 0x2e, 0x3e, 0x0b,
1382
+	0x5a, 0x0b, 0x56, 0x5d, 0x7c, 0x94, 0xd3, 0xae, 0x5c, 0xfb, 0x9e, 0x28, 0xd9, 0x2e, 0x3e, 0xf6,
1383
+	0x69, 0xb6, 0x6b, 0x9e, 0x1a, 0x35, 0xdb, 0xb5, 0xaf, 0x84, 0xf7, 0xac, 0x9f, 0x43, 0xa7, 0xf8,
1384
+	0xb0, 0x66, 0x65, 0x46, 0x5a, 0xf9, 0x7c, 0xd8, 0x7b, 0xb0, 0x66, 0x55, 0x33, 0xfc, 0x04, 0x6a,
1385
+	0xea, 0xc5, 0x2c, 0x4b, 0x39, 0xf3, 0xa1, 0xad, 0xb7, 0x5b, 0x04, 0xf5, 0xae, 0x27, 0x50, 0x57,
1386
+	0x1f, 0x76, 0x3a, 0x00, 0x0a, 0xdf, 0x79, 0xbd, 0x96, 0x89, 0xda, 0xf7, 0x9e, 0x94, 0x32, 0x39,
1387
+	0x69, 0x41, 0x4e, 0xba, 0x4a, 0x8e, 0xe1, 0x9c, 0x8b, 0xba, 0xfc, 0x6b, 0xef, 0xe9, 0xbf, 0x03,
1388
+	0x00, 0x00, 0xff, 0xff, 0x58, 0xa9, 0x0a, 0x41, 0xe7, 0x1b, 0x00, 0x00,
1385 1389
 }
... ...
@@ -47,6 +47,9 @@ message CreateContainerRequest {
47 47
 	string stderr = 6; // path to file where stderr will be written (optional)
48 48
 	repeated string labels = 7;
49 49
 	bool noPivotRoot = 8;
50
+	string runtime = 9;
51
+	repeated string runtimeArgs = 10;
52
+	string checkpointDir = 11; // Directory where checkpoints are stored
50 53
 }
51 54
 
52 55
 message CreateContainerResponse {
... ...
@@ -98,6 +101,7 @@ message AddProcessResponse {
98 98
 message CreateCheckpointRequest {
99 99
 	string id = 1; // ID of container
100 100
 	Checkpoint checkpoint = 2; // Checkpoint configuration
101
+	string checkpointDir = 3; // Directory where checkpoints are stored
101 102
 }
102 103
 
103 104
 message CreateCheckpointResponse {
... ...
@@ -106,6 +110,7 @@ message CreateCheckpointResponse {
106 106
 message DeleteCheckpointRequest {
107 107
 	string id = 1; // ID of container
108 108
 	string name = 2; // Name of checkpoint
109
+	string checkpointDir = 3; // Directory where checkpoints are stored
109 110
 }
110 111
 
111 112
 message DeleteCheckpointResponse {
... ...
@@ -113,6 +118,7 @@ message DeleteCheckpointResponse {
113 113
 
114 114
 message ListCheckpointRequest {
115 115
 	string id = 1; // ID of container
116
+	string checkpointDir = 2; // Directory where checkpoints are stored
116 117
 }
117 118
 
118 119
 message Checkpoint {
... ...
@@ -193,6 +199,7 @@ message UpdateResource {
193 193
 	uint32 memorySwap = 8;
194 194
 	uint32 memoryReservation = 9;
195 195
 	uint32 kernelMemoryLimit = 10;
196
+	uint32 kernelTCPMemoryLimit = 11;
196 197
 }
197 198
 
198 199
 message UpdateContainerResponse {
... ...
@@ -39,5 +39,5 @@ test: install generate-test-pbs
39 39
 generate-test-pbs:
40 40
 	make install
41 41
 	make -C testdata
42
-	protoc --go_out=Mtestdata/test.proto=github.com/golang/protobuf/proto/testdata,Mgoogle/protobuf/any.proto=github.com/golang/protobuf/ptypes/any:. proto3_proto/proto3.proto
42
+	protoc --go_out=Mtestdata/test.proto=github.com/golang/protobuf/proto/testdata:. proto3_proto/proto3.proto
43 43
 	make
... ...
@@ -768,11 +768,10 @@ func (o *Buffer) dec_new_map(p *Properties, base structPointer) error {
768 768
 		}
769 769
 	}
770 770
 	keyelem, valelem := keyptr.Elem(), valptr.Elem()
771
-	if !keyelem.IsValid() {
772
-		keyelem = reflect.Zero(p.mtype.Key())
773
-	}
774
-	if !valelem.IsValid() {
775
-		valelem = reflect.Zero(p.mtype.Elem())
771
+	if !keyelem.IsValid() || !valelem.IsValid() {
772
+		// We did not decode the key or the value in the map entry.
773
+		// Either way, it's an invalid map entry.
774
+		return fmt.Errorf("proto: bad map data: missing key/val")
776 775
 	}
777 776
 
778 777
 	v.SetMapIndex(keyelem, valelem)
... ...
@@ -64,10 +64,6 @@ var (
64 64
 	// a struct with a repeated field containing a nil element.
65 65
 	errRepeatedHasNil = errors.New("proto: repeated field has nil element")
66 66
 
67
-	// errOneofHasNil is the error returned if Marshal is called with
68
-	// a struct with a oneof field containing a nil element.
69
-	errOneofHasNil = errors.New("proto: oneof field has nil value")
70
-
71 67
 	// ErrNil is the error returned if Marshal is called with nil.
72 68
 	ErrNil = errors.New("proto: Marshal called with nil")
73 69
 )
... ...
@@ -1226,9 +1222,7 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
1226 1226
 	// Do oneof fields.
1227 1227
 	if prop.oneofMarshaler != nil {
1228 1228
 		m := structPointer_Interface(base, prop.stype).(Message)
1229
-		if err := prop.oneofMarshaler(m, o); err == ErrNil {
1230
-			return errOneofHasNil
1231
-		} else if err != nil {
1229
+		if err := prop.oneofMarshaler(m, o); err != nil {
1232 1230
 			return err
1233 1231
 		}
1234 1232
 	}
... ...
@@ -175,93 +175,7 @@ type raw interface {
175 175
 	Bytes() []byte
176 176
 }
177 177
 
178
-func requiresQuotes(u string) bool {
179
-	// When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted.
180
-	for _, ch := range u {
181
-		switch {
182
-		case ch == '.' || ch == '/' || ch == '_':
183
-			continue
184
-		case '0' <= ch && ch <= '9':
185
-			continue
186
-		case 'A' <= ch && ch <= 'Z':
187
-			continue
188
-		case 'a' <= ch && ch <= 'z':
189
-			continue
190
-		default:
191
-			return true
192
-		}
193
-	}
194
-	return false
195
-}
196
-
197
-// isAny reports whether sv is a google.protobuf.Any message
198
-func isAny(sv reflect.Value) bool {
199
-	type wkt interface {
200
-		XXX_WellKnownType() string
201
-	}
202
-	t, ok := sv.Addr().Interface().(wkt)
203
-	return ok && t.XXX_WellKnownType() == "Any"
204
-}
205
-
206
-// writeProto3Any writes an expanded google.protobuf.Any message.
207
-//
208
-// It returns (false, nil) if sv value can't be unmarshaled (e.g. because
209
-// required messages are not linked in).
210
-//
211
-// It returns (true, error) when sv was written in expanded format or an error
212
-// was encountered.
213
-func (tm *TextMarshaler) writeProto3Any(w *textWriter, sv reflect.Value) (bool, error) {
214
-	turl := sv.FieldByName("TypeUrl")
215
-	val := sv.FieldByName("Value")
216
-	if !turl.IsValid() || !val.IsValid() {
217
-		return true, errors.New("proto: invalid google.protobuf.Any message")
218
-	}
219
-
220
-	b, ok := val.Interface().([]byte)
221
-	if !ok {
222
-		return true, errors.New("proto: invalid google.protobuf.Any message")
223
-	}
224
-
225
-	parts := strings.Split(turl.String(), "/")
226
-	mt := MessageType(parts[len(parts)-1])
227
-	if mt == nil {
228
-		return false, nil
229
-	}
230
-	m := reflect.New(mt.Elem())
231
-	if err := Unmarshal(b, m.Interface().(Message)); err != nil {
232
-		return false, nil
233
-	}
234
-	w.Write([]byte("["))
235
-	u := turl.String()
236
-	if requiresQuotes(u) {
237
-		writeString(w, u)
238
-	} else {
239
-		w.Write([]byte(u))
240
-	}
241
-	if w.compact {
242
-		w.Write([]byte("]:<"))
243
-	} else {
244
-		w.Write([]byte("]: <\n"))
245
-		w.ind++
246
-	}
247
-	if err := tm.writeStruct(w, m.Elem()); err != nil {
248
-		return true, err
249
-	}
250
-	if w.compact {
251
-		w.Write([]byte("> "))
252
-	} else {
253
-		w.ind--
254
-		w.Write([]byte(">\n"))
255
-	}
256
-	return true, nil
257
-}
258
-
259
-func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
260
-	if tm.ExpandAny && isAny(sv) {
261
-		if canExpand, err := tm.writeProto3Any(w, sv); canExpand {
262
-			return err
263
-		}
264
-	}
178
+func writeStruct(w *textWriter, sv reflect.Value) error {
265 179
 	st := sv.Type()
266 180
 	sprops := GetProperties(st)
267 181
 	for i := 0; i < sv.NumField(); i++ {
... ...
@@ -313,7 +227,7 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
313 313
 					}
314 314
 					continue
315 315
 				}
316
-				if err := tm.writeAny(w, v, props); err != nil {
316
+				if err := writeAny(w, v, props); err != nil {
317 317
 					return err
318 318
 				}
319 319
 				if err := w.WriteByte('\n'); err != nil {
... ...
@@ -355,7 +269,7 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
355 355
 						return err
356 356
 					}
357 357
 				}
358
-				if err := tm.writeAny(w, key, props.mkeyprop); err != nil {
358
+				if err := writeAny(w, key, props.mkeyprop); err != nil {
359 359
 					return err
360 360
 				}
361 361
 				if err := w.WriteByte('\n'); err != nil {
... ...
@@ -372,7 +286,7 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
372 372
 							return err
373 373
 						}
374 374
 					}
375
-					if err := tm.writeAny(w, val, props.mvalprop); err != nil {
375
+					if err := writeAny(w, val, props.mvalprop); err != nil {
376 376
 						return err
377 377
 					}
378 378
 					if err := w.WriteByte('\n'); err != nil {
... ...
@@ -444,7 +358,7 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
444 444
 		}
445 445
 
446 446
 		// Enums have a String method, so writeAny will work fine.
447
-		if err := tm.writeAny(w, fv, props); err != nil {
447
+		if err := writeAny(w, fv, props); err != nil {
448 448
 			return err
449 449
 		}
450 450
 
... ...
@@ -456,7 +370,7 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
456 456
 	// Extensions (the XXX_extensions field).
457 457
 	pv := sv.Addr()
458 458
 	if pv.Type().Implements(extendableProtoType) {
459
-		if err := tm.writeExtensions(w, pv); err != nil {
459
+		if err := writeExtensions(w, pv); err != nil {
460 460
 			return err
461 461
 		}
462 462
 	}
... ...
@@ -486,7 +400,7 @@ func writeRaw(w *textWriter, b []byte) error {
486 486
 }
487 487
 
488 488
 // writeAny writes an arbitrary field.
489
-func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error {
489
+func writeAny(w *textWriter, v reflect.Value, props *Properties) error {
490 490
 	v = reflect.Indirect(v)
491 491
 
492 492
 	// Floats have special cases.
... ...
@@ -535,15 +449,15 @@ func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Propert
535 535
 			}
536 536
 		}
537 537
 		w.indent()
538
-		if etm, ok := v.Interface().(encoding.TextMarshaler); ok {
539
-			text, err := etm.MarshalText()
538
+		if tm, ok := v.Interface().(encoding.TextMarshaler); ok {
539
+			text, err := tm.MarshalText()
540 540
 			if err != nil {
541 541
 				return err
542 542
 			}
543 543
 			if _, err = w.Write(text); err != nil {
544 544
 				return err
545 545
 			}
546
-		} else if err := tm.writeStruct(w, v); err != nil {
546
+		} else if err := writeStruct(w, v); err != nil {
547 547
 			return err
548 548
 		}
549 549
 		w.unindent()
... ...
@@ -687,7 +601,7 @@ func (s int32Slice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
687 687
 
688 688
 // writeExtensions writes all the extensions in pv.
689 689
 // pv is assumed to be a pointer to a protocol message struct that is extendable.
690
-func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error {
690
+func writeExtensions(w *textWriter, pv reflect.Value) error {
691 691
 	emap := extensionMaps[pv.Type().Elem()]
692 692
 	ep := pv.Interface().(extendableProto)
693 693
 
... ...
@@ -722,13 +636,13 @@ func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error
722 722
 
723 723
 		// Repeated extensions will appear as a slice.
724 724
 		if !desc.repeated() {
725
-			if err := tm.writeExtension(w, desc.Name, pb); err != nil {
725
+			if err := writeExtension(w, desc.Name, pb); err != nil {
726 726
 				return err
727 727
 			}
728 728
 		} else {
729 729
 			v := reflect.ValueOf(pb)
730 730
 			for i := 0; i < v.Len(); i++ {
731
-				if err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil {
731
+				if err := writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil {
732 732
 					return err
733 733
 				}
734 734
 			}
... ...
@@ -737,7 +651,7 @@ func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error
737 737
 	return nil
738 738
 }
739 739
 
740
-func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error {
740
+func writeExtension(w *textWriter, name string, pb interface{}) error {
741 741
 	if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil {
742 742
 		return err
743 743
 	}
... ...
@@ -746,7 +660,7 @@ func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface
746 746
 			return err
747 747
 		}
748 748
 	}
749
-	if err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil {
749
+	if err := writeAny(w, reflect.ValueOf(pb), nil); err != nil {
750 750
 		return err
751 751
 	}
752 752
 	if err := w.WriteByte('\n'); err != nil {
... ...
@@ -773,13 +687,12 @@ func (w *textWriter) writeIndent() {
773 773
 
774 774
 // TextMarshaler is a configurable text format marshaler.
775 775
 type TextMarshaler struct {
776
-	Compact   bool // use compact text format (one line).
777
-	ExpandAny bool // expand google.protobuf.Any messages of known types
776
+	Compact bool // use compact text format (one line).
778 777
 }
779 778
 
780 779
 // Marshal writes a given protocol buffer in text format.
781 780
 // The only errors returned are from w.
782
-func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error {
781
+func (m *TextMarshaler) Marshal(w io.Writer, pb Message) error {
783 782
 	val := reflect.ValueOf(pb)
784 783
 	if pb == nil || val.IsNil() {
785 784
 		w.Write([]byte("<nil>"))
... ...
@@ -794,11 +707,11 @@ func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error {
794 794
 	aw := &textWriter{
795 795
 		w:        ww,
796 796
 		complete: true,
797
-		compact:  tm.Compact,
797
+		compact:  m.Compact,
798 798
 	}
799 799
 
800
-	if etm, ok := pb.(encoding.TextMarshaler); ok {
801
-		text, err := etm.MarshalText()
800
+	if tm, ok := pb.(encoding.TextMarshaler); ok {
801
+		text, err := tm.MarshalText()
802 802
 		if err != nil {
803 803
 			return err
804 804
 		}
... ...
@@ -812,7 +725,7 @@ func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error {
812 812
 	}
813 813
 	// Dereference the received pointer so we don't have outer < and >.
814 814
 	v := reflect.Indirect(val)
815
-	if err := tm.writeStruct(aw, v); err != nil {
815
+	if err := writeStruct(aw, v); err != nil {
816 816
 		return err
817 817
 	}
818 818
 	if bw != nil {
... ...
@@ -822,9 +735,9 @@ func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error {
822 822
 }
823 823
 
824 824
 // Text is the same as Marshal, but returns the string directly.
825
-func (tm *TextMarshaler) Text(pb Message) string {
825
+func (m *TextMarshaler) Text(pb Message) string {
826 826
 	var buf bytes.Buffer
827
-	tm.Marshal(&buf, pb)
827
+	m.Marshal(&buf, pb)
828 828
 	return buf.String()
829 829
 }
830 830
 
... ...
@@ -163,7 +163,7 @@ func (p *textParser) advance() {
163 163
 	p.cur.offset, p.cur.line = p.offset, p.line
164 164
 	p.cur.unquoted = ""
165 165
 	switch p.s[0] {
166
-	case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/':
166
+	case '<', '>', '{', '}', ':', '[', ']', ';', ',':
167 167
 		// Single symbol
168 168
 		p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)]
169 169
 	case '"', '\'':
... ...
@@ -451,10 +451,7 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
451 451
 	fieldSet := make(map[string]bool)
452 452
 	// A struct is a sequence of "name: value", terminated by one of
453 453
 	// '>' or '}', or the end of the input.  A name may also be
454
-	// "[extension]" or "[type/url]".
455
-	//
456
-	// The whole struct can also be an expanded Any message, like:
457
-	// [type/url] < ... struct contents ... >
454
+	// "[extension]".
458 455
 	for {
459 456
 		tok := p.next()
460 457
 		if tok.err != nil {
... ...
@@ -464,66 +461,33 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
464 464
 			break
465 465
 		}
466 466
 		if tok.value == "[" {
467
-			// Looks like an extension or an Any.
467
+			// Looks like an extension.
468 468
 			//
469 469
 			// TODO: Check whether we need to handle
470 470
 			// namespace rooted names (e.g. ".something.Foo").
471
-			extName, err := p.consumeExtName()
472
-			if err != nil {
473
-				return err
471
+			tok = p.next()
472
+			if tok.err != nil {
473
+				return tok.err
474 474
 			}
475
-
476
-			if s := strings.LastIndex(extName, "/"); s >= 0 {
477
-				// If it contains a slash, it's an Any type URL.
478
-				messageName := extName[s+1:]
479
-				mt := MessageType(messageName)
480
-				if mt == nil {
481
-					return p.errorf("unrecognized message %q in google.protobuf.Any", messageName)
482
-				}
483
-				tok = p.next()
484
-				if tok.err != nil {
485
-					return tok.err
486
-				}
487
-				// consume an optional colon
488
-				if tok.value == ":" {
489
-					tok = p.next()
490
-					if tok.err != nil {
491
-						return tok.err
492
-					}
493
-				}
494
-				var terminator string
495
-				switch tok.value {
496
-				case "<":
497
-					terminator = ">"
498
-				case "{":
499
-					terminator = "}"
500
-				default:
501
-					return p.errorf("expected '{' or '<', found %q", tok.value)
502
-				}
503
-				v := reflect.New(mt.Elem())
504
-				if pe := p.readStruct(v.Elem(), terminator); pe != nil {
505
-					return pe
506
-				}
507
-				b, err := Marshal(v.Interface().(Message))
508
-				if err != nil {
509
-					return p.errorf("failed to marshal message of type %q: %v", messageName, err)
510
-				}
511
-				sv.FieldByName("TypeUrl").SetString(extName)
512
-				sv.FieldByName("Value").SetBytes(b)
513
-				continue
514
-			}
515
-
516 475
 			var desc *ExtensionDesc
517 476
 			// This could be faster, but it's functional.
518 477
 			// TODO: Do something smarter than a linear scan.
519 478
 			for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) {
520
-				if d.Name == extName {
479
+				if d.Name == tok.value {
521 480
 					desc = d
522 481
 					break
523 482
 				}
524 483
 			}
525 484
 			if desc == nil {
526
-				return p.errorf("unrecognized extension %q", extName)
485
+				return p.errorf("unrecognized extension %q", tok.value)
486
+			}
487
+			// Check the extension terminator.
488
+			tok = p.next()
489
+			if tok.err != nil {
490
+				return tok.err
491
+			}
492
+			if tok.value != "]" {
493
+				return p.errorf("unrecognized extension terminator %q", tok.value)
527 494
 			}
528 495
 
529 496
 			props := &Properties{}
... ...
@@ -679,35 +643,6 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
679 679
 	return reqFieldErr
680 680
 }
681 681
 
682
-// consumeExtName consumes extension name or expanded Any type URL and the
683
-// following ']'. It returns the name or URL consumed.
684
-func (p *textParser) consumeExtName() (string, error) {
685
-	tok := p.next()
686
-	if tok.err != nil {
687
-		return "", tok.err
688
-	}
689
-
690
-	// If extension name or type url is quoted, it's a single token.
691
-	if len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] {
692
-		name, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0]))
693
-		if err != nil {
694
-			return "", err
695
-		}
696
-		return name, p.consumeToken("]")
697
-	}
698
-
699
-	// Consume everything up to "]"
700
-	var parts []string
701
-	for tok.value != "]" {
702
-		parts = append(parts, tok.value)
703
-		tok = p.next()
704
-		if tok.err != nil {
705
-			return "", p.errorf("unrecognized type_url or extension name: %s", tok.err)
706
-		}
707
-	}
708
-	return strings.Join(parts, ""), nil
709
-}
710
-
711 682
 // consumeOptionalSeparator consumes an optional semicolon or comma.
712 683
 // It is used in readStruct to provide backward compatibility.
713 684
 func (p *textParser) consumeOptionalSeparator() error {
... ...
@@ -189,7 +189,7 @@ func Background() Context {
189 189
 }
190 190
 
191 191
 // TODO returns a non-nil, empty Context.  Code should use context.TODO when
192
-// it's unclear which Context to use or it's is not yet available (because the
192
+// it's unclear which Context to use or it is not yet available (because the
193 193
 // surrounding function has not yet been extended to accept a Context
194 194
 // parameter).  TODO is recognized by static analysis tools that determine
195 195
 // whether Contexts are propagated correctly in a program.
... ...
@@ -210,13 +210,13 @@ type CancelFunc func()
210 210
 // call cancel as soon as the operations running in this Context complete.
211 211
 func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
212 212
 	c := newCancelCtx(parent)
213
-	propagateCancel(parent, &c)
214
-	return &c, func() { c.cancel(true, Canceled) }
213
+	propagateCancel(parent, c)
214
+	return c, func() { c.cancel(true, Canceled) }
215 215
 }
216 216
 
217 217
 // newCancelCtx returns an initialized cancelCtx.
218
-func newCancelCtx(parent Context) cancelCtx {
219
-	return cancelCtx{
218
+func newCancelCtx(parent Context) *cancelCtx {
219
+	return &cancelCtx{
220 220
 		Context: parent,
221 221
 		done:    make(chan struct{}),
222 222
 	}
... ...
@@ -259,7 +259,7 @@ func parentCancelCtx(parent Context) (*cancelCtx, bool) {
259 259
 		case *cancelCtx:
260 260
 			return c, true
261 261
 		case *timerCtx:
262
-			return &c.cancelCtx, true
262
+			return c.cancelCtx, true
263 263
 		case *valueCtx:
264 264
 			parent = c.Context
265 265
 		default:
... ...
@@ -377,7 +377,7 @@ func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
377 377
 // implement Done and Err.  It implements cancel by stopping its timer then
378 378
 // delegating to cancelCtx.cancel.
379 379
 type timerCtx struct {
380
-	cancelCtx
380
+	*cancelCtx
381 381
 	timer *time.Timer // Under cancelCtx.mu.
382 382
 
383 383
 	deadline time.Time
... ...
@@ -9,6 +9,7 @@ package ctxhttp
9 9
 import "net/http"
10 10
 
11 11
 func canceler(client *http.Client, req *http.Request) func() {
12
+	// TODO(djd): Respect any existing value of req.Cancel.
12 13
 	ch := make(chan struct{})
13 14
 	req.Cancel = ch
14 15
 
... ...
@@ -14,6 +14,14 @@ import (
14 14
 	"golang.org/x/net/context"
15 15
 )
16 16
 
17
+func nop() {}
18
+
19
+var (
20
+	testHookContextDoneBeforeHeaders = nop
21
+	testHookDoReturned               = nop
22
+	testHookDidBodyClose             = nop
23
+)
24
+
17 25
 // Do sends an HTTP request with the provided http.Client and returns an HTTP response.
18 26
 // If the client is nil, http.DefaultClient is used.
19 27
 // If the context is canceled or times out, ctx.Err() will be returned.
... ...
@@ -31,18 +39,51 @@ func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Resp
31 31
 	}
32 32
 	result := make(chan responseAndError, 1)
33 33
 
34
+	// Make local copies of test hooks closed over by goroutines below.
35
+	// Prevents data races in tests.
36
+	testHookDoReturned := testHookDoReturned
37
+	testHookDidBodyClose := testHookDidBodyClose
38
+
34 39
 	go func() {
35 40
 		resp, err := client.Do(req)
41
+		testHookDoReturned()
36 42
 		result <- responseAndError{resp, err}
37 43
 	}()
38 44
 
45
+	var resp *http.Response
46
+
39 47
 	select {
40 48
 	case <-ctx.Done():
49
+		testHookContextDoneBeforeHeaders()
41 50
 		cancel()
51
+		// Clean up after the goroutine calling client.Do:
52
+		go func() {
53
+			if r := <-result; r.resp != nil {
54
+				testHookDidBodyClose()
55
+				r.resp.Body.Close()
56
+			}
57
+		}()
42 58
 		return nil, ctx.Err()
43 59
 	case r := <-result:
44
-		return r.resp, r.err
60
+		var err error
61
+		resp, err = r.resp, r.err
62
+		if err != nil {
63
+			return resp, err
64
+		}
45 65
 	}
66
+
67
+	c := make(chan struct{})
68
+	go func() {
69
+		select {
70
+		case <-ctx.Done():
71
+			cancel()
72
+		case <-c:
73
+			// The response's Body is closed.
74
+		}
75
+	}()
76
+	resp.Body = &notifyingReader{resp.Body, c}
77
+
78
+	return resp, nil
46 79
 }
47 80
 
48 81
 // Get issues a GET request via the Do function.
... ...
@@ -77,3 +118,28 @@ func Post(ctx context.Context, client *http.Client, url string, bodyType string,
77 77
 func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) {
78 78
 	return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
79 79
 }
80
+
81
+// notifyingReader is an io.ReadCloser that closes the notify channel after
82
+// Close is called or a Read fails on the underlying ReadCloser.
83
+type notifyingReader struct {
84
+	io.ReadCloser
85
+	notify chan<- struct{}
86
+}
87
+
88
+func (r *notifyingReader) Read(p []byte) (int, error) {
89
+	n, err := r.ReadCloser.Read(p)
90
+	if err != nil && r.notify != nil {
91
+		close(r.notify)
92
+		r.notify = nil
93
+	}
94
+	return n, err
95
+}
96
+
97
+func (r *notifyingReader) Close() error {
98
+	err := r.ReadCloser.Close()
99
+	if r.notify != nil {
100
+		close(r.notify)
101
+		r.notify = nil
102
+	}
103
+	return err
104
+}
... ...
@@ -17,8 +17,15 @@ RUN apt-get install -y --no-install-recommends \
17 17
        libcunit1-dev libssl-dev libxml2-dev libevent-dev \
18 18
        automake autoconf
19 19
 
20
+# The list of packages nghttp2 recommends for h2load:
21
+RUN apt-get install -y --no-install-recommends make binutils \
22
+        autoconf automake autotools-dev \
23
+        libtool pkg-config zlib1g-dev libcunit1-dev libssl-dev libxml2-dev \
24
+        libev-dev libevent-dev libjansson-dev libjemalloc-dev \
25
+        cython python3.4-dev python-setuptools
26
+
20 27
 # Note: setting NGHTTP2_VER before the git clone, so an old git clone isn't cached:
21
-ENV NGHTTP2_VER af24f8394e43f4
28
+ENV NGHTTP2_VER 895da9a
22 29
 RUN cd /root && git clone https://github.com/tatsuhiro-t/nghttp2.git
23 30
 
24 31
 WORKDIR /root/nghttp2
... ...
@@ -31,9 +38,9 @@ RUN make
31 31
 RUN make install
32 32
 
33 33
 WORKDIR /root
34
-RUN wget http://curl.haxx.se/download/curl-7.40.0.tar.gz
35
-RUN tar -zxvf curl-7.40.0.tar.gz
36
-WORKDIR /root/curl-7.40.0
34
+RUN wget http://curl.haxx.se/download/curl-7.45.0.tar.gz
35
+RUN tar -zxvf curl-7.45.0.tar.gz
36
+WORKDIR /root/curl-7.45.0
37 37
 RUN ./configure --with-ssl --with-nghttp2=/usr/local
38 38
 RUN make
39 39
 RUN make install
40 40
deleted file mode 100644
... ...
@@ -1,76 +0,0 @@
1
-// Copyright 2014 The Go Authors.
2
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
3
-// Licensed under the same terms as Go itself:
4
-// https://code.google.com/p/go/source/browse/LICENSE
5
-
6
-package http2
7
-
8
-import (
9
-	"errors"
10
-)
11
-
12
-// buffer is an io.ReadWriteCloser backed by a fixed size buffer.
13
-// It never allocates, but moves old data as new data is written.
14
-type buffer struct {
15
-	buf    []byte
16
-	r, w   int
17
-	closed bool
18
-	err    error // err to return to reader
19
-}
20
-
21
-var (
22
-	errReadEmpty   = errors.New("read from empty buffer")
23
-	errWriteClosed = errors.New("write on closed buffer")
24
-	errWriteFull   = errors.New("write on full buffer")
25
-)
26
-
27
-// Read copies bytes from the buffer into p.
28
-// It is an error to read when no data is available.
29
-func (b *buffer) Read(p []byte) (n int, err error) {
30
-	n = copy(p, b.buf[b.r:b.w])
31
-	b.r += n
32
-	if b.closed && b.r == b.w {
33
-		err = b.err
34
-	} else if b.r == b.w && n == 0 {
35
-		err = errReadEmpty
36
-	}
37
-	return n, err
38
-}
39
-
40
-// Len returns the number of bytes of the unread portion of the buffer.
41
-func (b *buffer) Len() int {
42
-	return b.w - b.r
43
-}
44
-
45
-// Write copies bytes from p into the buffer.
46
-// It is an error to write more data than the buffer can hold.
47
-func (b *buffer) Write(p []byte) (n int, err error) {
48
-	if b.closed {
49
-		return 0, errWriteClosed
50
-	}
51
-
52
-	// Slide existing data to beginning.
53
-	if b.r > 0 && len(p) > len(b.buf)-b.w {
54
-		copy(b.buf, b.buf[b.r:b.w])
55
-		b.w -= b.r
56
-		b.r = 0
57
-	}
58
-
59
-	// Write new data.
60
-	n = copy(b.buf[b.w:], p)
61
-	b.w += n
62
-	if n < len(p) {
63
-		err = errWriteFull
64
-	}
65
-	return n, err
66
-}
67
-
68
-// Close marks the buffer as closed. Future calls to Write will
69
-// return an error. Future calls to Read, once the buffer is
70
-// empty, will return err.
71
-func (b *buffer) Close(err error) {
72
-	if !b.closed {
73
-		b.closed = true
74
-		b.err = err
75
-	}
76
-}
77 1
new file mode 100644
... ...
@@ -0,0 +1,225 @@
0
+// Copyright 2015 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// Transport code's client connection pooling.
5
+
6
+package http2
7
+
8
+import (
9
+	"crypto/tls"
10
+	"net/http"
11
+	"sync"
12
+)
13
+
14
+// ClientConnPool manages a pool of HTTP/2 client connections.
15
+type ClientConnPool interface {
16
+	GetClientConn(req *http.Request, addr string) (*ClientConn, error)
17
+	MarkDead(*ClientConn)
18
+}
19
+
20
+// TODO: use singleflight for dialing and addConnCalls?
21
+type clientConnPool struct {
22
+	t *Transport
23
+
24
+	mu sync.Mutex // TODO: maybe switch to RWMutex
25
+	// TODO: add support for sharing conns based on cert names
26
+	// (e.g. share conn for googleapis.com and appspot.com)
27
+	conns        map[string][]*ClientConn // key is host:port
28
+	dialing      map[string]*dialCall     // currently in-flight dials
29
+	keys         map[*ClientConn][]string
30
+	addConnCalls map[string]*addConnCall // in-flight addConnIfNeede calls
31
+}
32
+
33
+func (p *clientConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) {
34
+	return p.getClientConn(req, addr, dialOnMiss)
35
+}
36
+
37
+const (
38
+	dialOnMiss   = true
39
+	noDialOnMiss = false
40
+)
41
+
42
+func (p *clientConnPool) getClientConn(_ *http.Request, addr string, dialOnMiss bool) (*ClientConn, error) {
43
+	p.mu.Lock()
44
+	for _, cc := range p.conns[addr] {
45
+		if cc.CanTakeNewRequest() {
46
+			p.mu.Unlock()
47
+			return cc, nil
48
+		}
49
+	}
50
+	if !dialOnMiss {
51
+		p.mu.Unlock()
52
+		return nil, ErrNoCachedConn
53
+	}
54
+	call := p.getStartDialLocked(addr)
55
+	p.mu.Unlock()
56
+	<-call.done
57
+	return call.res, call.err
58
+}
59
+
60
+// dialCall is an in-flight Transport dial call to a host.
61
+type dialCall struct {
62
+	p    *clientConnPool
63
+	done chan struct{} // closed when done
64
+	res  *ClientConn   // valid after done is closed
65
+	err  error         // valid after done is closed
66
+}
67
+
68
+// requires p.mu is held.
69
+func (p *clientConnPool) getStartDialLocked(addr string) *dialCall {
70
+	if call, ok := p.dialing[addr]; ok {
71
+		// A dial is already in-flight. Don't start another.
72
+		return call
73
+	}
74
+	call := &dialCall{p: p, done: make(chan struct{})}
75
+	if p.dialing == nil {
76
+		p.dialing = make(map[string]*dialCall)
77
+	}
78
+	p.dialing[addr] = call
79
+	go call.dial(addr)
80
+	return call
81
+}
82
+
83
+// run in its own goroutine.
84
+func (c *dialCall) dial(addr string) {
85
+	c.res, c.err = c.p.t.dialClientConn(addr)
86
+	close(c.done)
87
+
88
+	c.p.mu.Lock()
89
+	delete(c.p.dialing, addr)
90
+	if c.err == nil {
91
+		c.p.addConnLocked(addr, c.res)
92
+	}
93
+	c.p.mu.Unlock()
94
+}
95
+
96
+// addConnIfNeeded makes a NewClientConn out of c if a connection for key doesn't
97
+// already exist. It coalesces concurrent calls with the same key.
98
+// This is used by the http1 Transport code when it creates a new connection. Because
99
+// the http1 Transport doesn't de-dup TCP dials to outbound hosts (because it doesn't know
100
+// the protocol), it can get into a situation where it has multiple TLS connections.
101
+// This code decides which ones live or die.
102
+// The return value used is whether c was used.
103
+// c is never closed.
104
+func (p *clientConnPool) addConnIfNeeded(key string, t *Transport, c *tls.Conn) (used bool, err error) {
105
+	p.mu.Lock()
106
+	for _, cc := range p.conns[key] {
107
+		if cc.CanTakeNewRequest() {
108
+			p.mu.Unlock()
109
+			return false, nil
110
+		}
111
+	}
112
+	call, dup := p.addConnCalls[key]
113
+	if !dup {
114
+		if p.addConnCalls == nil {
115
+			p.addConnCalls = make(map[string]*addConnCall)
116
+		}
117
+		call = &addConnCall{
118
+			p:    p,
119
+			done: make(chan struct{}),
120
+		}
121
+		p.addConnCalls[key] = call
122
+		go call.run(t, key, c)
123
+	}
124
+	p.mu.Unlock()
125
+
126
+	<-call.done
127
+	if call.err != nil {
128
+		return false, call.err
129
+	}
130
+	return !dup, nil
131
+}
132
+
133
+type addConnCall struct {
134
+	p    *clientConnPool
135
+	done chan struct{} // closed when done
136
+	err  error
137
+}
138
+
139
+func (c *addConnCall) run(t *Transport, key string, tc *tls.Conn) {
140
+	cc, err := t.NewClientConn(tc)
141
+
142
+	p := c.p
143
+	p.mu.Lock()
144
+	if err != nil {
145
+		c.err = err
146
+	} else {
147
+		p.addConnLocked(key, cc)
148
+	}
149
+	delete(p.addConnCalls, key)
150
+	p.mu.Unlock()
151
+	close(c.done)
152
+}
153
+
154
+func (p *clientConnPool) addConn(key string, cc *ClientConn) {
155
+	p.mu.Lock()
156
+	p.addConnLocked(key, cc)
157
+	p.mu.Unlock()
158
+}
159
+
160
+// p.mu must be held
161
+func (p *clientConnPool) addConnLocked(key string, cc *ClientConn) {
162
+	for _, v := range p.conns[key] {
163
+		if v == cc {
164
+			return
165
+		}
166
+	}
167
+	if p.conns == nil {
168
+		p.conns = make(map[string][]*ClientConn)
169
+	}
170
+	if p.keys == nil {
171
+		p.keys = make(map[*ClientConn][]string)
172
+	}
173
+	p.conns[key] = append(p.conns[key], cc)
174
+	p.keys[cc] = append(p.keys[cc], key)
175
+}
176
+
177
+func (p *clientConnPool) MarkDead(cc *ClientConn) {
178
+	p.mu.Lock()
179
+	defer p.mu.Unlock()
180
+	for _, key := range p.keys[cc] {
181
+		vv, ok := p.conns[key]
182
+		if !ok {
183
+			continue
184
+		}
185
+		newList := filterOutClientConn(vv, cc)
186
+		if len(newList) > 0 {
187
+			p.conns[key] = newList
188
+		} else {
189
+			delete(p.conns, key)
190
+		}
191
+	}
192
+	delete(p.keys, cc)
193
+}
194
+
195
+func (p *clientConnPool) closeIdleConnections() {
196
+	p.mu.Lock()
197
+	defer p.mu.Unlock()
198
+	// TODO: don't close a cc if it was just added to the pool
199
+	// milliseconds ago and has never been used. There's currently
200
+	// a small race window with the HTTP/1 Transport's integration
201
+	// where it can add an idle conn just before using it, and
202
+	// somebody else can concurrently call CloseIdleConns and
203
+	// break some caller's RoundTrip.
204
+	for _, vv := range p.conns {
205
+		for _, cc := range vv {
206
+			cc.closeIfIdle()
207
+		}
208
+	}
209
+}
210
+
211
+func filterOutClientConn(in []*ClientConn, exclude *ClientConn) []*ClientConn {
212
+	out := in[:0]
213
+	for _, v := range in {
214
+		if v != exclude {
215
+			out = append(out, v)
216
+		}
217
+	}
218
+	// If we filtered it out, zero out the last item to prevent
219
+	// the GC from seeing it.
220
+	if len(in) != len(out) {
221
+		in[len(in)-1] = nil
222
+	}
223
+	return out
224
+}
0 225
new file mode 100644
... ...
@@ -0,0 +1,89 @@
0
+// Copyright 2015 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build go1.6
5
+
6
+package http2
7
+
8
+import (
9
+	"crypto/tls"
10
+	"fmt"
11
+	"net/http"
12
+)
13
+
14
+func configureTransport(t1 *http.Transport) (*Transport, error) {
15
+	connPool := new(clientConnPool)
16
+	t2 := &Transport{
17
+		ConnPool: noDialClientConnPool{connPool},
18
+		t1:       t1,
19
+	}
20
+	connPool.t = t2
21
+	if err := registerHTTPSProtocol(t1, noDialH2RoundTripper{t2}); err != nil {
22
+		return nil, err
23
+	}
24
+	if t1.TLSClientConfig == nil {
25
+		t1.TLSClientConfig = new(tls.Config)
26
+	}
27
+	if !strSliceContains(t1.TLSClientConfig.NextProtos, "h2") {
28
+		t1.TLSClientConfig.NextProtos = append([]string{"h2"}, t1.TLSClientConfig.NextProtos...)
29
+	}
30
+	if !strSliceContains(t1.TLSClientConfig.NextProtos, "http/1.1") {
31
+		t1.TLSClientConfig.NextProtos = append(t1.TLSClientConfig.NextProtos, "http/1.1")
32
+	}
33
+	upgradeFn := func(authority string, c *tls.Conn) http.RoundTripper {
34
+		addr := authorityAddr(authority)
35
+		if used, err := connPool.addConnIfNeeded(addr, t2, c); err != nil {
36
+			go c.Close()
37
+			return erringRoundTripper{err}
38
+		} else if !used {
39
+			// Turns out we don't need this c.
40
+			// For example, two goroutines made requests to the same host
41
+			// at the same time, both kicking off TCP dials. (since protocol
42
+			// was unknown)
43
+			go c.Close()
44
+		}
45
+		return t2
46
+	}
47
+	if m := t1.TLSNextProto; len(m) == 0 {
48
+		t1.TLSNextProto = map[string]func(string, *tls.Conn) http.RoundTripper{
49
+			"h2": upgradeFn,
50
+		}
51
+	} else {
52
+		m["h2"] = upgradeFn
53
+	}
54
+	return t2, nil
55
+}
56
+
57
+// registerHTTPSProtocol calls Transport.RegisterProtocol but
58
+// convering panics into errors.
59
+func registerHTTPSProtocol(t *http.Transport, rt http.RoundTripper) (err error) {
60
+	defer func() {
61
+		if e := recover(); e != nil {
62
+			err = fmt.Errorf("%v", e)
63
+		}
64
+	}()
65
+	t.RegisterProtocol("https", rt)
66
+	return nil
67
+}
68
+
69
+// noDialClientConnPool is an implementation of http2.ClientConnPool
70
+// which never dials.  We let the HTTP/1.1 client dial and use its TLS
71
+// connection instead.
72
+type noDialClientConnPool struct{ *clientConnPool }
73
+
74
+func (p noDialClientConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) {
75
+	return p.getClientConn(req, addr, noDialOnMiss)
76
+}
77
+
78
+// noDialH2RoundTripper is a RoundTripper which only tries to complete the request
79
+// if there's already has a cached connection to the host.
80
+type noDialH2RoundTripper struct{ t *Transport }
81
+
82
+func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
83
+	res, err := rt.t.RoundTrip(req)
84
+	if err == ErrNoCachedConn {
85
+		return nil, http.ErrSkipAltProtocol
86
+	}
87
+	return res, err
88
+}
... ...
@@ -1,11 +1,13 @@
1
-// Copyright 2014 The Go Authors.
2
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
3
-// Licensed under the same terms as Go itself:
4
-// https://code.google.com/p/go/source/browse/LICENSE
1
+// Copyright 2014 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
5 4
 
6 5
 package http2
7 6
 
8
-import "fmt"
7
+import (
8
+	"errors"
9
+	"fmt"
10
+)
9 11
 
10 12
 // An ErrCode is an unsigned 32-bit error code as defined in the HTTP/2 spec.
11 13
 type ErrCode uint32
... ...
@@ -76,3 +78,45 @@ func (e StreamError) Error() string {
76 76
 type goAwayFlowError struct{}
77 77
 
78 78
 func (goAwayFlowError) Error() string { return "connection exceeded flow control window size" }
79
+
80
+// connErrorReason wraps a ConnectionError with an informative error about why it occurs.
81
+
82
+// Errors of this type are only returned by the frame parser functions
83
+// and converted into ConnectionError(ErrCodeProtocol).
84
+type connError struct {
85
+	Code   ErrCode
86
+	Reason string
87
+}
88
+
89
+func (e connError) Error() string {
90
+	return fmt.Sprintf("http2: connection error: %v: %v", e.Code, e.Reason)
91
+}
92
+
93
+type pseudoHeaderError string
94
+
95
+func (e pseudoHeaderError) Error() string {
96
+	return fmt.Sprintf("invalid pseudo-header %q", string(e))
97
+}
98
+
99
+type duplicatePseudoHeaderError string
100
+
101
+func (e duplicatePseudoHeaderError) Error() string {
102
+	return fmt.Sprintf("duplicate pseudo-header %q", string(e))
103
+}
104
+
105
+type headerFieldNameError string
106
+
107
+func (e headerFieldNameError) Error() string {
108
+	return fmt.Sprintf("invalid header field name %q", string(e))
109
+}
110
+
111
+type headerFieldValueError string
112
+
113
+func (e headerFieldValueError) Error() string {
114
+	return fmt.Sprintf("invalid header field value %q", string(e))
115
+}
116
+
117
+var (
118
+	errMixPseudoHeaderTypes = errors.New("mix of request and response pseudo headers")
119
+	errPseudoAfterRegular   = errors.New("pseudo header field after regular")
120
+)
79 121
new file mode 100644
... ...
@@ -0,0 +1,60 @@
0
+// Copyright 2014 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+package http2
5
+
6
+import (
7
+	"errors"
8
+)
9
+
10
+// fixedBuffer is an io.ReadWriter backed by a fixed size buffer.
11
+// It never allocates, but moves old data as new data is written.
12
+type fixedBuffer struct {
13
+	buf  []byte
14
+	r, w int
15
+}
16
+
17
+var (
18
+	errReadEmpty = errors.New("read from empty fixedBuffer")
19
+	errWriteFull = errors.New("write on full fixedBuffer")
20
+)
21
+
22
+// Read copies bytes from the buffer into p.
23
+// It is an error to read when no data is available.
24
+func (b *fixedBuffer) Read(p []byte) (n int, err error) {
25
+	if b.r == b.w {
26
+		return 0, errReadEmpty
27
+	}
28
+	n = copy(p, b.buf[b.r:b.w])
29
+	b.r += n
30
+	if b.r == b.w {
31
+		b.r = 0
32
+		b.w = 0
33
+	}
34
+	return n, nil
35
+}
36
+
37
+// Len returns the number of bytes of the unread portion of the buffer.
38
+func (b *fixedBuffer) Len() int {
39
+	return b.w - b.r
40
+}
41
+
42
+// Write copies bytes from p into the buffer.
43
+// It is an error to write more data than the buffer can hold.
44
+func (b *fixedBuffer) Write(p []byte) (n int, err error) {
45
+	// Slide existing data to beginning.
46
+	if b.r > 0 && len(p) > len(b.buf)-b.w {
47
+		copy(b.buf, b.buf[b.r:b.w])
48
+		b.w -= b.r
49
+		b.r = 0
50
+	}
51
+
52
+	// Write new data.
53
+	n = copy(b.buf[b.w:], p)
54
+	b.w += n
55
+	if n < len(p) {
56
+		err = errWriteFull
57
+	}
58
+	return n, err
59
+}
... ...
@@ -1,7 +1,6 @@
1
-// Copyright 2014 The Go Authors.
2
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
3
-// Licensed under the same terms as Go itself:
4
-// https://code.google.com/p/go/source/browse/LICENSE
1
+// Copyright 2014 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
5 4
 
6 5
 // Flow control
7 6
 
... ...
@@ -1,7 +1,6 @@
1
-// Copyright 2014 The Go Authors.
2
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
3
-// Licensed under the same terms as Go itself:
4
-// https://code.google.com/p/go/source/browse/LICENSE
1
+// Copyright 2014 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
5 4
 
6 5
 package http2
7 6
 
... ...
@@ -11,7 +10,11 @@ import (
11 11
 	"errors"
12 12
 	"fmt"
13 13
 	"io"
14
+	"log"
15
+	"strings"
14 16
 	"sync"
17
+
18
+	"golang.org/x/net/http2/hpack"
15 19
 )
16 20
 
17 21
 const frameHeaderLen = 9
... ...
@@ -172,6 +175,12 @@ func (h FrameHeader) Header() FrameHeader { return h }
172 172
 func (h FrameHeader) String() string {
173 173
 	var buf bytes.Buffer
174 174
 	buf.WriteString("[FrameHeader ")
175
+	h.writeDebug(&buf)
176
+	buf.WriteByte(']')
177
+	return buf.String()
178
+}
179
+
180
+func (h FrameHeader) writeDebug(buf *bytes.Buffer) {
175 181
 	buf.WriteString(h.Type.String())
176 182
 	if h.Flags != 0 {
177 183
 		buf.WriteString(" flags=")
... ...
@@ -188,15 +197,14 @@ func (h FrameHeader) String() string {
188 188
 			if name != "" {
189 189
 				buf.WriteString(name)
190 190
 			} else {
191
-				fmt.Fprintf(&buf, "0x%x", 1<<i)
191
+				fmt.Fprintf(buf, "0x%x", 1<<i)
192 192
 			}
193 193
 		}
194 194
 	}
195 195
 	if h.StreamID != 0 {
196
-		fmt.Fprintf(&buf, " stream=%d", h.StreamID)
196
+		fmt.Fprintf(buf, " stream=%d", h.StreamID)
197 197
 	}
198
-	fmt.Fprintf(&buf, " len=%d]", h.Length)
199
-	return buf.String()
198
+	fmt.Fprintf(buf, " len=%d", h.Length)
200 199
 }
201 200
 
202 201
 func (h *FrameHeader) checkValid() {
... ...
@@ -256,6 +264,11 @@ type Frame interface {
256 256
 type Framer struct {
257 257
 	r         io.Reader
258 258
 	lastFrame Frame
259
+	errDetail error
260
+
261
+	// lastHeaderStream is non-zero if the last frame was an
262
+	// unfinished HEADERS/CONTINUATION.
263
+	lastHeaderStream uint32
259 264
 
260 265
 	maxReadSize uint32
261 266
 	headerBuf   [frameHeaderLen]byte
... ...
@@ -272,18 +285,48 @@ type Framer struct {
272 272
 	wbuf []byte
273 273
 
274 274
 	// AllowIllegalWrites permits the Framer's Write methods to
275
-	// write frames that do not conform to the HTTP/2 spec.  This
275
+	// write frames that do not conform to the HTTP/2 spec. This
276 276
 	// permits using the Framer to test other HTTP/2
277 277
 	// implementations' conformance to the spec.
278 278
 	// If false, the Write methods will prefer to return an error
279 279
 	// rather than comply.
280 280
 	AllowIllegalWrites bool
281 281
 
282
+	// AllowIllegalReads permits the Framer's ReadFrame method
283
+	// to return non-compliant frames or frame orders.
284
+	// This is for testing and permits using the Framer to test
285
+	// other HTTP/2 implementations' conformance to the spec.
286
+	// It is not compatible with ReadMetaHeaders.
287
+	AllowIllegalReads bool
288
+
289
+	// ReadMetaHeaders if non-nil causes ReadFrame to merge
290
+	// HEADERS and CONTINUATION frames together and return
291
+	// MetaHeadersFrame instead.
292
+	ReadMetaHeaders *hpack.Decoder
293
+
294
+	// MaxHeaderListSize is the http2 MAX_HEADER_LIST_SIZE.
295
+	// It's used only if ReadMetaHeaders is set; 0 means a sane default
296
+	// (currently 16MB)
297
+	// If the limit is hit, MetaHeadersFrame.Truncated is set true.
298
+	MaxHeaderListSize uint32
299
+
282 300
 	// TODO: track which type of frame & with which flags was sent
283 301
 	// last.  Then return an error (unless AllowIllegalWrites) if
284 302
 	// we're in the middle of a header block and a
285 303
 	// non-Continuation or Continuation on a different stream is
286 304
 	// attempted to be written.
305
+
306
+	logReads bool
307
+
308
+	debugFramer    *Framer // only use for logging written writes
309
+	debugFramerBuf *bytes.Buffer
310
+}
311
+
312
+func (fr *Framer) maxHeaderListSize() uint32 {
313
+	if fr.MaxHeaderListSize == 0 {
314
+		return 16 << 20 // sane default, per docs
315
+	}
316
+	return fr.MaxHeaderListSize
287 317
 }
288 318
 
289 319
 func (f *Framer) startWrite(ftype FrameType, flags Flags, streamID uint32) {
... ...
@@ -311,6 +354,10 @@ func (f *Framer) endWrite() error {
311 311
 		byte(length>>16),
312 312
 		byte(length>>8),
313 313
 		byte(length))
314
+	if logFrameWrites {
315
+		f.logWrite()
316
+	}
317
+
314 318
 	n, err := f.w.Write(f.wbuf)
315 319
 	if err == nil && n != len(f.wbuf) {
316 320
 		err = io.ErrShortWrite
... ...
@@ -318,6 +365,24 @@ func (f *Framer) endWrite() error {
318 318
 	return err
319 319
 }
320 320
 
321
+func (f *Framer) logWrite() {
322
+	if f.debugFramer == nil {
323
+		f.debugFramerBuf = new(bytes.Buffer)
324
+		f.debugFramer = NewFramer(nil, f.debugFramerBuf)
325
+		f.debugFramer.logReads = false // we log it ourselves, saying "wrote" below
326
+		// Let us read anything, even if we accidentally wrote it
327
+		// in the wrong order:
328
+		f.debugFramer.AllowIllegalReads = true
329
+	}
330
+	f.debugFramerBuf.Write(f.wbuf)
331
+	fr, err := f.debugFramer.ReadFrame()
332
+	if err != nil {
333
+		log.Printf("http2: Framer %p: failed to decode just-written frame", f)
334
+		return
335
+	}
336
+	log.Printf("http2: Framer %p: wrote %v", f, summarizeFrame(fr))
337
+}
338
+
321 339
 func (f *Framer) writeByte(v byte)     { f.wbuf = append(f.wbuf, v) }
322 340
 func (f *Framer) writeBytes(v []byte)  { f.wbuf = append(f.wbuf, v...) }
323 341
 func (f *Framer) writeUint16(v uint16) { f.wbuf = append(f.wbuf, byte(v>>8), byte(v)) }
... ...
@@ -333,8 +398,9 @@ const (
333 333
 // NewFramer returns a Framer that writes frames to w and reads them from r.
334 334
 func NewFramer(w io.Writer, r io.Reader) *Framer {
335 335
 	fr := &Framer{
336
-		w: w,
337
-		r: r,
336
+		w:        w,
337
+		r:        r,
338
+		logReads: logFrameReads,
338 339
 	}
339 340
 	fr.getReadBuf = func(size uint32) []byte {
340 341
 		if cap(fr.readBuf) >= int(size) {
... ...
@@ -358,15 +424,39 @@ func (fr *Framer) SetMaxReadFrameSize(v uint32) {
358 358
 	fr.maxReadSize = v
359 359
 }
360 360
 
361
+// ErrorDetail returns a more detailed error of the last error
362
+// returned by Framer.ReadFrame. For instance, if ReadFrame
363
+// returns a StreamError with code PROTOCOL_ERROR, ErrorDetail
364
+// will say exactly what was invalid. ErrorDetail is not guaranteed
365
+// to return a non-nil value and like the rest of the http2 package,
366
+// its return value is not protected by an API compatibility promise.
367
+// ErrorDetail is reset after the next call to ReadFrame.
368
+func (fr *Framer) ErrorDetail() error {
369
+	return fr.errDetail
370
+}
371
+
361 372
 // ErrFrameTooLarge is returned from Framer.ReadFrame when the peer
362 373
 // sends a frame that is larger than declared with SetMaxReadFrameSize.
363 374
 var ErrFrameTooLarge = errors.New("http2: frame too large")
364 375
 
376
+// terminalReadFrameError reports whether err is an unrecoverable
377
+// error from ReadFrame and no other frames should be read.
378
+func terminalReadFrameError(err error) bool {
379
+	if _, ok := err.(StreamError); ok {
380
+		return false
381
+	}
382
+	return err != nil
383
+}
384
+
365 385
 // ReadFrame reads a single frame. The returned Frame is only valid
366 386
 // until the next call to ReadFrame.
367
-// If the frame is larger than previously set with SetMaxReadFrameSize,
368
-// the returned error is ErrFrameTooLarge.
387
+//
388
+// If the frame is larger than previously set with SetMaxReadFrameSize, the
389
+// returned error is ErrFrameTooLarge. Other errors may be of type
390
+// ConnectionError, StreamError, or anything else from from the underlying
391
+// reader.
369 392
 func (fr *Framer) ReadFrame() (Frame, error) {
393
+	fr.errDetail = nil
370 394
 	if fr.lastFrame != nil {
371 395
 		fr.lastFrame.invalidate()
372 396
 	}
... ...
@@ -383,12 +473,71 @@ func (fr *Framer) ReadFrame() (Frame, error) {
383 383
 	}
384 384
 	f, err := typeFrameParser(fh.Type)(fh, payload)
385 385
 	if err != nil {
386
+		if ce, ok := err.(connError); ok {
387
+			return nil, fr.connError(ce.Code, ce.Reason)
388
+		}
386 389
 		return nil, err
387 390
 	}
388
-	fr.lastFrame = f
391
+	if err := fr.checkFrameOrder(f); err != nil {
392
+		return nil, err
393
+	}
394
+	if fr.logReads {
395
+		log.Printf("http2: Framer %p: read %v", fr, summarizeFrame(f))
396
+	}
397
+	if fh.Type == FrameHeaders && fr.ReadMetaHeaders != nil {
398
+		return fr.readMetaFrame(f.(*HeadersFrame))
399
+	}
389 400
 	return f, nil
390 401
 }
391 402
 
403
+// connError returns ConnectionError(code) but first
404
+// stashes away a public reason to the caller can optionally relay it
405
+// to the peer before hanging up on them. This might help others debug
406
+// their implementations.
407
+func (fr *Framer) connError(code ErrCode, reason string) error {
408
+	fr.errDetail = errors.New(reason)
409
+	return ConnectionError(code)
410
+}
411
+
412
+// checkFrameOrder reports an error if f is an invalid frame to return
413
+// next from ReadFrame. Mostly it checks whether HEADERS and
414
+// CONTINUATION frames are contiguous.
415
+func (fr *Framer) checkFrameOrder(f Frame) error {
416
+	last := fr.lastFrame
417
+	fr.lastFrame = f
418
+	if fr.AllowIllegalReads {
419
+		return nil
420
+	}
421
+
422
+	fh := f.Header()
423
+	if fr.lastHeaderStream != 0 {
424
+		if fh.Type != FrameContinuation {
425
+			return fr.connError(ErrCodeProtocol,
426
+				fmt.Sprintf("got %s for stream %d; expected CONTINUATION following %s for stream %d",
427
+					fh.Type, fh.StreamID,
428
+					last.Header().Type, fr.lastHeaderStream))
429
+		}
430
+		if fh.StreamID != fr.lastHeaderStream {
431
+			return fr.connError(ErrCodeProtocol,
432
+				fmt.Sprintf("got CONTINUATION for stream %d; expected stream %d",
433
+					fh.StreamID, fr.lastHeaderStream))
434
+		}
435
+	} else if fh.Type == FrameContinuation {
436
+		return fr.connError(ErrCodeProtocol, fmt.Sprintf("unexpected CONTINUATION for stream %d", fh.StreamID))
437
+	}
438
+
439
+	switch fh.Type {
440
+	case FrameHeaders, FrameContinuation:
441
+		if fh.Flags.Has(FlagHeadersEndHeaders) {
442
+			fr.lastHeaderStream = 0
443
+		} else {
444
+			fr.lastHeaderStream = fh.StreamID
445
+		}
446
+	}
447
+
448
+	return nil
449
+}
450
+
392 451
 // A DataFrame conveys arbitrary, variable-length sequences of octets
393 452
 // associated with a stream.
394 453
 // See http://http2.github.io/http2-spec/#rfc.section.6.1
... ...
@@ -417,7 +566,7 @@ func parseDataFrame(fh FrameHeader, payload []byte) (Frame, error) {
417 417
 		// field is 0x0, the recipient MUST respond with a
418 418
 		// connection error (Section 5.4.1) of type
419 419
 		// PROTOCOL_ERROR.
420
-		return nil, ConnectionError(ErrCodeProtocol)
420
+		return nil, connError{ErrCodeProtocol, "DATA frame with stream ID 0"}
421 421
 	}
422 422
 	f := &DataFrame{
423 423
 		FrameHeader: fh,
... ...
@@ -435,7 +584,7 @@ func parseDataFrame(fh FrameHeader, payload []byte) (Frame, error) {
435 435
 		// length of the frame payload, the recipient MUST
436 436
 		// treat this as a connection error.
437 437
 		// Filed: https://github.com/http2/http2-spec/issues/610
438
-		return nil, ConnectionError(ErrCodeProtocol)
438
+		return nil, connError{ErrCodeProtocol, "pad size larger than data payload"}
439 439
 	}
440 440
 	f.data = payload[:len(payload)-int(padSize)]
441 441
 	return f, nil
... ...
@@ -575,6 +724,8 @@ type PingFrame struct {
575 575
 	Data [8]byte
576 576
 }
577 577
 
578
+func (f *PingFrame) IsAck() bool { return f.Flags.Has(FlagPingAck) }
579
+
578 580
 func parsePingFrame(fh FrameHeader, payload []byte) (Frame, error) {
579 581
 	if len(payload) != 8 {
580 582
 		return nil, ConnectionError(ErrCodeFrameSize)
... ...
@@ -663,7 +814,7 @@ func parseUnknownFrame(fh FrameHeader, p []byte) (Frame, error) {
663 663
 // See http://http2.github.io/http2-spec/#rfc.section.6.9
664 664
 type WindowUpdateFrame struct {
665 665
 	FrameHeader
666
-	Increment uint32
666
+	Increment uint32 // never read with high bit set
667 667
 }
668 668
 
669 669
 func parseWindowUpdateFrame(fh FrameHeader, p []byte) (Frame, error) {
... ...
@@ -740,7 +891,7 @@ func parseHeadersFrame(fh FrameHeader, p []byte) (_ Frame, err error) {
740 740
 		// is received whose stream identifier field is 0x0, the recipient MUST
741 741
 		// respond with a connection error (Section 5.4.1) of type
742 742
 		// PROTOCOL_ERROR.
743
-		return nil, ConnectionError(ErrCodeProtocol)
743
+		return nil, connError{ErrCodeProtocol, "HEADERS frame with stream ID 0"}
744 744
 	}
745 745
 	var padLength uint8
746 746
 	if fh.Flags.Has(FlagHeadersPadded) {
... ...
@@ -870,10 +1021,10 @@ func (p PriorityParam) IsZero() bool {
870 870
 
871 871
 func parsePriorityFrame(fh FrameHeader, payload []byte) (Frame, error) {
872 872
 	if fh.StreamID == 0 {
873
-		return nil, ConnectionError(ErrCodeProtocol)
873
+		return nil, connError{ErrCodeProtocol, "PRIORITY frame with stream ID 0"}
874 874
 	}
875 875
 	if len(payload) != 5 {
876
-		return nil, ConnectionError(ErrCodeFrameSize)
876
+		return nil, connError{ErrCodeFrameSize, fmt.Sprintf("PRIORITY frame payload size was %d; want 5", len(payload))}
877 877
 	}
878 878
 	v := binary.BigEndian.Uint32(payload[:4])
879 879
 	streamID := v & 0x7fffffff // mask off high bit
... ...
@@ -943,13 +1094,12 @@ type ContinuationFrame struct {
943 943
 }
944 944
 
945 945
 func parseContinuationFrame(fh FrameHeader, p []byte) (Frame, error) {
946
+	if fh.StreamID == 0 {
947
+		return nil, connError{ErrCodeProtocol, "CONTINUATION frame with stream ID 0"}
948
+	}
946 949
 	return &ContinuationFrame{fh, p}, nil
947 950
 }
948 951
 
949
-func (f *ContinuationFrame) StreamEnded() bool {
950
-	return f.FrameHeader.Flags.Has(FlagDataEndStream)
951
-}
952
-
953 952
 func (f *ContinuationFrame) HeaderBlockFragment() []byte {
954 953
 	f.checkValid()
955 954
 	return f.headerFragBuf
... ...
@@ -1111,3 +1261,236 @@ type streamEnder interface {
1111 1111
 type headersEnder interface {
1112 1112
 	HeadersEnded() bool
1113 1113
 }
1114
+
1115
+type headersOrContinuation interface {
1116
+	headersEnder
1117
+	HeaderBlockFragment() []byte
1118
+}
1119
+
1120
+// A MetaHeadersFrame is the representation of one HEADERS frame and
1121
+// zero or more contiguous CONTINUATION frames and the decoding of
1122
+// their HPACK-encoded contents.
1123
+//
1124
+// This type of frame does not appear on the wire and is only returned
1125
+// by the Framer when Framer.ReadMetaHeaders is set.
1126
+type MetaHeadersFrame struct {
1127
+	*HeadersFrame
1128
+
1129
+	// Fields are the fields contained in the HEADERS and
1130
+	// CONTINUATION frames. The underlying slice is owned by the
1131
+	// Framer and must not be retained after the next call to
1132
+	// ReadFrame.
1133
+	//
1134
+	// Fields are guaranteed to be in the correct http2 order and
1135
+	// not have unknown pseudo header fields or invalid header
1136
+	// field names or values. Required pseudo header fields may be
1137
+	// missing, however. Use the MetaHeadersFrame.Pseudo accessor
1138
+	// method access pseudo headers.
1139
+	Fields []hpack.HeaderField
1140
+
1141
+	// Truncated is whether the max header list size limit was hit
1142
+	// and Fields is incomplete. The hpack decoder state is still
1143
+	// valid, however.
1144
+	Truncated bool
1145
+}
1146
+
1147
+// PseudoValue returns the given pseudo header field's value.
1148
+// The provided pseudo field should not contain the leading colon.
1149
+func (mh *MetaHeadersFrame) PseudoValue(pseudo string) string {
1150
+	for _, hf := range mh.Fields {
1151
+		if !hf.IsPseudo() {
1152
+			return ""
1153
+		}
1154
+		if hf.Name[1:] == pseudo {
1155
+			return hf.Value
1156
+		}
1157
+	}
1158
+	return ""
1159
+}
1160
+
1161
+// RegularFields returns the regular (non-pseudo) header fields of mh.
1162
+// The caller does not own the returned slice.
1163
+func (mh *MetaHeadersFrame) RegularFields() []hpack.HeaderField {
1164
+	for i, hf := range mh.Fields {
1165
+		if !hf.IsPseudo() {
1166
+			return mh.Fields[i:]
1167
+		}
1168
+	}
1169
+	return nil
1170
+}
1171
+
1172
+// PseudoFields returns the pseudo header fields of mh.
1173
+// The caller does not own the returned slice.
1174
+func (mh *MetaHeadersFrame) PseudoFields() []hpack.HeaderField {
1175
+	for i, hf := range mh.Fields {
1176
+		if !hf.IsPseudo() {
1177
+			return mh.Fields[:i]
1178
+		}
1179
+	}
1180
+	return mh.Fields
1181
+}
1182
+
1183
+func (mh *MetaHeadersFrame) checkPseudos() error {
1184
+	var isRequest, isResponse bool
1185
+	pf := mh.PseudoFields()
1186
+	for i, hf := range pf {
1187
+		switch hf.Name {
1188
+		case ":method", ":path", ":scheme", ":authority":
1189
+			isRequest = true
1190
+		case ":status":
1191
+			isResponse = true
1192
+		default:
1193
+			return pseudoHeaderError(hf.Name)
1194
+		}
1195
+		// Check for duplicates.
1196
+		// This would be a bad algorithm, but N is 4.
1197
+		// And this doesn't allocate.
1198
+		for _, hf2 := range pf[:i] {
1199
+			if hf.Name == hf2.Name {
1200
+				return duplicatePseudoHeaderError(hf.Name)
1201
+			}
1202
+		}
1203
+	}
1204
+	if isRequest && isResponse {
1205
+		return errMixPseudoHeaderTypes
1206
+	}
1207
+	return nil
1208
+}
1209
+
1210
+func (fr *Framer) maxHeaderStringLen() int {
1211
+	v := fr.maxHeaderListSize()
1212
+	if uint32(int(v)) == v {
1213
+		return int(v)
1214
+	}
1215
+	// They had a crazy big number for MaxHeaderBytes anyway,
1216
+	// so give them unlimited header lengths:
1217
+	return 0
1218
+}
1219
+
1220
+// readMetaFrame returns 0 or more CONTINUATION frames from fr and
1221
+// merge them into into the provided hf and returns a MetaHeadersFrame
1222
+// with the decoded hpack values.
1223
+func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) {
1224
+	if fr.AllowIllegalReads {
1225
+		return nil, errors.New("illegal use of AllowIllegalReads with ReadMetaHeaders")
1226
+	}
1227
+	mh := &MetaHeadersFrame{
1228
+		HeadersFrame: hf,
1229
+	}
1230
+	var remainSize = fr.maxHeaderListSize()
1231
+	var sawRegular bool
1232
+
1233
+	var invalid error // pseudo header field errors
1234
+	hdec := fr.ReadMetaHeaders
1235
+	hdec.SetEmitEnabled(true)
1236
+	hdec.SetMaxStringLength(fr.maxHeaderStringLen())
1237
+	hdec.SetEmitFunc(func(hf hpack.HeaderField) {
1238
+		if !validHeaderFieldValue(hf.Value) {
1239
+			invalid = headerFieldValueError(hf.Value)
1240
+		}
1241
+		isPseudo := strings.HasPrefix(hf.Name, ":")
1242
+		if isPseudo {
1243
+			if sawRegular {
1244
+				invalid = errPseudoAfterRegular
1245
+			}
1246
+		} else {
1247
+			sawRegular = true
1248
+			if !validHeaderFieldName(hf.Name) {
1249
+				invalid = headerFieldNameError(hf.Name)
1250
+			}
1251
+		}
1252
+
1253
+		if invalid != nil {
1254
+			hdec.SetEmitEnabled(false)
1255
+			return
1256
+		}
1257
+
1258
+		size := hf.Size()
1259
+		if size > remainSize {
1260
+			hdec.SetEmitEnabled(false)
1261
+			mh.Truncated = true
1262
+			return
1263
+		}
1264
+		remainSize -= size
1265
+
1266
+		mh.Fields = append(mh.Fields, hf)
1267
+	})
1268
+	// Lose reference to MetaHeadersFrame:
1269
+	defer hdec.SetEmitFunc(func(hf hpack.HeaderField) {})
1270
+
1271
+	var hc headersOrContinuation = hf
1272
+	for {
1273
+		frag := hc.HeaderBlockFragment()
1274
+		if _, err := hdec.Write(frag); err != nil {
1275
+			return nil, ConnectionError(ErrCodeCompression)
1276
+		}
1277
+
1278
+		if hc.HeadersEnded() {
1279
+			break
1280
+		}
1281
+		if f, err := fr.ReadFrame(); err != nil {
1282
+			return nil, err
1283
+		} else {
1284
+			hc = f.(*ContinuationFrame) // guaranteed by checkFrameOrder
1285
+		}
1286
+	}
1287
+
1288
+	mh.HeadersFrame.headerFragBuf = nil
1289
+	mh.HeadersFrame.invalidate()
1290
+
1291
+	if err := hdec.Close(); err != nil {
1292
+		return nil, ConnectionError(ErrCodeCompression)
1293
+	}
1294
+	if invalid != nil {
1295
+		fr.errDetail = invalid
1296
+		return nil, StreamError{mh.StreamID, ErrCodeProtocol}
1297
+	}
1298
+	if err := mh.checkPseudos(); err != nil {
1299
+		fr.errDetail = err
1300
+		return nil, StreamError{mh.StreamID, ErrCodeProtocol}
1301
+	}
1302
+	return mh, nil
1303
+}
1304
+
1305
+func summarizeFrame(f Frame) string {
1306
+	var buf bytes.Buffer
1307
+	f.Header().writeDebug(&buf)
1308
+	switch f := f.(type) {
1309
+	case *SettingsFrame:
1310
+		n := 0
1311
+		f.ForeachSetting(func(s Setting) error {
1312
+			n++
1313
+			if n == 1 {
1314
+				buf.WriteString(", settings:")
1315
+			}
1316
+			fmt.Fprintf(&buf, " %v=%v,", s.ID, s.Val)
1317
+			return nil
1318
+		})
1319
+		if n > 0 {
1320
+			buf.Truncate(buf.Len() - 1) // remove trailing comma
1321
+		}
1322
+	case *DataFrame:
1323
+		data := f.Data()
1324
+		const max = 256
1325
+		if len(data) > max {
1326
+			data = data[:max]
1327
+		}
1328
+		fmt.Fprintf(&buf, " data=%q", data)
1329
+		if len(f.Data()) > max {
1330
+			fmt.Fprintf(&buf, " (%d bytes omitted)", len(f.Data())-max)
1331
+		}
1332
+	case *WindowUpdateFrame:
1333
+		if f.StreamID == 0 {
1334
+			buf.WriteString(" (conn)")
1335
+		}
1336
+		fmt.Fprintf(&buf, " incr=%v", f.Increment)
1337
+	case *PingFrame:
1338
+		fmt.Fprintf(&buf, " ping=%q", f.Data[:])
1339
+	case *GoAwayFrame:
1340
+		fmt.Fprintf(&buf, " LastStreamID=%v ErrCode=%v Debug=%q",
1341
+			f.LastStreamID, f.ErrCode, f.debugData)
1342
+	case *RSTStreamFrame:
1343
+		fmt.Fprintf(&buf, " ErrCode=%v", f.ErrCode)
1344
+	}
1345
+	return buf.String()
1346
+}
1114 1347
new file mode 100644
... ...
@@ -0,0 +1,11 @@
0
+// Copyright 2015 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build go1.5
5
+
6
+package http2
7
+
8
+import "net/http"
9
+
10
+func requestCancel(req *http.Request) <-chan struct{} { return req.Cancel }
... ...
@@ -1,9 +1,6 @@
1 1
 // Copyright 2014 The Go Authors. All rights reserved.
2 2
 // Use of this source code is governed by a BSD-style
3 3
 // license that can be found in the LICENSE file.
4
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
5
-// Licensed under the same terms as Go itself:
6
-// https://code.google.com/p/go/source/browse/LICENSE
7 4
 
8 5
 // Defensive debug-only utility to track that functions run on the
9 6
 // goroutine that they're supposed to.
... ...
@@ -1,9 +1,6 @@
1 1
 // Copyright 2014 The Go Authors. All rights reserved.
2 2
 // Use of this source code is governed by a BSD-style
3 3
 // license that can be found in the LICENSE file.
4
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
5
-// Licensed under the same terms as Go itself:
6
-// https://code.google.com/p/go/source/browse/LICENSE
7 4
 
8 5
 package http2
9 6
 
... ...
@@ -60,6 +57,7 @@ func init() {
60 60
 		"server",
61 61
 		"set-cookie",
62 62
 		"strict-transport-security",
63
+		"trailer",
63 64
 		"transfer-encoding",
64 65
 		"user-agent",
65 66
 		"vary",
... ...
@@ -1,7 +1,6 @@
1
-// Copyright 2014 The Go Authors.
2
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
3
-// Licensed under the same terms as Go itself:
4
-// https://code.google.com/p/go/source/browse/LICENSE
1
+// Copyright 2014 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
5 4
 
6 5
 package hpack
7 6
 
... ...
@@ -145,7 +144,7 @@ func (e *Encoder) SetMaxDynamicTableSizeLimit(v uint32) {
145 145
 
146 146
 // shouldIndex reports whether f should be indexed.
147 147
 func (e *Encoder) shouldIndex(f HeaderField) bool {
148
-	return !f.Sensitive && f.size() <= e.dynTab.maxSize
148
+	return !f.Sensitive && f.Size() <= e.dynTab.maxSize
149 149
 }
150 150
 
151 151
 // appendIndexed appends index i, as encoded in "Indexed Header Field"
... ...
@@ -1,7 +1,6 @@
1
-// Copyright 2014 The Go Authors.
2
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
3
-// Licensed under the same terms as Go itself:
4
-// https://code.google.com/p/go/source/browse/LICENSE
1
+// Copyright 2014 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
5 4
 
6 5
 // Package hpack implements HPACK, a compression format for
7 6
 // efficiently representing HTTP header fields in the context of HTTP/2.
... ...
@@ -42,7 +41,24 @@ type HeaderField struct {
42 42
 	Sensitive bool
43 43
 }
44 44
 
45
-func (hf *HeaderField) size() uint32 {
45
+// IsPseudo reports whether the header field is an http2 pseudo header.
46
+// That is, it reports whether it starts with a colon.
47
+// It is not otherwise guaranteed to be a valid psuedo header field,
48
+// though.
49
+func (hf HeaderField) IsPseudo() bool {
50
+	return len(hf.Name) != 0 && hf.Name[0] == ':'
51
+}
52
+
53
+func (hf HeaderField) String() string {
54
+	var suffix string
55
+	if hf.Sensitive {
56
+		suffix = " (sensitive)"
57
+	}
58
+	return fmt.Sprintf("header field %q = %q%s", hf.Name, hf.Value, suffix)
59
+}
60
+
61
+// Size returns the size of an entry per RFC 7540 section 5.2.
62
+func (hf HeaderField) Size() uint32 {
46 63
 	// http://http2.github.io/http2-spec/compression.html#rfc.section.4.1
47 64
 	// "The size of the dynamic table is the sum of the size of
48 65
 	// its entries.  The size of an entry is the sum of its name's
... ...
@@ -64,23 +80,65 @@ type Decoder struct {
64 64
 	dynTab dynamicTable
65 65
 	emit   func(f HeaderField)
66 66
 
67
+	emitEnabled bool // whether calls to emit are enabled
68
+	maxStrLen   int  // 0 means unlimited
69
+
67 70
 	// buf is the unparsed buffer. It's only written to
68 71
 	// saveBuf if it was truncated in the middle of a header
69 72
 	// block. Because it's usually not owned, we can only
70 73
 	// process it under Write.
71
-	buf     []byte // usually not owned
74
+	buf []byte // not owned; only valid during Write
75
+
76
+	// saveBuf is previous data passed to Write which we weren't able
77
+	// to fully parse before. Unlike buf, we own this data.
72 78
 	saveBuf bytes.Buffer
73 79
 }
74 80
 
75
-func NewDecoder(maxSize uint32, emitFunc func(f HeaderField)) *Decoder {
81
+// NewDecoder returns a new decoder with the provided maximum dynamic
82
+// table size. The emitFunc will be called for each valid field
83
+// parsed, in the same goroutine as calls to Write, before Write returns.
84
+func NewDecoder(maxDynamicTableSize uint32, emitFunc func(f HeaderField)) *Decoder {
76 85
 	d := &Decoder{
77
-		emit: emitFunc,
86
+		emit:        emitFunc,
87
+		emitEnabled: true,
78 88
 	}
79
-	d.dynTab.allowedMaxSize = maxSize
80
-	d.dynTab.setMaxSize(maxSize)
89
+	d.dynTab.allowedMaxSize = maxDynamicTableSize
90
+	d.dynTab.setMaxSize(maxDynamicTableSize)
81 91
 	return d
82 92
 }
83 93
 
94
+// ErrStringLength is returned by Decoder.Write when the max string length
95
+// (as configured by Decoder.SetMaxStringLength) would be violated.
96
+var ErrStringLength = errors.New("hpack: string too long")
97
+
98
+// SetMaxStringLength sets the maximum size of a HeaderField name or
99
+// value string. If a string exceeds this length (even after any
100
+// decompression), Write will return ErrStringLength.
101
+// A value of 0 means unlimited and is the default from NewDecoder.
102
+func (d *Decoder) SetMaxStringLength(n int) {
103
+	d.maxStrLen = n
104
+}
105
+
106
+// SetEmitFunc changes the callback used when new header fields
107
+// are decoded.
108
+// It must be non-nil. It does not affect EmitEnabled.
109
+func (d *Decoder) SetEmitFunc(emitFunc func(f HeaderField)) {
110
+	d.emit = emitFunc
111
+}
112
+
113
+// SetEmitEnabled controls whether the emitFunc provided to NewDecoder
114
+// should be called. The default is true.
115
+//
116
+// This facility exists to let servers enforce MAX_HEADER_LIST_SIZE
117
+// while still decoding and keeping in-sync with decoder state, but
118
+// without doing unnecessary decompression or generating unnecessary
119
+// garbage for header fields past the limit.
120
+func (d *Decoder) SetEmitEnabled(v bool) { d.emitEnabled = v }
121
+
122
+// EmitEnabled reports whether calls to the emitFunc provided to NewDecoder
123
+// are currently enabled. The default is true.
124
+func (d *Decoder) EmitEnabled() bool { return d.emitEnabled }
125
+
84 126
 // TODO: add method *Decoder.Reset(maxSize, emitFunc) to let callers re-use Decoders and their
85 127
 // underlying buffers for garbage reasons.
86 128
 
... ...
@@ -122,7 +180,7 @@ func (dt *dynamicTable) setMaxSize(v uint32) {
122 122
 
123 123
 func (dt *dynamicTable) add(f HeaderField) {
124 124
 	dt.ents = append(dt.ents, f)
125
-	dt.size += f.size()
125
+	dt.size += f.Size()
126 126
 	dt.evict()
127 127
 }
128 128
 
... ...
@@ -130,7 +188,7 @@ func (dt *dynamicTable) add(f HeaderField) {
130 130
 func (dt *dynamicTable) evict() {
131 131
 	base := dt.ents // keep base pointer of slice
132 132
 	for dt.size > dt.maxSize {
133
-		dt.size -= dt.ents[0].size()
133
+		dt.size -= dt.ents[0].Size()
134 134
 		dt.ents = dt.ents[1:]
135 135
 	}
136 136
 
... ...
@@ -247,15 +305,23 @@ func (d *Decoder) Write(p []byte) (n int, err error) {
247 247
 
248 248
 	for len(d.buf) > 0 {
249 249
 		err = d.parseHeaderFieldRepr()
250
-		if err != nil {
251
-			if err == errNeedMore {
252
-				err = nil
253
-				d.saveBuf.Write(d.buf)
250
+		if err == errNeedMore {
251
+			// Extra paranoia, making sure saveBuf won't
252
+			// get too large.  All the varint and string
253
+			// reading code earlier should already catch
254
+			// overlong things and return ErrStringLength,
255
+			// but keep this as a last resort.
256
+			const varIntOverhead = 8 // conservative
257
+			if d.maxStrLen != 0 && int64(len(d.buf)) > 2*(int64(d.maxStrLen)+varIntOverhead) {
258
+				return 0, ErrStringLength
254 259
 			}
260
+			d.saveBuf.Write(d.buf)
261
+			return len(p), nil
262
+		}
263
+		if err != nil {
255 264
 			break
256 265
 		}
257 266
 	}
258
-
259 267
 	return len(p), err
260 268
 }
261 269
 
... ...
@@ -323,9 +389,8 @@ func (d *Decoder) parseFieldIndexed() error {
323 323
 	if !ok {
324 324
 		return DecodingError{InvalidIndexError(idx)}
325 325
 	}
326
-	d.emit(HeaderField{Name: hf.Name, Value: hf.Value})
327 326
 	d.buf = buf
328
-	return nil
327
+	return d.callEmit(HeaderField{Name: hf.Name, Value: hf.Value})
329 328
 }
330 329
 
331 330
 // (same invariants and behavior as parseHeaderFieldRepr)
... ...
@@ -337,6 +402,7 @@ func (d *Decoder) parseFieldLiteral(n uint8, it indexType) error {
337 337
 	}
338 338
 
339 339
 	var hf HeaderField
340
+	wantStr := d.emitEnabled || it.indexed()
340 341
 	if nameIdx > 0 {
341 342
 		ihf, ok := d.at(nameIdx)
342 343
 		if !ok {
... ...
@@ -344,12 +410,12 @@ func (d *Decoder) parseFieldLiteral(n uint8, it indexType) error {
344 344
 		}
345 345
 		hf.Name = ihf.Name
346 346
 	} else {
347
-		hf.Name, buf, err = readString(buf)
347
+		hf.Name, buf, err = d.readString(buf, wantStr)
348 348
 		if err != nil {
349 349
 			return err
350 350
 		}
351 351
 	}
352
-	hf.Value, buf, err = readString(buf)
352
+	hf.Value, buf, err = d.readString(buf, wantStr)
353 353
 	if err != nil {
354 354
 		return err
355 355
 	}
... ...
@@ -358,7 +424,18 @@ func (d *Decoder) parseFieldLiteral(n uint8, it indexType) error {
358 358
 		d.dynTab.add(hf)
359 359
 	}
360 360
 	hf.Sensitive = it.sensitive()
361
-	d.emit(hf)
361
+	return d.callEmit(hf)
362
+}
363
+
364
+func (d *Decoder) callEmit(hf HeaderField) error {
365
+	if d.maxStrLen != 0 {
366
+		if len(hf.Name) > d.maxStrLen || len(hf.Value) > d.maxStrLen {
367
+			return ErrStringLength
368
+		}
369
+	}
370
+	if d.emitEnabled {
371
+		d.emit(hf)
372
+	}
362 373
 	return nil
363 374
 }
364 375
 
... ...
@@ -420,7 +497,15 @@ func readVarInt(n byte, p []byte) (i uint64, remain []byte, err error) {
420 420
 	return 0, origP, errNeedMore
421 421
 }
422 422
 
423
-func readString(p []byte) (s string, remain []byte, err error) {
423
+// readString decodes an hpack string from p.
424
+//
425
+// wantStr is whether s will be used. If false, decompression and
426
+// []byte->string garbage are skipped if s will be ignored
427
+// anyway. This does mean that huffman decoding errors for non-indexed
428
+// strings past the MAX_HEADER_LIST_SIZE are ignored, but the server
429
+// is returning an error anyway, and because they're not indexed, the error
430
+// won't affect the decoding state.
431
+func (d *Decoder) readString(p []byte, wantStr bool) (s string, remain []byte, err error) {
424 432
 	if len(p) == 0 {
425 433
 		return "", p, errNeedMore
426 434
 	}
... ...
@@ -429,17 +514,29 @@ func readString(p []byte) (s string, remain []byte, err error) {
429 429
 	if err != nil {
430 430
 		return "", p, err
431 431
 	}
432
+	if d.maxStrLen != 0 && strLen > uint64(d.maxStrLen) {
433
+		return "", nil, ErrStringLength
434
+	}
432 435
 	if uint64(len(p)) < strLen {
433 436
 		return "", p, errNeedMore
434 437
 	}
435 438
 	if !isHuff {
436
-		return string(p[:strLen]), p[strLen:], nil
439
+		if wantStr {
440
+			s = string(p[:strLen])
441
+		}
442
+		return s, p[strLen:], nil
437 443
 	}
438 444
 
439
-	// TODO: optimize this garbage:
440
-	var buf bytes.Buffer
441
-	if _, err := HuffmanDecode(&buf, p[:strLen]); err != nil {
442
-		return "", nil, err
445
+	if wantStr {
446
+		buf := bufPool.Get().(*bytes.Buffer)
447
+		buf.Reset() // don't trust others
448
+		defer bufPool.Put(buf)
449
+		if err := huffmanDecode(buf, d.maxStrLen, p[:strLen]); err != nil {
450
+			buf.Reset()
451
+			return "", nil, err
452
+		}
453
+		s = buf.String()
454
+		buf.Reset() // be nice to GC
443 455
 	}
444
-	return buf.String(), p[strLen:], nil
456
+	return s, p[strLen:], nil
445 457
 }
... ...
@@ -1,12 +1,12 @@
1
-// Copyright 2014 The Go Authors.
2
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
3
-// Licensed under the same terms as Go itself:
4
-// https://code.google.com/p/go/source/browse/LICENSE
1
+// Copyright 2014 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
5 4
 
6 5
 package hpack
7 6
 
8 7
 import (
9 8
 	"bytes"
9
+	"errors"
10 10
 	"io"
11 11
 	"sync"
12 12
 )
... ...
@@ -22,15 +22,46 @@ func HuffmanDecode(w io.Writer, v []byte) (int, error) {
22 22
 	buf := bufPool.Get().(*bytes.Buffer)
23 23
 	buf.Reset()
24 24
 	defer bufPool.Put(buf)
25
+	if err := huffmanDecode(buf, 0, v); err != nil {
26
+		return 0, err
27
+	}
28
+	return w.Write(buf.Bytes())
29
+}
30
+
31
+// HuffmanDecodeToString decodes the string in v.
32
+func HuffmanDecodeToString(v []byte) (string, error) {
33
+	buf := bufPool.Get().(*bytes.Buffer)
34
+	buf.Reset()
35
+	defer bufPool.Put(buf)
36
+	if err := huffmanDecode(buf, 0, v); err != nil {
37
+		return "", err
38
+	}
39
+	return buf.String(), nil
40
+}
25 41
 
42
+// ErrInvalidHuffman is returned for errors found decoding
43
+// Huffman-encoded strings.
44
+var ErrInvalidHuffman = errors.New("hpack: invalid Huffman-encoded data")
45
+
46
+// huffmanDecode decodes v to buf.
47
+// If maxLen is greater than 0, attempts to write more to buf than
48
+// maxLen bytes will return ErrStringLength.
49
+func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error {
26 50
 	n := rootHuffmanNode
27 51
 	cur, nbits := uint(0), uint8(0)
28 52
 	for _, b := range v {
29 53
 		cur = cur<<8 | uint(b)
30 54
 		nbits += 8
31 55
 		for nbits >= 8 {
32
-			n = n.children[byte(cur>>(nbits-8))]
56
+			idx := byte(cur >> (nbits - 8))
57
+			n = n.children[idx]
58
+			if n == nil {
59
+				return ErrInvalidHuffman
60
+			}
33 61
 			if n.children == nil {
62
+				if maxLen != 0 && buf.Len() == maxLen {
63
+					return ErrStringLength
64
+				}
34 65
 				buf.WriteByte(n.sym)
35 66
 				nbits -= n.codeLen
36 67
 				n = rootHuffmanNode
... ...
@@ -48,7 +79,7 @@ func HuffmanDecode(w io.Writer, v []byte) (int, error) {
48 48
 		nbits -= n.codeLen
49 49
 		n = rootHuffmanNode
50 50
 	}
51
-	return w.Write(buf.Bytes())
51
+	return nil
52 52
 }
53 53
 
54 54
 type node struct {
... ...
@@ -67,10 +98,10 @@ func newInternalNode() *node {
67 67
 var rootHuffmanNode = newInternalNode()
68 68
 
69 69
 func init() {
70
+	if len(huffmanCodes) != 256 {
71
+		panic("unexpected size")
72
+	}
70 73
 	for i, code := range huffmanCodes {
71
-		if i > 255 {
72
-			panic("too many huffman codes")
73
-		}
74 74
 		addDecoderNode(byte(i), code, huffmanCodeLen[i])
75 75
 	}
76 76
 }
... ...
@@ -1,7 +1,6 @@
1
-// Copyright 2014 The Go Authors.
2
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
3
-// Licensed under the same terms as Go itself:
4
-// https://code.google.com/p/go/source/browse/LICENSE
1
+// Copyright 2014 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
5 4
 
6 5
 package hpack
7 6
 
... ...
@@ -10,7 +9,7 @@ func pair(name, value string) HeaderField {
10 10
 }
11 11
 
12 12
 // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#appendix-B
13
-var staticTable = []HeaderField{
13
+var staticTable = [...]HeaderField{
14 14
 	pair(":authority", ""), // index 1 (1-based)
15 15
 	pair(":method", "GET"),
16 16
 	pair(":method", "POST"),
... ...
@@ -74,7 +73,7 @@ var staticTable = []HeaderField{
74 74
 	pair("www-authenticate", ""),
75 75
 }
76 76
 
77
-var huffmanCodes = []uint32{
77
+var huffmanCodes = [256]uint32{
78 78
 	0x1ff8,
79 79
 	0x7fffd8,
80 80
 	0xfffffe2,
... ...
@@ -333,7 +332,7 @@ var huffmanCodes = []uint32{
333 333
 	0x3ffffee,
334 334
 }
335 335
 
336
-var huffmanCodeLen = []uint8{
336
+var huffmanCodeLen = [256]uint8{
337 337
 	13, 23, 28, 28, 28, 28, 28, 28, 28, 24, 30, 28, 28, 30, 28, 28,
338 338
 	28, 28, 28, 28, 28, 28, 30, 28, 28, 28, 28, 28, 28, 28, 28, 28,
339 339
 	6, 10, 10, 12, 13, 6, 8, 11, 10, 10, 8, 11, 8, 6, 6, 6,
... ...
@@ -1,31 +1,51 @@
1 1
 // Copyright 2014 The Go Authors. All rights reserved.
2 2
 // Use of this source code is governed by a BSD-style
3 3
 // license that can be found in the LICENSE file.
4
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
5
-// Licensed under the same terms as Go itself:
6
-// https://code.google.com/p/go/source/browse/LICENSE
7 4
 
8 5
 // Package http2 implements the HTTP/2 protocol.
9 6
 //
10
-// This is a work in progress. This package is low-level and intended
11
-// to be used directly by very few people. Most users will use it
12
-// indirectly through integration with the net/http package. See
13
-// ConfigureServer. That ConfigureServer call will likely be automatic
14
-// or available via an empty import in the future.
7
+// This package is low-level and intended to be used directly by very
8
+// few people. Most users will use it indirectly through the automatic
9
+// use by the net/http package (from Go 1.6 and later).
10
+// For use in earlier Go versions see ConfigureServer. (Transport support
11
+// requires Go 1.6 or later)
15 12
 //
16
-// See http://http2.github.io/
13
+// See https://http2.github.io/ for more information on HTTP/2.
14
+//
15
+// See https://http2.golang.org/ for a test server running this code.
17 16
 package http2
18 17
 
19 18
 import (
20 19
 	"bufio"
20
+	"crypto/tls"
21
+	"errors"
21 22
 	"fmt"
22 23
 	"io"
23 24
 	"net/http"
25
+	"os"
26
+	"sort"
24 27
 	"strconv"
28
+	"strings"
25 29
 	"sync"
26 30
 )
27 31
 
28
-var VerboseLogs = false
32
+var (
33
+	VerboseLogs    bool
34
+	logFrameWrites bool
35
+	logFrameReads  bool
36
+)
37
+
38
+func init() {
39
+	e := os.Getenv("GODEBUG")
40
+	if strings.Contains(e, "http2debug=1") {
41
+		VerboseLogs = true
42
+	}
43
+	if strings.Contains(e, "http2debug=2") {
44
+		VerboseLogs = true
45
+		logFrameWrites = true
46
+		logFrameReads = true
47
+	}
48
+}
29 49
 
30 50
 const (
31 51
 	// ClientPreface is the string that must be sent by new
... ...
@@ -141,17 +161,63 @@ func (s SettingID) String() string {
141 141
 	return fmt.Sprintf("UNKNOWN_SETTING_%d", uint16(s))
142 142
 }
143 143
 
144
-func validHeader(v string) bool {
144
+var (
145
+	errInvalidHeaderFieldName  = errors.New("http2: invalid header field name")
146
+	errInvalidHeaderFieldValue = errors.New("http2: invalid header field value")
147
+)
148
+
149
+// validHeaderFieldName reports whether v is a valid header field name (key).
150
+//  RFC 7230 says:
151
+//   header-field   = field-name ":" OWS field-value OWS
152
+//   field-name     = token
153
+//   token          = 1*tchar
154
+//   tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
155
+//           "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
156
+// Further, http2 says:
157
+//   "Just as in HTTP/1.x, header field names are strings of ASCII
158
+//   characters that are compared in a case-insensitive
159
+//   fashion. However, header field names MUST be converted to
160
+//   lowercase prior to their encoding in HTTP/2. "
161
+func validHeaderFieldName(v string) bool {
145 162
 	if len(v) == 0 {
146 163
 		return false
147 164
 	}
148 165
 	for _, r := range v {
149
-		// "Just as in HTTP/1.x, header field names are
150
-		// strings of ASCII characters that are compared in a
151
-		// case-insensitive fashion. However, header field
152
-		// names MUST be converted to lowercase prior to their
153
-		// encoding in HTTP/2. "
154
-		if r >= 127 || ('A' <= r && r <= 'Z') {
166
+		if int(r) >= len(isTokenTable) || ('A' <= r && r <= 'Z') {
167
+			return false
168
+		}
169
+		if !isTokenTable[byte(r)] {
170
+			return false
171
+		}
172
+	}
173
+	return true
174
+}
175
+
176
+// validHeaderFieldValue reports whether v is a valid header field value.
177
+//
178
+// RFC 7230 says:
179
+//  field-value    = *( field-content / obs-fold )
180
+//  obj-fold       =  N/A to http2, and deprecated
181
+//  field-content  = field-vchar [ 1*( SP / HTAB ) field-vchar ]
182
+//  field-vchar    = VCHAR / obs-text
183
+//  obs-text       = %x80-FF
184
+//  VCHAR          = "any visible [USASCII] character"
185
+//
186
+// http2 further says: "Similarly, HTTP/2 allows header field values
187
+// that are not valid. While most of the values that can be encoded
188
+// will not alter header field parsing, carriage return (CR, ASCII
189
+// 0xd), line feed (LF, ASCII 0xa), and the zero character (NUL, ASCII
190
+// 0x0) might be exploited by an attacker if they are translated
191
+// verbatim. Any request or response that contains a character not
192
+// permitted in a header field value MUST be treated as malformed
193
+// (Section 8.1.2.6). Valid characters are defined by the
194
+// field-content ABNF rule in Section 3.2 of [RFC7230]."
195
+//
196
+// This function does not (yet?) properly handle the rejection of
197
+// strings that begin or end with SP or HTAB.
198
+func validHeaderFieldValue(v string) bool {
199
+	for i := 0; i < len(v); i++ {
200
+		if b := v[i]; b < ' ' && b != '\t' || b == 0x7f {
155 201
 			return false
156 202
 		}
157 203
 	}
... ...
@@ -247,3 +313,152 @@ func (w *bufferedWriter) Flush() error {
247 247
 	w.bw = nil
248 248
 	return err
249 249
 }
250
+
251
+func mustUint31(v int32) uint32 {
252
+	if v < 0 || v > 2147483647 {
253
+		panic("out of range")
254
+	}
255
+	return uint32(v)
256
+}
257
+
258
+// bodyAllowedForStatus reports whether a given response status code
259
+// permits a body. See RFC2616, section 4.4.
260
+func bodyAllowedForStatus(status int) bool {
261
+	switch {
262
+	case status >= 100 && status <= 199:
263
+		return false
264
+	case status == 204:
265
+		return false
266
+	case status == 304:
267
+		return false
268
+	}
269
+	return true
270
+}
271
+
272
+type httpError struct {
273
+	msg     string
274
+	timeout bool
275
+}
276
+
277
+func (e *httpError) Error() string   { return e.msg }
278
+func (e *httpError) Timeout() bool   { return e.timeout }
279
+func (e *httpError) Temporary() bool { return true }
280
+
281
+var errTimeout error = &httpError{msg: "http2: timeout awaiting response headers", timeout: true}
282
+
283
+var isTokenTable = [127]bool{
284
+	'!':  true,
285
+	'#':  true,
286
+	'$':  true,
287
+	'%':  true,
288
+	'&':  true,
289
+	'\'': true,
290
+	'*':  true,
291
+	'+':  true,
292
+	'-':  true,
293
+	'.':  true,
294
+	'0':  true,
295
+	'1':  true,
296
+	'2':  true,
297
+	'3':  true,
298
+	'4':  true,
299
+	'5':  true,
300
+	'6':  true,
301
+	'7':  true,
302
+	'8':  true,
303
+	'9':  true,
304
+	'A':  true,
305
+	'B':  true,
306
+	'C':  true,
307
+	'D':  true,
308
+	'E':  true,
309
+	'F':  true,
310
+	'G':  true,
311
+	'H':  true,
312
+	'I':  true,
313
+	'J':  true,
314
+	'K':  true,
315
+	'L':  true,
316
+	'M':  true,
317
+	'N':  true,
318
+	'O':  true,
319
+	'P':  true,
320
+	'Q':  true,
321
+	'R':  true,
322
+	'S':  true,
323
+	'T':  true,
324
+	'U':  true,
325
+	'W':  true,
326
+	'V':  true,
327
+	'X':  true,
328
+	'Y':  true,
329
+	'Z':  true,
330
+	'^':  true,
331
+	'_':  true,
332
+	'`':  true,
333
+	'a':  true,
334
+	'b':  true,
335
+	'c':  true,
336
+	'd':  true,
337
+	'e':  true,
338
+	'f':  true,
339
+	'g':  true,
340
+	'h':  true,
341
+	'i':  true,
342
+	'j':  true,
343
+	'k':  true,
344
+	'l':  true,
345
+	'm':  true,
346
+	'n':  true,
347
+	'o':  true,
348
+	'p':  true,
349
+	'q':  true,
350
+	'r':  true,
351
+	's':  true,
352
+	't':  true,
353
+	'u':  true,
354
+	'v':  true,
355
+	'w':  true,
356
+	'x':  true,
357
+	'y':  true,
358
+	'z':  true,
359
+	'|':  true,
360
+	'~':  true,
361
+}
362
+
363
+type connectionStater interface {
364
+	ConnectionState() tls.ConnectionState
365
+}
366
+
367
+var sorterPool = sync.Pool{New: func() interface{} { return new(sorter) }}
368
+
369
+type sorter struct {
370
+	v []string // owned by sorter
371
+}
372
+
373
+func (s *sorter) Len() int           { return len(s.v) }
374
+func (s *sorter) Swap(i, j int)      { s.v[i], s.v[j] = s.v[j], s.v[i] }
375
+func (s *sorter) Less(i, j int) bool { return s.v[i] < s.v[j] }
376
+
377
+// Keys returns the sorted keys of h.
378
+//
379
+// The returned slice is only valid until s used again or returned to
380
+// its pool.
381
+func (s *sorter) Keys(h http.Header) []string {
382
+	keys := s.v[:0]
383
+	for k := range h {
384
+		keys = append(keys, k)
385
+	}
386
+	s.v = keys
387
+	sort.Sort(s)
388
+	return keys
389
+}
390
+
391
+func (s *sorter) SortStrings(ss []string) {
392
+	// Our sorter works on s.v, which sorter owners, so
393
+	// stash it away while we sort the user's buffer.
394
+	save := s.v
395
+	s.v = ss
396
+	sort.Sort(s)
397
+	s.v = save
398
+}
250 399
new file mode 100644
... ...
@@ -0,0 +1,11 @@
0
+// Copyright 2015 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build !go1.5
5
+
6
+package http2
7
+
8
+import "net/http"
9
+
10
+func requestCancel(req *http.Request) <-chan struct{} { return nil }
0 11
new file mode 100644
... ...
@@ -0,0 +1,13 @@
0
+// Copyright 2015 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build !go1.6
5
+
6
+package http2
7
+
8
+import "net/http"
9
+
10
+func configureTransport(t1 *http.Transport) (*Transport, error) {
11
+	return nil, errTransportVersion
12
+}
... ...
@@ -1,43 +1,147 @@
1
-// Copyright 2014 The Go Authors.
2
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
3
-// Licensed under the same terms as Go itself:
4
-// https://code.google.com/p/go/source/browse/LICENSE
1
+// Copyright 2014 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
5 4
 
6 5
 package http2
7 6
 
8 7
 import (
8
+	"errors"
9
+	"io"
9 10
 	"sync"
10 11
 )
11 12
 
13
+// pipe is a goroutine-safe io.Reader/io.Writer pair.  It's like
14
+// io.Pipe except there are no PipeReader/PipeWriter halves, and the
15
+// underlying buffer is an interface. (io.Pipe is always unbuffered)
12 16
 type pipe struct {
13
-	b buffer
14
-	c sync.Cond
15
-	m sync.Mutex
17
+	mu       sync.Mutex
18
+	c        sync.Cond // c.L lazily initialized to &p.mu
19
+	b        pipeBuffer
20
+	err      error         // read error once empty. non-nil means closed.
21
+	breakErr error         // immediate read error (caller doesn't see rest of b)
22
+	donec    chan struct{} // closed on error
23
+	readFn   func()        // optional code to run in Read before error
24
+}
25
+
26
+type pipeBuffer interface {
27
+	Len() int
28
+	io.Writer
29
+	io.Reader
16 30
 }
17 31
 
18 32
 // Read waits until data is available and copies bytes
19 33
 // from the buffer into p.
20
-func (r *pipe) Read(p []byte) (n int, err error) {
21
-	r.c.L.Lock()
22
-	defer r.c.L.Unlock()
23
-	for r.b.Len() == 0 && !r.b.closed {
24
-		r.c.Wait()
34
+func (p *pipe) Read(d []byte) (n int, err error) {
35
+	p.mu.Lock()
36
+	defer p.mu.Unlock()
37
+	if p.c.L == nil {
38
+		p.c.L = &p.mu
39
+	}
40
+	for {
41
+		if p.breakErr != nil {
42
+			return 0, p.breakErr
43
+		}
44
+		if p.b.Len() > 0 {
45
+			return p.b.Read(d)
46
+		}
47
+		if p.err != nil {
48
+			if p.readFn != nil {
49
+				p.readFn()     // e.g. copy trailers
50
+				p.readFn = nil // not sticky like p.err
51
+			}
52
+			return 0, p.err
53
+		}
54
+		p.c.Wait()
25 55
 	}
26
-	return r.b.Read(p)
27 56
 }
28 57
 
58
+var errClosedPipeWrite = errors.New("write on closed buffer")
59
+
29 60
 // Write copies bytes from p into the buffer and wakes a reader.
30 61
 // It is an error to write more data than the buffer can hold.
31
-func (w *pipe) Write(p []byte) (n int, err error) {
32
-	w.c.L.Lock()
33
-	defer w.c.L.Unlock()
34
-	defer w.c.Signal()
35
-	return w.b.Write(p)
36
-}
37
-
38
-func (c *pipe) Close(err error) {
39
-	c.c.L.Lock()
40
-	defer c.c.L.Unlock()
41
-	defer c.c.Signal()
42
-	c.b.Close(err)
62
+func (p *pipe) Write(d []byte) (n int, err error) {
63
+	p.mu.Lock()
64
+	defer p.mu.Unlock()
65
+	if p.c.L == nil {
66
+		p.c.L = &p.mu
67
+	}
68
+	defer p.c.Signal()
69
+	if p.err != nil {
70
+		return 0, errClosedPipeWrite
71
+	}
72
+	return p.b.Write(d)
73
+}
74
+
75
+// CloseWithError causes the next Read (waking up a current blocked
76
+// Read if needed) to return the provided err after all data has been
77
+// read.
78
+//
79
+// The error must be non-nil.
80
+func (p *pipe) CloseWithError(err error) { p.closeWithError(&p.err, err, nil) }
81
+
82
+// BreakWithError causes the next Read (waking up a current blocked
83
+// Read if needed) to return the provided err immediately, without
84
+// waiting for unread data.
85
+func (p *pipe) BreakWithError(err error) { p.closeWithError(&p.breakErr, err, nil) }
86
+
87
+// closeWithErrorAndCode is like CloseWithError but also sets some code to run
88
+// in the caller's goroutine before returning the error.
89
+func (p *pipe) closeWithErrorAndCode(err error, fn func()) { p.closeWithError(&p.err, err, fn) }
90
+
91
+func (p *pipe) closeWithError(dst *error, err error, fn func()) {
92
+	if err == nil {
93
+		panic("err must be non-nil")
94
+	}
95
+	p.mu.Lock()
96
+	defer p.mu.Unlock()
97
+	if p.c.L == nil {
98
+		p.c.L = &p.mu
99
+	}
100
+	defer p.c.Signal()
101
+	if *dst != nil {
102
+		// Already been done.
103
+		return
104
+	}
105
+	p.readFn = fn
106
+	*dst = err
107
+	p.closeDoneLocked()
108
+}
109
+
110
+// requires p.mu be held.
111
+func (p *pipe) closeDoneLocked() {
112
+	if p.donec == nil {
113
+		return
114
+	}
115
+	// Close if unclosed. This isn't racy since we always
116
+	// hold p.mu while closing.
117
+	select {
118
+	case <-p.donec:
119
+	default:
120
+		close(p.donec)
121
+	}
122
+}
123
+
124
+// Err returns the error (if any) first set by BreakWithError or CloseWithError.
125
+func (p *pipe) Err() error {
126
+	p.mu.Lock()
127
+	defer p.mu.Unlock()
128
+	if p.breakErr != nil {
129
+		return p.breakErr
130
+	}
131
+	return p.err
132
+}
133
+
134
+// Done returns a channel which is closed if and when this pipe is closed
135
+// with CloseWithError.
136
+func (p *pipe) Done() <-chan struct{} {
137
+	p.mu.Lock()
138
+	defer p.mu.Unlock()
139
+	if p.donec == nil {
140
+		p.donec = make(chan struct{})
141
+		if p.err != nil || p.breakErr != nil {
142
+			// Already hit an error.
143
+			p.closeDoneLocked()
144
+		}
145
+	}
146
+	return p.donec
43 147
 }
... ...
@@ -1,16 +1,13 @@
1 1
 // Copyright 2014 The Go Authors. All rights reserved.
2 2
 // Use of this source code is governed by a BSD-style
3 3
 // license that can be found in the LICENSE file.
4
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
5
-// Licensed under the same terms as Go itself:
6
-// https://code.google.com/p/go/source/browse/LICENSE
7 4
 
8 5
 // TODO: replace all <-sc.doneServing with reads from the stream's cw
9 6
 // instead, and make sure that on close we close all open
10 7
 // streams. then remove doneServing?
11 8
 
12
-// TODO: finish GOAWAY support. Consider each incoming frame type and
13
-// whether it should be ignored during a shutdown race.
9
+// TODO: re-audit GOAWAY support. Consider each incoming frame type and
10
+// whether it should be ignored during graceful shutdown.
14 11
 
15 12
 // TODO: disconnect idle clients. GFE seems to do 4 minutes. make
16 13
 // configurable?  or maximum number of idle clients and remove the
... ...
@@ -49,7 +46,11 @@ import (
49 49
 	"log"
50 50
 	"net"
51 51
 	"net/http"
52
+	"net/textproto"
52 53
 	"net/url"
54
+	"os"
55
+	"reflect"
56
+	"runtime"
53 57
 	"strconv"
54 58
 	"strings"
55 59
 	"sync"
... ...
@@ -68,7 +69,8 @@ const (
68 68
 var (
69 69
 	errClientDisconnected = errors.New("client disconnected")
70 70
 	errClosedBody         = errors.New("body closed by handler")
71
-	errStreamBroken       = errors.New("http2: stream broken")
71
+	errHandlerComplete    = errors.New("http2: request body closed due to handler exiting")
72
+	errStreamClosed       = errors.New("http2: stream closed")
72 73
 )
73 74
 
74 75
 var responseWriterStatePool = sync.Pool{
... ...
@@ -133,12 +135,33 @@ func (s *Server) maxConcurrentStreams() uint32 {
133 133
 // The configuration conf may be nil.
134 134
 //
135 135
 // ConfigureServer must be called before s begins serving.
136
-func ConfigureServer(s *http.Server, conf *Server) {
136
+func ConfigureServer(s *http.Server, conf *Server) error {
137 137
 	if conf == nil {
138 138
 		conf = new(Server)
139 139
 	}
140
+
140 141
 	if s.TLSConfig == nil {
141 142
 		s.TLSConfig = new(tls.Config)
143
+	} else if s.TLSConfig.CipherSuites != nil {
144
+		// If they already provided a CipherSuite list, return
145
+		// an error if it has a bad order or is missing
146
+		// ECDHE_RSA_WITH_AES_128_GCM_SHA256.
147
+		const requiredCipher = tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
148
+		haveRequired := false
149
+		sawBad := false
150
+		for i, cs := range s.TLSConfig.CipherSuites {
151
+			if cs == requiredCipher {
152
+				haveRequired = true
153
+			}
154
+			if isBadCipher(cs) {
155
+				sawBad = true
156
+			} else if sawBad {
157
+				return fmt.Errorf("http2: TLSConfig.CipherSuites index %d contains an HTTP/2-approved cipher suite (%#04x), but it comes after unapproved cipher suites. With this configuration, clients that don't support previous, approved cipher suites may be given an unapproved one and reject the connection.", i, cs)
158
+			}
159
+		}
160
+		if !haveRequired {
161
+			return fmt.Errorf("http2: TLSConfig.CipherSuites is missing HTTP/2-required TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256")
162
+		}
142 163
 	}
143 164
 
144 165
 	// Note: not setting MinVersion to tls.VersionTLS12,
... ...
@@ -148,22 +171,7 @@ func ConfigureServer(s *http.Server, conf *Server) {
148 148
 	// during next-proto selection, but using TLS <1.2 with
149 149
 	// HTTP/2 is still the client's bug.
150 150
 
151
-	// Be sure we advertise tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
152
-	// at least.
153
-	// TODO: enable PreferServerCipherSuites?
154
-	if s.TLSConfig.CipherSuites != nil {
155
-		const requiredCipher = tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
156
-		haveRequired := false
157
-		for _, v := range s.TLSConfig.CipherSuites {
158
-			if v == requiredCipher {
159
-				haveRequired = true
160
-				break
161
-			}
162
-		}
163
-		if !haveRequired {
164
-			s.TLSConfig.CipherSuites = append(s.TLSConfig.CipherSuites, requiredCipher)
165
-		}
166
-	}
151
+	s.TLSConfig.PreferServerCipherSuites = true
167 152
 
168 153
 	haveNPN := false
169 154
 	for _, p := range s.TLSConfig.NextProtos {
... ...
@@ -186,28 +194,76 @@ func ConfigureServer(s *http.Server, conf *Server) {
186 186
 		if testHookOnConn != nil {
187 187
 			testHookOnConn()
188 188
 		}
189
-		conf.handleConn(hs, c, h)
189
+		conf.ServeConn(c, &ServeConnOpts{
190
+			Handler:    h,
191
+			BaseConfig: hs,
192
+		})
190 193
 	}
191 194
 	s.TLSNextProto[NextProtoTLS] = protoHandler
192 195
 	s.TLSNextProto["h2-14"] = protoHandler // temporary; see above.
196
+	return nil
193 197
 }
194 198
 
195
-func (srv *Server) handleConn(hs *http.Server, c net.Conn, h http.Handler) {
199
+// ServeConnOpts are options for the Server.ServeConn method.
200
+type ServeConnOpts struct {
201
+	// BaseConfig optionally sets the base configuration
202
+	// for values. If nil, defaults are used.
203
+	BaseConfig *http.Server
204
+
205
+	// Handler specifies which handler to use for processing
206
+	// requests. If nil, BaseConfig.Handler is used. If BaseConfig
207
+	// or BaseConfig.Handler is nil, http.DefaultServeMux is used.
208
+	Handler http.Handler
209
+}
210
+
211
+func (o *ServeConnOpts) baseConfig() *http.Server {
212
+	if o != nil && o.BaseConfig != nil {
213
+		return o.BaseConfig
214
+	}
215
+	return new(http.Server)
216
+}
217
+
218
+func (o *ServeConnOpts) handler() http.Handler {
219
+	if o != nil {
220
+		if o.Handler != nil {
221
+			return o.Handler
222
+		}
223
+		if o.BaseConfig != nil && o.BaseConfig.Handler != nil {
224
+			return o.BaseConfig.Handler
225
+		}
226
+	}
227
+	return http.DefaultServeMux
228
+}
229
+
230
+// ServeConn serves HTTP/2 requests on the provided connection and
231
+// blocks until the connection is no longer readable.
232
+//
233
+// ServeConn starts speaking HTTP/2 assuming that c has not had any
234
+// reads or writes. It writes its initial settings frame and expects
235
+// to be able to read the preface and settings frame from the
236
+// client. If c has a ConnectionState method like a *tls.Conn, the
237
+// ConnectionState is used to verify the TLS ciphersuite and to set
238
+// the Request.TLS field in Handlers.
239
+//
240
+// ServeConn does not support h2c by itself. Any h2c support must be
241
+// implemented in terms of providing a suitably-behaving net.Conn.
242
+//
243
+// The opts parameter is optional. If nil, default values are used.
244
+func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
196 245
 	sc := &serverConn{
197
-		srv:              srv,
198
-		hs:               hs,
246
+		srv:              s,
247
+		hs:               opts.baseConfig(),
199 248
 		conn:             c,
200 249
 		remoteAddrStr:    c.RemoteAddr().String(),
201 250
 		bw:               newBufferedWriter(c),
202
-		handler:          h,
251
+		handler:          opts.handler(),
203 252
 		streams:          make(map[uint32]*stream),
204
-		readFrameCh:      make(chan frameAndGate),
205
-		readFrameErrCh:   make(chan error, 1), // must be buffered for 1
253
+		readFrameCh:      make(chan readFrameResult),
206 254
 		wantWriteFrameCh: make(chan frameWriteMsg, 8),
207
-		wroteFrameCh:     make(chan struct{}, 1), // buffered; one send in reading goroutine
208
-		bodyReadCh:       make(chan bodyReadMsg), // buffering doesn't matter either way
255
+		wroteFrameCh:     make(chan frameWriteResult, 1), // buffered; one send in writeFrameAsync
256
+		bodyReadCh:       make(chan bodyReadMsg),         // buffering doesn't matter either way
209 257
 		doneServing:      make(chan struct{}),
210
-		advMaxStreams:    srv.maxConcurrentStreams(),
258
+		advMaxStreams:    s.maxConcurrentStreams(),
211 259
 		writeSched: writeScheduler{
212 260
 			maxFrameSize: initialMaxFrameSize,
213 261
 		},
... ...
@@ -219,13 +275,14 @@ func (srv *Server) handleConn(hs *http.Server, c net.Conn, h http.Handler) {
219 219
 	sc.flow.add(initialWindowSize)
220 220
 	sc.inflow.add(initialWindowSize)
221 221
 	sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf)
222
-	sc.hpackDecoder = hpack.NewDecoder(initialHeaderTableSize, sc.onNewHeaderField)
223 222
 
224 223
 	fr := NewFramer(sc.bw, c)
225
-	fr.SetMaxReadFrameSize(srv.maxReadFrameSize())
224
+	fr.ReadMetaHeaders = hpack.NewDecoder(initialHeaderTableSize, nil)
225
+	fr.MaxHeaderListSize = sc.maxHeaderListSize()
226
+	fr.SetMaxReadFrameSize(s.maxReadFrameSize())
226 227
 	sc.framer = fr
227 228
 
228
-	if tc, ok := c.(*tls.Conn); ok {
229
+	if tc, ok := c.(connectionStater); ok {
229 230
 		sc.tlsState = new(tls.ConnectionState)
230 231
 		*sc.tlsState = tc.ConnectionState()
231 232
 		// 9.2 Use of TLS Features
... ...
@@ -255,7 +312,7 @@ func (srv *Server) handleConn(hs *http.Server, c net.Conn, h http.Handler) {
255 255
 			// So for now, do nothing here again.
256 256
 		}
257 257
 
258
-		if !srv.PermitProhibitedCipherSuites && isBadCipher(sc.tlsState.CipherSuite) {
258
+		if !s.PermitProhibitedCipherSuites && isBadCipher(sc.tlsState.CipherSuite) {
259 259
 			// "Endpoints MAY choose to generate a connection error
260 260
 			// (Section 5.4.1) of type INADEQUATE_SECURITY if one of
261 261
 			// the prohibited cipher suites are negotiated."
... ...
@@ -302,23 +359,13 @@ func isBadCipher(cipher uint16) bool {
302 302
 }
303 303
 
304 304
 func (sc *serverConn) rejectConn(err ErrCode, debug string) {
305
-	log.Printf("REJECTING conn: %v, %s", err, debug)
305
+	sc.vlogf("http2: server rejecting conn: %v, %s", err, debug)
306 306
 	// ignoring errors. hanging up anyway.
307 307
 	sc.framer.WriteGoAway(0, err, []byte(debug))
308 308
 	sc.bw.Flush()
309 309
 	sc.conn.Close()
310 310
 }
311 311
 
312
-// frameAndGates coordinates the readFrames and serve
313
-// goroutines. Because the Framer interface only permits the most
314
-// recently-read Frame from being accessed, the readFrames goroutine
315
-// blocks until it has a frame, passes it to serve, and then waits for
316
-// serve to be done with it before reading the next one.
317
-type frameAndGate struct {
318
-	f Frame
319
-	g gate
320
-}
321
-
322 312
 type serverConn struct {
323 313
 	// Immutable:
324 314
 	srv              *Server
... ...
@@ -327,17 +374,15 @@ type serverConn struct {
327 327
 	bw               *bufferedWriter // writing to conn
328 328
 	handler          http.Handler
329 329
 	framer           *Framer
330
-	hpackDecoder     *hpack.Decoder
331
-	doneServing      chan struct{}     // closed when serverConn.serve ends
332
-	readFrameCh      chan frameAndGate // written by serverConn.readFrames
333
-	readFrameErrCh   chan error
334
-	wantWriteFrameCh chan frameWriteMsg   // from handlers -> serve
335
-	wroteFrameCh     chan struct{}        // from writeFrameAsync -> serve, tickles more frame writes
336
-	bodyReadCh       chan bodyReadMsg     // from handlers -> serve
337
-	testHookCh       chan func()          // code to run on the serve loop
338
-	flow             flow                 // conn-wide (not stream-specific) outbound flow control
339
-	inflow           flow                 // conn-wide inbound flow control
340
-	tlsState         *tls.ConnectionState // shared by all handlers, like net/http
330
+	doneServing      chan struct{}         // closed when serverConn.serve ends
331
+	readFrameCh      chan readFrameResult  // written by serverConn.readFrames
332
+	wantWriteFrameCh chan frameWriteMsg    // from handlers -> serve
333
+	wroteFrameCh     chan frameWriteResult // from writeFrameAsync -> serve, tickles more frame writes
334
+	bodyReadCh       chan bodyReadMsg      // from handlers -> serve
335
+	testHookCh       chan func(int)        // code to run on the serve loop
336
+	flow             flow                  // conn-wide (not stream-specific) outbound flow control
337
+	inflow           flow                  // conn-wide inbound flow control
338
+	tlsState         *tls.ConnectionState  // shared by all handlers, like net/http
341 339
 	remoteAddrStr    string
342 340
 
343 341
 	// Everything following is owned by the serve loop; use serveG.check():
... ...
@@ -353,9 +398,8 @@ type serverConn struct {
353 353
 	streams               map[uint32]*stream
354 354
 	initialWindowSize     int32
355 355
 	headerTableSize       uint32
356
-	maxHeaderListSize     uint32            // zero means unknown (default)
356
+	peerMaxHeaderListSize uint32            // zero means unknown (default)
357 357
 	canonHeader           map[string]string // http2-lower-case -> Go-Canonical-Case
358
-	req                   requestParam      // non-zero while reading request headers
359 358
 	writingFrame          bool              // started write goroutine but haven't heard back on wroteFrameCh
360 359
 	needsFrameFlush       bool              // last frame write wasn't a flush
361 360
 	writeSched            writeScheduler
... ...
@@ -364,24 +408,23 @@ type serverConn struct {
364 364
 	goAwayCode            ErrCode
365 365
 	shutdownTimerCh       <-chan time.Time // nil until used
366 366
 	shutdownTimer         *time.Timer      // nil until used
367
+	freeRequestBodyBuf    []byte           // if non-nil, a free initialWindowSize buffer for getRequestBodyBuf
367 368
 
368 369
 	// Owned by the writeFrameAsync goroutine:
369 370
 	headerWriteBuf bytes.Buffer
370 371
 	hpackEncoder   *hpack.Encoder
371 372
 }
372 373
 
373
-// requestParam is the state of the next request, initialized over
374
-// potentially several frames HEADERS + zero or more CONTINUATION
375
-// frames.
376
-type requestParam struct {
377
-	// stream is non-nil if we're reading (HEADER or CONTINUATION)
378
-	// frames for a request (but not DATA).
379
-	stream            *stream
380
-	header            http.Header
381
-	method, path      string
382
-	scheme, authority string
383
-	sawRegularHeader  bool // saw a non-pseudo header already
384
-	invalidHeader     bool // an invalid header was seen
374
+func (sc *serverConn) maxHeaderListSize() uint32 {
375
+	n := sc.hs.MaxHeaderBytes
376
+	if n <= 0 {
377
+		n = http.DefaultMaxHeaderBytes
378
+	}
379
+	// http2's count is in a slightly different unit and includes 32 bytes per pair.
380
+	// So, take the net/http.Server value and pad it up a bit, assuming 10 headers.
381
+	const perFieldOverhead = 32 // per http2 spec
382
+	const typicalHeaders = 10   // conservative
383
+	return uint32(n + typicalHeaders*perFieldOverhead)
385 384
 }
386 385
 
387 386
 // stream represents a stream. This is the minimal metadata needed by
... ...
@@ -393,20 +436,27 @@ type requestParam struct {
393 393
 // responseWriter's state field.
394 394
 type stream struct {
395 395
 	// immutable:
396
+	sc   *serverConn
396 397
 	id   uint32
397 398
 	body *pipe       // non-nil if expecting DATA frames
398 399
 	cw   closeWaiter // closed wait stream transitions to closed state
399 400
 
400 401
 	// owned by serverConn's serve loop:
401
-	bodyBytes     int64   // body bytes seen so far
402
-	declBodyBytes int64   // or -1 if undeclared
403
-	flow          flow    // limits writing from Handler to client
404
-	inflow        flow    // what the client is allowed to POST/etc to us
405
-	parent        *stream // or nil
406
-	weight        uint8
407
-	state         streamState
408
-	sentReset     bool // only true once detached from streams map
409
-	gotReset      bool // only true once detacted from streams map
402
+	bodyBytes        int64   // body bytes seen so far
403
+	declBodyBytes    int64   // or -1 if undeclared
404
+	flow             flow    // limits writing from Handler to client
405
+	inflow           flow    // what the client is allowed to POST/etc to us
406
+	parent           *stream // or nil
407
+	numTrailerValues int64
408
+	weight           uint8
409
+	state            streamState
410
+	sentReset        bool // only true once detached from streams map
411
+	gotReset         bool // only true once detacted from streams map
412
+	gotTrailerHeader bool // HEADER frame for trailers was seen
413
+	reqBuf           []byte
414
+
415
+	trailer    http.Header // accumulated trailers
416
+	reqTrailer http.Header // handler's Request.Trailer
410 417
 }
411 418
 
412 419
 func (sc *serverConn) Framer() *Framer  { return sc.framer }
... ...
@@ -434,6 +484,15 @@ func (sc *serverConn) state(streamID uint32) (streamState, *stream) {
434 434
 	return stateIdle, nil
435 435
 }
436 436
 
437
+// setConnState calls the net/http ConnState hook for this connection, if configured.
438
+// Note that the net/http package does StateNew and StateClosed for us.
439
+// There is currently no plan for StateHijacked or hijacking HTTP/2 connections.
440
+func (sc *serverConn) setConnState(state http.ConnState) {
441
+	if sc.hs.ConnState != nil {
442
+		sc.hs.ConnState(sc.conn, state)
443
+	}
444
+}
445
+
437 446
 func (sc *serverConn) vlogf(format string, args ...interface{}) {
438 447
 	if VerboseLogs {
439 448
 		sc.logf(format, args...)
... ...
@@ -448,12 +507,55 @@ func (sc *serverConn) logf(format string, args ...interface{}) {
448 448
 	}
449 449
 }
450 450
 
451
+// errno returns v's underlying uintptr, else 0.
452
+//
453
+// TODO: remove this helper function once http2 can use build
454
+// tags. See comment in isClosedConnError.
455
+func errno(v error) uintptr {
456
+	if rv := reflect.ValueOf(v); rv.Kind() == reflect.Uintptr {
457
+		return uintptr(rv.Uint())
458
+	}
459
+	return 0
460
+}
461
+
462
+// isClosedConnError reports whether err is an error from use of a closed
463
+// network connection.
464
+func isClosedConnError(err error) bool {
465
+	if err == nil {
466
+		return false
467
+	}
468
+
469
+	// TODO: remove this string search and be more like the Windows
470
+	// case below. That might involve modifying the standard library
471
+	// to return better error types.
472
+	str := err.Error()
473
+	if strings.Contains(str, "use of closed network connection") {
474
+		return true
475
+	}
476
+
477
+	// TODO(bradfitz): x/tools/cmd/bundle doesn't really support
478
+	// build tags, so I can't make an http2_windows.go file with
479
+	// Windows-specific stuff. Fix that and move this, once we
480
+	// have a way to bundle this into std's net/http somehow.
481
+	if runtime.GOOS == "windows" {
482
+		if oe, ok := err.(*net.OpError); ok && oe.Op == "read" {
483
+			if se, ok := oe.Err.(*os.SyscallError); ok && se.Syscall == "wsarecv" {
484
+				const WSAECONNABORTED = 10053
485
+				const WSAECONNRESET = 10054
486
+				if n := errno(se.Err); n == WSAECONNRESET || n == WSAECONNABORTED {
487
+					return true
488
+				}
489
+			}
490
+		}
491
+	}
492
+	return false
493
+}
494
+
451 495
 func (sc *serverConn) condlogf(err error, format string, args ...interface{}) {
452 496
 	if err == nil {
453 497
 		return
454 498
 	}
455
-	str := err.Error()
456
-	if err == io.EOF || strings.Contains(str, "use of closed network connection") {
499
+	if err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err) {
457 500
 		// Boring, expected errors.
458 501
 		sc.vlogf(format, args...)
459 502
 	} else {
... ...
@@ -461,57 +563,6 @@ func (sc *serverConn) condlogf(err error, format string, args ...interface{}) {
461 461
 	}
462 462
 }
463 463
 
464
-func (sc *serverConn) onNewHeaderField(f hpack.HeaderField) {
465
-	sc.serveG.check()
466
-	sc.vlogf("got header field %+v", f)
467
-	switch {
468
-	case !validHeader(f.Name):
469
-		sc.req.invalidHeader = true
470
-	case strings.HasPrefix(f.Name, ":"):
471
-		if sc.req.sawRegularHeader {
472
-			sc.logf("pseudo-header after regular header")
473
-			sc.req.invalidHeader = true
474
-			return
475
-		}
476
-		var dst *string
477
-		switch f.Name {
478
-		case ":method":
479
-			dst = &sc.req.method
480
-		case ":path":
481
-			dst = &sc.req.path
482
-		case ":scheme":
483
-			dst = &sc.req.scheme
484
-		case ":authority":
485
-			dst = &sc.req.authority
486
-		default:
487
-			// 8.1.2.1 Pseudo-Header Fields
488
-			// "Endpoints MUST treat a request or response
489
-			// that contains undefined or invalid
490
-			// pseudo-header fields as malformed (Section
491
-			// 8.1.2.6)."
492
-			sc.logf("invalid pseudo-header %q", f.Name)
493
-			sc.req.invalidHeader = true
494
-			return
495
-		}
496
-		if *dst != "" {
497
-			sc.logf("duplicate pseudo-header %q sent", f.Name)
498
-			sc.req.invalidHeader = true
499
-			return
500
-		}
501
-		*dst = f.Value
502
-	case f.Name == "cookie":
503
-		sc.req.sawRegularHeader = true
504
-		if s, ok := sc.req.header["Cookie"]; ok && len(s) == 1 {
505
-			s[0] = s[0] + "; " + f.Value
506
-		} else {
507
-			sc.req.header.Add("Cookie", f.Value)
508
-		}
509
-	default:
510
-		sc.req.sawRegularHeader = true
511
-		sc.req.header.Add(sc.canonicalHeader(f.Name), f.Value)
512
-	}
513
-}
514
-
515 464
 func (sc *serverConn) canonicalHeader(v string) string {
516 465
 	sc.serveG.check()
517 466
 	cv, ok := commonCanonHeader[v]
... ...
@@ -530,41 +581,54 @@ func (sc *serverConn) canonicalHeader(v string) string {
530 530
 	return cv
531 531
 }
532 532
 
533
+type readFrameResult struct {
534
+	f   Frame // valid until readMore is called
535
+	err error
536
+
537
+	// readMore should be called once the consumer no longer needs or
538
+	// retains f. After readMore, f is invalid and more frames can be
539
+	// read.
540
+	readMore func()
541
+}
542
+
533 543
 // readFrames is the loop that reads incoming frames.
544
+// It takes care to only read one frame at a time, blocking until the
545
+// consumer is done with the frame.
534 546
 // It's run on its own goroutine.
535 547
 func (sc *serverConn) readFrames() {
536
-	g := make(gate, 1)
548
+	gate := make(gate)
549
+	gateDone := gate.Done
537 550
 	for {
538 551
 		f, err := sc.framer.ReadFrame()
539
-		if err != nil {
540
-			sc.readFrameErrCh <- err
541
-			close(sc.readFrameCh)
552
+		select {
553
+		case sc.readFrameCh <- readFrameResult{f, err, gateDone}:
554
+		case <-sc.doneServing:
555
+			return
556
+		}
557
+		select {
558
+		case <-gate:
559
+		case <-sc.doneServing:
560
+			return
561
+		}
562
+		if terminalReadFrameError(err) {
542 563
 			return
543 564
 		}
544
-		sc.readFrameCh <- frameAndGate{f, g}
545
-		// We can't read another frame until this one is
546
-		// processed, as the ReadFrame interface doesn't copy
547
-		// memory.  The Frame accessor methods access the last
548
-		// frame's (shared) buffer. So we wait for the
549
-		// serve goroutine to tell us it's done:
550
-		g.Wait()
551 565
 	}
552 566
 }
553 567
 
568
+// frameWriteResult is the message passed from writeFrameAsync to the serve goroutine.
569
+type frameWriteResult struct {
570
+	wm  frameWriteMsg // what was written (or attempted)
571
+	err error         // result of the writeFrame call
572
+}
573
+
554 574
 // writeFrameAsync runs in its own goroutine and writes a single frame
555 575
 // and then reports when it's done.
556 576
 // At most one goroutine can be running writeFrameAsync at a time per
557 577
 // serverConn.
558 578
 func (sc *serverConn) writeFrameAsync(wm frameWriteMsg) {
559 579
 	err := wm.write.writeFrame(sc)
560
-	if ch := wm.done; ch != nil {
561
-		select {
562
-		case ch <- err:
563
-		default:
564
-			panic(fmt.Sprintf("unbuffered done channel passed in for type %T", wm.write))
565
-		}
566
-	}
567
-	sc.wroteFrameCh <- struct{}{} // tickle frame selection scheduler
580
+	sc.wroteFrameCh <- frameWriteResult{wm, err}
568 581
 }
569 582
 
570 583
 func (sc *serverConn) closeAllStreamsOnConnClose() {
... ...
@@ -582,6 +646,7 @@ func (sc *serverConn) stopShutdownTimer() {
582 582
 }
583 583
 
584 584
 func (sc *serverConn) notePanic() {
585
+	// Note: this is for serverConn.serve panicking, not http.Handler code.
585 586
 	if testHookOnPanicMu != nil {
586 587
 		testHookOnPanicMu.Lock()
587 588
 		defer testHookOnPanicMu.Unlock()
... ...
@@ -603,12 +668,15 @@ func (sc *serverConn) serve() {
603 603
 	defer sc.stopShutdownTimer()
604 604
 	defer close(sc.doneServing) // unblocks handlers trying to send
605 605
 
606
-	sc.vlogf("HTTP/2 connection from %v on %p", sc.conn.RemoteAddr(), sc.hs)
606
+	if VerboseLogs {
607
+		sc.vlogf("http2: server connection from %v on %p", sc.conn.RemoteAddr(), sc.hs)
608
+	}
607 609
 
608 610
 	sc.writeFrame(frameWriteMsg{
609 611
 		write: writeSettings{
610 612
 			{SettingMaxFrameSize, sc.srv.maxReadFrameSize()},
611 613
 			{SettingMaxConcurrentStreams, sc.advMaxStreams},
614
+			{SettingMaxHeaderListSize, sc.maxHeaderListSize()},
612 615
 
613 616
 			// TODO: more actual settings, notably
614 617
 			// SettingInitialWindowSize, but then we also
... ...
@@ -619,30 +687,32 @@ func (sc *serverConn) serve() {
619 619
 	sc.unackedSettings++
620 620
 
621 621
 	if err := sc.readPreface(); err != nil {
622
-		sc.condlogf(err, "error reading preface from client %v: %v", sc.conn.RemoteAddr(), err)
622
+		sc.condlogf(err, "http2: server: error reading preface from client %v: %v", sc.conn.RemoteAddr(), err)
623 623
 		return
624 624
 	}
625
+	// Now that we've got the preface, get us out of the
626
+	// "StateNew" state.  We can't go directly to idle, though.
627
+	// Active means we read some data and anticipate a request. We'll
628
+	// do another Active when we get a HEADERS frame.
629
+	sc.setConnState(http.StateActive)
630
+	sc.setConnState(http.StateIdle)
625 631
 
626 632
 	go sc.readFrames() // closed by defer sc.conn.Close above
627 633
 
628 634
 	settingsTimer := time.NewTimer(firstSettingsTimeout)
635
+	loopNum := 0
629 636
 	for {
637
+		loopNum++
630 638
 		select {
631 639
 		case wm := <-sc.wantWriteFrameCh:
632 640
 			sc.writeFrame(wm)
633
-		case <-sc.wroteFrameCh:
634
-			if sc.writingFrame != true {
635
-				panic("internal error: expected to be already writing a frame")
636
-			}
637
-			sc.writingFrame = false
638
-			sc.scheduleFrameWrite()
639
-		case fg, ok := <-sc.readFrameCh:
640
-			if !ok {
641
-				sc.readFrameCh = nil
642
-			}
643
-			if !sc.processFrameFromReader(fg, ok) {
641
+		case res := <-sc.wroteFrameCh:
642
+			sc.wroteFrame(res)
643
+		case res := <-sc.readFrameCh:
644
+			if !sc.processFrameFromReader(res) {
644 645
 				return
645 646
 			}
647
+			res.readMore()
646 648
 			if settingsTimer.C != nil {
647 649
 				settingsTimer.Stop()
648 650
 				settingsTimer.C = nil
... ...
@@ -656,7 +726,7 @@ func (sc *serverConn) serve() {
656 656
 			sc.vlogf("GOAWAY close timer fired; closing conn from %v", sc.conn.RemoteAddr())
657 657
 			return
658 658
 		case fn := <-sc.testHookCh:
659
-			fn()
659
+			fn(loopNum)
660 660
 		}
661 661
 	}
662 662
 }
... ...
@@ -683,38 +753,62 @@ func (sc *serverConn) readPreface() error {
683 683
 		return errors.New("timeout waiting for client preface")
684 684
 	case err := <-errc:
685 685
 		if err == nil {
686
-			sc.vlogf("client %v said hello", sc.conn.RemoteAddr())
686
+			if VerboseLogs {
687
+				sc.vlogf("http2: server: client %v said hello", sc.conn.RemoteAddr())
688
+			}
687 689
 		}
688 690
 		return err
689 691
 	}
690 692
 }
691 693
 
692
-// writeDataFromHandler writes the data described in req to stream.id.
693
-//
694
-// The provided ch is used to avoid allocating new channels for each
695
-// write operation. It's expected that the caller reuses writeData and ch
696
-// over time.
697
-//
698
-// The flow control currently happens in the Handler where it waits
699
-// for 1 or more bytes to be available to then write here.  So at this
700
-// point we know that we have flow control. But this might have to
701
-// change when priority is implemented, so the serve goroutine knows
702
-// the total amount of bytes waiting to be sent and can can have more
703
-// scheduling decisions available.
704
-func (sc *serverConn) writeDataFromHandler(stream *stream, writeData *writeData, ch chan error) error {
705
-	sc.writeFrameFromHandler(frameWriteMsg{
706
-		write:  writeData,
694
+var errChanPool = sync.Pool{
695
+	New: func() interface{} { return make(chan error, 1) },
696
+}
697
+
698
+var writeDataPool = sync.Pool{
699
+	New: func() interface{} { return new(writeData) },
700
+}
701
+
702
+// writeDataFromHandler writes DATA response frames from a handler on
703
+// the given stream.
704
+func (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStream bool) error {
705
+	ch := errChanPool.Get().(chan error)
706
+	writeArg := writeDataPool.Get().(*writeData)
707
+	*writeArg = writeData{stream.id, data, endStream}
708
+	err := sc.writeFrameFromHandler(frameWriteMsg{
709
+		write:  writeArg,
707 710
 		stream: stream,
708 711
 		done:   ch,
709 712
 	})
710
-	select {
711
-	case err := <-ch:
713
+	if err != nil {
712 714
 		return err
715
+	}
716
+	var frameWriteDone bool // the frame write is done (successfully or not)
717
+	select {
718
+	case err = <-ch:
719
+		frameWriteDone = true
713 720
 	case <-sc.doneServing:
714 721
 		return errClientDisconnected
715 722
 	case <-stream.cw:
716
-		return errStreamBroken
723
+		// If both ch and stream.cw were ready (as might
724
+		// happen on the final Write after an http.Handler
725
+		// ends), prefer the write result. Otherwise this
726
+		// might just be us successfully closing the stream.
727
+		// The writeFrameAsync and serve goroutines guarantee
728
+		// that the ch send will happen before the stream.cw
729
+		// close.
730
+		select {
731
+		case err = <-ch:
732
+			frameWriteDone = true
733
+		default:
734
+			return errStreamClosed
735
+		}
736
+	}
737
+	errChanPool.Put(ch)
738
+	if frameWriteDone {
739
+		writeDataPool.Put(writeArg)
717 740
 	}
741
+	return err
718 742
 }
719 743
 
720 744
 // writeFrameFromHandler sends wm to sc.wantWriteFrameCh, but aborts
... ...
@@ -724,12 +818,15 @@ func (sc *serverConn) writeDataFromHandler(stream *stream, writeData *writeData,
724 724
 // deadlock writing to sc.wantWriteFrameCh (which is only mildly
725 725
 // buffered and is read by serve itself). If you're on the serve
726 726
 // goroutine, call writeFrame instead.
727
-func (sc *serverConn) writeFrameFromHandler(wm frameWriteMsg) {
727
+func (sc *serverConn) writeFrameFromHandler(wm frameWriteMsg) error {
728 728
 	sc.serveG.checkNotOn() // NOT
729 729
 	select {
730 730
 	case sc.wantWriteFrameCh <- wm:
731
+		return nil
731 732
 	case <-sc.doneServing:
733
+		// Serve loop is gone.
732 734
 		// Client has closed their connection to the server.
735
+		return errClientDisconnected
733 736
 	}
734 737
 }
735 738
 
... ...
@@ -755,7 +852,6 @@ func (sc *serverConn) startFrameWrite(wm frameWriteMsg) {
755 755
 	if sc.writingFrame {
756 756
 		panic("internal error: can only be writing one frame at a time")
757 757
 	}
758
-	sc.writingFrame = true
759 758
 
760 759
 	st := wm.stream
761 760
 	if st != nil {
... ...
@@ -764,16 +860,53 @@ func (sc *serverConn) startFrameWrite(wm frameWriteMsg) {
764 764
 			panic("internal error: attempt to send frame on half-closed-local stream")
765 765
 		case stateClosed:
766 766
 			if st.sentReset || st.gotReset {
767
-				// Skip this frame. But fake the frame write to reschedule:
768
-				sc.wroteFrameCh <- struct{}{}
767
+				// Skip this frame.
768
+				sc.scheduleFrameWrite()
769 769
 				return
770 770
 			}
771 771
 			panic(fmt.Sprintf("internal error: attempt to send a write %v on a closed stream", wm))
772 772
 		}
773 773
 	}
774 774
 
775
+	sc.writingFrame = true
775 776
 	sc.needsFrameFlush = true
776
-	if endsStream(wm.write) {
777
+	go sc.writeFrameAsync(wm)
778
+}
779
+
780
+// errHandlerPanicked is the error given to any callers blocked in a read from
781
+// Request.Body when the main goroutine panics. Since most handlers read in the
782
+// the main ServeHTTP goroutine, this will show up rarely.
783
+var errHandlerPanicked = errors.New("http2: handler panicked")
784
+
785
+// wroteFrame is called on the serve goroutine with the result of
786
+// whatever happened on writeFrameAsync.
787
+func (sc *serverConn) wroteFrame(res frameWriteResult) {
788
+	sc.serveG.check()
789
+	if !sc.writingFrame {
790
+		panic("internal error: expected to be already writing a frame")
791
+	}
792
+	sc.writingFrame = false
793
+
794
+	wm := res.wm
795
+	st := wm.stream
796
+
797
+	closeStream := endsStream(wm.write)
798
+
799
+	if _, ok := wm.write.(handlerPanicRST); ok {
800
+		sc.closeStream(st, errHandlerPanicked)
801
+	}
802
+
803
+	// Reply (if requested) to the blocked ServeHTTP goroutine.
804
+	if ch := wm.done; ch != nil {
805
+		select {
806
+		case ch <- res.err:
807
+		default:
808
+			panic(fmt.Sprintf("unbuffered done channel passed in for type %T", wm.write))
809
+		}
810
+	}
811
+	wm.write = nil // prevent use (assume it's tainted after wm.done send)
812
+
813
+	if closeStream {
777 814
 		if st == nil {
778 815
 			panic("internal error: expecting non-nil stream")
779 816
 		}
... ...
@@ -791,10 +924,11 @@ func (sc *serverConn) startFrameWrite(wm frameWriteMsg) {
791 791
 			errCancel := StreamError{st.id, ErrCodeCancel}
792 792
 			sc.resetStream(errCancel)
793 793
 		case stateHalfClosedRemote:
794
-			sc.closeStream(st, nil)
794
+			sc.closeStream(st, errHandlerComplete)
795 795
 		}
796 796
 	}
797
-	go sc.writeFrameAsync(wm)
797
+
798
+	sc.scheduleFrameWrite()
798 799
 }
799 800
 
800 801
 // scheduleFrameWrite tickles the frame writing scheduler.
... ...
@@ -874,32 +1008,18 @@ func (sc *serverConn) resetStream(se StreamError) {
874 874
 	}
875 875
 }
876 876
 
877
-// curHeaderStreamID returns the stream ID of the header block we're
878
-// currently in the middle of reading. If this returns non-zero, the
879
-// next frame must be a CONTINUATION with this stream id.
880
-func (sc *serverConn) curHeaderStreamID() uint32 {
881
-	sc.serveG.check()
882
-	st := sc.req.stream
883
-	if st == nil {
884
-		return 0
885
-	}
886
-	return st.id
887
-}
888
-
889 877
 // processFrameFromReader processes the serve loop's read from readFrameCh from the
890 878
 // frame-reading goroutine.
891 879
 // processFrameFromReader returns whether the connection should be kept open.
892
-func (sc *serverConn) processFrameFromReader(fg frameAndGate, fgValid bool) bool {
880
+func (sc *serverConn) processFrameFromReader(res readFrameResult) bool {
893 881
 	sc.serveG.check()
894
-	var clientGone bool
895
-	var err error
896
-	if !fgValid {
897
-		err = <-sc.readFrameErrCh
882
+	err := res.err
883
+	if err != nil {
898 884
 		if err == ErrFrameTooLarge {
899 885
 			sc.goAway(ErrCodeFrameSize)
900 886
 			return true // goAway will close the loop
901 887
 		}
902
-		clientGone = err == io.EOF || strings.Contains(err.Error(), "use of closed network connection")
888
+		clientGone := err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err)
903 889
 		if clientGone {
904 890
 			// TODO: could we also get into this state if
905 891
 			// the peer does a half close
... ...
@@ -911,13 +1031,12 @@ func (sc *serverConn) processFrameFromReader(fg frameAndGate, fgValid bool) bool
911 911
 			// just for testing we could have a non-TLS mode.
912 912
 			return false
913 913
 		}
914
-	}
915
-
916
-	if fgValid {
917
-		f := fg.f
918
-		sc.vlogf("got %v: %#v", f.Header(), f)
914
+	} else {
915
+		f := res.f
916
+		if VerboseLogs {
917
+			sc.vlogf("http2: server read frame %v", summarizeFrame(f))
918
+		}
919 919
 		err = sc.processFrame(f)
920
-		fg.g.Done() // unblock the readFrames goroutine
921 920
 		if err == nil {
922 921
 			return true
923 922
 		}
... ...
@@ -931,17 +1050,17 @@ func (sc *serverConn) processFrameFromReader(fg frameAndGate, fgValid bool) bool
931 931
 		sc.goAway(ErrCodeFlowControl)
932 932
 		return true
933 933
 	case ConnectionError:
934
-		sc.logf("%v: %v", sc.conn.RemoteAddr(), ev)
934
+		sc.logf("http2: server connection error from %v: %v", sc.conn.RemoteAddr(), ev)
935 935
 		sc.goAway(ErrCode(ev))
936 936
 		return true // goAway will handle shutdown
937 937
 	default:
938
-		if !fgValid {
939
-			sc.logf("disconnecting; error reading frame from client %s: %v", sc.conn.RemoteAddr(), err)
938
+		if res.err != nil {
939
+			sc.vlogf("http2: server closing client connection; error reading frame from client %s: %v", sc.conn.RemoteAddr(), err)
940 940
 		} else {
941
-			sc.logf("disconnection due to other error: %v", err)
941
+			sc.logf("http2: server closing client connection: %v", err)
942 942
 		}
943
+		return false
943 944
 	}
944
-	return false
945 945
 }
946 946
 
947 947
 func (sc *serverConn) processFrame(f Frame) error {
... ...
@@ -955,21 +1074,11 @@ func (sc *serverConn) processFrame(f Frame) error {
955 955
 		sc.sawFirstSettings = true
956 956
 	}
957 957
 
958
-	if s := sc.curHeaderStreamID(); s != 0 {
959
-		if cf, ok := f.(*ContinuationFrame); !ok {
960
-			return ConnectionError(ErrCodeProtocol)
961
-		} else if cf.Header().StreamID != s {
962
-			return ConnectionError(ErrCodeProtocol)
963
-		}
964
-	}
965
-
966 958
 	switch f := f.(type) {
967 959
 	case *SettingsFrame:
968 960
 		return sc.processSettings(f)
969
-	case *HeadersFrame:
961
+	case *MetaHeadersFrame:
970 962
 		return sc.processHeaders(f)
971
-	case *ContinuationFrame:
972
-		return sc.processContinuation(f)
973 963
 	case *WindowUpdateFrame:
974 964
 		return sc.processWindowUpdate(f)
975 965
 	case *PingFrame:
... ...
@@ -985,14 +1094,14 @@ func (sc *serverConn) processFrame(f Frame) error {
985 985
 		// frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
986 986
 		return ConnectionError(ErrCodeProtocol)
987 987
 	default:
988
-		log.Printf("Ignoring frame: %v", f.Header())
988
+		sc.vlogf("http2: server ignoring frame: %v", f.Header())
989 989
 		return nil
990 990
 	}
991 991
 }
992 992
 
993 993
 func (sc *serverConn) processPing(f *PingFrame) error {
994 994
 	sc.serveG.check()
995
-	if f.Flags.Has(FlagSettingsAck) {
995
+	if f.IsAck() {
996 996
 		// 6.7 PING: " An endpoint MUST NOT respond to PING frames
997 997
 		// containing this flag."
998 998
 		return nil
... ...
@@ -1060,12 +1169,27 @@ func (sc *serverConn) closeStream(st *stream, err error) {
1060 1060
 	}
1061 1061
 	st.state = stateClosed
1062 1062
 	sc.curOpenStreams--
1063
+	if sc.curOpenStreams == 0 {
1064
+		sc.setConnState(http.StateIdle)
1065
+	}
1063 1066
 	delete(sc.streams, st.id)
1064 1067
 	if p := st.body; p != nil {
1065
-		p.Close(err)
1068
+		p.CloseWithError(err)
1066 1069
 	}
1067 1070
 	st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc
1068 1071
 	sc.writeSched.forgetStream(st.id)
1072
+	if st.reqBuf != nil {
1073
+		// Stash this request body buffer (64k) away for reuse
1074
+		// by a future POST/PUT/etc.
1075
+		//
1076
+		// TODO(bradfitz): share on the server? sync.Pool?
1077
+		// Server requires locks and might hurt contention.
1078
+		// sync.Pool might work, or might be worse, depending
1079
+		// on goroutine CPU migrations. (get and put on
1080
+		// separate CPUs).  Maybe a mix of strategies. But
1081
+		// this is an easy win for now.
1082
+		sc.freeRequestBodyBuf = st.reqBuf
1083
+	}
1069 1084
 }
1070 1085
 
1071 1086
 func (sc *serverConn) processSettings(f *SettingsFrame) error {
... ...
@@ -1093,7 +1217,9 @@ func (sc *serverConn) processSetting(s Setting) error {
1093 1093
 	if err := s.Valid(); err != nil {
1094 1094
 		return err
1095 1095
 	}
1096
-	sc.vlogf("processing setting %v", s)
1096
+	if VerboseLogs {
1097
+		sc.vlogf("http2: server processing setting %v", s)
1098
+	}
1097 1099
 	switch s.ID {
1098 1100
 	case SettingHeaderTableSize:
1099 1101
 		sc.headerTableSize = s.Val
... ...
@@ -1107,11 +1233,14 @@ func (sc *serverConn) processSetting(s Setting) error {
1107 1107
 	case SettingMaxFrameSize:
1108 1108
 		sc.writeSched.maxFrameSize = s.Val
1109 1109
 	case SettingMaxHeaderListSize:
1110
-		sc.maxHeaderListSize = s.Val
1110
+		sc.peerMaxHeaderListSize = s.Val
1111 1111
 	default:
1112 1112
 		// Unknown setting: "An endpoint that receives a SETTINGS
1113 1113
 		// frame with any unknown or unsupported identifier MUST
1114 1114
 		// ignore that setting."
1115
+		if VerboseLogs {
1116
+			sc.vlogf("http2: server ignoring unknown setting %v", s)
1117
+		}
1115 1118
 	}
1116 1119
 	return nil
1117 1120
 }
... ...
@@ -1151,7 +1280,7 @@ func (sc *serverConn) processData(f *DataFrame) error {
1151 1151
 	// with a stream error (Section 5.4.2) of type STREAM_CLOSED."
1152 1152
 	id := f.Header().StreamID
1153 1153
 	st, ok := sc.streams[id]
1154
-	if !ok || st.state != stateOpen {
1154
+	if !ok || st.state != stateOpen || st.gotTrailerHeader {
1155 1155
 		// This includes sending a RST_STREAM if the stream is
1156 1156
 		// in stateHalfClosedLocal (which currently means that
1157 1157
 		// the http.Handler returned, so it's done reading &
... ...
@@ -1166,7 +1295,7 @@ func (sc *serverConn) processData(f *DataFrame) error {
1166 1166
 
1167 1167
 	// Sender sending more than they'd declared?
1168 1168
 	if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes {
1169
-		st.body.Close(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes))
1169
+		st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes))
1170 1170
 		return StreamError{id, ErrCodeStreamClosed}
1171 1171
 	}
1172 1172
 	if len(data) > 0 {
... ...
@@ -1185,18 +1314,39 @@ func (sc *serverConn) processData(f *DataFrame) error {
1185 1185
 		st.bodyBytes += int64(len(data))
1186 1186
 	}
1187 1187
 	if f.StreamEnded() {
1188
-		if st.declBodyBytes != -1 && st.declBodyBytes != st.bodyBytes {
1189
-			st.body.Close(fmt.Errorf("request declared a Content-Length of %d but only wrote %d bytes",
1190
-				st.declBodyBytes, st.bodyBytes))
1191
-		} else {
1192
-			st.body.Close(io.EOF)
1193
-		}
1194
-		st.state = stateHalfClosedRemote
1188
+		st.endStream()
1195 1189
 	}
1196 1190
 	return nil
1197 1191
 }
1198 1192
 
1199
-func (sc *serverConn) processHeaders(f *HeadersFrame) error {
1193
+// endStream closes a Request.Body's pipe. It is called when a DATA
1194
+// frame says a request body is over (or after trailers).
1195
+func (st *stream) endStream() {
1196
+	sc := st.sc
1197
+	sc.serveG.check()
1198
+
1199
+	if st.declBodyBytes != -1 && st.declBodyBytes != st.bodyBytes {
1200
+		st.body.CloseWithError(fmt.Errorf("request declared a Content-Length of %d but only wrote %d bytes",
1201
+			st.declBodyBytes, st.bodyBytes))
1202
+	} else {
1203
+		st.body.closeWithErrorAndCode(io.EOF, st.copyTrailersToHandlerRequest)
1204
+		st.body.CloseWithError(io.EOF)
1205
+	}
1206
+	st.state = stateHalfClosedRemote
1207
+}
1208
+
1209
+// copyTrailersToHandlerRequest is run in the Handler's goroutine in
1210
+// its Request.Body.Read just before it gets io.EOF.
1211
+func (st *stream) copyTrailersToHandlerRequest() {
1212
+	for k, vv := range st.trailer {
1213
+		if _, ok := st.reqTrailer[k]; ok {
1214
+			// Only copy it over it was pre-declared.
1215
+			st.reqTrailer[k] = vv
1216
+		}
1217
+	}
1218
+}
1219
+
1220
+func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
1200 1221
 	sc.serveG.check()
1201 1222
 	id := f.Header().StreamID
1202 1223
 	if sc.inGoAway {
... ...
@@ -1204,20 +1354,34 @@ func (sc *serverConn) processHeaders(f *HeadersFrame) error {
1204 1204
 		return nil
1205 1205
 	}
1206 1206
 	// http://http2.github.io/http2-spec/#rfc.section.5.1.1
1207
-	if id%2 != 1 || id <= sc.maxStreamID || sc.req.stream != nil {
1208
-		// Streams initiated by a client MUST use odd-numbered
1209
-		// stream identifiers. [...] The identifier of a newly
1210
-		// established stream MUST be numerically greater than all
1211
-		// streams that the initiating endpoint has opened or
1212
-		// reserved. [...]  An endpoint that receives an unexpected
1213
-		// stream identifier MUST respond with a connection error
1214
-		// (Section 5.4.1) of type PROTOCOL_ERROR.
1207
+	// Streams initiated by a client MUST use odd-numbered stream
1208
+	// identifiers. [...] An endpoint that receives an unexpected
1209
+	// stream identifier MUST respond with a connection error
1210
+	// (Section 5.4.1) of type PROTOCOL_ERROR.
1211
+	if id%2 != 1 {
1215 1212
 		return ConnectionError(ErrCodeProtocol)
1216 1213
 	}
1217
-	if id > sc.maxStreamID {
1218
-		sc.maxStreamID = id
1214
+	// A HEADERS frame can be used to create a new stream or
1215
+	// send a trailer for an open one. If we already have a stream
1216
+	// open, let it process its own HEADERS frame (trailers at this
1217
+	// point, if it's valid).
1218
+	st := sc.streams[f.Header().StreamID]
1219
+	if st != nil {
1220
+		return st.processTrailerHeaders(f)
1219 1221
 	}
1220
-	st := &stream{
1222
+
1223
+	// [...] The identifier of a newly established stream MUST be
1224
+	// numerically greater than all streams that the initiating
1225
+	// endpoint has opened or reserved. [...]  An endpoint that
1226
+	// receives an unexpected stream identifier MUST respond with
1227
+	// a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
1228
+	if id <= sc.maxStreamID {
1229
+		return ConnectionError(ErrCodeProtocol)
1230
+	}
1231
+	sc.maxStreamID = id
1232
+
1233
+	st = &stream{
1234
+		sc:    sc,
1221 1235
 		id:    id,
1222 1236
 		state: stateOpen,
1223 1237
 	}
... ...
@@ -1236,36 +1400,9 @@ func (sc *serverConn) processHeaders(f *HeadersFrame) error {
1236 1236
 		adjustStreamPriority(sc.streams, st.id, f.Priority)
1237 1237
 	}
1238 1238
 	sc.curOpenStreams++
1239
-	sc.req = requestParam{
1240
-		stream: st,
1241
-		header: make(http.Header),
1242
-	}
1243
-	return sc.processHeaderBlockFragment(st, f.HeaderBlockFragment(), f.HeadersEnded())
1244
-}
1245
-
1246
-func (sc *serverConn) processContinuation(f *ContinuationFrame) error {
1247
-	sc.serveG.check()
1248
-	st := sc.streams[f.Header().StreamID]
1249
-	if st == nil || sc.curHeaderStreamID() != st.id {
1250
-		return ConnectionError(ErrCodeProtocol)
1251
-	}
1252
-	return sc.processHeaderBlockFragment(st, f.HeaderBlockFragment(), f.HeadersEnded())
1253
-}
1254
-
1255
-func (sc *serverConn) processHeaderBlockFragment(st *stream, frag []byte, end bool) error {
1256
-	sc.serveG.check()
1257
-	if _, err := sc.hpackDecoder.Write(frag); err != nil {
1258
-		// TODO: convert to stream error I assume?
1259
-		return err
1239
+	if sc.curOpenStreams == 1 {
1240
+		sc.setConnState(http.StateActive)
1260 1241
 	}
1261
-	if !end {
1262
-		return nil
1263
-	}
1264
-	if err := sc.hpackDecoder.Close(); err != nil {
1265
-		// TODO: convert to stream error I assume?
1266
-		return err
1267
-	}
1268
-	defer sc.resetPendingRequest()
1269 1242
 	if sc.curOpenStreams > sc.advMaxStreams {
1270 1243
 		// "Endpoints MUST NOT exceed the limit set by their
1271 1244
 		// peer. An endpoint that receives a HEADERS frame
... ...
@@ -1285,13 +1422,48 @@ func (sc *serverConn) processHeaderBlockFragment(st *stream, frag []byte, end bo
1285 1285
 		return StreamError{st.id, ErrCodeRefusedStream}
1286 1286
 	}
1287 1287
 
1288
-	rw, req, err := sc.newWriterAndRequest()
1288
+	rw, req, err := sc.newWriterAndRequest(st, f)
1289 1289
 	if err != nil {
1290 1290
 		return err
1291 1291
 	}
1292
+	st.reqTrailer = req.Trailer
1293
+	if st.reqTrailer != nil {
1294
+		st.trailer = make(http.Header)
1295
+	}
1292 1296
 	st.body = req.Body.(*requestBody).pipe // may be nil
1293 1297
 	st.declBodyBytes = req.ContentLength
1294
-	go sc.runHandler(rw, req)
1298
+
1299
+	handler := sc.handler.ServeHTTP
1300
+	if f.Truncated {
1301
+		// Their header list was too long. Send a 431 error.
1302
+		handler = handleHeaderListTooLong
1303
+	}
1304
+
1305
+	go sc.runHandler(rw, req, handler)
1306
+	return nil
1307
+}
1308
+
1309
+func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error {
1310
+	sc := st.sc
1311
+	sc.serveG.check()
1312
+	if st.gotTrailerHeader {
1313
+		return ConnectionError(ErrCodeProtocol)
1314
+	}
1315
+	st.gotTrailerHeader = true
1316
+	if !f.StreamEnded() {
1317
+		return StreamError{st.id, ErrCodeProtocol}
1318
+	}
1319
+
1320
+	if len(f.PseudoFields()) > 0 {
1321
+		return StreamError{st.id, ErrCodeProtocol}
1322
+	}
1323
+	if st.trailer != nil {
1324
+		for _, hf := range f.RegularFields() {
1325
+			key := sc.canonicalHeader(hf.Name)
1326
+			st.trailer[key] = append(st.trailer[key], hf.Value)
1327
+		}
1328
+	}
1329
+	st.endStream()
1295 1330
 	return nil
1296 1331
 }
1297 1332
 
... ...
@@ -1336,19 +1508,21 @@ func adjustStreamPriority(streams map[uint32]*stream, streamID uint32, priority
1336 1336
 	}
1337 1337
 }
1338 1338
 
1339
-// resetPendingRequest zeros out all state related to a HEADERS frame
1340
-// and its zero or more CONTINUATION frames sent to start a new
1341
-// request.
1342
-func (sc *serverConn) resetPendingRequest() {
1339
+func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*responseWriter, *http.Request, error) {
1343 1340
 	sc.serveG.check()
1344
-	sc.req = requestParam{}
1345
-}
1346 1341
 
1347
-func (sc *serverConn) newWriterAndRequest() (*responseWriter, *http.Request, error) {
1348
-	sc.serveG.check()
1349
-	rp := &sc.req
1350
-	if rp.invalidHeader || rp.method == "" || rp.path == "" ||
1351
-		(rp.scheme != "https" && rp.scheme != "http") {
1342
+	method := f.PseudoValue("method")
1343
+	path := f.PseudoValue("path")
1344
+	scheme := f.PseudoValue("scheme")
1345
+	authority := f.PseudoValue("authority")
1346
+
1347
+	isConnect := method == "CONNECT"
1348
+	if isConnect {
1349
+		if path != "" || scheme != "" || authority == "" {
1350
+			return nil, nil, StreamError{f.StreamID, ErrCodeProtocol}
1351
+		}
1352
+	} else if method == "" || path == "" ||
1353
+		(scheme != "https" && scheme != "http") {
1352 1354
 		// See 8.1.2.6 Malformed Requests and Responses:
1353 1355
 		//
1354 1356
 		// Malformed requests or responses that are detected
... ...
@@ -1359,52 +1533,99 @@ func (sc *serverConn) newWriterAndRequest() (*responseWriter, *http.Request, err
1359 1359
 		// "All HTTP/2 requests MUST include exactly one valid
1360 1360
 		// value for the :method, :scheme, and :path
1361 1361
 		// pseudo-header fields"
1362
-		return nil, nil, StreamError{rp.stream.id, ErrCodeProtocol}
1362
+		return nil, nil, StreamError{f.StreamID, ErrCodeProtocol}
1363
+	}
1364
+
1365
+	bodyOpen := !f.StreamEnded()
1366
+	if method == "HEAD" && bodyOpen {
1367
+		// HEAD requests can't have bodies
1368
+		return nil, nil, StreamError{f.StreamID, ErrCodeProtocol}
1363 1369
 	}
1364 1370
 	var tlsState *tls.ConnectionState // nil if not scheme https
1365
-	if rp.scheme == "https" {
1371
+
1372
+	if scheme == "https" {
1366 1373
 		tlsState = sc.tlsState
1367 1374
 	}
1368
-	authority := rp.authority
1375
+
1376
+	header := make(http.Header)
1377
+	for _, hf := range f.RegularFields() {
1378
+		header.Add(sc.canonicalHeader(hf.Name), hf.Value)
1379
+	}
1380
+
1369 1381
 	if authority == "" {
1370
-		authority = rp.header.Get("Host")
1382
+		authority = header.Get("Host")
1371 1383
 	}
1372
-	needsContinue := rp.header.Get("Expect") == "100-continue"
1384
+	needsContinue := header.Get("Expect") == "100-continue"
1373 1385
 	if needsContinue {
1374
-		rp.header.Del("Expect")
1386
+		header.Del("Expect")
1387
+	}
1388
+	// Merge Cookie headers into one "; "-delimited value.
1389
+	if cookies := header["Cookie"]; len(cookies) > 1 {
1390
+		header.Set("Cookie", strings.Join(cookies, "; "))
1391
+	}
1392
+
1393
+	// Setup Trailers
1394
+	var trailer http.Header
1395
+	for _, v := range header["Trailer"] {
1396
+		for _, key := range strings.Split(v, ",") {
1397
+			key = http.CanonicalHeaderKey(strings.TrimSpace(key))
1398
+			switch key {
1399
+			case "Transfer-Encoding", "Trailer", "Content-Length":
1400
+				// Bogus. (copy of http1 rules)
1401
+				// Ignore.
1402
+			default:
1403
+				if trailer == nil {
1404
+					trailer = make(http.Header)
1405
+				}
1406
+				trailer[key] = nil
1407
+			}
1408
+		}
1375 1409
 	}
1376
-	bodyOpen := rp.stream.state == stateOpen
1410
+	delete(header, "Trailer")
1411
+
1377 1412
 	body := &requestBody{
1378 1413
 		conn:          sc,
1379
-		stream:        rp.stream,
1414
+		stream:        st,
1380 1415
 		needsContinue: needsContinue,
1381 1416
 	}
1382
-	// TODO: handle asterisk '*' requests + test
1383
-	url, err := url.ParseRequestURI(rp.path)
1384
-	if err != nil {
1385
-		// TODO: find the right error code?
1386
-		return nil, nil, StreamError{rp.stream.id, ErrCodeProtocol}
1417
+	var url_ *url.URL
1418
+	var requestURI string
1419
+	if isConnect {
1420
+		url_ = &url.URL{Host: authority}
1421
+		requestURI = authority // mimic HTTP/1 server behavior
1422
+	} else {
1423
+		var err error
1424
+		url_, err = url.ParseRequestURI(path)
1425
+		if err != nil {
1426
+			return nil, nil, StreamError{f.StreamID, ErrCodeProtocol}
1427
+		}
1428
+		requestURI = path
1387 1429
 	}
1388 1430
 	req := &http.Request{
1389
-		Method:     rp.method,
1390
-		URL:        url,
1431
+		Method:     method,
1432
+		URL:        url_,
1391 1433
 		RemoteAddr: sc.remoteAddrStr,
1392
-		Header:     rp.header,
1393
-		RequestURI: rp.path,
1434
+		Header:     header,
1435
+		RequestURI: requestURI,
1394 1436
 		Proto:      "HTTP/2.0",
1395 1437
 		ProtoMajor: 2,
1396 1438
 		ProtoMinor: 0,
1397 1439
 		TLS:        tlsState,
1398 1440
 		Host:       authority,
1399 1441
 		Body:       body,
1442
+		Trailer:    trailer,
1400 1443
 	}
1401 1444
 	if bodyOpen {
1445
+		// Disabled, per golang.org/issue/14960:
1446
+		// st.reqBuf = sc.getRequestBodyBuf()
1447
+		// TODO: remove this 64k of garbage per request (again, but without a data race):
1448
+		buf := make([]byte, initialWindowSize)
1449
+
1402 1450
 		body.pipe = &pipe{
1403
-			b: buffer{buf: make([]byte, initialWindowSize)}, // TODO: share/remove XXX
1451
+			b: &fixedBuffer{buf: buf},
1404 1452
 		}
1405
-		body.pipe.c.L = &body.pipe.m
1406 1453
 
1407
-		if vv, ok := rp.header["Content-Length"]; ok {
1454
+		if vv, ok := header["Content-Length"]; ok {
1408 1455
 			req.ContentLength, _ = strconv.ParseInt(vv[0], 10, 64)
1409 1456
 		} else {
1410 1457
 			req.ContentLength = -1
... ...
@@ -1417,25 +1638,59 @@ func (sc *serverConn) newWriterAndRequest() (*responseWriter, *http.Request, err
1417 1417
 	rws.conn = sc
1418 1418
 	rws.bw = bwSave
1419 1419
 	rws.bw.Reset(chunkWriter{rws})
1420
-	rws.stream = rp.stream
1420
+	rws.stream = st
1421 1421
 	rws.req = req
1422 1422
 	rws.body = body
1423
-	rws.frameWriteCh = make(chan error, 1)
1424 1423
 
1425 1424
 	rw := &responseWriter{rws: rws}
1426 1425
 	return rw, req, nil
1427 1426
 }
1428 1427
 
1428
+func (sc *serverConn) getRequestBodyBuf() []byte {
1429
+	sc.serveG.check()
1430
+	if buf := sc.freeRequestBodyBuf; buf != nil {
1431
+		sc.freeRequestBodyBuf = nil
1432
+		return buf
1433
+	}
1434
+	return make([]byte, initialWindowSize)
1435
+}
1436
+
1429 1437
 // Run on its own goroutine.
1430
-func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request) {
1431
-	defer rw.handlerDone()
1432
-	// TODO: catch panics like net/http.Server
1433
-	sc.handler.ServeHTTP(rw, req)
1438
+func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) {
1439
+	didPanic := true
1440
+	defer func() {
1441
+		if didPanic {
1442
+			e := recover()
1443
+			// Same as net/http:
1444
+			const size = 64 << 10
1445
+			buf := make([]byte, size)
1446
+			buf = buf[:runtime.Stack(buf, false)]
1447
+			sc.writeFrameFromHandler(frameWriteMsg{
1448
+				write:  handlerPanicRST{rw.rws.stream.id},
1449
+				stream: rw.rws.stream,
1450
+			})
1451
+			sc.logf("http2: panic serving %v: %v\n%s", sc.conn.RemoteAddr(), e, buf)
1452
+			return
1453
+		}
1454
+		rw.handlerDone()
1455
+	}()
1456
+	handler(rw, req)
1457
+	didPanic = false
1458
+}
1459
+
1460
+func handleHeaderListTooLong(w http.ResponseWriter, r *http.Request) {
1461
+	// 10.5.1 Limits on Header Block Size:
1462
+	// .. "A server that receives a larger header block than it is
1463
+	// willing to handle can send an HTTP 431 (Request Header Fields Too
1464
+	// Large) status code"
1465
+	const statusRequestHeaderFieldsTooLarge = 431 // only in Go 1.6+
1466
+	w.WriteHeader(statusRequestHeaderFieldsTooLarge)
1467
+	io.WriteString(w, "<h1>HTTP Error 431</h1><p>Request Header Field(s) Too Large</p>")
1434 1468
 }
1435 1469
 
1436 1470
 // called from handler goroutines.
1437 1471
 // h may be nil.
1438
-func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders, tempCh chan error) {
1472
+func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) error {
1439 1473
 	sc.serveG.checkNotOn() // NOT on
1440 1474
 	var errc chan error
1441 1475
 	if headerData.h != nil {
... ...
@@ -1443,22 +1698,27 @@ func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders, temp
1443 1443
 		// waiting for this frame to be written, so an http.Flush mid-handler
1444 1444
 		// writes out the correct value of keys, before a handler later potentially
1445 1445
 		// mutates it.
1446
-		errc = tempCh
1446
+		errc = errChanPool.Get().(chan error)
1447 1447
 	}
1448
-	sc.writeFrameFromHandler(frameWriteMsg{
1448
+	if err := sc.writeFrameFromHandler(frameWriteMsg{
1449 1449
 		write:  headerData,
1450 1450
 		stream: st,
1451 1451
 		done:   errc,
1452
-	})
1452
+	}); err != nil {
1453
+		return err
1454
+	}
1453 1455
 	if errc != nil {
1454 1456
 		select {
1455
-		case <-errc:
1456
-			// Ignore. Just for synchronization.
1457
-			// Any error will be handled in the writing goroutine.
1457
+		case err := <-errc:
1458
+			errChanPool.Put(errc)
1459
+			return err
1458 1460
 		case <-sc.doneServing:
1459
-			// Client has closed the connection.
1461
+			return errClientDisconnected
1462
+		case <-st.cw:
1463
+			return errStreamClosed
1460 1464
 		}
1461 1465
 	}
1466
+	return nil
1462 1467
 }
1463 1468
 
1464 1469
 // called from handler goroutines.
... ...
@@ -1481,7 +1741,10 @@ type bodyReadMsg struct {
1481 1481
 // and schedules flow control tokens to be sent.
1482 1482
 func (sc *serverConn) noteBodyReadFromHandler(st *stream, n int) {
1483 1483
 	sc.serveG.checkNotOn() // NOT on
1484
-	sc.bodyReadCh <- bodyReadMsg{st, n}
1484
+	select {
1485
+	case sc.bodyReadCh <- bodyReadMsg{st, n}:
1486
+	case <-sc.doneServing:
1487
+	}
1485 1488
 }
1486 1489
 
1487 1490
 func (sc *serverConn) noteBodyRead(st *stream, n int) {
... ...
@@ -1548,7 +1811,7 @@ type requestBody struct {
1548 1548
 
1549 1549
 func (b *requestBody) Close() error {
1550 1550
 	if b.pipe != nil {
1551
-		b.pipe.Close(errClosedBody)
1551
+		b.pipe.CloseWithError(errClosedBody)
1552 1552
 	}
1553 1553
 	b.closed = true
1554 1554
 	return nil
... ...
@@ -1599,12 +1862,14 @@ type responseWriterState struct {
1599 1599
 	// mutated by http.Handler goroutine:
1600 1600
 	handlerHeader http.Header // nil until called
1601 1601
 	snapHeader    http.Header // snapshot of handlerHeader at WriteHeader time
1602
+	trailers      []string    // set in writeChunk
1602 1603
 	status        int         // status code passed to WriteHeader
1603 1604
 	wroteHeader   bool        // WriteHeader called (explicitly or implicitly). Not necessarily sent to user yet.
1604 1605
 	sentHeader    bool        // have we sent the header frame?
1605 1606
 	handlerDone   bool        // handler has finished
1606
-	curWrite      writeData
1607
-	frameWriteCh  chan error // re-used whenever we need to block on a frame being written
1607
+
1608
+	sentContentLen int64 // non-zero if handler set a Content-Length header
1609
+	wroteBytes     int64
1608 1610
 
1609 1611
 	closeNotifierMu sync.Mutex // guards closeNotifierCh
1610 1612
 	closeNotifierCh chan bool  // nil until first used
... ...
@@ -1614,6 +1879,23 @@ type chunkWriter struct{ rws *responseWriterState }
1614 1614
 
1615 1615
 func (cw chunkWriter) Write(p []byte) (n int, err error) { return cw.rws.writeChunk(p) }
1616 1616
 
1617
+func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) != 0 }
1618
+
1619
+// declareTrailer is called for each Trailer header when the
1620
+// response header is written. It notes that a header will need to be
1621
+// written in the trailers at the end of the response.
1622
+func (rws *responseWriterState) declareTrailer(k string) {
1623
+	k = http.CanonicalHeaderKey(k)
1624
+	switch k {
1625
+	case "Transfer-Encoding", "Content-Length", "Trailer":
1626
+		// Forbidden by RFC 2616 14.40.
1627
+		return
1628
+	}
1629
+	if !strSliceContains(rws.trailers, k) {
1630
+		rws.trailers = append(rws.trailers, k)
1631
+	}
1632
+}
1633
+
1617 1634
 // writeChunk writes chunks from the bufio.Writer. But because
1618 1635
 // bufio.Writer may bypass its chunking, sometimes p may be
1619 1636
 // arbitrarily large.
... ...
@@ -1624,41 +1906,137 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
1624 1624
 	if !rws.wroteHeader {
1625 1625
 		rws.writeHeader(200)
1626 1626
 	}
1627
+
1628
+	isHeadResp := rws.req.Method == "HEAD"
1627 1629
 	if !rws.sentHeader {
1628 1630
 		rws.sentHeader = true
1629
-		var ctype, clen string // implicit ones, if we can calculate it
1630
-		if rws.handlerDone && rws.snapHeader.Get("Content-Length") == "" {
1631
+		var ctype, clen string
1632
+		if clen = rws.snapHeader.Get("Content-Length"); clen != "" {
1633
+			rws.snapHeader.Del("Content-Length")
1634
+			clen64, err := strconv.ParseInt(clen, 10, 64)
1635
+			if err == nil && clen64 >= 0 {
1636
+				rws.sentContentLen = clen64
1637
+			} else {
1638
+				clen = ""
1639
+			}
1640
+		}
1641
+		if clen == "" && rws.handlerDone && bodyAllowedForStatus(rws.status) && (len(p) > 0 || !isHeadResp) {
1631 1642
 			clen = strconv.Itoa(len(p))
1632 1643
 		}
1633
-		if rws.snapHeader.Get("Content-Type") == "" {
1644
+		_, hasContentType := rws.snapHeader["Content-Type"]
1645
+		if !hasContentType && bodyAllowedForStatus(rws.status) {
1634 1646
 			ctype = http.DetectContentType(p)
1635 1647
 		}
1636
-		endStream := rws.handlerDone && len(p) == 0
1637
-		rws.conn.writeHeaders(rws.stream, &writeResHeaders{
1648
+		var date string
1649
+		if _, ok := rws.snapHeader["Date"]; !ok {
1650
+			// TODO(bradfitz): be faster here, like net/http? measure.
1651
+			date = time.Now().UTC().Format(http.TimeFormat)
1652
+		}
1653
+
1654
+		for _, v := range rws.snapHeader["Trailer"] {
1655
+			foreachHeaderElement(v, rws.declareTrailer)
1656
+		}
1657
+
1658
+		endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp
1659
+		err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
1638 1660
 			streamID:      rws.stream.id,
1639 1661
 			httpResCode:   rws.status,
1640 1662
 			h:             rws.snapHeader,
1641 1663
 			endStream:     endStream,
1642 1664
 			contentType:   ctype,
1643 1665
 			contentLength: clen,
1644
-		}, rws.frameWriteCh)
1666
+			date:          date,
1667
+		})
1668
+		if err != nil {
1669
+			return 0, err
1670
+		}
1645 1671
 		if endStream {
1646 1672
 			return 0, nil
1647 1673
 		}
1648 1674
 	}
1675
+	if isHeadResp {
1676
+		return len(p), nil
1677
+	}
1649 1678
 	if len(p) == 0 && !rws.handlerDone {
1650 1679
 		return 0, nil
1651 1680
 	}
1652
-	curWrite := &rws.curWrite
1653
-	curWrite.streamID = rws.stream.id
1654
-	curWrite.p = p
1655
-	curWrite.endStream = rws.handlerDone
1656
-	if err := rws.conn.writeDataFromHandler(rws.stream, curWrite, rws.frameWriteCh); err != nil {
1657
-		return 0, err
1681
+
1682
+	if rws.handlerDone {
1683
+		rws.promoteUndeclaredTrailers()
1684
+	}
1685
+
1686
+	endStream := rws.handlerDone && !rws.hasTrailers()
1687
+	if len(p) > 0 || endStream {
1688
+		// only send a 0 byte DATA frame if we're ending the stream.
1689
+		if err := rws.conn.writeDataFromHandler(rws.stream, p, endStream); err != nil {
1690
+			return 0, err
1691
+		}
1692
+	}
1693
+
1694
+	if rws.handlerDone && rws.hasTrailers() {
1695
+		err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
1696
+			streamID:  rws.stream.id,
1697
+			h:         rws.handlerHeader,
1698
+			trailers:  rws.trailers,
1699
+			endStream: true,
1700
+		})
1701
+		return len(p), err
1658 1702
 	}
1659 1703
 	return len(p), nil
1660 1704
 }
1661 1705
 
1706
+// TrailerPrefix is a magic prefix for ResponseWriter.Header map keys
1707
+// that, if present, signals that the map entry is actually for
1708
+// the response trailers, and not the response headers. The prefix
1709
+// is stripped after the ServeHTTP call finishes and the values are
1710
+// sent in the trailers.
1711
+//
1712
+// This mechanism is intended only for trailers that are not known
1713
+// prior to the headers being written. If the set of trailers is fixed
1714
+// or known before the header is written, the normal Go trailers mechanism
1715
+// is preferred:
1716
+//    https://golang.org/pkg/net/http/#ResponseWriter
1717
+//    https://golang.org/pkg/net/http/#example_ResponseWriter_trailers
1718
+const TrailerPrefix = "Trailer:"
1719
+
1720
+// promoteUndeclaredTrailers permits http.Handlers to set trailers
1721
+// after the header has already been flushed. Because the Go
1722
+// ResponseWriter interface has no way to set Trailers (only the
1723
+// Header), and because we didn't want to expand the ResponseWriter
1724
+// interface, and because nobody used trailers, and because RFC 2616
1725
+// says you SHOULD (but not must) predeclare any trailers in the
1726
+// header, the official ResponseWriter rules said trailers in Go must
1727
+// be predeclared, and then we reuse the same ResponseWriter.Header()
1728
+// map to mean both Headers and Trailers.  When it's time to write the
1729
+// Trailers, we pick out the fields of Headers that were declared as
1730
+// trailers. That worked for a while, until we found the first major
1731
+// user of Trailers in the wild: gRPC (using them only over http2),
1732
+// and gRPC libraries permit setting trailers mid-stream without
1733
+// predeclarnig them. So: change of plans. We still permit the old
1734
+// way, but we also permit this hack: if a Header() key begins with
1735
+// "Trailer:", the suffix of that key is a Trailer. Because ':' is an
1736
+// invalid token byte anyway, there is no ambiguity. (And it's already
1737
+// filtered out) It's mildly hacky, but not terrible.
1738
+//
1739
+// This method runs after the Handler is done and promotes any Header
1740
+// fields to be trailers.
1741
+func (rws *responseWriterState) promoteUndeclaredTrailers() {
1742
+	for k, vv := range rws.handlerHeader {
1743
+		if !strings.HasPrefix(k, TrailerPrefix) {
1744
+			continue
1745
+		}
1746
+		trailerKey := strings.TrimPrefix(k, TrailerPrefix)
1747
+		rws.declareTrailer(trailerKey)
1748
+		rws.handlerHeader[http.CanonicalHeaderKey(trailerKey)] = vv
1749
+	}
1750
+
1751
+	if len(rws.trailers) > 1 {
1752
+		sorter := sorterPool.Get().(*sorter)
1753
+		sorter.SortStrings(rws.trailers)
1754
+		sorterPool.Put(sorter)
1755
+	}
1756
+}
1757
+
1662 1758
 func (w *responseWriter) Flush() {
1663 1759
 	rws := w.rws
1664 1760
 	if rws == nil {
... ...
@@ -1761,6 +2139,15 @@ func (w *responseWriter) write(lenData int, dataB []byte, dataS string) (n int,
1761 1761
 	if !rws.wroteHeader {
1762 1762
 		w.WriteHeader(200)
1763 1763
 	}
1764
+	if !bodyAllowedForStatus(rws.status) {
1765
+		return 0, http.ErrBodyNotAllowed
1766
+	}
1767
+	rws.wroteBytes += int64(len(dataB)) + int64(len(dataS)) // only one can be set
1768
+	if rws.sentContentLen != 0 && rws.wroteBytes > rws.sentContentLen {
1769
+		// TODO: send a RST_STREAM
1770
+		return 0, errors.New("http2: handler wrote more than declared Content-Length")
1771
+	}
1772
+
1764 1773
 	if dataB != nil {
1765 1774
 		return rws.bw.Write(dataB)
1766 1775
 	} else {
... ...
@@ -1770,11 +2157,26 @@ func (w *responseWriter) write(lenData int, dataB []byte, dataS string) (n int,
1770 1770
 
1771 1771
 func (w *responseWriter) handlerDone() {
1772 1772
 	rws := w.rws
1773
-	if rws == nil {
1774
-		panic("handlerDone called twice")
1775
-	}
1776 1773
 	rws.handlerDone = true
1777 1774
 	w.Flush()
1778 1775
 	w.rws = nil
1779 1776
 	responseWriterStatePool.Put(rws)
1780 1777
 }
1778
+
1779
+// foreachHeaderElement splits v according to the "#rule" construction
1780
+// in RFC 2616 section 2.1 and calls fn for each non-empty element.
1781
+func foreachHeaderElement(v string, fn func(string)) {
1782
+	v = textproto.TrimString(v)
1783
+	if v == "" {
1784
+		return
1785
+	}
1786
+	if !strings.Contains(v, ",") {
1787
+		fn(v)
1788
+		return
1789
+	}
1790
+	for _, f := range strings.Split(v, ",") {
1791
+		if f = textproto.TrimString(f); f != "" {
1792
+			fn(f)
1793
+		}
1794
+	}
1795
+}
... ...
@@ -1,55 +1,156 @@
1
-// Copyright 2015 The Go Authors.
2
-// See https://go.googlesource.com/go/+/master/CONTRIBUTORS
3
-// Licensed under the same terms as Go itself:
4
-// https://go.googlesource.com/go/+/master/LICENSE
1
+// Copyright 2015 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
4
+
5
+// Transport code.
5 6
 
6 7
 package http2
7 8
 
8 9
 import (
9 10
 	"bufio"
10 11
 	"bytes"
12
+	"compress/gzip"
11 13
 	"crypto/tls"
12 14
 	"errors"
13 15
 	"fmt"
14 16
 	"io"
17
+	"io/ioutil"
15 18
 	"log"
16 19
 	"net"
17 20
 	"net/http"
21
+	"sort"
18 22
 	"strconv"
19 23
 	"strings"
20 24
 	"sync"
25
+	"time"
21 26
 
22 27
 	"golang.org/x/net/http2/hpack"
23 28
 )
24 29
 
30
+const (
31
+	// transportDefaultConnFlow is how many connection-level flow control
32
+	// tokens we give the server at start-up, past the default 64k.
33
+	transportDefaultConnFlow = 1 << 30
34
+
35
+	// transportDefaultStreamFlow is how many stream-level flow
36
+	// control tokens we announce to the peer, and how many bytes
37
+	// we buffer per stream.
38
+	transportDefaultStreamFlow = 4 << 20
39
+
40
+	// transportDefaultStreamMinRefresh is the minimum number of bytes we'll send
41
+	// a stream-level WINDOW_UPDATE for at a time.
42
+	transportDefaultStreamMinRefresh = 4 << 10
43
+
44
+	defaultUserAgent = "Go-http-client/2.0"
45
+)
46
+
47
+// Transport is an HTTP/2 Transport.
48
+//
49
+// A Transport internally caches connections to servers. It is safe
50
+// for concurrent use by multiple goroutines.
25 51
 type Transport struct {
26
-	Fallback http.RoundTripper
52
+	// DialTLS specifies an optional dial function for creating
53
+	// TLS connections for requests.
54
+	//
55
+	// If DialTLS is nil, tls.Dial is used.
56
+	//
57
+	// If the returned net.Conn has a ConnectionState method like tls.Conn,
58
+	// it will be used to set http.Response.TLS.
59
+	DialTLS func(network, addr string, cfg *tls.Config) (net.Conn, error)
60
+
61
+	// TLSClientConfig specifies the TLS configuration to use with
62
+	// tls.Client. If nil, the default configuration is used.
63
+	TLSClientConfig *tls.Config
64
+
65
+	// ConnPool optionally specifies an alternate connection pool to use.
66
+	// If nil, the default is used.
67
+	ConnPool ClientConnPool
68
+
69
+	// DisableCompression, if true, prevents the Transport from
70
+	// requesting compression with an "Accept-Encoding: gzip"
71
+	// request header when the Request contains no existing
72
+	// Accept-Encoding value. If the Transport requests gzip on
73
+	// its own and gets a gzipped response, it's transparently
74
+	// decoded in the Response.Body. However, if the user
75
+	// explicitly requested gzip it is not automatically
76
+	// uncompressed.
77
+	DisableCompression bool
78
+
79
+	// MaxHeaderListSize is the http2 SETTINGS_MAX_HEADER_LIST_SIZE to
80
+	// send in the initial settings frame. It is how many bytes
81
+	// of response headers are allow. Unlike the http2 spec, zero here
82
+	// means to use a default limit (currently 10MB). If you actually
83
+	// want to advertise an ulimited value to the peer, Transport
84
+	// interprets the highest possible value here (0xffffffff or 1<<32-1)
85
+	// to mean no limit.
86
+	MaxHeaderListSize uint32
87
+
88
+	// t1, if non-nil, is the standard library Transport using
89
+	// this transport. Its settings are used (but not its
90
+	// RoundTrip method, etc).
91
+	t1 *http.Transport
92
+
93
+	connPoolOnce  sync.Once
94
+	connPoolOrDef ClientConnPool // non-nil version of ConnPool
95
+}
96
+
97
+func (t *Transport) maxHeaderListSize() uint32 {
98
+	if t.MaxHeaderListSize == 0 {
99
+		return 10 << 20
100
+	}
101
+	if t.MaxHeaderListSize == 0xffffffff {
102
+		return 0
103
+	}
104
+	return t.MaxHeaderListSize
105
+}
106
+
107
+func (t *Transport) disableCompression() bool {
108
+	return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression)
109
+}
110
+
111
+var errTransportVersion = errors.New("http2: ConfigureTransport is only supported starting at Go 1.6")
112
+
113
+// ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2.
114
+// It requires Go 1.6 or later and returns an error if the net/http package is too old
115
+// or if t1 has already been HTTP/2-enabled.
116
+func ConfigureTransport(t1 *http.Transport) error {
117
+	_, err := configureTransport(t1) // in configure_transport.go (go1.6) or not_go16.go
118
+	return err
119
+}
27 120
 
28
-	// TODO: remove this and make more general with a TLS dial hook, like http
29
-	InsecureTLSDial bool
121
+func (t *Transport) connPool() ClientConnPool {
122
+	t.connPoolOnce.Do(t.initConnPool)
123
+	return t.connPoolOrDef
124
+}
30 125
 
31
-	connMu sync.Mutex
32
-	conns  map[string][]*clientConn // key is host:port
126
+func (t *Transport) initConnPool() {
127
+	if t.ConnPool != nil {
128
+		t.connPoolOrDef = t.ConnPool
129
+	} else {
130
+		t.connPoolOrDef = &clientConnPool{t: t}
131
+	}
33 132
 }
34 133
 
35
-type clientConn struct {
134
+// ClientConn is the state of a single HTTP/2 client connection to an
135
+// HTTP/2 server.
136
+type ClientConn struct {
36 137
 	t        *Transport
37
-	tconn    *tls.Conn
38
-	tlsState *tls.ConnectionState
39
-	connKey  []string // key(s) this connection is cached in, in t.conns
138
+	tconn    net.Conn             // usually *tls.Conn, except specialized impls
139
+	tlsState *tls.ConnectionState // nil only for specialized impls
40 140
 
141
+	// readLoop goroutine fields:
41 142
 	readerDone chan struct{} // closed on error
42 143
 	readerErr  error         // set before readerDone is closed
43
-	hdec       *hpack.Decoder
44
-	nextRes    *http.Response
45 144
 
46
-	mu           sync.Mutex
145
+	mu           sync.Mutex // guards following
146
+	cond         *sync.Cond // hold mu; broadcast on flow/closed changes
147
+	flow         flow       // our conn-level flow control quota (cs.flow is per stream)
148
+	inflow       flow       // peer's conn-level flow control
47 149
 	closed       bool
48
-	goAway       *GoAwayFrame // if non-nil, the GoAwayFrame we received
49
-	streams      map[uint32]*clientStream
150
+	goAway       *GoAwayFrame             // if non-nil, the GoAwayFrame we received
151
+	streams      map[uint32]*clientStream // client-initiated
50 152
 	nextStreamID uint32
51 153
 	bw           *bufio.Writer
52
-	werr         error // first write error that has occurred
53 154
 	br           *bufio.Reader
54 155
 	fr           *Framer
55 156
 	// Settings from peer:
... ...
@@ -58,13 +159,78 @@ type clientConn struct {
58 58
 	initialWindowSize    uint32
59 59
 	hbuf                 bytes.Buffer // HPACK encoder writes into this
60 60
 	henc                 *hpack.Encoder
61
+	freeBuf              [][]byte
62
+
63
+	wmu  sync.Mutex // held while writing; acquire AFTER mu if holding both
64
+	werr error      // first write error that has occurred
61 65
 }
62 66
 
67
+// clientStream is the state for a single HTTP/2 stream. One of these
68
+// is created for each Transport.RoundTrip call.
63 69
 type clientStream struct {
64
-	ID   uint32
65
-	resc chan resAndError
66
-	pw   *io.PipeWriter
67
-	pr   *io.PipeReader
70
+	cc            *ClientConn
71
+	req           *http.Request
72
+	ID            uint32
73
+	resc          chan resAndError
74
+	bufPipe       pipe // buffered pipe with the flow-controlled response payload
75
+	requestedGzip bool
76
+
77
+	flow        flow  // guarded by cc.mu
78
+	inflow      flow  // guarded by cc.mu
79
+	bytesRemain int64 // -1 means unknown; owned by transportResponseBody.Read
80
+	readErr     error // sticky read error; owned by transportResponseBody.Read
81
+	stopReqBody error // if non-nil, stop writing req body; guarded by cc.mu
82
+
83
+	peerReset chan struct{} // closed on peer reset
84
+	resetErr  error         // populated before peerReset is closed
85
+
86
+	done chan struct{} // closed when stream remove from cc.streams map; close calls guarded by cc.mu
87
+
88
+	// owned by clientConnReadLoop:
89
+	pastHeaders  bool // got first MetaHeadersFrame (actual headers)
90
+	pastTrailers bool // got optional second MetaHeadersFrame (trailers)
91
+
92
+	trailer    http.Header  // accumulated trailers
93
+	resTrailer *http.Header // client's Response.Trailer
94
+}
95
+
96
+// awaitRequestCancel runs in its own goroutine and waits for the user
97
+// to either cancel a RoundTrip request (using the provided
98
+// Request.Cancel channel), or for the request to be done (any way it
99
+// might be removed from the cc.streams map: peer reset, successful
100
+// completion, TCP connection breakage, etc)
101
+func (cs *clientStream) awaitRequestCancel(cancel <-chan struct{}) {
102
+	if cancel == nil {
103
+		return
104
+	}
105
+	select {
106
+	case <-cancel:
107
+		cs.bufPipe.CloseWithError(errRequestCanceled)
108
+		cs.cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
109
+	case <-cs.done:
110
+	}
111
+}
112
+
113
+// checkReset reports any error sent in a RST_STREAM frame by the
114
+// server.
115
+func (cs *clientStream) checkReset() error {
116
+	select {
117
+	case <-cs.peerReset:
118
+		return cs.resetErr
119
+	default:
120
+		return nil
121
+	}
122
+}
123
+
124
+func (cs *clientStream) abortRequestBodyWrite(err error) {
125
+	if err == nil {
126
+		panic("nil error")
127
+	}
128
+	cc := cs.cc
129
+	cc.mu.Lock()
130
+	cs.stopReqBody = err
131
+	cc.cond.Broadcast()
132
+	cc.mu.Unlock()
68 133
 }
69 134
 
70 135
 type stickyErrWriter struct {
... ...
@@ -81,30 +247,49 @@ func (sew stickyErrWriter) Write(p []byte) (n int, err error) {
81 81
 	return
82 82
 }
83 83
 
84
+var ErrNoCachedConn = errors.New("http2: no cached connection was available")
85
+
86
+// RoundTripOpt are options for the Transport.RoundTripOpt method.
87
+type RoundTripOpt struct {
88
+	// OnlyCachedConn controls whether RoundTripOpt may
89
+	// create a new TCP connection. If set true and
90
+	// no cached connection is available, RoundTripOpt
91
+	// will return ErrNoCachedConn.
92
+	OnlyCachedConn bool
93
+}
94
+
84 95
 func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
85
-	if req.URL.Scheme != "https" {
86
-		if t.Fallback == nil {
87
-			return nil, errors.New("http2: unsupported scheme and no Fallback")
88
-		}
89
-		return t.Fallback.RoundTrip(req)
96
+	return t.RoundTripOpt(req, RoundTripOpt{})
97
+}
98
+
99
+// authorityAddr returns a given authority (a host/IP, or host:port / ip:port)
100
+// and returns a host:port. The port 443 is added if needed.
101
+func authorityAddr(authority string) (addr string) {
102
+	if _, _, err := net.SplitHostPort(authority); err == nil {
103
+		return authority
90 104
 	}
105
+	return net.JoinHostPort(authority, "443")
106
+}
91 107
 
92
-	host, port, err := net.SplitHostPort(req.URL.Host)
93
-	if err != nil {
94
-		host = req.URL.Host
95
-		port = "443"
108
+// RoundTripOpt is like RoundTrip, but takes options.
109
+func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) {
110
+	if req.URL.Scheme != "https" {
111
+		return nil, errors.New("http2: unsupported scheme")
96 112
 	}
97 113
 
114
+	addr := authorityAddr(req.URL.Host)
98 115
 	for {
99
-		cc, err := t.getClientConn(host, port)
116
+		cc, err := t.connPool().GetClientConn(req, addr)
100 117
 		if err != nil {
118
+			t.vlogf("http2: Transport failed to get client conn for %s: %v", addr, err)
101 119
 			return nil, err
102 120
 		}
103
-		res, err := cc.roundTrip(req)
104
-		if shouldRetryRequest(err) { // TODO: or clientconn is overloaded (too many outstanding requests)?
121
+		res, err := cc.RoundTrip(req)
122
+		if shouldRetryRequest(req, err) {
105 123
 			continue
106 124
 		}
107 125
 		if err != nil {
126
+			t.vlogf("RoundTrip failure: %v", err)
108 127
 			return nil, err
109 128
 		}
110 129
 		return res, nil
... ...
@@ -115,106 +300,96 @@ func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
115 115
 // connected from previous requests but are now sitting idle.
116 116
 // It does not interrupt any connections currently in use.
117 117
 func (t *Transport) CloseIdleConnections() {
118
-	t.connMu.Lock()
119
-	defer t.connMu.Unlock()
120
-	for _, vv := range t.conns {
121
-		for _, cc := range vv {
122
-			cc.closeIfIdle()
123
-		}
118
+	if cp, ok := t.connPool().(*clientConnPool); ok {
119
+		cp.closeIdleConnections()
124 120
 	}
125 121
 }
126 122
 
127
-var errClientConnClosed = errors.New("http2: client conn is closed")
123
+var (
124
+	errClientConnClosed   = errors.New("http2: client conn is closed")
125
+	errClientConnUnusable = errors.New("http2: client conn not usable")
126
+)
128 127
 
129
-func shouldRetryRequest(err error) bool {
130
-	// TODO: or GOAWAY graceful shutdown stuff
131
-	return err == errClientConnClosed
128
+func shouldRetryRequest(req *http.Request, err error) bool {
129
+	// TODO: retry GET requests (no bodies) more aggressively, if shutdown
130
+	// before response.
131
+	return err == errClientConnUnusable
132 132
 }
133 133
 
134
-func (t *Transport) removeClientConn(cc *clientConn) {
135
-	t.connMu.Lock()
136
-	defer t.connMu.Unlock()
137
-	for _, key := range cc.connKey {
138
-		vv, ok := t.conns[key]
139
-		if !ok {
140
-			continue
141
-		}
142
-		newList := filterOutClientConn(vv, cc)
143
-		if len(newList) > 0 {
144
-			t.conns[key] = newList
145
-		} else {
146
-			delete(t.conns, key)
147
-		}
134
+func (t *Transport) dialClientConn(addr string) (*ClientConn, error) {
135
+	host, _, err := net.SplitHostPort(addr)
136
+	if err != nil {
137
+		return nil, err
148 138
 	}
149
-}
150
-
151
-func filterOutClientConn(in []*clientConn, exclude *clientConn) []*clientConn {
152
-	out := in[:0]
153
-	for _, v := range in {
154
-		if v != exclude {
155
-			out = append(out, v)
156
-		}
139
+	tconn, err := t.dialTLS()("tcp", addr, t.newTLSConfig(host))
140
+	if err != nil {
141
+		return nil, err
157 142
 	}
158
-	return out
143
+	return t.NewClientConn(tconn)
159 144
 }
160 145
 
161
-func (t *Transport) getClientConn(host, port string) (*clientConn, error) {
162
-	t.connMu.Lock()
163
-	defer t.connMu.Unlock()
164
-
165
-	key := net.JoinHostPort(host, port)
166
-
167
-	for _, cc := range t.conns[key] {
168
-		if cc.canTakeNewRequest() {
169
-			return cc, nil
170
-		}
146
+func (t *Transport) newTLSConfig(host string) *tls.Config {
147
+	cfg := new(tls.Config)
148
+	if t.TLSClientConfig != nil {
149
+		*cfg = *t.TLSClientConfig
171 150
 	}
172
-	if t.conns == nil {
173
-		t.conns = make(map[string][]*clientConn)
151
+	if !strSliceContains(cfg.NextProtos, NextProtoTLS) {
152
+		cfg.NextProtos = append([]string{NextProtoTLS}, cfg.NextProtos...)
174 153
 	}
175
-	cc, err := t.newClientConn(host, port, key)
176
-	if err != nil {
177
-		return nil, err
154
+	if cfg.ServerName == "" {
155
+		cfg.ServerName = host
178 156
 	}
179
-	t.conns[key] = append(t.conns[key], cc)
180
-	return cc, nil
157
+	return cfg
181 158
 }
182 159
 
183
-func (t *Transport) newClientConn(host, port, key string) (*clientConn, error) {
184
-	cfg := &tls.Config{
185
-		ServerName:         host,
186
-		NextProtos:         []string{NextProtoTLS},
187
-		InsecureSkipVerify: t.InsecureTLSDial,
160
+func (t *Transport) dialTLS() func(string, string, *tls.Config) (net.Conn, error) {
161
+	if t.DialTLS != nil {
162
+		return t.DialTLS
188 163
 	}
189
-	tconn, err := tls.Dial("tcp", net.JoinHostPort(host, port), cfg)
164
+	return t.dialTLSDefault
165
+}
166
+
167
+func (t *Transport) dialTLSDefault(network, addr string, cfg *tls.Config) (net.Conn, error) {
168
+	cn, err := tls.Dial(network, addr, cfg)
190 169
 	if err != nil {
191 170
 		return nil, err
192 171
 	}
193
-	if err := tconn.Handshake(); err != nil {
172
+	if err := cn.Handshake(); err != nil {
194 173
 		return nil, err
195 174
 	}
196
-	if !t.InsecureTLSDial {
197
-		if err := tconn.VerifyHostname(cfg.ServerName); err != nil {
175
+	if !cfg.InsecureSkipVerify {
176
+		if err := cn.VerifyHostname(cfg.ServerName); err != nil {
198 177
 			return nil, err
199 178
 		}
200 179
 	}
201
-	state := tconn.ConnectionState()
180
+	state := cn.ConnectionState()
202 181
 	if p := state.NegotiatedProtocol; p != NextProtoTLS {
203
-		// TODO(bradfitz): fall back to Fallback
204
-		return nil, fmt.Errorf("bad protocol: %v", p)
182
+		return nil, fmt.Errorf("http2: unexpected ALPN protocol %q; want %q", p, NextProtoTLS)
205 183
 	}
206 184
 	if !state.NegotiatedProtocolIsMutual {
207
-		return nil, errors.New("could not negotiate protocol mutually")
185
+		return nil, errors.New("http2: could not negotiate protocol mutually")
186
+	}
187
+	return cn, nil
188
+}
189
+
190
+// disableKeepAlives reports whether connections should be closed as
191
+// soon as possible after handling the first request.
192
+func (t *Transport) disableKeepAlives() bool {
193
+	return t.t1 != nil && t.t1.DisableKeepAlives
194
+}
195
+
196
+func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) {
197
+	if VerboseLogs {
198
+		t.vlogf("http2: Transport creating client conn to %v", c.RemoteAddr())
208 199
 	}
209
-	if _, err := tconn.Write(clientPreface); err != nil {
200
+	if _, err := c.Write(clientPreface); err != nil {
201
+		t.vlogf("client preface write error: %v", err)
210 202
 		return nil, err
211 203
 	}
212 204
 
213
-	cc := &clientConn{
205
+	cc := &ClientConn{
214 206
 		t:                    t,
215
-		tconn:                tconn,
216
-		connKey:              []string{key}, // TODO: cert's validated hostnames too
217
-		tlsState:             &state,
207
+		tconn:                c,
218 208
 		readerDone:           make(chan struct{}),
219 209
 		nextStreamID:         1,
220 210
 		maxFrameSize:         16 << 10, // spec default
... ...
@@ -222,14 +397,36 @@ func (t *Transport) newClientConn(host, port, key string) (*clientConn, error) {
222 222
 		maxConcurrentStreams: 1000,     // "infinite", per spec. 1000 seems good enough.
223 223
 		streams:              make(map[uint32]*clientStream),
224 224
 	}
225
-	cc.bw = bufio.NewWriter(stickyErrWriter{tconn, &cc.werr})
226
-	cc.br = bufio.NewReader(tconn)
225
+	cc.cond = sync.NewCond(&cc.mu)
226
+	cc.flow.add(int32(initialWindowSize))
227
+
228
+	// TODO: adjust this writer size to account for frame size +
229
+	// MTU + crypto/tls record padding.
230
+	cc.bw = bufio.NewWriter(stickyErrWriter{c, &cc.werr})
231
+	cc.br = bufio.NewReader(c)
227 232
 	cc.fr = NewFramer(cc.bw, cc.br)
233
+	cc.fr.ReadMetaHeaders = hpack.NewDecoder(initialHeaderTableSize, nil)
234
+	cc.fr.MaxHeaderListSize = t.maxHeaderListSize()
235
+
236
+	// TODO: SetMaxDynamicTableSize, SetMaxDynamicTableSizeLimit on
237
+	// henc in response to SETTINGS frames?
228 238
 	cc.henc = hpack.NewEncoder(&cc.hbuf)
229 239
 
230
-	cc.fr.WriteSettings()
231
-	// TODO: re-send more conn-level flow control tokens when server uses all these.
232
-	cc.fr.WriteWindowUpdate(0, 1<<30) // um, 0x7fffffff doesn't work to Google? it hangs?
240
+	if cs, ok := c.(connectionStater); ok {
241
+		state := cs.ConnectionState()
242
+		cc.tlsState = &state
243
+	}
244
+
245
+	initialSettings := []Setting{
246
+		{ID: SettingEnablePush, Val: 0},
247
+		{ID: SettingInitialWindowSize, Val: transportDefaultStreamFlow},
248
+	}
249
+	if max := t.maxHeaderListSize(); max != 0 {
250
+		initialSettings = append(initialSettings, Setting{ID: SettingMaxHeaderListSize, Val: max})
251
+	}
252
+	cc.fr.WriteSettings(initialSettings...)
253
+	cc.fr.WriteWindowUpdate(0, transportDefaultConnFlow)
254
+	cc.inflow.add(transportDefaultConnFlow + initialWindowSize)
233 255
 	cc.bw.Flush()
234 256
 	if cc.werr != nil {
235 257
 		return nil, cc.werr
... ...
@@ -256,33 +453,35 @@ func (t *Transport) newClientConn(host, port, key string) (*clientConn, error) {
256 256
 		case SettingInitialWindowSize:
257 257
 			cc.initialWindowSize = s.Val
258 258
 		default:
259
-			// TODO(bradfitz): handle more
260
-			log.Printf("Unhandled Setting: %v", s)
259
+			// TODO(bradfitz): handle more; at least SETTINGS_HEADER_TABLE_SIZE?
260
+			t.vlogf("Unhandled Setting: %v", s)
261 261
 		}
262 262
 		return nil
263 263
 	})
264
-	// TODO: figure out henc size
265
-	cc.hdec = hpack.NewDecoder(initialHeaderTableSize, cc.onNewHeaderField)
266 264
 
267 265
 	go cc.readLoop()
268 266
 	return cc, nil
269 267
 }
270 268
 
271
-func (cc *clientConn) setGoAway(f *GoAwayFrame) {
269
+func (cc *ClientConn) setGoAway(f *GoAwayFrame) {
272 270
 	cc.mu.Lock()
273 271
 	defer cc.mu.Unlock()
274 272
 	cc.goAway = f
275 273
 }
276 274
 
277
-func (cc *clientConn) canTakeNewRequest() bool {
275
+func (cc *ClientConn) CanTakeNewRequest() bool {
278 276
 	cc.mu.Lock()
279 277
 	defer cc.mu.Unlock()
280
-	return cc.goAway == nil &&
278
+	return cc.canTakeNewRequestLocked()
279
+}
280
+
281
+func (cc *ClientConn) canTakeNewRequestLocked() bool {
282
+	return cc.goAway == nil && !cc.closed &&
281 283
 		int64(len(cc.streams)+1) < int64(cc.maxConcurrentStreams) &&
282 284
 		cc.nextStreamID < 2147483647
283 285
 }
284 286
 
285
-func (cc *clientConn) closeIfIdle() {
287
+func (cc *ClientConn) closeIfIdle() {
286 288
 	cc.mu.Lock()
287 289
 	if len(cc.streams) > 0 {
288 290
 		cc.mu.Unlock()
... ...
@@ -295,96 +494,533 @@ func (cc *clientConn) closeIfIdle() {
295 295
 	cc.tconn.Close()
296 296
 }
297 297
 
298
-func (cc *clientConn) roundTrip(req *http.Request) (*http.Response, error) {
298
+const maxAllocFrameSize = 512 << 10
299
+
300
+// frameBuffer returns a scratch buffer suitable for writing DATA frames.
301
+// They're capped at the min of the peer's max frame size or 512KB
302
+// (kinda arbitrarily), but definitely capped so we don't allocate 4GB
303
+// bufers.
304
+func (cc *ClientConn) frameScratchBuffer() []byte {
299 305
 	cc.mu.Lock()
306
+	size := cc.maxFrameSize
307
+	if size > maxAllocFrameSize {
308
+		size = maxAllocFrameSize
309
+	}
310
+	for i, buf := range cc.freeBuf {
311
+		if len(buf) >= int(size) {
312
+			cc.freeBuf[i] = nil
313
+			cc.mu.Unlock()
314
+			return buf[:size]
315
+		}
316
+	}
317
+	cc.mu.Unlock()
318
+	return make([]byte, size)
319
+}
320
+
321
+func (cc *ClientConn) putFrameScratchBuffer(buf []byte) {
322
+	cc.mu.Lock()
323
+	defer cc.mu.Unlock()
324
+	const maxBufs = 4 // arbitrary; 4 concurrent requests per conn? investigate.
325
+	if len(cc.freeBuf) < maxBufs {
326
+		cc.freeBuf = append(cc.freeBuf, buf)
327
+		return
328
+	}
329
+	for i, old := range cc.freeBuf {
330
+		if old == nil {
331
+			cc.freeBuf[i] = buf
332
+			return
333
+		}
334
+	}
335
+	// forget about it.
336
+}
337
+
338
+// errRequestCanceled is a copy of net/http's errRequestCanceled because it's not
339
+// exported. At least they'll be DeepEqual for h1-vs-h2 comparisons tests.
340
+var errRequestCanceled = errors.New("net/http: request canceled")
341
+
342
+func commaSeparatedTrailers(req *http.Request) (string, error) {
343
+	keys := make([]string, 0, len(req.Trailer))
344
+	for k := range req.Trailer {
345
+		k = http.CanonicalHeaderKey(k)
346
+		switch k {
347
+		case "Transfer-Encoding", "Trailer", "Content-Length":
348
+			return "", &badStringError{"invalid Trailer key", k}
349
+		}
350
+		keys = append(keys, k)
351
+	}
352
+	if len(keys) > 0 {
353
+		sort.Strings(keys)
354
+		// TODO: could do better allocation-wise here, but trailers are rare,
355
+		// so being lazy for now.
356
+		return strings.Join(keys, ","), nil
357
+	}
358
+	return "", nil
359
+}
360
+
361
+func (cc *ClientConn) responseHeaderTimeout() time.Duration {
362
+	if cc.t.t1 != nil {
363
+		return cc.t.t1.ResponseHeaderTimeout
364
+	}
365
+	// No way to do this (yet?) with just an http2.Transport. Probably
366
+	// no need. Request.Cancel this is the new way. We only need to support
367
+	// this for compatibility with the old http.Transport fields when
368
+	// we're doing transparent http2.
369
+	return 0
370
+}
371
+
372
+// checkConnHeaders checks whether req has any invalid connection-level headers.
373
+// per RFC 7540 section 8.1.2.2: Connection-Specific Header Fields.
374
+// Certain headers are special-cased as okay but not transmitted later.
375
+func checkConnHeaders(req *http.Request) error {
376
+	if v := req.Header.Get("Upgrade"); v != "" {
377
+		return errors.New("http2: invalid Upgrade request header")
378
+	}
379
+	if v := req.Header.Get("Transfer-Encoding"); (v != "" && v != "chunked") || len(req.Header["Transfer-Encoding"]) > 1 {
380
+		return errors.New("http2: invalid Transfer-Encoding request header")
381
+	}
382
+	if v := req.Header.Get("Connection"); (v != "" && v != "close" && v != "keep-alive") || len(req.Header["Connection"]) > 1 {
383
+		return errors.New("http2: invalid Connection request header")
384
+	}
385
+	return nil
386
+}
387
+
388
+func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
389
+	if err := checkConnHeaders(req); err != nil {
390
+		return nil, err
391
+	}
392
+
393
+	trailers, err := commaSeparatedTrailers(req)
394
+	if err != nil {
395
+		return nil, err
396
+	}
397
+	hasTrailers := trailers != ""
398
+
399
+	var body io.Reader = req.Body
400
+	contentLen := req.ContentLength
401
+	if req.Body != nil && contentLen == 0 {
402
+		// Test to see if it's actually zero or just unset.
403
+		var buf [1]byte
404
+		n, rerr := io.ReadFull(body, buf[:])
405
+		if rerr != nil && rerr != io.EOF {
406
+			contentLen = -1
407
+			body = errorReader{rerr}
408
+		} else if n == 1 {
409
+			// Oh, guess there is data in this Body Reader after all.
410
+			// The ContentLength field just wasn't set.
411
+			// Stich the Body back together again, re-attaching our
412
+			// consumed byte.
413
+			contentLen = -1
414
+			body = io.MultiReader(bytes.NewReader(buf[:]), body)
415
+		} else {
416
+			// Body is actually empty.
417
+			body = nil
418
+		}
419
+	}
300 420
 
301
-	if cc.closed {
421
+	cc.mu.Lock()
422
+	if cc.closed || !cc.canTakeNewRequestLocked() {
302 423
 		cc.mu.Unlock()
303
-		return nil, errClientConnClosed
424
+		return nil, errClientConnUnusable
304 425
 	}
305 426
 
306 427
 	cs := cc.newStream()
307
-	hasBody := false // TODO
428
+	cs.req = req
429
+	hasBody := body != nil
430
+
431
+	// TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere?
432
+	if !cc.t.disableCompression() &&
433
+		req.Header.Get("Accept-Encoding") == "" &&
434
+		req.Header.Get("Range") == "" &&
435
+		req.Method != "HEAD" {
436
+		// Request gzip only, not deflate. Deflate is ambiguous and
437
+		// not as universally supported anyway.
438
+		// See: http://www.gzip.org/zlib/zlib_faq.html#faq38
439
+		//
440
+		// Note that we don't request this for HEAD requests,
441
+		// due to a bug in nginx:
442
+		//   http://trac.nginx.org/nginx/ticket/358
443
+		//   https://golang.org/issue/5522
444
+		//
445
+		// We don't request gzip if the request is for a range, since
446
+		// auto-decoding a portion of a gzipped document will just fail
447
+		// anyway. See https://golang.org/issue/8923
448
+		cs.requestedGzip = true
449
+	}
308 450
 
309
-	// we send: HEADERS[+CONTINUATION] + (DATA?)
310
-	hdrs := cc.encodeHeaders(req)
311
-	first := true
312
-	for len(hdrs) > 0 {
451
+	// we send: HEADERS{1}, CONTINUATION{0,} + DATA{0,} (DATA is
452
+	// sent by writeRequestBody below, along with any Trailers,
453
+	// again in form HEADERS{1}, CONTINUATION{0,})
454
+	hdrs := cc.encodeHeaders(req, cs.requestedGzip, trailers, contentLen)
455
+	cc.wmu.Lock()
456
+	endStream := !hasBody && !hasTrailers
457
+	werr := cc.writeHeaders(cs.ID, endStream, hdrs)
458
+	cc.wmu.Unlock()
459
+	cc.mu.Unlock()
460
+
461
+	if werr != nil {
462
+		if hasBody {
463
+			req.Body.Close() // per RoundTripper contract
464
+		}
465
+		cc.forgetStreamID(cs.ID)
466
+		// Don't bother sending a RST_STREAM (our write already failed;
467
+		// no need to keep writing)
468
+		return nil, werr
469
+	}
470
+
471
+	var respHeaderTimer <-chan time.Time
472
+	var bodyCopyErrc chan error // result of body copy
473
+	if hasBody {
474
+		bodyCopyErrc = make(chan error, 1)
475
+		go func() {
476
+			bodyCopyErrc <- cs.writeRequestBody(body, req.Body)
477
+		}()
478
+	} else {
479
+		if d := cc.responseHeaderTimeout(); d != 0 {
480
+			timer := time.NewTimer(d)
481
+			defer timer.Stop()
482
+			respHeaderTimer = timer.C
483
+		}
484
+	}
485
+
486
+	readLoopResCh := cs.resc
487
+	requestCanceledCh := requestCancel(req)
488
+	bodyWritten := false
489
+
490
+	for {
491
+		select {
492
+		case re := <-readLoopResCh:
493
+			res := re.res
494
+			if re.err != nil || res.StatusCode > 299 {
495
+				// On error or status code 3xx, 4xx, 5xx, etc abort any
496
+				// ongoing write, assuming that the server doesn't care
497
+				// about our request body. If the server replied with 1xx or
498
+				// 2xx, however, then assume the server DOES potentially
499
+				// want our body (e.g. full-duplex streaming:
500
+				// golang.org/issue/13444). If it turns out the server
501
+				// doesn't, they'll RST_STREAM us soon enough.  This is a
502
+				// heuristic to avoid adding knobs to Transport.  Hopefully
503
+				// we can keep it.
504
+				cs.abortRequestBodyWrite(errStopReqBodyWrite)
505
+			}
506
+			if re.err != nil {
507
+				cc.forgetStreamID(cs.ID)
508
+				return nil, re.err
509
+			}
510
+			res.Request = req
511
+			res.TLS = cc.tlsState
512
+			return res, nil
513
+		case <-respHeaderTimer:
514
+			cc.forgetStreamID(cs.ID)
515
+			if !hasBody || bodyWritten {
516
+				cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
517
+			} else {
518
+				cs.abortRequestBodyWrite(errStopReqBodyWriteAndCancel)
519
+			}
520
+			return nil, errTimeout
521
+		case <-requestCanceledCh:
522
+			cc.forgetStreamID(cs.ID)
523
+			if !hasBody || bodyWritten {
524
+				cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
525
+			} else {
526
+				cs.abortRequestBodyWrite(errStopReqBodyWriteAndCancel)
527
+			}
528
+			return nil, errRequestCanceled
529
+		case <-cs.peerReset:
530
+			// processResetStream already removed the
531
+			// stream from the streams map; no need for
532
+			// forgetStreamID.
533
+			return nil, cs.resetErr
534
+		case err := <-bodyCopyErrc:
535
+			if err != nil {
536
+				return nil, err
537
+			}
538
+			bodyWritten = true
539
+			if d := cc.responseHeaderTimeout(); d != 0 {
540
+				timer := time.NewTimer(d)
541
+				defer timer.Stop()
542
+				respHeaderTimer = timer.C
543
+			}
544
+		}
545
+	}
546
+}
547
+
548
+// requires cc.wmu be held
549
+func (cc *ClientConn) writeHeaders(streamID uint32, endStream bool, hdrs []byte) error {
550
+	first := true // first frame written (HEADERS is first, then CONTINUATION)
551
+	frameSize := int(cc.maxFrameSize)
552
+	for len(hdrs) > 0 && cc.werr == nil {
313 553
 		chunk := hdrs
314
-		if len(chunk) > int(cc.maxFrameSize) {
315
-			chunk = chunk[:cc.maxFrameSize]
554
+		if len(chunk) > frameSize {
555
+			chunk = chunk[:frameSize]
316 556
 		}
317 557
 		hdrs = hdrs[len(chunk):]
318 558
 		endHeaders := len(hdrs) == 0
319 559
 		if first {
320 560
 			cc.fr.WriteHeaders(HeadersFrameParam{
321
-				StreamID:      cs.ID,
561
+				StreamID:      streamID,
322 562
 				BlockFragment: chunk,
323
-				EndStream:     !hasBody,
563
+				EndStream:     endStream,
324 564
 				EndHeaders:    endHeaders,
325 565
 			})
326 566
 			first = false
327 567
 		} else {
328
-			cc.fr.WriteContinuation(cs.ID, endHeaders, chunk)
568
+			cc.fr.WriteContinuation(streamID, endHeaders, chunk)
329 569
 		}
330 570
 	}
571
+	// TODO(bradfitz): this Flush could potentially block (as
572
+	// could the WriteHeaders call(s) above), which means they
573
+	// wouldn't respond to Request.Cancel being readable. That's
574
+	// rare, but this should probably be in a goroutine.
331 575
 	cc.bw.Flush()
332
-	werr := cc.werr
333
-	cc.mu.Unlock()
576
+	return cc.werr
577
+}
334 578
 
335
-	if hasBody {
336
-		// TODO: write data. and it should probably be interleaved:
337
-		//   go ... io.Copy(dataFrameWriter{cc, cs, ...}, req.Body) ... etc
579
+// internal error values; they don't escape to callers
580
+var (
581
+	// abort request body write; don't send cancel
582
+	errStopReqBodyWrite = errors.New("http2: aborting request body write")
583
+
584
+	// abort request body write, but send stream reset of cancel.
585
+	errStopReqBodyWriteAndCancel = errors.New("http2: canceling request")
586
+)
587
+
588
+func (cs *clientStream) writeRequestBody(body io.Reader, bodyCloser io.Closer) (err error) {
589
+	cc := cs.cc
590
+	sentEnd := false // whether we sent the final DATA frame w/ END_STREAM
591
+	buf := cc.frameScratchBuffer()
592
+	defer cc.putFrameScratchBuffer(buf)
593
+
594
+	defer func() {
595
+		// TODO: write h12Compare test showing whether
596
+		// Request.Body is closed by the Transport,
597
+		// and in multiple cases: server replies <=299 and >299
598
+		// while still writing request body
599
+		cerr := bodyCloser.Close()
600
+		if err == nil {
601
+			err = cerr
602
+		}
603
+	}()
604
+
605
+	req := cs.req
606
+	hasTrailers := req.Trailer != nil
607
+
608
+	var sawEOF bool
609
+	for !sawEOF {
610
+		n, err := body.Read(buf)
611
+		if err == io.EOF {
612
+			sawEOF = true
613
+			err = nil
614
+		} else if err != nil {
615
+			return err
616
+		}
617
+
618
+		remain := buf[:n]
619
+		for len(remain) > 0 && err == nil {
620
+			var allowed int32
621
+			allowed, err = cs.awaitFlowControl(len(remain))
622
+			switch {
623
+			case err == errStopReqBodyWrite:
624
+				return err
625
+			case err == errStopReqBodyWriteAndCancel:
626
+				cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
627
+				return err
628
+			case err != nil:
629
+				return err
630
+			}
631
+			cc.wmu.Lock()
632
+			data := remain[:allowed]
633
+			remain = remain[allowed:]
634
+			sentEnd = sawEOF && len(remain) == 0 && !hasTrailers
635
+			err = cc.fr.WriteData(cs.ID, sentEnd, data)
636
+			if err == nil {
637
+				// TODO(bradfitz): this flush is for latency, not bandwidth.
638
+				// Most requests won't need this. Make this opt-in or opt-out?
639
+				// Use some heuristic on the body type? Nagel-like timers?
640
+				// Based on 'n'? Only last chunk of this for loop, unless flow control
641
+				// tokens are low? For now, always:
642
+				err = cc.bw.Flush()
643
+			}
644
+			cc.wmu.Unlock()
645
+		}
646
+		if err != nil {
647
+			return err
648
+		}
338 649
 	}
339 650
 
340
-	if werr != nil {
341
-		return nil, werr
651
+	cc.wmu.Lock()
652
+	if !sentEnd {
653
+		var trls []byte
654
+		if hasTrailers {
655
+			cc.mu.Lock()
656
+			trls = cc.encodeTrailers(req)
657
+			cc.mu.Unlock()
658
+		}
659
+
660
+		// Avoid forgetting to send an END_STREAM if the encoded
661
+		// trailers are 0 bytes. Both results produce and END_STREAM.
662
+		if len(trls) > 0 {
663
+			err = cc.writeHeaders(cs.ID, true, trls)
664
+		} else {
665
+			err = cc.fr.WriteData(cs.ID, true, nil)
666
+		}
667
+	}
668
+	if ferr := cc.bw.Flush(); ferr != nil && err == nil {
669
+		err = ferr
342 670
 	}
671
+	cc.wmu.Unlock()
672
+
673
+	return err
674
+}
675
+
676
+// awaitFlowControl waits for [1, min(maxBytes, cc.cs.maxFrameSize)] flow
677
+// control tokens from the server.
678
+// It returns either the non-zero number of tokens taken or an error
679
+// if the stream is dead.
680
+func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) {
681
+	cc := cs.cc
682
+	cc.mu.Lock()
683
+	defer cc.mu.Unlock()
684
+	for {
685
+		if cc.closed {
686
+			return 0, errClientConnClosed
687
+		}
688
+		if cs.stopReqBody != nil {
689
+			return 0, cs.stopReqBody
690
+		}
691
+		if err := cs.checkReset(); err != nil {
692
+			return 0, err
693
+		}
694
+		if a := cs.flow.available(); a > 0 {
695
+			take := a
696
+			if int(take) > maxBytes {
343 697
 
344
-	re := <-cs.resc
345
-	if re.err != nil {
346
-		return nil, re.err
698
+				take = int32(maxBytes) // can't truncate int; take is int32
699
+			}
700
+			if take > int32(cc.maxFrameSize) {
701
+				take = int32(cc.maxFrameSize)
702
+			}
703
+			cs.flow.take(take)
704
+			return take, nil
705
+		}
706
+		cc.cond.Wait()
347 707
 	}
348
-	res := re.res
349
-	res.Request = req
350
-	res.TLS = cc.tlsState
351
-	return res, nil
352 708
 }
353 709
 
710
+type badStringError struct {
711
+	what string
712
+	str  string
713
+}
714
+
715
+func (e *badStringError) Error() string { return fmt.Sprintf("%s %q", e.what, e.str) }
716
+
354 717
 // requires cc.mu be held.
355
-func (cc *clientConn) encodeHeaders(req *http.Request) []byte {
718
+func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trailers string, contentLength int64) []byte {
356 719
 	cc.hbuf.Reset()
357 720
 
358
-	// TODO(bradfitz): figure out :authority-vs-Host stuff between http2 and Go
359 721
 	host := req.Host
360 722
 	if host == "" {
361 723
 		host = req.URL.Host
362 724
 	}
363 725
 
364
-	path := req.URL.Path
365
-	if path == "" {
366
-		path = "/"
367
-	}
368
-
369
-	cc.writeHeader(":authority", host) // probably not right for all sites
726
+	// 8.1.2.3 Request Pseudo-Header Fields
727
+	// The :path pseudo-header field includes the path and query parts of the
728
+	// target URI (the path-absolute production and optionally a '?' character
729
+	// followed by the query production (see Sections 3.3 and 3.4 of
730
+	// [RFC3986]).
731
+	cc.writeHeader(":authority", host)
370 732
 	cc.writeHeader(":method", req.Method)
371
-	cc.writeHeader(":path", path)
372
-	cc.writeHeader(":scheme", "https")
733
+	if req.Method != "CONNECT" {
734
+		cc.writeHeader(":path", req.URL.RequestURI())
735
+		cc.writeHeader(":scheme", "https")
736
+	}
737
+	if trailers != "" {
738
+		cc.writeHeader("trailer", trailers)
739
+	}
373 740
 
741
+	var didUA bool
374 742
 	for k, vv := range req.Header {
375 743
 		lowKey := strings.ToLower(k)
376
-		if lowKey == "host" {
744
+		switch lowKey {
745
+		case "host", "content-length":
746
+			// Host is :authority, already sent.
747
+			// Content-Length is automatic, set below.
377 748
 			continue
749
+		case "connection", "proxy-connection", "transfer-encoding", "upgrade", "keep-alive":
750
+			// Per 8.1.2.2 Connection-Specific Header
751
+			// Fields, don't send connection-specific
752
+			// fields. We have already checked if any
753
+			// are error-worthy so just ignore the rest.
754
+			continue
755
+		case "user-agent":
756
+			// Match Go's http1 behavior: at most one
757
+			// User-Agent. If set to nil or empty string,
758
+			// then omit it. Otherwise if not mentioned,
759
+			// include the default (below).
760
+			didUA = true
761
+			if len(vv) < 1 {
762
+				continue
763
+			}
764
+			vv = vv[:1]
765
+			if vv[0] == "" {
766
+				continue
767
+			}
378 768
 		}
379 769
 		for _, v := range vv {
380 770
 			cc.writeHeader(lowKey, v)
381 771
 		}
382 772
 	}
773
+	if shouldSendReqContentLength(req.Method, contentLength) {
774
+		cc.writeHeader("content-length", strconv.FormatInt(contentLength, 10))
775
+	}
776
+	if addGzipHeader {
777
+		cc.writeHeader("accept-encoding", "gzip")
778
+	}
779
+	if !didUA {
780
+		cc.writeHeader("user-agent", defaultUserAgent)
781
+	}
383 782
 	return cc.hbuf.Bytes()
384 783
 }
385 784
 
386
-func (cc *clientConn) writeHeader(name, value string) {
387
-	log.Printf("sending %q = %q", name, value)
785
+// shouldSendReqContentLength reports whether the http2.Transport should send
786
+// a "content-length" request header. This logic is basically a copy of the net/http
787
+// transferWriter.shouldSendContentLength.
788
+// The contentLength is the corrected contentLength (so 0 means actually 0, not unknown).
789
+// -1 means unknown.
790
+func shouldSendReqContentLength(method string, contentLength int64) bool {
791
+	if contentLength > 0 {
792
+		return true
793
+	}
794
+	if contentLength < 0 {
795
+		return false
796
+	}
797
+	// For zero bodies, whether we send a content-length depends on the method.
798
+	// It also kinda doesn't matter for http2 either way, with END_STREAM.
799
+	switch method {
800
+	case "POST", "PUT", "PATCH":
801
+		return true
802
+	default:
803
+		return false
804
+	}
805
+}
806
+
807
+// requires cc.mu be held.
808
+func (cc *ClientConn) encodeTrailers(req *http.Request) []byte {
809
+	cc.hbuf.Reset()
810
+	for k, vv := range req.Trailer {
811
+		// Transfer-Encoding, etc.. have already been filter at the
812
+		// start of RoundTrip
813
+		lowKey := strings.ToLower(k)
814
+		for _, v := range vv {
815
+			cc.writeHeader(lowKey, v)
816
+		}
817
+	}
818
+	return cc.hbuf.Bytes()
819
+}
820
+
821
+func (cc *ClientConn) writeHeader(name, value string) {
822
+	if VerboseLogs {
823
+		log.Printf("http2: Transport encoding header %q = %q", name, value)
824
+	}
388 825
 	cc.henc.WriteField(hpack.HeaderField{Name: name, Value: value})
389 826
 }
390 827
 
... ...
@@ -394,160 +1030,635 @@ type resAndError struct {
394 394
 }
395 395
 
396 396
 // requires cc.mu be held.
397
-func (cc *clientConn) newStream() *clientStream {
397
+func (cc *ClientConn) newStream() *clientStream {
398 398
 	cs := &clientStream{
399
-		ID:   cc.nextStreamID,
400
-		resc: make(chan resAndError, 1),
399
+		cc:        cc,
400
+		ID:        cc.nextStreamID,
401
+		resc:      make(chan resAndError, 1),
402
+		peerReset: make(chan struct{}),
403
+		done:      make(chan struct{}),
401 404
 	}
405
+	cs.flow.add(int32(cc.initialWindowSize))
406
+	cs.flow.setConnFlow(&cc.flow)
407
+	cs.inflow.add(transportDefaultStreamFlow)
408
+	cs.inflow.setConnFlow(&cc.inflow)
402 409
 	cc.nextStreamID += 2
403 410
 	cc.streams[cs.ID] = cs
404 411
 	return cs
405 412
 }
406 413
 
407
-func (cc *clientConn) streamByID(id uint32, andRemove bool) *clientStream {
414
+func (cc *ClientConn) forgetStreamID(id uint32) {
415
+	cc.streamByID(id, true)
416
+}
417
+
418
+func (cc *ClientConn) streamByID(id uint32, andRemove bool) *clientStream {
408 419
 	cc.mu.Lock()
409 420
 	defer cc.mu.Unlock()
410 421
 	cs := cc.streams[id]
411
-	if andRemove {
422
+	if andRemove && cs != nil && !cc.closed {
412 423
 		delete(cc.streams, id)
424
+		close(cs.done)
413 425
 	}
414 426
 	return cs
415 427
 }
416 428
 
417
-// runs in its own goroutine.
418
-func (cc *clientConn) readLoop() {
419
-	defer cc.t.removeClientConn(cc)
429
+// clientConnReadLoop is the state owned by the clientConn's frame-reading readLoop.
430
+type clientConnReadLoop struct {
431
+	cc            *ClientConn
432
+	activeRes     map[uint32]*clientStream // keyed by streamID
433
+	closeWhenIdle bool
434
+}
435
+
436
+// readLoop runs in its own goroutine and reads and dispatches frames.
437
+func (cc *ClientConn) readLoop() {
438
+	rl := &clientConnReadLoop{
439
+		cc:        cc,
440
+		activeRes: make(map[uint32]*clientStream),
441
+	}
442
+
443
+	defer rl.cleanup()
444
+	cc.readerErr = rl.run()
445
+	if ce, ok := cc.readerErr.(ConnectionError); ok {
446
+		cc.wmu.Lock()
447
+		cc.fr.WriteGoAway(0, ErrCode(ce), nil)
448
+		cc.wmu.Unlock()
449
+	}
450
+}
451
+
452
+func (rl *clientConnReadLoop) cleanup() {
453
+	cc := rl.cc
454
+	defer cc.tconn.Close()
455
+	defer cc.t.connPool().MarkDead(cc)
420 456
 	defer close(cc.readerDone)
421 457
 
422
-	activeRes := map[uint32]*clientStream{} // keyed by streamID
423 458
 	// Close any response bodies if the server closes prematurely.
424 459
 	// TODO: also do this if we've written the headers but not
425 460
 	// gotten a response yet.
426
-	defer func() {
427
-		err := cc.readerErr
428
-		if err == io.EOF {
429
-			err = io.ErrUnexpectedEOF
430
-		}
431
-		for _, cs := range activeRes {
432
-			cs.pw.CloseWithError(err)
461
+	err := cc.readerErr
462
+	if err == io.EOF {
463
+		err = io.ErrUnexpectedEOF
464
+	}
465
+	cc.mu.Lock()
466
+	for _, cs := range rl.activeRes {
467
+		cs.bufPipe.CloseWithError(err)
468
+	}
469
+	for _, cs := range cc.streams {
470
+		select {
471
+		case cs.resc <- resAndError{err: err}:
472
+		default:
433 473
 		}
434
-	}()
435
-
436
-	// continueStreamID is the stream ID we're waiting for
437
-	// continuation frames for.
438
-	var continueStreamID uint32
474
+		close(cs.done)
475
+	}
476
+	cc.closed = true
477
+	cc.cond.Broadcast()
478
+	cc.mu.Unlock()
479
+}
439 480
 
481
+func (rl *clientConnReadLoop) run() error {
482
+	cc := rl.cc
483
+	rl.closeWhenIdle = cc.t.disableKeepAlives()
484
+	gotReply := false // ever saw a reply
440 485
 	for {
441 486
 		f, err := cc.fr.ReadFrame()
442 487
 		if err != nil {
443
-			cc.readerErr = err
444
-			return
488
+			cc.vlogf("Transport readFrame error: (%T) %v", err, err)
445 489
 		}
446
-		log.Printf("Transport received %v: %#v", f.Header(), f)
447
-
448
-		streamID := f.Header().StreamID
449
-
450
-		_, isContinue := f.(*ContinuationFrame)
451
-		if isContinue {
452
-			if streamID != continueStreamID {
453
-				log.Printf("Protocol violation: got CONTINUATION with id %d; want %d", streamID, continueStreamID)
454
-				cc.readerErr = ConnectionError(ErrCodeProtocol)
455
-				return
490
+		if se, ok := err.(StreamError); ok {
491
+			if cs := cc.streamByID(se.StreamID, true /*ended; remove it*/); cs != nil {
492
+				rl.endStreamError(cs, cc.fr.errDetail)
456 493
 			}
457
-		} else if continueStreamID != 0 {
458
-			// Continue frames need to be adjacent in the stream
459
-			// and we were in the middle of headers.
460
-			log.Printf("Protocol violation: got %T for stream %d, want CONTINUATION for %d", f, streamID, continueStreamID)
461
-			cc.readerErr = ConnectionError(ErrCodeProtocol)
462
-			return
463
-		}
464
-
465
-		if streamID%2 == 0 {
466
-			// Ignore streams pushed from the server for now.
467
-			// These always have an even stream id.
468 494
 			continue
495
+		} else if err != nil {
496
+			return err
469 497
 		}
470
-		streamEnded := false
471
-		if ff, ok := f.(streamEnder); ok {
472
-			streamEnded = ff.StreamEnded()
473
-		}
474
-
475
-		cs := cc.streamByID(streamID, streamEnded)
476
-		if cs == nil {
477
-			log.Printf("Received frame for untracked stream ID %d", streamID)
478
-			continue
498
+		if VerboseLogs {
499
+			cc.vlogf("http2: Transport received %s", summarizeFrame(f))
479 500
 		}
501
+		maybeIdle := false // whether frame might transition us to idle
480 502
 
481 503
 		switch f := f.(type) {
482
-		case *HeadersFrame:
483
-			cc.nextRes = &http.Response{
484
-				Proto:      "HTTP/2.0",
485
-				ProtoMajor: 2,
486
-				Header:     make(http.Header),
487
-			}
488
-			cs.pr, cs.pw = io.Pipe()
489
-			cc.hdec.Write(f.HeaderBlockFragment())
490
-		case *ContinuationFrame:
491
-			cc.hdec.Write(f.HeaderBlockFragment())
504
+		case *MetaHeadersFrame:
505
+			err = rl.processHeaders(f)
506
+			maybeIdle = true
507
+			gotReply = true
492 508
 		case *DataFrame:
493
-			log.Printf("DATA: %q", f.Data())
494
-			cs.pw.Write(f.Data())
509
+			err = rl.processData(f)
510
+			maybeIdle = true
495 511
 		case *GoAwayFrame:
496
-			cc.t.removeClientConn(cc)
497
-			if f.ErrCode != 0 {
498
-				// TODO: deal with GOAWAY more. particularly the error code
499
-				log.Printf("transport got GOAWAY with error code = %v", f.ErrCode)
500
-			}
501
-			cc.setGoAway(f)
512
+			err = rl.processGoAway(f)
513
+			maybeIdle = true
514
+		case *RSTStreamFrame:
515
+			err = rl.processResetStream(f)
516
+			maybeIdle = true
517
+		case *SettingsFrame:
518
+			err = rl.processSettings(f)
519
+		case *PushPromiseFrame:
520
+			err = rl.processPushPromise(f)
521
+		case *WindowUpdateFrame:
522
+			err = rl.processWindowUpdate(f)
523
+		case *PingFrame:
524
+			err = rl.processPing(f)
502 525
 		default:
503
-			log.Printf("Transport: unhandled response frame type %T", f)
526
+			cc.logf("Transport: unhandled response frame type %T", f)
504 527
 		}
505
-		headersEnded := false
506
-		if he, ok := f.(headersEnder); ok {
507
-			headersEnded = he.HeadersEnded()
508
-			if headersEnded {
509
-				continueStreamID = 0
510
-			} else {
511
-				continueStreamID = streamID
512
-			}
528
+		if err != nil {
529
+			return err
513 530
 		}
531
+		if rl.closeWhenIdle && gotReply && maybeIdle && len(rl.activeRes) == 0 {
532
+			cc.closeIfIdle()
533
+		}
534
+	}
535
+}
536
+
537
+func (rl *clientConnReadLoop) processHeaders(f *MetaHeadersFrame) error {
538
+	cc := rl.cc
539
+	cs := cc.streamByID(f.StreamID, f.StreamEnded())
540
+	if cs == nil {
541
+		// We'd get here if we canceled a request while the
542
+		// server had its response still in flight. So if this
543
+		// was just something we canceled, ignore it.
544
+		return nil
545
+	}
546
+	if !cs.pastHeaders {
547
+		cs.pastHeaders = true
548
+	} else {
549
+		return rl.processTrailers(cs, f)
550
+	}
514 551
 
515
-		if streamEnded {
516
-			cs.pw.Close()
517
-			delete(activeRes, streamID)
552
+	res, err := rl.handleResponse(cs, f)
553
+	if err != nil {
554
+		if _, ok := err.(ConnectionError); ok {
555
+			return err
518 556
 		}
519
-		if headersEnded {
520
-			if cs == nil {
521
-				panic("couldn't find stream") // TODO be graceful
557
+		// Any other error type is a stream error.
558
+		cs.cc.writeStreamReset(f.StreamID, ErrCodeProtocol, err)
559
+		cs.resc <- resAndError{err: err}
560
+		return nil // return nil from process* funcs to keep conn alive
561
+	}
562
+	if res == nil {
563
+		// (nil, nil) special case. See handleResponse docs.
564
+		return nil
565
+	}
566
+	if res.Body != noBody {
567
+		rl.activeRes[cs.ID] = cs
568
+	}
569
+	cs.resTrailer = &res.Trailer
570
+	cs.resc <- resAndError{res: res}
571
+	return nil
572
+}
573
+
574
+// may return error types nil, or ConnectionError. Any other error value
575
+// is a StreamError of type ErrCodeProtocol. The returned error in that case
576
+// is the detail.
577
+//
578
+// As a special case, handleResponse may return (nil, nil) to skip the
579
+// frame (currently only used for 100 expect continue). This special
580
+// case is going away after Issue 13851 is fixed.
581
+func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFrame) (*http.Response, error) {
582
+	if f.Truncated {
583
+		return nil, errResponseHeaderListSize
584
+	}
585
+
586
+	status := f.PseudoValue("status")
587
+	if status == "" {
588
+		return nil, errors.New("missing status pseudo header")
589
+	}
590
+	statusCode, err := strconv.Atoi(status)
591
+	if err != nil {
592
+		return nil, errors.New("malformed non-numeric status pseudo header")
593
+	}
594
+
595
+	if statusCode == 100 {
596
+		// Just skip 100-continue response headers for now.
597
+		// TODO: golang.org/issue/13851 for doing it properly.
598
+		cs.pastHeaders = false // do it all again
599
+		return nil, nil
600
+	}
601
+
602
+	header := make(http.Header)
603
+	res := &http.Response{
604
+		Proto:      "HTTP/2.0",
605
+		ProtoMajor: 2,
606
+		Header:     header,
607
+		StatusCode: statusCode,
608
+		Status:     status + " " + http.StatusText(statusCode),
609
+	}
610
+	for _, hf := range f.RegularFields() {
611
+		key := http.CanonicalHeaderKey(hf.Name)
612
+		if key == "Trailer" {
613
+			t := res.Trailer
614
+			if t == nil {
615
+				t = make(http.Header)
616
+				res.Trailer = t
522 617
 			}
523
-			// TODO: set the Body to one which notes the
524
-			// Close and also sends the server a
525
-			// RST_STREAM
526
-			cc.nextRes.Body = cs.pr
527
-			res := cc.nextRes
528
-			activeRes[streamID] = cs
529
-			cs.resc <- resAndError{res: res}
618
+			foreachHeaderElement(hf.Value, func(v string) {
619
+				t[http.CanonicalHeaderKey(v)] = nil
620
+			})
621
+		} else {
622
+			header[key] = append(header[key], hf.Value)
530 623
 		}
531 624
 	}
625
+
626
+	streamEnded := f.StreamEnded()
627
+	isHead := cs.req.Method == "HEAD"
628
+	if !streamEnded || isHead {
629
+		res.ContentLength = -1
630
+		if clens := res.Header["Content-Length"]; len(clens) == 1 {
631
+			if clen64, err := strconv.ParseInt(clens[0], 10, 64); err == nil {
632
+				res.ContentLength = clen64
633
+			} else {
634
+				// TODO: care? unlike http/1, it won't mess up our framing, so it's
635
+				// more safe smuggling-wise to ignore.
636
+			}
637
+		} else if len(clens) > 1 {
638
+			// TODO: care? unlike http/1, it won't mess up our framing, so it's
639
+			// more safe smuggling-wise to ignore.
640
+		}
641
+	}
642
+
643
+	if streamEnded || isHead {
644
+		res.Body = noBody
645
+		return res, nil
646
+	}
647
+
648
+	buf := new(bytes.Buffer) // TODO(bradfitz): recycle this garbage
649
+	cs.bufPipe = pipe{b: buf}
650
+	cs.bytesRemain = res.ContentLength
651
+	res.Body = transportResponseBody{cs}
652
+	go cs.awaitRequestCancel(requestCancel(cs.req))
653
+
654
+	if cs.requestedGzip && res.Header.Get("Content-Encoding") == "gzip" {
655
+		res.Header.Del("Content-Encoding")
656
+		res.Header.Del("Content-Length")
657
+		res.ContentLength = -1
658
+		res.Body = &gzipReader{body: res.Body}
659
+	}
660
+	return res, nil
532 661
 }
533 662
 
534
-func (cc *clientConn) onNewHeaderField(f hpack.HeaderField) {
535
-	// TODO: verifiy pseudo headers come before non-pseudo headers
536
-	// TODO: verifiy the status is set
537
-	log.Printf("Header field: %+v", f)
538
-	if f.Name == ":status" {
539
-		code, err := strconv.Atoi(f.Value)
540
-		if err != nil {
541
-			panic("TODO: be graceful")
663
+func (rl *clientConnReadLoop) processTrailers(cs *clientStream, f *MetaHeadersFrame) error {
664
+	if cs.pastTrailers {
665
+		// Too many HEADERS frames for this stream.
666
+		return ConnectionError(ErrCodeProtocol)
667
+	}
668
+	cs.pastTrailers = true
669
+	if !f.StreamEnded() {
670
+		// We expect that any headers for trailers also
671
+		// has END_STREAM.
672
+		return ConnectionError(ErrCodeProtocol)
673
+	}
674
+	if len(f.PseudoFields()) > 0 {
675
+		// No pseudo header fields are defined for trailers.
676
+		// TODO: ConnectionError might be overly harsh? Check.
677
+		return ConnectionError(ErrCodeProtocol)
678
+	}
679
+
680
+	trailer := make(http.Header)
681
+	for _, hf := range f.RegularFields() {
682
+		key := http.CanonicalHeaderKey(hf.Name)
683
+		trailer[key] = append(trailer[key], hf.Value)
684
+	}
685
+	cs.trailer = trailer
686
+
687
+	rl.endStream(cs)
688
+	return nil
689
+}
690
+
691
+// transportResponseBody is the concrete type of Transport.RoundTrip's
692
+// Response.Body. It is an io.ReadCloser. On Read, it reads from cs.body.
693
+// On Close it sends RST_STREAM if EOF wasn't already seen.
694
+type transportResponseBody struct {
695
+	cs *clientStream
696
+}
697
+
698
+func (b transportResponseBody) Read(p []byte) (n int, err error) {
699
+	cs := b.cs
700
+	cc := cs.cc
701
+
702
+	if cs.readErr != nil {
703
+		return 0, cs.readErr
704
+	}
705
+	n, err = b.cs.bufPipe.Read(p)
706
+	if cs.bytesRemain != -1 {
707
+		if int64(n) > cs.bytesRemain {
708
+			n = int(cs.bytesRemain)
709
+			if err == nil {
710
+				err = errors.New("net/http: server replied with more than declared Content-Length; truncated")
711
+				cc.writeStreamReset(cs.ID, ErrCodeProtocol, err)
712
+			}
713
+			cs.readErr = err
714
+			return int(cs.bytesRemain), err
715
+		}
716
+		cs.bytesRemain -= int64(n)
717
+		if err == io.EOF && cs.bytesRemain > 0 {
718
+			err = io.ErrUnexpectedEOF
719
+			cs.readErr = err
720
+			return n, err
542 721
 		}
543
-		cc.nextRes.Status = f.Value + " " + http.StatusText(code)
544
-		cc.nextRes.StatusCode = code
545
-		return
546 722
 	}
547
-	if strings.HasPrefix(f.Name, ":") {
548
-		// "Endpoints MUST NOT generate pseudo-header fields other than those defined in this document."
549
-		// TODO: treat as invalid?
723
+	if n == 0 {
724
+		// No flow control tokens to send back.
550 725
 		return
551 726
 	}
552
-	cc.nextRes.Header.Add(http.CanonicalHeaderKey(f.Name), f.Value)
727
+
728
+	cc.mu.Lock()
729
+	defer cc.mu.Unlock()
730
+
731
+	var connAdd, streamAdd int32
732
+	// Check the conn-level first, before the stream-level.
733
+	if v := cc.inflow.available(); v < transportDefaultConnFlow/2 {
734
+		connAdd = transportDefaultConnFlow - v
735
+		cc.inflow.add(connAdd)
736
+	}
737
+	if err == nil { // No need to refresh if the stream is over or failed.
738
+		if v := cs.inflow.available(); v < transportDefaultStreamFlow-transportDefaultStreamMinRefresh {
739
+			streamAdd = transportDefaultStreamFlow - v
740
+			cs.inflow.add(streamAdd)
741
+		}
742
+	}
743
+	if connAdd != 0 || streamAdd != 0 {
744
+		cc.wmu.Lock()
745
+		defer cc.wmu.Unlock()
746
+		if connAdd != 0 {
747
+			cc.fr.WriteWindowUpdate(0, mustUint31(connAdd))
748
+		}
749
+		if streamAdd != 0 {
750
+			cc.fr.WriteWindowUpdate(cs.ID, mustUint31(streamAdd))
751
+		}
752
+		cc.bw.Flush()
753
+	}
754
+	return
755
+}
756
+
757
+var errClosedResponseBody = errors.New("http2: response body closed")
758
+
759
+func (b transportResponseBody) Close() error {
760
+	cs := b.cs
761
+	if cs.bufPipe.Err() != io.EOF {
762
+		// TODO: write test for this
763
+		cs.cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
764
+	}
765
+	cs.bufPipe.BreakWithError(errClosedResponseBody)
766
+	return nil
767
+}
768
+
769
+func (rl *clientConnReadLoop) processData(f *DataFrame) error {
770
+	cc := rl.cc
771
+	cs := cc.streamByID(f.StreamID, f.StreamEnded())
772
+	if cs == nil {
773
+		cc.mu.Lock()
774
+		neverSent := cc.nextStreamID
775
+		cc.mu.Unlock()
776
+		if f.StreamID >= neverSent {
777
+			// We never asked for this.
778
+			cc.logf("http2: Transport received unsolicited DATA frame; closing connection")
779
+			return ConnectionError(ErrCodeProtocol)
780
+		}
781
+		// We probably did ask for this, but canceled. Just ignore it.
782
+		// TODO: be stricter here? only silently ignore things which
783
+		// we canceled, but not things which were closed normally
784
+		// by the peer? Tough without accumulating too much state.
785
+		return nil
786
+	}
787
+	if data := f.Data(); len(data) > 0 {
788
+		if cs.bufPipe.b == nil {
789
+			// Data frame after it's already closed?
790
+			cc.logf("http2: Transport received DATA frame for closed stream; closing connection")
791
+			return ConnectionError(ErrCodeProtocol)
792
+		}
793
+
794
+		// Check connection-level flow control.
795
+		cc.mu.Lock()
796
+		if cs.inflow.available() >= int32(len(data)) {
797
+			cs.inflow.take(int32(len(data)))
798
+		} else {
799
+			cc.mu.Unlock()
800
+			return ConnectionError(ErrCodeFlowControl)
801
+		}
802
+		cc.mu.Unlock()
803
+
804
+		if _, err := cs.bufPipe.Write(data); err != nil {
805
+			rl.endStreamError(cs, err)
806
+			return err
807
+		}
808
+	}
809
+
810
+	if f.StreamEnded() {
811
+		rl.endStream(cs)
812
+	}
813
+	return nil
814
+}
815
+
816
+var errInvalidTrailers = errors.New("http2: invalid trailers")
817
+
818
+func (rl *clientConnReadLoop) endStream(cs *clientStream) {
819
+	// TODO: check that any declared content-length matches, like
820
+	// server.go's (*stream).endStream method.
821
+	rl.endStreamError(cs, nil)
822
+}
823
+
824
+func (rl *clientConnReadLoop) endStreamError(cs *clientStream, err error) {
825
+	var code func()
826
+	if err == nil {
827
+		err = io.EOF
828
+		code = cs.copyTrailers
829
+	}
830
+	cs.bufPipe.closeWithErrorAndCode(err, code)
831
+	delete(rl.activeRes, cs.ID)
832
+	if cs.req.Close || cs.req.Header.Get("Connection") == "close" {
833
+		rl.closeWhenIdle = true
834
+	}
835
+}
836
+
837
+func (cs *clientStream) copyTrailers() {
838
+	for k, vv := range cs.trailer {
839
+		t := cs.resTrailer
840
+		if *t == nil {
841
+			*t = make(http.Header)
842
+		}
843
+		(*t)[k] = vv
844
+	}
845
+}
846
+
847
+func (rl *clientConnReadLoop) processGoAway(f *GoAwayFrame) error {
848
+	cc := rl.cc
849
+	cc.t.connPool().MarkDead(cc)
850
+	if f.ErrCode != 0 {
851
+		// TODO: deal with GOAWAY more. particularly the error code
852
+		cc.vlogf("transport got GOAWAY with error code = %v", f.ErrCode)
853
+	}
854
+	cc.setGoAway(f)
855
+	return nil
856
+}
857
+
858
+func (rl *clientConnReadLoop) processSettings(f *SettingsFrame) error {
859
+	cc := rl.cc
860
+	cc.mu.Lock()
861
+	defer cc.mu.Unlock()
862
+	return f.ForeachSetting(func(s Setting) error {
863
+		switch s.ID {
864
+		case SettingMaxFrameSize:
865
+			cc.maxFrameSize = s.Val
866
+		case SettingMaxConcurrentStreams:
867
+			cc.maxConcurrentStreams = s.Val
868
+		case SettingInitialWindowSize:
869
+			// TODO: error if this is too large.
870
+
871
+			// TODO: adjust flow control of still-open
872
+			// frames by the difference of the old initial
873
+			// window size and this one.
874
+			cc.initialWindowSize = s.Val
875
+		default:
876
+			// TODO(bradfitz): handle more settings? SETTINGS_HEADER_TABLE_SIZE probably.
877
+			cc.vlogf("Unhandled Setting: %v", s)
878
+		}
879
+		return nil
880
+	})
881
+}
882
+
883
+func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error {
884
+	cc := rl.cc
885
+	cs := cc.streamByID(f.StreamID, false)
886
+	if f.StreamID != 0 && cs == nil {
887
+		return nil
888
+	}
889
+
890
+	cc.mu.Lock()
891
+	defer cc.mu.Unlock()
892
+
893
+	fl := &cc.flow
894
+	if cs != nil {
895
+		fl = &cs.flow
896
+	}
897
+	if !fl.add(int32(f.Increment)) {
898
+		return ConnectionError(ErrCodeFlowControl)
899
+	}
900
+	cc.cond.Broadcast()
901
+	return nil
902
+}
903
+
904
+func (rl *clientConnReadLoop) processResetStream(f *RSTStreamFrame) error {
905
+	cs := rl.cc.streamByID(f.StreamID, true)
906
+	if cs == nil {
907
+		// TODO: return error if server tries to RST_STEAM an idle stream
908
+		return nil
909
+	}
910
+	select {
911
+	case <-cs.peerReset:
912
+		// Already reset.
913
+		// This is the only goroutine
914
+		// which closes this, so there
915
+		// isn't a race.
916
+	default:
917
+		err := StreamError{cs.ID, f.ErrCode}
918
+		cs.resetErr = err
919
+		close(cs.peerReset)
920
+		cs.bufPipe.CloseWithError(err)
921
+		cs.cc.cond.Broadcast() // wake up checkReset via clientStream.awaitFlowControl
922
+	}
923
+	delete(rl.activeRes, cs.ID)
924
+	return nil
925
+}
926
+
927
+func (rl *clientConnReadLoop) processPing(f *PingFrame) error {
928
+	if f.IsAck() {
929
+		// 6.7 PING: " An endpoint MUST NOT respond to PING frames
930
+		// containing this flag."
931
+		return nil
932
+	}
933
+	cc := rl.cc
934
+	cc.wmu.Lock()
935
+	defer cc.wmu.Unlock()
936
+	if err := cc.fr.WritePing(true, f.Data); err != nil {
937
+		return err
938
+	}
939
+	return cc.bw.Flush()
940
+}
941
+
942
+func (rl *clientConnReadLoop) processPushPromise(f *PushPromiseFrame) error {
943
+	// We told the peer we don't want them.
944
+	// Spec says:
945
+	// "PUSH_PROMISE MUST NOT be sent if the SETTINGS_ENABLE_PUSH
946
+	// setting of the peer endpoint is set to 0. An endpoint that
947
+	// has set this setting and has received acknowledgement MUST
948
+	// treat the receipt of a PUSH_PROMISE frame as a connection
949
+	// error (Section 5.4.1) of type PROTOCOL_ERROR."
950
+	return ConnectionError(ErrCodeProtocol)
951
+}
952
+
953
+func (cc *ClientConn) writeStreamReset(streamID uint32, code ErrCode, err error) {
954
+	// TODO: do something with err? send it as a debug frame to the peer?
955
+	// But that's only in GOAWAY. Invent a new frame type? Is there one already?
956
+	cc.wmu.Lock()
957
+	cc.fr.WriteRSTStream(streamID, code)
958
+	cc.bw.Flush()
959
+	cc.wmu.Unlock()
960
+}
961
+
962
+var (
963
+	errResponseHeaderListSize = errors.New("http2: response header list larger than advertised limit")
964
+	errPseudoTrailers         = errors.New("http2: invalid pseudo header in trailers")
965
+)
966
+
967
+func (cc *ClientConn) logf(format string, args ...interface{}) {
968
+	cc.t.logf(format, args...)
969
+}
970
+
971
+func (cc *ClientConn) vlogf(format string, args ...interface{}) {
972
+	cc.t.vlogf(format, args...)
973
+}
974
+
975
+func (t *Transport) vlogf(format string, args ...interface{}) {
976
+	if VerboseLogs {
977
+		t.logf(format, args...)
978
+	}
979
+}
980
+
981
+func (t *Transport) logf(format string, args ...interface{}) {
982
+	log.Printf(format, args...)
553 983
 }
984
+
985
+var noBody io.ReadCloser = ioutil.NopCloser(bytes.NewReader(nil))
986
+
987
+func strSliceContains(ss []string, s string) bool {
988
+	for _, v := range ss {
989
+		if v == s {
990
+			return true
991
+		}
992
+	}
993
+	return false
994
+}
995
+
996
+type erringRoundTripper struct{ err error }
997
+
998
+func (rt erringRoundTripper) RoundTrip(*http.Request) (*http.Response, error) { return nil, rt.err }
999
+
1000
+// gzipReader wraps a response body so it can lazily
1001
+// call gzip.NewReader on the first call to Read
1002
+type gzipReader struct {
1003
+	body io.ReadCloser // underlying Response.Body
1004
+	zr   *gzip.Reader  // lazily-initialized gzip reader
1005
+	zerr error         // sticky error
1006
+}
1007
+
1008
+func (gz *gzipReader) Read(p []byte) (n int, err error) {
1009
+	if gz.zerr != nil {
1010
+		return 0, gz.zerr
1011
+	}
1012
+	if gz.zr == nil {
1013
+		gz.zr, err = gzip.NewReader(gz.body)
1014
+		if err != nil {
1015
+			gz.zerr = err
1016
+			return 0, err
1017
+		}
1018
+	}
1019
+	return gz.zr.Read(p)
1020
+}
1021
+
1022
+func (gz *gzipReader) Close() error {
1023
+	return gz.body.Close()
1024
+}
1025
+
1026
+type errorReader struct{ err error }
1027
+
1028
+func (r errorReader) Read(p []byte) (int, error) { return 0, r.err }
... ...
@@ -1,15 +1,13 @@
1 1
 // Copyright 2014 The Go Authors. All rights reserved.
2 2
 // Use of this source code is governed by a BSD-style
3 3
 // license that can be found in the LICENSE file.
4
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
5
-// Licensed under the same terms as Go itself:
6
-// https://code.google.com/p/go/source/browse/LICENSE
7 4
 
8 5
 package http2
9 6
 
10 7
 import (
11 8
 	"bytes"
12 9
 	"fmt"
10
+	"log"
13 11
 	"net/http"
14 12
 	"time"
15 13
 
... ...
@@ -26,7 +24,11 @@ type writeFramer interface {
26 26
 // frame writing scheduler (see writeScheduler in writesched.go).
27 27
 //
28 28
 // This interface is implemented by *serverConn.
29
-// TODO: use it from the client code too, once it exists.
29
+//
30
+// TODO: decide whether to a) use this in the client code (which didn't
31
+// end up using this yet, because it has a simpler design, not
32
+// currently implementing priorities), or b) delete this and
33
+// make the server code a bit more concrete.
30 34
 type writeContext interface {
31 35
 	Framer() *Framer
32 36
 	Flush() error
... ...
@@ -44,6 +46,11 @@ func endsStream(w writeFramer) bool {
44 44
 		return v.endStream
45 45
 	case *writeResHeaders:
46 46
 		return v.endStream
47
+	case nil:
48
+		// This can only happen if the caller reuses w after it's
49
+		// been intentionally nil'ed out to prevent use. Keep this
50
+		// here to catch future refactoring breaking it.
51
+		panic("endsStream called on nil writeFramer")
47 52
 	}
48 53
 	return false
49 54
 }
... ...
@@ -89,6 +96,16 @@ func (w *writeData) writeFrame(ctx writeContext) error {
89 89
 	return ctx.Framer().WriteData(w.streamID, w.endStream, w.p)
90 90
 }
91 91
 
92
+// handlerPanicRST is the message sent from handler goroutines when
93
+// the handler panics.
94
+type handlerPanicRST struct {
95
+	StreamID uint32
96
+}
97
+
98
+func (hp handlerPanicRST) writeFrame(ctx writeContext) error {
99
+	return ctx.Framer().WriteRSTStream(hp.StreamID, ErrCodeInternal)
100
+}
101
+
92 102
 func (se StreamError) writeFrame(ctx writeContext) error {
93 103
 	return ctx.Framer().WriteRSTStream(se.StreamID, se.Code)
94 104
 }
... ...
@@ -106,40 +123,48 @@ func (writeSettingsAck) writeFrame(ctx writeContext) error {
106 106
 }
107 107
 
108 108
 // writeResHeaders is a request to write a HEADERS and 0+ CONTINUATION frames
109
-// for HTTP response headers from a server handler.
109
+// for HTTP response headers or trailers from a server handler.
110 110
 type writeResHeaders struct {
111 111
 	streamID    uint32
112
-	httpResCode int
112
+	httpResCode int         // 0 means no ":status" line
113 113
 	h           http.Header // may be nil
114
+	trailers    []string    // if non-nil, which keys of h to write. nil means all.
114 115
 	endStream   bool
115 116
 
117
+	date          string
116 118
 	contentType   string
117 119
 	contentLength string
118 120
 }
119 121
 
122
+func encKV(enc *hpack.Encoder, k, v string) {
123
+	if VerboseLogs {
124
+		log.Printf("http2: server encoding header %q = %q", k, v)
125
+	}
126
+	enc.WriteField(hpack.HeaderField{Name: k, Value: v})
127
+}
128
+
120 129
 func (w *writeResHeaders) writeFrame(ctx writeContext) error {
121 130
 	enc, buf := ctx.HeaderEncoder()
122 131
 	buf.Reset()
123
-	enc.WriteField(hpack.HeaderField{Name: ":status", Value: httpCodeString(w.httpResCode)})
124
-	for k, vv := range w.h {
125
-		k = lowerHeader(k)
126
-		for _, v := range vv {
127
-			// TODO: more of "8.1.2.2 Connection-Specific Header Fields"
128
-			if k == "transfer-encoding" && v != "trailers" {
129
-				continue
130
-			}
131
-			enc.WriteField(hpack.HeaderField{Name: k, Value: v})
132
-		}
132
+
133
+	if w.httpResCode != 0 {
134
+		encKV(enc, ":status", httpCodeString(w.httpResCode))
133 135
 	}
136
+
137
+	encodeHeaders(enc, w.h, w.trailers)
138
+
134 139
 	if w.contentType != "" {
135
-		enc.WriteField(hpack.HeaderField{Name: "content-type", Value: w.contentType})
140
+		encKV(enc, "content-type", w.contentType)
136 141
 	}
137 142
 	if w.contentLength != "" {
138
-		enc.WriteField(hpack.HeaderField{Name: "content-length", Value: w.contentLength})
143
+		encKV(enc, "content-length", w.contentLength)
144
+	}
145
+	if w.date != "" {
146
+		encKV(enc, "date", w.date)
139 147
 	}
140 148
 
141 149
 	headerBlock := buf.Bytes()
142
-	if len(headerBlock) == 0 {
150
+	if len(headerBlock) == 0 && w.trailers == nil {
143 151
 		panic("unexpected empty hpack")
144 152
 	}
145 153
 
... ...
@@ -185,7 +210,7 @@ type write100ContinueHeadersFrame struct {
185 185
 func (w write100ContinueHeadersFrame) writeFrame(ctx writeContext) error {
186 186
 	enc, buf := ctx.HeaderEncoder()
187 187
 	buf.Reset()
188
-	enc.WriteField(hpack.HeaderField{Name: ":status", Value: "100"})
188
+	encKV(enc, ":status", "100")
189 189
 	return ctx.Framer().WriteHeaders(HeadersFrameParam{
190 190
 		StreamID:      w.streamID,
191 191
 		BlockFragment: buf.Bytes(),
... ...
@@ -202,3 +227,36 @@ type writeWindowUpdate struct {
202 202
 func (wu writeWindowUpdate) writeFrame(ctx writeContext) error {
203 203
 	return ctx.Framer().WriteWindowUpdate(wu.streamID, wu.n)
204 204
 }
205
+
206
+func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) {
207
+	if keys == nil {
208
+		sorter := sorterPool.Get().(*sorter)
209
+		// Using defer here, since the returned keys from the
210
+		// sorter.Keys method is only valid until the sorter
211
+		// is returned:
212
+		defer sorterPool.Put(sorter)
213
+		keys = sorter.Keys(h)
214
+	}
215
+	for _, k := range keys {
216
+		vv := h[k]
217
+		k = lowerHeader(k)
218
+		if !validHeaderFieldName(k) {
219
+			// TODO: return an error? golang.org/issue/14048
220
+			// For now just omit it.
221
+			continue
222
+		}
223
+		isTE := k == "transfer-encoding"
224
+		for _, v := range vv {
225
+			if !validHeaderFieldValue(v) {
226
+				// TODO: return an error? golang.org/issue/14048
227
+				// For now just omit it.
228
+				continue
229
+			}
230
+			// TODO: more of "8.1.2.2 Connection-Specific Header Fields"
231
+			if isTE && v != "trailers" {
232
+				continue
233
+			}
234
+			encKV(enc, k, v)
235
+		}
236
+	}
237
+}
... ...
@@ -1,9 +1,6 @@
1 1
 // Copyright 2014 The Go Authors. All rights reserved.
2 2
 // Use of this source code is governed by a BSD-style
3 3
 // license that can be found in the LICENSE file.
4
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
5
-// Licensed under the same terms as Go itself:
6
-// https://code.google.com/p/go/source/browse/LICENSE
7 4
 
8 5
 package http2
9 6
 
... ...
@@ -95,11 +95,14 @@ var DebugUseAfterFinish = false
95 95
 //
96 96
 // The default AuthRequest function returns (true, true) iff the request comes from localhost/127.0.0.1/[::1].
97 97
 var AuthRequest = func(req *http.Request) (any, sensitive bool) {
98
+	// RemoteAddr is commonly in the form "IP" or "IP:port".
99
+	// If it is in the form "IP:port", split off the port.
98 100
 	host, _, err := net.SplitHostPort(req.RemoteAddr)
99
-	switch {
100
-	case err != nil: // Badly formed address; fail closed.
101
-		return false, false
102
-	case host == "localhost" || host == "127.0.0.1" || host == "::1":
101
+	if err != nil {
102
+		host = req.RemoteAddr
103
+	}
104
+	switch host {
105
+	case "localhost", "127.0.0.1", "::1":
103 106
 		return true, true
104 107
 	default:
105 108
 		return false, false
... ...
@@ -113,6 +116,7 @@ func init() {
113 113
 			http.Error(w, "not allowed", http.StatusUnauthorized)
114 114
 			return
115 115
 		}
116
+		w.Header().Set("Content-Type", "text/html; charset=utf-8")
116 117
 		Render(w, req, sensitive)
117 118
 	})
118 119
 	http.HandleFunc("/debug/events", func(w http.ResponseWriter, req *http.Request) {
... ...
@@ -121,6 +125,7 @@ func init() {
121 121
 			http.Error(w, "not allowed", http.StatusUnauthorized)
122 122
 			return
123 123
 		}
124
+		w.Header().Set("Content-Type", "text/html; charset=utf-8")
124 125
 		RenderEvents(w, req, sensitive)
125 126
 	})
126 127
 }
... ...
@@ -172,7 +177,7 @@ func Render(w io.Writer, req *http.Request, sensitive bool) {
172 172
 
173 173
 	completedMu.RLock()
174 174
 	data.Families = make([]string, 0, len(completedTraces))
175
-	for fam, _ := range completedTraces {
175
+	for fam := range completedTraces {
176 176
 		data.Families = append(data.Families, fam)
177 177
 	}
178 178
 	completedMu.RUnlock()
... ...
@@ -144,6 +144,8 @@ type frameHandler interface {
144 144
 }
145 145
 
146 146
 // Conn represents a WebSocket connection.
147
+//
148
+// Multiple goroutines may invoke methods on a Conn simultaneously.
147 149
 type Conn struct {
148 150
 	config  *Config
149 151
 	request *http.Request
... ...
@@ -1,5 +1,9 @@
1 1
 language: go
2 2
 
3
+go:
4
+  - 1.5.3
5
+  - 1.6
6
+
3 7
 before_install:
4 8
   - go get github.com/axw/gocov/gocov
5 9
   - go get github.com/mattn/goveralls
... ...
@@ -11,4 +15,3 @@ install:
11 11
 
12 12
 script:
13 13
   - make test testrace
14
-  - make coverage
... ...
@@ -1,16 +1,39 @@
1 1
 # How to contribute
2 2
 
3
-We definitely welcome patches and contribution to grpc! Here is some guideline
3
+We definitely welcome patches and contribution to grpc! Here are some guidelines
4 4
 and information about how to do so.
5 5
 
6
-## Getting started
6
+## Sending patches
7 7
 
8
-### Legal requirements
8
+### Getting started
9
+
10
+1. Check out the code:
11
+
12
+        $ go get google.golang.org/grpc
13
+        $ cd $GOPATH/src/google.golang.org/grpc
14
+
15
+1. Create a fork of the grpc-go repository.
16
+1. Add your fork as a remote:
17
+
18
+        $ git remote add fork git@github.com:$YOURGITHUBUSERNAME/grpc-go.git
19
+
20
+1. Make changes, commit them.
21
+1. Run the test suite:
22
+
23
+        $ make test
24
+
25
+1. Push your changes to your fork:
26
+
27
+        $ git push fork ...
28
+
29
+1. Open a pull request.
30
+
31
+## Legal requirements
9 32
 
10 33
 In order to protect both you and ourselves, you will need to sign the
11 34
 [Contributor License Agreement](https://cla.developers.google.com/clas).
12 35
 
13
-### Filing Issues
36
+## Filing Issues
14 37
 When filing an issue, make sure to answer these five questions:
15 38
 
16 39
 1. What version of Go are you using (`go version`)?
... ...
@@ -1,15 +1,3 @@
1
-.PHONY: \
2
-	all \
3
-	deps \
4
-	updatedeps \
5
-	testdeps \
6
-	updatetestdeps \
7
-	build \
8
-	proto \
9
-	test \
10
-	testrace \
11
-	clean \
12
-
13 1
 all: test testrace
14 2
 
15 3
 deps:
... ...
@@ -32,7 +20,7 @@ proto:
32 32
 		echo "error: protoc not installed" >&2; \
33 33
 		exit 1; \
34 34
 	fi
35
-	go get -v github.com/golang/protobuf/protoc-gen-go
35
+	go get -u -v github.com/golang/protobuf/protoc-gen-go
36 36
 	for file in $$(git ls-files '*.proto'); do \
37 37
 		protoc -I $$(dirname $$file) --go_out=plugins=grpc:$$(dirname $$file) $$file; \
38 38
 	done
... ...
@@ -44,7 +32,20 @@ testrace: testdeps
44 44
 	go test -v -race -cpu 1,4 google.golang.org/grpc/...
45 45
 
46 46
 clean:
47
-	go clean google.golang.org/grpc/...
47
+	go clean -i google.golang.org/grpc/...
48 48
 
49 49
 coverage: testdeps
50 50
 	./coverage.sh --coveralls
51
+
52
+.PHONY: \
53
+	all \
54
+	deps \
55
+	updatedeps \
56
+	testdeps \
57
+	updatetestdeps \
58
+	build \
59
+	proto \
60
+	test \
61
+	testrace \
62
+	clean \
63
+	coverage
... ...
@@ -7,7 +7,7 @@ The Go implementation of [gRPC](http://www.grpc.io/): A high performance, open s
7 7
 Installation
8 8
 ------------
9 9
 
10
-To install this package, you need to install Go 1.4 or above and setup your Go workspace on your computer. The simplest way to install the library is to run:
10
+To install this package, you need to install Go and setup your Go workspace on your computer. The simplest way to install the library is to run:
11 11
 
12 12
 ```
13 13
 $ go get google.golang.org/grpc
... ...
@@ -16,7 +16,7 @@ $ go get google.golang.org/grpc
16 16
 Prerequisites
17 17
 -------------
18 18
 
19
-This requires Go 1.4 or above.
19
+This requires Go 1.5 or later .
20 20
 
21 21
 Constraints
22 22
 -----------
23 23
new file mode 100644
... ...
@@ -0,0 +1,80 @@
0
+package grpc
1
+
2
+import (
3
+	"math/rand"
4
+	"time"
5
+)
6
+
7
+// DefaultBackoffConfig uses values specified for backoff in
8
+// https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md.
9
+var (
10
+	DefaultBackoffConfig = BackoffConfig{
11
+		MaxDelay:  120 * time.Second,
12
+		baseDelay: 1.0 * time.Second,
13
+		factor:    1.6,
14
+		jitter:    0.2,
15
+	}
16
+)
17
+
18
+// backoffStrategy defines the methodology for backing off after a grpc
19
+// connection failure.
20
+//
21
+// This is unexported until the GRPC project decides whether or not to allow
22
+// alternative backoff strategies. Once a decision is made, this type and its
23
+// method may be exported.
24
+type backoffStrategy interface {
25
+	// backoff returns the amount of time to wait before the next retry given
26
+	// the number of consecutive failures.
27
+	backoff(retries int) time.Duration
28
+}
29
+
30
+// BackoffConfig defines the parameters for the default GRPC backoff strategy.
31
+type BackoffConfig struct {
32
+	// MaxDelay is the upper bound of backoff delay.
33
+	MaxDelay time.Duration
34
+
35
+	// TODO(stevvooe): The following fields are not exported, as allowing
36
+	// changes would violate the current GRPC specification for backoff. If
37
+	// GRPC decides to allow more interesting backoff strategies, these fields
38
+	// may be opened up in the future.
39
+
40
+	// baseDelay is the amount of time to wait before retrying after the first
41
+	// failure.
42
+	baseDelay time.Duration
43
+
44
+	// factor is applied to the backoff after each retry.
45
+	factor float64
46
+
47
+	// jitter provides a range to randomize backoff delays.
48
+	jitter float64
49
+}
50
+
51
+func setDefaults(bc *BackoffConfig) {
52
+	md := bc.MaxDelay
53
+	*bc = DefaultBackoffConfig
54
+
55
+	if md > 0 {
56
+		bc.MaxDelay = md
57
+	}
58
+}
59
+
60
+func (bc BackoffConfig) backoff(retries int) (t time.Duration) {
61
+	if retries == 0 {
62
+		return bc.baseDelay
63
+	}
64
+	backoff, max := float64(bc.baseDelay), float64(bc.MaxDelay)
65
+	for backoff < max && retries > 0 {
66
+		backoff *= bc.factor
67
+		retries--
68
+	}
69
+	if backoff > max {
70
+		backoff = max
71
+	}
72
+	// Randomize backoff delays so that if a cluster of requests start at
73
+	// the same time, they won't operate in lockstep.
74
+	backoff *= 1 + bc.jitter*(rand.Float64()*2-1)
75
+	if backoff < 0 {
76
+		return 0
77
+	}
78
+	return time.Duration(backoff)
79
+}
... ...
@@ -34,13 +34,13 @@
34 34
 package grpc
35 35
 
36 36
 import (
37
+	"bytes"
37 38
 	"io"
38 39
 	"time"
39 40
 
40 41
 	"golang.org/x/net/context"
41 42
 	"golang.org/x/net/trace"
42 43
 	"google.golang.org/grpc/codes"
43
-	"google.golang.org/grpc/metadata"
44 44
 	"google.golang.org/grpc/transport"
45 45
 )
46 46
 
... ...
@@ -48,16 +48,16 @@ import (
48 48
 // On error, it returns the error and indicates whether the call should be retried.
49 49
 //
50 50
 // TODO(zhaoq): Check whether the received message sequence is valid.
51
-func recvResponse(codec Codec, t transport.ClientTransport, c *callInfo, stream *transport.Stream, reply interface{}) error {
51
+func recvResponse(dopts dialOptions, t transport.ClientTransport, c *callInfo, stream *transport.Stream, reply interface{}) error {
52 52
 	// Try to acquire header metadata from the server if there is any.
53 53
 	var err error
54 54
 	c.headerMD, err = stream.Header()
55 55
 	if err != nil {
56 56
 		return err
57 57
 	}
58
-	p := &parser{s: stream}
58
+	p := &parser{r: stream}
59 59
 	for {
60
-		if err = recv(p, codec, reply); err != nil {
60
+		if err = recv(p, dopts.codec, stream, dopts.dc, reply); err != nil {
61 61
 			if err == io.EOF {
62 62
 				break
63 63
 			}
... ...
@@ -69,7 +69,7 @@ func recvResponse(codec Codec, t transport.ClientTransport, c *callInfo, stream
69 69
 }
70 70
 
71 71
 // sendRequest writes out various information of an RPC such as Context and Message.
72
-func sendRequest(ctx context.Context, codec Codec, callHdr *transport.CallHdr, t transport.ClientTransport, args interface{}, opts *transport.Options) (_ *transport.Stream, err error) {
72
+func sendRequest(ctx context.Context, codec Codec, compressor Compressor, callHdr *transport.CallHdr, t transport.ClientTransport, args interface{}, opts *transport.Options) (_ *transport.Stream, err error) {
73 73
 	stream, err := t.NewStream(ctx, callHdr)
74 74
 	if err != nil {
75 75
 		return nil, err
... ...
@@ -81,8 +81,11 @@ func sendRequest(ctx context.Context, codec Codec, callHdr *transport.CallHdr, t
81 81
 			}
82 82
 		}
83 83
 	}()
84
-	// TODO(zhaoq): Support compression.
85
-	outBuf, err := encode(codec, args, compressionNone)
84
+	var cbuf *bytes.Buffer
85
+	if compressor != nil {
86
+		cbuf = new(bytes.Buffer)
87
+	}
88
+	outBuf, err := encode(codec, args, compressor, cbuf)
86 89
 	if err != nil {
87 90
 		return nil, transport.StreamErrorf(codes.Internal, "grpc: %v", err)
88 91
 	}
... ...
@@ -94,16 +97,9 @@ func sendRequest(ctx context.Context, codec Codec, callHdr *transport.CallHdr, t
94 94
 	return stream, nil
95 95
 }
96 96
 
97
-// callInfo contains all related configuration and information about an RPC.
98
-type callInfo struct {
99
-	failFast  bool
100
-	headerMD  metadata.MD
101
-	trailerMD metadata.MD
102
-	traceInfo traceInfo // in trace.go
103
-}
104
-
105
-// Invoke is called by the generated code. It sends the RPC request on the
106
-// wire and returns after response is received.
97
+// Invoke sends the RPC request on the wire and returns after response is received.
98
+// Invoke is called by generated code. Also users can call Invoke directly when it
99
+// is really needed in their use cases.
107 100
 func Invoke(ctx context.Context, method string, args, reply interface{}, cc *ClientConn, opts ...CallOption) (err error) {
108 101
 	var c callInfo
109 102
 	for _, o := range opts {
... ...
@@ -153,6 +149,9 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
153 153
 			Host:   cc.authority,
154 154
 			Method: method,
155 155
 		}
156
+		if cc.dopts.cp != nil {
157
+			callHdr.SendCompress = cc.dopts.cp.Type()
158
+		}
156 159
 		t, err = cc.dopts.picker.Pick(ctx)
157 160
 		if err != nil {
158 161
 			if lastErr != nil {
... ...
@@ -164,7 +163,7 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
164 164
 		if c.traceInfo.tr != nil {
165 165
 			c.traceInfo.tr.LazyLog(&payload{sent: true, msg: args}, true)
166 166
 		}
167
-		stream, err = sendRequest(ctx, cc.dopts.codec, callHdr, t, args, topts)
167
+		stream, err = sendRequest(ctx, cc.dopts.codec, cc.dopts.cp, callHdr, t, args, topts)
168 168
 		if err != nil {
169 169
 			if _, ok := err.(transport.ConnectionError); ok {
170 170
 				lastErr = err
... ...
@@ -176,7 +175,7 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
176 176
 			return toRPCErr(err)
177 177
 		}
178 178
 		// Receive the response
179
-		lastErr = recvResponse(cc.dopts.codec, t, &c, stream, reply)
179
+		lastErr = recvResponse(cc.dopts, t, &c, stream, reply)
180 180
 		if _, ok := lastErr.(transport.ConnectionError); ok {
181 181
 			continue
182 182
 		}
... ...
@@ -187,6 +186,6 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
187 187
 		if lastErr != nil {
188 188
 			return toRPCErr(lastErr)
189 189
 		}
190
-		return Errorf(stream.StatusCode(), stream.StatusDesc())
190
+		return Errorf(stream.StatusCode(), "%s", stream.StatusDesc())
191 191
 	}
192 192
 }
... ...
@@ -52,10 +52,10 @@ var (
52 52
 	// ErrUnspecTarget indicates that the target address is unspecified.
53 53
 	ErrUnspecTarget = errors.New("grpc: target is unspecified")
54 54
 	// ErrNoTransportSecurity indicates that there is no transport security
55
-	// being set for ClientConn. Users should either set one or explicityly
55
+	// being set for ClientConn. Users should either set one or explicitly
56 56
 	// call WithInsecure DialOption to disable security.
57 57
 	ErrNoTransportSecurity = errors.New("grpc: no transport security set (use grpc.WithInsecure() explicitly or set credentials)")
58
-	// ErrCredentialsMisuse indicates that users want to transmit security infomation
58
+	// ErrCredentialsMisuse indicates that users want to transmit security information
59 59
 	// (e.g., oauth2 token) which requires secure connection on an insecure
60 60
 	// connection.
61 61
 	ErrCredentialsMisuse = errors.New("grpc: the credentials require transport level security (use grpc.WithTransportAuthenticator() to set)")
... ...
@@ -73,6 +73,9 @@ var (
73 73
 // values passed to Dial.
74 74
 type dialOptions struct {
75 75
 	codec    Codec
76
+	cp       Compressor
77
+	dc       Decompressor
78
+	bs       backoffStrategy
76 79
 	picker   Picker
77 80
 	block    bool
78 81
 	insecure bool
... ...
@@ -89,12 +92,57 @@ func WithCodec(c Codec) DialOption {
89 89
 	}
90 90
 }
91 91
 
92
+// WithCompressor returns a DialOption which sets a CompressorGenerator for generating message
93
+// compressor.
94
+func WithCompressor(cp Compressor) DialOption {
95
+	return func(o *dialOptions) {
96
+		o.cp = cp
97
+	}
98
+}
99
+
100
+// WithDecompressor returns a DialOption which sets a DecompressorGenerator for generating
101
+// message decompressor.
102
+func WithDecompressor(dc Decompressor) DialOption {
103
+	return func(o *dialOptions) {
104
+		o.dc = dc
105
+	}
106
+}
107
+
108
+// WithPicker returns a DialOption which sets a picker for connection selection.
92 109
 func WithPicker(p Picker) DialOption {
93 110
 	return func(o *dialOptions) {
94 111
 		o.picker = p
95 112
 	}
96 113
 }
97 114
 
115
+// WithBackoffMaxDelay configures the dialer to use the provided maximum delay
116
+// when backing off after failed connection attempts.
117
+func WithBackoffMaxDelay(md time.Duration) DialOption {
118
+	return WithBackoffConfig(BackoffConfig{MaxDelay: md})
119
+}
120
+
121
+// WithBackoffConfig configures the dialer to use the provided backoff
122
+// parameters after connection failures.
123
+//
124
+// Use WithBackoffMaxDelay until more parameters on BackoffConfig are opened up
125
+// for use.
126
+func WithBackoffConfig(b BackoffConfig) DialOption {
127
+	// Set defaults to ensure that provided BackoffConfig is valid and
128
+	// unexported fields get default values.
129
+	setDefaults(&b)
130
+	return withBackoff(b)
131
+}
132
+
133
+// withBackoff sets the backoff strategy used for retries after a
134
+// failed connection attempt.
135
+//
136
+// This can be exported if arbitrary backoff strategies are allowed by GRPC.
137
+func withBackoff(bs backoffStrategy) DialOption {
138
+	return func(o *dialOptions) {
139
+		o.bs = bs
140
+	}
141
+}
142
+
98 143
 // WithBlock returns a DialOption which makes caller of Dial blocks until the underlying
99 144
 // connection is up. Without this, Dial returns immediately and connecting the server
100 145
 // happens in background.
... ...
@@ -104,6 +152,8 @@ func WithBlock() DialOption {
104 104
 	}
105 105
 }
106 106
 
107
+// WithInsecure returns a DialOption which disables transport security for this ClientConn.
108
+// Note that transport security is required unless WithInsecure is set.
107 109
 func WithInsecure() DialOption {
108 110
 	return func(o *dialOptions) {
109 111
 		o.insecure = true
... ...
@@ -159,6 +209,11 @@ func Dial(target string, opts ...DialOption) (*ClientConn, error) {
159 159
 		// Set the default codec.
160 160
 		cc.dopts.codec = protoCodec{}
161 161
 	}
162
+
163
+	if cc.dopts.bs == nil {
164
+		cc.dopts.bs = DefaultBackoffConfig
165
+	}
166
+
162 167
 	if cc.dopts.picker == nil {
163 168
 		cc.dopts.picker = &unicastPicker{
164 169
 			target: target,
... ...
@@ -267,10 +322,9 @@ func NewConn(cc *ClientConn) (*Conn, error) {
267 267
 	if !c.dopts.insecure {
268 268
 		var ok bool
269 269
 		for _, cd := range c.dopts.copts.AuthOptions {
270
-			if _, ok := cd.(credentials.TransportAuthenticator); !ok {
271
-				continue
270
+			if _, ok = cd.(credentials.TransportAuthenticator); ok {
271
+				break
272 272
 			}
273
-			ok = true
274 273
 		}
275 274
 		if !ok {
276 275
 			return nil, ErrNoTransportSecurity
... ...
@@ -395,7 +449,7 @@ func (cc *Conn) resetTransport(closeTransport bool) error {
395 395
 				return ErrClientConnTimeout
396 396
 			}
397 397
 		}
398
-		sleepTime := backoff(retries)
398
+		sleepTime := cc.dopts.bs.backoff(retries)
399 399
 		timeout := sleepTime
400 400
 		if timeout < minConnectTimeout {
401 401
 			timeout = minConnectTimeout
... ...
@@ -518,8 +572,9 @@ func (cc *Conn) Wait(ctx context.Context) (transport.ClientTransport, error) {
518 518
 			cc.mu.Unlock()
519 519
 			return nil, ErrClientConnClosing
520 520
 		case cc.state == Ready:
521
+			ct := cc.transport
521 522
 			cc.mu.Unlock()
522
-			return cc.transport, nil
523
+			return ct, nil
523 524
 		default:
524 525
 			ready := cc.ready
525 526
 			if ready == nil {
... ...
@@ -4,15 +4,20 @@ set -e
4 4
 
5 5
 workdir=.cover
6 6
 profile="$workdir/cover.out"
7
-mode=count
7
+mode=set
8
+end2endtest="google.golang.org/grpc/test"
8 9
 
9 10
 generate_cover_data() {
10 11
     rm -rf "$workdir"
11 12
     mkdir "$workdir"
12 13
 
13 14
     for pkg in "$@"; do
14
-        f="$workdir/$(echo $pkg | tr / -).cover"
15
-        go test -covermode="$mode" -coverprofile="$f" "$pkg"
15
+        if [ $pkg == "google.golang.org/grpc" -o $pkg == "google.golang.org/grpc/transport" -o $pkg == "google.golang.org/grpc/metadata" -o $pkg == "google.golang.org/grpc/credentials" ]
16
+            then
17
+                f="$workdir/$(echo $pkg | tr / -)"
18
+                go test -covermode="$mode" -coverprofile="$f.cover" "$pkg"
19
+                go test -covermode="$mode" -coverpkg "$pkg" -coverprofile="$f.e2e.cover" "$end2endtest"
20
+        fi
16 21
     done
17 22
 
18 23
     echo "mode: $mode" >"$profile"
... ...
@@ -32,6 +37,8 @@ show_cover_report func
32 32
 case "$1" in
33 33
 "")
34 34
     ;;
35
+--html)
36
+    show_cover_report html ;;
35 37
 --coveralls)
36 38
     push_to_coveralls ;;
37 39
 *)
... ...
@@ -87,19 +87,6 @@ type AuthInfo interface {
87 87
 	AuthType() string
88 88
 }
89 89
 
90
-type authInfoKey struct{}
91
-
92
-// NewContext creates a new context with authInfo attached.
93
-func NewContext(ctx context.Context, authInfo AuthInfo) context.Context {
94
-	return context.WithValue(ctx, authInfoKey{}, authInfo)
95
-}
96
-
97
-// FromContext returns the authInfo in ctx if it exists.
98
-func FromContext(ctx context.Context) (authInfo AuthInfo, ok bool) {
99
-	authInfo, ok = ctx.Value(authInfoKey{}).(AuthInfo)
100
-	return
101
-}
102
-
103 90
 // TransportAuthenticator defines the common interface for all the live gRPC wire
104 91
 // protocols and supported transport security protocols (e.g., TLS, SSL).
105 92
 type TransportAuthenticator interface {
... ...
@@ -1,6 +1,6 @@
1 1
 /*
2 2
 Package grpc implements an RPC system called gRPC.
3 3
 
4
-See https://github.com/grpc/grpc for more information about gRPC.
4
+See www.grpc.io for more information about gRPC.
5 5
 */
6 6
 package grpc // import "google.golang.org/grpc"
... ...
@@ -42,6 +42,8 @@ import (
42 42
 )
43 43
 
44 44
 // Use golang's standard logger by default.
45
+// Access is not mutex-protected: do not modify except in init()
46
+// functions.
45 47
 var logger Logger = log.New(os.Stderr, "", log.LstdFlags)
46 48
 
47 49
 // Logger mimics golang's standard Logger as an interface.
... ...
@@ -54,7 +56,8 @@ type Logger interface {
54 54
 	Println(args ...interface{})
55 55
 }
56 56
 
57
-// SetLogger sets the logger that is used in grpc.
57
+// SetLogger sets the logger that is used in grpc. Call only from
58
+// init() functions.
58 59
 func SetLogger(l Logger) {
59 60
 	logger = l
60 61
 }
61 62
new file mode 100644
... ...
@@ -0,0 +1,74 @@
0
+/*
1
+ *
2
+ * Copyright 2016, Google Inc.
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions are
7
+ * met:
8
+ *
9
+ *     * Redistributions of source code must retain the above copyright
10
+ * notice, this list of conditions and the following disclaimer.
11
+ *     * Redistributions in binary form must reproduce the above
12
+ * copyright notice, this list of conditions and the following disclaimer
13
+ * in the documentation and/or other materials provided with the
14
+ * distribution.
15
+ *     * Neither the name of Google Inc. nor the names of its
16
+ * contributors may be used to endorse or promote products derived from
17
+ * this software without specific prior written permission.
18
+ *
19
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ *
31
+ */
32
+
33
+package grpc
34
+
35
+import (
36
+	"golang.org/x/net/context"
37
+)
38
+
39
+// UnaryServerInfo consists of various information about a unary RPC on
40
+// server side. All per-rpc information may be mutated by the interceptor.
41
+type UnaryServerInfo struct {
42
+	// Server is the service implementation the user provides. This is read-only.
43
+	Server interface{}
44
+	// FullMethod is the full RPC method string, i.e., /package.service/method.
45
+	FullMethod string
46
+}
47
+
48
+// UnaryHandler defines the handler invoked by UnaryServerInterceptor to complete the normal
49
+// execution of a unary RPC.
50
+type UnaryHandler func(ctx context.Context, req interface{}) (interface{}, error)
51
+
52
+// UnaryServerInterceptor provides a hook to intercept the execution of a unary RPC on the server. info
53
+// contains all the information of this RPC the interceptor can operate on. And handler is the wrapper
54
+// of the service method implementation. It is the responsibility of the interceptor to invoke handler
55
+// to complete the RPC.
56
+type UnaryServerInterceptor func(ctx context.Context, req interface{}, info *UnaryServerInfo, handler UnaryHandler) (resp interface{}, err error)
57
+
58
+// StreamServerInfo consists of various information about a streaming RPC on
59
+// server side. All per-rpc information may be mutated by the interceptor.
60
+type StreamServerInfo struct {
61
+	// FullMethod is the full RPC method string, i.e., /package.service/method.
62
+	FullMethod string
63
+	// IsClientStream indicates whether the RPC is a client streaming RPC.
64
+	IsClientStream bool
65
+	// IsServerStream indicates whether the RPC is a server streaming RPC.
66
+	IsServerStream bool
67
+}
68
+
69
+// StreamServerInterceptor provides a hook to intercept the execution of a streaming RPC on the server.
70
+// info contains all the information of this RPC the interceptor can operate on. And handler is the
71
+// service method implementation. It is the responsibility of the interceptor to invoke handler to
72
+// complete the RPC.
73
+type StreamServerInterceptor func(srv interface{}, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error
0 74
new file mode 100644
... ...
@@ -0,0 +1,49 @@
0
+/*
1
+ * Copyright 2016, Google Inc.
2
+ * All rights reserved.
3
+ *
4
+ * Redistribution and use in source and binary forms, with or without
5
+ * modification, are permitted provided that the following conditions are
6
+ * met:
7
+ *
8
+ *     * Redistributions of source code must retain the above copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ *     * Redistributions in binary form must reproduce the above
11
+ * copyright notice, this list of conditions and the following disclaimer
12
+ * in the documentation and/or other materials provided with the
13
+ * distribution.
14
+ *     * Neither the name of Google Inc. nor the names of its
15
+ * contributors may be used to endorse or promote products derived from
16
+ * this software without specific prior written permission.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ *
30
+ */
31
+
32
+// Package internal contains gRPC-internal code for testing, to avoid polluting
33
+// the godoc of the top-level grpc package.
34
+package internal
35
+
36
+// TestingCloseConns closes all existing transports but keeps
37
+// grpcServer.lis accepting new connections.
38
+//
39
+// The provided grpcServer must be of type *grpc.Server. It is untyped
40
+// for circular dependency reasons.
41
+var TestingCloseConns func(grpcServer interface{})
42
+
43
+// TestingUseHandlerImpl enables the http.Handler-based server implementation.
44
+// It must be called before Serve and requires TLS credentials.
45
+//
46
+// The provided grpcServer must be of type *grpc.Server. It is untyped
47
+// for circular dependency reasons.
48
+var TestingUseHandlerImpl func(grpcServer interface{})
0 49
new file mode 100644
... ...
@@ -0,0 +1,65 @@
0
+/*
1
+ *
2
+ * Copyright 2014, Google Inc.
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions are
7
+ * met:
8
+ *
9
+ *     * Redistributions of source code must retain the above copyright
10
+ * notice, this list of conditions and the following disclaimer.
11
+ *     * Redistributions in binary form must reproduce the above
12
+ * copyright notice, this list of conditions and the following disclaimer
13
+ * in the documentation and/or other materials provided with the
14
+ * distribution.
15
+ *     * Neither the name of Google Inc. nor the names of its
16
+ * contributors may be used to endorse or promote products derived from
17
+ * this software without specific prior written permission.
18
+ *
19
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ *
31
+ */
32
+
33
+// Package peer defines various peer information associated with RPCs and
34
+// corresponding utils.
35
+package peer
36
+
37
+import (
38
+	"net"
39
+
40
+	"golang.org/x/net/context"
41
+	"google.golang.org/grpc/credentials"
42
+)
43
+
44
+// Peer contains the information of the peer for an RPC.
45
+type Peer struct {
46
+	// Addr is the peer address.
47
+	Addr net.Addr
48
+	// AuthInfo is the authentication information of the transport.
49
+	// It is nil if there is no transport security being used.
50
+	AuthInfo credentials.AuthInfo
51
+}
52
+
53
+type peerKey struct{}
54
+
55
+// NewContext creates a new context with peer information attached.
56
+func NewContext(ctx context.Context, p *Peer) context.Context {
57
+	return context.WithValue(ctx, peerKey{}, p)
58
+}
59
+
60
+// FromContext returns the peer information in ctx if it exists.
61
+func FromContext(ctx context.Context) (p *Peer, ok bool) {
62
+	p, ok = ctx.Value(peerKey{}).(*Peer)
63
+	return
64
+}
... ...
@@ -172,7 +172,7 @@ func (p *unicastNamingPicker) processUpdates() error {
172 172
 			}
173 173
 			p.mu.Unlock()
174 174
 		default:
175
-			grpclog.Println("Unknown update.Op %d", update.Op)
175
+			grpclog.Println("Unknown update.Op ", update.Op)
176 176
 		}
177 177
 	}
178 178
 	return nil
... ...
@@ -34,13 +34,14 @@
34 34
 package grpc
35 35
 
36 36
 import (
37
+	"bytes"
38
+	"compress/gzip"
37 39
 	"encoding/binary"
38 40
 	"fmt"
39 41
 	"io"
42
+	"io/ioutil"
40 43
 	"math"
41
-	"math/rand"
42 44
 	"os"
43
-	"time"
44 45
 
45 46
 	"github.com/golang/protobuf/proto"
46 47
 	"golang.org/x/net/context"
... ...
@@ -75,6 +76,71 @@ func (protoCodec) String() string {
75 75
 	return "proto"
76 76
 }
77 77
 
78
+// Compressor defines the interface gRPC uses to compress a message.
79
+type Compressor interface {
80
+	// Do compresses p into w.
81
+	Do(w io.Writer, p []byte) error
82
+	// Type returns the compression algorithm the Compressor uses.
83
+	Type() string
84
+}
85
+
86
+// NewGZIPCompressor creates a Compressor based on GZIP.
87
+func NewGZIPCompressor() Compressor {
88
+	return &gzipCompressor{}
89
+}
90
+
91
+type gzipCompressor struct {
92
+}
93
+
94
+func (c *gzipCompressor) Do(w io.Writer, p []byte) error {
95
+	z := gzip.NewWriter(w)
96
+	if _, err := z.Write(p); err != nil {
97
+		return err
98
+	}
99
+	return z.Close()
100
+}
101
+
102
+func (c *gzipCompressor) Type() string {
103
+	return "gzip"
104
+}
105
+
106
+// Decompressor defines the interface gRPC uses to decompress a message.
107
+type Decompressor interface {
108
+	// Do reads the data from r and uncompress them.
109
+	Do(r io.Reader) ([]byte, error)
110
+	// Type returns the compression algorithm the Decompressor uses.
111
+	Type() string
112
+}
113
+
114
+type gzipDecompressor struct {
115
+}
116
+
117
+// NewGZIPDecompressor creates a Decompressor based on GZIP.
118
+func NewGZIPDecompressor() Decompressor {
119
+	return &gzipDecompressor{}
120
+}
121
+
122
+func (d *gzipDecompressor) Do(r io.Reader) ([]byte, error) {
123
+	z, err := gzip.NewReader(r)
124
+	if err != nil {
125
+		return nil, err
126
+	}
127
+	defer z.Close()
128
+	return ioutil.ReadAll(z)
129
+}
130
+
131
+func (d *gzipDecompressor) Type() string {
132
+	return "gzip"
133
+}
134
+
135
+// callInfo contains all related configuration and information about an RPC.
136
+type callInfo struct {
137
+	failFast  bool
138
+	headerMD  metadata.MD
139
+	trailerMD metadata.MD
140
+	traceInfo traceInfo // in trace.go
141
+}
142
+
78 143
 // CallOption configures a Call before it starts or extracts information from
79 144
 // a Call after it completes.
80 145
 type CallOption interface {
... ...
@@ -118,36 +184,49 @@ type payloadFormat uint8
118 118
 
119 119
 const (
120 120
 	compressionNone payloadFormat = iota // no compression
121
-	compressionFlate
122
-	// More formats
121
+	compressionMade
123 122
 )
124 123
 
125 124
 // parser reads complelete gRPC messages from the underlying reader.
126 125
 type parser struct {
127
-	s io.Reader
128
-}
126
+	// r is the underlying reader.
127
+	// See the comment on recvMsg for the permissible
128
+	// error types.
129
+	r io.Reader
129 130
 
130
-// recvMsg is to read a complete gRPC message from the stream. It is blocking if
131
-// the message has not been complete yet. It returns the message and its type,
132
-// EOF is returned with nil msg and 0 pf if the entire stream is done. Other
133
-// non-nil error is returned if something is wrong on reading.
134
-func (p *parser) recvMsg() (pf payloadFormat, msg []byte, err error) {
135 131
 	// The header of a gRPC message. Find more detail
136 132
 	// at http://www.grpc.io/docs/guides/wire.html.
137
-	var buf [5]byte
133
+	header [5]byte
134
+}
138 135
 
139
-	if _, err := io.ReadFull(p.s, buf[:]); err != nil {
136
+// recvMsg reads a complete gRPC message from the stream.
137
+//
138
+// It returns the message and its payload (compression/encoding)
139
+// format. The caller owns the returned msg memory.
140
+//
141
+// If there is an error, possible values are:
142
+//   * io.EOF, when no messages remain
143
+//   * io.ErrUnexpectedEOF
144
+//   * of type transport.ConnectionError
145
+//   * of type transport.StreamError
146
+// No other error values or types must be returned, which also means
147
+// that the underlying io.Reader must not return an incompatible
148
+// error.
149
+func (p *parser) recvMsg() (pf payloadFormat, msg []byte, err error) {
150
+	if _, err := io.ReadFull(p.r, p.header[:]); err != nil {
140 151
 		return 0, nil, err
141 152
 	}
142 153
 
143
-	pf = payloadFormat(buf[0])
144
-	length := binary.BigEndian.Uint32(buf[1:])
154
+	pf = payloadFormat(p.header[0])
155
+	length := binary.BigEndian.Uint32(p.header[1:])
145 156
 
146 157
 	if length == 0 {
147 158
 		return pf, nil, nil
148 159
 	}
160
+	// TODO(bradfitz,zhaoq): garbage. reuse buffer after proto decoding instead
161
+	// of making it for each message:
149 162
 	msg = make([]byte, int(length))
150
-	if _, err := io.ReadFull(p.s, msg); err != nil {
163
+	if _, err := io.ReadFull(p.r, msg); err != nil {
151 164
 		if err == io.EOF {
152 165
 			err = io.ErrUnexpectedEOF
153 166
 		}
... ...
@@ -158,7 +237,7 @@ func (p *parser) recvMsg() (pf payloadFormat, msg []byte, err error) {
158 158
 
159 159
 // encode serializes msg and prepends the message header. If msg is nil, it
160 160
 // generates the message header of 0 message length.
161
-func encode(c Codec, msg interface{}, pf payloadFormat) ([]byte, error) {
161
+func encode(c Codec, msg interface{}, cp Compressor, cbuf *bytes.Buffer) ([]byte, error) {
162 162
 	var b []byte
163 163
 	var length uint
164 164
 	if msg != nil {
... ...
@@ -168,6 +247,12 @@ func encode(c Codec, msg interface{}, pf payloadFormat) ([]byte, error) {
168 168
 		if err != nil {
169 169
 			return nil, err
170 170
 		}
171
+		if cp != nil {
172
+			if err := cp.Do(cbuf, b); err != nil {
173
+				return nil, err
174
+			}
175
+			b = cbuf.Bytes()
176
+		}
171 177
 		length = uint(len(b))
172 178
 	}
173 179
 	if length > math.MaxUint32 {
... ...
@@ -182,7 +267,11 @@ func encode(c Codec, msg interface{}, pf payloadFormat) ([]byte, error) {
182 182
 	var buf = make([]byte, payloadLen+sizeLen+len(b))
183 183
 
184 184
 	// Write payload format
185
-	buf[0] = byte(pf)
185
+	if cp == nil {
186
+		buf[0] = byte(compressionNone)
187
+	} else {
188
+		buf[0] = byte(compressionMade)
189
+	}
186 190
 	// Write length of b into buf
187 191
 	binary.BigEndian.PutUint32(buf[1:], uint32(length))
188 192
 	// Copy encoded msg to buf
... ...
@@ -191,22 +280,38 @@ func encode(c Codec, msg interface{}, pf payloadFormat) ([]byte, error) {
191 191
 	return buf, nil
192 192
 }
193 193
 
194
-func recv(p *parser, c Codec, m interface{}) error {
194
+func checkRecvPayload(pf payloadFormat, recvCompress string, dc Decompressor) error {
195
+	switch pf {
196
+	case compressionNone:
197
+	case compressionMade:
198
+		if recvCompress == "" {
199
+			return transport.StreamErrorf(codes.InvalidArgument, "grpc: invalid grpc-encoding %q with compression enabled", recvCompress)
200
+		}
201
+		if dc == nil || recvCompress != dc.Type() {
202
+			return transport.StreamErrorf(codes.InvalidArgument, "grpc: Decompressor is not installed for grpc-encoding %q", recvCompress)
203
+		}
204
+	default:
205
+		return transport.StreamErrorf(codes.InvalidArgument, "grpc: received unexpected payload format %d", pf)
206
+	}
207
+	return nil
208
+}
209
+
210
+func recv(p *parser, c Codec, s *transport.Stream, dc Decompressor, m interface{}) error {
195 211
 	pf, d, err := p.recvMsg()
196 212
 	if err != nil {
197 213
 		return err
198 214
 	}
199
-	switch pf {
200
-	case compressionNone:
201
-		if err := c.Unmarshal(d, m); err != nil {
202
-			if rErr, ok := err.(rpcError); ok {
203
-				return rErr
204
-			} else {
205
-				return Errorf(codes.Internal, "grpc: %v", err)
206
-			}
215
+	if err := checkRecvPayload(pf, s.RecvCompress(), dc); err != nil {
216
+		return err
217
+	}
218
+	if pf == compressionMade {
219
+		d, err = dc.Do(bytes.NewReader(d))
220
+		if err != nil {
221
+			return transport.StreamErrorf(codes.Internal, "grpc: failed to decompress the received message %v", err)
207 222
 		}
208
-	default:
209
-		return Errorf(codes.Internal, "gprc: compression is not supported yet.")
223
+	}
224
+	if err := c.Unmarshal(d, m); err != nil {
225
+		return transport.StreamErrorf(codes.Internal, "grpc: failed to unmarshal the received message %v", err)
210 226
 	}
211 227
 	return nil
212 228
 }
... ...
@@ -218,7 +323,7 @@ type rpcError struct {
218 218
 }
219 219
 
220 220
 func (e rpcError) Error() string {
221
-	return fmt.Sprintf("rpc error: code = %d desc = %q", e.code, e.desc)
221
+	return fmt.Sprintf("rpc error: code = %d desc = %s", e.code, e.desc)
222 222
 }
223 223
 
224 224
 // Code returns the error code for err if it was produced by the rpc system.
... ...
@@ -304,34 +409,10 @@ func convertCode(err error) codes.Code {
304 304
 	return codes.Unknown
305 305
 }
306 306
 
307
-const (
308
-	// how long to wait after the first failure before retrying
309
-	baseDelay = 1.0 * time.Second
310
-	// upper bound of backoff delay
311
-	maxDelay = 120 * time.Second
312
-	// backoff increases by this factor on each retry
313
-	backoffFactor = 1.6
314
-	// backoff is randomized downwards by this factor
315
-	backoffJitter = 0.2
316
-)
317
-
318
-func backoff(retries int) (t time.Duration) {
319
-	if retries == 0 {
320
-		return baseDelay
321
-	}
322
-	backoff, max := float64(baseDelay), float64(maxDelay)
323
-	for backoff < max && retries > 0 {
324
-		backoff *= backoffFactor
325
-		retries--
326
-	}
327
-	if backoff > max {
328
-		backoff = max
329
-	}
330
-	// Randomize backoff delays so that if a cluster of requests start at
331
-	// the same time, they won't operate in lockstep.
332
-	backoff *= 1 + backoffJitter*(rand.Float64()*2-1)
333
-	if backoff < 0 {
334
-		return 0
335
-	}
336
-	return time.Duration(backoff)
337
-}
307
+// SupportPackageIsVersion2 is referenced from generated protocol buffer files
308
+// to assert that that code is compatible with this version of the grpc package.
309
+//
310
+// This constant may be renamed in the future if a change in the generated code
311
+// requires a synchronised update of grpc-go and protoc-gen-go. This constant
312
+// should not be referenced from any other code.
313
+const SupportPackageIsVersion2 = true
... ...
@@ -34,10 +34,12 @@
34 34
 package grpc
35 35
 
36 36
 import (
37
+	"bytes"
37 38
 	"errors"
38 39
 	"fmt"
39 40
 	"io"
40 41
 	"net"
42
+	"net/http"
41 43
 	"reflect"
42 44
 	"runtime"
43 45
 	"strings"
... ...
@@ -45,15 +47,17 @@ import (
45 45
 	"time"
46 46
 
47 47
 	"golang.org/x/net/context"
48
+	"golang.org/x/net/http2"
48 49
 	"golang.org/x/net/trace"
49 50
 	"google.golang.org/grpc/codes"
50 51
 	"google.golang.org/grpc/credentials"
51 52
 	"google.golang.org/grpc/grpclog"
53
+	"google.golang.org/grpc/internal"
52 54
 	"google.golang.org/grpc/metadata"
53 55
 	"google.golang.org/grpc/transport"
54 56
 )
55 57
 
56
-type methodHandler func(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error)
58
+type methodHandler func(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor UnaryServerInterceptor) (interface{}, error)
57 59
 
58 60
 // MethodDesc represents an RPC service's method specification.
59 61
 type MethodDesc struct {
... ...
@@ -81,10 +85,11 @@ type service struct {
81 81
 
82 82
 // Server is a gRPC server to serve RPC requests.
83 83
 type Server struct {
84
-	opts   options
85
-	mu     sync.Mutex
84
+	opts options
85
+
86
+	mu     sync.Mutex // guards following
86 87
 	lis    map[net.Listener]bool
87
-	conns  map[transport.ServerTransport]bool
88
+	conns  map[io.Closer]bool
88 89
 	m      map[string]*service // service name -> service info
89 90
 	events trace.EventLog
90 91
 }
... ...
@@ -92,7 +97,12 @@ type Server struct {
92 92
 type options struct {
93 93
 	creds                credentials.Credentials
94 94
 	codec                Codec
95
+	cp                   Compressor
96
+	dc                   Decompressor
97
+	unaryInt             UnaryServerInterceptor
98
+	streamInt            StreamServerInterceptor
95 99
 	maxConcurrentStreams uint32
100
+	useHandlerImpl       bool // use http.Handler-based server
96 101
 }
97 102
 
98 103
 // A ServerOption sets options.
... ...
@@ -105,6 +115,18 @@ func CustomCodec(codec Codec) ServerOption {
105 105
 	}
106 106
 }
107 107
 
108
+func RPCCompressor(cp Compressor) ServerOption {
109
+	return func(o *options) {
110
+		o.cp = cp
111
+	}
112
+}
113
+
114
+func RPCDecompressor(dc Decompressor) ServerOption {
115
+	return func(o *options) {
116
+		o.dc = dc
117
+	}
118
+}
119
+
108 120
 // MaxConcurrentStreams returns a ServerOption that will apply a limit on the number
109 121
 // of concurrent streams to each ServerTransport.
110 122
 func MaxConcurrentStreams(n uint32) ServerOption {
... ...
@@ -120,6 +142,29 @@ func Creds(c credentials.Credentials) ServerOption {
120 120
 	}
121 121
 }
122 122
 
123
+// UnaryInterceptor returns a ServerOption that sets the UnaryServerInterceptor for the
124
+// server. Only one unary interceptor can be installed. The construction of multiple
125
+// interceptors (e.g., chaining) can be implemented at the caller.
126
+func UnaryInterceptor(i UnaryServerInterceptor) ServerOption {
127
+	return func(o *options) {
128
+		if o.unaryInt != nil {
129
+			panic("The unary server interceptor has been set.")
130
+		}
131
+		o.unaryInt = i
132
+	}
133
+}
134
+
135
+// StreamInterceptor returns a ServerOption that sets the StreamServerInterceptor for the
136
+// server. Only one stream interceptor can be installed.
137
+func StreamInterceptor(i StreamServerInterceptor) ServerOption {
138
+	return func(o *options) {
139
+		if o.streamInt != nil {
140
+			panic("The stream server interceptor has been set.")
141
+		}
142
+		o.streamInt = i
143
+	}
144
+}
145
+
123 146
 // NewServer creates a gRPC server which has no service registered and has not
124 147
 // started to accept requests yet.
125 148
 func NewServer(opt ...ServerOption) *Server {
... ...
@@ -134,7 +179,7 @@ func NewServer(opt ...ServerOption) *Server {
134 134
 	s := &Server{
135 135
 		lis:   make(map[net.Listener]bool),
136 136
 		opts:  opts,
137
-		conns: make(map[transport.ServerTransport]bool),
137
+		conns: make(map[io.Closer]bool),
138 138
 		m:     make(map[string]*service),
139 139
 	}
140 140
 	if EnableTracing {
... ...
@@ -201,9 +246,17 @@ var (
201 201
 	ErrServerStopped = errors.New("grpc: the server has been stopped")
202 202
 )
203 203
 
204
+func (s *Server) useTransportAuthenticator(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
205
+	creds, ok := s.opts.creds.(credentials.TransportAuthenticator)
206
+	if !ok {
207
+		return rawConn, nil, nil
208
+	}
209
+	return creds.ServerHandshake(rawConn)
210
+}
211
+
204 212
 // Serve accepts incoming connections on the listener lis, creating a new
205 213
 // ServerTransport and service goroutine for each. The service goroutines
206
-// read gRPC request and then call the registered handlers to reply to them.
214
+// read gRPC requests and then call the registered handlers to reply to them.
207 215
 // Service returns when lis.Accept fails.
208 216
 func (s *Server) Serve(lis net.Listener) error {
209 217
 	s.mu.Lock()
... ...
@@ -221,74 +274,167 @@ func (s *Server) Serve(lis net.Listener) error {
221 221
 		s.mu.Unlock()
222 222
 	}()
223 223
 	for {
224
-		c, err := lis.Accept()
224
+		rawConn, err := lis.Accept()
225 225
 		if err != nil {
226 226
 			s.mu.Lock()
227 227
 			s.printf("done serving; Accept = %v", err)
228 228
 			s.mu.Unlock()
229 229
 			return err
230 230
 		}
231
-		var authInfo credentials.AuthInfo
232
-		if creds, ok := s.opts.creds.(credentials.TransportAuthenticator); ok {
233
-			var conn net.Conn
234
-			conn, authInfo, err = creds.ServerHandshake(c)
235
-			if err != nil {
236
-				s.mu.Lock()
237
-				s.errorf("ServerHandshake(%q) failed: %v", c.RemoteAddr(), err)
238
-				s.mu.Unlock()
239
-				grpclog.Println("grpc: Server.Serve failed to complete security handshake.")
240
-				continue
241
-			}
242
-			c = conn
243
-		}
231
+		// Start a new goroutine to deal with rawConn
232
+		// so we don't stall this Accept loop goroutine.
233
+		go s.handleRawConn(rawConn)
234
+	}
235
+}
236
+
237
+// handleRawConn is run in its own goroutine and handles a just-accepted
238
+// connection that has not had any I/O performed on it yet.
239
+func (s *Server) handleRawConn(rawConn net.Conn) {
240
+	conn, authInfo, err := s.useTransportAuthenticator(rawConn)
241
+	if err != nil {
244 242
 		s.mu.Lock()
245
-		if s.conns == nil {
246
-			s.mu.Unlock()
247
-			c.Close()
248
-			return nil
249
-		}
250
-		st, err := transport.NewServerTransport("http2", c, s.opts.maxConcurrentStreams, authInfo)
251
-		if err != nil {
252
-			s.errorf("NewServerTransport(%q) failed: %v", c.RemoteAddr(), err)
253
-			s.mu.Unlock()
254
-			c.Close()
255
-			grpclog.Println("grpc: Server.Serve failed to create ServerTransport: ", err)
256
-			continue
257
-		}
258
-		s.conns[st] = true
243
+		s.errorf("ServerHandshake(%q) failed: %v", rawConn.RemoteAddr(), err)
259 244
 		s.mu.Unlock()
245
+		grpclog.Printf("grpc: Server.Serve failed to complete security handshake from %q: %v", rawConn.RemoteAddr(), err)
246
+		rawConn.Close()
247
+		return
248
+	}
249
+
250
+	s.mu.Lock()
251
+	if s.conns == nil {
252
+		s.mu.Unlock()
253
+		conn.Close()
254
+		return
255
+	}
256
+	s.mu.Unlock()
257
+
258
+	if s.opts.useHandlerImpl {
259
+		s.serveUsingHandler(conn)
260
+	} else {
261
+		s.serveNewHTTP2Transport(conn, authInfo)
262
+	}
263
+}
264
+
265
+// serveNewHTTP2Transport sets up a new http/2 transport (using the
266
+// gRPC http2 server transport in transport/http2_server.go) and
267
+// serves streams on it.
268
+// This is run in its own goroutine (it does network I/O in
269
+// transport.NewServerTransport).
270
+func (s *Server) serveNewHTTP2Transport(c net.Conn, authInfo credentials.AuthInfo) {
271
+	st, err := transport.NewServerTransport("http2", c, s.opts.maxConcurrentStreams, authInfo)
272
+	if err != nil {
273
+		s.mu.Lock()
274
+		s.errorf("NewServerTransport(%q) failed: %v", c.RemoteAddr(), err)
275
+		s.mu.Unlock()
276
+		c.Close()
277
+		grpclog.Println("grpc: Server.Serve failed to create ServerTransport: ", err)
278
+		return
279
+	}
280
+	if !s.addConn(st) {
281
+		st.Close()
282
+		return
283
+	}
284
+	s.serveStreams(st)
285
+}
260 286
 
287
+func (s *Server) serveStreams(st transport.ServerTransport) {
288
+	defer s.removeConn(st)
289
+	defer st.Close()
290
+	var wg sync.WaitGroup
291
+	st.HandleStreams(func(stream *transport.Stream) {
292
+		wg.Add(1)
261 293
 		go func() {
262
-			var wg sync.WaitGroup
263
-			st.HandleStreams(func(stream *transport.Stream) {
264
-				var trInfo *traceInfo
265
-				if EnableTracing {
266
-					trInfo = &traceInfo{
267
-						tr: trace.New("grpc.Recv."+methodFamily(stream.Method()), stream.Method()),
268
-					}
269
-					trInfo.firstLine.client = false
270
-					trInfo.firstLine.remoteAddr = st.RemoteAddr()
271
-					stream.TraceContext(trInfo.tr)
272
-					if dl, ok := stream.Context().Deadline(); ok {
273
-						trInfo.firstLine.deadline = dl.Sub(time.Now())
274
-					}
275
-				}
276
-				wg.Add(1)
277
-				go func() {
278
-					s.handleStream(st, stream, trInfo)
279
-					wg.Done()
280
-				}()
281
-			})
282
-			wg.Wait()
283
-			s.mu.Lock()
284
-			delete(s.conns, st)
285
-			s.mu.Unlock()
294
+			defer wg.Done()
295
+			s.handleStream(st, stream, s.traceInfo(st, stream))
286 296
 		}()
297
+	})
298
+	wg.Wait()
299
+}
300
+
301
+var _ http.Handler = (*Server)(nil)
302
+
303
+// serveUsingHandler is called from handleRawConn when s is configured
304
+// to handle requests via the http.Handler interface. It sets up a
305
+// net/http.Server to handle the just-accepted conn. The http.Server
306
+// is configured to route all incoming requests (all HTTP/2 streams)
307
+// to ServeHTTP, which creates a new ServerTransport for each stream.
308
+// serveUsingHandler blocks until conn closes.
309
+//
310
+// This codepath is only used when Server.TestingUseHandlerImpl has
311
+// been configured. This lets the end2end tests exercise the ServeHTTP
312
+// method as one of the environment types.
313
+//
314
+// conn is the *tls.Conn that's already been authenticated.
315
+func (s *Server) serveUsingHandler(conn net.Conn) {
316
+	if !s.addConn(conn) {
317
+		conn.Close()
318
+		return
319
+	}
320
+	defer s.removeConn(conn)
321
+	h2s := &http2.Server{
322
+		MaxConcurrentStreams: s.opts.maxConcurrentStreams,
323
+	}
324
+	h2s.ServeConn(conn, &http2.ServeConnOpts{
325
+		Handler: s,
326
+	})
327
+}
328
+
329
+func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
330
+	st, err := transport.NewServerHandlerTransport(w, r)
331
+	if err != nil {
332
+		http.Error(w, err.Error(), http.StatusInternalServerError)
333
+		return
334
+	}
335
+	if !s.addConn(st) {
336
+		st.Close()
337
+		return
338
+	}
339
+	defer s.removeConn(st)
340
+	s.serveStreams(st)
341
+}
342
+
343
+// traceInfo returns a traceInfo and associates it with stream, if tracing is enabled.
344
+// If tracing is not enabled, it returns nil.
345
+func (s *Server) traceInfo(st transport.ServerTransport, stream *transport.Stream) (trInfo *traceInfo) {
346
+	if !EnableTracing {
347
+		return nil
348
+	}
349
+	trInfo = &traceInfo{
350
+		tr: trace.New("grpc.Recv."+methodFamily(stream.Method()), stream.Method()),
351
+	}
352
+	trInfo.firstLine.client = false
353
+	trInfo.firstLine.remoteAddr = st.RemoteAddr()
354
+	stream.TraceContext(trInfo.tr)
355
+	if dl, ok := stream.Context().Deadline(); ok {
356
+		trInfo.firstLine.deadline = dl.Sub(time.Now())
357
+	}
358
+	return trInfo
359
+}
360
+
361
+func (s *Server) addConn(c io.Closer) bool {
362
+	s.mu.Lock()
363
+	defer s.mu.Unlock()
364
+	if s.conns == nil {
365
+		return false
366
+	}
367
+	s.conns[c] = true
368
+	return true
369
+}
370
+
371
+func (s *Server) removeConn(c io.Closer) {
372
+	s.mu.Lock()
373
+	defer s.mu.Unlock()
374
+	if s.conns != nil {
375
+		delete(s.conns, c)
287 376
 	}
288 377
 }
289 378
 
290
-func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Stream, msg interface{}, pf payloadFormat, opts *transport.Options) error {
291
-	p, err := encode(s.opts.codec, msg, pf)
379
+func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Stream, msg interface{}, cp Compressor, opts *transport.Options) error {
380
+	var cbuf *bytes.Buffer
381
+	if cp != nil {
382
+		cbuf = new(bytes.Buffer)
383
+	}
384
+	p, err := encode(s.opts.codec, msg, cp, cbuf)
292 385
 	if err != nil {
293 386
 		// This typically indicates a fatal issue (e.g., memory
294 387
 		// corruption or hardware faults) the application program
... ...
@@ -314,97 +460,130 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
314 314
 			}
315 315
 		}()
316 316
 	}
317
-	p := &parser{s: stream}
317
+	p := &parser{r: stream}
318 318
 	for {
319 319
 		pf, req, err := p.recvMsg()
320 320
 		if err == io.EOF {
321 321
 			// The entire stream is done (for unary RPC only).
322 322
 			return err
323 323
 		}
324
+		if err == io.ErrUnexpectedEOF {
325
+			err = transport.StreamError{Code: codes.Internal, Desc: "io.ErrUnexpectedEOF"}
326
+		}
324 327
 		if err != nil {
325 328
 			switch err := err.(type) {
326 329
 			case transport.ConnectionError:
327 330
 				// Nothing to do here.
328 331
 			case transport.StreamError:
329 332
 				if err := t.WriteStatus(stream, err.Code, err.Desc); err != nil {
330
-					grpclog.Printf("grpc: Server.processUnaryRPC failed to write status: %v", err)
333
+					grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", err)
331 334
 				}
332 335
 			default:
333 336
 				panic(fmt.Sprintf("grpc: Unexpected error (%T) from recvMsg: %v", err, err))
334 337
 			}
335 338
 			return err
336 339
 		}
337
-		switch pf {
338
-		case compressionNone:
339
-			statusCode := codes.OK
340
-			statusDesc := ""
341
-			df := func(v interface{}) error {
342
-				if err := s.opts.codec.Unmarshal(req, v); err != nil {
343
-					return err
344
-				}
345
-				if trInfo != nil {
346
-					trInfo.tr.LazyLog(&payload{sent: false, msg: v}, true)
347
-				}
348
-				return nil
349
-			}
350
-			reply, appErr := md.Handler(srv.server, stream.Context(), df)
351
-			if appErr != nil {
352
-				if err, ok := appErr.(rpcError); ok {
353
-					statusCode = err.code
354
-					statusDesc = err.desc
355
-				} else {
356
-					statusCode = convertCode(appErr)
357
-					statusDesc = appErr.Error()
340
+
341
+		if err := checkRecvPayload(pf, stream.RecvCompress(), s.opts.dc); err != nil {
342
+			switch err := err.(type) {
343
+			case transport.StreamError:
344
+				if err := t.WriteStatus(stream, err.Code, err.Desc); err != nil {
345
+					grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", err)
358 346
 				}
359
-				if trInfo != nil && statusCode != codes.OK {
360
-					trInfo.tr.LazyLog(stringer(statusDesc), true)
361
-					trInfo.tr.SetError()
347
+			default:
348
+				if err := t.WriteStatus(stream, codes.Internal, err.Error()); err != nil {
349
+					grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", err)
362 350
 				}
363 351
 
364
-				if err := t.WriteStatus(stream, statusCode, statusDesc); err != nil {
365
-					grpclog.Printf("grpc: Server.processUnaryRPC failed to write status: %v", err)
352
+			}
353
+			return err
354
+		}
355
+		statusCode := codes.OK
356
+		statusDesc := ""
357
+		df := func(v interface{}) error {
358
+			if pf == compressionMade {
359
+				var err error
360
+				req, err = s.opts.dc.Do(bytes.NewReader(req))
361
+				if err != nil {
362
+					if err := t.WriteStatus(stream, codes.Internal, err.Error()); err != nil {
363
+						grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", err)
364
+					}
366 365
 					return err
367 366
 				}
368
-				return nil
367
+			}
368
+			if err := s.opts.codec.Unmarshal(req, v); err != nil {
369
+				return err
369 370
 			}
370 371
 			if trInfo != nil {
371
-				trInfo.tr.LazyLog(stringer("OK"), false)
372
+				trInfo.tr.LazyLog(&payload{sent: false, msg: v}, true)
372 373
 			}
373
-			opts := &transport.Options{
374
-				Last:  true,
375
-				Delay: false,
374
+			return nil
375
+		}
376
+		reply, appErr := md.Handler(srv.server, stream.Context(), df, s.opts.unaryInt)
377
+		if appErr != nil {
378
+			if err, ok := appErr.(rpcError); ok {
379
+				statusCode = err.code
380
+				statusDesc = err.desc
381
+			} else {
382
+				statusCode = convertCode(appErr)
383
+				statusDesc = appErr.Error()
376 384
 			}
377
-			if err := s.sendResponse(t, stream, reply, compressionNone, opts); err != nil {
378
-				switch err := err.(type) {
379
-				case transport.ConnectionError:
380
-					// Nothing to do here.
381
-				case transport.StreamError:
382
-					statusCode = err.Code
383
-					statusDesc = err.Desc
384
-				default:
385
-					statusCode = codes.Unknown
386
-					statusDesc = err.Error()
387
-				}
385
+			if trInfo != nil && statusCode != codes.OK {
386
+				trInfo.tr.LazyLog(stringer(statusDesc), true)
387
+				trInfo.tr.SetError()
388
+			}
389
+			if err := t.WriteStatus(stream, statusCode, statusDesc); err != nil {
390
+				grpclog.Printf("grpc: Server.processUnaryRPC failed to write status: %v", err)
388 391
 				return err
389 392
 			}
390
-			if trInfo != nil {
391
-				trInfo.tr.LazyLog(&payload{sent: true, msg: reply}, true)
393
+			return nil
394
+		}
395
+		if trInfo != nil {
396
+			trInfo.tr.LazyLog(stringer("OK"), false)
397
+		}
398
+		opts := &transport.Options{
399
+			Last:  true,
400
+			Delay: false,
401
+		}
402
+		if s.opts.cp != nil {
403
+			stream.SetSendCompress(s.opts.cp.Type())
404
+		}
405
+		if err := s.sendResponse(t, stream, reply, s.opts.cp, opts); err != nil {
406
+			switch err := err.(type) {
407
+			case transport.ConnectionError:
408
+				// Nothing to do here.
409
+			case transport.StreamError:
410
+				statusCode = err.Code
411
+				statusDesc = err.Desc
412
+			default:
413
+				statusCode = codes.Unknown
414
+				statusDesc = err.Error()
392 415
 			}
393
-			return t.WriteStatus(stream, statusCode, statusDesc)
394
-		default:
395
-			panic(fmt.Sprintf("payload format to be supported: %d", pf))
416
+			return err
396 417
 		}
418
+		if trInfo != nil {
419
+			trInfo.tr.LazyLog(&payload{sent: true, msg: reply}, true)
420
+		}
421
+		return t.WriteStatus(stream, statusCode, statusDesc)
397 422
 	}
398 423
 }
399 424
 
400 425
 func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transport.Stream, srv *service, sd *StreamDesc, trInfo *traceInfo) (err error) {
426
+	if s.opts.cp != nil {
427
+		stream.SetSendCompress(s.opts.cp.Type())
428
+	}
401 429
 	ss := &serverStream{
402 430
 		t:      t,
403 431
 		s:      stream,
404
-		p:      &parser{s: stream},
432
+		p:      &parser{r: stream},
405 433
 		codec:  s.opts.codec,
434
+		cp:     s.opts.cp,
435
+		dc:     s.opts.dc,
406 436
 		trInfo: trInfo,
407 437
 	}
438
+	if ss.cp != nil {
439
+		ss.cbuf = new(bytes.Buffer)
440
+	}
408 441
 	if trInfo != nil {
409 442
 		trInfo.tr.LazyLog(&trInfo.firstLine, false)
410 443
 		defer func() {
... ...
@@ -418,10 +597,24 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp
418 418
 			ss.mu.Unlock()
419 419
 		}()
420 420
 	}
421
-	if appErr := sd.Handler(srv.server, ss); appErr != nil {
421
+	var appErr error
422
+	if s.opts.streamInt == nil {
423
+		appErr = sd.Handler(srv.server, ss)
424
+	} else {
425
+		info := &StreamServerInfo{
426
+			FullMethod:     stream.Method(),
427
+			IsClientStream: sd.ClientStreams,
428
+			IsServerStream: sd.ServerStreams,
429
+		}
430
+		appErr = s.opts.streamInt(srv.server, ss, info, sd.Handler)
431
+	}
432
+	if appErr != nil {
422 433
 		if err, ok := appErr.(rpcError); ok {
423 434
 			ss.statusCode = err.code
424 435
 			ss.statusDesc = err.desc
436
+		} else if err, ok := appErr.(transport.StreamError); ok {
437
+			ss.statusCode = err.Code
438
+			ss.statusDesc = err.Desc
425 439
 		} else {
426 440
 			ss.statusCode = convertCode(appErr)
427 441
 			ss.statusDesc = appErr.Error()
... ...
@@ -509,8 +702,11 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str
509 509
 	}
510 510
 }
511 511
 
512
-// Stop stops the gRPC server. Once Stop returns, the server stops accepting
513
-// connection requests and closes all the connected connections.
512
+// Stop stops the gRPC server. It immediately closes all open
513
+// connections and listeners.
514
+// It cancels all active RPCs on the server side and the corresponding
515
+// pending RPCs on the client side will get notified by connection
516
+// errors.
514 517
 func (s *Server) Stop() {
515 518
 	s.mu.Lock()
516 519
 	listeners := s.lis
... ...
@@ -518,12 +714,14 @@ func (s *Server) Stop() {
518 518
 	cs := s.conns
519 519
 	s.conns = nil
520 520
 	s.mu.Unlock()
521
+
521 522
 	for lis := range listeners {
522 523
 		lis.Close()
523 524
 	}
524 525
 	for c := range cs {
525 526
 		c.Close()
526 527
 	}
528
+
527 529
 	s.mu.Lock()
528 530
 	if s.events != nil {
529 531
 		s.events.Finish()
... ...
@@ -532,14 +730,23 @@ func (s *Server) Stop() {
532 532
 	s.mu.Unlock()
533 533
 }
534 534
 
535
-// TestingCloseConns closes all exiting transports but keeps s.lis accepting new
536
-// connections. This is for test only now.
537
-func (s *Server) TestingCloseConns() {
535
+func init() {
536
+	internal.TestingCloseConns = func(arg interface{}) {
537
+		arg.(*Server).testingCloseConns()
538
+	}
539
+	internal.TestingUseHandlerImpl = func(arg interface{}) {
540
+		arg.(*Server).opts.useHandlerImpl = true
541
+	}
542
+}
543
+
544
+// testingCloseConns closes all existing transports but keeps s.lis
545
+// accepting new connections.
546
+func (s *Server) testingCloseConns() {
538 547
 	s.mu.Lock()
539 548
 	for c := range s.conns {
540 549
 		c.Close()
550
+		delete(s.conns, c)
541 551
 	}
542
-	s.conns = make(map[transport.ServerTransport]bool)
543 552
 	s.mu.Unlock()
544 553
 }
545 554
 
... ...
@@ -34,6 +34,7 @@
34 34
 package grpc
35 35
 
36 36
 import (
37
+	"bytes"
37 38
 	"errors"
38 39
 	"io"
39 40
 	"sync"
... ...
@@ -46,12 +47,14 @@ import (
46 46
 	"google.golang.org/grpc/transport"
47 47
 )
48 48
 
49
-type streamHandler func(srv interface{}, stream ServerStream) error
49
+// StreamHandler defines the handler called by gRPC server to complete the
50
+// execution of a streaming RPC.
51
+type StreamHandler func(srv interface{}, stream ServerStream) error
50 52
 
51 53
 // StreamDesc represents a streaming RPC service's method specification.
52 54
 type StreamDesc struct {
53 55
 	StreamName string
54
-	Handler    streamHandler
56
+	Handler    StreamHandler
55 57
 
56 58
 	// At least one of these is true.
57 59
 	ServerStreams bool
... ...
@@ -66,18 +69,19 @@ type Stream interface {
66 66
 	// breaks.
67 67
 	// On error, it aborts the stream and returns an RPC status on client
68 68
 	// side. On server side, it simply returns the error to the caller.
69
-	// SendMsg is called by generated code.
69
+	// SendMsg is called by generated code. Also Users can call SendMsg
70
+	// directly when it is really needed in their use cases.
70 71
 	SendMsg(m interface{}) error
71 72
 	// RecvMsg blocks until it receives a message or the stream is
72 73
 	// done. On client side, it returns io.EOF when the stream is done. On
73
-	// any other error, it aborts the streama nd returns an RPC status. On
74
+	// any other error, it aborts the stream and returns an RPC status. On
74 75
 	// server side, it simply returns the error to the caller.
75 76
 	RecvMsg(m interface{}) error
76 77
 }
77 78
 
78 79
 // ClientStream defines the interface a client stream has to satify.
79 80
 type ClientStream interface {
80
-	// Header returns the header metedata received from the server if there
81
+	// Header returns the header metadata received from the server if there
81 82
 	// is any. It blocks if the metadata is not ready to read.
82 83
 	Header() (metadata.MD, error)
83 84
 	// Trailer returns the trailer metadata from the server. It must be called
... ...
@@ -108,12 +112,22 @@ func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth
108 108
 	callHdr := &transport.CallHdr{
109 109
 		Host:   cc.authority,
110 110
 		Method: method,
111
+		Flush:  desc.ServerStreams && desc.ClientStreams,
112
+	}
113
+	if cc.dopts.cp != nil {
114
+		callHdr.SendCompress = cc.dopts.cp.Type()
111 115
 	}
112 116
 	cs := &clientStream{
113 117
 		desc:    desc,
114 118
 		codec:   cc.dopts.codec,
119
+		cp:      cc.dopts.cp,
120
+		dc:      cc.dopts.dc,
115 121
 		tracing: EnableTracing,
116 122
 	}
123
+	if cc.dopts.cp != nil {
124
+		callHdr.SendCompress = cc.dopts.cp.Type()
125
+		cs.cbuf = new(bytes.Buffer)
126
+	}
117 127
 	if cs.tracing {
118 128
 		cs.trInfo.tr = trace.New("grpc.Sent."+methodFamily(method), method)
119 129
 		cs.trInfo.firstLine.client = true
... ...
@@ -125,16 +139,23 @@ func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth
125 125
 	}
126 126
 	s, err := t.NewStream(ctx, callHdr)
127 127
 	if err != nil {
128
+		cs.finish(err)
128 129
 		return nil, toRPCErr(err)
129 130
 	}
130 131
 	cs.t = t
131 132
 	cs.s = s
132
-	cs.p = &parser{s: s}
133
+	cs.p = &parser{r: s}
133 134
 	// Listen on ctx.Done() to detect cancellation when there is no pending
134 135
 	// I/O operations on this stream.
135 136
 	go func() {
136
-		<-s.Context().Done()
137
-		cs.closeTransportStream(transport.ContextErr(s.Context().Err()))
137
+		select {
138
+		case <-t.Error():
139
+			// Incur transport error, simply exit.
140
+		case <-s.Context().Done():
141
+			err := s.Context().Err()
142
+			cs.finish(err)
143
+			cs.closeTransportStream(transport.ContextErr(err))
144
+		}
138 145
 	}()
139 146
 	return cs, nil
140 147
 }
... ...
@@ -146,6 +167,9 @@ type clientStream struct {
146 146
 	p     *parser
147 147
 	desc  *StreamDesc
148 148
 	codec Codec
149
+	cp    Compressor
150
+	cbuf  *bytes.Buffer
151
+	dc    Decompressor
149 152
 
150 153
 	tracing bool // set to EnableTracing when the clientStream is created.
151 154
 
... ...
@@ -183,6 +207,9 @@ func (cs *clientStream) SendMsg(m interface{}) (err error) {
183 183
 		cs.mu.Unlock()
184 184
 	}
185 185
 	defer func() {
186
+		if err != nil {
187
+			cs.finish(err)
188
+		}
186 189
 		if err == nil || err == io.EOF {
187 190
 			return
188 191
 		}
... ...
@@ -191,7 +218,12 @@ func (cs *clientStream) SendMsg(m interface{}) (err error) {
191 191
 		}
192 192
 		err = toRPCErr(err)
193 193
 	}()
194
-	out, err := encode(cs.codec, m, compressionNone)
194
+	out, err := encode(cs.codec, m, cs.cp, cs.cbuf)
195
+	defer func() {
196
+		if cs.cbuf != nil {
197
+			cs.cbuf.Reset()
198
+		}
199
+	}()
195 200
 	if err != nil {
196 201
 		return transport.StreamErrorf(codes.Internal, "grpc: %v", err)
197 202
 	}
... ...
@@ -199,7 +231,7 @@ func (cs *clientStream) SendMsg(m interface{}) (err error) {
199 199
 }
200 200
 
201 201
 func (cs *clientStream) RecvMsg(m interface{}) (err error) {
202
-	err = recv(cs.p, cs.codec, m)
202
+	err = recv(cs.p, cs.codec, cs.s, cs.dc, m)
203 203
 	defer func() {
204 204
 		// err != nil indicates the termination of the stream.
205 205
 		if err != nil {
... ...
@@ -218,16 +250,17 @@ func (cs *clientStream) RecvMsg(m interface{}) (err error) {
218 218
 			return
219 219
 		}
220 220
 		// Special handling for client streaming rpc.
221
-		err = recv(cs.p, cs.codec, m)
221
+		err = recv(cs.p, cs.codec, cs.s, cs.dc, m)
222 222
 		cs.closeTransportStream(err)
223 223
 		if err == nil {
224 224
 			return toRPCErr(errors.New("grpc: client streaming protocol violation: get <nil>, want <EOF>"))
225 225
 		}
226 226
 		if err == io.EOF {
227 227
 			if cs.s.StatusCode() == codes.OK {
228
+				cs.finish(err)
228 229
 				return nil
229 230
 			}
230
-			return Errorf(cs.s.StatusCode(), cs.s.StatusDesc())
231
+			return Errorf(cs.s.StatusCode(), "%s", cs.s.StatusDesc())
231 232
 		}
232 233
 		return toRPCErr(err)
233 234
 	}
... ...
@@ -239,13 +272,18 @@ func (cs *clientStream) RecvMsg(m interface{}) (err error) {
239 239
 			// Returns io.EOF to indicate the end of the stream.
240 240
 			return
241 241
 		}
242
-		return Errorf(cs.s.StatusCode(), cs.s.StatusDesc())
242
+		return Errorf(cs.s.StatusCode(), "%s", cs.s.StatusDesc())
243 243
 	}
244 244
 	return toRPCErr(err)
245 245
 }
246 246
 
247 247
 func (cs *clientStream) CloseSend() (err error) {
248 248
 	err = cs.t.Write(cs.s, nil, &transport.Options{Last: true})
249
+	defer func() {
250
+		if err != nil {
251
+			cs.finish(err)
252
+		}
253
+	}()
249 254
 	if err == nil || err == io.EOF {
250 255
 		return
251 256
 	}
... ...
@@ -303,6 +341,9 @@ type serverStream struct {
303 303
 	s          *transport.Stream
304 304
 	p          *parser
305 305
 	codec      Codec
306
+	cp         Compressor
307
+	dc         Decompressor
308
+	cbuf       *bytes.Buffer
306 309
 	statusCode codes.Code
307 310
 	statusDesc string
308 311
 	trInfo     *traceInfo
... ...
@@ -341,7 +382,12 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) {
341 341
 			ss.mu.Unlock()
342 342
 		}
343 343
 	}()
344
-	out, err := encode(ss.codec, m, compressionNone)
344
+	out, err := encode(ss.codec, m, ss.cp, ss.cbuf)
345
+	defer func() {
346
+		if ss.cbuf != nil {
347
+			ss.cbuf.Reset()
348
+		}
349
+	}()
345 350
 	if err != nil {
346 351
 		err = transport.StreamErrorf(codes.Internal, "grpc: %v", err)
347 352
 		return err
... ...
@@ -364,5 +410,5 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) {
364 364
 			ss.mu.Unlock()
365 365
 		}
366 366
 	}()
367
-	return recv(ss.p, ss.codec, m)
367
+	return recv(ss.p, ss.codec, ss.s, ss.dc, m)
368 368
 }
... ...
@@ -56,43 +56,33 @@ type windowUpdate struct {
56 56
 	increment uint32
57 57
 }
58 58
 
59
-func (windowUpdate) isItem() bool {
60
-	return true
61
-}
59
+func (*windowUpdate) item() {}
62 60
 
63 61
 type settings struct {
64 62
 	ack bool
65 63
 	ss  []http2.Setting
66 64
 }
67 65
 
68
-func (settings) isItem() bool {
69
-	return true
70
-}
66
+func (*settings) item() {}
71 67
 
72 68
 type resetStream struct {
73 69
 	streamID uint32
74 70
 	code     http2.ErrCode
75 71
 }
76 72
 
77
-func (resetStream) isItem() bool {
78
-	return true
79
-}
73
+func (*resetStream) item() {}
80 74
 
81 75
 type flushIO struct {
82 76
 }
83 77
 
84
-func (flushIO) isItem() bool {
85
-	return true
86
-}
78
+func (*flushIO) item() {}
87 79
 
88 80
 type ping struct {
89 81
 	ack  bool
90 82
 	data [8]byte
91 83
 }
92 84
 
93
-func (ping) isItem() bool {
94
-	return true
95
-}
85
+func (*ping) item() {}
96 86
 
97 87
 // quotaPool is a pool which accumulates the quota and sends it to acquire()
98 88
 // when it is available.
... ...
@@ -172,10 +162,6 @@ func (qb *quotaPool) acquire() <-chan int {
172 172
 type inFlow struct {
173 173
 	// The inbound flow control limit for pending data.
174 174
 	limit uint32
175
-	// conn points to the shared connection-level inFlow that is shared
176
-	// by all streams on that conn. It is nil for the inFlow on the conn
177
-	// directly.
178
-	conn *inFlow
179 175
 
180 176
 	mu sync.Mutex
181 177
 	// pendingData is the overall data which have been received but not been
... ...
@@ -186,75 +172,39 @@ type inFlow struct {
186 186
 	pendingUpdate uint32
187 187
 }
188 188
 
189
-// onData is invoked when some data frame is received. It increments not only its
190
-// own pendingData but also that of the associated connection-level flow.
189
+// onData is invoked when some data frame is received. It updates pendingData.
191 190
 func (f *inFlow) onData(n uint32) error {
192
-	if n == 0 {
193
-		return nil
194
-	}
195 191
 	f.mu.Lock()
196 192
 	defer f.mu.Unlock()
197
-	if f.pendingData+f.pendingUpdate+n > f.limit {
198
-		return fmt.Errorf("recieved %d-bytes data exceeding the limit %d bytes", f.pendingData+f.pendingUpdate+n, f.limit)
199
-	}
200
-	if f.conn != nil {
201
-		if err := f.conn.onData(n); err != nil {
202
-			return ConnectionErrorf("%v", err)
203
-		}
204
-	}
205 193
 	f.pendingData += n
206
-	return nil
207
-}
208
-
209
-// connOnRead updates the connection level states when the application consumes data.
210
-func (f *inFlow) connOnRead(n uint32) uint32 {
211
-	if n == 0 || f.conn != nil {
212
-		return 0
213
-	}
214
-	f.mu.Lock()
215
-	defer f.mu.Unlock()
216
-	f.pendingData -= n
217
-	f.pendingUpdate += n
218
-	if f.pendingUpdate >= f.limit/4 {
219
-		ret := f.pendingUpdate
220
-		f.pendingUpdate = 0
221
-		return ret
194
+	if f.pendingData+f.pendingUpdate > f.limit {
195
+		return fmt.Errorf("received %d-bytes data exceeding the limit %d bytes", f.pendingData+f.pendingUpdate, f.limit)
222 196
 	}
223
-	return 0
197
+	return nil
224 198
 }
225 199
 
226
-// onRead is invoked when the application reads the data. It returns the window updates
227
-// for both stream and connection level.
228
-func (f *inFlow) onRead(n uint32) (swu, cwu uint32) {
229
-	if n == 0 {
230
-		return
231
-	}
200
+// onRead is invoked when the application reads the data. It returns the window size
201
+// to be sent to the peer.
202
+func (f *inFlow) onRead(n uint32) uint32 {
232 203
 	f.mu.Lock()
233 204
 	defer f.mu.Unlock()
234 205
 	if f.pendingData == 0 {
235
-		// pendingData has been adjusted by restoreConn.
236
-		return
206
+		return 0
237 207
 	}
238 208
 	f.pendingData -= n
239 209
 	f.pendingUpdate += n
240 210
 	if f.pendingUpdate >= f.limit/4 {
241
-		swu = f.pendingUpdate
211
+		wu := f.pendingUpdate
242 212
 		f.pendingUpdate = 0
213
+		return wu
243 214
 	}
244
-	cwu = f.conn.connOnRead(n)
245
-	return
215
+	return 0
246 216
 }
247 217
 
248
-// restoreConn is invoked when a stream is terminated. It removes its stake in
249
-// the connection-level flow and resets its own state.
250
-func (f *inFlow) restoreConn() uint32 {
251
-	if f.conn == nil {
252
-		return 0
253
-	}
218
+func (f *inFlow) resetPendingData() uint32 {
254 219
 	f.mu.Lock()
255 220
 	defer f.mu.Unlock()
256 221
 	n := f.pendingData
257 222
 	f.pendingData = 0
258
-	f.pendingUpdate = 0
259
-	return f.conn.connOnRead(n)
223
+	return n
260 224
 }
261 225
new file mode 100644
... ...
@@ -0,0 +1,383 @@
0
+/*
1
+ * Copyright 2016, Google Inc.
2
+ * All rights reserved.
3
+ *
4
+ * Redistribution and use in source and binary forms, with or without
5
+ * modification, are permitted provided that the following conditions are
6
+ * met:
7
+ *
8
+ *     * Redistributions of source code must retain the above copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ *     * Redistributions in binary form must reproduce the above
11
+ * copyright notice, this list of conditions and the following disclaimer
12
+ * in the documentation and/or other materials provided with the
13
+ * distribution.
14
+ *     * Neither the name of Google Inc. nor the names of its
15
+ * contributors may be used to endorse or promote products derived from
16
+ * this software without specific prior written permission.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ *
30
+ */
31
+
32
+// This file is the implementation of a gRPC server using HTTP/2 which
33
+// uses the standard Go http2 Server implementation (via the
34
+// http.Handler interface), rather than speaking low-level HTTP/2
35
+// frames itself. It is the implementation of *grpc.Server.ServeHTTP.
36
+
37
+package transport
38
+
39
+import (
40
+	"errors"
41
+	"fmt"
42
+	"io"
43
+	"net"
44
+	"net/http"
45
+	"strings"
46
+	"sync"
47
+	"time"
48
+
49
+	"golang.org/x/net/context"
50
+	"golang.org/x/net/http2"
51
+	"google.golang.org/grpc/codes"
52
+	"google.golang.org/grpc/credentials"
53
+	"google.golang.org/grpc/metadata"
54
+	"google.golang.org/grpc/peer"
55
+)
56
+
57
+// NewServerHandlerTransport returns a ServerTransport handling gRPC
58
+// from inside an http.Handler. It requires that the http Server
59
+// supports HTTP/2.
60
+func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request) (ServerTransport, error) {
61
+	if r.ProtoMajor != 2 {
62
+		return nil, errors.New("gRPC requires HTTP/2")
63
+	}
64
+	if r.Method != "POST" {
65
+		return nil, errors.New("invalid gRPC request method")
66
+	}
67
+	if !strings.Contains(r.Header.Get("Content-Type"), "application/grpc") {
68
+		return nil, errors.New("invalid gRPC request content-type")
69
+	}
70
+	if _, ok := w.(http.Flusher); !ok {
71
+		return nil, errors.New("gRPC requires a ResponseWriter supporting http.Flusher")
72
+	}
73
+	if _, ok := w.(http.CloseNotifier); !ok {
74
+		return nil, errors.New("gRPC requires a ResponseWriter supporting http.CloseNotifier")
75
+	}
76
+
77
+	st := &serverHandlerTransport{
78
+		rw:       w,
79
+		req:      r,
80
+		closedCh: make(chan struct{}),
81
+		writes:   make(chan func()),
82
+	}
83
+
84
+	if v := r.Header.Get("grpc-timeout"); v != "" {
85
+		to, err := timeoutDecode(v)
86
+		if err != nil {
87
+			return nil, StreamErrorf(codes.Internal, "malformed time-out: %v", err)
88
+		}
89
+		st.timeoutSet = true
90
+		st.timeout = to
91
+	}
92
+
93
+	var metakv []string
94
+	for k, vv := range r.Header {
95
+		k = strings.ToLower(k)
96
+		if isReservedHeader(k) {
97
+			continue
98
+		}
99
+		for _, v := range vv {
100
+			if k == "user-agent" {
101
+				// user-agent is special. Copying logic of http_util.go.
102
+				if i := strings.LastIndex(v, " "); i == -1 {
103
+					// There is no application user agent string being set
104
+					continue
105
+				} else {
106
+					v = v[:i]
107
+				}
108
+			}
109
+			metakv = append(metakv, k, v)
110
+
111
+		}
112
+	}
113
+	st.headerMD = metadata.Pairs(metakv...)
114
+
115
+	return st, nil
116
+}
117
+
118
+// serverHandlerTransport is an implementation of ServerTransport
119
+// which replies to exactly one gRPC request (exactly one HTTP request),
120
+// using the net/http.Handler interface. This http.Handler is guaranteed
121
+// at this point to be speaking over HTTP/2, so it's able to speak valid
122
+// gRPC.
123
+type serverHandlerTransport struct {
124
+	rw               http.ResponseWriter
125
+	req              *http.Request
126
+	timeoutSet       bool
127
+	timeout          time.Duration
128
+	didCommonHeaders bool
129
+
130
+	headerMD metadata.MD
131
+
132
+	closeOnce sync.Once
133
+	closedCh  chan struct{} // closed on Close
134
+
135
+	// writes is a channel of code to run serialized in the
136
+	// ServeHTTP (HandleStreams) goroutine. The channel is closed
137
+	// when WriteStatus is called.
138
+	writes chan func()
139
+}
140
+
141
+func (ht *serverHandlerTransport) Close() error {
142
+	ht.closeOnce.Do(ht.closeCloseChanOnce)
143
+	return nil
144
+}
145
+
146
+func (ht *serverHandlerTransport) closeCloseChanOnce() { close(ht.closedCh) }
147
+
148
+func (ht *serverHandlerTransport) RemoteAddr() net.Addr { return strAddr(ht.req.RemoteAddr) }
149
+
150
+// strAddr is a net.Addr backed by either a TCP "ip:port" string, or
151
+// the empty string if unknown.
152
+type strAddr string
153
+
154
+func (a strAddr) Network() string {
155
+	if a != "" {
156
+		// Per the documentation on net/http.Request.RemoteAddr, if this is
157
+		// set, it's set to the IP:port of the peer (hence, TCP):
158
+		// https://golang.org/pkg/net/http/#Request
159
+		//
160
+		// If we want to support Unix sockets later, we can
161
+		// add our own grpc-specific convention within the
162
+		// grpc codebase to set RemoteAddr to a different
163
+		// format, or probably better: we can attach it to the
164
+		// context and use that from serverHandlerTransport.RemoteAddr.
165
+		return "tcp"
166
+	}
167
+	return ""
168
+}
169
+
170
+func (a strAddr) String() string { return string(a) }
171
+
172
+// do runs fn in the ServeHTTP goroutine.
173
+func (ht *serverHandlerTransport) do(fn func()) error {
174
+	select {
175
+	case ht.writes <- fn:
176
+		return nil
177
+	case <-ht.closedCh:
178
+		return ErrConnClosing
179
+	}
180
+}
181
+
182
+func (ht *serverHandlerTransport) WriteStatus(s *Stream, statusCode codes.Code, statusDesc string) error {
183
+	err := ht.do(func() {
184
+		ht.writeCommonHeaders(s)
185
+
186
+		// And flush, in case no header or body has been sent yet.
187
+		// This forces a separation of headers and trailers if this is the
188
+		// first call (for example, in end2end tests's TestNoService).
189
+		ht.rw.(http.Flusher).Flush()
190
+
191
+		h := ht.rw.Header()
192
+		h.Set("Grpc-Status", fmt.Sprintf("%d", statusCode))
193
+		if statusDesc != "" {
194
+			h.Set("Grpc-Message", statusDesc)
195
+		}
196
+		if md := s.Trailer(); len(md) > 0 {
197
+			for k, vv := range md {
198
+				for _, v := range vv {
199
+					// http2 ResponseWriter mechanism to
200
+					// send undeclared Trailers after the
201
+					// headers have possibly been written.
202
+					h.Add(http2.TrailerPrefix+k, v)
203
+				}
204
+			}
205
+		}
206
+	})
207
+	close(ht.writes)
208
+	return err
209
+}
210
+
211
+// writeCommonHeaders sets common headers on the first write
212
+// call (Write, WriteHeader, or WriteStatus).
213
+func (ht *serverHandlerTransport) writeCommonHeaders(s *Stream) {
214
+	if ht.didCommonHeaders {
215
+		return
216
+	}
217
+	ht.didCommonHeaders = true
218
+
219
+	h := ht.rw.Header()
220
+	h["Date"] = nil // suppress Date to make tests happy; TODO: restore
221
+	h.Set("Content-Type", "application/grpc")
222
+
223
+	// Predeclare trailers we'll set later in WriteStatus (after the body).
224
+	// This is a SHOULD in the HTTP RFC, and the way you add (known)
225
+	// Trailers per the net/http.ResponseWriter contract.
226
+	// See https://golang.org/pkg/net/http/#ResponseWriter
227
+	// and https://golang.org/pkg/net/http/#example_ResponseWriter_trailers
228
+	h.Add("Trailer", "Grpc-Status")
229
+	h.Add("Trailer", "Grpc-Message")
230
+
231
+	if s.sendCompress != "" {
232
+		h.Set("Grpc-Encoding", s.sendCompress)
233
+	}
234
+}
235
+
236
+func (ht *serverHandlerTransport) Write(s *Stream, data []byte, opts *Options) error {
237
+	return ht.do(func() {
238
+		ht.writeCommonHeaders(s)
239
+		ht.rw.Write(data)
240
+		if !opts.Delay {
241
+			ht.rw.(http.Flusher).Flush()
242
+		}
243
+	})
244
+}
245
+
246
+func (ht *serverHandlerTransport) WriteHeader(s *Stream, md metadata.MD) error {
247
+	return ht.do(func() {
248
+		ht.writeCommonHeaders(s)
249
+		h := ht.rw.Header()
250
+		for k, vv := range md {
251
+			for _, v := range vv {
252
+				h.Add(k, v)
253
+			}
254
+		}
255
+		ht.rw.WriteHeader(200)
256
+		ht.rw.(http.Flusher).Flush()
257
+	})
258
+}
259
+
260
+func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream)) {
261
+	// With this transport type there will be exactly 1 stream: this HTTP request.
262
+
263
+	var ctx context.Context
264
+	var cancel context.CancelFunc
265
+	if ht.timeoutSet {
266
+		ctx, cancel = context.WithTimeout(context.Background(), ht.timeout)
267
+	} else {
268
+		ctx, cancel = context.WithCancel(context.Background())
269
+	}
270
+
271
+	// requestOver is closed when either the request's context is done
272
+	// or the status has been written via WriteStatus.
273
+	requestOver := make(chan struct{})
274
+
275
+	// clientGone receives a single value if peer is gone, either
276
+	// because the underlying connection is dead or because the
277
+	// peer sends an http2 RST_STREAM.
278
+	clientGone := ht.rw.(http.CloseNotifier).CloseNotify()
279
+	go func() {
280
+		select {
281
+		case <-requestOver:
282
+			return
283
+		case <-ht.closedCh:
284
+		case <-clientGone:
285
+		}
286
+		cancel()
287
+	}()
288
+
289
+	req := ht.req
290
+
291
+	s := &Stream{
292
+		id:            0,            // irrelevant
293
+		windowHandler: func(int) {}, // nothing
294
+		cancel:        cancel,
295
+		buf:           newRecvBuffer(),
296
+		st:            ht,
297
+		method:        req.URL.Path,
298
+		recvCompress:  req.Header.Get("grpc-encoding"),
299
+	}
300
+	pr := &peer.Peer{
301
+		Addr: ht.RemoteAddr(),
302
+	}
303
+	if req.TLS != nil {
304
+		pr.AuthInfo = credentials.TLSInfo{*req.TLS}
305
+	}
306
+	ctx = metadata.NewContext(ctx, ht.headerMD)
307
+	ctx = peer.NewContext(ctx, pr)
308
+	s.ctx = newContextWithStream(ctx, s)
309
+	s.dec = &recvBufferReader{ctx: s.ctx, recv: s.buf}
310
+
311
+	// readerDone is closed when the Body.Read-ing goroutine exits.
312
+	readerDone := make(chan struct{})
313
+	go func() {
314
+		defer close(readerDone)
315
+
316
+		// TODO: minimize garbage, optimize recvBuffer code/ownership
317
+		const readSize = 8196
318
+		for buf := make([]byte, readSize); ; {
319
+			n, err := req.Body.Read(buf)
320
+			if n > 0 {
321
+				s.buf.put(&recvMsg{data: buf[:n:n]})
322
+				buf = buf[n:]
323
+			}
324
+			if err != nil {
325
+				s.buf.put(&recvMsg{err: mapRecvMsgError(err)})
326
+				return
327
+			}
328
+			if len(buf) == 0 {
329
+				buf = make([]byte, readSize)
330
+			}
331
+		}
332
+	}()
333
+
334
+	// startStream is provided by the *grpc.Server's serveStreams.
335
+	// It starts a goroutine serving s and exits immediately.
336
+	// The goroutine that is started is the one that then calls
337
+	// into ht, calling WriteHeader, Write, WriteStatus, Close, etc.
338
+	startStream(s)
339
+
340
+	ht.runStream()
341
+	close(requestOver)
342
+
343
+	// Wait for reading goroutine to finish.
344
+	req.Body.Close()
345
+	<-readerDone
346
+}
347
+
348
+func (ht *serverHandlerTransport) runStream() {
349
+	for {
350
+		select {
351
+		case fn, ok := <-ht.writes:
352
+			if !ok {
353
+				return
354
+			}
355
+			fn()
356
+		case <-ht.closedCh:
357
+			return
358
+		}
359
+	}
360
+}
361
+
362
+// mapRecvMsgError returns the non-nil err into the appropriate
363
+// error value as expected by callers of *grpc.parser.recvMsg.
364
+// In particular, in can only be:
365
+//   * io.EOF
366
+//   * io.ErrUnexpectedEOF
367
+//   * of type transport.ConnectionError
368
+//   * of type transport.StreamError
369
+func mapRecvMsgError(err error) error {
370
+	if err == io.EOF || err == io.ErrUnexpectedEOF {
371
+		return err
372
+	}
373
+	if se, ok := err.(http2.StreamError); ok {
374
+		if code, ok := http2ErrConvTab[se.Code]; ok {
375
+			return StreamError{
376
+				Code: code,
377
+				Desc: se.Error(),
378
+			}
379
+		}
380
+	}
381
+	return ConnectionError{Desc: err.Error()}
382
+}
... ...
@@ -50,6 +50,7 @@ import (
50 50
 	"google.golang.org/grpc/credentials"
51 51
 	"google.golang.org/grpc/grpclog"
52 52
 	"google.golang.org/grpc/metadata"
53
+	"google.golang.org/grpc/peer"
53 54
 )
54 55
 
55 56
 // http2Client implements the ClientTransport interface with HTTP2.
... ...
@@ -139,29 +140,6 @@ func newHTTP2Client(addr string, opts *ConnectOptions) (_ ClientTransport, err e
139 139
 			conn.Close()
140 140
 		}
141 141
 	}()
142
-	// Send connection preface to server.
143
-	n, err := conn.Write(clientPreface)
144
-	if err != nil {
145
-		return nil, ConnectionErrorf("transport: %v", err)
146
-	}
147
-	if n != len(clientPreface) {
148
-		return nil, ConnectionErrorf("transport: preface mismatch, wrote %d bytes; want %d", n, len(clientPreface))
149
-	}
150
-	framer := newFramer(conn)
151
-	if initialWindowSize != defaultWindowSize {
152
-		err = framer.writeSettings(true, http2.Setting{http2.SettingInitialWindowSize, uint32(initialWindowSize)})
153
-	} else {
154
-		err = framer.writeSettings(true)
155
-	}
156
-	if err != nil {
157
-		return nil, ConnectionErrorf("transport: %v", err)
158
-	}
159
-	// Adjust the connection flow control window if needed.
160
-	if delta := uint32(initialConnWindowSize - defaultWindowSize); delta > 0 {
161
-		if err := framer.writeWindowUpdate(true, 0, delta); err != nil {
162
-			return nil, ConnectionErrorf("transport: %v", err)
163
-		}
164
-	}
165 142
 	ua := primaryUA
166 143
 	if opts.UserAgent != "" {
167 144
 		ua = opts.UserAgent + " " + ua
... ...
@@ -177,7 +155,7 @@ func newHTTP2Client(addr string, opts *ConnectOptions) (_ ClientTransport, err e
177 177
 		writableChan:    make(chan int, 1),
178 178
 		shutdownChan:    make(chan struct{}),
179 179
 		errorChan:       make(chan struct{}),
180
-		framer:          framer,
180
+		framer:          newFramer(conn),
181 181
 		hBuf:            &buf,
182 182
 		hEnc:            hpack.NewEncoder(&buf),
183 183
 		controlBuf:      newRecvBuffer(),
... ...
@@ -190,27 +168,49 @@ func newHTTP2Client(addr string, opts *ConnectOptions) (_ ClientTransport, err e
190 190
 		maxStreams:      math.MaxInt32,
191 191
 		streamSendQuota: defaultWindowSize,
192 192
 	}
193
+	// Start the reader goroutine for incoming message. Each transport has
194
+	// a dedicated goroutine which reads HTTP2 frame from network. Then it
195
+	// dispatches the frame to the corresponding stream entity.
196
+	go t.reader()
197
+	// Send connection preface to server.
198
+	n, err := t.conn.Write(clientPreface)
199
+	if err != nil {
200
+		t.Close()
201
+		return nil, ConnectionErrorf("transport: %v", err)
202
+	}
203
+	if n != len(clientPreface) {
204
+		t.Close()
205
+		return nil, ConnectionErrorf("transport: preface mismatch, wrote %d bytes; want %d", n, len(clientPreface))
206
+	}
207
+	if initialWindowSize != defaultWindowSize {
208
+		err = t.framer.writeSettings(true, http2.Setting{http2.SettingInitialWindowSize, uint32(initialWindowSize)})
209
+	} else {
210
+		err = t.framer.writeSettings(true)
211
+	}
212
+	if err != nil {
213
+		t.Close()
214
+		return nil, ConnectionErrorf("transport: %v", err)
215
+	}
216
+	// Adjust the connection flow control window if needed.
217
+	if delta := uint32(initialConnWindowSize - defaultWindowSize); delta > 0 {
218
+		if err := t.framer.writeWindowUpdate(true, 0, delta); err != nil {
219
+			t.Close()
220
+			return nil, ConnectionErrorf("transport: %v", err)
221
+		}
222
+	}
193 223
 	go t.controller()
194 224
 	t.writableChan <- 0
195
-	// Start the reader goroutine for incoming message. The threading model
196
-	// on receiving is that each transport has a dedicated goroutine which
197
-	// reads HTTP2 frame from network. Then it dispatches the frame to the
198
-	// corresponding stream entity.
199
-	go t.reader()
200 225
 	return t, nil
201 226
 }
202 227
 
203 228
 func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr) *Stream {
204
-	fc := &inFlow{
205
-		limit: initialWindowSize,
206
-		conn:  t.fc,
207
-	}
208 229
 	// TODO(zhaoq): Handle uint32 overflow of Stream.id.
209 230
 	s := &Stream{
210 231
 		id:            t.nextID,
211 232
 		method:        callHdr.Method,
233
+		sendCompress:  callHdr.SendCompress,
212 234
 		buf:           newRecvBuffer(),
213
-		fc:            fc,
235
+		fc:            &inFlow{limit: initialWindowSize},
214 236
 		sendQuotaPool: newQuotaPool(int(t.streamSendQuota)),
215 237
 		headerChan:    make(chan struct{}),
216 238
 	}
... ...
@@ -234,14 +234,20 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
234 234
 	var timeout time.Duration
235 235
 	if dl, ok := ctx.Deadline(); ok {
236 236
 		timeout = dl.Sub(time.Now())
237
-		if timeout <= 0 {
238
-			return nil, ContextErr(context.DeadlineExceeded)
239
-		}
237
+	}
238
+	select {
239
+	case <-ctx.Done():
240
+		return nil, ContextErr(ctx.Err())
241
+	default:
242
+	}
243
+	pr := &peer.Peer{
244
+		Addr: t.conn.RemoteAddr(),
240 245
 	}
241 246
 	// Attach Auth info if there is any.
242 247
 	if t.authInfo != nil {
243
-		ctx = credentials.NewContext(ctx, t.authInfo)
248
+		pr.AuthInfo = t.authInfo
244 249
 	}
250
+	ctx = peer.NewContext(ctx, pr)
245 251
 	authData := make(map[string]string)
246 252
 	for _, c := range t.authCreds {
247 253
 		// Construct URI required to get auth request metadata.
... ...
@@ -317,10 +323,15 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
317 317
 	t.hEnc.WriteField(hpack.HeaderField{Name: "user-agent", Value: t.userAgent})
318 318
 	t.hEnc.WriteField(hpack.HeaderField{Name: "te", Value: "trailers"})
319 319
 
320
+	if callHdr.SendCompress != "" {
321
+		t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-encoding", Value: callHdr.SendCompress})
322
+	}
320 323
 	if timeout > 0 {
321 324
 		t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-timeout", Value: timeoutEncode(timeout)})
322 325
 	}
323 326
 	for k, v := range authData {
327
+		// Capital header names are illegal in HTTP/2.
328
+		k = strings.ToLower(k)
324 329
 		t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: v})
325 330
 	}
326 331
 	var (
... ...
@@ -344,6 +355,10 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
344 344
 		} else {
345 345
 			endHeaders = true
346 346
 		}
347
+		var flush bool
348
+		if endHeaders && (hasMD || callHdr.Flush) {
349
+			flush = true
350
+		}
347 351
 		if first {
348 352
 			// Sends a HeadersFrame to server to start a new stream.
349 353
 			p := http2.HeadersFrameParam{
... ...
@@ -355,11 +370,11 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
355 355
 			// Do a force flush for the buffered frames iff it is the last headers frame
356 356
 			// and there is header metadata to be sent. Otherwise, there is flushing until
357 357
 			// the corresponding data frame is written.
358
-			err = t.framer.writeHeaders(hasMD && endHeaders, p)
358
+			err = t.framer.writeHeaders(flush, p)
359 359
 			first = false
360 360
 		} else {
361 361
 			// Sends Continuation frames for the leftover headers.
362
-			err = t.framer.writeContinuation(hasMD && endHeaders, s.id, endHeaders, t.hBuf.Next(size))
362
+			err = t.framer.writeContinuation(flush, s.id, endHeaders, t.hBuf.Next(size))
363 363
 		}
364 364
 		if err != nil {
365 365
 			t.notifyError(err)
... ...
@@ -389,8 +404,10 @@ func (t *http2Client) CloseStream(s *Stream, err error) {
389 389
 	// other goroutines.
390 390
 	s.cancel()
391 391
 	s.mu.Lock()
392
-	if q := s.fc.restoreConn(); q > 0 {
393
-		t.controlBuf.put(&windowUpdate{0, q})
392
+	if q := s.fc.resetPendingData(); q > 0 {
393
+		if n := t.fc.onRead(q); n > 0 {
394
+			t.controlBuf.put(&windowUpdate{0, n})
395
+		}
394 396
 	}
395 397
 	if s.state == streamDone {
396 398
 		s.mu.Unlock()
... ...
@@ -412,6 +429,9 @@ func (t *http2Client) CloseStream(s *Stream, err error) {
412 412
 // accessed any more.
413 413
 func (t *http2Client) Close() (err error) {
414 414
 	t.mu.Lock()
415
+	if t.state == reachable {
416
+		close(t.errorChan)
417
+	}
415 418
 	if t.state == closing {
416 419
 		t.mu.Unlock()
417 420
 		return errors.New("transport: Close() was already called")
... ...
@@ -490,6 +510,10 @@ func (t *http2Client) Write(s *Stream, data []byte, opts *Options) error {
490 490
 		t.framer.adjustNumWriters(1)
491 491
 		// Got some quota. Try to acquire writing privilege on the transport.
492 492
 		if _, err := wait(s.ctx, t.shutdownChan, t.writableChan); err != nil {
493
+			if _, ok := err.(StreamError); ok {
494
+				// Return the connection quota back.
495
+				t.sendQuotaPool.add(len(p))
496
+			}
493 497
 			if t.framer.adjustNumWriters(-1) == 0 {
494 498
 				// This writer is the last one in this batch and has the
495 499
 				// responsibility to flush the buffered frames. It queues
... ...
@@ -499,6 +523,16 @@ func (t *http2Client) Write(s *Stream, data []byte, opts *Options) error {
499 499
 			}
500 500
 			return err
501 501
 		}
502
+		select {
503
+		case <-s.ctx.Done():
504
+			t.sendQuotaPool.add(len(p))
505
+			if t.framer.adjustNumWriters(-1) == 0 {
506
+				t.controlBuf.put(&flushIO{})
507
+			}
508
+			t.writableChan <- 0
509
+			return ContextErr(s.ctx.Err())
510
+		default:
511
+		}
502 512
 		if r.Len() == 0 && t.framer.adjustNumWriters(0) == 1 {
503 513
 			// Do a force flush iff this is last frame for the entire gRPC message
504 514
 			// and the caller is the only writer at this moment.
... ...
@@ -537,47 +571,52 @@ func (t *http2Client) Write(s *Stream, data []byte, opts *Options) error {
537 537
 func (t *http2Client) getStream(f http2.Frame) (*Stream, bool) {
538 538
 	t.mu.Lock()
539 539
 	defer t.mu.Unlock()
540
-	if t.activeStreams == nil {
541
-		// The transport is closing.
542
-		return nil, false
543
-	}
544
-	if s, ok := t.activeStreams[f.Header().StreamID]; ok {
545
-		return s, true
546
-	}
547
-	return nil, false
540
+	s, ok := t.activeStreams[f.Header().StreamID]
541
+	return s, ok
548 542
 }
549 543
 
550 544
 // updateWindow adjusts the inbound quota for the stream and the transport.
551 545
 // Window updates will deliver to the controller for sending when
552 546
 // the cumulative quota exceeds the corresponding threshold.
553 547
 func (t *http2Client) updateWindow(s *Stream, n uint32) {
554
-	swu, cwu := s.fc.onRead(n)
555
-	if swu > 0 {
556
-		t.controlBuf.put(&windowUpdate{s.id, swu})
548
+	s.mu.Lock()
549
+	defer s.mu.Unlock()
550
+	if s.state == streamDone {
551
+		return
552
+	}
553
+	if w := t.fc.onRead(n); w > 0 {
554
+		t.controlBuf.put(&windowUpdate{0, w})
557 555
 	}
558
-	if cwu > 0 {
559
-		t.controlBuf.put(&windowUpdate{0, cwu})
556
+	if w := s.fc.onRead(n); w > 0 {
557
+		t.controlBuf.put(&windowUpdate{s.id, w})
560 558
 	}
561 559
 }
562 560
 
563 561
 func (t *http2Client) handleData(f *http2.DataFrame) {
562
+	size := len(f.Data())
563
+	if err := t.fc.onData(uint32(size)); err != nil {
564
+		t.notifyError(ConnectionErrorf("%v", err))
565
+		return
566
+	}
564 567
 	// Select the right stream to dispatch.
565 568
 	s, ok := t.getStream(f)
566 569
 	if !ok {
570
+		if w := t.fc.onRead(uint32(size)); w > 0 {
571
+			t.controlBuf.put(&windowUpdate{0, w})
572
+		}
567 573
 		return
568 574
 	}
569
-	size := len(f.Data())
570 575
 	if size > 0 {
571
-		if err := s.fc.onData(uint32(size)); err != nil {
572
-			if _, ok := err.(ConnectionError); ok {
573
-				t.notifyError(err)
574
-				return
575
-			}
576
-			s.mu.Lock()
577
-			if s.state == streamDone {
578
-				s.mu.Unlock()
579
-				return
576
+		s.mu.Lock()
577
+		if s.state == streamDone {
578
+			s.mu.Unlock()
579
+			// The stream has been closed. Release the corresponding quota.
580
+			if w := t.fc.onRead(uint32(size)); w > 0 {
581
+				t.controlBuf.put(&windowUpdate{0, w})
580 582
 			}
583
+			return
584
+		}
585
+		if err := s.fc.onData(uint32(size)); err != nil {
581 586
 			s.state = streamDone
582 587
 			s.statusCode = codes.Internal
583 588
 			s.statusDesc = err.Error()
... ...
@@ -586,6 +625,7 @@ func (t *http2Client) handleData(f *http2.DataFrame) {
586 586
 			t.controlBuf.put(&resetStream{s.id, http2.ErrCodeFlowControl})
587 587
 			return
588 588
 		}
589
+		s.mu.Unlock()
589 590
 		// TODO(bradfitz, zhaoq): A copy is required here because there is no
590 591
 		// guarantee f.Data() is consumed before the arrival of next frame.
591 592
 		// Can this copy be eliminated?
... ...
@@ -624,9 +664,10 @@ func (t *http2Client) handleRSTStream(f *http2.RSTStreamFrame) {
624 624
 		close(s.headerChan)
625 625
 		s.headerDone = true
626 626
 	}
627
-	s.statusCode, ok = http2RSTErrConvTab[http2.ErrCode(f.ErrCode)]
627
+	s.statusCode, ok = http2ErrConvTab[http2.ErrCode(f.ErrCode)]
628 628
 	if !ok {
629 629
 		grpclog.Println("transport: http2Client.handleRSTStream found no mapped gRPC status for the received http2 error ", f.ErrCode)
630
+		s.statusCode = codes.Unknown
630 631
 	}
631 632
 	s.mu.Unlock()
632 633
 	s.write(recvMsg{err: io.EOF})
... ...
@@ -667,52 +708,59 @@ func (t *http2Client) handleWindowUpdate(f *http2.WindowUpdateFrame) {
667 667
 	}
668 668
 }
669 669
 
670
-// operateHeader takes action on the decoded headers. It returns the current
671
-// stream if there are remaining headers on the wire (in the following
672
-// Continuation frame).
673
-func (t *http2Client) operateHeaders(hDec *hpackDecoder, s *Stream, frame headerFrame, endStream bool) (pendingStream *Stream) {
674
-	defer func() {
675
-		if pendingStream == nil {
676
-			hDec.state = decodeState{}
677
-		}
678
-	}()
679
-	endHeaders, err := hDec.decodeClientHTTP2Headers(frame)
680
-	if s == nil {
681
-		// s has been closed.
682
-		return nil
670
+// operateHeaders takes action on the decoded headers.
671
+func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) {
672
+	s, ok := t.getStream(frame)
673
+	if !ok {
674
+		return
683 675
 	}
684
-	if err != nil {
685
-		s.write(recvMsg{err: err})
686
-		// Something wrong. Stops reading even when there is remaining.
687
-		return nil
676
+	var state decodeState
677
+	for _, hf := range frame.Fields {
678
+		state.processHeaderField(hf)
688 679
 	}
689
-	if !endHeaders {
690
-		return s
680
+	if state.err != nil {
681
+		s.write(recvMsg{err: state.err})
682
+		// Something wrong. Stops reading even when there is remaining.
683
+		return
691 684
 	}
692 685
 
686
+	endStream := frame.StreamEnded()
687
+
693 688
 	s.mu.Lock()
689
+	if !endStream {
690
+		s.recvCompress = state.encoding
691
+	}
694 692
 	if !s.headerDone {
695
-		if !endStream && len(hDec.state.mdata) > 0 {
696
-			s.header = hDec.state.mdata
693
+		if !endStream && len(state.mdata) > 0 {
694
+			s.header = state.mdata
697 695
 		}
698 696
 		close(s.headerChan)
699 697
 		s.headerDone = true
700 698
 	}
701 699
 	if !endStream || s.state == streamDone {
702 700
 		s.mu.Unlock()
703
-		return nil
701
+		return
704 702
 	}
705 703
 
706
-	if len(hDec.state.mdata) > 0 {
707
-		s.trailer = hDec.state.mdata
704
+	if len(state.mdata) > 0 {
705
+		s.trailer = state.mdata
708 706
 	}
709 707
 	s.state = streamDone
710
-	s.statusCode = hDec.state.statusCode
711
-	s.statusDesc = hDec.state.statusDesc
708
+	s.statusCode = state.statusCode
709
+	s.statusDesc = state.statusDesc
712 710
 	s.mu.Unlock()
713 711
 
714 712
 	s.write(recvMsg{err: io.EOF})
715
-	return nil
713
+}
714
+
715
+func handleMalformedHTTP2(s *Stream, err error) {
716
+	s.mu.Lock()
717
+	if !s.headerDone {
718
+		close(s.headerChan)
719
+		s.headerDone = true
720
+	}
721
+	s.mu.Unlock()
722
+	s.write(recvMsg{err: err})
716 723
 }
717 724
 
718 725
 // reader runs as a separate goroutine in charge of reading data from network
... ...
@@ -735,25 +783,31 @@ func (t *http2Client) reader() {
735 735
 	}
736 736
 	t.handleSettings(sf)
737 737
 
738
-	hDec := newHPACKDecoder()
739
-	var curStream *Stream
740 738
 	// loop to keep reading incoming messages on this transport.
741 739
 	for {
742 740
 		frame, err := t.framer.readFrame()
743 741
 		if err != nil {
744
-			t.notifyError(err)
745
-			return
742
+			// Abort an active stream if the http2.Framer returns a
743
+			// http2.StreamError. This can happen only if the server's response
744
+			// is malformed http2.
745
+			if se, ok := err.(http2.StreamError); ok {
746
+				t.mu.Lock()
747
+				s := t.activeStreams[se.StreamID]
748
+				t.mu.Unlock()
749
+				if s != nil {
750
+					// use error detail to provide better err message
751
+					handleMalformedHTTP2(s, StreamErrorf(http2ErrConvTab[se.Code], "%v", t.framer.errorDetail()))
752
+				}
753
+				continue
754
+			} else {
755
+				// Transport error.
756
+				t.notifyError(err)
757
+				return
758
+			}
746 759
 		}
747 760
 		switch frame := frame.(type) {
748
-		case *http2.HeadersFrame:
749
-			// operateHeaders has to be invoked regardless the value of curStream
750
-			// because the HPACK decoder needs to be updated using the received
751
-			// headers.
752
-			curStream, _ = t.getStream(frame)
753
-			endStream := frame.Header().Flags.Has(http2.FlagHeadersEndStream)
754
-			curStream = t.operateHeaders(hDec, curStream, frame, endStream)
755
-		case *http2.ContinuationFrame:
756
-			curStream = t.operateHeaders(hDec, curStream, frame, frame.HeadersEnded())
761
+		case *http2.MetaHeadersFrame:
762
+			t.operateHeaders(frame)
757 763
 		case *http2.DataFrame:
758 764
 			t.handleData(frame)
759 765
 		case *http2.RSTStreamFrame:
... ...
@@ -49,6 +49,7 @@ import (
49 49
 	"google.golang.org/grpc/credentials"
50 50
 	"google.golang.org/grpc/grpclog"
51 51
 	"google.golang.org/grpc/metadata"
52
+	"google.golang.org/grpc/peer"
52 53
 )
53 54
 
54 55
 // ErrIllegalHeaderWrite indicates that setting header is illegal because of
... ...
@@ -61,8 +62,8 @@ type http2Server struct {
61 61
 	maxStreamID uint32               // max stream ID ever seen
62 62
 	authInfo    credentials.AuthInfo // auth info about the connection
63 63
 	// writableChan synchronizes write access to the transport.
64
-	// A writer acquires the write lock by sending a value on writableChan
65
-	// and releases it by receiving from writableChan.
64
+	// A writer acquires the write lock by receiving a value on writableChan
65
+	// and releases it by sending on writableChan.
66 66
 	writableChan chan int
67 67
 	// shutdownChan is closed when Close is called.
68 68
 	// Blocking operations should select on shutdownChan to avoid
... ...
@@ -135,66 +136,69 @@ func newHTTP2Server(conn net.Conn, maxStreams uint32, authInfo credentials.AuthI
135 135
 	return t, nil
136 136
 }
137 137
 
138
-// operateHeader takes action on the decoded headers. It returns the current
139
-// stream if there are remaining headers on the wire (in the following
140
-// Continuation frame).
141
-func (t *http2Server) operateHeaders(hDec *hpackDecoder, s *Stream, frame headerFrame, endStream bool, handle func(*Stream)) (pendingStream *Stream) {
142
-	defer func() {
143
-		if pendingStream == nil {
144
-			hDec.state = decodeState{}
145
-		}
146
-	}()
147
-	endHeaders, err := hDec.decodeServerHTTP2Headers(frame)
148
-	if s == nil {
149
-		// s has been closed.
150
-		return nil
138
+// operateHeader takes action on the decoded headers.
139
+func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(*Stream)) {
140
+	buf := newRecvBuffer()
141
+	s := &Stream{
142
+		id:  frame.Header().StreamID,
143
+		st:  t,
144
+		buf: buf,
145
+		fc:  &inFlow{limit: initialWindowSize},
151 146
 	}
152
-	if err != nil {
153
-		grpclog.Printf("transport: http2Server.operateHeader found %v", err)
147
+
148
+	var state decodeState
149
+	for _, hf := range frame.Fields {
150
+		state.processHeaderField(hf)
151
+	}
152
+	if err := state.err; err != nil {
154 153
 		if se, ok := err.(StreamError); ok {
155 154
 			t.controlBuf.put(&resetStream{s.id, statusCodeConvTab[se.Code]})
156 155
 		}
157
-		return nil
156
+		return
158 157
 	}
159
-	if endStream {
158
+
159
+	if frame.StreamEnded() {
160 160
 		// s is just created by the caller. No lock needed.
161 161
 		s.state = streamReadDone
162 162
 	}
163
-	if !endHeaders {
164
-		return s
165
-	}
166
-	if hDec.state.timeoutSet {
167
-		s.ctx, s.cancel = context.WithTimeout(context.TODO(), hDec.state.timeout)
163
+	s.recvCompress = state.encoding
164
+	if state.timeoutSet {
165
+		s.ctx, s.cancel = context.WithTimeout(context.TODO(), state.timeout)
168 166
 	} else {
169 167
 		s.ctx, s.cancel = context.WithCancel(context.TODO())
170 168
 	}
169
+	pr := &peer.Peer{
170
+		Addr: t.conn.RemoteAddr(),
171
+	}
171 172
 	// Attach Auth info if there is any.
172 173
 	if t.authInfo != nil {
173
-		s.ctx = credentials.NewContext(s.ctx, t.authInfo)
174
+		pr.AuthInfo = t.authInfo
174 175
 	}
176
+	s.ctx = peer.NewContext(s.ctx, pr)
175 177
 	// Cache the current stream to the context so that the server application
176 178
 	// can find out. Required when the server wants to send some metadata
177 179
 	// back to the client (unary call only).
178 180
 	s.ctx = newContextWithStream(s.ctx, s)
179 181
 	// Attach the received metadata to the context.
180
-	if len(hDec.state.mdata) > 0 {
181
-		s.ctx = metadata.NewContext(s.ctx, hDec.state.mdata)
182
+	if len(state.mdata) > 0 {
183
+		s.ctx = metadata.NewContext(s.ctx, state.mdata)
182 184
 	}
183 185
 
184 186
 	s.dec = &recvBufferReader{
185 187
 		ctx:  s.ctx,
186 188
 		recv: s.buf,
187 189
 	}
188
-	s.method = hDec.state.method
190
+	s.recvCompress = state.encoding
191
+	s.method = state.method
189 192
 	t.mu.Lock()
190 193
 	if t.state != reachable {
191 194
 		t.mu.Unlock()
192
-		return nil
195
+		return
193 196
 	}
194 197
 	if uint32(len(t.activeStreams)) >= t.maxStreams {
195 198
 		t.mu.Unlock()
196 199
 		t.controlBuf.put(&resetStream{s.id, http2.ErrCodeRefusedStream})
197
-		return nil
200
+		return
198 201
 	}
199 202
 	s.sendQuotaPool = newQuotaPool(int(t.streamSendQuota))
200 203
 	t.activeStreams[s.id] = s
... ...
@@ -203,7 +207,6 @@ func (t *http2Server) operateHeaders(hDec *hpackDecoder, s *Stream, frame header
203 203
 		t.updateWindow(s, uint32(n))
204 204
 	}
205 205
 	handle(s)
206
-	return nil
207 206
 }
208 207
 
209 208
 // HandleStreams receives incoming streams using the given handler. This is
... ...
@@ -236,16 +239,24 @@ func (t *http2Server) HandleStreams(handle func(*Stream)) {
236 236
 	}
237 237
 	t.handleSettings(sf)
238 238
 
239
-	hDec := newHPACKDecoder()
240
-	var curStream *Stream
241 239
 	for {
242 240
 		frame, err := t.framer.readFrame()
243 241
 		if err != nil {
242
+			if se, ok := err.(http2.StreamError); ok {
243
+				t.mu.Lock()
244
+				s := t.activeStreams[se.StreamID]
245
+				t.mu.Unlock()
246
+				if s != nil {
247
+					t.closeStream(s)
248
+				}
249
+				t.controlBuf.put(&resetStream{se.StreamID, se.Code})
250
+				continue
251
+			}
244 252
 			t.Close()
245 253
 			return
246 254
 		}
247 255
 		switch frame := frame.(type) {
248
-		case *http2.HeadersFrame:
256
+		case *http2.MetaHeadersFrame:
249 257
 			id := frame.Header().StreamID
250 258
 			if id%2 != 1 || id <= t.maxStreamID {
251 259
 				// illegal gRPC stream id.
... ...
@@ -254,21 +265,7 @@ func (t *http2Server) HandleStreams(handle func(*Stream)) {
254 254
 				break
255 255
 			}
256 256
 			t.maxStreamID = id
257
-			buf := newRecvBuffer()
258
-			fc := &inFlow{
259
-				limit: initialWindowSize,
260
-				conn:  t.fc,
261
-			}
262
-			curStream = &Stream{
263
-				id:  frame.Header().StreamID,
264
-				st:  t,
265
-				buf: buf,
266
-				fc:  fc,
267
-			}
268
-			endStream := frame.Header().Flags.Has(http2.FlagHeadersEndStream)
269
-			curStream = t.operateHeaders(hDec, curStream, frame, endStream, handle)
270
-		case *http2.ContinuationFrame:
271
-			curStream = t.operateHeaders(hDec, curStream, frame, frame.HeadersEnded(), handle)
257
+			t.operateHeaders(frame, handle)
272 258
 		case *http2.DataFrame:
273 259
 			t.handleData(frame)
274 260
 		case *http2.RSTStreamFrame:
... ...
@@ -306,33 +303,51 @@ func (t *http2Server) getStream(f http2.Frame) (*Stream, bool) {
306 306
 // Window updates will deliver to the controller for sending when
307 307
 // the cumulative quota exceeds the corresponding threshold.
308 308
 func (t *http2Server) updateWindow(s *Stream, n uint32) {
309
-	swu, cwu := s.fc.onRead(n)
310
-	if swu > 0 {
311
-		t.controlBuf.put(&windowUpdate{s.id, swu})
309
+	s.mu.Lock()
310
+	defer s.mu.Unlock()
311
+	if s.state == streamDone {
312
+		return
312 313
 	}
313
-	if cwu > 0 {
314
-		t.controlBuf.put(&windowUpdate{0, cwu})
314
+	if w := t.fc.onRead(n); w > 0 {
315
+		t.controlBuf.put(&windowUpdate{0, w})
316
+	}
317
+	if w := s.fc.onRead(n); w > 0 {
318
+		t.controlBuf.put(&windowUpdate{s.id, w})
315 319
 	}
316 320
 }
317 321
 
318 322
 func (t *http2Server) handleData(f *http2.DataFrame) {
323
+	size := len(f.Data())
324
+	if err := t.fc.onData(uint32(size)); err != nil {
325
+		grpclog.Printf("transport: http2Server %v", err)
326
+		t.Close()
327
+		return
328
+	}
319 329
 	// Select the right stream to dispatch.
320 330
 	s, ok := t.getStream(f)
321 331
 	if !ok {
332
+		if w := t.fc.onRead(uint32(size)); w > 0 {
333
+			t.controlBuf.put(&windowUpdate{0, w})
334
+		}
322 335
 		return
323 336
 	}
324
-	size := len(f.Data())
325 337
 	if size > 0 {
326
-		if err := s.fc.onData(uint32(size)); err != nil {
327
-			if _, ok := err.(ConnectionError); ok {
328
-				grpclog.Printf("transport: http2Server %v", err)
329
-				t.Close()
330
-				return
338
+		s.mu.Lock()
339
+		if s.state == streamDone {
340
+			s.mu.Unlock()
341
+			// The stream has been closed. Release the corresponding quota.
342
+			if w := t.fc.onRead(uint32(size)); w > 0 {
343
+				t.controlBuf.put(&windowUpdate{0, w})
331 344
 			}
345
+			return
346
+		}
347
+		if err := s.fc.onData(uint32(size)); err != nil {
348
+			s.mu.Unlock()
332 349
 			t.closeStream(s)
333 350
 			t.controlBuf.put(&resetStream{s.id, http2.ErrCodeFlowControl})
334 351
 			return
335 352
 		}
353
+		s.mu.Unlock()
336 354
 		// TODO(bradfitz, zhaoq): A copy is required here because there is no
337 355
 		// guarantee f.Data() is consumed before the arrival of next frame.
338 356
 		// Can this copy be eliminated?
... ...
@@ -441,6 +456,9 @@ func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error {
441 441
 	t.hBuf.Reset()
442 442
 	t.hEnc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"})
443 443
 	t.hEnc.WriteField(hpack.HeaderField{Name: "content-type", Value: "application/grpc"})
444
+	if s.sendCompress != "" {
445
+		t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-encoding", Value: s.sendCompress})
446
+	}
444 447
 	for k, v := range md {
445 448
 		for _, entry := range v {
446 449
 			t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: entry})
... ...
@@ -503,6 +521,10 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error {
503 503
 	// TODO(zhaoq): Support multi-writers for a single stream.
504 504
 	var writeHeaderFrame bool
505 505
 	s.mu.Lock()
506
+	if s.state == streamDone {
507
+		s.mu.Unlock()
508
+		return StreamErrorf(codes.Unknown, "the stream has been done")
509
+	}
506 510
 	if !s.headerOk {
507 511
 		writeHeaderFrame = true
508 512
 		s.headerOk = true
... ...
@@ -515,6 +537,9 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error {
515 515
 		t.hBuf.Reset()
516 516
 		t.hEnc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"})
517 517
 		t.hEnc.WriteField(hpack.HeaderField{Name: "content-type", Value: "application/grpc"})
518
+		if s.sendCompress != "" {
519
+			t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-encoding", Value: s.sendCompress})
520
+		}
518 521
 		p := http2.HeadersFrameParam{
519 522
 			StreamID:      s.id,
520 523
 			BlockFragment: t.hBuf.Bytes(),
... ...
@@ -567,6 +592,10 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error {
567 567
 		// Got some quota. Try to acquire writing privilege on the
568 568
 		// transport.
569 569
 		if _, err := wait(s.ctx, t.shutdownChan, t.writableChan); err != nil {
570
+			if _, ok := err.(StreamError); ok {
571
+				// Return the connection quota back.
572
+				t.sendQuotaPool.add(ps)
573
+			}
570 574
 			if t.framer.adjustNumWriters(-1) == 0 {
571 575
 				// This writer is the last one in this batch and has the
572 576
 				// responsibility to flush the buffered frames. It queues
... ...
@@ -576,6 +605,16 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error {
576 576
 			}
577 577
 			return err
578 578
 		}
579
+		select {
580
+		case <-s.ctx.Done():
581
+			t.sendQuotaPool.add(ps)
582
+			if t.framer.adjustNumWriters(-1) == 0 {
583
+				t.controlBuf.put(&flushIO{})
584
+			}
585
+			t.writableChan <- 0
586
+			return ContextErr(s.ctx.Err())
587
+		default:
588
+		}
579 589
 		var forceFlush bool
580 590
 		if r.Len() == 0 && t.framer.adjustNumWriters(0) == 1 && !opts.Last {
581 591
 			forceFlush = true
... ...
@@ -673,20 +712,22 @@ func (t *http2Server) closeStream(s *Stream) {
673 673
 	t.mu.Lock()
674 674
 	delete(t.activeStreams, s.id)
675 675
 	t.mu.Unlock()
676
-	if q := s.fc.restoreConn(); q > 0 {
677
-		t.controlBuf.put(&windowUpdate{0, q})
678
-	}
676
+	// In case stream sending and receiving are invoked in separate
677
+	// goroutines (e.g., bi-directional streaming), cancel needs to be
678
+	// called to interrupt the potential blocking on other goroutines.
679
+	s.cancel()
679 680
 	s.mu.Lock()
681
+	if q := s.fc.resetPendingData(); q > 0 {
682
+		if w := t.fc.onRead(q); w > 0 {
683
+			t.controlBuf.put(&windowUpdate{0, w})
684
+		}
685
+	}
680 686
 	if s.state == streamDone {
681 687
 		s.mu.Unlock()
682 688
 		return
683 689
 	}
684 690
 	s.state = streamDone
685 691
 	s.mu.Unlock()
686
-	// In case stream sending and receiving are invoked in separate
687
-	// goroutines (e.g., bi-directional streaming), cancel needs to be
688
-	// called to interrupt the potential blocking on other goroutines.
689
-	s.cancel()
690 692
 }
691 693
 
692 694
 func (t *http2Server) RemoteAddr() net.Addr {
... ...
@@ -62,13 +62,14 @@ const (
62 62
 )
63 63
 
64 64
 var (
65
-	clientPreface      = []byte(http2.ClientPreface)
66
-	http2RSTErrConvTab = map[http2.ErrCode]codes.Code{
65
+	clientPreface   = []byte(http2.ClientPreface)
66
+	http2ErrConvTab = map[http2.ErrCode]codes.Code{
67 67
 		http2.ErrCodeNo:                 codes.Internal,
68 68
 		http2.ErrCodeProtocol:           codes.Internal,
69 69
 		http2.ErrCodeInternal:           codes.Internal,
70 70
 		http2.ErrCodeFlowControl:        codes.ResourceExhausted,
71 71
 		http2.ErrCodeSettingsTimeout:    codes.Internal,
72
+		http2.ErrCodeStreamClosed:       codes.Internal,
72 73
 		http2.ErrCodeFrameSize:          codes.Internal,
73 74
 		http2.ErrCodeRefusedStream:      codes.Unavailable,
74 75
 		http2.ErrCodeCancel:             codes.Canceled,
... ...
@@ -76,6 +77,7 @@ var (
76 76
 		http2.ErrCodeConnect:            codes.Internal,
77 77
 		http2.ErrCodeEnhanceYourCalm:    codes.ResourceExhausted,
78 78
 		http2.ErrCodeInadequateSecurity: codes.PermissionDenied,
79
+		http2.ErrCodeHTTP11Required:     codes.FailedPrecondition,
79 80
 	}
80 81
 	statusCodeConvTab = map[codes.Code]http2.ErrCode{
81 82
 		codes.Internal:          http2.ErrCodeInternal,
... ...
@@ -89,6 +91,9 @@ var (
89 89
 // Records the states during HPACK decoding. Must be reset once the
90 90
 // decoding of the entire headers are finished.
91 91
 type decodeState struct {
92
+	err error // first error encountered decoding
93
+
94
+	encoding string
92 95
 	// statusCode caches the stream status received from the trailer
93 96
 	// the server sent. Client side only.
94 97
 	statusCode codes.Code
... ...
@@ -101,25 +106,11 @@ type decodeState struct {
101 101
 	mdata map[string][]string
102 102
 }
103 103
 
104
-// An hpackDecoder decodes HTTP2 headers which may span multiple frames.
105
-type hpackDecoder struct {
106
-	h     *hpack.Decoder
107
-	state decodeState
108
-	err   error // The err when decoding
109
-}
110
-
111
-// A headerFrame is either a http2.HeaderFrame or http2.ContinuationFrame.
112
-type headerFrame interface {
113
-	Header() http2.FrameHeader
114
-	HeaderBlockFragment() []byte
115
-	HeadersEnded() bool
116
-}
117
-
118 104
 // isReservedHeader checks whether hdr belongs to HTTP2 headers
119 105
 // reserved by gRPC protocol. Any other headers are classified as the
120 106
 // user-specified metadata.
121 107
 func isReservedHeader(hdr string) bool {
122
-	if hdr[0] == ':' {
108
+	if hdr != "" && hdr[0] == ':' {
123 109
 		return true
124 110
 	}
125 111
 	switch hdr {
... ...
@@ -136,98 +127,62 @@ func isReservedHeader(hdr string) bool {
136 136
 	}
137 137
 }
138 138
 
139
-func newHPACKDecoder() *hpackDecoder {
140
-	d := &hpackDecoder{}
141
-	d.h = hpack.NewDecoder(http2InitHeaderTableSize, func(f hpack.HeaderField) {
142
-		switch f.Name {
143
-		case "content-type":
144
-			if !strings.Contains(f.Value, "application/grpc") {
145
-				d.err = StreamErrorf(codes.FailedPrecondition, "transport: received the unexpected header")
146
-				return
139
+func (d *decodeState) setErr(err error) {
140
+	if d.err == nil {
141
+		d.err = err
142
+	}
143
+}
144
+
145
+func (d *decodeState) processHeaderField(f hpack.HeaderField) {
146
+	switch f.Name {
147
+	case "content-type":
148
+		if !strings.Contains(f.Value, "application/grpc") {
149
+			d.setErr(StreamErrorf(codes.FailedPrecondition, "transport: received the unexpected content-type %q", f.Value))
150
+			return
151
+		}
152
+	case "grpc-encoding":
153
+		d.encoding = f.Value
154
+	case "grpc-status":
155
+		code, err := strconv.Atoi(f.Value)
156
+		if err != nil {
157
+			d.setErr(StreamErrorf(codes.Internal, "transport: malformed grpc-status: %v", err))
158
+			return
159
+		}
160
+		d.statusCode = codes.Code(code)
161
+	case "grpc-message":
162
+		d.statusDesc = f.Value
163
+	case "grpc-timeout":
164
+		d.timeoutSet = true
165
+		var err error
166
+		d.timeout, err = timeoutDecode(f.Value)
167
+		if err != nil {
168
+			d.setErr(StreamErrorf(codes.Internal, "transport: malformed time-out: %v", err))
169
+			return
170
+		}
171
+	case ":path":
172
+		d.method = f.Value
173
+	default:
174
+		if !isReservedHeader(f.Name) {
175
+			if f.Name == "user-agent" {
176
+				i := strings.LastIndex(f.Value, " ")
177
+				if i == -1 {
178
+					// There is no application user agent string being set.
179
+					return
180
+				}
181
+				// Extract the application user agent string.
182
+				f.Value = f.Value[:i]
147 183
 			}
148
-		case "grpc-status":
149
-			code, err := strconv.Atoi(f.Value)
150
-			if err != nil {
151
-				d.err = StreamErrorf(codes.Internal, "transport: malformed grpc-status: %v", err)
152
-				return
184
+			if d.mdata == nil {
185
+				d.mdata = make(map[string][]string)
153 186
 			}
154
-			d.state.statusCode = codes.Code(code)
155
-		case "grpc-message":
156
-			d.state.statusDesc = f.Value
157
-		case "grpc-timeout":
158
-			d.state.timeoutSet = true
159
-			var err error
160
-			d.state.timeout, err = timeoutDecode(f.Value)
187
+			k, v, err := metadata.DecodeKeyValue(f.Name, f.Value)
161 188
 			if err != nil {
162
-				d.err = StreamErrorf(codes.Internal, "transport: malformed time-out: %v", err)
189
+				grpclog.Printf("Failed to decode (%q, %q): %v", f.Name, f.Value, err)
163 190
 				return
164 191
 			}
165
-		case ":path":
166
-			d.state.method = f.Value
167
-		default:
168
-			if !isReservedHeader(f.Name) {
169
-				if f.Name == "user-agent" {
170
-					i := strings.LastIndex(f.Value, " ")
171
-					if i == -1 {
172
-						// There is no application user agent string being set.
173
-						return
174
-					}
175
-					// Extract the application user agent string.
176
-					f.Value = f.Value[:i]
177
-				}
178
-				if d.state.mdata == nil {
179
-					d.state.mdata = make(map[string][]string)
180
-				}
181
-				k, v, err := metadata.DecodeKeyValue(f.Name, f.Value)
182
-				if err != nil {
183
-					grpclog.Printf("Failed to decode (%q, %q): %v", f.Name, f.Value, err)
184
-					return
185
-				}
186
-				d.state.mdata[k] = append(d.state.mdata[k], v)
187
-			}
192
+			d.mdata[k] = append(d.mdata[k], v)
188 193
 		}
189
-	})
190
-	return d
191
-}
192
-
193
-func (d *hpackDecoder) decodeClientHTTP2Headers(frame headerFrame) (endHeaders bool, err error) {
194
-	d.err = nil
195
-	_, err = d.h.Write(frame.HeaderBlockFragment())
196
-	if err != nil {
197
-		err = StreamErrorf(codes.Internal, "transport: HPACK header decode error: %v", err)
198
-	}
199
-
200
-	if frame.HeadersEnded() {
201
-		if closeErr := d.h.Close(); closeErr != nil && err == nil {
202
-			err = StreamErrorf(codes.Internal, "transport: HPACK decoder close error: %v", closeErr)
203
-		}
204
-		endHeaders = true
205 194
 	}
206
-
207
-	if err == nil && d.err != nil {
208
-		err = d.err
209
-	}
210
-	return
211
-}
212
-
213
-func (d *hpackDecoder) decodeServerHTTP2Headers(frame headerFrame) (endHeaders bool, err error) {
214
-	d.err = nil
215
-	_, err = d.h.Write(frame.HeaderBlockFragment())
216
-	if err != nil {
217
-		err = StreamErrorf(codes.Internal, "transport: HPACK header decode error: %v", err)
218
-	}
219
-
220
-	if frame.HeadersEnded() {
221
-		if closeErr := d.h.Close(); closeErr != nil && err == nil {
222
-			err = StreamErrorf(codes.Internal, "transport: HPACK decoder close error: %v", closeErr)
223
-		}
224
-		endHeaders = true
225
-	}
226
-
227
-	if err == nil && d.err != nil {
228
-		err = d.err
229
-	}
230
-	return
231 195
 }
232 196
 
233 197
 type timeoutUnit uint8
... ...
@@ -318,10 +273,11 @@ type framer struct {
318 318
 
319 319
 func newFramer(conn net.Conn) *framer {
320 320
 	f := &framer{
321
-		reader: conn,
321
+		reader: bufio.NewReaderSize(conn, http2IOBufSize),
322 322
 		writer: bufio.NewWriterSize(conn, http2IOBufSize),
323 323
 	}
324 324
 	f.fr = http2.NewFramer(f.writer, f.reader)
325
+	f.fr.ReadMetaHeaders = hpack.NewDecoder(http2InitHeaderTableSize, nil)
325 326
 	return f
326 327
 }
327 328
 
... ...
@@ -449,3 +405,7 @@ func (f *framer) flushWrite() error {
449 449
 func (f *framer) readFrame() (http2.Frame, error) {
450 450
 	return f.fr.ReadFrame()
451 451
 }
452
+
453
+func (f *framer) errorDetail() error {
454
+	return f.fr.ErrorDetail()
455
+}
... ...
@@ -63,13 +63,11 @@ type recvMsg struct {
63 63
 	err error
64 64
 }
65 65
 
66
-func (recvMsg) isItem() bool {
67
-	return true
68
-}
66
+func (*recvMsg) item() {}
69 67
 
70 68
 // All items in an out of a recvBuffer should be the same type.
71 69
 type item interface {
72
-	isItem() bool
70
+	item()
73 71
 }
74 72
 
75 73
 // recvBuffer is an unbounded channel of item.
... ...
@@ -89,12 +87,14 @@ func newRecvBuffer() *recvBuffer {
89 89
 func (b *recvBuffer) put(r item) {
90 90
 	b.mu.Lock()
91 91
 	defer b.mu.Unlock()
92
-	b.backlog = append(b.backlog, r)
93
-	select {
94
-	case b.c <- b.backlog[0]:
95
-		b.backlog = b.backlog[1:]
96
-	default:
92
+	if len(b.backlog) == 0 {
93
+		select {
94
+		case b.c <- r:
95
+			return
96
+		default:
97
+		}
97 98
 	}
99
+	b.backlog = append(b.backlog, r)
98 100
 }
99 101
 
100 102
 func (b *recvBuffer) load() {
... ...
@@ -170,11 +170,13 @@ type Stream struct {
170 170
 	ctx    context.Context
171 171
 	cancel context.CancelFunc
172 172
 	// method records the associated RPC method of the stream.
173
-	method    string
174
-	buf       *recvBuffer
175
-	dec       io.Reader
176
-	fc        *inFlow
177
-	recvQuota uint32
173
+	method       string
174
+	recvCompress string
175
+	sendCompress string
176
+	buf          *recvBuffer
177
+	dec          io.Reader
178
+	fc           *inFlow
179
+	recvQuota    uint32
178 180
 	// The accumulated inbound quota pending for window update.
179 181
 	updateQuota uint32
180 182
 	// The handler to control the window update procedure for both this
... ...
@@ -201,6 +203,17 @@ type Stream struct {
201 201
 	statusDesc string
202 202
 }
203 203
 
204
+// RecvCompress returns the compression algorithm applied to the inbound
205
+// message. It is empty string if there is no compression applied.
206
+func (s *Stream) RecvCompress() string {
207
+	return s.recvCompress
208
+}
209
+
210
+// SetSendCompress sets the compression algorithm to the stream.
211
+func (s *Stream) SetSendCompress(str string) {
212
+	s.sendCompress = str
213
+}
214
+
204 215
 // Header acquires the key-value pairs of header metadata once it
205 216
 // is available. It blocks until i) the metadata is ready or ii) there is no
206 217
 // header metadata or iii) the stream is cancelled/expired.
... ...
@@ -286,20 +299,18 @@ func (s *Stream) Read(p []byte) (n int, err error) {
286 286
 	return
287 287
 }
288 288
 
289
-type key int
290
-
291 289
 // The key to save transport.Stream in the context.
292
-const streamKey = key(0)
290
+type streamKey struct{}
293 291
 
294 292
 // newContextWithStream creates a new context from ctx and attaches stream
295 293
 // to it.
296 294
 func newContextWithStream(ctx context.Context, stream *Stream) context.Context {
297
-	return context.WithValue(ctx, streamKey, stream)
295
+	return context.WithValue(ctx, streamKey{}, stream)
298 296
 }
299 297
 
300 298
 // StreamFromContext returns the stream saved in ctx.
301 299
 func StreamFromContext(ctx context.Context) (s *Stream, ok bool) {
302
-	s, ok = ctx.Value(streamKey).(*Stream)
300
+	s, ok = ctx.Value(streamKey{}).(*Stream)
303 301
 	return
304 302
 }
305 303
 
... ...
@@ -339,20 +350,40 @@ func NewClientTransport(target string, opts *ConnectOptions) (ClientTransport, e
339 339
 // Options provides additional hints and information for message
340 340
 // transmission.
341 341
 type Options struct {
342
-	// Indicate whether it is the last piece for this stream.
342
+	// Last indicates whether this write is the last piece for
343
+	// this stream.
343 344
 	Last bool
344
-	// The hint to transport impl whether the data could be buffered for
345
-	// batching write. Transport impl can feel free to ignore it.
345
+
346
+	// Delay is a hint to the transport implementation for whether
347
+	// the data could be buffered for a batching write. The
348
+	// Transport implementation may ignore the hint.
346 349
 	Delay bool
347 350
 }
348 351
 
349 352
 // CallHdr carries the information of a particular RPC.
350 353
 type CallHdr struct {
351
-	Host   string // peer host
352
-	Method string // the operation to perform on the specified host
354
+	// Host specifies the peer's host.
355
+	Host string
356
+
357
+	// Method specifies the operation to perform.
358
+	Method string
359
+
360
+	// RecvCompress specifies the compression algorithm applied on
361
+	// inbound messages.
362
+	RecvCompress string
363
+
364
+	// SendCompress specifies the compression algorithm applied on
365
+	// outbound message.
366
+	SendCompress string
367
+
368
+	// Flush indicates whether a new stream command should be sent
369
+	// to the peer without waiting for the first data. This is
370
+	// only a hint. The transport may modify the flush decision
371
+	// for performance purposes.
372
+	Flush bool
353 373
 }
354 374
 
355
-// ClientTransport is the common interface for all gRPC client side transport
375
+// ClientTransport is the common interface for all gRPC client-side transport
356 376
 // implementations.
357 377
 type ClientTransport interface {
358 378
 	// Close tears down this transport. Once it returns, the transport
... ...
@@ -381,21 +412,33 @@ type ClientTransport interface {
381 381
 	Error() <-chan struct{}
382 382
 }
383 383
 
384
-// ServerTransport is the common interface for all gRPC server side transport
384
+// ServerTransport is the common interface for all gRPC server-side transport
385 385
 // implementations.
386
+//
387
+// Methods may be called concurrently from multiple goroutines, but
388
+// Write methods for a given Stream will be called serially.
386 389
 type ServerTransport interface {
387
-	// WriteStatus sends the status of a stream to the client.
388
-	WriteStatus(s *Stream, statusCode codes.Code, statusDesc string) error
389
-	// Write sends the data for the given stream.
390
-	Write(s *Stream, data []byte, opts *Options) error
391
-	// WriteHeader sends the header metedata for the given stream.
392
-	WriteHeader(s *Stream, md metadata.MD) error
393 390
 	// HandleStreams receives incoming streams using the given handler.
394 391
 	HandleStreams(func(*Stream))
392
+
393
+	// WriteHeader sends the header metadata for the given stream.
394
+	// WriteHeader may not be called on all streams.
395
+	WriteHeader(s *Stream, md metadata.MD) error
396
+
397
+	// Write sends the data for the given stream.
398
+	// Write may not be called on all streams.
399
+	Write(s *Stream, data []byte, opts *Options) error
400
+
401
+	// WriteStatus sends the status of a stream to the client.
402
+	// WriteStatus is the final call made on a stream and always
403
+	// occurs.
404
+	WriteStatus(s *Stream, statusCode codes.Code, statusDesc string) error
405
+
395 406
 	// Close tears down the transport. Once it is called, the transport
396 407
 	// should not be accessed any more. All the pending streams and their
397 408
 	// handlers will be terminated asynchronously.
398 409
 	Close() error
410
+
399 411
 	// RemoteAddr returns the remote network address.
400 412
 	RemoteAddr() net.Addr
401 413
 }