nginxtra 1.2.8.8 → 1.4.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. data/bin/nginxtra +1 -1
  2. data/bin/nginxtra_rails +1 -1
  3. data/lib/nginxtra/version.rb +1 -1
  4. data/vendor/nginx/CHANGES +202 -63
  5. data/vendor/nginx/CHANGES.ru +208 -66
  6. data/vendor/nginx/auto/lib/md5/conf +3 -3
  7. data/vendor/nginx/auto/lib/perl/conf +3 -1
  8. data/vendor/nginx/auto/lib/perl/make +21 -16
  9. data/vendor/nginx/auto/lib/sha1/conf +1 -1
  10. data/vendor/nginx/auto/modules +25 -4
  11. data/vendor/nginx/auto/options +7 -1
  12. data/vendor/nginx/auto/sources +15 -1
  13. data/vendor/nginx/auto/unix +14 -0
  14. data/vendor/nginx/src/core/nginx.h +2 -2
  15. data/vendor/nginx/src/core/ngx_array.c +1 -7
  16. data/vendor/nginx/src/core/ngx_array.h +2 -2
  17. data/vendor/nginx/src/core/ngx_connection.c +13 -7
  18. data/vendor/nginx/src/core/ngx_connection.h +1 -2
  19. data/vendor/nginx/src/core/ngx_core.h +1 -2
  20. data/vendor/nginx/src/core/ngx_crypt.c +37 -0
  21. data/vendor/nginx/src/core/ngx_cycle.h +1 -1
  22. data/vendor/nginx/src/core/ngx_inet.c +219 -48
  23. data/vendor/nginx/src/core/ngx_inet.h +1 -1
  24. data/vendor/nginx/src/event/modules/ngx_devpoll_module.c +7 -1
  25. data/vendor/nginx/src/event/modules/ngx_eventport_module.c +1 -1
  26. data/vendor/nginx/src/event/ngx_event.c +5 -1
  27. data/vendor/nginx/src/event/ngx_event.h +1 -0
  28. data/vendor/nginx/src/event/ngx_event_connect.c +1 -1
  29. data/vendor/nginx/src/event/ngx_event_openssl.c +135 -9
  30. data/vendor/nginx/src/event/ngx_event_openssl.h +9 -0
  31. data/vendor/nginx/src/event/ngx_event_openssl_stapling.c +1749 -0
  32. data/vendor/nginx/src/http/modules/ngx_http_addition_filter_module.c +1 -0
  33. data/vendor/nginx/src/http/modules/ngx_http_chunked_filter_module.c +1 -0
  34. data/vendor/nginx/src/http/modules/ngx_http_fastcgi_module.c +5 -0
  35. data/vendor/nginx/src/http/modules/ngx_http_flv_module.c +4 -0
  36. data/vendor/nginx/src/http/modules/ngx_http_geo_module.c +7 -8
  37. data/vendor/nginx/src/http/modules/ngx_http_geoip_module.c +10 -12
  38. data/vendor/nginx/src/http/modules/ngx_http_gunzip_filter_module.c +677 -0
  39. data/vendor/nginx/src/http/modules/ngx_http_gzip_filter_module.c +3 -0
  40. data/vendor/nginx/src/http/modules/ngx_http_gzip_static_module.c +36 -10
  41. data/vendor/nginx/src/http/modules/ngx_http_headers_filter_module.c +31 -13
  42. data/vendor/nginx/src/http/modules/ngx_http_image_filter_module.c +13 -0
  43. data/vendor/nginx/src/http/modules/ngx_http_limit_conn_module.c +18 -2
  44. data/vendor/nginx/src/http/modules/ngx_http_limit_req_module.c +19 -2
  45. data/vendor/nginx/src/http/modules/ngx_http_map_module.c +1 -1
  46. data/vendor/nginx/src/http/modules/ngx_http_memcached_module.c +60 -8
  47. data/vendor/nginx/src/http/modules/ngx_http_mp4_module.c +4 -8
  48. data/vendor/nginx/src/http/modules/ngx_http_not_modified_filter_module.c +126 -29
  49. data/vendor/nginx/src/http/modules/ngx_http_proxy_module.c +59 -301
  50. data/vendor/nginx/src/http/modules/ngx_http_range_filter_module.c +34 -6
  51. data/vendor/nginx/src/http/modules/ngx_http_realip_module.c +13 -12
  52. data/vendor/nginx/src/http/modules/ngx_http_scgi_module.c +30 -11
  53. data/vendor/nginx/src/http/modules/ngx_http_ssi_filter_module.c +1 -0
  54. data/vendor/nginx/src/http/modules/ngx_http_ssl_module.c +155 -4
  55. data/vendor/nginx/src/http/modules/ngx_http_ssl_module.h +6 -0
  56. data/vendor/nginx/src/http/modules/ngx_http_static_module.c +4 -0
  57. data/vendor/nginx/src/http/modules/ngx_http_stub_status_module.c +90 -3
  58. data/vendor/nginx/src/http/modules/ngx_http_sub_filter_module.c +1 -0
  59. data/vendor/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c +5 -0
  60. data/vendor/nginx/src/http/modules/ngx_http_upstream_least_conn_module.c +5 -0
  61. data/vendor/nginx/src/http/modules/ngx_http_uwsgi_module.c +14 -1
  62. data/vendor/nginx/src/http/modules/ngx_http_xslt_filter_module.c +1 -0
  63. data/vendor/nginx/src/http/modules/perl/Makefile.PL +4 -2
  64. data/vendor/nginx/src/http/modules/perl/nginx.pm +1 -1
  65. data/vendor/nginx/src/http/modules/perl/nginx.xs +36 -3
  66. data/vendor/nginx/src/http/ngx_http.c +24 -1
  67. data/vendor/nginx/src/http/ngx_http.h +26 -2
  68. data/vendor/nginx/src/http/ngx_http_core_module.c +136 -10
  69. data/vendor/nginx/src/http/ngx_http_core_module.h +37 -13
  70. data/vendor/nginx/src/http/ngx_http_header_filter_module.c +9 -2
  71. data/vendor/nginx/src/http/ngx_http_parse.c +404 -0
  72. data/vendor/nginx/src/http/ngx_http_request.c +840 -517
  73. data/vendor/nginx/src/http/ngx_http_request.h +37 -25
  74. data/vendor/nginx/src/http/ngx_http_request_body.c +585 -156
  75. data/vendor/nginx/src/http/ngx_http_spdy.c +2882 -0
  76. data/vendor/nginx/src/http/ngx_http_spdy.h +235 -0
  77. data/vendor/nginx/src/http/ngx_http_spdy_filter_module.c +999 -0
  78. data/vendor/nginx/src/http/ngx_http_spdy_module.c +351 -0
  79. data/vendor/nginx/src/http/ngx_http_spdy_module.h +36 -0
  80. data/vendor/nginx/src/http/ngx_http_special_response.c +3 -1
  81. data/vendor/nginx/src/http/ngx_http_upstream.c +415 -26
  82. data/vendor/nginx/src/http/ngx_http_upstream.h +11 -1
  83. data/vendor/nginx/src/http/ngx_http_upstream_round_robin.c +2 -45
  84. data/vendor/nginx/src/http/ngx_http_upstream_round_robin.h +0 -2
  85. data/vendor/nginx/src/http/ngx_http_variables.c +72 -12
  86. data/vendor/nginx/src/mail/ngx_mail.h +2 -2
  87. data/vendor/nginx/src/mail/ngx_mail_auth_http_module.c +35 -25
  88. data/vendor/nginx/src/mail/ngx_mail_core_module.c +5 -1
  89. metadata +9 -2
