nginxtra 1.6.3.9 → 1.8.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (181) 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 +358 -14
  6. data/vendor/nginx/CHANGES.ru +372 -18
  7. data/vendor/nginx/LICENSE +2 -2
  8. data/vendor/nginx/auto/cc/clang +5 -0
  9. data/vendor/nginx/auto/cc/gcc +5 -0
  10. data/vendor/nginx/auto/lib/google-perftools/conf +1 -1
  11. data/vendor/nginx/auto/lib/openssl/make +0 -5
  12. data/vendor/nginx/auto/lib/perl/conf +9 -1
  13. data/vendor/nginx/auto/make +1 -1
  14. data/vendor/nginx/auto/modules +11 -0
  15. data/vendor/nginx/auto/options +10 -2
  16. data/vendor/nginx/auto/os/darwin +0 -1
  17. data/vendor/nginx/auto/os/freebsd +6 -23
  18. data/vendor/nginx/auto/sources +16 -14
  19. data/vendor/nginx/auto/summary +3 -24
  20. data/vendor/nginx/auto/threads +20 -0
  21. data/vendor/nginx/auto/types/sizeof +2 -12
  22. data/vendor/nginx/auto/unix +50 -6
  23. data/vendor/nginx/configure +5 -0
  24. data/vendor/nginx/contrib/vim/syntax/nginx.vim +183 -50
  25. data/vendor/nginx/src/core/nginx.c +21 -9
  26. data/vendor/nginx/src/core/nginx.h +8 -2
  27. data/vendor/nginx/src/core/ngx_buf.c +88 -0
  28. data/vendor/nginx/src/core/ngx_buf.h +15 -1
  29. data/vendor/nginx/src/core/ngx_conf_file.c +4 -1
  30. data/vendor/nginx/src/core/ngx_connection.c +25 -66
  31. data/vendor/nginx/src/core/ngx_connection.h +1 -3
  32. data/vendor/nginx/src/core/ngx_core.h +11 -3
  33. data/vendor/nginx/src/core/ngx_crypt.c +1 -1
  34. data/vendor/nginx/src/core/ngx_cycle.c +7 -1
  35. data/vendor/nginx/src/core/ngx_cycle.h +6 -2
  36. data/vendor/nginx/src/core/ngx_file.c +13 -5
  37. data/vendor/nginx/src/core/ngx_file.h +6 -0
  38. data/vendor/nginx/src/core/ngx_log.c +215 -21
  39. data/vendor/nginx/src/core/ngx_log.h +9 -1
  40. data/vendor/nginx/src/core/ngx_output_chain.c +104 -15
  41. data/vendor/nginx/src/core/ngx_palloc.c +3 -7
  42. data/vendor/nginx/src/core/ngx_rbtree.c +2 -4
  43. data/vendor/nginx/src/core/ngx_rbtree.h +2 -4
  44. data/vendor/nginx/src/core/ngx_regex.c +14 -6
  45. data/vendor/nginx/src/core/ngx_resolver.c +16 -23
  46. data/vendor/nginx/src/core/ngx_resolver.h +8 -7
  47. data/vendor/nginx/src/core/ngx_shmtx.c +1 -1
  48. data/vendor/nginx/src/core/ngx_slab.c +89 -2
  49. data/vendor/nginx/src/core/ngx_slab.h +3 -0
  50. data/vendor/nginx/src/core/ngx_string.c +58 -2
  51. data/vendor/nginx/src/core/ngx_string.h +1 -0
  52. data/vendor/nginx/src/core/ngx_syslog.c +374 -0
  53. data/vendor/nginx/src/core/ngx_syslog.h +30 -0
  54. data/vendor/nginx/src/core/ngx_thread_pool.c +630 -0
  55. data/vendor/nginx/src/core/ngx_thread_pool.h +36 -0
  56. data/vendor/nginx/src/core/ngx_times.c +19 -2
  57. data/vendor/nginx/src/core/ngx_times.h +1 -0
  58. data/vendor/nginx/src/event/modules/ngx_aio_module.c +1 -1
  59. data/vendor/nginx/src/event/modules/ngx_devpoll_module.c +9 -24
  60. data/vendor/nginx/src/event/modules/ngx_epoll_module.c +152 -28
  61. data/vendor/nginx/src/event/modules/ngx_eventport_module.c +43 -25
  62. data/vendor/nginx/src/event/modules/ngx_kqueue_module.c +86 -156
  63. data/vendor/nginx/src/event/modules/ngx_poll_module.c +21 -37
  64. data/vendor/nginx/src/event/modules/ngx_rtsig_module.c +15 -27
  65. data/vendor/nginx/src/event/modules/ngx_select_module.c +10 -12
  66. data/vendor/nginx/src/event/modules/ngx_win32_select_module.c +7 -9
  67. data/vendor/nginx/src/event/ngx_event.c +5 -33
  68. data/vendor/nginx/src/event/ngx_event.h +15 -50
  69. data/vendor/nginx/src/event/ngx_event_accept.c +11 -10
  70. data/vendor/nginx/src/event/ngx_event_connect.c +0 -11
  71. data/vendor/nginx/src/event/ngx_event_connect.h +1 -4
  72. data/vendor/nginx/src/event/ngx_event_openssl.c +622 -38
  73. data/vendor/nginx/src/event/ngx_event_openssl.h +20 -2
  74. data/vendor/nginx/src/event/ngx_event_openssl_stapling.c +5 -1
  75. data/vendor/nginx/src/event/ngx_event_pipe.c +45 -19
  76. data/vendor/nginx/src/event/ngx_event_pipe.h +3 -0
  77. data/vendor/nginx/src/event/ngx_event_posted.c +7 -145
  78. data/vendor/nginx/src/event/ngx_event_posted.h +12 -39
  79. data/vendor/nginx/src/event/ngx_event_timer.c +50 -70
  80. data/vendor/nginx/src/event/ngx_event_timer.h +2 -14
  81. data/vendor/nginx/src/http/modules/ngx_http_addition_filter_module.c +1 -1
  82. data/vendor/nginx/src/http/modules/ngx_http_autoindex_module.c +416 -71
  83. data/vendor/nginx/src/http/modules/ngx_http_charset_filter_module.c +19 -15
  84. data/vendor/nginx/src/http/modules/ngx_http_dav_module.c +16 -4
  85. data/vendor/nginx/src/http/modules/ngx_http_fastcgi_module.c +601 -134
  86. data/vendor/nginx/src/http/modules/ngx_http_geo_module.c +1 -1
  87. data/vendor/nginx/src/http/modules/ngx_http_geoip_module.c +9 -3
  88. data/vendor/nginx/src/http/modules/ngx_http_gunzip_filter_module.c +9 -3
  89. data/vendor/nginx/src/http/modules/ngx_http_gzip_filter_module.c +9 -3
  90. data/vendor/nginx/src/http/modules/ngx_http_gzip_static_module.c +0 -2
  91. data/vendor/nginx/src/http/modules/ngx_http_headers_filter_module.c +197 -91
  92. data/vendor/nginx/src/http/modules/ngx_http_image_filter_module.c +1 -0
  93. data/vendor/nginx/src/http/modules/ngx_http_limit_conn_module.c +65 -162
  94. data/vendor/nginx/src/http/modules/ngx_http_limit_req_module.c +53 -67
  95. data/vendor/nginx/src/http/modules/ngx_http_log_module.c +128 -23
  96. data/vendor/nginx/src/http/modules/ngx_http_memcached_module.c +25 -6
  97. data/vendor/nginx/src/http/modules/ngx_http_mp4_module.c +1 -1
  98. data/vendor/nginx/src/http/modules/ngx_http_not_modified_filter_module.c +39 -13
  99. data/vendor/nginx/src/http/modules/ngx_http_proxy_module.c +697 -141
  100. data/vendor/nginx/src/http/modules/ngx_http_rewrite_module.c +5 -1
  101. data/vendor/nginx/src/http/modules/ngx_http_scgi_module.c +282 -125
  102. data/vendor/nginx/src/http/modules/ngx_http_ssi_filter_module.c +4 -1
  103. data/vendor/nginx/src/http/modules/ngx_http_ssl_module.c +44 -1
  104. data/vendor/nginx/src/http/modules/ngx_http_ssl_module.h +2 -0
  105. data/vendor/nginx/src/http/modules/ngx_http_stub_status_module.c +10 -8
  106. data/vendor/nginx/src/http/modules/ngx_http_sub_filter_module.c +18 -3
  107. data/vendor/nginx/src/http/modules/ngx_http_upstream_hash_module.c +641 -0
  108. data/vendor/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c +1 -1
  109. data/vendor/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c +3 -21
  110. data/vendor/nginx/src/http/modules/ngx_http_upstream_least_conn_module.c +0 -5
  111. data/vendor/nginx/src/http/modules/ngx_http_uwsgi_module.c +449 -125
  112. data/vendor/nginx/src/http/modules/ngx_http_xslt_filter_module.c +4 -2
  113. data/vendor/nginx/src/http/modules/perl/ngx_http_perl_module.c +2 -1
  114. data/vendor/nginx/src/http/ngx_http.c +10 -5
  115. data/vendor/nginx/src/http/ngx_http.h +4 -4
  116. data/vendor/nginx/src/http/ngx_http_cache.h +26 -1
  117. data/vendor/nginx/src/http/ngx_http_copy_filter_module.c +109 -68
  118. data/vendor/nginx/src/http/ngx_http_core_module.c +191 -46
  119. data/vendor/nginx/src/http/ngx_http_core_module.h +16 -4
  120. data/vendor/nginx/src/http/ngx_http_file_cache.c +584 -67
  121. data/vendor/nginx/src/http/ngx_http_parse.c +55 -4
  122. data/vendor/nginx/src/http/ngx_http_request.c +14 -6
  123. data/vendor/nginx/src/http/ngx_http_request.h +12 -4
  124. data/vendor/nginx/src/http/ngx_http_request_body.c +114 -28
  125. data/vendor/nginx/src/http/ngx_http_spdy.c +383 -229
  126. data/vendor/nginx/src/http/ngx_http_spdy.h +8 -5
  127. data/vendor/nginx/src/http/ngx_http_spdy_filter_module.c +12 -4
  128. data/vendor/nginx/src/http/ngx_http_special_response.c +2 -2
  129. data/vendor/nginx/src/http/ngx_http_upstream.c +808 -132
  130. data/vendor/nginx/src/http/ngx_http_upstream.h +33 -3
  131. data/vendor/nginx/src/http/ngx_http_upstream_round_robin.c +72 -65
  132. data/vendor/nginx/src/http/ngx_http_upstream_round_robin.h +1 -2
  133. data/vendor/nginx/src/http/ngx_http_variables.c +47 -3
  134. data/vendor/nginx/src/http/ngx_http_write_filter_module.c +15 -6
  135. data/vendor/nginx/src/mail/ngx_mail.c +2 -3
  136. data/vendor/nginx/src/mail/ngx_mail.h +2 -0
  137. data/vendor/nginx/src/mail/ngx_mail_auth_http_module.c +140 -11
  138. data/vendor/nginx/src/mail/ngx_mail_core_module.c +3 -3
  139. data/vendor/nginx/src/mail/ngx_mail_handler.c +79 -2
  140. data/vendor/nginx/src/mail/ngx_mail_imap_module.c +3 -1
  141. data/vendor/nginx/src/mail/ngx_mail_pop3_module.c +3 -1
  142. data/vendor/nginx/src/mail/ngx_mail_smtp_module.c +3 -1
  143. data/vendor/nginx/src/mail/ngx_mail_ssl_module.c +125 -1
  144. data/vendor/nginx/src/mail/ngx_mail_ssl_module.h +8 -0
  145. data/vendor/nginx/src/misc/ngx_cpp_test_module.cpp +1 -1
  146. data/vendor/nginx/src/os/unix/ngx_aio_read_chain.c +1 -1
  147. data/vendor/nginx/src/os/unix/ngx_channel.c +0 -7
  148. data/vendor/nginx/src/os/unix/ngx_darwin_config.h +0 -3
  149. data/vendor/nginx/src/os/unix/ngx_darwin_sendfile_chain.c +44 -208
  150. data/vendor/nginx/src/os/unix/ngx_file_aio_read.c +25 -17
  151. data/vendor/nginx/src/os/unix/ngx_files.c +109 -0
  152. data/vendor/nginx/src/os/unix/ngx_files.h +6 -0
  153. data/vendor/nginx/src/os/unix/ngx_freebsd_config.h +0 -6
  154. data/vendor/nginx/src/os/unix/ngx_freebsd_sendfile_chain.c +78 -206
  155. data/vendor/nginx/src/os/unix/ngx_linux_aio_read.c +25 -14
  156. data/vendor/nginx/src/os/unix/ngx_linux_config.h +4 -1
  157. data/vendor/nginx/src/os/unix/ngx_linux_sendfile_chain.c +235 -194
  158. data/vendor/nginx/src/os/unix/ngx_os.h +25 -3
  159. data/vendor/nginx/src/os/unix/ngx_posix_init.c +4 -2
  160. data/vendor/nginx/src/os/unix/ngx_process_cycle.c +13 -195
  161. data/vendor/nginx/src/os/unix/ngx_process_cycle.h +0 -1
  162. data/vendor/nginx/src/os/unix/ngx_readv_chain.c +27 -108
  163. data/vendor/nginx/src/os/unix/ngx_setproctitle.h +2 -2
  164. data/vendor/nginx/src/os/unix/ngx_solaris_sendfilev_chain.c +12 -67
  165. data/vendor/nginx/src/os/unix/ngx_thread.h +26 -83
  166. data/vendor/nginx/src/os/unix/ngx_thread_cond.c +87 -0
  167. data/vendor/nginx/src/os/unix/ngx_thread_id.c +70 -0
  168. data/vendor/nginx/src/os/unix/ngx_thread_mutex.c +174 -0
  169. data/vendor/nginx/src/os/unix/ngx_user.c +2 -20
  170. data/vendor/nginx/src/os/unix/ngx_writev_chain.c +129 -98
  171. metadata +16 -17
  172. data/vendor/nginx/auto/lib/zlib/patch.zlib.h +0 -10
  173. data/vendor/nginx/src/event/ngx_event_busy_lock.c +0 -286
  174. data/vendor/nginx/src/event/ngx_event_busy_lock.h +0 -65
  175. data/vendor/nginx/src/event/ngx_event_mutex.c +0 -70
  176. data/vendor/nginx/src/http/ngx_http_busy_lock.c +0 -307
  177. data/vendor/nginx/src/http/ngx_http_busy_lock.h +0 -54
  178. data/vendor/nginx/src/os/unix/ngx_freebsd_rfork_thread.c +0 -756
  179. data/vendor/nginx/src/os/unix/ngx_freebsd_rfork_thread.h +0 -122
  180. data/vendor/nginx/src/os/unix/ngx_pthread_thread.c +0 -278
  181. data/vendor/nginx/src/os/unix/rfork_thread.S +0 -73
