nginxtra 1.8.1.12 → 1.10.1.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (238) hide show
  1. checksums.yaml +4 -4
  2. data/bin/nginxtra +1 -1
  3. data/bin/nginxtra_rails +1 -1
  4. data/lib/nginxtra/version.rb +1 -1
  5. data/vendor/nginx/CHANGES +363 -25
  6. data/vendor/nginx/CHANGES.ru +365 -21
  7. data/vendor/nginx/LICENSE +2 -2
  8. data/vendor/nginx/auto/cc/conf +32 -0
  9. data/vendor/nginx/auto/cc/gcc +1 -1
  10. data/vendor/nginx/auto/cc/icc +2 -2
  11. data/vendor/nginx/auto/cc/msvc +29 -8
  12. data/vendor/nginx/auto/cc/name +2 -25
  13. data/vendor/nginx/auto/cc/sunc +3 -0
  14. data/vendor/nginx/auto/endianness +7 -2
  15. data/vendor/nginx/auto/install +60 -26
  16. data/vendor/nginx/auto/lib/conf +4 -4
  17. data/vendor/nginx/auto/lib/geoip/conf +6 -1
  18. data/vendor/nginx/auto/lib/libgd/conf +6 -1
  19. data/vendor/nginx/auto/lib/libxslt/conf +11 -2
  20. data/vendor/nginx/auto/lib/make +1 -1
  21. data/vendor/nginx/auto/lib/md5/conf +2 -2
  22. data/vendor/nginx/auto/lib/md5/make +2 -2
  23. data/vendor/nginx/auto/lib/openssl/conf +52 -3
  24. data/vendor/nginx/auto/lib/openssl/make +1 -1
  25. data/vendor/nginx/auto/lib/pcre/conf +2 -2
  26. data/vendor/nginx/auto/lib/pcre/make +2 -2
  27. data/vendor/nginx/auto/lib/perl/conf +6 -3
  28. data/vendor/nginx/auto/lib/perl/make +4 -1
  29. data/vendor/nginx/auto/lib/sha1/conf +2 -2
  30. data/vendor/nginx/auto/lib/sha1/make +2 -2
  31. data/vendor/nginx/auto/lib/zlib/conf +2 -2
  32. data/vendor/nginx/auto/lib/zlib/make +2 -2
  33. data/vendor/nginx/auto/make +281 -16
  34. data/vendor/nginx/auto/module +122 -0
  35. data/vendor/nginx/auto/modules +909 -178
  36. data/vendor/nginx/auto/options +81 -19
  37. data/vendor/nginx/auto/os/conf +9 -0
  38. data/vendor/nginx/auto/os/darwin +3 -0
  39. data/vendor/nginx/auto/os/freebsd +0 -20
  40. data/vendor/nginx/auto/os/linux +0 -12
  41. data/vendor/nginx/auto/os/win32 +5 -1
  42. data/vendor/nginx/auto/sources +11 -311
  43. data/vendor/nginx/auto/summary +1 -0
  44. data/vendor/nginx/auto/types/sizeof +5 -3
  45. data/vendor/nginx/auto/types/typedef +9 -4
  46. data/vendor/nginx/auto/types/uintptr_t +7 -2
  47. data/vendor/nginx/auto/unix +72 -12
  48. data/vendor/nginx/conf/fastcgi.conf +1 -0
  49. data/vendor/nginx/conf/fastcgi_params +1 -0
  50. data/vendor/nginx/conf/scgi_params +1 -0
  51. data/vendor/nginx/conf/uwsgi_params +1 -0
  52. data/vendor/nginx/configure +1 -1
  53. data/vendor/nginx/contrib/vim/syntax/nginx.vim +2 -2
  54. data/vendor/nginx/man/nginx.8 +6 -2
  55. data/vendor/nginx/src/core/nginx.c +281 -114
  56. data/vendor/nginx/src/core/nginx.h +2 -2
  57. data/vendor/nginx/src/core/ngx_conf_file.c +54 -13
  58. data/vendor/nginx/src/core/ngx_conf_file.h +8 -52
  59. data/vendor/nginx/src/core/ngx_config.h +0 -5
  60. data/vendor/nginx/src/core/ngx_connection.c +270 -37
  61. data/vendor/nginx/src/core/ngx_connection.h +35 -12
  62. data/vendor/nginx/src/core/ngx_core.h +4 -0
  63. data/vendor/nginx/src/core/ngx_crypt.c +2 -2
  64. data/vendor/nginx/src/core/ngx_cycle.c +72 -25
  65. data/vendor/nginx/src/core/ngx_cycle.h +28 -39
  66. data/vendor/nginx/src/core/ngx_file.c +14 -5
  67. data/vendor/nginx/src/core/ngx_file.h +2 -0
  68. data/vendor/nginx/src/core/ngx_hash.c +13 -1
  69. data/vendor/nginx/src/core/ngx_inet.c +20 -18
  70. data/vendor/nginx/src/core/ngx_log.c +12 -12
  71. data/vendor/nginx/src/core/ngx_log.h +13 -6
  72. data/vendor/nginx/src/core/ngx_module.c +360 -0
  73. data/vendor/nginx/src/core/ngx_module.h +307 -0
  74. data/vendor/nginx/src/core/ngx_open_file_cache.c +2 -2
  75. data/vendor/nginx/src/core/ngx_output_chain.c +8 -4
  76. data/vendor/nginx/src/core/ngx_palloc.c +42 -44
  77. data/vendor/nginx/src/{http/ngx_http_parse_time.c → core/ngx_parse_time.c} +2 -3
  78. data/vendor/nginx/src/core/ngx_parse_time.h +22 -0
  79. data/vendor/nginx/src/core/ngx_proxy_protocol.c +50 -1
  80. data/vendor/nginx/src/core/ngx_proxy_protocol.h +3 -1
  81. data/vendor/nginx/src/core/ngx_regex.c +1 -38
  82. data/vendor/nginx/src/core/ngx_resolver.c +1814 -320
  83. data/vendor/nginx/src/core/ngx_resolver.h +67 -10
  84. data/vendor/nginx/src/core/ngx_rwlock.c +120 -0
  85. data/vendor/nginx/src/core/ngx_rwlock.h +21 -0
  86. data/vendor/nginx/src/core/ngx_slab.c +6 -5
  87. data/vendor/nginx/src/core/ngx_string.c +1 -1
  88. data/vendor/nginx/src/core/ngx_syslog.c +11 -3
  89. data/vendor/nginx/src/core/ngx_syslog.h +2 -1
  90. data/vendor/nginx/src/core/ngx_thread_pool.c +4 -0
  91. data/vendor/nginx/src/core/ngx_times.c +2 -2
  92. data/vendor/nginx/src/event/modules/ngx_devpoll_module.c +3 -1
  93. data/vendor/nginx/src/event/modules/ngx_epoll_module.c +5 -2
  94. data/vendor/nginx/src/event/modules/ngx_eventport_module.c +5 -5
  95. data/vendor/nginx/src/event/modules/ngx_kqueue_module.c +15 -8
  96. data/vendor/nginx/src/event/modules/ngx_poll_module.c +0 -10
  97. data/vendor/nginx/src/event/modules/ngx_select_module.c +0 -10
  98. data/vendor/nginx/src/event/ngx_event.c +60 -103
  99. data/vendor/nginx/src/event/ngx_event.h +22 -26
  100. data/vendor/nginx/src/event/ngx_event_accept.c +414 -88
  101. data/vendor/nginx/src/event/ngx_event_connect.c +27 -18
  102. data/vendor/nginx/src/event/ngx_event_connect.h +1 -0
  103. data/vendor/nginx/src/event/ngx_event_openssl.c +65 -25
  104. data/vendor/nginx/src/event/ngx_event_openssl.h +17 -0
  105. data/vendor/nginx/src/event/ngx_event_openssl_stapling.c +73 -7
  106. data/vendor/nginx/src/event/ngx_event_pipe.c +85 -27
  107. data/vendor/nginx/src/event/ngx_event_pipe.h +10 -0
  108. data/vendor/nginx/src/http/modules/ngx_http_auth_basic_module.c +1 -1
  109. data/vendor/nginx/src/http/modules/ngx_http_auth_request_module.c +2 -2
  110. data/vendor/nginx/src/http/modules/ngx_http_chunked_filter_module.c +2 -2
  111. data/vendor/nginx/src/http/modules/ngx_http_dav_module.c +6 -6
  112. data/vendor/nginx/src/http/modules/ngx_http_fastcgi_module.c +17 -11
  113. data/vendor/nginx/src/http/modules/ngx_http_gzip_filter_module.c +2 -2
  114. data/vendor/nginx/src/http/modules/ngx_http_headers_filter_module.c +9 -9
  115. data/vendor/nginx/src/http/modules/ngx_http_image_filter_module.c +2 -2
  116. data/vendor/nginx/src/http/modules/ngx_http_limit_conn_module.c +2 -2
  117. data/vendor/nginx/src/http/modules/ngx_http_limit_req_module.c +0 -7
  118. data/vendor/nginx/src/http/modules/ngx_http_map_module.c +6 -6
  119. data/vendor/nginx/src/http/modules/ngx_http_memcached_module.c +2 -1
  120. data/vendor/nginx/src/http/modules/ngx_http_mp4_module.c +13 -13
  121. data/vendor/nginx/src/http/modules/ngx_http_not_modified_filter_module.c +2 -2
  122. data/vendor/nginx/src/http/modules/ngx_http_proxy_module.c +26 -21
  123. data/vendor/nginx/src/http/modules/ngx_http_random_index_module.c +1 -1
  124. data/vendor/nginx/src/http/modules/ngx_http_range_filter_module.c +26 -8
  125. data/vendor/nginx/src/http/modules/ngx_http_realip_module.c +73 -3
  126. data/vendor/nginx/src/http/modules/ngx_http_referer_module.c +1 -1
  127. data/vendor/nginx/src/http/modules/ngx_http_rewrite_module.c +6 -6
  128. data/vendor/nginx/src/http/modules/ngx_http_scgi_module.c +5 -3
  129. data/vendor/nginx/src/http/modules/ngx_http_slice_filter_module.c +526 -0
  130. data/vendor/nginx/src/http/modules/ngx_http_ssi_filter_module.c +7 -7
  131. data/vendor/nginx/src/http/modules/ngx_http_ssl_module.c +19 -16
  132. data/vendor/nginx/src/http/modules/ngx_http_static_module.c +1 -1
  133. data/vendor/nginx/src/http/modules/ngx_http_stub_status_module.c +1 -1
  134. data/vendor/nginx/src/http/modules/ngx_http_sub_filter_module.c +373 -173
  135. data/vendor/nginx/src/http/modules/ngx_http_upstream_hash_module.c +72 -46
  136. data/vendor/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c +18 -30
  137. data/vendor/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c +50 -39
  138. data/vendor/nginx/src/http/modules/ngx_http_upstream_least_conn_module.c +38 -129
  139. data/vendor/nginx/src/http/modules/ngx_http_upstream_zone_module.c +246 -0
  140. data/vendor/nginx/src/http/modules/ngx_http_uwsgi_module.c +6 -5
  141. data/vendor/nginx/src/http/modules/perl/nginx.xs +9 -9
  142. data/vendor/nginx/src/http/ngx_http.c +46 -43
  143. data/vendor/nginx/src/http/ngx_http.h +4 -9
  144. data/vendor/nginx/src/http/ngx_http_cache.h +4 -0
  145. data/vendor/nginx/src/http/ngx_http_copy_filter_module.c +13 -5
  146. data/vendor/nginx/src/http/ngx_http_core_module.c +92 -91
  147. data/vendor/nginx/src/http/ngx_http_core_module.h +12 -8
  148. data/vendor/nginx/src/http/ngx_http_file_cache.c +61 -10
  149. data/vendor/nginx/src/http/ngx_http_request.c +37 -50
  150. data/vendor/nginx/src/http/ngx_http_request.h +10 -15
  151. data/vendor/nginx/src/http/ngx_http_request_body.c +64 -88
  152. data/vendor/nginx/src/http/ngx_http_script.c +3 -3
  153. data/vendor/nginx/src/http/ngx_http_special_response.c +1 -4
  154. data/vendor/nginx/src/http/ngx_http_upstream.c +245 -109
  155. data/vendor/nginx/src/http/ngx_http_upstream.h +11 -5
  156. data/vendor/nginx/src/http/ngx_http_upstream_round_robin.c +212 -65
  157. data/vendor/nginx/src/http/ngx_http_upstream_round_robin.h +66 -5
  158. data/vendor/nginx/src/http/ngx_http_variables.c +28 -15
  159. data/vendor/nginx/src/http/ngx_http_write_filter_module.c +1 -1
  160. data/vendor/nginx/src/http/v2/ngx_http_v2.c +4349 -0
  161. data/vendor/nginx/src/http/v2/ngx_http_v2.h +337 -0
  162. data/vendor/nginx/src/http/v2/ngx_http_v2_filter_module.c +1391 -0
  163. data/vendor/nginx/src/http/v2/ngx_http_v2_huff_decode.c +2714 -0
  164. data/vendor/nginx/src/http/v2/ngx_http_v2_huff_encode.c +254 -0
  165. data/vendor/nginx/src/http/v2/ngx_http_v2_module.c +469 -0
  166. data/vendor/nginx/src/http/{ngx_http_spdy_module.h → v2/ngx_http_v2_module.h} +10 -9
  167. data/vendor/nginx/src/http/v2/ngx_http_v2_table.c +349 -0
  168. data/vendor/nginx/src/mail/ngx_mail.c +49 -82
  169. data/vendor/nginx/src/mail/ngx_mail.h +16 -23
  170. data/vendor/nginx/src/mail/ngx_mail_auth_http_module.c +1 -1
  171. data/vendor/nginx/src/mail/ngx_mail_core_module.c +60 -34
  172. data/vendor/nginx/src/mail/ngx_mail_handler.c +17 -12
  173. data/vendor/nginx/src/mail/ngx_mail_proxy_module.c +1 -14
  174. data/vendor/nginx/src/mail/ngx_mail_smtp_handler.c +1 -1
  175. data/vendor/nginx/src/mail/ngx_mail_ssl_module.c +5 -5
  176. data/vendor/nginx/src/os/unix/ngx_atomic.h +10 -10
  177. data/vendor/nginx/src/os/unix/ngx_channel.h +4 -4
  178. data/vendor/nginx/src/os/unix/ngx_darwin_config.h +2 -0
  179. data/vendor/nginx/src/os/unix/ngx_darwin_init.c +1 -0
  180. data/vendor/nginx/src/os/unix/ngx_dlopen.c +28 -0
  181. data/vendor/nginx/src/os/unix/ngx_dlopen.h +31 -0
  182. data/vendor/nginx/src/os/unix/ngx_errno.h +1 -0
  183. data/vendor/nginx/src/os/unix/ngx_file_aio_read.c +1 -1
  184. data/vendor/nginx/src/os/unix/ngx_files.c +313 -80
  185. data/vendor/nginx/src/os/unix/ngx_files.h +5 -2
  186. data/vendor/nginx/src/os/unix/ngx_freebsd_config.h +3 -1
  187. data/vendor/nginx/src/os/unix/ngx_freebsd_init.c +1 -0
  188. data/vendor/nginx/src/os/unix/ngx_freebsd_sendfile_chain.c +13 -0
  189. data/vendor/nginx/src/os/unix/ngx_linux.h +0 -2
  190. data/vendor/nginx/src/os/unix/ngx_linux_aio_read.c +1 -1
  191. data/vendor/nginx/src/os/unix/ngx_linux_config.h +2 -6
  192. data/vendor/nginx/src/os/unix/ngx_linux_init.c +1 -33
  193. data/vendor/nginx/src/os/unix/ngx_linux_sendfile_chain.c +55 -12
  194. data/vendor/nginx/src/os/unix/ngx_os.h +3 -9
  195. data/vendor/nginx/src/os/unix/ngx_posix_config.h +14 -1
  196. data/vendor/nginx/src/os/unix/ngx_posix_init.c +2 -1
  197. data/vendor/nginx/src/os/unix/ngx_process.c +1 -1
  198. data/vendor/nginx/src/os/unix/ngx_process_cycle.c +25 -51
  199. data/vendor/nginx/src/os/unix/ngx_process_cycle.h +1 -0
  200. data/vendor/nginx/src/os/unix/ngx_readv_chain.c +24 -28
  201. data/vendor/nginx/src/os/unix/ngx_recv.c +30 -79
  202. data/vendor/nginx/src/os/unix/ngx_send.c +1 -1
  203. data/vendor/nginx/src/os/unix/ngx_setaffinity.c +14 -30
  204. data/vendor/nginx/src/os/unix/ngx_setaffinity.h +15 -1
  205. data/vendor/nginx/src/os/unix/ngx_solaris_config.h +2 -0
  206. data/vendor/nginx/src/os/unix/ngx_solaris_init.c +1 -0
  207. data/vendor/nginx/src/os/unix/ngx_solaris_sendfilev_chain.c +23 -0
  208. data/vendor/nginx/src/os/unix/ngx_sunpro_amd64.il +3 -3
  209. data/vendor/nginx/src/os/unix/ngx_sunpro_x86.il +3 -3
  210. data/vendor/nginx/src/os/unix/ngx_udp_recv.c +5 -48
  211. data/vendor/nginx/src/os/unix/ngx_udp_send.c +56 -0
  212. data/vendor/nginx/src/stream/ngx_stream.c +564 -0
  213. data/vendor/nginx/src/stream/ngx_stream.h +212 -0
  214. data/vendor/nginx/src/stream/ngx_stream_access_module.c +451 -0
  215. data/vendor/nginx/src/stream/ngx_stream_core_module.c +562 -0
  216. data/vendor/nginx/src/stream/ngx_stream_handler.c +344 -0
  217. data/vendor/nginx/src/stream/ngx_stream_limit_conn_module.c +632 -0
  218. data/vendor/nginx/src/stream/ngx_stream_proxy_module.c +1674 -0
  219. data/vendor/nginx/src/stream/ngx_stream_ssl_module.c +460 -0
  220. data/vendor/nginx/src/stream/ngx_stream_ssl_module.h +49 -0
  221. data/vendor/nginx/src/stream/ngx_stream_upstream.c +464 -0
  222. data/vendor/nginx/src/stream/ngx_stream_upstream.h +107 -0
  223. data/vendor/nginx/src/stream/ngx_stream_upstream_hash_module.c +656 -0
  224. data/vendor/nginx/src/stream/ngx_stream_upstream_least_conn_module.c +307 -0
  225. data/vendor/nginx/src/stream/ngx_stream_upstream_round_robin.c +702 -0
  226. data/vendor/nginx/src/stream/ngx_stream_upstream_round_robin.h +139 -0
  227. data/vendor/nginx/src/stream/ngx_stream_upstream_zone_module.c +242 -0
  228. metadata +39 -15
  229. data/vendor/nginx/src/event/modules/ngx_aio_module.c +0 -171
  230. data/vendor/nginx/src/event/modules/ngx_rtsig_module.c +0 -735
  231. data/vendor/nginx/src/http/ngx_http_spdy.c +0 -3701
  232. data/vendor/nginx/src/http/ngx_http_spdy.h +0 -261
  233. data/vendor/nginx/src/http/ngx_http_spdy_filter_module.c +0 -1222
  234. data/vendor/nginx/src/http/ngx_http_spdy_module.c +0 -408
  235. data/vendor/nginx/src/os/unix/ngx_aio_read.c +0 -109
  236. data/vendor/nginx/src/os/unix/ngx_aio_read_chain.c +0 -78
  237. data/vendor/nginx/src/os/unix/ngx_aio_write.c +0 -109
  238. data/vendor/nginx/src/os/unix/ngx_aio_write_chain.c +0 -100
