puma 5.2.2 → 6.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of puma might be problematic. Click here for more details.
- checksums.yaml +4 -4
 - data/History.md +483 -4
 - data/README.md +101 -20
 - data/bin/puma-wild +1 -1
 - data/docs/architecture.md +50 -16
 - data/docs/compile_options.md +38 -2
 - data/docs/deployment.md +53 -67
 - data/docs/fork_worker.md +1 -3
 - data/docs/jungle/rc.d/README.md +1 -1
 - data/docs/kubernetes.md +1 -1
 - data/docs/nginx.md +1 -1
 - data/docs/plugins.md +15 -15
 - data/docs/rails_dev_mode.md +2 -3
 - data/docs/restart.md +7 -7
 - data/docs/signals.md +11 -10
 - data/docs/stats.md +8 -8
 - data/docs/systemd.md +65 -69
 - data/docs/testing_benchmarks_local_files.md +150 -0
 - data/docs/testing_test_rackup_ci_files.md +36 -0
 - data/ext/puma_http11/extconf.rb +44 -13
 - data/ext/puma_http11/http11_parser.c +24 -11
 - data/ext/puma_http11/http11_parser.h +2 -2
 - data/ext/puma_http11/http11_parser.java.rl +2 -2
 - data/ext/puma_http11/http11_parser.rl +2 -2
 - data/ext/puma_http11/http11_parser_common.rl +3 -3
 - data/ext/puma_http11/mini_ssl.c +150 -23
 - data/ext/puma_http11/org/jruby/puma/Http11.java +3 -3
 - data/ext/puma_http11/org/jruby/puma/Http11Parser.java +50 -48
 - data/ext/puma_http11/org/jruby/puma/MiniSSL.java +188 -102
 - data/ext/puma_http11/puma_http11.c +18 -10
 - data/lib/puma/app/status.rb +10 -7
 - data/lib/puma/binder.rb +112 -62
 - data/lib/puma/cli.rb +24 -20
 - data/lib/puma/client.rb +162 -36
 - data/lib/puma/cluster/worker.rb +31 -27
 - data/lib/puma/cluster/worker_handle.rb +12 -1
 - data/lib/puma/cluster.rb +102 -61
 - data/lib/puma/commonlogger.rb +21 -14
 - data/lib/puma/configuration.rb +78 -54
 - data/lib/puma/const.rb +135 -97
 - data/lib/puma/control_cli.rb +25 -20
 - data/lib/puma/detect.rb +12 -2
 - data/lib/puma/dsl.rb +308 -58
 - data/lib/puma/error_logger.rb +20 -11
 - data/lib/puma/events.rb +6 -126
 - data/lib/puma/io_buffer.rb +39 -4
 - data/lib/puma/jruby_restart.rb +2 -1
 - data/lib/puma/{json.rb → json_serialization.rb} +1 -1
 - data/lib/puma/launcher/bundle_pruner.rb +104 -0
 - data/lib/puma/launcher.rb +114 -173
 - data/lib/puma/log_writer.rb +147 -0
 - data/lib/puma/minissl/context_builder.rb +30 -16
 - data/lib/puma/minissl.rb +132 -38
 - data/lib/puma/null_io.rb +5 -0
 - data/lib/puma/plugin/systemd.rb +90 -0
 - data/lib/puma/plugin/tmp_restart.rb +1 -1
 - data/lib/puma/plugin.rb +2 -2
 - data/lib/puma/rack/builder.rb +7 -7
 - data/lib/puma/rack_default.rb +19 -4
 - data/lib/puma/reactor.rb +19 -10
 - data/lib/puma/request.rb +373 -153
 - data/lib/puma/runner.rb +74 -28
 - data/lib/puma/sd_notify.rb +149 -0
 - data/lib/puma/server.rb +127 -136
 - data/lib/puma/single.rb +13 -11
 - data/lib/puma/state_file.rb +39 -7
 - data/lib/puma/thread_pool.rb +33 -26
 - data/lib/puma/util.rb +20 -15
 - data/lib/puma.rb +28 -11
 - data/lib/rack/handler/puma.rb +113 -86
 - data/tools/Dockerfile +1 -1
 - metadata +15 -10
 - data/lib/puma/queue_close.rb +0 -26
 - data/lib/puma/systemd.rb +0 -46
 
| 
         @@ -34,9 +34,9 @@ private static short[] init__puma_parser_key_offsets_0() 
     | 
|
| 
       34 
34 
     | 
    
         
             
            {
         
     | 
| 
       35 
35 
     | 
    
         
             
            	return new short [] {
         
     | 
| 
       36 
36 
     | 
    
         
             
            	    0,    0,    8,   17,   27,   29,   30,   31,   32,   33,   34,   36,
         
     | 
| 
       37 
     | 
    
         
            -
            	   39,   41,   44,   45,   61,   62,   78,    
     | 
| 
       38 
     | 
    
         
            -
            	   
     | 
| 
       39 
     | 
    
         
            -
            	   
     | 
| 
      
 37 
     | 
    
         
            +
            	   39,   41,   44,   45,   61,   62,   78,   85,   91,   99,  107,  117,
         
     | 
| 
      
 38 
     | 
    
         
            +
            	  125,  134,  142,  150,  159,  168,  177,  186,  195,  204,  213,  222,
         
     | 
| 
      
 39 
     | 
    
         
            +
            	  231,  240,  249,  258,  267,  276,  285,  294,  303,  312,  313
         
     | 
| 
       40 
40 
     | 
    
         
             
            	};
         
     | 
| 
       41 
41 
     | 
    
         
             
            }
         
     | 
| 
       42 
42 
     | 
    
         | 
| 
         @@ -52,26 +52,27 @@ private static char[] init__puma_parser_trans_keys_0() 
     | 
|
| 
       52 
52 
     | 
    
         
             
            	   46,   48,   57,   48,   57,   13,   48,   57,   10,   13,   33,  124,
         
     | 
| 
       53 
53 
     | 
    
         
             
            	  126,   35,   39,   42,   43,   45,   46,   48,   57,   65,   90,   94,
         
     | 
| 
       54 
54 
     | 
    
         
             
            	  122,   10,   33,   58,  124,  126,   35,   39,   42,   43,   45,   46,
         
     | 
| 
       55 
     | 
    
         
            -
            	   48,   57,   65,   90,   94,  122,   13,   32, 
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
            	    
     | 
| 
       58 
     | 
    
         
            -
            	    
     | 
| 
       59 
     | 
    
         
            -
            	    
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
            	    
     | 
| 
       62 
     | 
    
         
            -
            	   65,   90,   32,   36,   95,   45,   46,   48,   57,   65,   90, 
     | 
| 
       63 
     | 
    
         
            -
            	   36,   95,   45,   46,   48,   57,   65,   90,   32,   36,   95, 
     | 
| 
       64 
     | 
    
         
            -
            	   46,   48,   57,   65,   90,   32,   36,   95,   45,   46,   48, 
     | 
| 
       65 
     | 
    
         
            -
            	   65,   90,   32,   36,   95,   45,   46,   48,   57,   65,   90, 
     | 
| 
       66 
     | 
    
         
            -
            	   36,   95,   45,   46,   48,   57,   65,   90,   32,   36,   95, 
     | 
| 
       67 
     | 
    
         
            -
            	   46,   48,   57,   65,   90,   32,   36,   95,   45,   46,   48, 
     | 
| 
       68 
     | 
    
         
            -
            	   65,   90,   32,   36,   95,   45,   46,   48,   57,   65,   90, 
     | 
| 
       69 
     | 
    
         
            -
            	   36,   95,   45,   46,   48,   57,   65,   90,   32,   36,   95, 
     | 
| 
       70 
     | 
    
         
            -
            	   46,   48,   57,   65,   90,   32,   36,   95,   45,   46,   48, 
     | 
| 
       71 
     | 
    
         
            -
            	   65,   90,   32,   36,   95,   45,   46,   48,   57,   65,   90, 
     | 
| 
       72 
     | 
    
         
            -
            	   36,   95,   45,   46,   48,   57,   65,   90,   32,   36,   95, 
     | 
| 
       73 
     | 
    
         
            -
            	   46,   48,   57,   65,   90,   32,   36,   95,   45,   46,   48, 
     | 
| 
       74 
     | 
    
         
            -
            	   65,   90,   32, 
     | 
| 
      
 55 
     | 
    
         
            +
            	   48,   57,   65,   90,   94,  122,   13,   32,  127,    0,    8,   10,
         
     | 
| 
      
 56 
     | 
    
         
            +
            	   31,   13,  127,    0,    8,   10,   31,   32,   60,   62,  127,    0,
         
     | 