@@ -14,7 +14,7 @@
14
14
 
15
15
 
16
16
  #ifndef NGX_CYCLE_POOL_SIZE
17
- #define NGX_CYCLE_POOL_SIZE 16384
17
+ #define NGX_CYCLE_POOL_SIZE NGX_DEFAULT_POOL_SIZE
18
18
  #endif
19
19
 
20
20
 
@@ -611,11 +611,13 @@ ngx_parse_unix_domain_url(ngx_pool_t *pool, ngx_url_t *u)
611
611
  static ngx_int_t
612
612
  ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
613
613
  {
614
- u_char *p, *host, *port, *last, *uri, *args;
615
- size_t len;
616
- ngx_int_t n;
617
- struct hostent *h;
618
- struct sockaddr_in *sin;
614
+ u_char *p, *host, *port, *last, *uri, *args;
615
+ size_t len;
616
+ ngx_int_t n;
617
+ struct sockaddr_in *sin;
618
+ #if (NGX_HAVE_INET6)
619
+ struct sockaddr_in6 *sin6;
620
+ #endif
619
621
 
620
622
  u->socklen = sizeof(struct sockaddr_in);
621
623
  sin = (struct sockaddr_in *) &u->sockaddr;
@@ -705,6 +707,8 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
705
707
  }
