Skip to content

Commit ffdc2fd

Browse files
committed
Added http2 supports.
1 parent eeb7ca6 commit ffdc2fd

File tree

12 files changed

+859
-400
lines changed

12 files changed

+859
-400
lines changed

config.m4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ if test "$PHP_SWOOLE" != "no"; then
261261
swoole_buffer.c \
262262
swoole_table.c \
263263
swoole_http_server.c \
264+
swoole_http_v2_server.c \
264265
swoole_websocket_server.c \
265266
swoole_http_client.c \
266267
swoole_mysql.c \

include/http2.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,16 @@ enum swHttp2FrameType
5555
SW_HTTP2_TYPE_CONTINUATION = 9,
5656
};
5757

58+
enum swHttp2FrameFlag
59+
{
60+
SW_HTTP2_FLAG_NONE = 0x00,
61+
SW_HTTP2_FLAG_ACK_FLAG = 0x01,
62+
SW_HTTP2_FLAG_END_STREAM = 0x01,
63+
SW_HTTP2_FLAG_END_HEADERS = 0x04,
64+
SW_HTTP2_FLAG_PADDED = 0x08,
65+
SW_HTTP2_FLAG_PRIORITY = 0x20,
66+
};
67+
5868
#define SW_HTTP2_FRAME_HEADER_SIZE 9
5969
#define SW_HTTP2_RST_STREAM_SIZE 4
6070
#define SW_HTTP2_PRIORITY_SIZE 5
@@ -93,6 +103,28 @@ static sw_inline uint32_t swHttp2_get_length(char *buf)
93103
int swHttp2_get_frame_length(swProtocol *protocol, swConnection *conn, char *buf, uint32_t length);
94104
int swHttp2_send_setting_frame(swProtocol *protocol, swConnection *conn);
95105

106+
107+
/**
108+
+-----------------------------------------------+
109+
| Length (24) |
110+
+---------------+---------------+---------------+
111+
| Type (8) | Flags (8) |
112+
+-+-------------+---------------+-------------------------------+
113+
|R| Stream Identifier (31) |
114+
+=+=============================================================+
115+
| Frame Payload (0...) ...
116+
+---------------------------------------------------------------+
117+
*/
118+
static void sw_inline swHttp2_set_frame_header(char *buffer, int type, int length, int flags, int stream_id)
119+
{
120+
buffer[0] = length >> 16;
121+
buffer[1] = length >> 8;
122+
buffer[2] = length;
123+
buffer[3] = type;
124+
buffer[4] = flags;
125+
*(int*) (buffer + 5) = htonl(stream_id);
126+
}
127+
96128
#ifdef __cplusplus
97129
}
98130
#endif

include/swoole.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,7 +1012,9 @@ static inline int swoole_strrnpos(char *haystack, char *needle, uint32_t length)
10121012
return -1;
10131013
}
10141014

1015+
int swoole_itoa(char *buf, long value);
10151016
void swoole_dump_bin(char *data, char type, int size);
1017+
void swoole_dump_hex(uchar *data, int outlen);
10161018
int swoole_type_size(char type);
10171019
int swoole_mkdir_recursive(const char *dir);
10181020
char* swoole_dirname(char *file);

package.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
<file role="src" name="swoole_table.c" />
102102
<file role="src" name="swoole_buffer.c" />
103103
<file role="src" name="swoole_http_server.c" />
104+
<file role="src" name="swoole_http_v2_server.c" />
104105
<file role="src" name="swoole_http_client.c" />
105106
<file role="src" name="swoole_http.h" />
106107
<file role="src" name="swoole_websocket_server.c" />

src/core/base.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,25 @@ void swoole_dump_bin(char *data, char type, int size)
155155
printf("\n");
156156
}
157157

158+
void swoole_dump_hex(uchar *data, int outlen)
159+
{
160+
int i;
161+
162+
for (i = 0; i < outlen; ++i)
163+
{
164+
if ((i & 0x0fu) == 0)
165+
{
166+
printf("%08zX: ", i);
167+
}
168+
printf("%02X ", data[i]);
169+
if (((i + 1) & 0x0fu) == 0)
170+
{
171+
printf("\n");
172+
}
173+
}
174+
printf("\n");
175+
}
176+
158177
/**
159178
* Recursive directory creation
160179
*/
@@ -736,6 +755,36 @@ static char *swoole_kmp_search(char *haystack, size_t haylen, char *needle, uint
736755
return NULL;
737756
}
738757