| 
      
 57 
     | 
    
         
            +
            	   31,   34,   35,   32,   60,   62,  127,    0,   31,   34,   35,   43,
         
     | 
| 
      
 58 
     | 
    
         
            +
            	   58,   45,   46,   48,   57,   65,   90,   97,  122,   32,   34,   35,
         
     | 
| 
      
 59 
     | 
    
         
            +
            	   60,   62,  127,    0,   31,   32,   34,   35,   60,   62,   63,  127,
         
     | 
| 
      
 60 
     | 
    
         
            +
            	    0,   31,   32,   34,   35,   60,   62,  127,    0,   31,   32,   34,
         
     | 
| 
      
 61 
     | 
    
         
            +
            	   35,   60,   62,  127,    0,   31,   32,   36,   95,   45,   46,   48,
         
     | 
| 
      
 62 
     | 
    
         
            +
            	   57,   65,   90,   32,   36,   95,   45,   46,   48,   57,   65,   90,
         
     | 
| 
      
 63 
     | 
    
         
            +
            	   32,   36,   95,   45,   46,   48,   57,   65,   90,   32,   36,   95,
         
     | 
| 
      
 64 
     | 
    
         
            +
            	   45,   46,   48,   57,   65,   90,   32,   36,   95,   45,   46,   48,
         
     | 
| 
      
 65 
     | 
    
         
            +
            	   57,   65,   90,   32,   36,   95,   45,   46,   48,   57,   65,   90,
         
     | 
| 
      
 66 
     | 
    
         
            +
            	   32,   36,   95,   45,   46,   48,   57,   65,   90,   32,   36,   95,
         
     | 
| 
      
 67 
     | 
    
         
            +
            	   45,   46,   48,   57,   65,   90,   32,   36,   95,   45,   46,   48,
         
     | 
| 
      
 68 
     | 
    
         
            +
            	   57,   65,   90,   32,   36,   95,   45,   46,   48,   57,   65,   90,
         
     | 
| 
      
 69 
     | 
    
         
            +
            	   32,   36,   95,   45,   46,   48,   57,   65,   90,   32,   36,   95,
         
     | 
| 
      
 70 
     | 
    
         
            +
            	   45,   46,   48,   57,   65,   90,   32,   36,   95,   45,   46,   48,
         
     | 
| 
      
 71 
     | 
    
         
            +
            	   57,   65,   90,   32,   36,   95,   45,   46,   48,   57,   65,   90,
         
     | 
| 
      
 72 
     | 
    
         
            +
            	   32,   36,   95,   45,   46,   48,   57,   65,   90,   32,   36,   95,
         
     | 
| 
      
 73 
     | 
    
         
            +
            	   45,   46,   48,   57,   65,   90,   32,   36,   95,   45,   46,   48,
         
     | 
| 
      
 74 
     | 
    
         
            +
            	   57,   65,   90,   32,   36,   95,   45,   46,   48,   57,   65,   90,
         
     | 
| 
      
 75 
     | 
    
         
            +
            	   32,    0
         
     | 
| 
       75 
76 
     | 
    
         
             
            	};
         
     | 
| 
       76 
77 
     | 
    
         
             
            }
         
     | 
| 
       77 
78 
     | 
    
         | 
| 
         @@ -82,7 +83,7 @@ private static byte[] init__puma_parser_single_lengths_0() 
     | 
|
| 
       82 
83 
     | 
    
         
             
            {
         
     | 
| 
       83 
84 
     | 
    
         
             
            	return new byte [] {
         
     | 
| 
       84 
85 
     | 
    
         
             
            	    0,    2,    3,    4,    2,    1,    1,    1,    1,    1,    0,    1,
         
     | 
| 
       85 
     | 
    
         
            -
            	    0,    1,    1,    4,    1,    4,     
     | 
| 
      
 86 
     | 
    
         
            +
            	    0,    1,    1,    4,    1,    4,    3,    2,    4,    4,    2,    6,
         
     | 
| 
       86 
87 
     | 
    
         
             
            	    7,    6,    6,    3,    3,    3,    3,    3,    3,    3,    3,    3,
         
     | 
| 
       87 
88 
     | 
    
         
             
            	    3,    3,    3,    3,    3,    3,    3,    3,    3,    1,    0
         
     | 
| 
       88 
89 
     | 
    
         
             
            	};
         
     | 
| 
         @@ -95,7 +96,7 @@ private static byte[] init__puma_parser_range_lengths_0() 
     | 
|
| 
       95 
96 
     | 
    
         
             
            {
         
     | 
| 
       96 
97 
     | 
    
         
             
            	return new byte [] {
         
     | 
| 
       97 
98 
     | 
    
         
             
            	    0,    3,    3,    3,    0,    0,    0,    0,    0,    0,    1,    1,
         
     | 
| 
       98 
     | 
    
         
            -
            	    1,    1,    0,    6,    0,    6,     
     | 
| 
      
 99 
     | 
    
         
            +
            	    1,    1,    0,    6,    0,    6,    2,    2,    2,    2,    4,    1,
         
     | 
| 
       99 
100 
     | 
    
         
             
            	    1,    1,    1,    3,    3,    3,    3,    3,    3,    3,    3,    3,
         
     | 
| 
       100 
101 
     | 
    
         
             
            	    3,    3,    3,    3,    3,    3,    3,    3,    3,    0,    0
         
     | 
| 
       101 
102 
     | 
    
         
             
            	};
         
     | 
| 
         @@ -108,9 +109,9 @@ private static short[] init__puma_parser_index_offsets_0() 
     | 
|
| 
       108 
109 
     | 
    
         
             
            {
         
     | 
| 
       109 
110 
     | 
    
         
             
            	return new short [] {
         
     | 
| 
       110 
111 
     | 
    
         
             
            	    0,    0,    6,   13,   21,   24,   26,   28,   30,   32,   34,   36,
         
     | 
| 
       111 
     | 
    
         
            -
            	   39,   41,   44,   46,   57,   59,   70,    
     | 
| 
       112 
     | 
    
         
            -
            	   
     | 
| 
       113 
     | 
    
         
            -
            	   
     | 
| 
      
 112 
     | 
    
         
            +
            	   39,   41,   44,   46,   57,   59,   70,   76,   81,   88,   95,  102,
         
     | 
| 
      
 113 
     | 
    
         
            +
            	  110,  119,  127,  135,  142,  149,  156,  163,  170,  177,  184,  191,
         
     | 
| 
      
 114 
     | 
    
         
            +
            	  198,  205,  212,  219,  226,  233,  240,  247,  254,  261,  263
         
     | 
| 
       114 
115 
     | 
    
         
             
            	};
         
     | 
| 
       115 
116 
     | 
    
         
             
            }
         
     | 
| 
       116 
117 
     | 
    
         | 
| 
         @@ -126,22 +127,23 @@ private static byte[] init__puma_parser_indicies_0() 
     | 
|
| 
       126 
127 
     | 
    
         
             
            	   16,   15,    1,   17,    1,   18,   17,    1,   19,    1,   20,   21,
         
     | 
| 
       127 
128 
     | 
    
         
             
            	   21,   21,   21,   21,   21,   21,   21,   21,    1,   22,    1,   23,
         
     | 
| 
       128 
129 
     | 
    
         
             
            	   24,   23,   23,   23,   23,   23,   23,   23,   23,    1,   26,   27,
         
     | 
| 
       129 
     | 
    
         
            -
             
     | 
| 
       130 
     | 
    
         
            -
            	    1,    1,    1,    1, 
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
            	    1,    
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
       134 
     | 
    
         
            -
             
     | 
| 
       135 
     | 
    
         
            -
            	    
     | 
| 
       136 
     | 
    
         
            -
            	     
     | 
| 
       137 
     | 
    
         
            -
            	    
     | 
| 
       138 
     | 
    
         
            -
            	    
     | 
| 
       139 
     | 
    
         
            -
             
     | 
| 
       140 
     | 
    
         
            -
             
     | 
| 
       141 
     | 
    
         
            -
            	    
     | 
| 
       142 
     | 
    
         
            -
            	    
     | 
| 
       143 
     | 
    
         
            -
            	     
     | 
| 
       144 
     | 
    
         
            -
            	   63,   63,    1,    2,    1,    1, 
     | 
| 
      
 130 
     | 
    
         
            +
            	    1,    1,    1,   25,   29,    1,    1,    1,   28,   30,    1,    1,
         
     | 
| 
      
 131 
     | 
    
         
            +
            	    1,    1,    1,   31,   32,    1,    1,    1,    1,    1,   33,   34,
         
     | 
| 
      
 132 
     | 
    
         
            +
            	   35,   34,   34,   34,   34,    1,    8,    1,    9,    1,    1,    1,
         
     | 
| 
      
 133 
     | 
    
         
            +
            	    1,   35,   36,    1,   38,    1,    1,   39,    1,    1,   37,   40,
         
     | 
| 
      
 134 
     | 
    
         
            +
            	    1,   42,    1,    1,    1,    1,   41,   43,    1,   45,    1,    1,
         
     | 
| 
      
 135 
     | 
    
         
            +
            	    1,    1,   44,    2,   46,   46,   46,   46,   46,    1,    2,   47,
         
     | 
| 
      
 136 
     | 
    
         
            +
            	   47,   47,   47,   47,    1,    2,   48,   48,   48,   48,   48,    1,
         
     | 
| 
      
 137 
     | 
    
         
            +
            	    2,   49,   49,   49,   49,   49,    1,    2,   50,   50,   50,   50,
         
     | 
| 
      
 138 
     | 
    
         
            +
            	   50,    1,    2,   51,   51,   51,   51,   51,    1,    2,   52,   52,
         
     | 
| 
      
 139 
     | 
    
         
            +
            	   52,   52,   52,    1,    2,   53,   53,   53,   53,   53,    1,    2,
         
     | 
| 
      
 140 
     | 
    
         
            +
            	   54,   54,   54,   54,   54,    1,    2,   55,   55,   55,   55,   55,
         
     | 
| 
      
 141 
     | 
    
         
            +
            	    1,    2,   56,   56,   56,   56,   56,    1,    2,   57,   57,   57,
         
     | 
| 
      
 142 
     | 
    
         
            +
            	   57,   57,    1,    2,   58,   58,   58,   58,   58,    1,    2,   59,
         
     | 
| 
      
 143 
     | 
    
         
            +
            	   59,   59,   59,   59,    1,    2,   60,   60,   60,   60,   60,    1,
         
     | 
| 
      
 144 
     | 
    
         
            +
            	    2,   61,   61,   61,   61,   61,    1,    2,   62,   62,   62,   62,
         
     | 
| 
      
 145 
     | 
    
         
            +
            	   62,    1,    2,   63,   63,   63,   63,   63,    1,    2,    1,    1,
         
     | 
| 
      
 146 
     | 
    
         
            +
            	    0
         
     | 
| 
       145 
147 
     | 
    
         
             
            	};
         
     | 
| 
       146 
148 
     | 
    
         
             
            }
         
     | 