706
708
 
707
709
  u->no_port = 1;
710
+ u->port = u->default_port;
711
+ sin->sin_port = htons(u->default_port);
708
712
  }
709
713
 
710
714
  len = last - host;
@@ -714,59 +718,88 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
714
718
  return NGX_ERROR;
715
719
  }
716
720
 
717
- if (len == 1 && *host == '*') {
718
- len = 0;
719
- }
720
-
721
721
  u->host.len = len;
722
722
  u->host.data = host;
723
723
 
724
- if (u->no_resolve) {
724
+ if (u->listen && len == 1 && *host == '*') {
725
+ sin->sin_addr.s_addr = INADDR_ANY;
726
+ u->wildcard = 1;
725
727
  return NGX_OK;
726
728
  }
727
729
 
728
- if (len) {
729
- sin->sin_addr.s_addr = ngx_inet_addr(host, len);
730
+ sin->sin_addr.s_addr = ngx_inet_addr(host, len);
730
731
 
731
- if (sin->sin_addr.s_addr == INADDR_NONE) {
732
- p = ngx_alloc(++len, pool->log);
733
- if (p == NULL) {
734
- return NGX_ERROR;
735
- }
732
+ if (sin->sin_addr.s_addr != INADDR_NONE) {
736
733
 
737
- (void) ngx_cpystrn(p, host, len);
738
-
739
- h = gethostbyname((const char *) p);
734
+ if (sin->sin_addr.s_addr == INADDR_ANY) {
735
+ u->wildcard = 1;
736
+ }
740
737
 
741
- ngx_free(p);
738
+ u->naddrs = 1;
742
739
 
743
- if (h == NULL || h->h_addr_list[0] == NULL) {
744
- u->err = "host not found";
745
- return NGX_ERROR;
746
- }
740
+ u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));
741
+ if (u->addrs == NULL) {
742
+ return NGX_ERROR;
743
+ }
747
744
 
748
- sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[0]);
745
+ sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
746
+ if (sin == NULL) {
747
+ return NGX_ERROR;
749
748
  }
750
749
 
751
- if (sin->sin_addr.s_addr == INADDR_ANY) {
752
- u->wildcard = 1;
750
+ ngx_memcpy(sin, u->sockaddr, sizeof(struct sockaddr_in));
751
+
752
+ u->addrs[0].sockaddr = (struct sockaddr *) sin;
753
+ u->addrs[0].socklen = sizeof(struct sockaddr_in);
754
+
755
+ p = ngx_pnalloc(pool, u->host.len + sizeof(":65535") - 1);
756
+ if (p == NULL) {
757
+ return NGX_ERROR;
753
758
  }
754
759
 
755
- } else {
756
- sin->sin_addr.s_addr = INADDR_ANY;
757
- u->wildcard = 1;
758
- }
760
+ u->addrs[0].name.len = ngx_sprintf(p, "%V:%d",
761
+ &u->host, u->port) - p;
762
+ u->addrs[0].name.data = p;
759
763
 
760
- if (u->no_port) {
761
- u->port = u->default_port;
762
- sin->sin_port = htons(u->default_port);
764
+ return NGX_OK;
763
765
  }
764
766
 
765
- if (u->listen) {
767
+ if (u->no_resolve) {
766
768
  return NGX_OK;
767
769
  }
768
770
 
769
- return ngx_inet_resolve_host(pool, u);
771
+ if (ngx_inet_resolve_host(pool, u) != NGX_OK) {
772
+ return NGX_ERROR;
773
+ }
774
+
775
+ u->family = u->addrs[0].sockaddr->sa_family;
776
+ u->socklen = u->addrs[0].socklen;
777
+ ngx_memcpy(u->sockaddr, u->addrs[0].sockaddr, u->addrs[0].socklen);
778
+
779
+ switch (u->family) {
780
+
781
+ #if (NGX_HAVE_INET6)
782
+ case AF_INET6:
783
+ sin6 = (struct sockaddr_in6 *) &u->sockaddr;
784
+
785
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
786
+ u->wildcard = 1;
787
+ }
788
+
789
+ break;
790
+ #endif
791
+
792
+ default: /* AF_INET */
793
+ sin = (struct sockaddr_in *) &u->sockaddr;
794
+
795
+ if (sin->sin_addr.s_addr == INADDR_ANY) {
796
+ u->wildcard = 1;
797
+ }
798
+
799
+ break;
800
+ }
801
+
802
+ return NGX_OK;
770
803
  }