@@ -1,3701 +0,0 @@
1
-
2
- /*
3
- * Copyright (C) Nginx, Inc.
4
- * Copyright (C) Valentin V. Bartenev
5
- */
6
-
7
-
8
- #include <ngx_config.h>
9
- #include <ngx_core.h>
10
- #include <ngx_http.h>
11
- #include <ngx_http_spdy_module.h>
12
-
13
- #include <zlib.h>
14
-
15
-
16
- #if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED)
17
-
18
- #define ngx_str5cmp(m, c0, c1, c2, c3, c4) \
19
- *(uint32_t *) m == (c3 << 24 | c2 << 16 | c1 << 8 | c0) \
20
- && m[4] == c4
21
-
22
- #else
23
-
24
- #define ngx_str5cmp(m, c0, c1, c2, c3, c4) \
25
- m[0] == c0 && m[1] == c1 && m[2] == c2 && m[3] == c3 && m[4] == c4
26
-
27
- #endif
28
-
29
-
30
- #if (NGX_HAVE_NONALIGNED)
31
-
32
- #define ngx_spdy_frame_parse_uint16(p) ntohs(*(uint16_t *) (p))
33
- #define ngx_spdy_frame_parse_uint32(p) ntohl(*(uint32_t *) (p))
34
-
35
- #else
36
-
37
- #define ngx_spdy_frame_parse_uint16(p) ((p)[0] << 8 | (p)[1])
38
- #define ngx_spdy_frame_parse_uint32(p) \
39
- ((p)[0] << 24 | (p)[1] << 16 | (p)[2] << 8 | (p)[3])
40
-
41
- #endif
42
-
43
- #define ngx_spdy_frame_parse_sid(p) \
44
- (ngx_spdy_frame_parse_uint32(p) & 0x7fffffff)
45
- #define ngx_spdy_frame_parse_delta(p) \
46
- (ngx_spdy_frame_parse_uint32(p) & 0x7fffffff)
47
-
48
-
49
- #define ngx_spdy_ctl_frame_check(h) \
50
- (((h) & 0xffff0000) == ngx_spdy_ctl_frame_head(0))
51
- #define ngx_spdy_data_frame_check(h) \
52
- (!((h) & (uint32_t) NGX_SPDY_CTL_BIT << 31))
53
-
54
- #define ngx_spdy_ctl_frame_type(h) ((h) & 0x0000ffff)
55
- #define ngx_spdy_frame_flags(p) ((p) >> 24)
56
- #define ngx_spdy_frame_length(p) ((p) & 0x00ffffff)
57
- #define ngx_spdy_frame_id(p) ((p) & 0x00ffffff)
58
-
59
-
60
- #define NGX_SPDY_SKIP_HEADERS_BUFFER_SIZE 4096
61
- #define NGX_SPDY_CTL_FRAME_BUFFER_SIZE 16
62
-
63
- #define NGX_SPDY_PROTOCOL_ERROR 1
64
- #define NGX_SPDY_INVALID_STREAM 2
65
- #define NGX_SPDY_REFUSED_STREAM 3
66
- #define NGX_SPDY_UNSUPPORTED_VERSION 4
67
- #define NGX_SPDY_CANCEL 5
68
- #define NGX_SPDY_INTERNAL_ERROR 6
69
- #define NGX_SPDY_FLOW_CONTROL_ERROR 7
70
- #define NGX_SPDY_STREAM_IN_USE 8
71
- #define NGX_SPDY_STREAM_ALREADY_CLOSED 9
72
- /* deprecated 10 */
73
- #define NGX_SPDY_FRAME_TOO_LARGE 11
74
-
75
- #define NGX_SPDY_SETTINGS_MAX_STREAMS 4
76
- #define NGX_SPDY_SETTINGS_INIT_WINDOW 7
77
-
78
- #define NGX_SPDY_SETTINGS_FLAG_PERSIST 0x01
79
- #define NGX_SPDY_SETTINGS_FLAG_PERSISTED 0x02
80
-
81
- #define NGX_SPDY_MAX_WINDOW NGX_MAX_INT32_VALUE
82
- #define NGX_SPDY_CONNECTION_WINDOW 65536
83
- #define NGX_SPDY_INIT_STREAM_WINDOW 65536
84
- #define NGX_SPDY_STREAM_WINDOW NGX_SPDY_MAX_WINDOW
85
-
86
- typedef struct {
87
- ngx_uint_t hash;
88
- u_char len;
89
- u_char header[7];
90
- ngx_int_t (*handler)(ngx_http_request_t *r);
91
- } ngx_http_spdy_request_header_t;
92
-
93
-
94
- static void ngx_http_spdy_read_handler(ngx_event_t *rev);
95
- static void ngx_http_spdy_write_handler(ngx_event_t *wev);
96
- static void ngx_http_spdy_handle_connection(ngx_http_spdy_connection_t *sc);
97
-
98
- static u_char *ngx_http_spdy_proxy_protocol(ngx_http_spdy_connection_t *sc,
99
- u_char *pos, u_char *end);
100
- static u_char *ngx_http_spdy_state_head(ngx_http_spdy_connection_t *sc,
101
- u_char *pos, u_char *end);
102
- static u_char *ngx_http_spdy_state_syn_stream(ngx_http_spdy_connection_t *sc,
103
- u_char *pos, u_char *end);
104
- static u_char *ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc,
105
- u_char *pos, u_char *end);
106
- static u_char *ngx_http_spdy_state_headers_skip(ngx_http_spdy_connection_t *sc,
107
- u_char *pos, u_char *end);
108
- static u_char *ngx_http_spdy_state_headers_error(ngx_http_spdy_connection_t *sc,
109
- u_char *pos, u_char *end);
110
- static u_char *ngx_http_spdy_state_window_update(ngx_http_spdy_connection_t *sc,
111
- u_char *pos, u_char *end);
112
- static u_char *ngx_http_spdy_state_data(ngx_http_spdy_connection_t *sc,
113
- u_char *pos, u_char *end);
114
- static u_char *ngx_http_spdy_state_read_data(ngx_http_spdy_connection_t *sc,
115
- u_char *pos, u_char *end);
116
- static u_char *ngx_http_spdy_state_rst_stream(ngx_http_spdy_connection_t *sc,
117
- u_char *pos, u_char *end);
118
- static u_char *ngx_http_spdy_state_ping(ngx_http_spdy_connection_t *sc,
119
- u_char *pos, u_char *end);
120
- static u_char *ngx_http_spdy_state_skip(ngx_http_spdy_connection_t *sc,
121
- u_char *pos, u_char *end);
122
- static u_char *ngx_http_spdy_state_settings(ngx_http_spdy_connection_t *sc,
123
- u_char *pos, u_char *end);
124
- static u_char *ngx_http_spdy_state_complete(ngx_http_spdy_connection_t *sc,
125
- u_char *pos, u_char *end);
126
- static u_char *ngx_http_spdy_state_save(ngx_http_spdy_connection_t *sc,
127
- u_char *pos, u_char *end, ngx_http_spdy_handler_pt handler);
128
-
129
- static u_char *ngx_http_spdy_state_inflate_error(
130
- ngx_http_spdy_connection_t *sc, int rc);
131
- static u_char *ngx_http_spdy_state_protocol_error(
132
- ngx_http_spdy_connection_t *sc);
133
- static u_char *ngx_http_spdy_state_internal_error(
134
- ngx_http_spdy_connection_t *sc);
135
-
136
- static ngx_int_t ngx_http_spdy_send_window_update(
137
- ngx_http_spdy_connection_t *sc, ngx_uint_t sid, ngx_uint_t delta);
138
- static ngx_int_t ngx_http_spdy_send_rst_stream(ngx_http_spdy_connection_t *sc,
139
- ngx_uint_t sid, ngx_uint_t status, ngx_uint_t priority);
140
- static ngx_int_t ngx_http_spdy_send_settings(ngx_http_spdy_connection_t *sc);
141
- static ngx_int_t ngx_http_spdy_settings_frame_handler(
142
- ngx_http_spdy_connection_t *sc, ngx_http_spdy_out_frame_t *frame);
143
- static ngx_http_spdy_out_frame_t *ngx_http_spdy_get_ctl_frame(
144
- ngx_http_spdy_connection_t *sc, size_t size, ngx_uint_t priority);
145
- static ngx_int_t ngx_http_spdy_ctl_frame_handler(
146
- ngx_http_spdy_connection_t *sc, ngx_http_spdy_out_frame_t *frame);
147
-
148
- static ngx_http_spdy_stream_t *ngx_http_spdy_create_stream(
149
- ngx_http_spdy_connection_t *sc, ngx_uint_t id, ngx_uint_t priority);
150
- static ngx_http_spdy_stream_t *ngx_http_spdy_get_stream_by_id(
151
- ngx_http_spdy_connection_t *sc, ngx_uint_t sid);
152
- #define ngx_http_spdy_streams_index_size(sscf) (sscf->streams_index_mask + 1)
153
- #define ngx_http_spdy_stream_index(sscf, sid) \
154
- ((sid >> 1) & sscf->streams_index_mask)
155
-
156
- static ngx_int_t ngx_http_spdy_parse_header(ngx_http_request_t *r);
157
- static ngx_int_t ngx_http_spdy_alloc_large_header_buffer(ngx_http_request_t *r);
158
-
159
- static ngx_int_t ngx_http_spdy_handle_request_header(ngx_http_request_t *r);
160
- static ngx_int_t ngx_http_spdy_parse_method(ngx_http_request_t *r);
161
- static ngx_int_t ngx_http_spdy_parse_scheme(ngx_http_request_t *r);
162
- static ngx_int_t ngx_http_spdy_parse_host(ngx_http_request_t *r);
163
- static ngx_int_t ngx_http_spdy_parse_path(ngx_http_request_t *r);
164
- static ngx_int_t ngx_http_spdy_parse_version(ngx_http_request_t *r);
165
-
166
- static ngx_int_t ngx_http_spdy_construct_request_line(ngx_http_request_t *r);
167
- static void ngx_http_spdy_run_request(ngx_http_request_t *r);
168
- static ngx_int_t ngx_http_spdy_init_request_body(ngx_http_request_t *r);
169
-
170
- static ngx_int_t ngx_http_spdy_terminate_stream(ngx_http_spdy_connection_t *sc,
171
- ngx_http_spdy_stream_t *stream, ngx_uint_t status);
172
-
173
- static void ngx_http_spdy_close_stream_handler(ngx_event_t *ev);
174
-
175
- static void ngx_http_spdy_handle_connection_handler(ngx_event_t *rev);
176
- static void ngx_http_spdy_keepalive_handler(ngx_event_t *rev);
177
- static void ngx_http_spdy_finalize_connection(ngx_http_spdy_connection_t *sc,
178
- ngx_int_t rc);
179
-
180
- static ngx_int_t ngx_http_spdy_adjust_windows(ngx_http_spdy_connection_t *sc,
181
- ssize_t delta);
182
-
183
- static void ngx_http_spdy_pool_cleanup(void *data);
184
-
185
- static void *ngx_http_spdy_zalloc(void *opaque, u_int items, u_int size);
186
- static void ngx_http_spdy_zfree(void *opaque, void *address);
187
-
188
-
189
- static const u_char ngx_http_spdy_dict[] = {
190
- 0x00, 0x00, 0x00, 0x07, 0x6f, 0x70, 0x74, 0x69, /* - - - - o p t i */
191
- 0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, 0x04, 0x68, /* o n s - - - - h */
192
- 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x70, /* e a d - - - - p */
193
- 0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x03, 0x70, /* o s t - - - - p */
194
- 0x75, 0x74, 0x00, 0x00, 0x00, 0x06, 0x64, 0x65, /* u t - - - - d e */
195
- 0x6c, 0x65, 0x74, 0x65, 0x00, 0x00, 0x00, 0x05, /* l e t e - - - - */
196
- 0x74, 0x72, 0x61, 0x63, 0x65, 0x00, 0x00, 0x00, /* t r a c e - - - */
197
- 0x06, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x00, /* - a c c e p t - */
198
- 0x00, 0x00, 0x0e, 0x61, 0x63, 0x63, 0x65, 0x70, /* - - - a c c e p */
199
- 0x74, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, /* t - c h a r s e */
200
- 0x74, 0x00, 0x00, 0x00, 0x0f, 0x61, 0x63, 0x63, /* t - - - - a c c */
201
- 0x65, 0x70, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, /* e p t - e n c o */
202
- 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x0f, /* d i n g - - - - */
203
- 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x6c, /* a c c e p t - l */
204
- 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x00, /* a n g u a g e - */
205
- 0x00, 0x00, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x70, /* - - - a c c e p */
206
- 0x74, 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, /* t - r a n g e s */
207
- 0x00, 0x00, 0x00, 0x03, 0x61, 0x67, 0x65, 0x00, /* - - - - a g e - */
208
- 0x00, 0x00, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x77, /* - - - a l l o w */
209
- 0x00, 0x00, 0x00, 0x0d, 0x61, 0x75, 0x74, 0x68, /* - - - - a u t h */
210
- 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, /* o r i z a t i o */
211
- 0x6e, 0x00, 0x00, 0x00, 0x0d, 0x63, 0x61, 0x63, /* n - - - - c a c */
212
- 0x68, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, /* h e - c o n t r */
213
- 0x6f, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x63, 0x6f, /* o l - - - - c o */
214
- 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, /* n n e c t i o n */
215
- 0x00, 0x00, 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, /* - - - - c o n t */
216
- 0x65, 0x6e, 0x74, 0x2d, 0x62, 0x61, 0x73, 0x65, /* e n t - b a s e */
217
- 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, 0x6e, 0x74, /* - - - - c o n t */
218
- 0x65, 0x6e, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, /* e n t - e n c o */
219
- 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, /* d i n g - - - - */
220
- 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, /* c o n t e n t - */
221
- 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, /* l a n g u a g e */
222
- 0x00, 0x00, 0x00, 0x0e, 0x63, 0x6f, 0x6e, 0x74, /* - - - - c o n t */
223
- 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x65, 0x6e, 0x67, /* e n t - l e n g */
224
- 0x74, 0x68, 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, /* t h - - - - c o */
225
- 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x6f, /* n t e n t - l o */
226
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, /* c a t i o n - - */
227
- 0x00, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, /* - - c o n t e n */
228
- 0x74, 0x2d, 0x6d, 0x64, 0x35, 0x00, 0x00, 0x00, /* t - m d 5 - - - */
229
- 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, /* - c o n t e n t */
230
- 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, /* - r a n g e - - */
231
- 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, /* - - c o n t e n */
232
- 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00, /* t - t y p e - - */
233
- 0x00, 0x04, 0x64, 0x61, 0x74, 0x65, 0x00, 0x00, /* - - d a t e - - */
234
- 0x00, 0x04, 0x65, 0x74, 0x61, 0x67, 0x00, 0x00, /* - - e t a g - - */
235
- 0x00, 0x06, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, /* - - e x p e c t */
236
- 0x00, 0x00, 0x00, 0x07, 0x65, 0x78, 0x70, 0x69, /* - - - - e x p i */
237
- 0x72, 0x65, 0x73, 0x00, 0x00, 0x00, 0x04, 0x66, /* r e s - - - - f */
238
- 0x72, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x68, /* r o m - - - - h */
239
- 0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x08, 0x69, /* o s t - - - - i */
240
- 0x66, 0x2d, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, /* f - m a t c h - */
241
- 0x00, 0x00, 0x11, 0x69, 0x66, 0x2d, 0x6d, 0x6f, /* - - - i f - m o */
242
- 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2d, 0x73, /* d i f i e d - s */
243
- 0x69, 0x6e, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0d, /* i n c e - - - - */
244
- 0x69, 0x66, 0x2d, 0x6e, 0x6f, 0x6e, 0x65, 0x2d, /* i f - n o n e - */
245
- 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, 0x00, 0x00, /* m a t c h - - - */
246
- 0x08, 0x69, 0x66, 0x2d, 0x72, 0x61, 0x6e, 0x67, /* - i f - r a n g */
247
- 0x65, 0x00, 0x00, 0x00, 0x13, 0x69, 0x66, 0x2d, /* e - - - - i f - */
248
- 0x75, 0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, /* u n m o d i f i */
249
- 0x65, 0x64, 0x2d, 0x73, 0x69, 0x6e, 0x63, 0x65, /* e d - s i n c e */
250
- 0x00, 0x00, 0x00, 0x0d, 0x6c, 0x61, 0x73, 0x74, /* - - - - l a s t */
251
- 0x2d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, /* - m o d i f i e */
252
- 0x64, 0x00, 0x00, 0x00, 0x08, 0x6c, 0x6f, 0x63, /* d - - - - l o c */
253
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, /* a t i o n - - - */
254
- 0x0c, 0x6d, 0x61, 0x78, 0x2d, 0x66, 0x6f, 0x72, /* - m a x - f o r */
255
- 0x77, 0x61, 0x72, 0x64, 0x73, 0x00, 0x00, 0x00, /* w a r d s - - - */
256
- 0x06, 0x70, 0x72, 0x61, 0x67, 0x6d, 0x61, 0x00, /* - p r a g m a - */
257
- 0x00, 0x00, 0x12, 0x70, 0x72, 0x6f, 0x78, 0x79, /* - - - p r o x y */
258
- 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, /* - a u t h e n t */
259
- 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, /* i c a t e - - - */
260
- 0x13, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2d, 0x61, /* - p r o x y - a */
261
- 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, /* u t h o r i z a */
262
- 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x05, /* t i o n - - - - */
263
- 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00, /* r a n g e - - - */
264
- 0x07, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, /* - r e f e r e r */
265
- 0x00, 0x00, 0x00, 0x0b, 0x72, 0x65, 0x74, 0x72, /* - - - - r e t r */
266
- 0x79, 0x2d, 0x61, 0x66, 0x74, 0x65, 0x72, 0x00, /* y - a f t e r - */
267
- 0x00, 0x00, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, /* - - - s e r v e */
268
- 0x72, 0x00, 0x00, 0x00, 0x02, 0x74, 0x65, 0x00, /* r - - - - t e - */
269
- 0x00, 0x00, 0x07, 0x74, 0x72, 0x61, 0x69, 0x6c, /* - - - t r a i l */
270
- 0x65, 0x72, 0x00, 0x00, 0x00, 0x11, 0x74, 0x72, /* e r - - - - t r */
271
- 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, 0x65, /* a n s f e r - e */
272
- 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x00, /* n c o d i n g - */
273
- 0x00, 0x00, 0x07, 0x75, 0x70, 0x67, 0x72, 0x61, /* - - - u p g r a */
274
- 0x64, 0x65, 0x00, 0x00, 0x00, 0x0a, 0x75, 0x73, /* d e - - - - u s */
275
- 0x65, 0x72, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74, /* e r - a g e n t */
276
- 0x00, 0x00, 0x00, 0x04, 0x76, 0x61, 0x72, 0x79, /* - - - - v a r y */
277
- 0x00, 0x00, 0x00, 0x03, 0x76, 0x69, 0x61, 0x00, /* - - - - v i a - */
278
- 0x00, 0x00, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, /* - - - w a r n i */
279
- 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, 0x77, 0x77, /* n g - - - - w w */
280
- 0x77, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, /* w - a u t h e n */
281
- 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, /* t i c a t e - - */
282
- 0x00, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, /* - - m e t h o d */
283
- 0x00, 0x00, 0x00, 0x03, 0x67, 0x65, 0x74, 0x00, /* - - - - g e t - */
284
- 0x00, 0x00, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, /* - - - s t a t u */
285
- 0x73, 0x00, 0x00, 0x00, 0x06, 0x32, 0x30, 0x30, /* s - - - - 2 0 0 */
286
- 0x20, 0x4f, 0x4b, 0x00, 0x00, 0x00, 0x07, 0x76, /* - O K - - - - v */
287
- 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00, /* e r s i o n - - */
288
- 0x00, 0x08, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, /* - - H T T P - 1 */
289
- 0x2e, 0x31, 0x00, 0x00, 0x00, 0x03, 0x75, 0x72, /* - 1 - - - - u r */
290
- 0x6c, 0x00, 0x00, 0x00, 0x06, 0x70, 0x75, 0x62, /* l - - - - p u b */
291
- 0x6c, 0x69, 0x63, 0x00, 0x00, 0x00, 0x0a, 0x73, /* l i c - - - - s */
292
- 0x65, 0x74, 0x2d, 0x63, 0x6f, 0x6f, 0x6b, 0x69, /* e t - c o o k i */
293
- 0x65, 0x00, 0x00, 0x00, 0x0a, 0x6b, 0x65, 0x65, /* e - - - - k e e */
294
- 0x70, 0x2d, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x00, /* p - a l i v e - */
295
- 0x00, 0x00, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, /* - - - o r i g i */
296
- 0x6e, 0x31, 0x30, 0x30, 0x31, 0x30, 0x31, 0x32, /* n 1 0 0 1 0 1 2 */
297
- 0x30, 0x31, 0x32, 0x30, 0x32, 0x32, 0x30, 0x35, /* 0 1 2 0 2 2 0 5 */
298
- 0x32, 0x30, 0x36, 0x33, 0x30, 0x30, 0x33, 0x30, /* 2 0 6 3 0 0 3 0 */
299
- 0x32, 0x33, 0x30, 0x33, 0x33, 0x30, 0x34, 0x33, /* 2 3 0 3 3 0 4 3 */
300
- 0x30, 0x35, 0x33, 0x30, 0x36, 0x33, 0x30, 0x37, /* 0 5 3 0 6 3 0 7 */
301
- 0x34, 0x30, 0x32, 0x34, 0x30, 0x35, 0x34, 0x30, /* 4 0 2 4 0 5 4 0 */
302
- 0x36, 0x34, 0x30, 0x37, 0x34, 0x30, 0x38, 0x34, /* 6 4 0 7 4 0 8 4 */
303
- 0x30, 0x39, 0x34, 0x31, 0x30, 0x34, 0x31, 0x31, /* 0 9 4 1 0 4 1 1 */
304
- 0x34, 0x31, 0x32, 0x34, 0x31, 0x33, 0x34, 0x31, /* 4 1 2 4 1 3 4 1 */
305
- 0x34, 0x34, 0x31, 0x35, 0x34, 0x31, 0x36, 0x34, /* 4 4 1 5 4 1 6 4 */
306
- 0x31, 0x37, 0x35, 0x30, 0x32, 0x35, 0x30, 0x34, /* 1 7 5 0 2 5 0 4 */
307
- 0x35, 0x30, 0x35, 0x32, 0x30, 0x33, 0x20, 0x4e, /* 5 0 5 2 0 3 - N */
308
- 0x6f, 0x6e, 0x2d, 0x41, 0x75, 0x74, 0x68, 0x6f, /* o n - A u t h o */
309
- 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, /* r i t a t i v e */
310
- 0x20, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, /* - I n f o r m a */
311
- 0x74, 0x69, 0x6f, 0x6e, 0x32, 0x30, 0x34, 0x20, /* t i o n 2 0 4 - */
312
- 0x4e, 0x6f, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x65, /* N o - C o n t e */
313
- 0x6e, 0x74, 0x33, 0x30, 0x31, 0x20, 0x4d, 0x6f, /* n t 3 0 1 - M o */
314
- 0x76, 0x65, 0x64, 0x20, 0x50, 0x65, 0x72, 0x6d, /* v e d - P e r m */
315
- 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x34, /* a n e n t l y 4 */
316
- 0x30, 0x30, 0x20, 0x42, 0x61, 0x64, 0x20, 0x52, /* 0 0 - B a d - R */
317
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x34, 0x30, /* e q u e s t 4 0 */
318
- 0x31, 0x20, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, /* 1 - U n a u t h */
319
- 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x34, 0x30, /* o r i z e d 4 0 */
320
- 0x33, 0x20, 0x46, 0x6f, 0x72, 0x62, 0x69, 0x64, /* 3 - F o r b i d */
321
- 0x64, 0x65, 0x6e, 0x34, 0x30, 0x34, 0x20, 0x4e, /* d e n 4 0 4 - N */
322
- 0x6f, 0x74, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, /* o t - F o u n d */
323
- 0x35, 0x30, 0x30, 0x20, 0x49, 0x6e, 0x74, 0x65, /* 5 0 0 - I n t e */
324
- 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72, /* r n a l - S e r */
325
- 0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6f, /* v e r - E r r o */
326
- 0x72, 0x35, 0x30, 0x31, 0x20, 0x4e, 0x6f, 0x74, /* r 5 0 1 - N o t */
327
- 0x20, 0x49, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, /* - I m p l e m e */
328
- 0x6e, 0x74, 0x65, 0x64, 0x35, 0x30, 0x33, 0x20, /* n t e d 5 0 3 - */
329
- 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, /* S e r v i c e - */
330
- 0x55, 0x6e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, /* U n a v a i l a */
331
- 0x62, 0x6c, 0x65, 0x4a, 0x61, 0x6e, 0x20, 0x46, /* b l e J a n - F */
332
- 0x65, 0x62, 0x20, 0x4d, 0x61, 0x72, 0x20, 0x41, /* e b - M a r - A */
333
- 0x70, 0x72, 0x20, 0x4d, 0x61, 0x79, 0x20, 0x4a, /* p r - M a y - J */
334
- 0x75, 0x6e, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x41, /* u n - J u l - A */
335
- 0x75, 0x67, 0x20, 0x53, 0x65, 0x70, 0x74, 0x20, /* u g - S e p t - */
336
- 0x4f, 0x63, 0x74, 0x20, 0x4e, 0x6f, 0x76, 0x20, /* O c t - N o v - */
337
- 0x44, 0x65, 0x63, 0x20, 0x30, 0x30, 0x3a, 0x30, /* D e c - 0 0 - 0 */
338
- 0x30, 0x3a, 0x30, 0x30, 0x20, 0x4d, 0x6f, 0x6e, /* 0 - 0 0 - M o n */
339
- 0x2c, 0x20, 0x54, 0x75, 0x65, 0x2c, 0x20, 0x57, /* - - T u e - - W */
340
- 0x65, 0x64, 0x2c, 0x20, 0x54, 0x68, 0x75, 0x2c, /* e d - - T h u - */
341
- 0x20, 0x46, 0x72, 0x69, 0x2c, 0x20, 0x53, 0x61, /* - F r i - - S a */
342
- 0x74, 0x2c, 0x20, 0x53, 0x75, 0x6e, 0x2c, 0x20, /* t - - S u n - - */
343
- 0x47, 0x4d, 0x54, 0x63, 0x68, 0x75, 0x6e, 0x6b, /* G M T c h u n k */
344
- 0x65, 0x64, 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, /* e d - t e x t - */
345
- 0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x69, 0x6d, 0x61, /* h t m l - i m a */
346
- 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0x2c, 0x69, /* g e - p n g - i */
347
- 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x67, /* m a g e - j p g */
348
- 0x2c, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, /* - i m a g e - g */
349
- 0x69, 0x66, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, /* i f - a p p l i */
350
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, /* c a t i o n - x */
351
- 0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, /* m l - a p p l i */
352
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, /* c a t i o n - x */
353
- 0x68, 0x74, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, 0x6c, /* h t m l - x m l */
354
- 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, /* - t e x t - p l */
355
- 0x61, 0x69, 0x6e, 0x2c, 0x74, 0x65, 0x78, 0x74, /* a i n - t e x t */
356
- 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, /* - j a v a s c r */
357
- 0x69, 0x70, 0x74, 0x2c, 0x70, 0x75, 0x62, 0x6c, /* i p t - p u b l */
358
- 0x69, 0x63, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, /* i c p r i v a t */
359
- 0x65, 0x6d, 0x61, 0x78, 0x2d, 0x61, 0x67, 0x65, /* e m a x - a g e */
360
- 0x3d, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x64, 0x65, /* - g z i p - d e */
361
- 0x66, 0x6c, 0x61, 0x74, 0x65, 0x2c, 0x73, 0x64, /* f l a t e - s d */
362
- 0x63, 0x68, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, /* c h c h a r s e */
363
- 0x74, 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x63, /* t - u t f - 8 c */
364
- 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x69, /* h a r s e t - i */
365
- 0x73, 0x6f, 0x2d, 0x38, 0x38, 0x35, 0x39, 0x2d, /* s o - 8 8 5 9 - */
366
- 0x31, 0x2c, 0x75, 0x74, 0x66, 0x2d, 0x2c, 0x2a, /* 1 - u t f - - - */
367
- 0x2c, 0x65, 0x6e, 0x71, 0x3d, 0x30, 0x2e /* - e n q - 0 - */
368
- };
369
-
370
-
371
- static ngx_http_spdy_request_header_t ngx_http_spdy_request_headers[] = {
372
- { 0, 6, "method", ngx_http_spdy_parse_method },
373
- { 0, 6, "scheme", ngx_http_spdy_parse_scheme },
374
- { 0, 4, "host", ngx_http_spdy_parse_host },
375
- { 0, 4, "path", ngx_http_spdy_parse_path },
376
- { 0, 7, "version", ngx_http_spdy_parse_version },
377
- };
378
-
379
- #define NGX_SPDY_REQUEST_HEADERS \
380
- (sizeof(ngx_http_spdy_request_headers) \
381
- / sizeof(ngx_http_spdy_request_header_t))
382
-
383
-
384
- void
385
- ngx_http_spdy_init(ngx_event_t *rev)
386
- {
387
- int rc;
388
- ngx_connection_t *c;
389
- ngx_pool_cleanup_t *cln;
390
- ngx_http_connection_t *hc;
391
- ngx_http_spdy_srv_conf_t *sscf;
392
- ngx_http_spdy_main_conf_t *smcf;
393
- ngx_http_spdy_connection_t *sc;
394
-
395
- c = rev->data;
396
- hc = c->data;
397
-
398
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "init spdy request");
399
-
400
- c->log->action = "processing SPDY";
401
-
402
- smcf = ngx_http_get_module_main_conf(hc->conf_ctx, ngx_http_spdy_module);
403
-
404
- if (smcf->recv_buffer == NULL) {
405
- smcf->recv_buffer = ngx_palloc(ngx_cycle->pool, smcf->recv_buffer_size);
406
- if (smcf->recv_buffer == NULL) {
407
- ngx_http_close_connection(c);
408
- return;
409
- }
410
- }
411
-
412
- sc = ngx_pcalloc(c->pool, sizeof(ngx_http_spdy_connection_t));
413
- if (sc == NULL) {
414
- ngx_http_close_connection(c);
415
- return;
416
- }
417
-
418
- sc->connection = c;
419
- sc->http_connection = hc;
420
-
421
- sc->send_window = NGX_SPDY_CONNECTION_WINDOW;
422
- sc->recv_window = NGX_SPDY_CONNECTION_WINDOW;
423
-
424
- sc->init_window = NGX_SPDY_INIT_STREAM_WINDOW;
425
-
426
- sc->handler = hc->proxy_protocol ? ngx_http_spdy_proxy_protocol
427
- : ngx_http_spdy_state_head;
428
-
429
- sc->zstream_in.zalloc = ngx_http_spdy_zalloc;
430
- sc->zstream_in.zfree = ngx_http_spdy_zfree;
431
- sc->zstream_in.opaque = sc;
432
-
433
- rc = inflateInit(&sc->zstream_in);
434
- if (rc != Z_OK) {
435
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
436
- "inflateInit() failed: %d", rc);
437
- ngx_http_close_connection(c);
438
- return;
439
- }
440
-
441
- sc->zstream_out.zalloc = ngx_http_spdy_zalloc;
442
- sc->zstream_out.zfree = ngx_http_spdy_zfree;
443
- sc->zstream_out.opaque = sc;
444
-
445
- sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_spdy_module);
446
-
447
- rc = deflateInit2(&sc->zstream_out, (int) sscf->headers_comp,
448
- Z_DEFLATED, 11, 4, Z_DEFAULT_STRATEGY);
449
-
450
- if (rc != Z_OK) {
451
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
452
- "deflateInit2() failed: %d", rc);
453
- ngx_http_close_connection(c);
454
- return;
455
- }
456
-
457
- rc = deflateSetDictionary(&sc->zstream_out, ngx_http_spdy_dict,
458
- sizeof(ngx_http_spdy_dict));
459
- if (rc != Z_OK) {
460
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
461
- "deflateSetDictionary() failed: %d", rc);
462
- ngx_http_close_connection(c);
463
- return;
464
- }
465
-
466
- sc->pool = ngx_create_pool(sscf->pool_size, sc->connection->log);
467
- if (sc->pool == NULL) {
468
- ngx_http_close_connection(c);
469
- return;
470
- }
471
-
472
- cln = ngx_pool_cleanup_add(c->pool, sizeof(ngx_pool_cleanup_file_t));
473
- if (cln == NULL) {
474
- ngx_http_close_connection(c);
475
- return;
476
- }
477
-
478
- cln->handler = ngx_http_spdy_pool_cleanup;
479
- cln->data = sc;
480
-
481
- sc->streams_index = ngx_pcalloc(sc->pool,
482
- ngx_http_spdy_streams_index_size(sscf)
483
- * sizeof(ngx_http_spdy_stream_t *));
484
- if (sc->streams_index == NULL) {
485
- ngx_http_close_connection(c);
486
- return;
487
- }
488
-
489
- if (ngx_http_spdy_send_settings(sc) == NGX_ERROR) {
490
- ngx_http_close_connection(c);
491
- return;
492
- }
493
-
494
- if (ngx_http_spdy_send_window_update(sc, 0, NGX_SPDY_MAX_WINDOW
495
- - sc->recv_window)
496
- == NGX_ERROR)
497
- {
498
- ngx_http_close_connection(c);
499
- return;
500
- }
501
-
502
- sc->recv_window = NGX_SPDY_MAX_WINDOW;
503
-
504
- ngx_queue_init(&sc->waiting);
505
- ngx_queue_init(&sc->posted);
506
-
507
- c->data = sc;
508
-
509
- rev->handler = ngx_http_spdy_read_handler;
510
- c->write->handler = ngx_http_spdy_write_handler;
511
-
512
- ngx_http_spdy_read_handler(rev);
513
- }
514
-
515
-
516
- static void
517
- ngx_http_spdy_read_handler(ngx_event_t *rev)
518
- {
519
- u_char *p, *end;
520
- size_t available;
521
- ssize_t n;
522
- ngx_connection_t *c;
523
- ngx_http_spdy_main_conf_t *smcf;
524
- ngx_http_spdy_connection_t *sc;
525
-
526
- c = rev->data;
527
- sc = c->data;
528
-
529
- if (rev->timedout) {
530
- ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
531
- ngx_http_spdy_finalize_connection(sc, NGX_HTTP_REQUEST_TIME_OUT);
532
- return;
533
- }
534
-
535
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "spdy read handler");
536
-
537
- sc->blocked = 1;
538
-
539
- smcf = ngx_http_get_module_main_conf(sc->http_connection->conf_ctx,
540
- ngx_http_spdy_module);
541
-
542
- available = smcf->recv_buffer_size - 2 * NGX_SPDY_STATE_BUFFER_SIZE;
543
-
544
- do {
545
- p = smcf->recv_buffer;
546
-
547
- ngx_memcpy(p, sc->buffer, NGX_SPDY_STATE_BUFFER_SIZE);
548
- end = p + sc->buffer_used;
549
-
550
- n = c->recv(c, end, available);
551
-
552
- if (n == NGX_AGAIN) {
553
- break;
554
- }
555
-
556
- if (n == 0 && (sc->incomplete || sc->processing)) {
557
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
558
- "client prematurely closed connection");
559
- }
560
-
561
- if (n == 0 || n == NGX_ERROR) {
562
- ngx_http_spdy_finalize_connection(sc,
563
- NGX_HTTP_CLIENT_CLOSED_REQUEST);
564
- return;
565
- }
566
-
567
- end += n;
568
-
569
- sc->buffer_used = 0;
570
- sc->incomplete = 0;
571
-
572
- do {
573
- p = sc->handler(sc, p, end);
574
-
575
- if (p == NULL) {
576
- return;
577
- }
578
-
579
- } while (p != end);
580
-
581
- } while (rev->ready);
582
-
583
- if (ngx_handle_read_event(rev, 0) != NGX_OK) {
584
- ngx_http_spdy_finalize_connection(sc, NGX_HTTP_INTERNAL_SERVER_ERROR);
585
- return;
586
- }
587
-
588
- if (sc->last_out && ngx_http_spdy_send_output_queue(sc) == NGX_ERROR) {
589
- ngx_http_spdy_finalize_connection(sc, NGX_HTTP_CLIENT_CLOSED_REQUEST);
590
- return;
591
- }
592
-
593
- sc->blocked = 0;
594
-
595
- if (sc->processing) {
596
- if (rev->timer_set) {
597
- ngx_del_timer(rev);
598
- }
599
- return;
600
- }
601
-
602
- ngx_http_spdy_handle_connection(sc);
603
- }
604
-
605
-
606
- static void
607
- ngx_http_spdy_write_handler(ngx_event_t *wev)
608
- {
609
- ngx_int_t rc;
610
- ngx_queue_t *q;
611
- ngx_connection_t *c;
612
- ngx_http_spdy_stream_t *stream;
613
- ngx_http_spdy_connection_t *sc;
614
-
615
- c = wev->data;
616
- sc = c->data;
617
-
618
- if (wev->timedout) {
619
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
620
- "spdy write event timed out");
621
- ngx_http_spdy_finalize_connection(sc, NGX_HTTP_CLIENT_CLOSED_REQUEST);
622
- return;
623
- }
624
-
625
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "spdy write handler");
626
-
627
- sc->blocked = 1;
628
-
629
- rc = ngx_http_spdy_send_output_queue(sc);
630
-
631
- if (rc == NGX_ERROR) {
632
- ngx_http_spdy_finalize_connection(sc, NGX_HTTP_CLIENT_CLOSED_REQUEST);
633
- return;
634
- }
635
-
636
- while (!ngx_queue_empty(&sc->posted)) {
637
- q = ngx_queue_head(&sc->posted);
638
-
639
- ngx_queue_remove(q);
640
-
641
- stream = ngx_queue_data(q, ngx_http_spdy_stream_t, queue);
642
-
643
- stream->handled = 0;
644
-
645
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
646
- "run spdy stream %ui", stream->id);
647
-
648
- wev = stream->request->connection->write;
649
- wev->handler(wev);
650
- }
651
-
652
- sc->blocked = 0;
653
-
654
- if (rc == NGX_AGAIN) {
655
- return;
656
- }
657
-
658
- ngx_http_spdy_handle_connection(sc);
659
- }
660
-
661
-
662
- ngx_int_t
663
- ngx_http_spdy_send_output_queue(ngx_http_spdy_connection_t *sc)
664
- {
665
- int tcp_nodelay;
666
- ngx_chain_t *cl;
667
- ngx_event_t *wev;
668
- ngx_connection_t *c;
669
- ngx_http_core_loc_conf_t *clcf;
670
- ngx_http_spdy_out_frame_t *out, *frame, *fn;
671
-
672
- c = sc->connection;
673
-
674
- if (c->error) {
675
- return NGX_ERROR;
676
- }
677
-
678
- wev = c->write;
679
-
680
- if (!wev->ready) {
681
- return NGX_OK;
682
- }
683
-
684
- cl = NULL;
685
- out = NULL;
686
-
687
- for (frame = sc->last_out; frame; frame = fn) {
688
- frame->last->next = cl;
689
- cl = frame->first;
690
-
691
- fn = frame->next;
692
- frame->next = out;
693
- out = frame;
694
-
695
- ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0,
696
- "spdy frame out: %p sid:%ui prio:%ui bl:%d len:%uz",
697
- out, out->stream ? out->stream->id : 0, out->priority,
698
- out->blocked, out->length);
699
- }
700
-
701
- cl = c->send_chain(c, cl, 0);
702
-
703
- if (cl == NGX_CHAIN_ERROR) {
704
- goto error;
705
- }
706
-
707
- clcf = ngx_http_get_module_loc_conf(sc->http_connection->conf_ctx,
708
- ngx_http_core_module);
709
-
710
- if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
711
- goto error;
712
- }
713
-
714
- if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
715
- if (ngx_tcp_push(c->fd) == -1) {
716
- ngx_connection_error(c, ngx_socket_errno, ngx_tcp_push_n " failed");
717
- goto error;
718
- }
719
-
720
- c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
721
- tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;
722
-
723
- } else {
724
- tcp_nodelay = 1;
725
- }
726
-
727
- if (tcp_nodelay
728
- && clcf->tcp_nodelay
729
- && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
730
- {
731
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
732
-
733
- if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
734
- (const void *) &tcp_nodelay, sizeof(int))
735
- == -1)
736
- {
737
- #if (NGX_SOLARIS)
738
- /* Solaris returns EINVAL if a socket has been shut down */
739
- c->log_error = NGX_ERROR_IGNORE_EINVAL;
740
- #endif
741
-
742
- ngx_connection_error(c, ngx_socket_errno,
743
- "setsockopt(TCP_NODELAY) failed");
744
-
745
- c->log_error = NGX_ERROR_INFO;
746
- goto error;
747
- }
748
-
749
- c->tcp_nodelay = NGX_TCP_NODELAY_SET;
750
- }
751
-
752
- if (cl) {
753
- ngx_add_timer(wev, clcf->send_timeout);
754
-
755
- } else {
756
- if (wev->timer_set) {
757
- ngx_del_timer(wev);
758
- }
759
- }
760
-
761
- for ( /* void */ ; out; out = fn) {
762
- fn = out->next;
763
-
764
- if (out->handler(sc, out) != NGX_OK) {
765
- out->blocked = 1;
766
- out->priority = NGX_SPDY_HIGHEST_PRIORITY;
767
- break;
768
- }
769
-
770
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0,
771
- "spdy frame sent: %p sid:%ui bl:%d len:%uz",
772
- out, out->stream ? out->stream->id : 0,
773
- out->blocked, out->length);
774
- }
775
-
776
- frame = NULL;
777
-
778
- for ( /* void */ ; out; out = fn) {
779
- fn = out->next;
780
- out->next = frame;
781
- frame = out;
782
- }
783
-
784
- sc->last_out = frame;
785
-
786
- return NGX_OK;
787
-
788
- error:
789
-
790
- c->error = 1;
791
-
792
- if (!sc->blocked) {
793
- ngx_post_event(wev, &ngx_posted_events);
794
- }
795
-
796
- return NGX_ERROR;
797
- }
798
-
799
-
800
- static void
801
- ngx_http_spdy_handle_connection(ngx_http_spdy_connection_t *sc)
802
- {
803
- ngx_connection_t *c;
804
- ngx_http_spdy_srv_conf_t *sscf;
805
-
806
- if (sc->last_out || sc->processing) {
807
- return;
808
- }
809
-
810
- c = sc->connection;
811
-
812
- if (c->error) {
813
- ngx_http_close_connection(c);
814
- return;
815
- }
816
-
817
- if (c->buffered) {
818
- return;
819
- }
820
-
821
- sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
822
- ngx_http_spdy_module);
823
- if (sc->incomplete) {
824
- ngx_add_timer(c->read, sscf->recv_timeout);
825
- return;
826
- }
827
-
828
- if (ngx_terminate || ngx_exiting) {
829
- ngx_http_close_connection(c);
830
- return;
831
- }
832
-
833
- ngx_destroy_pool(sc->pool);
834
-
835
- sc->pool = NULL;
836
- sc->free_ctl_frames = NULL;
837
- sc->free_fake_connections = NULL;
838
-
839
- #if (NGX_HTTP_SSL)
840
- if (c->ssl) {
841
- ngx_ssl_free_buffer(c);
842
- }
843
- #endif
844
-
845
- c->destroyed = 1;
846
- c->idle = 1;
847
- ngx_reusable_connection(c, 1);
848
-
849
- c->write->handler = ngx_http_empty_handler;
850
- c->read->handler = ngx_http_spdy_keepalive_handler;
851
-
852
- if (c->write->timer_set) {
853
- ngx_del_timer(c->write);
854
- }
855
-
856
- ngx_add_timer(c->read, sscf->keepalive_timeout);
857
- }
858
-
859
-
860
- static u_char *
861
- ngx_http_spdy_proxy_protocol(ngx_http_spdy_connection_t *sc, u_char *pos,
862
- u_char *end)
863
- {
864
- ngx_log_t *log;
865
-
866
- log = sc->connection->log;
867
- log->action = "reading PROXY protocol";
868
-
869
- pos = ngx_proxy_protocol_parse(sc->connection, pos, end);
870
-
871
- log->action = "processing SPDY";
872
-
873
- if (pos == NULL) {
874
- return ngx_http_spdy_state_protocol_error(sc);
875
- }
876
-
877
- return ngx_http_spdy_state_complete(sc, pos, end);
878
- }
879
-
880
-
881
- static u_char *
882
- ngx_http_spdy_state_head(ngx_http_spdy_connection_t *sc, u_char *pos,
883
- u_char *end)
884
- {
885
- uint32_t head, flen;
886
- ngx_uint_t type;
887
-
888
- if (end - pos < NGX_SPDY_FRAME_HEADER_SIZE) {
889
- return ngx_http_spdy_state_save(sc, pos, end,
890
- ngx_http_spdy_state_head);
891
- }
892
-
893
- head = ngx_spdy_frame_parse_uint32(pos);
894
-
895
- pos += sizeof(uint32_t);
896
-
897
- flen = ngx_spdy_frame_parse_uint32(pos);
898
-
899
- sc->flags = ngx_spdy_frame_flags(flen);
900
- sc->length = ngx_spdy_frame_length(flen);
901
-
902
- pos += sizeof(uint32_t);
903
-
904
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
905
- "process spdy frame head:%08XD f:%Xd l:%uz",
906
- head, sc->flags, sc->length);
907
-
908
- if (ngx_spdy_ctl_frame_check(head)) {
909
- type = ngx_spdy_ctl_frame_type(head);
910
-
911
- switch (type) {
912
-
913
- case NGX_SPDY_SYN_STREAM:
914
- return ngx_http_spdy_state_syn_stream(sc, pos, end);
915
-
916
- case NGX_SPDY_SYN_REPLY:
917
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
918
- "client sent unexpected SYN_REPLY frame");
919
- return ngx_http_spdy_state_protocol_error(sc);
920
-
921
- case NGX_SPDY_RST_STREAM:
922
- return ngx_http_spdy_state_rst_stream(sc, pos, end);
923
-
924
- case NGX_SPDY_SETTINGS:
925
- return ngx_http_spdy_state_settings(sc, pos, end);
926
-
927
- case NGX_SPDY_PING:
928
- return ngx_http_spdy_state_ping(sc, pos, end);
929
-
930
- case NGX_SPDY_GOAWAY:
931
- return ngx_http_spdy_state_skip(sc, pos, end); /* TODO */
932
-
933
- case NGX_SPDY_HEADERS:
934
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
935
- "client sent unexpected HEADERS frame");
936
- return ngx_http_spdy_state_protocol_error(sc);
937
-
938
- case NGX_SPDY_WINDOW_UPDATE:
939
- return ngx_http_spdy_state_window_update(sc, pos, end);
940
-
941
- default:
942
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
943
- "spdy control frame with unknown type %ui", type);
944
- return ngx_http_spdy_state_skip(sc, pos, end);
945
- }
946
- }
947
-
948
- if (ngx_spdy_data_frame_check(head)) {
949
- sc->stream = ngx_http_spdy_get_stream_by_id(sc, head);
950
- return ngx_http_spdy_state_data(sc, pos, end);
951
- }
952
-
953
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
954
- "client sent invalid frame");
955
-
956
- return ngx_http_spdy_state_protocol_error(sc);
957
- }
958
-
959
-
960
- static u_char *
961
- ngx_http_spdy_state_syn_stream(ngx_http_spdy_connection_t *sc, u_char *pos,
962
- u_char *end)
963
- {
964
- ngx_uint_t sid, prio;
965
- ngx_http_spdy_stream_t *stream;
966
- ngx_http_spdy_srv_conf_t *sscf;
967
-
968
- if (end - pos < NGX_SPDY_SYN_STREAM_SIZE) {
969
- return ngx_http_spdy_state_save(sc, pos, end,
970
- ngx_http_spdy_state_syn_stream);
971
- }
972
-
973
- if (sc->length <= NGX_SPDY_SYN_STREAM_SIZE) {
974
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
975
- "client sent SYN_STREAM frame with incorrect length %uz",
976
- sc->length);
977
-
978
- return ngx_http_spdy_state_protocol_error(sc);
979
- }
980
-
981
- sc->length -= NGX_SPDY_SYN_STREAM_SIZE;
982
-
983
- sid = ngx_spdy_frame_parse_sid(pos);
984
- prio = pos[8] >> 5;
985
-
986
- pos += NGX_SPDY_SYN_STREAM_SIZE;
987
-
988
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
989
- "spdy SYN_STREAM frame sid:%ui prio:%ui", sid, prio);
990
-
991
- if (sid % 2 == 0 || sid <= sc->last_sid) {
992
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
993
- "client sent SYN_STREAM frame "
994
- "with invalid Stream-ID %ui", sid);
995
-
996
- stream = ngx_http_spdy_get_stream_by_id(sc, sid);
997
-
998
- if (stream) {
999
- if (ngx_http_spdy_terminate_stream(sc, stream,
1000
- NGX_SPDY_PROTOCOL_ERROR)
1001
- != NGX_OK)
1002
- {
1003
- return ngx_http_spdy_state_internal_error(sc);
1004
- }
1005
- }
1006
-
1007
- return ngx_http_spdy_state_protocol_error(sc);
1008
- }
1009
-
1010
- sc->last_sid = sid;
1011
-
1012
- sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
1013
- ngx_http_spdy_module);
1014
-
1015
- if (sc->processing >= sscf->concurrent_streams) {
1016
-
1017
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
1018
- "concurrent streams exceeded %ui", sc->processing);
1019
-
1020
- if (ngx_http_spdy_send_rst_stream(sc, sid, NGX_SPDY_REFUSED_STREAM,
1021
- prio)
1022
- != NGX_OK)
1023
- {
1024
- return ngx_http_spdy_state_internal_error(sc);
1025
- }
1026
-
1027
- return ngx_http_spdy_state_headers_skip(sc, pos, end);
1028
- }
1029
-
1030
- stream = ngx_http_spdy_create_stream(sc, sid, prio);
1031
- if (stream == NULL) {
1032
- return ngx_http_spdy_state_internal_error(sc);
1033
- }
1034
-
1035
- stream->in_closed = (sc->flags & NGX_SPDY_FLAG_FIN) ? 1 : 0;
1036
-
1037
- stream->request->request_length = NGX_SPDY_FRAME_HEADER_SIZE
1038
- + NGX_SPDY_SYN_STREAM_SIZE
1039
- + sc->length;
1040
-
1041
- sc->stream = stream;
1042
-
1043
- return ngx_http_spdy_state_headers(sc, pos, end);
1044
- }
1045
-
1046
-
1047
- static u_char *
1048
- ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
1049
- u_char *end)
1050
- {
1051
- int z;
1052
- size_t size;
1053
- ngx_buf_t *buf;
1054
- ngx_int_t rc;
1055
- ngx_http_request_t *r;
1056
-
1057
- size = end - pos;
1058
-
1059
- if (size == 0) {
1060
- return ngx_http_spdy_state_save(sc, pos, end,
1061
- ngx_http_spdy_state_headers);
1062
- }
1063
-
1064
- if (size > sc->length) {
1065
- size = sc->length;
1066
- }
1067
-
1068
- r = sc->stream->request;
1069
-
1070
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1071
- "process spdy header block %uz of %uz", size, sc->length);
1072
-
1073
- buf = r->header_in;
1074
-
1075
- sc->zstream_in.next_in = pos;
1076
- sc->zstream_in.avail_in = size;
1077
- sc->zstream_in.next_out = buf->last;
1078
-
1079
- /* one byte is reserved for null-termination of the last header value */
1080
- sc->zstream_in.avail_out = buf->end - buf->last - 1;
1081
-
1082
- z = inflate(&sc->zstream_in, Z_NO_FLUSH);
1083
-
1084
- if (z == Z_NEED_DICT) {
1085
- z = inflateSetDictionary(&sc->zstream_in, ngx_http_spdy_dict,
1086
- sizeof(ngx_http_spdy_dict));
1087
-
1088
- if (z != Z_OK) {
1089
- if (z == Z_DATA_ERROR) {
1090
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1091
- "client sent SYN_STREAM frame with header "
1092
- "block encoded using wrong dictionary: %ul",
1093
- (u_long) sc->zstream_in.adler);
1094
-
1095
- return ngx_http_spdy_state_protocol_error(sc);
1096
- }
1097
-
1098
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1099
- "inflateSetDictionary() failed: %d", z);
1100
-
1101
- return ngx_http_spdy_state_internal_error(sc);
1102
- }
1103
-
1104
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1105
- "spdy inflateSetDictionary(): %d", z);
1106
-
1107
- z = sc->zstream_in.avail_in ? inflate(&sc->zstream_in, Z_NO_FLUSH)
1108
- : Z_OK;
1109
- }
1110
-
1111
- ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1112
- "spdy inflate out: ni:%p no:%p ai:%ud ao:%ud rc:%d",
1113
- sc->zstream_in.next_in, sc->zstream_in.next_out,
1114
- sc->zstream_in.avail_in, sc->zstream_in.avail_out,
1115
- z);
1116
-
1117
- if (z != Z_OK) {
1118
- return ngx_http_spdy_state_inflate_error(sc, z);
1119
- }
1120
-
1121
- sc->length -= sc->zstream_in.next_in - pos;
1122
- pos = sc->zstream_in.next_in;
1123
-
1124
- buf->last = sc->zstream_in.next_out;
1125
-
1126
- if (r->headers_in.headers.part.elts == NULL) {
1127
-
1128
- if (buf->last - buf->pos < NGX_SPDY_NV_NUM_SIZE) {
1129
-
1130
- if (sc->length == 0) {
1131
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1132
- "premature end of spdy header block");
1133
-
1134
- return ngx_http_spdy_state_headers_error(sc, pos, end);
1135
- }
1136
-
1137
- return ngx_http_spdy_state_save(sc, pos, end,
1138
- ngx_http_spdy_state_headers);
1139
- }
1140
-
1141
- sc->entries = ngx_spdy_frame_parse_uint32(buf->pos);
1142
-
1143
- buf->pos += NGX_SPDY_NV_NUM_SIZE;
1144
-
1145
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1146
- "spdy header block has %ui entries",
1147
- sc->entries);
1148
-
1149
- if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
1150
- sizeof(ngx_table_elt_t))
1151
- != NGX_OK)
1152
- {
1153
- ngx_http_spdy_close_stream(sc->stream,
1154
- NGX_HTTP_INTERNAL_SERVER_ERROR);
1155
- return ngx_http_spdy_state_headers_skip(sc, pos, end);
1156
- }
1157
-
1158
- if (ngx_array_init(&r->headers_in.cookies, r->pool, 2,
1159
- sizeof(ngx_table_elt_t *))
1160
- != NGX_OK)
1161
- {
1162
- ngx_http_spdy_close_stream(sc->stream,
1163
- NGX_HTTP_INTERNAL_SERVER_ERROR);
1164
- return ngx_http_spdy_state_headers_skip(sc, pos, end);
1165
- }
1166
- }
1167
-
1168
- while (sc->entries) {
1169
-
1170
- rc = ngx_http_spdy_parse_header(r);
1171
-
1172
- switch (rc) {
1173
-
1174
- case NGX_DONE:
1175
- sc->entries--;
1176
-
1177
- case NGX_OK:
1178
- break;
1179
-
1180
- case NGX_AGAIN:
1181
-
1182
- if (sc->zstream_in.avail_in) {
1183
-
1184
- rc = ngx_http_spdy_alloc_large_header_buffer(r);
1185
-
1186
- if (rc == NGX_DECLINED) {
1187
- ngx_http_finalize_request(r,
1188
- NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
1189
- return ngx_http_spdy_state_headers_skip(sc, pos, end);
1190
- }
1191
-
1192
- if (rc != NGX_OK) {
1193
- ngx_http_spdy_close_stream(sc->stream,
1194
- NGX_HTTP_INTERNAL_SERVER_ERROR);
1195
- return ngx_http_spdy_state_headers_skip(sc, pos, end);
1196
- }
1197
-
1198
- /* null-terminate the last processed header name or value */
1199
- *buf->pos = '\0';
1200
-
1201
- buf = r->header_in;
1202
-
1203
- sc->zstream_in.next_out = buf->last;
1204
-
1205
- /* one byte is reserved for null-termination */
1206
- sc->zstream_in.avail_out = buf->end - buf->last - 1;
1207
-
1208
- z = inflate(&sc->zstream_in, Z_NO_FLUSH);
1209
-
1210
- ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1211
- "spdy inflate out: ni:%p no:%p ai:%ud ao:%ud rc:%d",
1212
- sc->zstream_in.next_in, sc->zstream_in.next_out,
1213
- sc->zstream_in.avail_in, sc->zstream_in.avail_out,
1214
- z);
1215
-
1216
- if (z != Z_OK) {
1217
- return ngx_http_spdy_state_inflate_error(sc, z);
1218
- }
1219
-
1220
- sc->length -= sc->zstream_in.next_in - pos;
1221
- pos = sc->zstream_in.next_in;
1222
-
1223
- buf->last = sc->zstream_in.next_out;
1224
-
1225
- continue;
1226
- }
1227
-
1228
- if (sc->length == 0) {
1229
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1230
- "premature end of spdy header block");
1231
-
1232
- return ngx_http_spdy_state_headers_error(sc, pos, end);
1233
- }
1234
-
1235
- return ngx_http_spdy_state_save(sc, pos, end,
1236
- ngx_http_spdy_state_headers);
1237
-
1238
- case NGX_HTTP_PARSE_INVALID_HEADER:
1239
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
1240
- return ngx_http_spdy_state_headers_skip(sc, pos, end);
1241
-
1242
- default: /* NGX_ERROR */
1243
- return ngx_http_spdy_state_headers_error(sc, pos, end);
1244
- }
1245
-
1246
- /* a header line has been parsed successfully */
1247
-
1248
- rc = ngx_http_spdy_handle_request_header(r);
1249
-
1250
- if (rc != NGX_OK) {
1251
- if (rc == NGX_HTTP_PARSE_INVALID_HEADER) {
1252
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
1253
- return ngx_http_spdy_state_headers_skip(sc, pos, end);
1254
- }
1255
-
1256
- if (rc != NGX_ABORT) {
1257
- ngx_http_spdy_close_stream(sc->stream,
1258
- NGX_HTTP_INTERNAL_SERVER_ERROR);
1259
- }
1260
-
1261
- return ngx_http_spdy_state_headers_skip(sc, pos, end);
1262
- }
1263
- }
1264
-
1265
- if (buf->pos != buf->last || sc->zstream_in.avail_in) {
1266
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1267
- "incorrect number of spdy header block entries");
1268
-
1269
- return ngx_http_spdy_state_headers_error(sc, pos, end);
1270
- }
1271
-
1272
- if (sc->length) {
1273
- return ngx_http_spdy_state_save(sc, pos, end,
1274
- ngx_http_spdy_state_headers);
1275
- }
1276
-
1277
- /* null-terminate the last header value */
1278
- *buf->pos = '\0';
1279
-
1280
- ngx_http_spdy_run_request(r);
1281
-
1282
- return ngx_http_spdy_state_complete(sc, pos, end);
1283
- }
1284
-
1285
-
1286
- static u_char *
1287
- ngx_http_spdy_state_headers_skip(ngx_http_spdy_connection_t *sc, u_char *pos,
1288
- u_char *end)
1289
- {
1290
- int n;
1291
- size_t size;
1292
- u_char buffer[NGX_SPDY_SKIP_HEADERS_BUFFER_SIZE];
1293
-
1294
- if (sc->length == 0) {
1295
- return ngx_http_spdy_state_complete(sc, pos, end);
1296
- }
1297
-
1298
- size = end - pos;
1299
-
1300
- if (size == 0) {
1301
- return ngx_http_spdy_state_save(sc, pos, end,
1302
- ngx_http_spdy_state_headers_skip);
1303
- }
1304
-
1305
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1306
- "spdy header block skip %uz of %uz", size, sc->length);
1307
-
1308
- sc->zstream_in.next_in = pos;
1309
- sc->zstream_in.avail_in = (size < sc->length) ? size : sc->length;
1310
-
1311
- while (sc->zstream_in.avail_in) {
1312
- sc->zstream_in.next_out = buffer;
1313
- sc->zstream_in.avail_out = NGX_SPDY_SKIP_HEADERS_BUFFER_SIZE;
1314
-
1315
- n = inflate(&sc->zstream_in, Z_NO_FLUSH);
1316
-
1317
- ngx_log_debug5(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1318
- "spdy inflate out: ni:%p no:%p ai:%ud ao:%ud rc:%d",
1319
- sc->zstream_in.next_in, sc->zstream_in.next_out,
1320
- sc->zstream_in.avail_in, sc->zstream_in.avail_out,
1321
- n);
1322
-
1323
- if (n != Z_OK) {
1324
- return ngx_http_spdy_state_inflate_error(sc, n);
1325
- }
1326
- }
1327
-
1328
- pos = sc->zstream_in.next_in;
1329
-
1330
- if (size < sc->length) {
1331
- sc->length -= size;
1332
- return ngx_http_spdy_state_save(sc, pos, end,
1333
- ngx_http_spdy_state_headers_skip);
1334
- }
1335
-
1336
- return ngx_http_spdy_state_complete(sc, pos, end);
1337
- }
1338
-
1339
-
1340
- static u_char *
1341
- ngx_http_spdy_state_headers_error(ngx_http_spdy_connection_t *sc, u_char *pos,
1342
- u_char *end)
1343
- {
1344
- ngx_http_spdy_stream_t *stream;
1345
-
1346
- stream = sc->stream;
1347
-
1348
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
1349
- "client sent SYN_STREAM frame for stream %ui "
1350
- "with invalid header block", stream->id);
1351
-
1352
- if (ngx_http_spdy_send_rst_stream(sc, stream->id, NGX_SPDY_PROTOCOL_ERROR,
1353
- stream->priority)
1354
- != NGX_OK)
1355
- {
1356
- return ngx_http_spdy_state_internal_error(sc);
1357
- }
1358
-
1359
- stream->out_closed = 1;
1360
-
1361
- ngx_http_spdy_close_stream(stream, NGX_HTTP_BAD_REQUEST);
1362
-
1363
- return ngx_http_spdy_state_headers_skip(sc, pos, end);
1364
- }
1365
-
1366
-
1367
- static u_char *
1368
- ngx_http_spdy_state_window_update(ngx_http_spdy_connection_t *sc, u_char *pos,
1369
- u_char *end)
1370
- {
1371
- size_t delta;
1372
- ngx_uint_t sid;
1373
- ngx_event_t *wev;
1374
- ngx_queue_t *q;
1375
- ngx_http_spdy_stream_t *stream;
1376
-
1377
- if (end - pos < NGX_SPDY_WINDOW_UPDATE_SIZE) {
1378
- return ngx_http_spdy_state_save(sc, pos, end,
1379
- ngx_http_spdy_state_window_update);
1380
- }
1381
-
1382
- if (sc->length != NGX_SPDY_WINDOW_UPDATE_SIZE) {
1383
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
1384
- "client sent WINDOW_UPDATE frame "
1385
- "with incorrect length %uz", sc->length);
1386
-
1387
- return ngx_http_spdy_state_protocol_error(sc);
1388
- }
1389
-
1390
- sid = ngx_spdy_frame_parse_sid(pos);
1391
-
1392
- pos += NGX_SPDY_SID_SIZE;
1393
-
1394
- delta = ngx_spdy_frame_parse_delta(pos);
1395
-
1396
- pos += NGX_SPDY_DELTA_SIZE;
1397
-
1398
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1399
- "spdy WINDOW_UPDATE sid:%ui delta:%uz", sid, delta);
1400
-
1401
- if (sid) {
1402
- stream = ngx_http_spdy_get_stream_by_id(sc, sid);
1403
-
1404
- if (stream == NULL) {
1405
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1406
- "unknown spdy stream");
1407
-
1408
- return ngx_http_spdy_state_complete(sc, pos, end);
1409
- }
1410
-
1411
- if (stream->send_window > (ssize_t) (NGX_SPDY_MAX_WINDOW - delta)) {
1412
-
1413
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
1414
- "client violated flow control for stream %ui: "
1415
- "received WINDOW_UPDATE frame with delta %uz "
1416
- "not allowed for window %z",
1417
- sid, delta, stream->send_window);
1418
-
1419
- if (ngx_http_spdy_terminate_stream(sc, stream,
1420
- NGX_SPDY_FLOW_CONTROL_ERROR)
1421
- == NGX_ERROR)
1422
- {
1423
- return ngx_http_spdy_state_internal_error(sc);
1424
- }
1425
-
1426
- return ngx_http_spdy_state_complete(sc, pos, end);
1427
- }
1428
-
1429
- stream->send_window += delta;
1430
-
1431
- if (stream->exhausted) {
1432
- stream->exhausted = 0;
1433
-
1434
- wev = stream->request->connection->write;
1435
-
1436
- if (!wev->timer_set) {
1437
- wev->delayed = 0;
1438
- wev->handler(wev);
1439
- }
1440
- }
1441
-
1442
- } else {
1443
- sc->send_window += delta;
1444
-
1445
- if (sc->send_window > NGX_SPDY_MAX_WINDOW) {
1446
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
1447
- "client violated connection flow control: "
1448
- "received WINDOW_UPDATE frame with delta %uz "
1449
- "not allowed for window %uz",
1450
- delta, sc->send_window);
1451
-
1452
- return ngx_http_spdy_state_protocol_error(sc);
1453
- }
1454
-
1455
- while (!ngx_queue_empty(&sc->waiting)) {
1456
- q = ngx_queue_head(&sc->waiting);
1457
-
1458
- ngx_queue_remove(q);
1459
-
1460
- stream = ngx_queue_data(q, ngx_http_spdy_stream_t, queue);
1461
-
1462
- stream->handled = 0;
1463
-
1464
- wev = stream->request->connection->write;
1465
-
1466
- if (!wev->timer_set) {
1467
- wev->delayed = 0;
1468
- wev->handler(wev);
1469
-
1470
- if (sc->send_window == 0) {
1471
- break;
1472
- }
1473
- }
1474
- }
1475
- }
1476
-
1477
- return ngx_http_spdy_state_complete(sc, pos, end);
1478
- }
1479
-
1480
-
1481
- static u_char *
1482
- ngx_http_spdy_state_data(ngx_http_spdy_connection_t *sc, u_char *pos,
1483
- u_char *end)
1484
- {
1485
- ngx_http_spdy_stream_t *stream;
1486
-
1487
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1488
- "spdy DATA frame");
1489
-
1490
- if (sc->length > sc->recv_window) {
1491
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
1492
- "client violated connection flow control: "
1493
- "received DATA frame length %uz, available window %uz",
1494
- sc->length, sc->recv_window);
1495
-
1496
- return ngx_http_spdy_state_protocol_error(sc);
1497
- }
1498
-
1499
- sc->recv_window -= sc->length;
1500
-
1501
- if (sc->recv_window < NGX_SPDY_MAX_WINDOW / 4) {
1502
-
1503
- if (ngx_http_spdy_send_window_update(sc, 0,
1504
- NGX_SPDY_MAX_WINDOW
1505
- - sc->recv_window)
1506
- == NGX_ERROR)
1507
- {
1508
- return ngx_http_spdy_state_internal_error(sc);
1509
- }
1510
-
1511
- sc->recv_window = NGX_SPDY_MAX_WINDOW;
1512
- }
1513
-
1514
- stream = sc->stream;
1515
-
1516
- if (stream == NULL) {
1517
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1518
- "unknown spdy stream");
1519
-
1520
- return ngx_http_spdy_state_skip(sc, pos, end);
1521
- }
1522
-
1523
- if (sc->length > stream->recv_window) {
1524
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
1525
- "client violated flow control for stream %ui: "
1526
- "received DATA frame length %uz, available window %uz",
1527
- stream->id, sc->length, stream->recv_window);
1528
-
1529
- if (ngx_http_spdy_terminate_stream(sc, stream,
1530
- NGX_SPDY_FLOW_CONTROL_ERROR)
1531
- == NGX_ERROR)
1532
- {
1533
- return ngx_http_spdy_state_internal_error(sc);
1534
- }
1535
-
1536
- return ngx_http_spdy_state_skip(sc, pos, end);
1537
- }
1538
-
1539
- stream->recv_window -= sc->length;
1540
-
1541
- if (stream->recv_window < NGX_SPDY_STREAM_WINDOW / 4) {
1542
-
1543
- if (ngx_http_spdy_send_window_update(sc, stream->id,
1544
- NGX_SPDY_STREAM_WINDOW
1545
- - stream->recv_window)
1546
- == NGX_ERROR)
1547
- {
1548
- return ngx_http_spdy_state_internal_error(sc);
1549
- }
1550
-
1551
- stream->recv_window = NGX_SPDY_STREAM_WINDOW;
1552
- }
1553
-
1554
- if (stream->in_closed) {
1555
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
1556
- "client sent DATA frame for half-closed stream %ui",
1557
- stream->id);
1558
-
1559
- if (ngx_http_spdy_terminate_stream(sc, stream,
1560
- NGX_SPDY_STREAM_ALREADY_CLOSED)
1561
- == NGX_ERROR)
1562
- {
1563
- return ngx_http_spdy_state_internal_error(sc);
1564
- }
1565
-
1566
- return ngx_http_spdy_state_skip(sc, pos, end);
1567
- }
1568
-
1569
- return ngx_http_spdy_state_read_data(sc, pos, end);
1570
- }
1571
-
1572
-
1573
- static u_char *
1574
- ngx_http_spdy_state_read_data(ngx_http_spdy_connection_t *sc, u_char *pos,
1575
- u_char *end)
1576
- {
1577
- size_t size;
1578
- ssize_t n;
1579
- ngx_buf_t *buf;
1580
- ngx_int_t rc;
1581
- ngx_temp_file_t *tf;
1582
- ngx_http_request_t *r;
1583
- ngx_http_spdy_stream_t *stream;
1584
- ngx_http_request_body_t *rb;
1585
- ngx_http_core_loc_conf_t *clcf;
1586
-
1587
- stream = sc->stream;
1588
-
1589
- if (stream == NULL) {
1590
- return ngx_http_spdy_state_skip(sc, pos, end);
1591
- }
1592
-
1593
- if (stream->skip_data) {
1594
-
1595
- if (sc->flags & NGX_SPDY_FLAG_FIN) {
1596
- stream->in_closed = 1;
1597
- }
1598
-
1599
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1600
- "skipping spdy DATA frame, reason: %d",
1601
- stream->skip_data);
1602
-
1603
- return ngx_http_spdy_state_skip(sc, pos, end);
1604
- }
1605
-
1606
- size = end - pos;
1607
-
1608
- if (size > sc->length) {
1609
- size = sc->length;
1610
- }
1611
-
1612
- r = stream->request;
1613
-
1614
- if (r->request_body == NULL
1615
- && ngx_http_spdy_init_request_body(r) != NGX_OK)
1616
- {
1617
- stream->skip_data = NGX_SPDY_DATA_INTERNAL_ERROR;
1618
- return ngx_http_spdy_state_skip(sc, pos, end);
1619
- }
1620
-
1621
- rb = r->request_body;
1622
- tf = rb->temp_file;
1623
- buf = rb->buf;
1624
-
1625
- if (size) {
1626
- rb->rest += size;
1627
-
1628
- if (r->headers_in.content_length_n != -1
1629
- && r->headers_in.content_length_n < rb->rest)
1630
- {
1631
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1632
- "client intended to send body data "
1633
- "larger than declared");
1634
-
1635
- stream->skip_data = NGX_SPDY_DATA_ERROR;
1636
- goto error;
1637
-
1638
- } else {
1639
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1640
-
1641
- if (clcf->client_max_body_size
1642
- && clcf->client_max_body_size < rb->rest)
1643
- {
1644
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1645
- "client intended to send "
1646
- "too large chunked body: %O bytes", rb->rest);
1647
-
1648
- stream->skip_data = NGX_SPDY_DATA_ERROR;
1649
- goto error;
1650
- }
1651
- }
1652
-
1653
- sc->length -= size;
1654
-
1655
- if (tf) {
1656
- buf->start = pos;
1657
- buf->pos = pos;
1658
-
1659
- pos += size;
1660
-
1661
- buf->end = pos;
1662
- buf->last = pos;
1663
-
1664
- n = ngx_write_chain_to_temp_file(tf, rb->bufs);
1665
-
1666
- /* TODO: n == 0 or not complete and level event */
1667
-
1668
- if (n == NGX_ERROR) {
1669
- stream->skip_data = NGX_SPDY_DATA_INTERNAL_ERROR;
1670
- goto error;
1671
- }
1672
-
1673
- tf->offset += n;
1674
-
1675
- } else {
1676
- buf->last = ngx_cpymem(buf->last, pos, size);
1677
- pos += size;
1678
- }
1679
-
1680
- r->request_length += size;
1681
- }
1682
-
1683
- if (sc->length) {
1684
- return ngx_http_spdy_state_save(sc, pos, end,
1685
- ngx_http_spdy_state_read_data);
1686
- }
1687
-
1688
- if (sc->flags & NGX_SPDY_FLAG_FIN) {
1689
-
1690
- stream->in_closed = 1;
1691
-
1692
- if (r->headers_in.content_length_n < 0) {
1693
- r->headers_in.content_length_n = rb->rest;
1694
-
1695
- } else if (r->headers_in.content_length_n != rb->rest) {
1696
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1697
- "client prematurely closed stream: "
1698
- "only %O out of %O bytes of request body received",
1699
- rb->rest, r->headers_in.content_length_n);
1700
-
1701
- stream->skip_data = NGX_SPDY_DATA_ERROR;
1702
- goto error;
1703
- }
1704
-
1705
- if (tf) {
1706
- ngx_memzero(buf, sizeof(ngx_buf_t));
1707
-
1708
- buf->in_file = 1;
1709
- buf->file_last = tf->file.offset;
1710
- buf->file = &tf->file;
1711
-
1712
- rb->buf = NULL;
1713
- }
1714
-
1715
- if (rb->post_handler) {
1716
- r->read_event_handler = ngx_http_block_reading;
1717
- rb->post_handler(r);
1718
- }
1719
- }
1720
-
1721
- return ngx_http_spdy_state_complete(sc, pos, end);
1722
-
1723
- error:
1724
-
1725
- if (rb->post_handler) {
1726
-
1727
- if (stream->skip_data == NGX_SPDY_DATA_ERROR) {
1728
- rc = (r->headers_in.content_length_n == -1)
1729
- ? NGX_HTTP_REQUEST_ENTITY_TOO_LARGE
1730
- : NGX_HTTP_BAD_REQUEST;
1731
-
1732
- } else {
1733
- rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
1734
- }
1735
-
1736
- ngx_http_finalize_request(r, rc);
1737
- }
1738
-
1739
- return ngx_http_spdy_state_skip(sc, pos, end);
1740
- }
1741
-
1742
-
1743
- static u_char *
1744
- ngx_http_spdy_state_rst_stream(ngx_http_spdy_connection_t *sc, u_char *pos,
1745
- u_char *end)
1746
- {
1747
- ngx_uint_t sid, status;
1748
- ngx_event_t *ev;
1749
- ngx_connection_t *fc;
1750
- ngx_http_spdy_stream_t *stream;
1751
-
1752
- if (end - pos < NGX_SPDY_RST_STREAM_SIZE) {
1753
- return ngx_http_spdy_state_save(sc, pos, end,
1754
- ngx_http_spdy_state_rst_stream);
1755
- }
1756
-
1757
- if (sc->length != NGX_SPDY_RST_STREAM_SIZE) {
1758
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
1759
- "client sent RST_STREAM frame with incorrect length %uz",
1760
- sc->length);
1761
-
1762
- return ngx_http_spdy_state_protocol_error(sc);
1763
- }
1764
-
1765
- sid = ngx_spdy_frame_parse_sid(pos);
1766
-
1767
- pos += NGX_SPDY_SID_SIZE;
1768
-
1769
- status = ngx_spdy_frame_parse_uint32(pos);
1770
-
1771
- pos += sizeof(uint32_t);
1772
-
1773
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1774
- "spdy RST_STREAM sid:%ui st:%ui", sid, status);
1775
-
1776
- stream = ngx_http_spdy_get_stream_by_id(sc, sid);
1777
-
1778
- if (stream == NULL) {
1779
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1780
- "unknown spdy stream");
1781
-
1782
- return ngx_http_spdy_state_complete(sc, pos, end);
1783
- }
1784
-
1785
- stream->in_closed = 1;
1786
- stream->out_closed = 1;
1787
-
1788
- fc = stream->request->connection;
1789
- fc->error = 1;
1790
-
1791
- switch (status) {
1792
-
1793
- case NGX_SPDY_CANCEL:
1794
- ngx_log_error(NGX_LOG_INFO, fc->log, 0,
1795
- "client canceled stream %ui", sid);
1796
- break;
1797
-
1798
- case NGX_SPDY_INTERNAL_ERROR:
1799
- ngx_log_error(NGX_LOG_INFO, fc->log, 0,
1800
- "client terminated stream %ui due to internal error",
1801
- sid);
1802
- break;
1803
-
1804
- default:
1805
- ngx_log_error(NGX_LOG_INFO, fc->log, 0,
1806
- "client terminated stream %ui with status %ui",
1807
- sid, status);
1808
- break;
1809
- }
1810
-
1811
- ev = fc->read;
1812
- ev->handler(ev);
1813
-
1814
- return ngx_http_spdy_state_complete(sc, pos, end);
1815
- }
1816
-
1817
-
1818
- static u_char *
1819
- ngx_http_spdy_state_ping(ngx_http_spdy_connection_t *sc, u_char *pos,
1820
- u_char *end)
1821
- {
1822
- u_char *p;
1823
- ngx_buf_t *buf;
1824
- ngx_http_spdy_out_frame_t *frame;
1825
-
1826
- if (end - pos < NGX_SPDY_PING_SIZE) {
1827
- return ngx_http_spdy_state_save(sc, pos, end,
1828
- ngx_http_spdy_state_ping);
1829
- }
1830
-
1831
- if (sc->length != NGX_SPDY_PING_SIZE) {
1832
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
1833
- "client sent PING frame with incorrect length %uz",
1834
- sc->length);
1835
-
1836
- return ngx_http_spdy_state_protocol_error(sc);
1837
- }
1838
-
1839
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1840
- "spdy PING frame");
1841
-
1842
- frame = ngx_http_spdy_get_ctl_frame(sc, NGX_SPDY_PING_SIZE,
1843
- NGX_SPDY_HIGHEST_PRIORITY);
1844
- if (frame == NULL) {
1845
- return ngx_http_spdy_state_internal_error(sc);
1846
- }
1847
-
1848
- buf = frame->first->buf;
1849
-
1850
- p = buf->pos;
1851
-
1852
- p = ngx_spdy_frame_write_head(p, NGX_SPDY_PING);
1853
- p = ngx_spdy_frame_write_flags_and_len(p, 0, NGX_SPDY_PING_SIZE);
1854
-
1855
- p = ngx_cpymem(p, pos, NGX_SPDY_PING_SIZE);
1856
-
1857
- buf->last = p;
1858
-
1859
- ngx_http_spdy_queue_frame(sc, frame);
1860
-
1861
- pos += NGX_SPDY_PING_SIZE;
1862
-
1863
- return ngx_http_spdy_state_complete(sc, pos, end);
1864
- }
1865
-
1866
-
1867
- static u_char *
1868
- ngx_http_spdy_state_skip(ngx_http_spdy_connection_t *sc, u_char *pos,
1869
- u_char *end)
1870
- {
1871
- size_t size;
1872
-
1873
- size = end - pos;
1874
-
1875
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1876
- "spdy frame skip %uz of %uz", size, sc->length);
1877
-
1878
- if (size < sc->length) {
1879
- sc->length -= size;
1880
- return ngx_http_spdy_state_save(sc, end, end,
1881
- ngx_http_spdy_state_skip);
1882
- }
1883
-
1884
- return ngx_http_spdy_state_complete(sc, pos + sc->length, end);
1885
- }
1886
-
1887
-
1888
- static u_char *
1889
- ngx_http_spdy_state_settings(ngx_http_spdy_connection_t *sc, u_char *pos,
1890
- u_char *end)
1891
- {
1892
- ngx_uint_t fid, val;
1893
-
1894
- if (sc->entries == 0) {
1895
-
1896
- if (end - pos < NGX_SPDY_SETTINGS_NUM_SIZE) {
1897
- return ngx_http_spdy_state_save(sc, pos, end,
1898
- ngx_http_spdy_state_settings);
1899
- }
1900
-
1901
- sc->entries = ngx_spdy_frame_parse_uint32(pos);
1902
-
1903
- pos += NGX_SPDY_SETTINGS_NUM_SIZE;
1904
- sc->length -= NGX_SPDY_SETTINGS_NUM_SIZE;
1905
-
1906
- if (sc->length < sc->entries * NGX_SPDY_SETTINGS_PAIR_SIZE) {
1907
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
1908
- "client sent SETTINGS frame with incorrect "
1909
- "length %uz or number of entries %ui",
1910
- sc->length, sc->entries);
1911
-
1912
- return ngx_http_spdy_state_protocol_error(sc);
1913
- }
1914
-
1915
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1916
- "spdy SETTINGS frame has %ui entries", sc->entries);
1917
- }
1918
-
1919
- while (sc->entries) {
1920
- if (end - pos < NGX_SPDY_SETTINGS_PAIR_SIZE) {
1921
- return ngx_http_spdy_state_save(sc, pos, end,
1922
- ngx_http_spdy_state_settings);
1923
- }
1924
-
1925
- sc->entries--;
1926
- sc->length -= NGX_SPDY_SETTINGS_PAIR_SIZE;
1927
-
1928
- fid = ngx_spdy_frame_parse_uint32(pos);
1929
-
1930
- pos += NGX_SPDY_SETTINGS_FID_SIZE;
1931
-
1932
- val = ngx_spdy_frame_parse_uint32(pos);
1933
-
1934
- pos += NGX_SPDY_SETTINGS_VAL_SIZE;
1935
-
1936
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1937
- "spdy SETTINGS entry fl:%ui id:%ui val:%ui",
1938
- ngx_spdy_frame_flags(fid), ngx_spdy_frame_id(fid), val);
1939
-
1940
- if (ngx_spdy_frame_flags(fid) == NGX_SPDY_SETTINGS_FLAG_PERSISTED) {
1941
- continue;
1942
- }
1943
-
1944
- switch (ngx_spdy_frame_id(fid)) {
1945
-
1946
- case NGX_SPDY_SETTINGS_INIT_WINDOW:
1947
-
1948
- if (val > NGX_SPDY_MAX_WINDOW) {
1949
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
1950
- "client sent SETTINGS frame with "
1951
- "incorrect INIT_WINDOW value: %ui", val);
1952
-
1953
- return ngx_http_spdy_state_protocol_error(sc);
1954
- }
1955
-
1956
- if (ngx_http_spdy_adjust_windows(sc, val - sc->init_window)
1957
- != NGX_OK)
1958
- {
1959
- return ngx_http_spdy_state_internal_error(sc);
1960
- }
1961
-
1962
- sc->init_window = val;
1963
-
1964
- continue;
1965
- }
1966
- }
1967
-
1968
- return ngx_http_spdy_state_complete(sc, pos, end);
1969
- }
1970
-
1971
-
1972
- static u_char *
1973
- ngx_http_spdy_state_complete(ngx_http_spdy_connection_t *sc, u_char *pos,
1974
- u_char *end)
1975
- {
1976
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1977
- "spdy frame complete pos:%p end:%p", pos, end);
1978
-
1979
- if (pos > end) {
1980
- ngx_log_error(NGX_LOG_ALERT, sc->connection->log, 0,
1981
- "receive buffer overrun");
1982
-
1983
- ngx_debug_point();
1984
- return ngx_http_spdy_state_internal_error(sc);
1985
- }
1986
-
1987
- sc->handler = ngx_http_spdy_state_head;
1988
- sc->stream = NULL;
1989
-
1990
- return pos;
1991
- }
1992
-
1993
-
1994
- static u_char *
1995
- ngx_http_spdy_state_save(ngx_http_spdy_connection_t *sc,
1996
- u_char *pos, u_char *end, ngx_http_spdy_handler_pt handler)
1997
- {
1998
- size_t size;
1999
-
2000
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
2001
- "spdy frame state save pos:%p end:%p handler:%p",
2002
- pos, end, handler);
2003
-
2004
- size = end - pos;
2005
-
2006
- if (size > NGX_SPDY_STATE_BUFFER_SIZE) {
2007
- ngx_log_error(NGX_LOG_ALERT, sc->connection->log, 0,
2008
- "state buffer overflow: %uz bytes required", size);
2009
-
2010
- ngx_debug_point();
2011
- return ngx_http_spdy_state_internal_error(sc);
2012
- }
2013
-
2014
- ngx_memcpy(sc->buffer, pos, NGX_SPDY_STATE_BUFFER_SIZE);
2015
-
2016
- sc->buffer_used = size;
2017
- sc->handler = handler;
2018
- sc->incomplete = 1;
2019
-
2020
- return end;
2021
- }
2022
-
2023
-
2024
- static u_char *
2025
- ngx_http_spdy_state_inflate_error(ngx_http_spdy_connection_t *sc, int rc)
2026
- {
2027
- if (rc == Z_DATA_ERROR || rc == Z_STREAM_END) {
2028
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
2029
- "client sent SYN_STREAM frame with "
2030
- "corrupted header block, inflate() failed: %d", rc);
2031
-
2032
- return ngx_http_spdy_state_protocol_error(sc);
2033
- }
2034
-
2035
- ngx_log_error(NGX_LOG_ERR, sc->connection->log, 0,
2036
- "inflate() failed: %d", rc);
2037
-
2038
- return ngx_http_spdy_state_internal_error(sc);
2039
- }
2040
-
2041
-
2042
- static u_char *
2043
- ngx_http_spdy_state_protocol_error(ngx_http_spdy_connection_t *sc)
2044
- {
2045
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
2046
- "spdy state protocol error");
2047
-
2048
- if (sc->stream) {
2049
- sc->stream->out_closed = 1;
2050
- ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_BAD_REQUEST);
2051
- }
2052
-
2053
- ngx_http_spdy_finalize_connection(sc, NGX_HTTP_CLIENT_CLOSED_REQUEST);
2054
-
2055
- return NULL;
2056
- }
2057
-
2058
-
2059
- static u_char *
2060
- ngx_http_spdy_state_internal_error(ngx_http_spdy_connection_t *sc)
2061
- {
2062
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
2063
- "spdy state internal error");
2064
-
2065
- if (sc->stream) {
2066
- sc->stream->out_closed = 1;
2067
- ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_INTERNAL_SERVER_ERROR);
2068
- }
2069
-
2070
- ngx_http_spdy_finalize_connection(sc, NGX_HTTP_INTERNAL_SERVER_ERROR);
2071
-
2072
- return NULL;
2073
- }
2074
-
2075
-
2076
- static ngx_int_t
2077
- ngx_http_spdy_send_window_update(ngx_http_spdy_connection_t *sc, ngx_uint_t sid,
2078
- ngx_uint_t delta)
2079
- {
2080
- u_char *p;
2081
- ngx_buf_t *buf;
2082
- ngx_http_spdy_out_frame_t *frame;
2083
-
2084
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
2085
- "spdy send WINDOW_UPDATE sid:%ui delta:%ui", sid, delta);
2086
-
2087
- frame = ngx_http_spdy_get_ctl_frame(sc, NGX_SPDY_WINDOW_UPDATE_SIZE,
2088
- NGX_SPDY_HIGHEST_PRIORITY);
2089
- if (frame == NULL) {
2090
- return NGX_ERROR;
2091
- }
2092
-
2093
- buf = frame->first->buf;
2094
-
2095
- p = buf->pos;
2096
-
2097
- p = ngx_spdy_frame_write_head(p, NGX_SPDY_WINDOW_UPDATE);
2098
- p = ngx_spdy_frame_write_flags_and_len(p, 0, NGX_SPDY_WINDOW_UPDATE_SIZE);
2099
-
2100
- p = ngx_spdy_frame_write_sid(p, sid);
2101
- p = ngx_spdy_frame_aligned_write_uint32(p, delta);
2102
-
2103
- buf->last = p;
2104
-
2105
- ngx_http_spdy_queue_frame(sc, frame);
2106
-
2107
- return NGX_OK;
2108
- }
2109
-
2110
-
2111
- static ngx_int_t
2112
- ngx_http_spdy_send_rst_stream(ngx_http_spdy_connection_t *sc, ngx_uint_t sid,
2113
- ngx_uint_t status, ngx_uint_t priority)
2114
- {
2115
- u_char *p;
2116
- ngx_buf_t *buf;
2117
- ngx_http_spdy_out_frame_t *frame;
2118
-
2119
- if (sc->connection->error) {
2120
- return NGX_OK;
2121
- }
2122
-
2123
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
2124
- "spdy send RST_STREAM sid:%ui st:%ui", sid, status);
2125
-
2126
- frame = ngx_http_spdy_get_ctl_frame(sc, NGX_SPDY_RST_STREAM_SIZE,
2127
- priority);
2128
- if (frame == NULL) {
2129
- return NGX_ERROR;
2130
- }
2131
-
2132
- buf = frame->first->buf;
2133
-
2134
- p = buf->pos;
2135
-
2136
- p = ngx_spdy_frame_write_head(p, NGX_SPDY_RST_STREAM);
2137
- p = ngx_spdy_frame_write_flags_and_len(p, 0, NGX_SPDY_RST_STREAM_SIZE);
2138
-
2139
- p = ngx_spdy_frame_write_sid(p, sid);
2140
- p = ngx_spdy_frame_aligned_write_uint32(p, status);
2141
-
2142
- buf->last = p;
2143
-
2144
- ngx_http_spdy_queue_frame(sc, frame);
2145
-
2146
- return NGX_OK;
2147
- }
2148
-
2149
-
2150
- #if 0
2151
- static ngx_int_t
2152
- ngx_http_spdy_send_goaway(ngx_http_spdy_connection_t *sc)
2153
- {
2154
- u_char *p;
2155
- ngx_buf_t *buf;
2156
- ngx_http_spdy_out_frame_t *frame;
2157
-
2158
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
2159
- "spdy send GOAWAY sid:%ui", sc->last_sid);
2160
-
2161
- frame = ngx_http_spdy_get_ctl_frame(sc, NGX_SPDY_GOAWAY_SIZE,
2162
- NGX_SPDY_HIGHEST_PRIORITY);
2163
- if (frame == NULL) {
2164
- return NGX_ERROR;
2165
- }
2166
-
2167
- buf = frame->first->buf;
2168
-
2169
- p = buf->pos;
2170
-
2171
- p = ngx_spdy_frame_write_head(p, NGX_SPDY_GOAWAY);
2172
- p = ngx_spdy_frame_write_flags_and_len(p, 0, NGX_SPDY_GOAWAY_SIZE);
2173
-
2174
- p = ngx_spdy_frame_write_sid(p, sc->last_sid);
2175
-
2176
- buf->last = p;
2177
-
2178
- ngx_http_spdy_queue_frame(sc, frame);
2179
-
2180
- return NGX_OK;
2181
- }
2182
- #endif
2183
-
2184
-
2185
- static ngx_int_t
2186
- ngx_http_spdy_send_settings(ngx_http_spdy_connection_t *sc)
2187
- {
2188
- u_char *p;
2189
- ngx_buf_t *buf;
2190
- ngx_chain_t *cl;
2191
- ngx_http_spdy_srv_conf_t *sscf;
2192
- ngx_http_spdy_out_frame_t *frame;
2193
-
2194
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
2195
- "spdy send SETTINGS frame");
2196
-
2197
- frame = ngx_palloc(sc->pool, sizeof(ngx_http_spdy_out_frame_t));
2198
- if (frame == NULL) {
2199
- return NGX_ERROR;
2200
- }
2201
-
2202
- cl = ngx_alloc_chain_link(sc->pool);
2203
- if (cl == NULL) {
2204
- return NGX_ERROR;
2205
- }
2206
-
2207
- buf = ngx_create_temp_buf(sc->pool, NGX_SPDY_FRAME_HEADER_SIZE
2208
- + NGX_SPDY_SETTINGS_NUM_SIZE
2209
- + 2 * NGX_SPDY_SETTINGS_PAIR_SIZE);
2210
- if (buf == NULL) {
2211
- return NGX_ERROR;
2212
- }
2213
-
2214
- buf->last_buf = 1;
2215
-
2216
- cl->buf = buf;
2217
- cl->next = NULL;
2218
-
2219
- frame->first = cl;
2220
- frame->last = cl;
2221
- frame->handler = ngx_http_spdy_settings_frame_handler;
2222
- frame->stream = NULL;
2223
- #if (NGX_DEBUG)
2224
- frame->length = NGX_SPDY_SETTINGS_NUM_SIZE
2225
- + 2 * NGX_SPDY_SETTINGS_PAIR_SIZE;
2226
- #endif
2227
- frame->priority = NGX_SPDY_HIGHEST_PRIORITY;
2228
- frame->blocked = 0;
2229
-
2230
- p = buf->pos;
2231
-
2232
- p = ngx_spdy_frame_write_head(p, NGX_SPDY_SETTINGS);
2233
- p = ngx_spdy_frame_write_flags_and_len(p, NGX_SPDY_FLAG_CLEAR_SETTINGS,
2234
- NGX_SPDY_SETTINGS_NUM_SIZE
2235
- + 2 * NGX_SPDY_SETTINGS_PAIR_SIZE);
2236
-
2237
- p = ngx_spdy_frame_aligned_write_uint32(p, 2);
2238
-
2239
- sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
2240
- ngx_http_spdy_module);
2241
-
2242
- p = ngx_spdy_frame_write_flags_and_id(p, 0, NGX_SPDY_SETTINGS_MAX_STREAMS);
2243
- p = ngx_spdy_frame_aligned_write_uint32(p, sscf->concurrent_streams);
2244
-
2245
- p = ngx_spdy_frame_write_flags_and_id(p, 0, NGX_SPDY_SETTINGS_INIT_WINDOW);
2246
- p = ngx_spdy_frame_aligned_write_uint32(p, NGX_SPDY_STREAM_WINDOW);
2247
-
2248
- buf->last = p;
2249
-
2250
- ngx_http_spdy_queue_frame(sc, frame);
2251
-
2252
- return NGX_OK;
2253
- }
2254
-
2255
-
2256
- ngx_int_t
2257
- ngx_http_spdy_settings_frame_handler(ngx_http_spdy_connection_t *sc,
2258
- ngx_http_spdy_out_frame_t *frame)
2259
- {
2260
- ngx_buf_t *buf;
2261
-
2262
- buf = frame->first->buf;
2263
-
2264
- if (buf->pos != buf->last) {
2265
- return NGX_AGAIN;
2266
- }
2267
-
2268
- ngx_free_chain(sc->pool, frame->first);
2269
-
2270
- return NGX_OK;
2271
- }
2272
-
2273
-
2274
- static ngx_http_spdy_out_frame_t *
2275
- ngx_http_spdy_get_ctl_frame(ngx_http_spdy_connection_t *sc, size_t length,
2276
- ngx_uint_t priority)
2277
- {
2278
- ngx_chain_t *cl;
2279
- ngx_http_spdy_out_frame_t *frame;
2280
-
2281
- frame = sc->free_ctl_frames;
2282
-
2283
- if (frame) {
2284
- sc->free_ctl_frames = frame->next;
2285
-
2286
- cl = frame->first;
2287
- cl->buf->pos = cl->buf->start;
2288
-
2289
- } else {
2290
- frame = ngx_palloc(sc->pool, sizeof(ngx_http_spdy_out_frame_t));
2291
- if (frame == NULL) {
2292
- return NULL;
2293
- }
2294
-
2295
- cl = ngx_alloc_chain_link(sc->pool);
2296
- if (cl == NULL) {
2297
- return NULL;
2298
- }
2299
-
2300
- cl->buf = ngx_create_temp_buf(sc->pool,
2301
- NGX_SPDY_CTL_FRAME_BUFFER_SIZE);
2302
- if (cl->buf == NULL) {
2303
- return NULL;
2304
- }
2305
-
2306
- cl->buf->last_buf = 1;
2307
-
2308
- frame->first = cl;
2309
- frame->last = cl;
2310
- frame->handler = ngx_http_spdy_ctl_frame_handler;
2311
- frame->stream = NULL;
2312
- }
2313
-
2314
- #if (NGX_DEBUG)
2315
- if (length > NGX_SPDY_CTL_FRAME_BUFFER_SIZE - NGX_SPDY_FRAME_HEADER_SIZE) {
2316
- ngx_log_error(NGX_LOG_ALERT, sc->pool->log, 0,
2317
- "requested control frame is too large: %uz", length);
2318
- return NULL;
2319
- }
2320
-
2321
- frame->length = length;
2322
- #endif
2323
-
2324
- frame->priority = priority;
2325
- frame->blocked = 0;
2326
-
2327
- return frame;
2328
- }
2329
-
2330
-
2331
- static ngx_int_t
2332
- ngx_http_spdy_ctl_frame_handler(ngx_http_spdy_connection_t *sc,
2333
- ngx_http_spdy_out_frame_t *frame)
2334
- {
2335
- ngx_buf_t *buf;
2336
-
2337
- buf = frame->first->buf;
2338
-
2339
- if (buf->pos != buf->last) {
2340
- return NGX_AGAIN;
2341
- }
2342
-
2343
- frame->next = sc->free_ctl_frames;
2344
- sc->free_ctl_frames = frame;
2345
-
2346
- return NGX_OK;
2347
- }
2348
-
2349
-
2350
- static ngx_http_spdy_stream_t *
2351
- ngx_http_spdy_create_stream(ngx_http_spdy_connection_t *sc, ngx_uint_t id,
2352
- ngx_uint_t priority)
2353
- {
2354
- ngx_log_t *log;
2355
- ngx_uint_t index;
2356
- ngx_event_t *rev, *wev;
2357
- ngx_connection_t *fc;
2358
- ngx_http_log_ctx_t *ctx;
2359
- ngx_http_request_t *r;
2360
- ngx_http_spdy_stream_t *stream;
2361
- ngx_http_core_srv_conf_t *cscf;
2362
- ngx_http_spdy_srv_conf_t *sscf;
2363
-
2364
- fc = sc->free_fake_connections;
2365
-
2366
- if (fc) {
2367
- sc->free_fake_connections = fc->data;
2368
-
2369
- rev = fc->read;
2370
- wev = fc->write;
2371
- log = fc->log;
2372
- ctx = log->data;
2373
-
2374
- } else {
2375
- fc = ngx_palloc(sc->pool, sizeof(ngx_connection_t));
2376
- if (fc == NULL) {
2377
- return NULL;
2378
- }
2379
-
2380
- rev = ngx_palloc(sc->pool, sizeof(ngx_event_t));
2381
- if (rev == NULL) {
2382
- return NULL;
2383
- }
2384
-
2385
- wev = ngx_palloc(sc->pool, sizeof(ngx_event_t));
2386
- if (wev == NULL) {
2387
- return NULL;
2388
- }
2389
-
2390
- log = ngx_palloc(sc->pool, sizeof(ngx_log_t));
2391
- if (log == NULL) {
2392
- return NULL;
2393
- }
2394
-
2395
- ctx = ngx_palloc(sc->pool, sizeof(ngx_http_log_ctx_t));
2396
- if (ctx == NULL) {
2397
- return NULL;
2398
- }
2399
-
2400
- ctx->connection = fc;
2401
- ctx->request = NULL;
2402
- }
2403
-
2404
- ngx_memcpy(log, sc->connection->log, sizeof(ngx_log_t));
2405
-
2406
- log->data = ctx;
2407
-
2408
- ngx_memzero(rev, sizeof(ngx_event_t));
2409
-
2410
- rev->data = fc;
2411
- rev->ready = 1;
2412
- rev->handler = ngx_http_spdy_close_stream_handler;
2413
- rev->log = log;
2414
-
2415
- ngx_memcpy(wev, rev, sizeof(ngx_event_t));
2416
-
2417
- wev->write = 1;
2418
-
2419
- ngx_memcpy(fc, sc->connection, sizeof(ngx_connection_t));
2420
-
2421
- fc->data = sc->http_connection;
2422
- fc->read = rev;
2423
- fc->write = wev;
2424
- fc->sent = 0;
2425
- fc->log = log;
2426
- fc->buffered = 0;
2427
- fc->sndlowat = 1;
2428
- fc->tcp_nodelay = NGX_TCP_NODELAY_DISABLED;
2429
-
2430
- r = ngx_http_create_request(fc);
2431
- if (r == NULL) {
2432
- return NULL;
2433
- }
2434
-
2435
- r->valid_location = 1;
2436
-
2437
- fc->data = r;
2438
- sc->connection->requests++;
2439
-
2440
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
2441
-
2442
- r->header_in = ngx_create_temp_buf(r->pool,
2443
- cscf->client_header_buffer_size);
2444
- if (r->header_in == NULL) {
2445
- ngx_http_free_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
2446
- return NULL;
2447
- }
2448
-
2449
- r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE;
2450
-
2451
- stream = ngx_pcalloc(r->pool, sizeof(ngx_http_spdy_stream_t));
2452
- if (stream == NULL) {
2453
- ngx_http_free_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
2454
- return NULL;
2455
- }
2456
-
2457
- r->spdy_stream = stream;
2458
-
2459
- stream->id = id;
2460
- stream->request = r;
2461
- stream->connection = sc;
2462
-
2463
- stream->send_window = sc->init_window;
2464
- stream->recv_window = NGX_SPDY_STREAM_WINDOW;
2465
-
2466
- stream->priority = priority;
2467
-
2468
- sscf = ngx_http_get_module_srv_conf(r, ngx_http_spdy_module);
2469
-
2470
- index = ngx_http_spdy_stream_index(sscf, id);
2471
-
2472
- stream->index = sc->streams_index[index];
2473
- sc->streams_index[index] = stream;
2474
-
2475
- sc->processing++;
2476
-
2477
- return stream;
2478
- }
2479
-
2480
-
2481
- static ngx_http_spdy_stream_t *
2482
- ngx_http_spdy_get_stream_by_id(ngx_http_spdy_connection_t *sc,
2483
- ngx_uint_t sid)
2484
- {
2485
- ngx_http_spdy_stream_t *stream;
2486
- ngx_http_spdy_srv_conf_t *sscf;
2487
-
2488
- sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
2489
- ngx_http_spdy_module);
2490
-
2491
- stream = sc->streams_index[ngx_http_spdy_stream_index(sscf, sid)];
2492
-
2493
- while (stream) {
2494
- if (stream->id == sid) {
2495
- return stream;
2496
- }
2497
-
2498
- stream = stream->index;
2499
- }
2500
-
2501
- return NULL;
2502
- }
2503
-
2504
-
2505
- static ngx_int_t
2506
- ngx_http_spdy_parse_header(ngx_http_request_t *r)
2507
- {
2508
- u_char *p, *end, ch;
2509
- ngx_uint_t hash;
2510
- ngx_http_core_srv_conf_t *cscf;
2511
-
2512
- enum {
2513
- sw_name_len = 0,
2514
- sw_name,
2515
- sw_value_len,
2516
- sw_value
2517
- } state;
2518
-
2519
- state = r->state;
2520
-
2521
- p = r->header_in->pos;
2522
- end = r->header_in->last;
2523
-
2524
- switch (state) {
2525
-
2526
- case sw_name_len:
2527
-
2528
- if (end - p < NGX_SPDY_NV_NLEN_SIZE) {
2529
- return NGX_AGAIN;
2530
- }
2531
-
2532
- r->lowcase_index = ngx_spdy_frame_parse_uint32(p);
2533
-
2534
- if (r->lowcase_index == 0) {
2535
- return NGX_ERROR;
2536
- }
2537
-
2538
- /* null-terminate the previous header value */
2539
- *p = '\0';
2540
-
2541
- p += NGX_SPDY_NV_NLEN_SIZE;
2542
-
2543
- r->invalid_header = 0;
2544
-
2545
- state = sw_name;
2546
-
2547
- /* fall through */
2548
-
2549
- case sw_name:
2550
-
2551
- if ((ngx_uint_t) (end - p) < r->lowcase_index) {
2552
- break;
2553
- }
2554
-
2555
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
2556
-
2557
- r->header_name_start = p;
2558
- r->header_name_end = p + r->lowcase_index;
2559
-
2560
- if (p[0] == ':') {
2561
- p++;
2562
- }
2563
-
2564
- hash = 0;
2565
-
2566
- for ( /* void */ ; p != r->header_name_end; p++) {
2567
-
2568
- ch = *p;
2569
-
2570
- hash = ngx_hash(hash, ch);
2571
-
2572
- if ((ch >= 'a' && ch <= 'z')
2573
- || (ch == '-')
2574
- || (ch >= '0' && ch <= '9')
2575
- || (ch == '_' && cscf->underscores_in_headers))
2576
- {
2577
- continue;
2578
- }
2579
-
2580
- switch (ch) {
2581
- case '\0':
2582
- case LF:
2583
- case CR:
2584
- case ':':
2585
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
2586
- "client sent invalid header name: \"%*s\"",
2587
- r->lowcase_index, r->header_name_start);
2588
-
2589
- return NGX_HTTP_PARSE_INVALID_HEADER;
2590
- }
2591
-
2592
- if (ch >= 'A' && ch <= 'Z') {
2593
- return NGX_ERROR;
2594
- }
2595
-
2596
- r->invalid_header = 1;
2597
- }
2598
-
2599
- r->header_hash = hash;
2600
-
2601
- state = sw_value_len;
2602
-
2603
- /* fall through */
2604
-
2605
- case sw_value_len:
2606
-
2607
- if (end - p < NGX_SPDY_NV_VLEN_SIZE) {
2608
- break;
2609
- }
2610
-
2611
- r->lowcase_index = ngx_spdy_frame_parse_uint32(p);
2612
-
2613
- /* null-terminate header name */
2614
- *p = '\0';
2615
-
2616
- p += NGX_SPDY_NV_VLEN_SIZE;
2617
-
2618
- state = sw_value;
2619
-
2620
- /* fall through */
2621
-
2622
- case sw_value:
2623
-
2624
- if ((ngx_uint_t) (end - p) < r->lowcase_index) {
2625
- break;
2626
- }
2627
-
2628
- r->header_start = p;
2629
-
2630
- while (r->lowcase_index--) {
2631
- ch = *p;
2632
-
2633
- if (ch == '\0') {
2634
-
2635
- if (p == r->header_start) {
2636
- return NGX_ERROR;
2637
- }
2638
-
2639
- r->header_end = p;
2640
- r->header_in->pos = p + 1;
2641
-
2642
- r->state = sw_value;
2643
-
2644
- return NGX_OK;
2645
- }
2646
-
2647
- if (ch == CR || ch == LF) {
2648
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
2649
- "client sent header \"%*s\" with "
2650
- "invalid value: \"%*s\\%c...\"",
2651
- r->header_name_end - r->header_name_start,
2652
- r->header_name_start,
2653
- p - r->header_start,
2654
- r->header_start,
2655
- ch == CR ? 'r' : 'n');
2656
-
2657
- return NGX_HTTP_PARSE_INVALID_HEADER;
2658
- }
2659
-
2660
- p++;
2661
- }
2662
-
2663
- r->header_end = p;
2664
- r->header_in->pos = p;
2665
-
2666
- r->state = 0;
2667
-
2668
- return NGX_DONE;
2669
- }
2670
-
2671
- r->header_in->pos = p;
2672
- r->state = state;
2673
-
2674
- return NGX_AGAIN;
2675
- }
2676
-
2677
-
2678
- static ngx_int_t
2679
- ngx_http_spdy_alloc_large_header_buffer(ngx_http_request_t *r)
2680
- {
2681
- u_char *old, *new, *p;
2682
- size_t rest;
2683
- ngx_buf_t *buf;
2684
- ngx_http_spdy_stream_t *stream;
2685
- ngx_http_core_srv_conf_t *cscf;
2686
-
2687
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2688
- "spdy alloc large header buffer");
2689
-
2690
- stream = r->spdy_stream;
2691
-
2692
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
2693
-
2694
- if (stream->header_buffers
2695
- == (ngx_uint_t) cscf->large_client_header_buffers.num)
2696
- {
2697
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
2698
- "client sent too large request");
2699
-
2700
- return NGX_DECLINED;
2701
- }
2702
-
2703
- rest = r->header_in->last - r->header_in->pos;
2704
-
2705
- /*
2706
- * One more byte is needed for null-termination
2707
- * and another one for further progress.
2708
- */
2709
- if (rest > cscf->large_client_header_buffers.size - 2) {
2710
- p = r->header_in->pos;
2711
-
2712
- if (rest > NGX_MAX_ERROR_STR - 300) {
2713
- rest = NGX_MAX_ERROR_STR - 300;
2714
- }
2715
-
2716
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
2717
- "client sent too long header name or value: \"%*s...\"",
2718
- rest, p);
2719
-
2720
- return NGX_DECLINED;
2721
- }
2722
-
2723
- buf = ngx_create_temp_buf(r->pool, cscf->large_client_header_buffers.size);
2724
- if (buf == NULL) {
2725
- return NGX_ERROR;
2726
- }
2727
-
2728
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2729
- "spdy large header alloc: %p %uz",
2730
- buf->pos, buf->end - buf->last);
2731
-
2732
- old = r->header_in->pos;
2733
- new = buf->pos;
2734
-
2735
- if (rest) {
2736
- buf->last = ngx_cpymem(new, old, rest);
2737
- }
2738
-
2739
- r->header_in = buf;
2740
-
2741
- stream->header_buffers++;
2742
-
2743
- return NGX_OK;
2744
- }
2745
-
2746
-
2747
- static ngx_int_t
2748
- ngx_http_spdy_handle_request_header(ngx_http_request_t *r)
2749
- {
2750
- ngx_uint_t i;
2751
- ngx_table_elt_t *h;
2752
- ngx_http_core_srv_conf_t *cscf;
2753
- ngx_http_spdy_request_header_t *sh;
2754
-
2755
- if (r->invalid_header) {
2756
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
2757
-
2758
- if (cscf->ignore_invalid_headers) {
2759
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
2760
- "client sent invalid header: \"%*s\"",
2761
- r->header_end - r->header_name_start,
2762
- r->header_name_start);
2763
- return NGX_OK;
2764
- }
2765
-
2766
- }
2767
-
2768
- if (r->header_name_start[0] == ':') {
2769
- r->header_name_start++;
2770
-
2771
- for (i = 0; i < NGX_SPDY_REQUEST_HEADERS; i++) {
2772
- sh = &ngx_http_spdy_request_headers[i];
2773
-
2774
- if (sh->hash != r->header_hash
2775
- || sh->len != r->header_name_end - r->header_name_start
2776
- || ngx_strncmp(sh->header, r->header_name_start, sh->len) != 0)
2777
- {
2778
- continue;
2779
- }
2780
-
2781
- return sh->handler(r);
2782
- }
2783
-
2784
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
2785
- "client sent invalid header name: \":%*s\"",
2786
- r->header_end - r->header_name_start,
2787
- r->header_name_start);
2788
-
2789
- return NGX_HTTP_PARSE_INVALID_HEADER;
2790
- }
2791
-
2792
- h = ngx_list_push(&r->headers_in.headers);
2793
- if (h == NULL) {
2794
- return NGX_ERROR;
2795
- }
2796
-
2797
- h->hash = r->header_hash;
2798
-
2799
- h->key.len = r->header_name_end - r->header_name_start;
2800
- h->key.data = r->header_name_start;
2801
-
2802
- h->value.len = r->header_end - r->header_start;
2803
- h->value.data = r->header_start;
2804
-
2805
- h->lowcase_key = h->key.data;
2806
-
2807
- return NGX_OK;
2808
- }
2809
-
2810
-
2811
- void
2812
- ngx_http_spdy_request_headers_init(void)
2813
- {
2814
- ngx_uint_t i;
2815
- ngx_http_spdy_request_header_t *h;
2816
-
2817
- for (i = 0; i < NGX_SPDY_REQUEST_HEADERS; i++) {
2818
- h = &ngx_http_spdy_request_headers[i];
2819
- h->hash = ngx_hash_key(h->header, h->len);
2820
- }
2821
- }
2822
-
2823
-
2824
- static ngx_int_t
2825
- ngx_http_spdy_parse_method(ngx_http_request_t *r)
2826
- {
2827
- size_t k, len;
2828
- ngx_uint_t n;
2829
- const u_char *p, *m;
2830
-
2831
- /*
2832
- * This array takes less than 256 sequential bytes,
2833
- * and if typical CPU cache line size is 64 bytes,
2834
- * it is prefetched for 4 load operations.
2835
- */
2836
- static const struct {
2837
- u_char len;
2838
- const u_char method[11];
2839
- uint32_t value;
2840
- } tests[] = {
2841
- { 3, "GET", NGX_HTTP_GET },
2842
- { 4, "POST", NGX_HTTP_POST },
2843
- { 4, "HEAD", NGX_HTTP_HEAD },
2844
- { 7, "OPTIONS", NGX_HTTP_OPTIONS },
2845
- { 8, "PROPFIND", NGX_HTTP_PROPFIND },
2846
- { 3, "PUT", NGX_HTTP_PUT },
2847
- { 5, "MKCOL", NGX_HTTP_MKCOL },
2848
- { 6, "DELETE", NGX_HTTP_DELETE },
2849
- { 4, "COPY", NGX_HTTP_COPY },
2850
- { 4, "MOVE", NGX_HTTP_MOVE },
2851
- { 9, "PROPPATCH", NGX_HTTP_PROPPATCH },
2852
- { 4, "LOCK", NGX_HTTP_LOCK },
2853
- { 6, "UNLOCK", NGX_HTTP_UNLOCK },
2854
- { 5, "PATCH", NGX_HTTP_PATCH },
2855
- { 5, "TRACE", NGX_HTTP_TRACE }
2856
- }, *test;
2857
-
2858
- if (r->method_name.len) {
2859
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
2860
- "client sent duplicate :method header");
2861
-
2862
- return NGX_HTTP_PARSE_INVALID_HEADER;
2863
- }
2864
-
2865
- len = r->header_end - r->header_start;
2866
-
2867
- r->method_name.len = len;
2868
- r->method_name.data = r->header_start;
2869
-
2870
- test = tests;
2871
- n = sizeof(tests) / sizeof(tests[0]);
2872
-
2873
- do {
2874
- if (len == test->len) {
2875
- p = r->method_name.data;
2876
- m = test->method;
2877
- k = len;
2878
-
2879
- do {
2880
- if (*p++ != *m++) {
2881
- goto next;
2882
- }
2883
- } while (--k);
2884
-
2885
- r->method = test->value;
2886
- return NGX_OK;
2887
- }
2888
-
2889
- next:
2890
- test++;
2891
-
2892
- } while (--n);
2893
-
2894
- p = r->method_name.data;
2895
-
2896
- do {
2897
- if ((*p < 'A' || *p > 'Z') && *p != '_') {
2898
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
2899
- "client sent invalid method: \"%V\"",
2900
- &r->method_name);
2901
-
2902
- return NGX_HTTP_PARSE_INVALID_HEADER;
2903
- }
2904
-
2905
- p++;
2906
-
2907
- } while (--len);
2908
-
2909
- return NGX_OK;
2910
- }
2911
-
2912
-
2913
- static ngx_int_t
2914
- ngx_http_spdy_parse_scheme(ngx_http_request_t *r)
2915
- {
2916
- if (r->schema_start) {
2917
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
2918
- "client sent duplicate :schema header");
2919
-
2920
- return NGX_HTTP_PARSE_INVALID_HEADER;
2921
- }
2922
-
2923
- r->schema_start = r->header_start;
2924
- r->schema_end = r->header_end;
2925
-
2926
- return NGX_OK;
2927
- }
2928
-
2929
-
2930
- static ngx_int_t
2931
- ngx_http_spdy_parse_host(ngx_http_request_t *r)
2932
- {
2933
- ngx_table_elt_t *h;
2934
-
2935
- if (r->headers_in.host) {
2936
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
2937
- "client sent duplicate :host header");
2938
-
2939
- return NGX_HTTP_PARSE_INVALID_HEADER;
2940
- }
2941
-
2942
- h = ngx_list_push(&r->headers_in.headers);
2943
- if (h == NULL) {
2944
- return NGX_ERROR;
2945
- }
2946
-
2947
- r->headers_in.host = h;
2948
-
2949
- h->hash = r->header_hash;
2950
-
2951
- h->key.len = r->header_name_end - r->header_name_start;
2952
- h->key.data = r->header_name_start;
2953
-
2954
- h->value.len = r->header_end - r->header_start;
2955
- h->value.data = r->header_start;
2956
-
2957
- h->lowcase_key = h->key.data;
2958
-
2959
- return NGX_OK;
2960
- }
2961
-
2962
-
2963
- static ngx_int_t
2964
- ngx_http_spdy_parse_path(ngx_http_request_t *r)
2965
- {
2966
- if (r->unparsed_uri.len) {
2967
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
2968
- "client sent duplicate :path header");
2969
-
2970
- return NGX_HTTP_PARSE_INVALID_HEADER;
2971
- }
2972
-
2973
- r->uri_start = r->header_start;
2974
- r->uri_end = r->header_end;
2975
-
2976
- if (ngx_http_parse_uri(r) != NGX_OK) {
2977
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
2978
- "client sent invalid URI: \"%*s\"",
2979
- r->uri_end - r->uri_start, r->uri_start);
2980
-
2981
- return NGX_HTTP_PARSE_INVALID_HEADER;
2982
- }
2983
-
2984
- if (ngx_http_process_request_uri(r) != NGX_OK) {
2985
- /*
2986
- * request has been finalized already
2987
- * in ngx_http_process_request_uri()
2988
- */
2989
- return NGX_ABORT;
2990
- }
2991
-
2992
- return NGX_OK;
2993
- }
2994
-
2995
-
2996
- static ngx_int_t
2997
- ngx_http_spdy_parse_version(ngx_http_request_t *r)
2998
- {
2999
- u_char *p, ch;
3000
-
3001
- if (r->http_protocol.len) {
3002
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
3003
- "client sent duplicate :version header");
3004
-
3005
- return NGX_HTTP_PARSE_INVALID_HEADER;
3006
- }
3007
-
3008
- p = r->header_start;
3009
-
3010
- if (r->header_end - p < 8 || !(ngx_str5cmp(p, 'H', 'T', 'T', 'P', '/'))) {
3011
- goto invalid;
3012
- }
3013
-
3014
- ch = *(p + 5);
3015
-
3016
- if (ch < '1' || ch > '9') {
3017
- goto invalid;
3018
- }
3019
-
3020
- r->http_major = ch - '0';
3021
-
3022
- for (p += 6; p != r->header_end - 2; p++) {
3023
-
3024
- ch = *p;
3025
-
3026
- if (ch == '.') {
3027
- break;
3028
- }
3029
-
3030
- if (ch < '0' || ch > '9') {
3031
- goto invalid;
3032
- }
3033
-
3034
- r->http_major = r->http_major * 10 + ch - '0';
3035
- }
3036
-
3037
- if (*p != '.') {
3038
- goto invalid;
3039
- }
3040
-
3041
- ch = *(p + 1);
3042
-
3043
- if (ch < '0' || ch > '9') {
3044
- goto invalid;
3045
- }
3046
-
3047
- r->http_minor = ch - '0';
3048
-
3049
- for (p += 2; p != r->header_end; p++) {
3050
-
3051
- ch = *p;
3052
-
3053
- if (ch < '0' || ch > '9') {
3054
- goto invalid;
3055
- }
3056
-
3057
- r->http_minor = r->http_minor * 10 + ch - '0';
3058
- }
3059
-
3060
- r->http_protocol.len = r->header_end - r->header_start;
3061
- r->http_protocol.data = r->header_start;
3062
- r->http_version = r->http_major * 1000 + r->http_minor;
3063
-
3064
- return NGX_OK;
3065
-
3066
- invalid:
3067
-
3068
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
3069
- "client sent invalid http version: \"%*s\"",
3070
- r->header_end - r->header_start, r->header_start);
3071
-
3072
- return NGX_HTTP_PARSE_INVALID_HEADER;
3073
- }
3074
-
3075
-
3076
- static ngx_int_t
3077
- ngx_http_spdy_construct_request_line(ngx_http_request_t *r)
3078
- {
3079
- u_char *p;
3080
-
3081
- if (r->method_name.len == 0
3082
- || r->unparsed_uri.len == 0
3083
- || r->http_protocol.len == 0)
3084
- {
3085
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
3086
- return NGX_ERROR;
3087
- }
3088
-
3089
- r->request_line.len = r->method_name.len + 1
3090
- + r->unparsed_uri.len + 1
3091
- + r->http_protocol.len;
3092
-
3093
- p = ngx_pnalloc(r->pool, r->request_line.len + 1);
3094
- if (p == NULL) {
3095
- ngx_http_spdy_close_stream(r->spdy_stream,
3096
- NGX_HTTP_INTERNAL_SERVER_ERROR);
3097
- return NGX_ERROR;
3098
- }
3099
-
3100
- r->request_line.data = p;
3101
-
3102
- p = ngx_cpymem(p, r->method_name.data, r->method_name.len);
3103
-
3104
- *p++ = ' ';
3105
-
3106
- p = ngx_cpymem(p, r->unparsed_uri.data, r->unparsed_uri.len);
3107
-
3108
- *p++ = ' ';
3109
-
3110
- ngx_memcpy(p, r->http_protocol.data, r->http_protocol.len + 1);
3111
-
3112
- /* some modules expect the space character after method name */
3113
- r->method_name.data = r->request_line.data;
3114
-
3115
- return NGX_OK;
3116
- }
3117
-
3118
-
3119
- static void
3120
- ngx_http_spdy_run_request(ngx_http_request_t *r)
3121
- {
3122
- ngx_uint_t i;
3123
- ngx_list_part_t *part;
3124
- ngx_table_elt_t *h;
3125
- ngx_http_header_t *hh;
3126
- ngx_http_core_main_conf_t *cmcf;
3127
-
3128
- if (ngx_http_spdy_construct_request_line(r) != NGX_OK) {
3129
- return;
3130
- }
3131
-
3132
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
3133
- "spdy http request line: \"%V\"", &r->request_line);
3134
-
3135
- cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
3136
-
3137
- part = &r->headers_in.headers.part;
3138
- h = part->elts;
3139
-
3140
- for (i = 0 ;; i++) {
3141
-
3142
- if (i >= part->nelts) {
3143
- if (part->next == NULL) {
3144
- break;
3145
- }
3146
-
3147
- part = part->next;
3148
- h = part->elts;
3149
- i = 0;
3150
- }
3151
-
3152
- hh = ngx_hash_find(&cmcf->headers_in_hash, h[i].hash,
3153
- h[i].lowcase_key, h[i].key.len);
3154
-
3155
- if (hh && hh->handler(r, &h[i], hh->offset) != NGX_OK) {
3156
- return;
3157
- }
3158
-
3159
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
3160
- "spdy http header: \"%V: %V\"", &h[i].key, &h[i].value);
3161
- }
3162
-
3163
- r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE;
3164
-
3165
- if (ngx_http_process_request_header(r) != NGX_OK) {
3166
- return;
3167
- }
3168
-
3169
- if (r->headers_in.content_length_n > 0 && r->spdy_stream->in_closed) {
3170
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
3171
- "client prematurely closed stream");
3172
-
3173
- r->spdy_stream->skip_data = NGX_SPDY_DATA_ERROR;
3174
-
3175
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
3176
- return;
3177
- }
3178
-
3179
- ngx_http_process_request(r);
3180
- }
3181
-
3182
-
3183
- static ngx_int_t
3184
- ngx_http_spdy_init_request_body(ngx_http_request_t *r)
3185
- {
3186
- ngx_buf_t *buf;
3187
- ngx_temp_file_t *tf;
3188
- ngx_http_request_body_t *rb;
3189
- ngx_http_core_loc_conf_t *clcf;
3190
-
3191
- rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
3192
- if (rb == NULL) {
3193
- return NGX_ERROR;
3194
- }
3195
-
3196
- r->request_body = rb;
3197
-
3198
- if (r->spdy_stream->in_closed) {
3199
- return NGX_OK;
3200
- }
3201
-
3202
- rb->rest = r->headers_in.content_length_n;
3203
-
3204
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
3205
-
3206
- if (r->request_body_in_file_only
3207
- || rb->rest > (off_t) clcf->client_body_buffer_size
3208
- || rb->rest < 0)
3209
- {
3210
- tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t));
3211
- if (tf == NULL) {
3212
- return NGX_ERROR;
3213
- }
3214
-
3215
- tf->file.fd = NGX_INVALID_FILE;
3216
- tf->file.log = r->connection->log;
3217
- tf->path = clcf->client_body_temp_path;
3218
- tf->pool = r->pool;
3219
- tf->warn = "a client request body is buffered to a temporary file";
3220
- tf->log_level = r->request_body_file_log_level;
3221
- tf->persistent = r->request_body_in_persistent_file;
3222
- tf->clean = r->request_body_in_clean_file;
3223
-
3224
- if (r->request_body_file_group_access) {
3225
- tf->access = 0660;
3226
- }
3227
-
3228
- rb->temp_file = tf;
3229
-
3230
- if (r->spdy_stream->in_closed
3231
- && ngx_create_temp_file(&tf->file, tf->path, tf->pool,
3232
- tf->persistent, tf->clean, tf->access)
3233
- != NGX_OK)
3234
- {
3235
- return NGX_ERROR;
3236
- }
3237
-
3238
- buf = ngx_calloc_buf(r->pool);
3239
- if (buf == NULL) {
3240
- return NGX_ERROR;
3241
- }
3242
-
3243
- } else {
3244
-
3245
- if (rb->rest == 0) {
3246
- return NGX_OK;
3247
- }
3248
-
3249
- buf = ngx_create_temp_buf(r->pool, (size_t) rb->rest);
3250
- if (buf == NULL) {
3251
- return NGX_ERROR;
3252
- }
3253
- }
3254
-
3255
- rb->buf = buf;
3256
-
3257
- rb->bufs = ngx_alloc_chain_link(r->pool);
3258
- if (rb->bufs == NULL) {
3259
- return NGX_ERROR;
3260
- }
3261
-
3262
- rb->bufs->buf = buf;
3263
- rb->bufs->next = NULL;
3264
-
3265
- rb->rest = 0;
3266
-
3267
- return NGX_OK;
3268
- }
3269
-
3270
-
3271
- ngx_int_t
3272
- ngx_http_spdy_read_request_body(ngx_http_request_t *r,
3273
- ngx_http_client_body_handler_pt post_handler)
3274
- {
3275
- ngx_http_spdy_stream_t *stream;
3276
-
3277
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
3278
- "spdy read request body");
3279
-
3280
- stream = r->spdy_stream;
3281
-
3282
- switch (stream->skip_data) {
3283
-
3284
- case NGX_SPDY_DATA_DISCARD:
3285
- post_handler(r);
3286
- return NGX_OK;
3287
-
3288
- case NGX_SPDY_DATA_ERROR:
3289
- if (r->headers_in.content_length_n == -1) {
3290
- return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE;
3291
- } else {
3292
- return NGX_HTTP_BAD_REQUEST;
3293
- }
3294
-
3295
- case NGX_SPDY_DATA_INTERNAL_ERROR:
3296
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
3297
- }
3298
-
3299
- if (!r->request_body && ngx_http_spdy_init_request_body(r) != NGX_OK) {
3300
- stream->skip_data = NGX_SPDY_DATA_INTERNAL_ERROR;
3301
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
3302
- }
3303
-
3304
- if (stream->in_closed) {
3305
- post_handler(r);
3306
- return NGX_OK;
3307
- }
3308
-
3309
- r->request_body->post_handler = post_handler;
3310
-
3311
- r->read_event_handler = ngx_http_test_reading;
3312
- r->write_event_handler = ngx_http_request_empty_handler;
3313
-
3314
- return NGX_AGAIN;
3315
- }
3316
-
3317
-
3318
- static ngx_int_t
3319
- ngx_http_spdy_terminate_stream(ngx_http_spdy_connection_t *sc,
3320
- ngx_http_spdy_stream_t *stream, ngx_uint_t status)
3321
- {
3322
- ngx_event_t *rev;
3323
- ngx_connection_t *fc;
3324
-
3325
- if (ngx_http_spdy_send_rst_stream(sc, stream->id, status,
3326
- NGX_SPDY_HIGHEST_PRIORITY)
3327
- == NGX_ERROR)
3328
- {
3329
- return NGX_ERROR;
3330
- }
3331
-
3332
- stream->out_closed = 1;
3333
-
3334
- fc = stream->request->connection;
3335
- fc->error = 1;
3336
-
3337
- rev = fc->read;
3338
- rev->handler(rev);
3339
-
3340
- return NGX_OK;
3341
- }
3342
-
3343
-
3344
- static void
3345
- ngx_http_spdy_close_stream_handler(ngx_event_t *ev)
3346
- {
3347
- ngx_connection_t *fc;
3348
- ngx_http_request_t *r;
3349
-
3350
- fc = ev->data;
3351
- r = fc->data;
3352
-
3353
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
3354
- "spdy close stream handler");
3355
-
3356
- ngx_http_spdy_close_stream(r->spdy_stream, 0);
3357
- }
3358
-
3359
-
3360
- void
3361
- ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc)
3362
- {
3363
- ngx_event_t *ev;
3364
- ngx_connection_t *fc;
3365
- ngx_http_spdy_stream_t **index, *s;
3366
- ngx_http_spdy_srv_conf_t *sscf;
3367
- ngx_http_spdy_connection_t *sc;
3368
-
3369
- sc = stream->connection;
3370
-
3371
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
3372
- "spdy close stream %ui, queued %ui, processing %ui",
3373
- stream->id, stream->queued, sc->processing);
3374
-
3375
- fc = stream->request->connection;
3376
-
3377
- if (stream->queued) {
3378
- fc->write->handler = ngx_http_spdy_close_stream_handler;
3379
- return;
3380
- }
3381
-
3382
- if (!stream->out_closed) {
3383
- if (ngx_http_spdy_send_rst_stream(sc, stream->id,
3384
- NGX_SPDY_INTERNAL_ERROR,
3385
- stream->priority)
3386
- != NGX_OK)
3387
- {
3388
- sc->connection->error = 1;
3389
- }
3390
- }
3391
-
3392
- if (sc->stream == stream) {
3393
- sc->stream = NULL;
3394
- }
3395
-
3396
- sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
3397
- ngx_http_spdy_module);
3398
-
3399
- index = sc->streams_index + ngx_http_spdy_stream_index(sscf, stream->id);
3400
-
3401
- for ( ;; ) {
3402
- s = *index;
3403
-
3404
- if (s == NULL) {
3405
- break;
3406
- }
3407
-
3408
- if (s == stream) {
3409
- *index = s->index;
3410
- break;
3411
- }
3412
-
3413
- index = &s->index;
3414
- }
3415
-
3416
- ngx_http_free_request(stream->request, rc);
3417
-
3418
- ev = fc->read;
3419
-
3420
- if (ev->active || ev->disabled) {
3421
- ngx_log_error(NGX_LOG_ALERT, sc->connection->log, 0,
3422
- "fake read event was activated");
3423
- }
3424
-
3425
- if (ev->timer_set) {
3426
- ngx_del_timer(ev);
3427
- }
3428
-
3429
- if (ev->posted) {
3430
- ngx_delete_posted_event(ev);
3431
- }
3432
-
3433
- ev = fc->write;
3434
-
3435
- if (ev->active || ev->disabled) {
3436
- ngx_log_error(NGX_LOG_ALERT, sc->connection->log, 0,
3437
- "fake write event was activated");
3438
- }
3439
-
3440
- if (ev->timer_set) {
3441
- ngx_del_timer(ev);
3442
- }
3443
-
3444
- if (ev->posted) {
3445
- ngx_delete_posted_event(ev);
3446
- }
3447
-
3448
- fc->data = sc->free_fake_connections;
3449
- sc->free_fake_connections = fc;
3450
-
3451
- sc->processing--;
3452
-
3453
- if (sc->processing || sc->blocked) {
3454
- return;
3455
- }
3456
-
3457
- ev = sc->connection->read;
3458
-
3459
- ev->handler = ngx_http_spdy_handle_connection_handler;
3460
- ngx_post_event(ev, &ngx_posted_events);
3461
- }
3462
-
3463
-
3464
- static void
3465
- ngx_http_spdy_handle_connection_handler(ngx_event_t *rev)
3466
- {
3467
- ngx_connection_t *c;
3468
-
3469
- rev->handler = ngx_http_spdy_read_handler;
3470
-
3471
- if (rev->ready) {
3472
- ngx_http_spdy_read_handler(rev);
3473
- return;
3474
- }
3475
-
3476
- c = rev->data;
3477
-
3478
- ngx_http_spdy_handle_connection(c->data);
3479
- }
3480
-
3481
-
3482
- static void
3483
- ngx_http_spdy_keepalive_handler(ngx_event_t *rev)
3484
- {
3485
- ngx_connection_t *c;
3486
- ngx_http_spdy_srv_conf_t *sscf;
3487
- ngx_http_spdy_connection_t *sc;
3488
-
3489
- c = rev->data;
3490
-
3491
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "spdy keepalive handler");
3492
-
3493
- if (rev->timedout || c->close) {
3494
- ngx_http_close_connection(c);
3495
- return;
3496
- }
3497
-
3498
- #if (NGX_HAVE_KQUEUE)
3499
-
3500
- if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
3501
- if (rev->pending_eof) {
3502
- c->log->handler = NULL;
3503
- ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
3504
- "kevent() reported that client %V closed "
3505
- "keepalive connection", &c->addr_text);
3506
- #if (NGX_HTTP_SSL)
3507
- if (c->ssl) {
3508
- c->ssl->no_send_shutdown = 1;
3509
- }
3510
- #endif
3511
- ngx_http_close_connection(c);
3512
- return;
3513
- }
3514
- }
3515
-
3516
- #endif
3517
-
3518
- c->destroyed = 0;
3519
- c->idle = 0;
3520
- ngx_reusable_connection(c, 0);
3521
-
3522
- sc = c->data;
3523
-
3524
- sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
3525
- ngx_http_spdy_module);
3526
-
3527
- sc->pool = ngx_create_pool(sscf->pool_size, sc->connection->log);
3528
- if (sc->pool == NULL) {
3529
- ngx_http_close_connection(c);
3530
- return;
3531
- }
3532
-
3533
- sc->streams_index = ngx_pcalloc(sc->pool,
3534
- ngx_http_spdy_streams_index_size(sscf)
3535
- * sizeof(ngx_http_spdy_stream_t *));
3536
- if (sc->streams_index == NULL) {
3537
- ngx_http_close_connection(c);
3538
- return;
3539
- }
3540
-
3541
- c->write->handler = ngx_http_spdy_write_handler;
3542
-
3543
- rev->handler = ngx_http_spdy_read_handler;
3544
- ngx_http_spdy_read_handler(rev);
3545
- }
3546
-
3547
-
3548
- static void
3549
- ngx_http_spdy_finalize_connection(ngx_http_spdy_connection_t *sc,
3550
- ngx_int_t rc)
3551
- {
3552
- ngx_uint_t i, size;
3553
- ngx_event_t *ev;
3554
- ngx_connection_t *c, *fc;
3555
- ngx_http_request_t *r;
3556
- ngx_http_spdy_stream_t *stream;
3557
- ngx_http_spdy_srv_conf_t *sscf;
3558
-
3559
- c = sc->connection;
3560
-
3561
- if (!sc->processing) {
3562
- ngx_http_close_connection(c);
3563
- return;
3564
- }
3565
-
3566
- c->error = 1;
3567
- c->read->handler = ngx_http_empty_handler;
3568
- c->write->handler = ngx_http_empty_handler;
3569
-
3570
- sc->last_out = NULL;
3571
-
3572
- sc->blocked = 1;
3573
-
3574
- sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
3575
- ngx_http_spdy_module);
3576
-
3577
- size = ngx_http_spdy_streams_index_size(sscf);
3578
-
3579
- for (i = 0; i < size; i++) {
3580
- stream = sc->streams_index[i];
3581
-
3582
- while (stream) {
3583
- stream->handled = 0;
3584
-
3585
- r = stream->request;
3586
- fc = r->connection;
3587
-
3588
- fc->error = 1;
3589
-
3590
- if (stream->queued) {
3591
- stream->queued = 0;
3592
-
3593
- ev = fc->write;
3594
- ev->delayed = 0;
3595
-
3596
- } else {
3597
- ev = fc->read;
3598
- }
3599
-
3600
- stream = stream->index;
3601
-
3602
- ev->eof = 1;
3603
- ev->handler(ev);
3604
- }
3605
- }
3606
-
3607
- sc->blocked = 0;
3608
-
3609
- if (sc->processing) {
3610
- return;
3611
- }
3612
-
3613
- ngx_http_close_connection(c);
3614
- }
3615
-
3616
-
3617
- static ngx_int_t
3618
- ngx_http_spdy_adjust_windows(ngx_http_spdy_connection_t *sc, ssize_t delta)
3619
- {
3620
- ngx_uint_t i, size;
3621
- ngx_event_t *wev;
3622
- ngx_http_spdy_stream_t *stream, *sn;
3623
- ngx_http_spdy_srv_conf_t *sscf;
3624
-
3625
- sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
3626
- ngx_http_spdy_module);
3627
-
3628
- size = ngx_http_spdy_streams_index_size(sscf);
3629
-
3630
- for (i = 0; i < size; i++) {
3631
-
3632
- for (stream = sc->streams_index[i]; stream; stream = sn) {
3633
- sn = stream->index;
3634
-
3635
- if (delta > 0
3636
- && stream->send_window
3637
- > (ssize_t) (NGX_SPDY_MAX_WINDOW - delta))
3638
- {
3639
- if (ngx_http_spdy_terminate_stream(sc, stream,
3640
- NGX_SPDY_FLOW_CONTROL_ERROR)
3641
- == NGX_ERROR)
3642
- {
3643
- return NGX_ERROR;
3644
- }
3645
-
3646
- continue;
3647
- }
3648
-
3649
- stream->send_window += delta;
3650
-
3651
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
3652
- "spdy:%ui adjust window:%z",
3653
- stream->id, stream->send_window);
3654
-
3655
- if (stream->send_window > 0 && stream->exhausted) {
3656
- stream->exhausted = 0;
3657
-
3658
- wev = stream->request->connection->write;
3659
-
3660
- if (!wev->timer_set) {
3661
- wev->delayed = 0;
3662
- wev->handler(wev);
3663
- }
3664
- }
3665
- }
3666
- }
3667
-
3668
- return NGX_OK;
3669
- }
3670
-
3671
-
3672
- static void
3673
- ngx_http_spdy_pool_cleanup(void *data)
3674
- {
3675
- ngx_http_spdy_connection_t *sc = data;
3676
-
3677
- if (sc->pool) {
3678
- ngx_destroy_pool(sc->pool);
3679
- }
3680
- }
3681
-
3682
-
3683
- static void *
3684
- ngx_http_spdy_zalloc(void *opaque, u_int items, u_int size)
3685
- {
3686
- ngx_http_spdy_connection_t *sc = opaque;
3687
-
3688
- return ngx_palloc(sc->connection->pool, items * size);
3689
- }
3690
-
3691
-
3692
- static void
3693
- ngx_http_spdy_zfree(void *opaque, void *address)
3694
- {
3695
- #if 0
3696
- ngx_http_spdy_connection_t *sc = opaque;
3697
-
3698
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
3699
- "spdy zfree: %p", address);
3700
- #endif
3701
- }