forked from swoole/swoole-src
-
Notifications
You must be signed in to change notification settings - Fork 1
/
swoole_http_v2_client.h
178 lines (149 loc) · 5.19 KB
/
swoole_http_v2_client.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@swoole.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef SWOOLE_HTTP_V2_CLIENT_H_
#define SWOOLE_HTTP_V2_CLIENT_H_
#include "php_swoole.h"
#include "swoole_http.h"
#include "http.h"
#include "http2.h"
#define HTTP2_CLIENT_HOST_HEADER_INDEX 3
#ifdef SW_HAVE_ZLIB
#include <zlib.h>
extern voidpf php_zlib_alloc(voidpf opaque, uInt items, uInt size);
extern void php_zlib_free(voidpf opaque, voidpf address);
extern int http_response_uncompress(z_stream *stream, swString *buffer, char *body, int length);
#endif
typedef struct
{
uint32_t stream_id;
uint8_t gzip;
uint8_t type;
zval *response_object;
zval *callback;
swString *buffer;
#ifdef SW_HAVE_ZLIB
z_stream gzip_stream;
swString *gzip_buffer;
#endif
#if PHP_MAJOR_VERSION >= 7
zval _callback;
zval _response_object;
#endif
// flow control
uint32_t send_window;
uint32_t recv_window;
} http2_client_stream;
typedef struct
{
uint8_t ssl;
uint8_t connecting;
uint8_t ready;
#ifdef SW_COROUTINE
uint8_t iowait;
int cid;
swClient *client;
#endif
uint32_t stream_id; // the next send stream id
uint32_t last_stream_id; // the last received stream id
// flow control
uint32_t send_window;
uint32_t recv_window;
uint32_t max_concurrent_streams;
uint32_t max_frame_size;
uint32_t max_header_list_size;
char *host;
zend_size_t host_len;
int port;
nghttp2_hd_inflater *inflater;
zval *object;
double timeout;
swLinkedList *requests;
swLinkedList *stream_requests;
swHashMap *streams;
} http2_client_property;
#ifdef SW_HAVE_ZLIB
/**
* init zlib stream
*/
static sw_inline void http2_client_init_gzip_stream(http2_client_stream *stream)
{
stream->gzip = 1;
memset(&stream->gzip_stream, 0, sizeof(stream->gzip_stream));
stream->gzip_buffer = swString_new(8192);
stream->gzip_stream.zalloc = php_zlib_alloc;
stream->gzip_stream.zfree = php_zlib_free;
}
#endif
int http2_client_parse_header(http2_client_property *hcc, http2_client_stream *stream , int flags, char *in, size_t inlen);
static sw_inline void http2_client_send_setting(swClient *cli)
{
uint16_t id = 0;
uint32_t value = 0;
char frame[SW_HTTP2_FRAME_HEADER_SIZE + 18];
memset(frame, 0, sizeof(frame));
swHttp2_set_frame_header(frame, SW_HTTP2_TYPE_SETTINGS, 18, 0, 0);
char *p = frame + SW_HTTP2_FRAME_HEADER_SIZE;
/**
* MAX_CONCURRENT_STREAMS
*/
id = htons(SW_HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS);
memcpy(p, &id, sizeof(id));
p += 2;
value = htonl(SW_HTTP2_MAX_CONCURRENT_STREAMS);
memcpy(p, &value, sizeof(value));
p += 4;
/**
* MAX_FRAME_SIZE
*/
id = htons(SW_HTTP2_SETTINGS_MAX_FRAME_SIZE);
memcpy(p, &id, sizeof(id));
p += 2;
value = htonl(SW_HTTP2_MAX_FRAME_SIZE);
memcpy(p, &value, sizeof(value));
p += 4;
/**
* INIT_WINDOW_SIZE
*/
id = htons(SW_HTTP2_SETTINGS_INIT_WINDOW_SIZE);
memcpy(p, &id, sizeof(id));
p += 2;
value = htonl(SW_HTTP2_DEFAULT_WINDOW_SIZE);
memcpy(p, &value, sizeof(value));
p += 4;
swTraceLog(SW_TRACE_HTTP2, "["SW_ECHO_GREEN"]\t[length=%d]", swHttp2_get_type(SW_HTTP2_TYPE_SETTINGS), 18);
cli->send(cli, frame, SW_HTTP2_FRAME_HEADER_SIZE + 18, 0);
}
static sw_inline void http2_client_send_window_update(swClient *cli, int stream_id, uint32_t size)
{
char frame[SW_HTTP2_FRAME_HEADER_SIZE + SW_HTTP2_WINDOW_UPDATE_SIZE];
swTraceLog(SW_TRACE_HTTP2, "["SW_ECHO_YELLOW"] stream_id=%d, size=%d", "WINDOW_UPDATE", stream_id, size);
*(uint32_t*) ((char *)frame + SW_HTTP2_FRAME_HEADER_SIZE) = htonl(size);
swHttp2_set_frame_header(frame, SW_HTTP2_TYPE_WINDOW_UPDATE, SW_HTTP2_WINDOW_UPDATE_SIZE, 0, stream_id);
cli->send(cli, frame, SW_HTTP2_FRAME_HEADER_SIZE + SW_HTTP2_WINDOW_UPDATE_SIZE, 0);
}
static sw_inline void http2_add_header(nghttp2_nv *headers, char *k, int kl, char *v, int vl)
{
k = zend_str_tolower_dup(k, kl); // auto to lower
headers->name = (uchar*) k;
headers->namelen = kl;
headers->value = (uchar*) v;
headers->valuelen = vl;
swTrace("k=%s, len=%d, v=%s, len=%d", k, kl, v, vl);
}
void http2_add_cookie(nghttp2_nv *nv, int *index, zval *cookies TSRMLS_DC);
extern swString *cookie_buffer;
extern zend_class_entry *swoole_client_class_entry_ptr;
#endif