Skip to content

Commit 3875381

Browse files
committed
Some minor optimizations
1 parent 2f7159a commit 3875381

8 files changed

+88
-36
lines changed

datastream_server.go

+2-7
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ func (stream *SimpleServerStream) ProcessRequest() {
133133
if len(trailers) > 0 {
134134
stream.quicServerStream.WriteTrailers(trailers)
135135
} else {
136-
stream.quicServerStream.WriteOrBufferData(make([]byte, 0), true)
136+
stream.quicServerStream.WriteOrBufferData(nil, true)
137137
}
138138
}
139139
}()
@@ -199,12 +199,7 @@ func (w *spdyResponseWriter) CloseNotify() <-chan bool {
199199
}
200200

201201
func (w *spdyResponseWriter) Flush() {
202-
// TODO(serialx): Support flush
203-
// Maybe it's not neccessary because QUIC sends packets in a paced interval.
204-
// I cannot find any flush related functions in current QUIC code,
205-
// and samples needing Flush seems to work fine.
206-
// This functionality maybe needed in the future when we plan to buffer user
207-
// writes in the Go side.
202+
w.w.Flush()
208203
}
209204

210205
type spdyResponseBufferedWriter struct {

go_structs.h

+5-4
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,13 @@ struct GoQuicServerConfig {
7676
};
7777

7878
struct GoSpdyHeader {
79-
const char** Keys;
80-
int* Keys_len;
79+
int N; // Size of header
80+
int* Keys_len; // Length of each keys in header
81+
int* Values_len; // Length of each values in header
8182

83+
// Used on C side to pass headers to Go.
84+
const char** Keys;
8285
const char** Values;
83-
int* Values_len;
84-
int N;
8586
};
8687

8788
typedef int64_t GoPtr;

quicstream_server.go

+11-19
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ package goquic
44
import "C"
55
import (
66
"net/http"
7-
"strings"
87
"unsafe"
98
)
109

@@ -20,19 +19,17 @@ func (stream *QuicServerStream) UserStream() DataStreamProcessor {
2019
}
2120

2221
func (stream *QuicServerStream) WriteHeader(header http.Header, is_body_empty bool) {
23-
header_c := C.initialize_header_block()
24-
for key, values := range header {
25-
value := strings.Join(values, ", ")
26-
C.insert_header_block(header_c, (*C.char)(unsafe.Pointer(&[]byte(key)[0])), C.size_t(len(key)),
27-
(*C.char)(unsafe.Pointer(&[]byte(value)[0])), C.size_t(len(value)))
28-
}
22+
keys, keylen, values, valuelen := digSpdyHeader(header)
2923

3024
if is_body_empty {
31-
C.quic_simple_server_stream_write_headers(stream.wrapper, header_c, 1)
25+
C.quic_simple_server_stream_write_headers(stream.wrapper, C.int(len(keylen)),
26+
(*C.char)(unsafe.Pointer(&keys[0])), (*C.int)(unsafe.Pointer(&keylen[0])),
27+
(*C.char)(unsafe.Pointer(&values[0])), (*C.int)(unsafe.Pointer(&valuelen[0])), 1)
3228
} else {
33-
C.quic_simple_server_stream_write_headers(stream.wrapper, header_c, 0)
29+
C.quic_simple_server_stream_write_headers(stream.wrapper, C.int(len(keylen)),
30+
(*C.char)(unsafe.Pointer(&keys[0])), (*C.int)(unsafe.Pointer(&keylen[0])),
31+
(*C.char)(unsafe.Pointer(&values[0])), (*C.int)(unsafe.Pointer(&valuelen[0])), 0)
3432
}
35-
C.delete_header_block(header_c)
3633
}
3734

3835
func (stream *QuicServerStream) WriteOrBufferData(body []byte, fin bool) {
@@ -49,16 +46,11 @@ func (stream *QuicServerStream) WriteOrBufferData(body []byte, fin bool) {
4946
}
5047

5148
func (stream *QuicServerStream) WriteTrailers(header http.Header) {
52-
header_c := C.initialize_header_block()
53-
for key, values := range header {
54-
value := strings.Join(values, ", ")
55-
// Due to spdy_utils.cc, all trailer headers key should be lower-case (why?)
56-
C.insert_header_block(header_c, (*C.char)(unsafe.Pointer(&[]byte(strings.ToLower(key))[0])), C.size_t(len(key)),
57-
(*C.char)(unsafe.Pointer(&[]byte(value)[0])), C.size_t(len(value)))
58-
}
49+
keys, keylen, values, valuelen := digSpdyHeader(header)
5950

60-
C.quic_simple_server_stream_write_trailers(stream.wrapper, header_c)
61-
C.delete_header_block(header_c)
51+
C.quic_simple_server_stream_write_trailers(stream.wrapper, C.int(len(keylen)),
52+
(*C.char)(unsafe.Pointer(&keys[0])), (*C.int)(unsafe.Pointer(&keylen[0])),
53+
(*C.char)(unsafe.Pointer(&values[0])), (*C.int)(unsafe.Pointer(&valuelen[0])))
6254
}
6355

6456
// TODO(hodduc): delete(stream.session.quicServerStreams, stream)

src/adaptor.cc

+18-4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "go_quic_alarm_go_wrapper.h"
88
#include "go_quic_alarm_factory.h"
99
#include "go_quic_simple_server_session_helper.h"
10+
#include "go_utils.h"
1011
#include "proof_source_goquic.h"
1112
#include "go_ephemeral_key_source.h"
1213

@@ -251,9 +252,15 @@ void insert_header_block(SpdyHeaderBlock* block,
251252
}
252253

253254
void quic_simple_server_stream_write_headers(GoQuicSimpleServerStream* wrapper,
254-
SpdyHeaderBlock* block,
255+
int header_size,
256+
char* header_keys,
257+
int* header_key_len,
258+
char* header_values,
259+
int* header_value_len,
255260
int is_empty_body) {
256-
wrapper->WriteHeaders(*block, is_empty_body, nullptr);
261+
SpdyHeaderBlock block;
262+
CreateSpdyHeaderBlock(block, header_size, header_keys, header_key_len, header_values, header_value_len);
263+
wrapper->WriteHeaders(block, is_empty_body, nullptr);
257264
}
258265

259266
void quic_simple_server_stream_write_or_buffer_data(
@@ -264,8 +271,15 @@ void quic_simple_server_stream_write_or_buffer_data(
264271
wrapper->WriteOrBufferBody(std::string(buf, bufsize), (fin != 0), nullptr);
265272
}
266273

267-
void quic_simple_server_stream_write_trailers(GoQuicSimpleServerStream* wrapper, SpdyHeaderBlock* block) {
268-
wrapper->WriteTrailers(*block, nullptr);
274+
void quic_simple_server_stream_write_trailers(GoQuicSimpleServerStream* wrapper,
275+
int header_size,
276+
char* header_keys,
277+
int* header_key_len,
278+
char* header_values,
279+
int* header_value_len) {
280+
SpdyHeaderBlock block;
281+
CreateSpdyHeaderBlock(block, header_size, header_keys, header_key_len, header_values, header_value_len);
282+
wrapper->WriteTrailers(block, nullptr);
269283
}
270284

271285
void go_quic_alarm_fire(GoQuicAlarmGoWrapper* go_quic_alarm) {

src/adaptor.h

+11-2
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,19 @@ void insert_header_block(SpdyHeaderBlock* map,
7272
size_t value_len);
7373

7474
void quic_simple_server_stream_write_headers(GoQuicSimpleServerStream* wrapper,
75-
SpdyHeaderBlock* header,
75+
int header_size,
76+
char* header_keys,
77+
int* header_key_len,
78+
char* header_values,
79+
int* header_value_len,
7680
int is_empty_body);
7781
void quic_simple_server_stream_write_or_buffer_data(GoQuicSimpleServerStream* wrapper, char* buf, size_t bufsize, int fin);
78-
void quic_simple_server_stream_write_trailers(GoQuicSimpleServerStream* wrapper, SpdyHeaderBlock* block);
82+
void quic_simple_server_stream_write_trailers(GoQuicSimpleServerStream* wrapper,
83+
int header_size,
84+
char* header_keys,
85+
int* header_key_len,
86+
char* header_values,
87+
int* header_value_len);
7988

8089
void go_quic_alarm_fire(GoQuicAlarmGoWrapper* go_quic_alarm);
8190
int64_t clock_now(QuicClock* clock);

src/go_utils.cc

+11
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,16 @@ void DeleteGoSpdyHeader(GoSpdyHeader* go_header) {
3333
delete(go_header);
3434
}
3535

36+
void CreateSpdyHeaderBlock(SpdyHeaderBlock& block, int N, char* key_ptr, int* key_len, char* value_ptr, int* value_len) {
37+
for (int i = 0; i < N; i++) {
38+
// Though StringPiece has constructors for (const char *, size_t)
39+
// std::string is needed here, to deep-copy every buffers.
40+
block[base::StringPiece(std::string(key_ptr, key_len[i]))] =
41+
base::StringPiece(std::string(value_ptr, value_len[i]));
42+
key_ptr += key_len[i];
43+
value_ptr += value_len[i];
44+
}
45+
}
46+
3647
}
3748

src/go_utils.h

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class SpdyHeaderBlock;
99

1010
GoSpdyHeader* CreateGoSpdyHeader(const SpdyHeaderBlock& header_block);
1111
void DeleteGoSpdyHeader(GoSpdyHeader* go_header);
12+
void CreateSpdyHeaderBlock(SpdyHeaderBlock& block, int N, char* key_ptr, int* key_len, char* value_ptr, int* value_len);
1213

1314
}
1415

stream.go

+29
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ package goquic
44
// #include "src/adaptor.h"
55
import "C"
66
import (
7+
"bytes"
8+
"fmt"
79
"net/http"
10+
"strings"
811
"unsafe"
912
)
1013

@@ -66,6 +69,32 @@ func createHeader(headers_c *C.struct_GoSpdyHeader) http.Header {
6669
return h
6770
}
6871

72+
func digSpdyHeader(header http.Header) ([]byte, []C.int, []byte, []C.int) {
73+
var keys, values bytes.Buffer
74+
var keylen, valuelen []C.int
75+
76+
keylen = make([]C.int, 0, len(header))
77+
valuelen = make([]C.int, 0, len(header))
78+
79+
for key, mvalue := range header {
80+
value := strings.Join(mvalue, ", ")
81+
82+
// Due to spdy_utils.cc, all trailer headers key should be lower-case (why?)
83+
nk, errk := keys.WriteString(strings.ToLower(key))
84+
nv, errv := values.WriteString(value)
85+
86+
keylen = append(keylen, C.int(nk))
87+
valuelen = append(valuelen, C.int(nv))
88+
89+
if errk != nil || errv != nil {
90+
fmt.Println("buffer write failed", errk, errv)
91+
break
92+
}
93+
}
94+
95+
return keys.Bytes(), keylen, values.Bytes(), valuelen
96+
}
97+
6998
//export CreateIncomingDynamicStream
7099
func CreateIncomingDynamicStream(session_key int64, stream_id uint32, wrapper_c unsafe.Pointer) int64 {
71100
session := quicServerSessionPtr.Get(session_key)

0 commit comments

Comments
 (0)