@@ -103,10 +103,10 @@ static u_char *ngx_http_spdy_state_syn_stream(ngx_http_spdy_connection_t *sc,
103
103
  u_char *pos, u_char *end);
104
104
  static u_char *ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc,
105
105
  u_char *pos, u_char *end);
106
- static u_char *ngx_http_spdy_state_headers_error(ngx_http_spdy_connection_t *sc,
107
- u_char *pos, u_char *end);
108
106
  static u_char *ngx_http_spdy_state_headers_skip(ngx_http_spdy_connection_t *sc,
109
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
110
  static u_char *ngx_http_spdy_state_window_update(ngx_http_spdy_connection_t *sc,
111
111
  u_char *pos, u_char *end);
112
112
  static u_char *ngx_http_spdy_state_data(ngx_http_spdy_connection_t *sc,
@@ -125,6 +125,9 @@ static u_char *ngx_http_spdy_state_complete(ngx_http_spdy_connection_t *sc,
125
125
  u_char *pos, u_char *end);
126
126
  static u_char *ngx_http_spdy_state_save(ngx_http_spdy_connection_t *sc,
127
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);
128
131
  static u_char *ngx_http_spdy_state_protocol_error(
129
132
  ngx_http_spdy_connection_t *sc);
130
133
  static u_char *ngx_http_spdy_state_internal_error(
@@ -392,8 +395,7 @@ ngx_http_spdy_init(ngx_event_t *rev)
392
395
  c = rev->data;
393
396
  hc = c->data;
394
397
 
395
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
396
- "init spdy request");
398
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "init spdy request");
397
399
 
398
400
  c->log->action = "processing SPDY";
399
401
 
@@ -421,12 +423,8 @@ ngx_http_spdy_init(ngx_event_t *rev)
421
423
 
422
424
  sc->init_window = NGX_SPDY_INIT_STREAM_WINDOW;
423
425
 
424
- sc->handler = ngx_http_spdy_state_head;
425
-
426
- if (hc->proxy_protocol) {
427
- c->log->action = "reading PROXY protocol";
428
- sc->handler = ngx_http_spdy_proxy_protocol;
429
- }
426
+ sc->handler = hc->proxy_protocol ? ngx_http_spdy_proxy_protocol
427
+ : ngx_http_spdy_state_head;
430
428
 
431
429
  sc->zstream_in.zalloc = ngx_http_spdy_zalloc;
432
430
  sc->zstream_in.zfree = ngx_http_spdy_zfree;
@@ -557,7 +555,7 @@ ngx_http_spdy_read_handler(ngx_event_t *rev)
557
555
 
558
556
  if (n == 0 && (sc->incomplete || sc->processing)) {
559
557
  ngx_log_error(NGX_LOG_INFO, c->log, 0,
560
- "client closed prematurely connection");
558
+ "client prematurely closed connection");
561
559
  }