758+
int swoole_itoa(char *buf, long value)
759+
{
760+
long i = 0, j;
761+
long sign_mask;
762+
unsigned long nn;
763+
764+
sign_mask = value >> sizeof(long) * 8 - 1;
765+
nn = (value + sign_mask) ^ sign_mask;
766+
do
767+
{
768+
buf[i++] = nn % 10 + '0';
769+
} while (nn /= 10);
770+
771+
buf[i] = '-';
772+
i += sign_mask & 1;
773+
buf[i] = '\0';
774+
775+
int s_len = i;
776+
char swap;
777+
778+
for (i = 0, j = s_len - 1; i < j; ++i, --j)
779+
{
780+
swap = buf[i];
781+
buf[i] = buf[j];
782+
buf[j] = swap;
783+
}
784+
buf[s_len] = 0;
785+
return s_len;
786+
}
787+
739788
char *swoole_kmp_strnstr(char *haystack, char *needle, uint32_t length)
740789
{
741790
if (!haystack || !needle)

src/core/string.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,25 @@ int swString_append(swString *str, swString *append_str)
9999
return SW_OK;
100100
}
101101

102+
int swString_append_int(swString *str, int value)
103+
{
104+
char buf[16];
105+
int s_len = swoole_itoa(buf, value);
106+
107+
int new_size = str->length + s_len;
108+
if (new_size > str->size)
109+
{
110+
if (swString_extend(str, swoole_size_align(new_size * 2, sysconf(_SC_PAGESIZE))) < 0)
111+
{
112+
return SW_ERR;
113+
}
114+
}
115+
116+
memcpy(str->str + str->length, buf, s_len);
117+
str->length += s_len;
118+
return SW_OK;
119+
}
120+
102121
int swString_append_ptr(swString *str, char *append_str, int length)
103122
{
104123
int new_size = str->length + length;

src/protocol/Http2.c

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,6 @@
1818
#include "Connection.h"
1919
#include "http2.h"
2020

21-
int swHttp2_get_frame_length(swProtocol *protocol, swConnection *conn, char *buf, uint32_t length)
22-
{
23-
if (length < SW_HTTP2_FRAME_HEADER_SIZE)
24-
{
25-
return 0;
26-
}
27-
return swHttp2_get_length(buf) + SW_HTTP2_FRAME_HEADER_SIZE;
28-
}
29-
3021
int swHttp2_parse_frame(swProtocol *protocol, swConnection *conn, char *data, uint32_t length)
3122
{
3223
int wait_body = 0;
@@ -77,3 +68,37 @@ int swHttp2_send_setting_frame(swProtocol *protocol, swConnection *conn)
7768
return swConnection_send(conn, setting_frame, SW_HTTP2_FRAME_HEADER_SIZE, 0);
7869
}
7970

71+
/**
72+
+-----------------------------------------------+
73+
| Length (24) |
74+
+---------------+---------------+---------------+
75+
| Type (8) | Flags (8) |
76+
+-+-------------+---------------+-------------------------------+
77+
|R| Stream Identifier (31) |
78+
+=+=============================================================+
79+
| Frame Payload (0...) ...
80+
+---------------------------------------------------------------+
81+
*/
82+
int swHttp2_get_frame_length(swProtocol *protocol, swConnection *conn, char *buf, uint32_t length)
83+
{
84+
if (length < SW_HTTP2_FRAME_HEADER_SIZE)
85+
{
86+
return 0;
87+
}
88+
return swHttp2_get_length(buf) + SW_HTTP2_FRAME_HEADER_SIZE;
89+
}
90+
91+
/**
92+
+---------------+
93+
|Pad Length? (8)|
94+
+-+-------------+-----------------------------------------------+
95+
|E| Stream Dependency? (31) |
96+
+-+-------------+-----------------------------------------------+
97+
| Weight? (8) |
98+
+-+-------------+-----------------------------------------------+
99+
| Header Block Fragment (*) ...
100+
+---------------------------------------------------------------+
101+
| Padding (*) ...
102+
+---------------------------------------------------------------+
103+
*/
104+

swoole_http.h

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,25 @@
2222
#include "thirdparty/php_http_parser.h"
2323
#include "thirdparty/multipart_parser.h"
2424

25+
#ifdef SW_USE_HTTP2
26+
#include <nghttp2/nghttp2.h>
27+
#endif
28+
29+
enum http_callback_type
30+
{
31+
HTTP_CALLBACK_onRequest = 0,
32+
HTTP_CALLBACK_onHandShake = 1,
33+
};
34+
35+
enum http_response_flag
36+
{
37+
HTTP_RESPONSE_SERVER = 1u << 1,
38+
HTTP_RESPONSE_CONNECTION = 1u << 2,
39+
HTTP_RESPONSE_CONTENT_LENGTH = 1u << 3,
40+
HTTP_RESPONSE_DATE = 1u << 4,
41+
HTTP_RESPONSE_CONTENT_TYPE = 1u << 5,
42+
};
43+
2544
typedef struct
2645
{
2746
enum php_http_method method;
@@ -65,25 +84,22 @@ typedef struct
6584

6685
uint32_t end :1;
6786
uint32_t send_header :1;
68-
uint32_t chunk :1;
69-
uint32_t keepalive :1;
70-
7187
uint32_t gzip_enable :1;
7288
uint32_t gzip_level :4;
73-
74-
uint32_t request_read :1;
75-
uint32_t current_header_name_allocated :1;
76-
uint32_t content_sender_initialized :1;
77-
89+
uint32_t chunk :1;
90+
uint32_t keepalive :1;
7891
uint32_t http2 :1;
7992

93+
uint8_t priority;
94+
uint32_t stream_id;
95+
8096
http_request request;
8197
http_response response;
8298

8399
#if PHP_MAJOR_VERSION >= 7
84100
struct
85101
{
86-
zval zrequest_object;
102+
zval zobject;
87103
zval zrequest;
88104
zval zserver;
89105
zval zheader;
@@ -95,12 +111,31 @@ typedef struct
95111
} request_stack;
96112
struct
97113
{
98-
zval zresponse_object;
114+
zval zobject;
99115
zval zheader;
100116
zval zcookie;
101117
} response_stack;
102118
#endif
103119

120+
} http_context;
121+
122+
typedef struct _swoole_http_client
123+
{
124+
int fd;
125+
126+
uint32_t request_read :1;
127+
uint32_t current_header_name_allocated :1;
128+
uint32_t content_sender_initialized :1;
129+
uint32_t http2 :1;
130+
131+
#ifdef SW_USE_HTTP2
132+
swHashMap *streams;
133+
nghttp2_hd_inflater *deflater;
134+
nghttp2_hd_inflater *inflater;
135+
#endif
136+
137+
http_context context;
138+
104139
php_http_parser parser;
105140
multipart_parser *mt_parser;
106141

@@ -114,12 +149,24 @@ typedef struct
114149

115150
} swoole_http_client;
116151

152+
/**
153+
* WebSocket
154+
*/
117155
int swoole_websocket_onMessage(swEventData *req);
118156
int swoole_websocket_onHandshake(swoole_http_client *client);
119157
void swoole_websocket_onOpen(swoole_http_client *client);
120158
void swoole_websocket_onReuqest(swoole_http_client *client);
121159
int swoole_websocket_isset_onMessage(void);
122-
void swoole_http_request_free(swoole_http_client *client TSRMLS_DC);
160+
/**
161+
* Http Context
162+
*/
163+
http_context* swoole_http_context_new(swoole_http_client* client TSRMLS_DC);
164+
void swoole_http_context_free(http_context *ctx TSRMLS_DC);
165+
/**
166+
* Http v2
167+
*/
168+
int swoole_http2_onFrame(swoole_http_client *client, swEventData *req);
169+
int swoole_http2_do_response(http_context *ctx, swString *body);
123170

124171
extern zend_class_entry swoole_http_server_ce;
125172
extern zend_class_entry *swoole_http_server_class_entry_ptr;
@@ -133,4 +180,6 @@ extern zend_class_entry *swoole_http_request_class_entry_ptr;
133180
extern swString *swoole_http_buffer;
134181
extern swString *swoole_zlib_buffer;
135182

183+
extern zval* php_sw_http_server_callbacks[2];
184+
136185
#endif /* SWOOLE_HTTP_H_ */

0 commit comments

Comments
 (0)