| 
       147 
149 
     | 
    
         | 
| 
         @@ -210,7 +212,7 @@ static final int puma_parser_error = 0; 
     | 
|
| 
       210 
212 
     | 
    
         
             
                      cs = 0;
         
     | 
| 
       211 
213 
     | 
    
         | 
| 
       212 
214 
     | 
    
         | 
| 
       213 
     | 
    
         
            -
            // line  
     | 
| 
      
 215 
     | 
    
         
            +
            // line 216 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
         
     | 
| 
       214 
216 
     | 
    
         
             
            	{
         
     | 
| 
       215 
217 
     | 
    
         
             
            	cs = puma_parser_start;
         
     | 
| 
       216 
218 
     | 
    
         
             
            	}
         
     | 
| 
         @@ -242,7 +244,7 @@ static final int puma_parser_error = 0; 
     | 
|
| 
       242 
244 
     | 
    
         
             
                 parser.buffer = buffer;
         
     | 
| 
       243 
245 
     | 
    
         | 
| 
       244 
246 
     | 
    
         | 
| 
       245 
     | 
    
         
            -
            // line  
     | 
| 
      
 247 
     | 
    
         
            +
            // line 248 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
         
     | 
| 
       246 
248 
     | 
    
         
             
            	{
         
     | 
| 
       247 
249 
     | 
    
         
             
            	int _klen;
         
     | 
| 
       248 
250 
     | 
    
         
             
            	int _trans = 0;
         
     | 
| 
         @@ -381,7 +383,7 @@ case 1: 
     | 
|
| 
       381 
383 
     | 
    
         
             
            	case 11:
         
     | 
| 
       382 
384 
     | 
    
         
             
            // line 42 "ext/puma_http11/http11_parser.java.rl"
         
     | 
| 
       383 
385 
     | 
    
         
             
            	{
         
     | 
| 
       384 
     | 
    
         
            -
                Http11. 
     | 
| 
      
 386 
     | 
    
         
            +
                Http11.server_protocol(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark);
         
     | 
| 
       385 
387 
     | 
    
         
             
              }
         
     | 
| 
       386 
388 
     | 
    
         
             
            	break;
         
     | 
| 
       387 
389 
     | 
    
         
             
            	case 12:
         
     | 
| 
         @@ -398,7 +400,7 @@ case 1: 
     | 
|
| 
       398 
400 
     | 
    
         
             
                { p += 1; _goto_targ = 5; if (true)  continue _goto;}
         
     | 
| 
       399 
401 
     | 
    
         
             
              }
         
     | 
| 
       400 
402 
     | 
    
         
             
            	break;
         
     | 
| 
       401 
     | 
    
         
            -
            // line  
     | 
| 
      
 403 
     | 
    
         
            +
            // line 404 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
         
     | 
| 
       402 
404 
     | 
    
         
             
            			}
         
     | 
| 
       403 
405 
     | 
    
         
             
            		}
         
     | 
| 
       404 
406 
     | 
    
         
             
            	}
         
     | 
| 
         @@ -1,11 +1,13 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            package org.jruby.puma;
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            import org.jruby.Ruby;
         
     | 
| 
      
 4 
     | 
    
         
            +
            import org.jruby.RubyArray;
         
     | 
| 
       4 
5 
     | 
    
         
             
            import org.jruby.RubyClass;
         
     | 
| 
       5 
6 
     | 
    
         
             
            import org.jruby.RubyModule;
         
     | 
| 
       6 
7 
     | 
    
         
             
            import org.jruby.RubyObject;
         
     | 
| 
       7 
8 
     | 
    
         
             
            import org.jruby.RubyString;
         
     | 
| 
       8 
9 
     | 
    
         
             
            import org.jruby.anno.JRubyMethod;
         
     | 
| 
      
 10 
     | 
    
         
            +
            import org.jruby.exceptions.RaiseException;
         
     | 
| 
       9 
11 
     | 
    
         
             
            import org.jruby.javasupport.JavaEmbedUtils;
         
     | 
| 
       10 
12 
     | 
    
         
             
            import org.jruby.runtime.Block;
         
     | 
| 
       11 
13 
     | 
    
         
             
            import org.jruby.runtime.ObjectAllocator;
         
     | 
| 
         @@ -14,6 +16,7 @@ import org.jruby.runtime.builtin.IRubyObject; 
     | 
|
| 
       14 
16 
     | 
    
         
             
            import org.jruby.util.ByteList;
         
     | 
| 
       15 
17 
     | 
    
         | 
| 
       16 
18 
     | 
    
         
             
            import javax.net.ssl.KeyManagerFactory;
         
     | 
| 
      
 19 
     | 
    
         
            +
            import javax.net.ssl.TrustManager;
         
     | 
| 
       17 
20 
     | 
    
         
             
            import javax.net.ssl.TrustManagerFactory;
         
     | 
| 
       18 
21 
     | 
    
         
             
            import javax.net.ssl.SSLContext;
         
     | 
| 
       19 
22 
     | 
    
         
             
            import javax.net.ssl.SSLEngine;
         
     | 
| 
         @@ -21,6 +24,7 @@ import javax.net.ssl.SSLEngineResult; 
     | 
|
| 
       21 
24 
     | 
    
         
             
            import javax.net.ssl.SSLException;
         
     | 
| 
       22 
25 
     | 
    
         
             
            import javax.net.ssl.SSLPeerUnverifiedException;
         
     | 
| 
       23 
26 
     | 
    
         
             
            import javax.net.ssl.SSLSession;
         
     | 
| 
      
 27 
     | 
    
         
            +
            import javax.net.ssl.X509TrustManager;
         
     | 
| 
       24 
28 
     | 
    
         
             
            import java.io.FileInputStream;
         
     | 
| 
       25 
29 
     | 
    
         
             
            import java.io.InputStream;
         
     | 
| 
       26 
30 
     | 
    
         
             
            import java.io.IOException;
         
     | 
| 
         @@ -31,15 +35,18 @@ import java.security.KeyStore; 
     | 
|
| 
       31 
35 
     | 
    
         
             
            import java.security.KeyStoreException;
         
     | 
| 
       32 
36 
     | 
    
         
             
            import java.security.NoSuchAlgorithmException;
         
     | 
| 
       33 