562
560
 
563
561
  if (n == 0 || n == NGX_ERROR) {
@@ -645,7 +643,7 @@ ngx_http_spdy_write_handler(ngx_event_t *wev)
645
643
  stream->handled = 0;
646
644
 
647
645
  ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
648
- "spdy run stream %ui", stream->id);
646
+ "run spdy stream %ui", stream->id);
649
647
 
650
648
  wev = stream->request->connection->write;
651
649
  wev->handler(wev);
@@ -664,6 +662,7 @@ ngx_http_spdy_write_handler(ngx_event_t *wev)
664
662
  ngx_int_t
665
663
  ngx_http_spdy_send_output_queue(ngx_http_spdy_connection_t *sc)
666
664
  {
665
+ int tcp_nodelay;
667
666
  ngx_chain_t *cl;
668
667
  ngx_event_t *wev;
669
668
  ngx_connection_t *c;
@@ -702,20 +701,52 @@ ngx_http_spdy_send_output_queue(ngx_http_spdy_connection_t *sc)
702
701
  cl = c->send_chain(c, cl, 0);
703
702
 
704
703
  if (cl == NGX_CHAIN_ERROR) {
705
- c->error = 1;
706
-
707
- if (!sc->blocked) {
708
- ngx_post_event(wev, &ngx_posted_events);
709
- }
710
-
711
- return NGX_ERROR;
704
+ goto error;
712
705
  }
713
706
 
714
707
  clcf = ngx_http_get_module_loc_conf(sc->http_connection->conf_ctx,
715
708
  ngx_http_core_module);
716
709
 
717
710
  if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
718
- return NGX_ERROR; /* FIXME */
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;
719
750
  }
720
751
 
721
752
  if (cl) {
@@ -753,6 +784,16 @@ ngx_http_spdy_send_output_queue(ngx_http_spdy_connection_t *sc)
753
784
  sc->last_out = frame;
754
785
 
755
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;
756
797
  }
757
798
 
758
799
 
@@ -820,14 +861,19 @@ static u_char *
820
861
  ngx_http_spdy_proxy_protocol(ngx_http_spdy_connection_t *sc, u_char *pos,
821
862
  u_char *end)
822
863
  {
864
+ ngx_log_t *log;
865
+
866
+ log = sc->connection->log;
867
+ log->action = "reading PROXY protocol";
868
+
823
869
  pos = ngx_proxy_protocol_parse(sc->connection, pos, end);
824
870
 
871
+ log->action = "processing SPDY";
872
+
825
873
  if (pos == NULL) {
826
874
  return ngx_http_spdy_state_protocol_error(sc);
827
875
  }
828
876
 
829
- sc->connection->log->action = "processing SPDY";
830
-
831
877
  return ngx_http_spdy_state_complete(sc, pos, end);
832
878
  }
833
879
 
@@ -856,7 +902,7 @@ ngx_http_spdy_state_head(ngx_http_spdy_connection_t *sc, u_char *pos,
856
902
  pos += sizeof(uint32_t);
857
903
 
858
904
  ngx_log_debug3(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
859
- "spdy process frame head:%08XD f:%Xd l:%uz",
905
+ "process spdy frame head:%08XD f:%Xd l:%uz",
860
906
  head, sc->flags, sc->length);
861
907
 
862
908
  if (ngx_spdy_ctl_frame_check(head)) {
@@ -868,6 +914,8 @@ ngx_http_spdy_state_head(ngx_http_spdy_connection_t *sc, u_char *pos,
868
914
  return ngx_http_spdy_state_syn_stream(sc, pos, end);
869
915
 
870
916
  case NGX_SPDY_SYN_REPLY:
917
+ ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
918
+ "client sent unexpected SYN_REPLY frame");
871
919
  return ngx_http_spdy_state_protocol_error(sc);
872
920
 
873
921
  case NGX_SPDY_RST_STREAM:
@@ -883,6 +931,8 @@ ngx_http_spdy_state_head(ngx_http_spdy_connection_t *sc, u_char *pos,
883
931
  return ngx_http_spdy_state_skip(sc, pos, end); /* TODO */
884
932
 
885
933
  case NGX_SPDY_HEADERS:
934
+ ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
935
+ "client sent unexpected HEADERS frame");
886
936
  return ngx_http_spdy_state_protocol_error(sc);
887
937
 
888
938
  case NGX_SPDY_WINDOW_UPDATE:
@@ -900,10 +950,8 @@ ngx_http_spdy_state_head(ngx_http_spdy_connection_t *sc, u_char *pos,
900
950
  return ngx_http_spdy_state_data(sc, pos, end);
901
951
  }
902
952
 
903
-
904
- /* TODO version & type check */
905
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
906
- "spdy unknown frame");
953
+ ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
954
+ "client sent invalid frame");
907
955
 
908
956
  return ngx_http_spdy_state_protocol_error(sc);
909
957
  }
@@ -923,7 +971,10 @@ ngx_http_spdy_state_syn_stream(ngx_http_spdy_connection_t *sc, u_char *pos,
923
971
  }
924
972
 
925
973
  if (sc->length <= NGX_SPDY_SYN_STREAM_SIZE) {
926
- /* TODO logging */
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
+
927
978
  return ngx_http_spdy_state_protocol_error(sc);
928
979
  }
929
980
 
@@ -937,13 +988,34 @@ ngx_http_spdy_state_syn_stream(ngx_http_spdy_connection_t *sc, u_char *pos,
937
988
  ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
938
989
  "spdy SYN_STREAM frame sid:%ui prio:%ui", sid, prio);
939
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
+
940
1012
  sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
941
1013
  ngx_http_spdy_module);
942
1014
 
943
1015
  if (sc->processing >= sscf->concurrent_streams) {
944
1016
 
945
1017
  ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
946
- "spdy concurrent streams exceeded %ui", sc->processing);
1018
+ "concurrent streams exceeded %ui", sc->processing);
947
1019
 
948
1020
  if (ngx_http_spdy_send_rst_stream(sc, sid, NGX_SPDY_REFUSED_STREAM,
949
1021
  prio)
@@ -968,8 +1040,6 @@ ngx_http_spdy_state_syn_stream(ngx_http_spdy_connection_t *sc, u_char *pos,
968
1040
 
969
1041
  sc->stream = stream;
970
1042
 
971
- sc->last_sid = sid;
972
-
973
1043
  return ngx_http_spdy_state_headers(sc, pos, end);
974
1044
  }
975
1045
 
@@ -982,7 +1052,6 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
982
1052
  size_t size;
983
1053
  ngx_buf_t *buf;
984
1054
  ngx_int_t rc;
985
- ngx_uint_t complete;
986
1055
  ngx_http_request_t *r;
987
1056
 
988
1057
  size = end - pos;
@@ -992,18 +1061,14 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
992
1061
  ngx_http_spdy_state_headers);