771
804
 
772
805
 
@@ -832,6 +865,8 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u)
832
865
 
833
866
  } else {
834
867
  u->no_port = 1;
868
+ u->port = u->default_port;
869
+ sin6->sin6_port = htons(u->default_port);
835
870
  }
836
871
  }
837
872
 
@@ -854,11 +889,6 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u)
854
889
  u->wildcard = 1;
855
890
  }
856
891
 
857
- if (u->no_port) {
858
- u->port = u->default_port;
859
- sin6->sin6_port = htons(u->default_port);
860
- }
861
-
862
892
  u->family = AF_INET6;
863
893
  u->naddrs = 1;
864
894
 
@@ -898,6 +928,150 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u)
898
928
  }
899
929
 
900
930
 
931
+ #if (NGX_HAVE_GETADDRINFO && NGX_HAVE_INET6)
932
+
933
+ ngx_int_t
934
+ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
935
+ {
936
+ u_char *p, *host;
937
+ size_t len;
938
+ in_port_t port;
939
+ ngx_uint_t i;
940
+ struct addrinfo hints, *res, *rp;
941
+ struct sockaddr_in *sin;
942
+ struct sockaddr_in6 *sin6;
943
+
944
+ port = htons(u->port);
945
+
946
+ host = ngx_alloc(u->host.len + 1, pool->log);
947
+ if (host == NULL) {
948
+ return NGX_ERROR;
949
+ }
950
+
951
+ (void) ngx_cpystrn(host, u->host.data, u->host.len + 1);
952
+
953
+ ngx_memzero(&hints, sizeof(struct addrinfo));
954
+ hints.ai_family = AF_UNSPEC;
955
+ hints.ai_socktype = SOCK_STREAM;
956
+
957
+ if (getaddrinfo((char *) host, NULL, &hints, &res) != 0) {
958
+ u->err = "host not found";
959
+ ngx_free(host);
960
+ return NGX_ERROR;
961
+ }
962
+
963
+ ngx_free(host);
964
+
965
+ for (i = 0, rp = res; rp != NULL; rp = rp->ai_next) {
966
+
967
+ switch (rp->ai_family) {
968
+
969
+ case AF_INET:
970
+ case AF_INET6:
971
+ break;
972
+
973
+ default:
974
+ continue;
975
+ }
976
+
977
+ i++;
978
+ }
979
+
980
+ if (i == 0) {
981
+ u->err = "host not found";
982
+ goto failed;
983
+ }
984
+
985
+ /* MP: ngx_shared_palloc() */
986
+
987
+ u->addrs = ngx_pcalloc(pool, i * sizeof(ngx_addr_t));
988
+ if (u->addrs == NULL) {
989
+ goto failed;
990
+ }
991
+
992
+ u->naddrs = i;
993
+
994
+ i = 0;
995
+
996
+ /* AF_INET addresses first */
997
+
998
+ for (rp = res; rp != NULL; rp = rp->ai_next) {
999
+
1000
+ if (rp->ai_family != AF_INET) {
1001
+ continue;
1002
+ }
1003
+
1004
+ sin = ngx_pcalloc(pool, rp->ai_addrlen);
1005
+ if (sin == NULL) {
1006
+ goto failed;
1007
+ }
1008
+
1009
+ ngx_memcpy(sin, rp->ai_addr, rp->ai_addrlen);
1010
+
1011
+ sin->sin_port = port;
1012
+
1013
+ u->addrs[i].sockaddr = (struct sockaddr *) sin;
1014
+ u->addrs[i].socklen = rp->ai_addrlen;
1015
+
1016
+ len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
1017
+
1018
+ p = ngx_pnalloc(pool, len);
1019
+ if (p == NULL) {
1020
+ goto failed;
1021
+ }
1022
+
1023
+ len = ngx_sock_ntop((struct sockaddr *) sin, p, len, 1);
1024
+
1025
+ u->addrs[i].name.len = len;
1026
+ u->addrs[i].name.data = p;
1027
+
1028
+ i++;
1029
+ }
1030
+
1031
+ for (rp = res; rp != NULL; rp = rp->ai_next) {
1032
+
1033
+ if (rp->ai_family != AF_INET6) {
1034
+ continue;
1035
+ }
1036
+
1037
+ sin6 = ngx_pcalloc(pool, rp->ai_addrlen);
1038
+ if (sin6 == NULL) {
1039
+ goto failed;
1040
+ }
1041
+
1042
+ ngx_memcpy(sin6, rp->ai_addr, rp->ai_addrlen);
1043
+
1044
+ sin6->sin6_port = port;
1045
+
1046
+ u->addrs[i].sockaddr = (struct sockaddr *) sin6;
1047
+ u->addrs[i].socklen = rp->ai_addrlen;
1048
+
1049
+ len = NGX_INET6_ADDRSTRLEN + sizeof("[]:65535") - 1;
1050
+
1051
+ p = ngx_pnalloc(pool, len);
1052
+ if (p == NULL) {
1053
+ goto failed;
1054
+ }
1055
+
1056
+ len = ngx_sock_ntop((struct sockaddr *) sin6, p, len, 1);
1057
+
1058
+ u->addrs[i].name.len = len;
1059
+ u->addrs[i].name.data = p;
1060
+
1061
+ i++;
1062
+ }
1063
+
1064
+ freeaddrinfo(res);
1065
+ return NGX_OK;
1066
+
1067
+ failed:
1068
+
1069
+ freeaddrinfo(res);
1070
+ return NGX_ERROR;
1071
+ }
1072
+
1073
+ #else /* !NGX_HAVE_GETADDRINFO || !NGX_HAVE_INET6 */
1074
+
901
1075
  ngx_int_t
