Mercurial > hg > nginx
comparison src/http/v2/ngx_http_v2_filter_module.c @ 7191:61d276dcd493
HTTP/2: more style, comments, and debugging.
author | Ruslan Ermilov <ru@nginx.com> |
---|---|
date | Mon, 29 Jan 2018 16:06:33 +0300 |
parents | 2bf605c6edf7 |
children | 641306096f5b |
comparison
equal
deleted
inserted
replaced
7190:e11a0679d349 | 7191:61d276dcd493 |
---|---|
136 ngx_uint_t i, port; | 136 ngx_uint_t i, port; |
137 ngx_list_part_t *part; | 137 ngx_list_part_t *part; |
138 ngx_table_elt_t *header; | 138 ngx_table_elt_t *header; |
139 ngx_connection_t *fc; | 139 ngx_connection_t *fc; |
140 ngx_http_cleanup_t *cln; | 140 ngx_http_cleanup_t *cln; |
141 ngx_http_v2_stream_t *stream; | |
141 ngx_http_v2_out_frame_t *frame; | 142 ngx_http_v2_out_frame_t *frame; |
142 ngx_http_v2_connection_t *h2c; | 143 ngx_http_v2_connection_t *h2c; |
143 ngx_http_core_loc_conf_t *clcf; | 144 ngx_http_core_loc_conf_t *clcf; |
144 ngx_http_core_srv_conf_t *cscf; | 145 ngx_http_core_srv_conf_t *cscf; |
145 u_char addr[NGX_SOCKADDR_STRLEN]; | 146 u_char addr[NGX_SOCKADDR_STRLEN]; |
155 | 156 |
156 static size_t nginx_ver_build_len = | 157 static size_t nginx_ver_build_len = |
157 ngx_http_v2_literal_size(NGINX_VER_BUILD); | 158 ngx_http_v2_literal_size(NGINX_VER_BUILD); |
158 static u_char nginx_ver_build[ngx_http_v2_literal_size(NGINX_VER_BUILD)]; | 159 static u_char nginx_ver_build[ngx_http_v2_literal_size(NGINX_VER_BUILD)]; |
159 | 160 |
160 if (!r->stream) { | 161 stream = r->stream; |
162 | |
163 if (!stream) { | |
161 return ngx_http_next_header_filter(r); | 164 return ngx_http_next_header_filter(r); |
162 } | 165 } |
163 | 166 |
164 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 167 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
165 "http2 header filter"); | 168 "http2 header filter"); |
234 default: | 237 default: |
235 status = 0; | 238 status = 0; |
236 } | 239 } |
237 } | 240 } |
238 | 241 |
239 h2c = r->stream->connection; | 242 h2c = stream->connection; |
240 | 243 |
241 len = h2c->table_update ? 1 : 0; | 244 len = h2c->table_update ? 1 : 0; |
242 | 245 |
243 len += status ? 1 : 1 + ngx_http_v2_literal_size("418"); | 246 len += status ? 1 : 1 + ngx_http_v2_literal_size("418"); |
244 | 247 |
631 frame = ngx_http_v2_create_headers_frame(r, start, pos, r->header_only); | 634 frame = ngx_http_v2_create_headers_frame(r, start, pos, r->header_only); |
632 if (frame == NULL) { | 635 if (frame == NULL) { |
633 return NGX_ERROR; | 636 return NGX_ERROR; |
634 } | 637 } |
635 | 638 |
636 ngx_http_v2_queue_blocked_frame(r->stream->connection, frame); | 639 ngx_http_v2_queue_blocked_frame(h2c, frame); |
637 | 640 |
638 r->stream->queued = 1; | 641 stream->queued = 1; |
639 | 642 |
640 cln = ngx_http_cleanup_add(r, 0); | 643 cln = ngx_http_cleanup_add(r, 0); |
641 if (cln == NULL) { | 644 if (cln == NULL) { |
642 return NGX_ERROR; | 645 return NGX_ERROR; |
643 } | 646 } |
644 | 647 |
645 cln->handler = ngx_http_v2_filter_cleanup; | 648 cln->handler = ngx_http_v2_filter_cleanup; |
646 cln->data = r->stream; | 649 cln->data = stream; |
647 | 650 |
648 fc->send_chain = ngx_http_v2_send_chain; | 651 fc->send_chain = ngx_http_v2_send_chain; |
649 fc->need_last_buf = 1; | 652 fc->need_last_buf = 1; |
650 | 653 |
651 return ngx_http_v2_filter_send(fc, r->stream); | 654 return ngx_http_v2_filter_send(fc, stream); |
652 } | |
653 | |
654 | |
655 static ngx_http_v2_out_frame_t * | |
656 ngx_http_v2_create_trailers_frame(ngx_http_request_t *r) | |
657 { | |
658 u_char *pos, *start, *tmp; | |
659 size_t len, tmp_len; | |
660 ngx_uint_t i; | |
661 ngx_list_part_t *part; | |
662 ngx_table_elt_t *header; | |
663 | |
664 len = 0; | |
665 tmp_len = 0; | |
666 | |
667 part = &r->headers_out.trailers.part; | |
668 header = part->elts; | |
669 | |
670 for (i = 0; /* void */; i++) { | |
671 | |
672 if (i >= part->nelts) { | |
673 if (part->next == NULL) { | |
674 break; | |
675 } | |
676 | |
677 part = part->next; | |
678 header = part->elts; | |
679 i = 0; | |
680 } | |
681 | |
682 if (header[i].hash == 0) { | |
683 continue; | |
684 } | |
685 | |
686 if (header[i].key.len > NGX_HTTP_V2_MAX_FIELD) { | |
687 ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0, | |
688 "too long response trailer name: \"%V\"", | |
689 &header[i].key); | |
690 return NULL; | |
691 } | |
692 | |
693 if (header[i].value.len > NGX_HTTP_V2_MAX_FIELD) { | |
694 ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0, | |
695 "too long response trailer value: \"%V: %V\"", | |
696 &header[i].key, &header[i].value); | |
697 return NULL; | |
698 } | |
699 | |
700 len += 1 + NGX_HTTP_V2_INT_OCTETS + header[i].key.len | |
701 + NGX_HTTP_V2_INT_OCTETS + header[i].value.len; | |
702 | |
703 if (header[i].key.len > tmp_len) { | |
704 tmp_len = header[i].key.len; | |
705 } | |
706 | |
707 if (header[i].value.len > tmp_len) { | |
708 tmp_len = header[i].value.len; | |
709 } | |
710 } | |
711 | |
712 if (len == 0) { | |
713 return NGX_HTTP_V2_NO_TRAILERS; | |
714 } | |
715 | |
716 tmp = ngx_palloc(r->pool, tmp_len); | |
717 pos = ngx_pnalloc(r->pool, len); | |
718 | |
719 if (pos == NULL || tmp == NULL) { | |
720 return NULL; | |
721 } | |
722 | |
723 start = pos; | |
724 | |
725 part = &r->headers_out.trailers.part; | |
726 header = part->elts; | |
727 | |
728 for (i = 0; /* void */; i++) { | |
729 | |
730 if (i >= part->nelts) { | |
731 if (part->next == NULL) { | |
732 break; | |
733 } | |
734 | |
735 part = part->next; | |
736 header = part->elts; | |
737 i = 0; | |
738 } | |
739 | |
740 if (header[i].hash == 0) { | |
741 continue; | |
742 } | |
743 | |
744 #if (NGX_DEBUG) | |
745 if (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP) { | |
746 ngx_strlow(tmp, header[i].key.data, header[i].key.len); | |
747 | |
748 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
749 "http2 output trailer: \"%*s: %V\"", | |
750 header[i].key.len, tmp, &header[i].value); | |
751 } | |
752 #endif | |
753 | |
754 *pos++ = 0; | |
755 | |
756 pos = ngx_http_v2_write_name(pos, header[i].key.data, | |
757 header[i].key.len, tmp); | |
758 | |
759 pos = ngx_http_v2_write_value(pos, header[i].value.data, | |
760 header[i].value.len, tmp); | |
761 } | |
762 | |
763 return ngx_http_v2_create_headers_frame(r, start, pos, 1); | |
764 } | 655 } |
765 | 656 |
766 | 657 |
767 static u_char * | 658 static u_char * |
768 ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len, u_char *tmp, | 659 ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len, u_char *tmp, |
912 "http2:%ui create HEADERS frame %p: len:%uz", | 803 "http2:%ui create HEADERS frame %p: len:%uz", |
913 stream->node->id, frame, frame->length); | 804 stream->node->id, frame, frame->length); |
914 | 805 |
915 return frame; | 806 return frame; |
916 } | 807 } |
808 } | |
809 | |
810 | |
811 static ngx_http_v2_out_frame_t * | |
812 ngx_http_v2_create_trailers_frame(ngx_http_request_t *r) | |
813 { | |
814 u_char *pos, *start, *tmp; | |
815 size_t len, tmp_len; | |
816 ngx_uint_t i; | |
817 ngx_list_part_t *part; | |
818 ngx_table_elt_t *header; | |
819 ngx_connection_t *fc; | |
820 | |
821 fc = r->connection; | |
822 len = 0; | |
823 tmp_len = 0; | |
824 | |
825 part = &r->headers_out.trailers.part; | |
826 header = part->elts; | |
827 | |
828 for (i = 0; /* void */; i++) { | |
829 | |
830 if (i >= part->nelts) { | |
831 if (part->next == NULL) { | |
832 break; | |
833 } | |
834 | |
835 part = part->next; | |
836 header = part->elts; | |
837 i = 0; | |
838 } | |
839 | |
840 if (header[i].hash == 0) { | |
841 continue; | |
842 } | |
843 | |
844 if (header[i].key.len > NGX_HTTP_V2_MAX_FIELD) { | |
845 ngx_log_error(NGX_LOG_CRIT, fc->log, 0, | |
846 "too long response trailer name: \"%V\"", | |
847 &header[i].key); | |
848 return NULL; | |
849 } | |
850 | |
851 if (header[i].value.len > NGX_HTTP_V2_MAX_FIELD) { | |
852 ngx_log_error(NGX_LOG_CRIT, fc->log, 0, | |
853 "too long response trailer value: \"%V: %V\"", | |
854 &header[i].key, &header[i].value); | |
855 return NULL; | |
856 } | |
857 | |
858 len += 1 + NGX_HTTP_V2_INT_OCTETS + header[i].key.len | |
859 + NGX_HTTP_V2_INT_OCTETS + header[i].value.len; | |
860 | |
861 if (header[i].key.len > tmp_len) { | |
862 tmp_len = header[i].key.len; | |
863 } | |
864 | |
865 if (header[i].value.len > tmp_len) { | |
866 tmp_len = header[i].value.len; | |
867 } | |
868 } | |
869 | |
870 if (len == 0) { | |
871 return NGX_HTTP_V2_NO_TRAILERS; | |
872 } | |
873 | |
874 tmp = ngx_palloc(r->pool, tmp_len); | |
875 pos = ngx_pnalloc(r->pool, len); | |
876 | |
877 if (pos == NULL || tmp == NULL) { | |
878 return NULL; | |
879 } | |
880 | |
881 start = pos; | |
882 | |
883 part = &r->headers_out.trailers.part; | |
884 header = part->elts; | |
885 | |
886 for (i = 0; /* void */; i++) { | |
887 | |
888 if (i >= part->nelts) { | |
889 if (part->next == NULL) { | |
890 break; | |
891 } | |
892 | |
893 part = part->next; | |
894 header = part->elts; | |
895 i = 0; | |
896 } | |
897 | |
898 if (header[i].hash == 0) { | |
899 continue; | |
900 } | |
901 | |
902 #if (NGX_DEBUG) | |
903 if (fc->log->log_level & NGX_LOG_DEBUG_HTTP) { | |
904 ngx_strlow(tmp, header[i].key.data, header[i].key.len); | |
905 | |
906 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, fc->log, 0, | |
907 "http2 output trailer: \"%*s: %V\"", | |
908 header[i].key.len, tmp, &header[i].value); | |
909 } | |
910 #endif | |
911 | |
912 *pos++ = 0; | |
913 | |
914 pos = ngx_http_v2_write_name(pos, header[i].key.data, | |
915 header[i].key.len, tmp); | |
916 | |
917 pos = ngx_http_v2_write_value(pos, header[i].value.data, | |
918 header[i].value.len, tmp); | |
919 } | |
920 | |
921 return ngx_http_v2_create_headers_frame(r, start, pos, 1); | |
917 } | 922 } |
918 | 923 |
919 | 924 |
920 static ngx_chain_t * | 925 static ngx_chain_t * |
921 ngx_http_v2_send_chain(ngx_connection_t *fc, ngx_chain_t *in, off_t limit) | 926 ngx_http_v2_send_chain(ngx_connection_t *fc, ngx_chain_t *in, off_t limit) |
1238 return frame; | 1243 return frame; |
1239 } | 1244 } |
1240 | 1245 |
1241 | 1246 |
1242 static ngx_inline ngx_int_t | 1247 static ngx_inline ngx_int_t |
1243 ngx_http_v2_filter_send(ngx_connection_t *fc, ngx_http_v2_stream_t *stream) | |
1244 { | |
1245 stream->blocked = 1; | |
1246 | |
1247 if (ngx_http_v2_send_output_queue(stream->connection) == NGX_ERROR) { | |
1248 fc->error = 1; | |
1249 return NGX_ERROR; | |
1250 } | |
1251 | |
1252 stream->blocked = 0; | |
1253 | |
1254 if (stream->queued) { | |
1255 fc->buffered |= NGX_HTTP_V2_BUFFERED; | |
1256 fc->write->active = 1; | |
1257 fc->write->ready = 0; | |
1258 return NGX_AGAIN; | |
1259 } | |
1260 | |
1261 fc->buffered &= ~NGX_HTTP_V2_BUFFERED; | |
1262 | |
1263 return NGX_OK; | |
1264 } | |
1265 | |
1266 | |
1267 static ngx_inline ngx_int_t | |
1268 ngx_http_v2_flow_control(ngx_http_v2_connection_t *h2c, | 1248 ngx_http_v2_flow_control(ngx_http_v2_connection_t *h2c, |
1269 ngx_http_v2_stream_t *stream) | 1249 ngx_http_v2_stream_t *stream) |
1270 { | 1250 { |
1271 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, | 1251 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, |
1272 "http2:%ui windows: conn:%uz stream:%z", | 1252 "http2:%ui windows: conn:%uz stream:%z", |
1314 } | 1294 } |
1315 | 1295 |
1316 ngx_queue_insert_after(q, &stream->queue); | 1296 ngx_queue_insert_after(q, &stream->queue); |
1317 } | 1297 } |
1318 | 1298 |
1299 | |
1300 static ngx_inline ngx_int_t | |
1301 ngx_http_v2_filter_send(ngx_connection_t *fc, ngx_http_v2_stream_t *stream) | |
1302 { | |
1303 stream->blocked = 1; | |
1304 | |
1305 if (ngx_http_v2_send_output_queue(stream->connection) == NGX_ERROR) { | |
1306 fc->error = 1; | |
1307 return NGX_ERROR; | |
1308 } | |
1309 | |
1310 stream->blocked = 0; | |
1311 | |
1312 if (stream->queued) { | |
1313 fc->buffered |= NGX_HTTP_V2_BUFFERED; | |
1314 fc->write->active = 1; | |
1315 fc->write->ready = 0; | |
1316 return NGX_AGAIN; | |
1317 } | |
1318 | |
1319 fc->buffered &= ~NGX_HTTP_V2_BUFFERED; | |
1320 | |
1321 return NGX_OK; | |
1322 } | |
1319 | 1323 |
1320 | 1324 |
1321 static ngx_int_t | 1325 static ngx_int_t |
1322 ngx_http_v2_headers_frame_handler(ngx_http_v2_connection_t *h2c, | 1326 ngx_http_v2_headers_frame_handler(ngx_http_v2_connection_t *h2c, |
1323 ngx_http_v2_out_frame_t *frame) | 1327 ngx_http_v2_out_frame_t *frame) |