993
1062
  }
994
1063
 
995
- if (size >= sc->length) {
1064
+ if (size > sc->length) {
996
1065
  size = sc->length;
997
- complete = 1;
998
-
999
- } else {
1000
- complete = 0;
1001
1066
  }
1002
1067
 
1003
1068
  r = sc->stream->request;
1004
1069
 
1005
1070
  ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1006
- "spdy process HEADERS %uz of %uz", size, sc->length);
1071
+ "process spdy header block %uz of %uz", size, sc->length);
1007
1072
 
1008
1073
  buf = r->header_in;
1009
1074
 
@@ -1019,11 +1084,21 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
1019
1084
  if (z == Z_NEED_DICT) {
1020
1085
  z = inflateSetDictionary(&sc->zstream_in, ngx_http_spdy_dict,
1021
1086
  sizeof(ngx_http_spdy_dict));
1087
+
1022
1088
  if (z != Z_OK) {
1023
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1024
- "spdy inflateSetDictionary() failed: %d", z);
1025
- ngx_http_spdy_close_stream(sc->stream, 0);
1026
- return ngx_http_spdy_state_protocol_error(sc);
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);
1027
1102
  }
1028
1103
 
1029
1104
  ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -1033,19 +1108,16 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
1033
1108
  : Z_OK;
1034
1109
  }
1035
1110
 
1036
- if (z != Z_OK) {
1037
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1038
- "spdy inflate() failed: %d", z);
1039
- ngx_http_spdy_close_stream(sc->stream, 0);
1040
- return ngx_http_spdy_state_protocol_error(sc);
1041
- }
1042
-
1043
1111
  ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1044
1112
  "spdy inflate out: ni:%p no:%p ai:%ud ao:%ud rc:%d",
1045
1113
  sc->zstream_in.next_in, sc->zstream_in.next_out,
1046
1114
  sc->zstream_in.avail_in, sc->zstream_in.avail_out,
1047
1115
  z);
1048
1116
 
1117
+ if (z != Z_OK) {
1118
+ return ngx_http_spdy_state_inflate_error(sc, z);
1119
+ }
1120
+
1049
1121
  sc->length -= sc->zstream_in.next_in - pos;
1050
1122
  pos = sc->zstream_in.next_in;
1051
1123
 
@@ -1055,12 +1127,11 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
1055
1127
 
1056
1128
  if (buf->last - buf->pos < NGX_SPDY_NV_NUM_SIZE) {
1057
1129
 
1058
- if (complete) {
1059
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1060
- "client sent SYN_STREAM frame "
1061
- "with invalid HEADERS block");
1062
- ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_BAD_REQUEST);
1063
- return ngx_http_spdy_state_protocol_error(sc);
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);
1064
1135
  }
1065
1136
 
1066
1137
  return ngx_http_spdy_state_save(sc, pos, end,
@@ -1072,7 +1143,7 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
1072
1143
  buf->pos += NGX_SPDY_NV_NUM_SIZE;
1073
1144
 
1074
1145
  ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1075
- "spdy HEADERS block consists of %ui entries",
1146
+ "spdy header block has %ui entries",
1076
1147
  sc->entries);
1077
1148
 
1078
1149
  if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
@@ -1081,7 +1152,7 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
1081
1152
  {
1082
1153
  ngx_http_spdy_close_stream(sc->stream,
1083
1154
  NGX_HTTP_INTERNAL_SERVER_ERROR);
1084
- return ngx_http_spdy_state_headers_error(sc, pos, end);
1155
+ return ngx_http_spdy_state_headers_skip(sc, pos, end);
1085
1156
  }
1086
1157
 
1087
1158
  if (ngx_array_init(&r->headers_in.cookies, r->pool, 2,
@@ -1090,7 +1161,7 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
1090
1161
  {
1091
1162
  ngx_http_spdy_close_stream(sc->stream,
1092
1163
  NGX_HTTP_INTERNAL_SERVER_ERROR);
1093
- return ngx_http_spdy_state_headers_error(sc, pos, end);
1164
+ return ngx_http_spdy_state_headers_skip(sc, pos, end);
1094
1165
  }
1095
1166
  }
1096
1167
 
@@ -1113,16 +1184,15 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
1113
1184
  rc = ngx_http_spdy_alloc_large_header_buffer(r);
1114
1185
 
1115
1186
  if (rc == NGX_DECLINED) {
1116
- /* TODO logging */
1117
1187
  ngx_http_finalize_request(r,
1118
1188
  NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
1119
- return ngx_http_spdy_state_headers_error(sc, pos, end);
1189
+ return ngx_http_spdy_state_headers_skip(sc, pos, end);
1120
1190
  }
1121
1191
 
1122
1192
  if (rc != NGX_OK) {
1123
1193
  ngx_http_spdy_close_stream(sc->stream,
1124
1194
  NGX_HTTP_INTERNAL_SERVER_ERROR);
1125
- return ngx_http_spdy_state_headers_error(sc, pos, end);
1195
+ return ngx_http_spdy_state_headers_skip(sc, pos, end);
1126
1196
  }
1127
1197
 
1128
1198
  /* null-terminate the last processed header name or value */
@@ -1137,11 +1207,14 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
1137
1207
 
1138
1208
  z = inflate(&sc->zstream_in, Z_NO_FLUSH);
1139
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
+
1140
1216
  if (z != Z_OK) {
1141
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1142
- "spdy inflate() failed: %d", z);
1143
- ngx_http_spdy_close_stream(sc->stream, 0);
1144
- return ngx_http_spdy_state_protocol_error(sc);
1217
+ return ngx_http_spdy_state_inflate_error(sc, z);
1145
1218
  }
1146
1219
 
1147
1220
  sc->length -= sc->zstream_in.next_in - pos;
@@ -1152,33 +1225,22 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
1152
1225
  continue;
1153
1226
  }
1154
1227
 
1155
- if (complete) {
1156
- /* TODO: improve error message */
1228
+ if (sc->length == 0) {
1157
1229
  ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1158
- "spdy again while last chunk");
1159
- ngx_http_spdy_close_stream(sc->stream, 0);
1160
- return ngx_http_spdy_state_protocol_error(sc);
1230
+ "premature end of spdy header block");
1231
+
1232
+ return ngx_http_spdy_state_headers_error(sc, pos, end);
1161
1233
  }
1162
1234
 
1163
1235
  return ngx_http_spdy_state_save(sc, pos, end,
1164
1236
  ngx_http_spdy_state_headers);
1165
1237
 
1166
- case NGX_HTTP_PARSE_INVALID_REQUEST:
1167
-
1168
- /* TODO: improve error message */
1169
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1170
- "client sent invalid header line");
1171
-
1238
+ case NGX_HTTP_PARSE_INVALID_HEADER:
1172
1239
  ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
1240
+ return ngx_http_spdy_state_headers_skip(sc, pos, end);
1173
1241
 
1242
+ default: /* NGX_ERROR */
1174
1243
  return ngx_http_spdy_state_headers_error(sc, pos, end);
1175
-
1176
- default: /* NGX_HTTP_PARSE_INVALID_HEADER */
1177
-
1178
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1179
- "client sent invalid HEADERS spdy frame");
1180
- ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_BAD_REQUEST);
1181
- return ngx_http_spdy_state_protocol_error(sc);
1182
1244
  }
1183
1245
 
1184
1246
  /* a header line has been parsed successfully */
@@ -1187,29 +1249,27 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
1187
1249
 
1188
1250
  if (rc != NGX_OK) {
1189
1251
  if (rc == NGX_HTTP_PARSE_INVALID_HEADER) {
1190
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1191
- "client sent invalid HEADERS spdy frame");
1192
- ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_BAD_REQUEST);
1193
- return ngx_http_spdy_state_protocol_error(sc);
1252
+ ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
1253
+ return ngx_http_spdy_state_headers_skip(sc, pos, end);
1194
1254
  }
1195
1255
 
1196
- if (rc == NGX_HTTP_PARSE_INVALID_REQUEST) {
1197
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
1256
+ if (rc != NGX_ABORT) {
1257
+ ngx_http_spdy_close_stream(sc->stream,
1258
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
1198
1259
  }
1199
1260
 
1200
- return ngx_http_spdy_state_headers_error(sc, pos, end);
1261
+ return ngx_http_spdy_state_headers_skip(sc, pos, end);
1201
1262
  }
1202
1263
  }