902
1076
  ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
903
1077
  {
@@ -932,12 +1106,7 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
932
1106
  return NGX_ERROR;
933
1107
  }
934
1108
 
935
- if (u->one_addr == 0) {
936
- for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ }
937
-
938
- } else {
939
- i = 1;
940
- }
1109
+ for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ }
941
1110
 
942
1111
  /* MP: ngx_shared_palloc() */
943
1112
 
@@ -1010,3 +1179,5 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
1010
1179
 
1011
1180
  return NGX_OK;
1012
1181
  }
1182
+
1183
+ #endif /* NGX_HAVE_GETADDRINFO && NGX_HAVE_INET6 */
@@ -87,7 +87,7 @@ typedef struct {
87
87
  unsigned listen:1;
88
88
  unsigned uri_part:1;
89
89
  unsigned no_resolve:1;
90
- unsigned one_addr:1;
90
+ unsigned one_addr:1; /* compatibility */
91
91
 
92
92
  unsigned no_port:1;
93
93
  unsigned wildcard:1;
@@ -343,7 +343,7 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
343
343
  ngx_fd_t fd;
344
344
  ngx_err_t err;
345
345
  ngx_int_t i;
346
- ngx_uint_t level;
346
+ ngx_uint_t level, instance;
347
347
  ngx_event_t *rev, *wev, **queue;
348
348
  ngx_connection_t *c;
349
349
  struct pollfd pfd;
@@ -510,7 +510,13 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
510
510
  ngx_locked_post_event(rev, queue);
511
511
 
512
512
  } else {
513
+ instance = rev->instance;
514
+
513
515
  rev->handler(rev);
516
+
517
+ if (c->fd == -1 || rev->instance != instance) {
518
+ continue;
519
+ }
514
520
  }
515
521
  }
516
522
 