37 
     | 
    
         
             
            import java.security.UnrecoverableKeyException;
         
     | 
| 
      
 38 
     | 
    
         
            +
            import java.security.cert.Certificate;
         
     | 
| 
       34 
39 
     | 
    
         
             
            import java.security.cert.CertificateEncodingException;
         
     | 
| 
       35 
40 
     | 
    
         
             
            import java.security.cert.CertificateException;
         
     | 
| 
      
 41 
     | 
    
         
            +
            import java.security.cert.X509Certificate;
         
     | 
| 
       36 
42 
     | 
    
         
             
            import java.util.concurrent.ConcurrentHashMap;
         
     | 
| 
       37 
43 
     | 
    
         
             
            import java.util.Map;
         
     | 
| 
      
 44 
     | 
    
         
            +
            import java.util.function.Supplier;
         
     | 
| 
       38 
45 
     | 
    
         | 
| 
       39 
46 
     | 
    
         
             
            import static javax.net.ssl.SSLEngineResult.Status;
         
     | 
| 
       40 
47 
     | 
    
         
             
            import static javax.net.ssl.SSLEngineResult.HandshakeStatus;
         
     | 
| 
       41 
48 
     | 
    
         | 
| 
       42 
     | 
    
         
            -
            public class MiniSSL extends RubyObject {
         
     | 
| 
      
 49 
     | 
    
         
            +
            public class MiniSSL extends RubyObject { // MiniSSL::Engine
         
     | 
| 
       43 
50 
     | 
    
         
             
              private static ObjectAllocator ALLOCATOR = new ObjectAllocator() {
         
     | 
| 
       44 
51 
     | 
    
         
             
                public IRubyObject allocate(Ruby runtime, RubyClass klass) {
         
     | 
| 
       45 
52 
     | 
    
         
             
                  return new MiniSSL(runtime, klass);
         
     | 
| 
         @@ -50,11 +57,10 @@ public class MiniSSL extends RubyObject { 
     | 
|
| 
       50 
57 
     | 
    
         
             
                RubyModule mPuma = runtime.defineModule("Puma");
         
     | 
| 
       51 
58 
     | 
    
         
             
                RubyModule ssl = mPuma.defineModuleUnder("MiniSSL");
         
     | 
| 
       52 
59 
     | 
    
         | 
| 
       53 
     | 
    
         
            -
                 
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
                                       runtime.getClass("IOError").getAllocator());
         
     | 
| 
      
 60 
     | 
    
         
            +
                // Puma::MiniSSL::SSLError
         
     | 
| 
      
 61 
     | 
    
         
            +
                ssl.defineClassUnder("SSLError", runtime.getStandardError(), runtime.getStandardError().getAllocator());
         
     | 
| 
       56 
62 
     | 
    
         | 
| 
       57 
     | 
    
         
            -
                RubyClass eng = ssl.defineClassUnder("Engine",runtime.getObject(),ALLOCATOR);
         
     | 
| 
      
 63 
     | 
    
         
            +
                RubyClass eng = ssl.defineClassUnder("Engine", runtime.getObject(), ALLOCATOR);
         
     | 
| 
       58 
64 
     | 
    
         
             
                eng.defineAnnotatedMethods(MiniSSL.class);
         
     | 
| 
       59 
65 
     | 
    
         
             
              }
         
     | 
| 
       60 
66 
     | 
    
         | 
| 
         @@ -80,11 +86,11 @@ public class MiniSSL extends RubyObject { 
     | 
|
| 
       80 
86 
     | 
    
         
             
                /**
         
     | 
| 
       81 
87 
     | 
    
         
             
                 * Writes bytes to the buffer after ensuring there's room
         
     | 
| 
       82 
88 
     | 
    
         
             
                 */
         
     | 
| 
       83 
     | 
    
         
            -
                 
     | 
| 
       84 
     | 
    
         
            -
                  if (buffer.remaining() <  
     | 
| 
       85 
     | 
    
         
            -
                    resize(buffer.limit() +  
     | 
| 
      
 89 
     | 
    
         
            +
                private void put(byte[] bytes, final int offset, final int length) {
         
     | 
| 
      
 90 
     | 
    
         
            +
                  if (buffer.remaining() < length) {
         
     | 
| 
      
 91 
     | 
    
         
            +
                    resize(buffer.limit() + length);
         
     | 
| 
       86 
92 
     | 
    
         
             
                  }
         
     | 
| 
       87 
     | 
    
         
            -
                  buffer.put(bytes);
         
     | 
| 
      
 93 
     | 
    
         
            +
                  buffer.put(bytes, offset, length);
         
     | 
| 
       88 
94 
     | 
    
         
             
                }
         
     | 
| 
       89 
95 
     | 
    
         | 
| 
       90 
96 
     | 
    
         
             
                /**
         
     | 
| 
         @@ -115,7 +121,7 @@ public class MiniSSL extends RubyObject { 
     | 
|
| 
       115 
121 
     | 
    
         | 
| 
       116 
122 
     | 
    
         
             
                  buffer.get(bss);
         
     | 
| 
       117 
123 
     | 
    
         
             
                  buffer.clear();
         
     | 
| 
       118 
     | 
    
         
            -
                  return new ByteList(bss);
         
     | 
| 
      
 124 
     | 
    
         
            +
                  return new ByteList(bss, false);
         
     | 
| 
       119 
125 
     | 
    
         
             
                }
         
     | 
| 
       120 
126 
     | 
    
         | 
| 
       121 
127 
     | 
    
         
             
                @Override
         
     | 
| 
         @@ -136,76 +142,116 @@ public class MiniSSL extends RubyObject { 
     | 
|
| 
       136 
142 
     | 
    
         
             
              private static Map<String, KeyManagerFactory> keyManagerFactoryMap = new ConcurrentHashMap<String, KeyManagerFactory>();
         
     | 
| 
       137 
143 
     | 
    
         
             
              private static Map<String, TrustManagerFactory> trustManagerFactoryMap = new ConcurrentHashMap<String, TrustManagerFactory>();
         
     | 
| 
       138 
144 
     | 
    
         | 
| 
       139 
     | 
    
         
            -
              @JRubyMethod(meta = true)
         
     | 
| 
      
 145 
     | 
    
         
            +
              @JRubyMethod(meta = true) // Engine.server
         
     | 
| 
       140 
146 
     | 
    
         
             
              public static synchronized IRubyObject server(ThreadContext context, IRubyObject recv, IRubyObject miniSSLContext)
         
     | 
| 
       141 
147 
     | 
    
         
             
                  throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException {
         
     | 
| 
       142 
148 
     | 
    
         
             
                // Create the KeyManagerFactory and TrustManagerFactory for this server
         
     | 
| 
       143 
     | 
    
         
            -
                String keystoreFile = miniSSLContext.callMethod(context, "keystore") 
     | 
| 
       144 
     | 
    
         
            -
                char[]  
     | 
| 
      
 149 
     | 
    
         
            +
                String keystoreFile = asStringValue(miniSSLContext.callMethod(context, "keystore"), null);
         
     | 
| 
      
 150 
     | 
    
         
            +
                char[] keystorePass = asStringValue(miniSSLContext.callMethod(context, "keystore_pass"), null).toCharArray();
         
     | 
| 
      
 151 
     | 
    
         
            +
                String keystoreType = asStringValue(miniSSLContext.callMethod(context, "keystore_type"), KeyStore::getDefaultType);
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
                String truststoreFile;
         
     | 
| 
      
 154 
     | 
    
         
            +
                char[] truststorePass;
         
     | 
| 
      
 155 
     | 
    
         
            +
                String truststoreType;
         
     | 
| 
      
 156 
     | 
    
         
            +
                IRubyObject truststore = miniSSLContext.callMethod(context, "truststore");
         
     | 
| 
      
 157 
     | 
    
         
            +
                if (truststore.isNil()) {
         
     | 
| 
      
 158 
     | 
    
         
            +
                  truststoreFile = keystoreFile;
         
     | 
| 
      
 159 
     | 
    
         
            +
                  truststorePass = keystorePass;
         
     | 
| 
      
 160 
     | 
    
         
            +
                  truststoreType = keystoreType;
         
     | 
| 
      
 161 
     | 
    
         
            +
                } else if (!isDefaultSymbol(context, truststore)) {
         
     | 
| 
      
 162 
     | 
    
         
            +
                  truststoreFile = truststore.convertToString().asJavaString();
         
     | 
| 
      
 163 
     | 
    
         
            +
                  IRubyObject pass = miniSSLContext.callMethod(context, "truststore_pass");
         
     | 
| 
      
 164 
     | 
    
         
            +
                  if (pass.isNil()) {
         
     | 
| 
      
 165 
     | 
    
         
            +
                    truststorePass = null;
         
     | 
| 
      
 166 
     | 
    
         
            +
                  } else {
         
     | 
| 
      
 167 
     | 
    
         
            +
                    truststorePass = asStringValue(pass, null).toCharArray();
         
     | 
| 
      
 168 
     | 
    
         
            +
                  }
         
     | 
| 
      
 169 
     | 
    
         
            +
                  truststoreType = asStringValue(miniSSLContext.callMethod(context, "truststore_type"), KeyStore::getDefaultType);
         
     | 
| 
      
 170 
     | 
    
         
            +
                } else { // self.truststore = :default
         
     | 
| 
      
 171 
     | 
    
         
            +
                  truststoreFile = null;
         
     | 
| 
      
 172 
     | 
    
         
            +
                  truststorePass = null;
         
     | 
| 
      
 173 
     | 
    
         
            +
                  truststoreType = null;
         
     | 
| 
      
 174 
     | 
    
         
            +
                }
         
     | 
| 
       145 
175 
     | 
    
         | 
| 
       146 
     | 
    
         
            -
                KeyStore ks = KeyStore.getInstance( 
     | 
| 
      
 176 
     | 
    
         
            +
                KeyStore ks = KeyStore.getInstance(keystoreType);
         
     | 
| 
       147 
177 
     | 
    
         
             
                InputStream is = new FileInputStream(keystoreFile);
         
     | 
| 
       148 
178 
     | 
    
         
             
                try {
         
     | 
| 
       149 
     | 
    
         
            -
                  ks.load(is,  
     | 
| 
      
 179 
     | 
    
         
            +
                  ks.load(is, keystorePass);
         
     | 
| 
       150 
180 
     | 
    
         
             
                } finally {
         
     | 
| 
       151 
181 
     | 
    
         
             
                  is.close();
         
     | 
| 
       152 
182 
     | 
    
         
             
                }
         
     | 
| 
       153 
183 
     | 
    
         
             
                KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
         
     | 
| 
       154 
     | 
    
         
            -
                kmf.init(ks,  
     | 
| 
      
 184 
     | 
    
         
            +
                kmf.init(ks, keystorePass);
         
     | 
| 
       155 
185 
     | 
    
         
             
                keyManagerFactoryMap.put(keystoreFile, kmf);
         
     | 
| 
       156 
186 
     | 
    
         | 
| 
       157 
     | 
    
         
            -
                 
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
       159 
     | 
    
         
            -
             
     | 
| 
       160 
     | 
    
         
            -
                   
     | 
| 
       161 
     | 
    
         
            -
             
     | 
| 
       162 
     | 
    
         
            -
                   
     | 
| 
      
 187 
     | 
    
         
            +
                if (truststoreFile != null) {
         
     | 
| 
      
 188 
     | 
    
         
            +
                  KeyStore ts = KeyStore.getInstance(truststoreType);
         
     | 
| 
      
 189 
     | 
    
         
            +
                  is = new FileInputStream(truststoreFile);
         
     | 
| 
      
 190 
     | 
    
         
            +
                  try {
         
     | 
| 
      
 191 
     | 
    
         
            +
                    ts.load(is, truststorePass);
         
     | 
| 
      
 192 
     | 
    
         
            +
                  } finally {
         
     | 
| 
      
 193 
     | 
    
         
            +
                    is.close();
         
     | 
| 
      
 194 
     | 
    
         
            +
                  }
         
     | 
| 
      
 195 
     | 
    
         
            +
                  TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
         
     | 
| 
      
 196 
     | 
    
         
            +
                  tmf.init(ts);
         
     | 
| 
      
 197 
     | 
    
         
            +
                  trustManagerFactoryMap.put(truststoreFile, tmf);
         
     | 
| 
       163 
198 
     | 
    
         
             
                }
         
     | 
| 
       164 
     | 
    
         
            -
                TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
         
     | 
| 
       165 
     | 
    
         
            -
                tmf.init(ts);
         
     | 
| 
       166 
     | 
    
         
            -
                trustManagerFactoryMap.put(keystoreFile, tmf);
         
     | 
| 
       167 
199 
     | 
    
         | 
| 
       168 
200 
     | 
    
         
             
                RubyClass klass = (RubyClass) recv;
         
     | 
| 
       169 
     | 
    
         
            -
                return klass.newInstance(context,
         
     | 
| 
       170 
     | 
    
         
            -
             
     | 
| 
       171 
     | 
    
         
            -
             
     | 
| 
      
 201 
     | 
    
         
            +
                return klass.newInstance(context, miniSSLContext, Block.NULL_BLOCK);
         
     | 
| 
      
 202 
     | 
    
         
            +
              }
         
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
      
 204 
     | 
    
         
            +
              private static String asStringValue(IRubyObject value, Supplier<String> defaultValue) {
         
     | 
| 
      
 205 
     | 
    
         
            +
                if (defaultValue != null && value.isNil()) return defaultValue.get();
         
     | 
| 
      
 206 
     | 
    
         
            +
                return value.convertToString().asJavaString();
         
     | 
| 
      
 207 
     | 
    
         
            +
              }
         
     | 
| 
      
 208 
     | 
    
         
            +
             
     | 
| 
      
 209 
     | 
    
         
            +
              private static boolean isDefaultSymbol(ThreadContext context, IRubyObject truststore) {
         
     | 
| 
      
 210 
     | 
    
         
            +
                return context.runtime.newSymbol("default").equals(truststore);
         
     | 
| 
       172 
211 
     | 
    
         
             
              }
         
     | 
| 
       173 
212 
     | 
    
         | 
| 
       174 
213 
     | 
    
         
             
              @JRubyMethod
         
     | 
| 
       175 
     | 
    
         
            -
              public IRubyObject initialize(ThreadContext  
     | 
| 
      
 214 
     | 
    
         
            +
              public IRubyObject initialize(ThreadContext context, IRubyObject miniSSLContext)
         
     | 
| 
       176 
215 
     | 
    
         
             
                  throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
         
     | 
| 
       177 
     | 
    
         
            -
                KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
         
     | 
| 
       178 
     | 
    
         
            -
                KeyStore ts = KeyStore.getInstance(KeyStore.getDefaultType());
         
     | 
| 
       179 
216 
     | 
    
         | 
| 
       180 
     | 
    
         
            -
                String keystoreFile = miniSSLContext.callMethod( 
     | 
| 
      
 217 
     | 
    
         
            +
                String keystoreFile = miniSSLContext.callMethod(context, "keystore").convertToString().asJavaString();
         
     | 
| 
       181 
218 
     | 
    
         
             
                KeyManagerFactory kmf = keyManagerFactoryMap.get(keystoreFile);
         
     | 
| 
       182 
     | 
    
         
            -
                 
     | 
| 
       183 
     | 
    
         
            -
                 
     | 
| 
       184 
     | 
    
         
            -
             
     | 
| 
      
 219 
     | 
    
         
            +
                IRubyObject truststore = miniSSLContext.callMethod(context, "truststore");
         
     | 
| 
      
 220 
     | 
    
         
            +
                String truststoreFile = isDefaultSymbol(context, truststore) ? "" : asStringValue(truststore, () -> keystoreFile);
         
     | 
| 
      
 221 
     | 
    
         
            +
                TrustManagerFactory tmf = trustManagerFactoryMap.get(truststoreFile); // null if self.truststore = :default
         
     | 
| 
      
 222 
     | 
    
         
            +
                if (kmf == null) {
         
     | 
| 
      
 223 
     | 
    
         
            +
                  throw new KeyStoreException("Could not find KeyManagerFactory for keystore: " + keystoreFile + " truststore: " + truststoreFile);
         
     | 
| 
       185 
224 
     | 
    
         
             
                }
         
     | 
| 
       186 
225 
     | 
    
         | 
| 
       187 
226 
     | 
    
         
             
                SSLContext sslCtx = SSLContext.getInstance("TLS");
         
     | 
| 
       188 
227 
     | 
    
         | 
| 
       189 
     | 
    
         
            -
                sslCtx.init(kmf.getKeyManagers(),  
     | 
| 
      
 228 
     | 
    
         
            +
                sslCtx.init(kmf.getKeyManagers(), getTrustManagers(tmf), null);
         
     | 
| 
       190 
229 
     | 
    
         
             
                closed = false;
         
     | 
| 
       191 
230 
     | 
    
         
             
                handshake = false;
         
     | 
| 
       192 
231 
     | 
    
         
             
                engine = sslCtx.createSSLEngine();
         
     | 
| 
       193 
232 
     | 
    
         | 
| 
       194 
     | 
    
         
            -
                String[]  
     | 
| 
       195 
     | 
    
         
            -
                 
     | 
| 
       196 
     | 
    
         
            -
             
     | 
| 
       197 
     | 
    
         
            -
             
     | 
| 
       198 
     | 
    
         
            -
                     
     | 
| 
       199 
     | 
    
         
            -
             
     | 
| 
      
 233 
     | 
    
         
            +
                String[] enabledProtocols;
         
     | 
| 
      
 234 
     | 
    
         
            +
                IRubyObject protocols = miniSSLContext.callMethod(context, "protocols");
         
     | 
| 
      
 235 
     | 
    
         
            +
                if (protocols.isNil()) {
         
     | 
| 
      
 236 
     | 
    
         
            +
                  if (miniSSLContext.callMethod(context, "no_tlsv1").isTrue()) {
         
     | 
| 
      
 237 
     | 
    
         
            +
                    enabledProtocols = new String[] { "TLSv1.1", "TLSv1.2", "TLSv1.3" };
         
     | 
| 
      
 238 
     | 
    
         
            +
                  } else {
         
     | 
| 
      
 239 
     | 
    
         
            +
                    enabledProtocols = new String[] { "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3" };
         
     | 
| 
      
 240 
     | 
    
         
            +
                  }
         
     | 
| 
       200 
241 
     | 
    
         | 
| 
       201 
     | 
    
         
            -
             
     | 
| 
       202 
     | 
    
         
            -
                     
     | 
| 
      
 242 
     | 
    
         
            +
                  if (miniSSLContext.callMethod(context, "no_tlsv1_1").isTrue()) {
         
     | 
| 
      
 243 
     | 
    
         
            +
                    enabledProtocols = new String[] { "TLSv1.2", "TLSv1.3" };
         
     | 
| 
      
 244 
     | 
    
         
            +
                  }
         
     | 
| 
      
 245 
     | 
    
         
            +
                } else if (protocols instanceof RubyArray) {
         
     | 
| 
      
 246 
     | 
    
         
            +
                  enabledProtocols = (String[]) ((RubyArray) protocols).toArray(new String[0]);
         
     | 
| 
      
 247 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 248 
     | 
    
         
            +
                  throw context.runtime.newTypeError(protocols, context.runtime.getArray());
         
     | 
| 
       203 
249 
     | 
    
         
             
                }
         
     | 
| 
      
 250 
     | 
    
         
            +
                engine.setEnabledProtocols(enabledProtocols);
         
     | 
| 
       204 
251 
     | 
    
         | 
| 
       205 
     | 
    
         
            -
                engine.setEnabledProtocols(protocols);
         
     | 
| 
       206 
252 
     | 
    
         
             
                engine.setUseClientMode(false);
         
     | 
| 
       207 
253 
     | 
    
         | 
| 
       208 
     | 
    
         
            -
                long verify_mode = miniSSLContext.callMethod( 
     | 
| 
      
 254 
     | 
    
         
            +
                long verify_mode = miniSSLContext.callMethod(context, "verify_mode").convertToInteger("to_i").getLongValue();
         
     | 
| 
       209 
255 
     | 
    
         
             
                if ((verify_mode & 0x1) != 0) { // 'peer'
         
     | 
| 
       210 
256 
     | 
    
         
             
                    engine.setWantClientAuth(true);
         
     | 
| 
       211 
257 
     | 
    
         
             
                }
         
     | 
| 
         @@ -213,10 +259,11 @@ public class MiniSSL extends RubyObject { 
     | 
|
| 
       213 
259 
     | 
    
         
             
                    engine.setNeedClientAuth(true);
         
     | 
| 
       214 
260 
     | 
    
         
             
                }
         
     | 
| 
       215 
261 
     | 
    
         | 
| 
       216 
     | 
    
         
            -
                IRubyObject  
     | 
| 
       217 
     | 
    
         
            -
                if ( 
     | 
| 
       218 
     | 
    
         
            -
                  String[]  
     | 
| 
       219 
     | 
    
         
            -
             
     | 
| 
      
 262 
     | 
    
         
            +
                IRubyObject cipher_suites = miniSSLContext.callMethod(context, "cipher_suites");
         
     | 
| 
      
 263 
     | 
    
         
            +
                if (cipher_suites instanceof RubyArray) {
         
     | 
| 
      
 264 
     | 
    
         
            +
                  engine.setEnabledCipherSuites((String[]) ((RubyArray) cipher_suites).toArray(new String[0]));
         
     | 
| 
      
 265 
     | 
    
         
            +
                } else if (!cipher_suites.isNil()) {
         
     | 
| 
      
 266 
     | 
    
         
            +
                  throw context.runtime.newTypeError(cipher_suites, context.runtime.getArray());
         
     | 
| 
       220 
267 
     | 
    
         
             
                }
         
     | 
| 
       221 
268 
     | 
    
         | 
| 
       222 
269 
     | 
    
         
             
                SSLSession session = engine.getSession();
         
     | 
| 
         @@ -228,16 +275,53 @@ public class MiniSSL extends RubyObject { 
     | 
|
| 
       228 
275 
     | 
    
         
             
                return this;
         
     | 
| 
       229 
276 
     | 
    
         
             
              }
         
     | 
| 
       230 
277 
     | 
    
         | 
| 
      
 278 
     | 
    
         
            +
              private TrustManager[] getTrustManagers(TrustManagerFactory factory) {
         
     | 
| 
      
 279 
     | 
    
         
            +
                if (factory == null) return null; // use JDK trust defaults
         
     | 
| 
      
 280 
     | 
    
         
            +
                final TrustManager[] tms = factory.getTrustManagers();
         
     | 
| 
      
 281 
     | 
    
         
            +
                if (tms != null) {
         
     | 
| 
      
 282 
     | 
    
         
            +
                  for (int i=0; i<tms.length; i++) {
         
     | 
| 
      
 283 
     | 
    
         
            +
                    final TrustManager tm = tms[i];
         
     | 
| 
      
 284 
     | 
    
         
            +
                    if (tm instanceof X509TrustManager) {
         
     | 
| 
      
 285 
     | 
    
         
            +
                      tms[i] = new TrustManagerWrapper((X509TrustManager) tm);
         
     | 
| 
      
 286 
     | 
    
         
            +
                    }
         
     | 
| 
      
 287 
     | 
    
         
            +
                  }
         
     | 
| 
      
 288 
     | 
    
         
            +
                }
         
     | 
| 
      
 289 
     | 
    
         
            +
                return tms;
         
     | 
| 
      
 290 
     | 
    
         
            +
              }
         
     | 
| 
      
 291 
     | 
    
         
            +
             
     | 
| 
      
 292 
     | 
    
         
            +
              private volatile transient X509Certificate lastCheckedCert0;
         
     | 
| 
      
 293 
     | 
    
         
            +
             
     | 
| 
      
 294 
     | 
    
         
            +
              private class TrustManagerWrapper implements X509TrustManager {
         
     | 
| 
      
 295 
     | 
    
         
            +
             
     | 
| 
      
 296 
     | 
    
         
            +
                private final X509TrustManager delegate;
         
     | 
| 
      
 297 
     | 
    
         
            +
             
     | 
| 
      
 298 
     | 
    
         
            +
                TrustManagerWrapper(X509TrustManager delegate) {
         
     | 
| 
      
 299 
     | 
    
         
            +
                  this.delegate = delegate;
         
     | 
| 
      
 300 
     | 
    
         
            +
                }
         
     | 
| 
      
 301 
     | 
    
         
            +
             
     | 
| 
      
 302 
     | 
    
         
            +
                @Override
         
     | 
| 
      
 303 
     | 
    
         
            +
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
         
     | 
| 
      
 304 
     | 
    
         
            +
                  lastCheckedCert0 = chain.length > 0 ? chain[0] : null;
         
     | 
| 
      
 305 
     | 
    
         
            +
                  delegate.checkClientTrusted(chain, authType);
         
     | 
| 
      
 306 
     | 
    
         
            +
                }
         
     | 
| 
      
 307 
     | 
    
         
            +
             
     | 
| 
      
 308 
     | 
    
         
            +
                @Override
         
     | 
| 
      
 309 
     | 
    
         
            +
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
         
     | 
| 
      
 310 
     | 
    
         
            +
                  delegate.checkServerTrusted(chain, authType);
         
     | 
| 
      
 311 
     | 
    
         
            +
                }
         
     | 
| 
      
 312 
     | 
    
         
            +
             
     | 
| 
      
 313 
     | 
    
         
            +
                @Override
         
     | 
| 
      
 314 
     | 
    
         
            +
                public X509Certificate[] getAcceptedIssuers() {
         
     | 
| 
      
 315 
     | 
    
         
            +
                  return delegate.getAcceptedIssuers();
         
     | 
| 
      
 316 
     | 
    
         
            +
                }
         
     | 
| 
      
 317 
     | 
    
         
            +
             
     | 
| 
      
 318 
     | 
    
         
            +
              }
         
     | 
| 
      
 319 
     | 
    
         
            +
             
     | 
| 
       231 
320 
     | 
    
         
             
              @JRubyMethod
         
     | 
| 
       232 
321 
     | 
    
         
             
              public IRubyObject inject(IRubyObject arg) {
         
     | 
| 
       233 
     | 
    
         
            -
                 
     | 
| 
       234 
     | 
    
         
            -
             
     | 
| 
       235 
     | 
    
         
            -
             
     | 
| 
       236 
     | 
    
         
            -
                  return this;
         
     | 
| 
       237 
     | 
    
         
            -
                } catch (Exception e) {
         
     | 
| 
       238 
     | 
    
         
            -
                  e.printStackTrace();
         
     | 
| 
       239 
     | 
    
         
            -
                  throw new RuntimeException(e);
         
     | 
| 
       240 
     | 
    
         
            -
                }
         
     | 
| 
      
 322 
     | 
    
         
            +
                ByteList bytes = arg.convertToString().getByteList();
         
     | 
| 
      
 323 
     | 
    
         
            +
                inboundNetData.put(bytes.unsafeBytes(), bytes.getBegin(), bytes.getRealSize());
         
     | 
| 
      
 324 
     | 
    
         
            +
                return this;
         
     | 
| 
       241 
325 
     | 
    
         
             
              }
         
     | 
| 
       242 
326 
     | 
    
         | 
| 
       243 
327 
     | 
    
         
             
              private enum SSLOperation {
         
     | 
| 
         @@ -257,7 +341,7 @@ public class MiniSSL extends RubyObject { 
     | 
|
| 
       257 
341 
     | 
    
         
             
                      res = engine.unwrap(src.getRawBuffer(), dst.getRawBuffer());
         
     | 
| 
       258 
342 
     | 
    
         
             
                      break;
         
     | 
| 
       259 
343 
     | 
    
         
             
                    default:
         
     | 
| 
       260 
     | 
    
         
            -
                      throw new  
     | 
| 
      
 344 
     | 
    
         
            +
                      throw new AssertionError("Unknown SSLOperation: " + sslOp);
         
     | 
| 
       261 
345 
     | 
    
         
             
                  }
         
     | 
| 
       262 
346 
     | 
    
         | 
| 
       263 
347 
     | 
    
         
             
                  switch (res.getStatus()) {
         
     | 
| 
         @@ -285,19 +369,11 @@ public class MiniSSL extends RubyObject { 
     | 
|
| 
       285 
369 
     | 
    
         
             
                  }
         
     | 
| 
       286 
370 
     | 
    
         
             
                }
         
     | 
| 
       287 
371 
     | 
    
         | 
| 
       288 
     | 
    
         
            -
                // after each op, run any delegated tasks if needed
         
     | 
| 
       289 
     | 
    
         
            -
                if(res.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
         
     | 
| 
       290 
     | 
    
         
            -
                  Runnable runnable;
         
     | 
| 
       291 
     | 
    
         
            -
                  while ((runnable = engine.getDelegatedTask()) != null) {
         
     | 
| 
       292 
     | 
    
         
            -
                    runnable.run();
         
     | 
| 
       293 
     | 
    
         
            -
                  }
         
     | 
| 
       294 
     | 
    
         
            -
                }
         
     | 
| 
       295 
     | 
    
         
            -
             
     | 
| 
       296 
372 
     | 
    
         
             
                return res;
         
     | 
| 
       297 
373 
     | 
    
         
             
              }
         
     | 
| 
       298 
374 
     | 
    
         | 
| 
       299 
375 
     | 
    
         
             
              @JRubyMethod
         
     | 
| 
       300 
     | 
    
         
            -
              public IRubyObject read()  
     | 
| 
      
 376 
     | 
    
         
            +
              public IRubyObject read() {
         
     | 
| 
       301 
377 
     | 
    
         
             
                try {
         
     | 
| 
       302 
378 
     | 
    
         
             
                  inboundNetData.flip();
         
     | 
| 
       303 
379 
     | 
    
         | 
| 
         @@ -310,11 +386,12 @@ public class MiniSSL extends RubyObject { 
     | 
|
| 
       310 
386 
     | 
    
         | 
| 
       311 
387 
     | 
    
         
             
                  HandshakeStatus handshakeStatus = engine.getHandshakeStatus();
         
     | 
| 
       312 
388 
     | 
    
         
             
                  boolean done = false;
         
     | 
| 
       313 
     | 
    
         
            -
                  SSLEngineResult res = null;
         
     | 
| 
       314 
389 
     | 
    
         
             
                  while (!done) {
         
     | 
| 
      
 390 
     | 
    
         
            +
                    SSLEngineResult res;
         
     | 
| 
       315 
391 
     | 
    
         
             
                    switch (handshakeStatus) {
         
     | 
| 
       316 
392 
     | 
    
         
             
                      case NEED_WRAP:
         
     | 
| 
       317 
393 
     | 
    
         
             
                        res = doOp(SSLOperation.WRAP, inboundAppData, outboundNetData);
         
     | 
| 
      
 394 
     | 
    
         
            +
                        handshakeStatus = res.getHandshakeStatus();
         
     | 
| 
       318 
395 
     | 
    
         
             
                        break;
         
     | 
| 
       319 
396 
     | 
    
         
             
                      case NEED_UNWRAP:
         
     | 
| 
       320 
397 
     | 
    
         
             
                        res = doOp(SSLOperation.UNWRAP, inboundNetData, inboundAppData);
         
     | 
| 
         @@ -322,13 +399,18 @@ public class MiniSSL extends RubyObject { 
     | 
|
| 
       322 
399 
     | 
    
         
             
                          // need more data before we can shake more hands
         
     | 
| 
       323 
400 
     | 
    
         
             
                          done = true;
         
     | 
| 
       324 
401 
     | 
    
         
             
                        }
         
     | 
| 
      
 402 
     | 
    
         
            +
                        handshakeStatus = res.getHandshakeStatus();
         
     | 
| 
      
 403 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 404 
     | 
    
         
            +
                      case NEED_TASK:
         
     | 
| 
      
 405 
     | 
    
         
            +
                        Runnable runnable;
         
     | 
| 
      
 406 
     | 
    
         
            +
                        while ((runnable = engine.getDelegatedTask()) != null) {
         
     | 
| 
      
 407 
     | 
    
         
            +
                          runnable.run();
         
     | 
| 
      
 408 
     | 
    
         
            +
                        }
         
     | 
| 
      
 409 
     | 
    
         
            +
                        handshakeStatus = engine.getHandshakeStatus();
         
     | 
| 
       325 
410 
     | 
    
         
             
                        break;
         
     | 
| 
       326 
411 
     | 
    
         
             
                      default:
         
     | 
| 
       327 
412 
     | 
    
         
             
                        done = true;
         
     | 
| 
       328 
413 
     | 
    
         
             
                    }
         
     | 
| 
       329 
     | 
    
         
            -
                    if (!done) {
         
     | 
| 
       330 
     | 
    
         
            -
                      handshakeStatus = res.getHandshakeStatus();
         
     | 
| 
       331 
     | 
    
         
            -
                    }
         
     | 
| 
       332 
414 
     | 
    
         
             
                  }
         
     | 
| 
       333 
415 
     | 
    
         | 
| 
       334 
416 
     | 
    
         
             
                  if (inboundNetData.hasRemaining()) {
         
     | 
| 
         @@ -342,65 +424,54 @@ public class MiniSSL extends RubyObject { 
     | 
|
| 
       342 
424 
     | 
    
         
             
                    return getRuntime().getNil();
         
     | 
| 
       343 
425 
     | 
    
         
             
                  }
         
     | 
| 
       344 
426 
     | 
    
         | 
| 
       345 
     | 
    
         
            -
                  RubyString 
     | 
| 
       346 
     | 
    
         
            -
             
     | 
| 
       347 
     | 
    
         
            -
                   
     | 
| 
       348 
     | 
    
         
            -
                } catch (Exception e) {
         
     | 
| 
       349 
     | 
    
         
            -
                  throw getRuntime().newEOFError(e.getMessage());
         
     | 
| 
      
 427 
     | 
    
         
            +
                  return RubyString.newString(getRuntime(), appDataByteList);
         
     | 
| 
      
 428 
     | 
    
         
            +
                } catch (SSLException e) {
         
     | 
| 
      
 429 
     | 
    
         
            +
                  throw newSSLError(getRuntime(), e);
         
     | 
| 
       350 
430 
     | 
    
         
             
                }
         
     | 
| 
       351 
431 
     | 
    
         
             
              }
         
     | 
| 
       352 
432 
     | 
    
         | 
| 
       353 
433 
     | 
    
         
             
              @JRubyMethod
         
     | 
| 
       354 
434 
     | 
    
         
             
              public IRubyObject write(IRubyObject arg) {
         
     | 
| 
       355 
     | 
    
         
            -
                 
     | 
| 
       356 
     | 
    
         
            -
             
     | 
| 
       357 
     | 
    
         
            -
                  outboundAppData = new MiniSSLBuffer(bls);
         
     | 
| 
      
 435 
     | 
    
         
            +
                byte[] bls = arg.convertToString().getBytes();
         
     | 
| 
      
 436 
     | 
    
         
            +
                outboundAppData = new MiniSSLBuffer(bls);
         
     | 
| 
       358 
437 
     | 
    
         | 
| 
       359 
     | 
    
         
            -
             
     | 
| 
       360 
     | 
    
         
            -
                } catch (Exception e) {
         
     | 
| 
       361 
     | 
    
         
            -
                  e.printStackTrace();
         
     | 
| 
       362 
     | 
    
         
            -
                  throw new RuntimeException(e);
         
     | 
| 
       363 
     | 
    
         
            -
                }
         
     | 
| 
      
 438 
     | 
    
         
            +
                return getRuntime().newFixnum(bls.length);
         
     | 
| 
       364 
439 
     | 
    
         
             
              }
         
     | 
| 
       365 
440 
     | 
    
         | 
| 
       366 
441 
     | 
    
         
             
              @JRubyMethod
         
     | 
| 
       367 
     | 
    
         
            -
              public IRubyObject extract()  
     | 
| 
      
 442 
     | 
    
         
            +
              public IRubyObject extract(ThreadContext context) {
         
     | 
| 
       368 
443 
     | 
    
         
             
                try {
         
     | 
| 
       369 
444 
     | 
    
         
             
                  ByteList dataByteList = outboundNetData.asByteList();
         
     | 
| 
       370 
445 
     | 
    
         
             
                  if (dataByteList != null) {
         
     | 
| 
       371 
     | 
    
         
            -
                    RubyString 
     | 
| 
       372 
     | 
    
         
            -
                    str.setValue(dataByteList);
         
     | 
| 
       373 
     | 
    
         
            -
                    return str;
         
     | 
| 
      
 446 
     | 
    
         
            +
                    return RubyString.newString(context.runtime, dataByteList);
         
     | 
| 
       374 
447 
     | 
    
         
             
                  }
         
     | 
| 
       375 
448 
     | 
    
         | 
| 
       376 
449 
     | 
    
         
             
                  if (!outboundAppData.hasRemaining()) {
         
     | 
| 
       377 
     | 
    
         
            -
                    return  
     | 
| 
      
 450 
     | 
    
         
            +
                    return context.nil;
         
     | 
| 
       378 
451 
     | 
    
         
             
                  }
         
     | 
| 
       379 
452 
     | 
    
         | 
| 
       380 
453 
     | 
    
         
             
                  outboundNetData.clear();
         
     | 
| 
       381 
454 
     | 
    
         
             
                  doOp(SSLOperation.WRAP, outboundAppData, outboundNetData);
         
     | 
| 
       382 
455 
     | 
    
         
             
                  dataByteList = outboundNetData.asByteList();
         
     | 
| 
       383 
456 
     | 
    
         
             
                  if (dataByteList == null) {
         
     | 
| 
       384 
     | 
    
         
            -
                    return  
     | 
| 
      
 457 
     | 
    
         
            +
                    return context.nil;
         
     | 
| 
       385 
458 
     | 
    
         
             
                  }
         
     | 
| 
       386 
459 
     | 
    
         | 
| 
       387 
     | 
    
         
            -
                  RubyString 
     | 
| 
       388 
     | 
    
         
            -
             
     | 
| 
       389 
     | 
    
         
            -
             
     | 
| 
       390 
     | 
    
         
            -
                  return str;
         
     | 
| 
       391 
     | 
    
         
            -
                } catch (Exception e) {
         
     | 
| 
       392 
     | 
    
         
            -
                  e.printStackTrace();
         
     | 
| 
       393 
     | 
    
         
            -
                  throw new RuntimeException(e);
         
     | 
| 
      
 460 
     | 
    
         
            +
                  return RubyString.newString(context.runtime, dataByteList);
         
     | 
| 
      
 461 
     | 
    
         
            +
                } catch (SSLException e) {
         
     | 
| 
      
 462 
     | 
    
         
            +
                  throw newSSLError(getRuntime(), e);
         
     | 
| 
       394 
463 
     | 
    
         
             
                }
         
     | 
| 
       395 
464 
     | 
    
         
             
              }
         
     | 
| 
       396 
465 
     | 
    
         | 
| 
       397 
466 
     | 
    
         
             
              @JRubyMethod
         
     | 
| 
       398 
     | 
    
         
            -
              public IRubyObject peercert() throws CertificateEncodingException {
         
     | 
| 
      
 467 
     | 
    
         
            +
              public IRubyObject peercert(ThreadContext context) throws CertificateEncodingException {
         
     | 
| 
      
 468 
     | 
    
         
            +
                Certificate peerCert;
         
     | 
| 
       399 
469 
     | 
    
         
             
                try {
         
     | 
| 
       400 
     | 
    
         
            -
                   
     | 
| 
       401 
     | 
    
         
            -
                } catch (SSLPeerUnverifiedException  
     | 
| 
       402 
     | 
    
         
            -
                   
     | 
| 
      
 470 
     | 
    
         
            +
                  peerCert = engine.getSession().getPeerCertificates()[0];
         
     | 
| 
      
 471 
     | 
    
         
            +
                } catch (SSLPeerUnverifiedException e) {
         
     | 
| 
      
 472 
     | 
    
         
            +
                  peerCert = lastCheckedCert0; // null if trust check did not happen
         
     | 
| 
       403 
473 
     | 
    
         
             
                }
         
     | 
| 
      
 474 
     | 
    
         
            +
                return peerCert == null ? context.nil : JavaEmbedUtils.javaToRuby(context.runtime, peerCert.getEncoded());
         
     | 
| 
       404 
475 
     | 
    
         
             
              }
         
     | 
| 
       405 
476 
     | 
    
         | 
| 
       406 
477 
     | 
    
         
             
              @JRubyMethod(name = "init?")
         
     | 
| 
         @@ -419,4 +490,19 @@ public class MiniSSL extends RubyObject { 
     | 
|
| 
       419 
490 
     | 
    
         
             
                  return getRuntime().getFalse();
         
     | 
| 
       420 
491 
     | 
    
         
             
                }
         
     | 
| 
       421 
492 
     | 
    
         
             
              }
         
     | 
| 
      
 493 
     | 
    
         
            +
             
     | 
| 
      
 494 
     | 
    
         
            +
              private static RubyClass getSSLError(Ruby runtime) {
         
     | 
| 
      
 495 
     | 
    
         
            +
                return (RubyClass) ((RubyModule) runtime.getModule("Puma").getConstantAt("MiniSSL")).getConstantAt("SSLError");
         
     | 
| 
      
 496 
     | 
    
         
            +
              }
         
     | 
| 
      
 497 
     | 
    
         
            +
             
     | 
| 
      
 498 
     | 
    
         
            +
              private static RaiseException newSSLError(Ruby runtime, SSLException cause) {
         
     | 
| 
      
 499 
     | 
    
         
            +
                return newError(runtime, getSSLError(runtime), cause.toString(), cause);
         
     | 
| 
      
 500 
     | 
    
         
            +
              }
         
     | 
| 
      
 501 
     | 
    
         
            +
             
     | 
| 
      
 502 
     | 
    
         
            +
              private static RaiseException newError(Ruby runtime, RubyClass errorClass, String message, Throwable cause) {
         
     | 
| 
      
 503 
     | 
    
         
            +
                RaiseException ex = new RaiseException(runtime, errorClass, message, true);
         
     | 
| 
      
 504 
     | 
    
         
            +
                ex.initCause(cause);
         
     | 
| 
      
 505 
     | 
    
         
            +
                return ex;
         
     | 
| 
      
 506 
     | 
    
         
            +
              }
         
     | 
| 
      
 507 
     | 
    
         
            +
             
     | 
| 
       422 
508 
     | 
    
         
             
            }
         
     |