1203
1264
 
1204
1265
  if (buf->pos != buf->last || sc->zstream_in.avail_in) {
1205
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1206
- "client sent SYN_STREAM frame "
1207
- "with invalid HEADERS block");
1208
- ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_BAD_REQUEST);
1209
- return ngx_http_spdy_state_protocol_error(sc);
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);
1210
1270
  }
1211
1271
 
1212
- if (!complete) {
1272
+ if (sc->length) {
1213
1273
  return ngx_http_spdy_state_save(sc, pos, end,
1214
1274
  ngx_http_spdy_state_headers);
1215
1275
  }
@@ -1223,18 +1283,6 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
1223
1283
  }
1224
1284
 
1225
1285
 
1226
- static u_char *
1227
- ngx_http_spdy_state_headers_error(ngx_http_spdy_connection_t *sc, u_char *pos,
1228
- u_char *end)
1229
- {
1230
- if (sc->connection->error) {
1231
- return ngx_http_spdy_state_internal_error(sc);
1232
- }
1233
-
1234
- return ngx_http_spdy_state_headers_skip(sc, pos, end);
1235
- }
1236
-
1237
-
1238
1286
  static u_char *
1239
1287
  ngx_http_spdy_state_headers_skip(ngx_http_spdy_connection_t *sc, u_char *pos,
1240
1288
  u_char *end)
@@ -1254,6 +1302,9 @@ ngx_http_spdy_state_headers_skip(ngx_http_spdy_connection_t *sc, u_char *pos,
1254
1302
  ngx_http_spdy_state_headers_skip);
1255
1303
  }
1256
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
+
1257
1308
  sc->zstream_in.next_in = pos;
1258
1309
  sc->zstream_in.avail_in = (size < sc->length) ? size : sc->length;
1259
1310
 
@@ -1263,12 +1314,14 @@ ngx_http_spdy_state_headers_skip(ngx_http_spdy_connection_t *sc, u_char *pos,
1263
1314
 
1264
1315
  n = inflate(&sc->zstream_in, Z_NO_FLUSH);
1265
1316
 
1266
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1267
- "spdy inflate(): %d", n);
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);
1268
1322
 
1269
1323
  if (n != Z_OK) {
1270
- /* TODO: logging */
1271
- return ngx_http_spdy_state_protocol_error(sc);
1324
+ return ngx_http_spdy_state_inflate_error(sc, n);
1272
1325
  }
1273
1326
  }
1274
1327
 
@@ -1284,6 +1337,33 @@ ngx_http_spdy_state_headers_skip(ngx_http_spdy_connection_t *sc, u_char *pos,
1284
1337
  }
1285
1338
 
1286
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
+
1287
1367
  static u_char *
1288
1368
  ngx_http_spdy_state_window_update(ngx_http_spdy_connection_t *sc, u_char *pos,
1289
1369
  u_char *end)
@@ -1316,22 +1396,14 @@ ngx_http_spdy_state_window_update(ngx_http_spdy_connection_t *sc, u_char *pos,
1316
1396
  pos += NGX_SPDY_DELTA_SIZE;
1317
1397
 
1318
1398
  ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1319
- "spdy WINDOW_UPDATE sid:%ui delta:%ui", sid, delta);
1399
+ "spdy WINDOW_UPDATE sid:%ui delta:%uz", sid, delta);
1320
1400
 
1321
1401
  if (sid) {
1322
1402
  stream = ngx_http_spdy_get_stream_by_id(sc, sid);
1323
1403
 
1324
1404
  if (stream == NULL) {
1325
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
1326
- "client sent WINDOW_UPDATE frame "
1327
- "for unknown stream %ui", sid);
1328
-
1329
- if (ngx_http_spdy_send_rst_stream(sc, sid, NGX_SPDY_INVALID_STREAM,
1330
- NGX_SPDY_LOWEST_PRIORITY)
1331
- == NGX_ERROR)
1332
- {
1333
- return ngx_http_spdy_state_internal_error(sc);
1334
- }
1405
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1406
+ "unknown spdy stream");
1335
1407
 
1336
1408
  return ngx_http_spdy_state_complete(sc, pos, end);
1337
1409
  }
@@ -1341,7 +1413,7 @@ ngx_http_spdy_state_window_update(ngx_http_spdy_connection_t *sc, u_char *pos,
1341
1413
  ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
1342
1414
  "client violated flow control for stream %ui: "
1343
1415
  "received WINDOW_UPDATE frame with delta %uz "
1344
- "that is not allowed for window %z",
1416
+ "not allowed for window %z",
1345
1417
  sid, delta, stream->send_window);
1346
1418
 