@@ -551,7 +551,7 @@ ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
551
551
  } else {
552
552
  rev->handler(rev);
553
553
 
554
- if (ev->closed) {
554
+ if (ev->closed || ev->instance != instance) {
555
555
  continue;
556
556
  }
557
557
  }
@@ -73,6 +73,8 @@ ngx_atomic_t ngx_stat_reading0;
73
73
  ngx_atomic_t *ngx_stat_reading = &ngx_stat_reading0;
74
74
  ngx_atomic_t ngx_stat_writing0;
75
75
  ngx_atomic_t *ngx_stat_writing = &ngx_stat_writing0;
76
+ ngx_atomic_t ngx_stat_waiting0;
77
+ ngx_atomic_t *ngx_stat_waiting = &ngx_stat_waiting0;
76
78
 
77
79
  #endif
78
80
 
@@ -511,7 +513,8 @@ ngx_event_module_init(ngx_cycle_t *cycle)
511
513
  + cl /* ngx_stat_requests */
512
514
  + cl /* ngx_stat_active */
513
515
  + cl /* ngx_stat_reading */
514
- + cl; /* ngx_stat_writing */
516
+ + cl /* ngx_stat_writing */
517
+ + cl; /* ngx_stat_waiting */
515
518
 
516
519
  #endif
517
520
 
@@ -558,6 +561,7 @@ ngx_event_module_init(ngx_cycle_t *cycle)
558
561
  ngx_stat_active = (ngx_atomic_t *) (shared + 6 * cl);
559
562
  ngx_stat_reading = (ngx_atomic_t *) (shared + 7 * cl);
560
563
  ngx_stat_writing = (ngx_atomic_t *) (shared + 8 * cl);
564
+ ngx_stat_waiting = (ngx_atomic_t *) (shared + 9 * cl);
561
565
 
562
566
  #endif
563
567
 
@@ -511,6 +511,7 @@ extern ngx_atomic_t *ngx_stat_requests;
511
511
  extern ngx_atomic_t *ngx_stat_active;
512
512
  extern ngx_atomic_t *ngx_stat_reading;
513
513
  extern ngx_atomic_t *ngx_stat_writing;
514
+ extern ngx_atomic_t *ngx_stat_waiting;
514
515
 
515
516
  #endif
516
517
 
@@ -84,7 +84,7 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
84
84
 
85
85
  c->log_error = pc->log_error;
86
86
 
87
- if (pc->sockaddr->sa_family != AF_INET) {
87
+ if (pc->sockaddr->sa_family == AF_UNIX) {
88
88
  c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
89
89
  c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED;
90
90
 
@@ -82,6 +82,8 @@ ngx_module_t ngx_openssl_module = {
82
82
  int ngx_ssl_connection_index;
83
83
  int ngx_ssl_server_conf_index;
84
84
  int ngx_ssl_session_cache_index;
85
+ int ngx_ssl_certificate_index;
86
+ int ngx_ssl_stapling_index;
85
87
 
86
88
 
87
89
  ngx_int_t
@@ -137,6 +139,22 @@ ngx_ssl_init(ngx_log_t *log)
137
139
  return NGX_ERROR;
138
140
  }
139
141
 
142
+ ngx_ssl_certificate_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
143
+ NULL);
144
+ if (ngx_ssl_certificate_index == -1) {
145
+ ngx_ssl_error(NGX_LOG_ALERT, log, 0,
146
+ "SSL_CTX_get_ex_new_index() failed");
147
+ return NGX_ERROR;
148
+ }
149
+
150
+ ngx_ssl_stapling_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
151
+ NULL);
152
+ if (ngx_ssl_stapling_index == -1) {
153
+ ngx_ssl_error(NGX_LOG_ALERT, log, 0,
154
+ "SSL_CTX_get_ex_new_index() failed");
155
+ return NGX_ERROR;
156
+ }
157
+
140
158
  return NGX_OK;
141
159
  }
142
160
 
@@ -218,19 +236,89 @@ ngx_int_t
218
236
  ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
219
237
  ngx_str_t *key)
220
238
  {
239
+ BIO *bio;
240
+ X509 *x509;
241
+ u_long n;
242
+
221
243
  if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) {
222
244
  return NGX_ERROR;
223
245
  }
224
246
 
225
- if (SSL_CTX_use_certificate_chain_file(ssl->ctx, (char *) cert->data)
247
+ /*
248
+ * we can't use SSL_CTX_use_certificate_chain_file() as it doesn't
249
+ * allow to access certificate later from SSL_CTX, so we reimplement
250
+ * it here
251
+ */
252
+
253
+ bio = BIO_new_file((char *) cert->data, "r");
254
+ if (bio == NULL) {
255
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
256
+ "BIO_new_file(\"%s\") failed", cert->data);
257
+ return NGX_ERROR;
258
+ }
259
+
260
+ x509 = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL);
261
+ if (x509 == NULL) {
262
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
263
+ "PEM_read_bio_X509_AUX(\"%s\") failed", cert->data);
264
+ BIO_free(bio);
265
+ return NGX_ERROR;
266
+ }
267
+
268
+ if (SSL_CTX_use_certificate(ssl->ctx, x509) == 0) {
269
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
270
+ "SSL_CTX_use_certificate(\"%s\") failed", cert->data);
271
+ X509_free(x509);
272
+ BIO_free(bio);
273
+ return NGX_ERROR;
274
+ }
275
+
276
+ if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_certificate_index, x509)
226
277
  == 0)