1347
1419
  if (ngx_http_spdy_terminate_stream(sc, stream,
@@ -1374,7 +1446,7 @@ ngx_http_spdy_state_window_update(ngx_http_spdy_connection_t *sc, u_char *pos,
1374
1446
  ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
1375
1447
  "client violated connection flow control: "
1376
1448
  "received WINDOW_UPDATE frame with delta %uz "
1377
- "that is not allowed for window %uz",
1449
+ "not allowed for window %uz",
1378
1450
  delta, sc->send_window);
1379
1451
 
1380
1452
  return ngx_http_spdy_state_protocol_error(sc);
@@ -1417,8 +1489,8 @@ ngx_http_spdy_state_data(ngx_http_spdy_connection_t *sc, u_char *pos,
1417
1489
 
1418
1490
  if (sc->length > sc->recv_window) {
1419
1491
  ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
1420
- "client violated connection flow control: length of "
1421
- "received DATA frame %uz, while available window %uz",
1492
+ "client violated connection flow control: "
1493
+ "received DATA frame length %uz, available window %uz",
1422
1494
  sc->length, sc->recv_window);
1423
1495
 
1424
1496
  return ngx_http_spdy_state_protocol_error(sc);
@@ -1442,13 +1514,16 @@ ngx_http_spdy_state_data(ngx_http_spdy_connection_t *sc, u_char *pos,
1442
1514
  stream = sc->stream;
1443
1515
 
1444
1516
  if (stream == NULL) {
1517
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1518
+ "unknown spdy stream");
1519
+
1445
1520
  return ngx_http_spdy_state_skip(sc, pos, end);
1446
1521
  }
1447
1522
 
1448
1523
  if (sc->length > stream->recv_window) {
1449
1524
  ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
1450
- "client violated flow control for stream %ui: length of "
1451
- "received DATA frame %uz, while available window %uz",
1525
+ "client violated flow control for stream %ui: "
1526
+ "received DATA frame length %uz, available window %uz",
1452
1527
  stream->id, sc->length, stream->recv_window);
1453
1528
 
1454
1529
  if (ngx_http_spdy_terminate_stream(sc, stream,
@@ -1478,7 +1553,7 @@ ngx_http_spdy_state_data(ngx_http_spdy_connection_t *sc, u_char *pos,
1478
1553
 
1479
1554
  if (stream->in_closed) {
1480
1555
  ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
1481
- "client sent DATA frame for half closed stream %ui",
1556
+ "client sent DATA frame for half-closed stream %ui",
1482
1557
  stream->id);
1483
1558
 
1484
1559
  if (ngx_http_spdy_terminate_stream(sc, stream,
@@ -1521,7 +1596,10 @@ ngx_http_spdy_state_read_data(ngx_http_spdy_connection_t *sc, u_char *pos,
1521
1596
  stream->in_closed = 1;
1522
1597
  }
1523
1598
 
1524
- /* TODO log and accounting */
1599
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1600
+ "skipping spdy DATA frame, reason: %d",
1601
+ stream->skip_data);
1602
+
1525
1603
  return ngx_http_spdy_state_skip(sc, pos, end);
1526
1604
  }
1527
1605
 
@@ -1550,7 +1628,10 @@ ngx_http_spdy_state_read_data(ngx_http_spdy_connection_t *sc, u_char *pos,
1550
1628
  if (r->headers_in.content_length_n != -1
1551
1629
  && r->headers_in.content_length_n < rb->rest)
1552
1630
  {
1553
- /* TODO logging */
1631
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1632
+ "client intended to send body data "
1633
+ "larger than declared");
1634
+
1554
1635
  stream->skip_data = NGX_SPDY_DATA_ERROR;
1555
1636
  goto error;
1556
1637
 
@@ -1561,9 +1642,8 @@ ngx_http_spdy_state_read_data(ngx_http_spdy_connection_t *sc, u_char *pos,
1561
1642
  && clcf->client_max_body_size < rb->rest)
1562
1643
  {
1563
1644
  ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1564
- "client intended to send too large chunked "
1565
- "body: %O bytes",
1566
- rb->rest);
1645
+ "client intended to send "
1646
+ "too large chunked body: %O bytes", rb->rest);
1567
1647
 
1568
1648
  stream->skip_data = NGX_SPDY_DATA_ERROR;
1569
1649
  goto error;
@@ -1615,7 +1695,7 @@ ngx_http_spdy_state_read_data(ngx_http_spdy_connection_t *sc, u_char *pos,
1615
1695
  } else if (r->headers_in.content_length_n != rb->rest) {
1616
1696
  ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1617
1697
  "client prematurely closed stream: "
1618
- "%O of %O bytes of request body received",
1698
+ "only %O out of %O bytes of request body received",
1619
1699
  rb->rest, r->headers_in.content_length_n);
1620
1700
 
1621
1701
  stream->skip_data = NGX_SPDY_DATA_ERROR;
@@ -1694,9 +1774,11 @@ ngx_http_spdy_state_rst_stream(ngx_http_spdy_connection_t *sc, u_char *pos,
1694
1774
  "spdy RST_STREAM sid:%ui st:%ui", sid, status);
1695
1775
 
1696
1776
  stream = ngx_http_spdy_get_stream_by_id(sc, sid);
1777
+
1697
1778
  if (stream == NULL) {
1698
1779
  ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1699
- "unknown stream, probably it has been closed already");
1780
+ "unknown spdy stream");
1781
+
1700
1782
  return ngx_http_spdy_state_complete(sc, pos, end);
1701
1783
  }
1702
1784
 
@@ -1715,7 +1797,7 @@ ngx_http_spdy_state_rst_stream(ngx_http_spdy_connection_t *sc, u_char *pos,
1715
1797
 
1716
1798
  case NGX_SPDY_INTERNAL_ERROR:
1717
1799
  ngx_log_error(NGX_LOG_INFO, fc->log, 0,
1718
- "client terminated stream %ui because of internal error",
1800
+ "client terminated stream %ui due to internal error",
1719
1801
  sid);
1720
1802
  break;
1721
1803
 
@@ -1747,7 +1829,10 @@ ngx_http_spdy_state_ping(ngx_http_spdy_connection_t *sc, u_char *pos,
1747
1829
  }
1748
1830
 
1749
1831
  if (sc->length != NGX_SPDY_PING_SIZE) {
1750
- /* TODO logging */
1832
+ ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
1833
+ "client sent PING frame with incorrect length %uz",
1834
+ sc->length);
1835
+
1751
1836
  return ngx_http_spdy_state_protocol_error(sc);
1752
1837
  }
1753
1838
 
@@ -1787,6 +1872,9 @@ ngx_http_spdy_state_skip(ngx_http_spdy_connection_t *sc, u_char *pos,
1787
1872
 
1788
1873
  size = end - pos;
1789
1874
 
1875
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1876
+ "spdy frame skip %uz of %uz", size, sc->length);
1877
+
1790
1878
  if (size < sc->length) {
1791
1879
  sc->length -= size;
1792
1880
  return ngx_http_spdy_state_save(sc, end, end,
@@ -1816,13 +1904,16 @@ ngx_http_spdy_state_settings(ngx_http_spdy_connection_t *sc, u_char *pos,
1816
1904
  sc->length -= NGX_SPDY_SETTINGS_NUM_SIZE;
1817
1905
 
1818
1906
  if (sc->length < sc->entries * NGX_SPDY_SETTINGS_PAIR_SIZE) {
1819
- /* TODO logging */
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
+
1820
1912
  return ngx_http_spdy_state_protocol_error(sc);
1821
1913
  }
1822
1914
 
1823
1915
  ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1824
- "spdy SETTINGS frame consists of %ui entries",
1825
- sc->entries);
1916
+ "spdy SETTINGS frame has %ui entries", sc->entries);
1826
1917
  }
1827
1918
 
1828
1919
  while (sc->entries) {
@@ -1882,7 +1973,20 @@ static u_char *
1882
1973
  ngx_http_spdy_state_complete(ngx_http_spdy_connection_t *sc, u_char *pos,
1883
1974
  u_char *end)
1884
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
+
1885
1987
  sc->handler = ngx_http_spdy_state_head;
1988
+ sc->stream = NULL;
1989
+
1886
1990
  return pos;
1887
1991
  }
1888
1992
 
@@ -1893,12 +1997,17 @@ ngx_http_spdy_state_save(ngx_http_spdy_connection_t *sc,
1893
1997
  {
1894
1998
  size_t size;
1895
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
+
1896
2004
  size = end - pos;
1897
2005
 
1898
2006
  if (size > NGX_SPDY_STATE_BUFFER_SIZE) {
1899
2007
  ngx_log_error(NGX_LOG_ALERT, sc->connection->log, 0,
1900
- "spdy state buffer overflow: "
1901
- "%uz bytes required", size);
2008
+ "state buffer overflow: %uz bytes required", size);
2009
+
2010
+ ngx_debug_point();
1902
2011
  return ngx_http_spdy_state_internal_error(sc);
1903
2012
  }
1904
2013
 
@@ -1912,14 +2021,37 @@ ngx_http_spdy_state_save(ngx_http_spdy_connection_t *sc,
1912
2021
  }
1913
2022
 
1914
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
+
1915
2042
  static u_char *
1916
2043
  ngx_http_spdy_state_protocol_error(ngx_http_spdy_connection_t *sc)
1917
2044
  {
1918
2045
  ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1919
2046
  "spdy state protocol error");
1920
2047
 
1921
- /* TODO */
2048
+ if (sc->stream) {
2049
+ sc->stream->out_closed = 1;
2050
+ ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_BAD_REQUEST);
2051
+ }
2052
+
1922
2053
  ngx_http_spdy_finalize_connection(sc, NGX_HTTP_CLIENT_CLOSED_REQUEST);
2054
+
1923
2055
  return NULL;
1924
2056
  }
1925
2057
 
@@ -1930,8 +2062,13 @@ ngx_http_spdy_state_internal_error(ngx_http_spdy_connection_t *sc)
1930
2062
  ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1931
2063
  "spdy state internal error");
1932
2064
 
1933
- /* TODO */
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
+
1934
2070
  ngx_http_spdy_finalize_connection(sc, NGX_HTTP_INTERNAL_SERVER_ERROR);
2071
+
1935
2072
  return NULL;
1936
2073
  }
1937
2074
 
@@ -1945,7 +2082,7 @@ ngx_http_spdy_send_window_update(ngx_http_spdy_connection_t *sc, ngx_uint_t sid,
1945
2082
  ngx_http_spdy_out_frame_t *frame;
1946
2083
 
1947
2084
  ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1948
- "spdy write WINDOW_UPDATE sid:%ui delta:%ui", sid, delta);
2085
+ "spdy send WINDOW_UPDATE sid:%ui delta:%ui", sid, delta);
1949
2086
 
1950
2087
  frame = ngx_http_spdy_get_ctl_frame(sc, NGX_SPDY_WINDOW_UPDATE_SIZE,
1951
2088
  NGX_SPDY_HIGHEST_PRIORITY);
@@ -1984,7 +2121,7 @@ ngx_http_spdy_send_rst_stream(ngx_http_spdy_connection_t *sc, ngx_uint_t sid,
1984
2121
  }
1985
2122
 
1986
2123
  ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1987
- "spdy write RST_STREAM sid:%ui st:%ui", sid, status);
2124
+ "spdy send RST_STREAM sid:%ui st:%ui", sid, status);
1988
2125
 
1989
2126
  frame = ngx_http_spdy_get_ctl_frame(sc, NGX_SPDY_RST_STREAM_SIZE,
1990
2127
  priority);
@@ -2019,7 +2156,7 @@ ngx_http_spdy_send_goaway(ngx_http_spdy_connection_t *sc)
2019
2156
  ngx_http_spdy_out_frame_t *frame;
2020
2157
 
2021
2158
  ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
2022
- "spdy create GOAWAY sid:%ui", sc->last_sid);
2159
+ "spdy send GOAWAY sid:%ui", sc->last_sid);
2023
2160
 
2024
2161
  frame = ngx_http_spdy_get_ctl_frame(sc, NGX_SPDY_GOAWAY_SIZE,
2025
2162
  NGX_SPDY_HIGHEST_PRIORITY);
@@ -2055,7 +2192,7 @@ ngx_http_spdy_send_settings(ngx_http_spdy_connection_t *sc)
2055
2192
  ngx_http_spdy_out_frame_t *frame;
2056
2193
 
2057
2194
  ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
2058
- "spdy create SETTINGS frame");
2195
+ "spdy send SETTINGS frame");
2059
2196
 
2060
2197
  frame = ngx_palloc(sc->pool, sizeof(ngx_http_spdy_out_frame_t));
2061
2198
  if (frame == NULL) {
@@ -2177,7 +2314,7 @@ ngx_http_spdy_get_ctl_frame(ngx_http_spdy_connection_t *sc, size_t length,
2177
2314
  #if (NGX_DEBUG)
2178
2315
  if (length > NGX_SPDY_CTL_FRAME_BUFFER_SIZE - NGX_SPDY_FRAME_HEADER_SIZE) {
2179
2316
  ngx_log_error(NGX_LOG_ALERT, sc->pool->log, 0,
2180
- "requested control frame is too big: %uz", length);
2317
+ "requested control frame is too large: %uz", length);
2181
2318
  return NULL;
2182
2319
  }
2183
2320
 
@@ -2395,7 +2532,7 @@ ngx_http_spdy_parse_header(ngx_http_request_t *r)
2395
2532
  r->lowcase_index = ngx_spdy_frame_parse_uint32(p);
2396
2533
 
2397
2534
  if (r->lowcase_index == 0) {
2398
- return NGX_HTTP_PARSE_INVALID_HEADER;
2535
+ return NGX_ERROR;
2399
2536
  }
2400
2537
 
2401
2538
  /* null-terminate the previous header value */
@@ -2445,11 +2582,15 @@ ngx_http_spdy_parse_header(ngx_http_request_t *r)
2445
2582
  case LF:
2446
2583
  case CR:
2447
2584
  case ':':
2448
- return NGX_HTTP_PARSE_INVALID_REQUEST;
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;
2449
2590
  }
2450
2591
 
2451
2592
  if (ch >= 'A' && ch <= 'Z') {
2452
- return NGX_HTTP_PARSE_INVALID_HEADER;
2593
+ return NGX_ERROR;
2453
2594
  }
2454
2595
 
2455
2596
  r->invalid_header = 1;
@@ -2498,10 +2639,21 @@ ngx_http_spdy_parse_header(ngx_http_request_t *r)
2498
2639
  r->header_end = p;
2499
2640
  r->header_in->pos = p + 1;
2500
2641
 
2642
+ r->state = sw_value;
2643
+
2501
2644
  return NGX_OK;
2502
2645
  }
2503
2646
 
2504
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
+
2505
2657
  return NGX_HTTP_PARSE_INVALID_HEADER;
2506
2658
  }
2507
2659
 
@@ -2526,7 +2678,7 @@ ngx_http_spdy_parse_header(ngx_http_request_t *r)
2526
2678
  static ngx_int_t
2527
2679
  ngx_http_spdy_alloc_large_header_buffer(ngx_http_request_t *r)
2528
2680
  {
2529
- u_char *old, *new;
2681
+ u_char *old, *new, *p;
2530
2682
  size_t rest;
2531
2683
  ngx_buf_t *buf;
2532
2684
  ngx_http_spdy_stream_t *stream;
@@ -2542,12 +2694,29 @@ ngx_http_spdy_alloc_large_header_buffer(ngx_http_request_t *r)
2542
2694
  if (stream->header_buffers
2543
2695
  == (ngx_uint_t) cscf->large_client_header_buffers.num)
2544
2696
  {
2697
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
2698
+ "client sent too large request");
2699
+
2545
2700
  return NGX_DECLINED;
2546
2701
  }
2547
2702
 
2548
2703
  rest = r->header_in->last - r->header_in->pos;
2549
2704
 
2550
- if (rest >= cscf->large_client_header_buffers.size) {
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
+
2551
2720
  return NGX_DECLINED;
2552
2721
  }
2553
2722
 
@@ -2557,7 +2726,7 @@ ngx_http_spdy_alloc_large_header_buffer(ngx_http_request_t *r)
2557
2726
  }
2558
2727
 
2559
2728
  ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2560
- "spdy large header alloc: %p %z",
2729
+ "spdy large header alloc: %p %uz",
2561
2730
  buf->pos, buf->end - buf->last);
2562
2731
 
2563
2732
  old = r->header_in->pos;
@@ -2612,13 +2781,16 @@ ngx_http_spdy_handle_request_header(ngx_http_request_t *r)
2612
2781
  return sh->handler(r);
2613
2782
  }
2614
2783
 
2615
- return NGX_HTTP_PARSE_INVALID_REQUEST;
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;
2616
2790
  }
2617
2791
 
2618
2792
  h = ngx_list_push(&r->headers_in.headers);
2619
2793
  if (h == NULL) {
2620
- ngx_http_spdy_close_stream(r->spdy_stream,
2621
- NGX_HTTP_INTERNAL_SERVER_ERROR);
2622
2794
  return NGX_ERROR;
2623
2795
  }
2624
2796
 
@@ -2684,6 +2856,9 @@ ngx_http_spdy_parse_method(ngx_http_request_t *r)
2684
2856
  }, *test;
2685
2857
 
2686
2858
  if (r->method_name.len) {
2859
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
2860
+ "client sent duplicate :method header");
2861
+
2687
2862
  return NGX_HTTP_PARSE_INVALID_HEADER;
2688
2863
  }
2689
2864
 
@@ -2721,8 +2896,10 @@ ngx_http_spdy_parse_method(ngx_http_request_t *r)
2721
2896
  do {
2722
2897
  if ((*p < 'A' || *p > 'Z') && *p != '_') {
2723
2898
  ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
2724
- "client sent invalid method");
2725
- return NGX_HTTP_PARSE_INVALID_REQUEST;
2899
+ "client sent invalid method: \"%V\"",
2900
+ &r->method_name);
2901
+
2902
+ return NGX_HTTP_PARSE_INVALID_HEADER;
2726
2903
  }
2727
2904
 
2728
2905
  p++;
@@ -2737,6 +2914,9 @@ static ngx_int_t
2737
2914
  ngx_http_spdy_parse_scheme(ngx_http_request_t *r)
2738
2915
  {
2739
2916
  if (r->schema_start) {
2917
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
2918
+ "client sent duplicate :schema header");
2919
+
2740
2920
  return NGX_HTTP_PARSE_INVALID_HEADER;
2741
2921
  }
2742
2922
 
@@ -2753,13 +2933,14 @@ ngx_http_spdy_parse_host(ngx_http_request_t *r)
2753
2933
  ngx_table_elt_t *h;
2754
2934
 
2755
2935
  if (r->headers_in.host) {
2936
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
2937
+ "client sent duplicate :host header");
2938
+
2756
2939
  return NGX_HTTP_PARSE_INVALID_HEADER;
2757
2940
  }
2758
2941
 
2759
2942
  h = ngx_list_push(&r->headers_in.headers);
2760
2943
  if (h == NULL) {
2761
- ngx_http_spdy_close_stream(r->spdy_stream,
2762
- NGX_HTTP_INTERNAL_SERVER_ERROR);
2763
2944
  return NGX_ERROR;
2764
2945
  }
2765
2946
 
@@ -2783,6 +2964,9 @@ static ngx_int_t
2783
2964
  ngx_http_spdy_parse_path(ngx_http_request_t *r)
2784
2965
  {
2785
2966
  if (r->unparsed_uri.len) {
2967
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
2968
+ "client sent duplicate :path header");
2969
+
2786
2970
  return NGX_HTTP_PARSE_INVALID_HEADER;
2787
2971
  }