227
278
  {
228
279
  ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
229
- "SSL_CTX_use_certificate_chain_file(\"%s\") failed",
230
- cert->data);
280
+ "SSL_CTX_set_ex_data() failed");
231
281
  return NGX_ERROR;
232
282
  }
233
283
 
284
+ X509_free(x509);
285
+
286
+ /* read rest of the chain */
287
+
288
+ for ( ;; ) {
289
+
290
+ x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
291
+ if (x509 == NULL) {
292
+ n = ERR_peek_last_error();
293
+
294
+ if (ERR_GET_LIB(n) == ERR_LIB_PEM
295
+ && ERR_GET_REASON(n) == PEM_R_NO_START_LINE)
296
+ {
297
+ /* end of file */
298
+ ERR_clear_error();
299
+ break;
300
+ }
301
+
302
+ /* some real error */
303
+
304
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
305
+ "PEM_read_bio_X509(\"%s\") failed", cert->data);
306
+ BIO_free(bio);
307
+ return NGX_ERROR;
308
+ }
309
+
310
+ if (SSL_CTX_add_extra_chain_cert(ssl->ctx, x509) == 0) {
311
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
312
+ "SSL_CTX_add_extra_chain_cert(\"%s\") failed",
313
+ cert->data);
314
+ X509_free(x509);
315
+ BIO_free(bio);
316
+ return NGX_ERROR;
317
+ }
318
+ }
319
+
320
+ BIO_free(bio);
321
+
234
322
  if (ngx_conf_full_name(cf->cycle, key, 1) != NGX_OK) {
235
323
  return NGX_ERROR;
236
324
  }
@@ -296,6 +384,33 @@ ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
296
384
  }
297
385
 
298
386
 
387
+ ngx_int_t
388
+ ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
389
+ ngx_int_t depth)
390
+ {
391
+ SSL_CTX_set_verify_depth(ssl->ctx, depth);
392
+
393
+ if (cert->len == 0) {
394
+ return NGX_OK;
395
+ }
396
+
397
+ if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) {
398
+ return NGX_ERROR;
399
+ }
400
+
401
+ if (SSL_CTX_load_verify_locations(ssl->ctx, (char *) cert->data, NULL)
402
+ == 0)
403
+ {
404
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
405
+ "SSL_CTX_load_verify_locations(\"%s\") failed",
406
+ cert->data);
407
+ return NGX_ERROR;
408
+ }
409
+
410
+ return NGX_OK;
411
+ }
412
+
413
+
299
414
  ngx_int_t
300
415
  ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl)
301
416
  {
@@ -1489,10 +1604,12 @@ ngx_ssl_clear_error(ngx_log_t *log)
1489
1604
  void ngx_cdecl
1490
1605
  ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
1491
1606
  {
1492
- u_long n;
1493
- va_list args;
1494
- u_char *p, *last;
1495
- u_char errstr[NGX_MAX_CONF_ERRSTR];
1607
+ int flags;
1608
+ u_long n;
1609
+ va_list args;
1610
+ u_char *p, *last;
1611
+ u_char errstr[NGX_MAX_CONF_ERRSTR];
1612
+ const char *data;
1496
1613
 
1497
1614
  last = errstr + NGX_MAX_CONF_ERRSTR;
1498
1615
 
@@ -1504,14 +1621,14 @@ ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
1504
1621
 
1505
1622
  for ( ;; ) {
1506
1623
 
1507
- n = ERR_get_error();
1624
+ n = ERR_peek_error_line_data(NULL, NULL, &data, &flags);
1508
1625
 
1509
1626
  if (n == 0) {
1510
1627
  break;
1511
1628
  }
1512
1629
 
1513
1630
  if (p >= last) {
1514
- continue;
1631
+ goto next;
1515
1632
  }
1516
1633
 
1517
1634
  *p++ = ' ';
@@ -1521,6 +1638,15 @@ ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
1521
1638
  while (p < last && *p) {
1522
1639
  p++;
1523
1640
  }
1641
+
1642
+ if (p < last && *data && (flags & ERR_TXT_STRING)) {
1643
+ *p++ = ':';
1644
+ p = ngx_cpystrn(p, (u_char *) data, last - p);
1645
+ }
1646
+
1647
+ next:
1648
+
1649
+ (void) ERR_get_error();
1524
1650
  }
1525
1651
 
1526
1652
  ngx_log_error(level, log, err, "%s)", errstr);