2788
2972
 
@@ -2790,11 +2974,19 @@ ngx_http_spdy_parse_path(ngx_http_request_t *r)
2790
2974
  r->uri_end = r->header_end;
2791
2975
 
2792
2976
  if (ngx_http_parse_uri(r) != NGX_OK) {
2793
- return NGX_HTTP_PARSE_INVALID_REQUEST;
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;
2794
2982
  }
2795
2983
 
2796
2984
  if (ngx_http_process_request_uri(r) != NGX_OK) {
2797
- return NGX_ERROR;
2985
+ /*
2986
+ * request has been finalized already
2987
+ * in ngx_http_process_request_uri()
2988
+ */
2989
+ return NGX_ABORT;
2798
2990
  }
2799
2991
 
2800
2992
  return NGX_OK;
@@ -2807,19 +2999,22 @@ ngx_http_spdy_parse_version(ngx_http_request_t *r)
2807
2999
  u_char *p, ch;
2808
3000
 
2809
3001
  if (r->http_protocol.len) {
3002
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
3003
+ "client sent duplicate :version header");
3004
+
2810
3005
  return NGX_HTTP_PARSE_INVALID_HEADER;
2811
3006
  }
2812
3007
 
2813
3008
  p = r->header_start;
2814
3009
 
2815
3010
  if (r->header_end - p < 8 || !(ngx_str5cmp(p, 'H', 'T', 'T', 'P', '/'))) {
2816
- return NGX_HTTP_PARSE_INVALID_REQUEST;
3011
+ goto invalid;
2817
3012
  }
2818
3013
 
2819
3014
  ch = *(p + 5);
2820
3015
 
2821
3016
  if (ch < '1' || ch > '9') {
2822
- return NGX_HTTP_PARSE_INVALID_REQUEST;
3017
+ goto invalid;
2823
3018
  }
2824
3019
 
2825
3020
  r->http_major = ch - '0';
@@ -2833,20 +3028,20 @@ ngx_http_spdy_parse_version(ngx_http_request_t *r)
2833
3028
  }
2834
3029
 
2835
3030
  if (ch < '0' || ch > '9') {
2836
- return NGX_HTTP_PARSE_INVALID_REQUEST;
3031
+ goto invalid;
2837
3032
  }
2838
3033
 
2839
3034
  r->http_major = r->http_major * 10 + ch - '0';
2840
3035
  }
2841
3036
 
2842
3037
  if (*p != '.') {
2843
- return NGX_HTTP_PARSE_INVALID_REQUEST;
3038
+ goto invalid;
2844
3039
  }
2845
3040
 
2846
3041
  ch = *(p + 1);
2847
3042
 
2848
3043
  if (ch < '0' || ch > '9') {
2849
- return NGX_HTTP_PARSE_INVALID_REQUEST;
3044
+ goto invalid;
2850
3045
  }
2851
3046
 
2852
3047
  r->http_minor = ch - '0';
@@ -2856,7 +3051,7 @@ ngx_http_spdy_parse_version(ngx_http_request_t *r)
2856
3051
  ch = *p;
2857
3052
 
2858
3053
  if (ch < '0' || ch > '9') {
2859
- return NGX_HTTP_PARSE_INVALID_REQUEST;
3054
+ goto invalid;
2860
3055
  }
2861
3056
 
2862
3057
  r->http_minor = r->http_minor * 10 + ch - '0';
@@ -2867,6 +3062,14 @@ ngx_http_spdy_parse_version(ngx_http_request_t *r)
2867
3062
  r->http_version = r->http_major * 1000 + r->http_minor;
2868
3063
 
2869
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;
2870
3073
  }
2871
3074
 
2872
3075
 
@@ -2889,7 +3092,8 @@ ngx_http_spdy_construct_request_line(ngx_http_request_t *r)
2889
3092
 
2890
3093
  p = ngx_pnalloc(r->pool, r->request_line.len + 1);
2891
3094
  if (p == NULL) {
2892
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
3095
+ ngx_http_spdy_close_stream(r->spdy_stream,
3096
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
2893
3097
  return NGX_ERROR;
2894
3098
  }
2895
3099
 
@@ -2953,7 +3157,7 @@ ngx_http_spdy_run_request(ngx_http_request_t *r)
2953
3157
  }
2954
3158
 
2955
3159
  ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2956
- "http header: \"%V: %V\"", &h[i].key, &h[i].value);
3160
+ "spdy http header: \"%V: %V\"", &h[i].key, &h[i].value);
2957
3161
  }
2958
3162
 
2959
3163
  r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE;
@@ -3156,10 +3360,8 @@ ngx_http_spdy_close_stream_handler(ngx_event_t *ev)
3156
3360
  void
3157
3361
  ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc)
3158
3362
  {
3159
- int tcp_nodelay;
3160
3363
  ngx_event_t *ev;
3161
- ngx_connection_t *c, *fc;
3162
- ngx_http_core_loc_conf_t *clcf;
3364
+ ngx_connection_t *fc;
3163
3365
  ngx_http_spdy_stream_t **index, *s;
3164
3366
  ngx_http_spdy_srv_conf_t *sscf;
3165
3367
  ngx_http_spdy_connection_t *sc;
@@ -3185,54 +3387,6 @@ ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc)
3185
3387
  {
3186
3388
  sc->connection->error = 1;
3187
3389
  }
3188
-
3189
- } else {
3190
- c = sc->connection;
3191
-
3192
- if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
3193
- if (ngx_tcp_push(c->fd) == -1) {
3194
- ngx_connection_error(c, ngx_socket_errno,
3195
- ngx_tcp_push_n " failed");
3196
- c->error = 1;
3197
- tcp_nodelay = 0;
3198
-
3199
- } else {
3200
- c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
3201
- tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;
3202
- }
3203
-
3204
- } else {
3205
- tcp_nodelay = 1;
3206
- }
3207
-
3208
- clcf = ngx_http_get_module_loc_conf(stream->request,
3209
- ngx_http_core_module);
3210
-
3211
- if (tcp_nodelay
3212
- && clcf->tcp_nodelay
3213
- && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
3214
- {
3215
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
3216
-
3217
- if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
3218
- (const void *) &tcp_nodelay, sizeof(int))
3219
- == -1)
3220
- {
3221
- #if (NGX_SOLARIS)
3222
- /* Solaris returns EINVAL if a socket has been shut down */
3223
- c->log_error = NGX_ERROR_IGNORE_EINVAL;
3224
- #endif
3225
-
3226
- ngx_connection_error(c, ngx_socket_errno,
3227
- "setsockopt(TCP_NODELAY) failed");
3228
-
3229
- c->log_error = NGX_ERROR_INFO;
3230
- c->error = 1;
3231
-
3232
- } else {
3233
- c->tcp_nodelay = NGX_TCP_NODELAY_SET;
3234
- }
3235
- }
3236
3390
  }
3237
3391
 
3238
3392
  if (sc->stream == stream) {
@@ -3265,14 +3419,14 @@ ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc)
3265
3419
 
3266
3420
  if (ev->active || ev->disabled) {
3267
3421
  ngx_log_error(NGX_LOG_ALERT, sc->connection->log, 0,
3268
- "spdy fake read event was activated");
3422
+ "fake read event was activated");
3269
3423
  }
3270
3424
 
3271
3425
  if (ev->timer_set) {
3272
3426
  ngx_del_timer(ev);
3273
3427
  }
3274
3428
 
3275
- if (ev->prev) {
3429
+ if (ev->posted) {
3276
3430
  ngx_delete_posted_event(ev);
3277
3431
  }
3278
3432
 
@@ -3280,14 +3434,14 @@ ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc)
3280
3434
 
3281
3435
  if (ev->active || ev->disabled) {
3282
3436
  ngx_log_error(NGX_LOG_ALERT, sc->connection->log, 0,
3283
- "spdy fake write event was activated");
3437
+ "fake write event was activated");
3284
3438
  }
3285
3439
 
3286
3440
  if (ev->timer_set) {
3287
3441
  ngx_del_timer(ev);
3288
3442
  }
3289
3443
 
3290
- if (ev->prev) {
3444
+ if (ev->posted) {
3291
3445
  ngx_delete_posted_event(ev);
3292
3446
  }
3293
3447