summaryrefslogtreecommitdiff
path: root/lib/net/https.rb
blob: e296dbbed44fe2c53a684faec61485f88c0ddb3c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
=begin

= $RCSfile$ -- SSL/TLS enhancement for Net::HTTP.

== Info
  'OpenSSL for Ruby 2' project
  Copyright (C) 2001 GOTOU Yuuzou <gotoyuzo@notwork.org>
  All rights reserved.

== Licence
  This program is licenced under the same licence as Ruby.
  (See the file 'LICENCE'.)

== Requirements
  This program requires Net 1.2.0 or higher version.
  You can get it from RAA or Ruby's CVS repository.

== Version
  $Id$
  
  2001-11-06: Contiributed to Ruby/OpenSSL project.
  2004-03-06: Some code is merged in to net/http.

== Example

Here is a simple HTTP client:

    require 'net/http'
    require 'uri'

    uri = URI.parse(ARGV[0] || 'http://localhost/')
    http = Net::HTTP.new(uri.host, uri.port)
    http.start {
      http.request_get(uri.path) {|res|
        print res.body
      }
    }

It can be replaced by the following code:

    require 'net/https'
    require 'uri'

    uri = URI.parse(ARGV[0] || 'https://localhost/')
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true if uri.scheme == "https"  # enable SSL/TLS
    http.start {
      http.request_get(uri.path) {|res|
        print res.body
      }
    }

== class Net::HTTP

=== Instance Methods

: use_ssl?
    returns true if use SSL/TLS with HTTP.

: use_ssl=((|true_or_false|))
    sets use_ssl.

: peer_cert
    return the X.509 certificates the server presented.

: key, key=((|key|))
    Sets an OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object.
    (This method is appeared in Michal Rokos's OpenSSL extention.)

: cert, cert=((|cert|))
    Sets an OpenSSL::X509::Certificate object as client certificate
    (This method is appeared in Michal Rokos's OpenSSL extention).

: ca_file, ca_file=((|path|))
    Sets path of a CA certification file in PEM format.
    The file can contrain several CA certificats.

: ca_path, ca_path=((|path|))
    Sets path of a CA certification directory containing certifications
    in PEM format.

: verify_mode, verify_mode=((|mode|))
    Sets the flags for server the certification verification at
    begining of SSL/TLS session.
    OpenSSL::SSL::VERIFY_NONE or OpenSSL::SSL::VERIFY_PEER is acceptable.

: verify_callback, verify_callback=((|proc|))
    Sets the verify callback for the server certification verification.

: verify_depth, verify_depth=((|num|))
    Sets the maximum depth for the certificate chain verification.

: cert_store, cert_store=((|store|))
    Sets the X509::Store to verify peer certificate.

: ssl_timeout, ssl_timeout=((|sec|))
    Sets the SSL timeout seconds.

=end

require 'net/http'
require 'openssl'

module Net

  class HTTP
    remove_method :use_ssl?
    def use_ssl?
      @use_ssl
    end

    # For backward compatibility.
    alias use_ssl use_ssl?

    # Turn on/off SSL.
    # This flag must be set before starting session.
    # If you change use_ssl value after session started,
    # a Net::HTTP object raises IOError.
    def use_ssl=(flag)
      flag = (flag ? true : false)
      raise IOError, "use_ssl value changed, but session already started" \
          if started? and @use_ssl != flag
      if flag and not @ssl_context
        @ssl_context = OpenSSL::SSL::SSLContext.new
      end
      @use_ssl = flag
    end

    def self.ssl_context_accessor(name)
      module_eval(<<-End, __FILE__, __LINE__ + 1)
        def #{name}
          return nil unless @ssl_context
          @ssl_context.#{name}
        end

        def #{name}=(val)
          @ssl_context ||= OpenSSL::SSL::SSLContext.new
          @ssl_context.#{name} = val
        end
      End
    end

    ssl_context_accessor :key
    ssl_context_accessor :cert
    ssl_context_accessor :ca_file
    ssl_context_accessor :ca_path
    ssl_context_accessor :verify_mode
    ssl_context_accessor :verify_callback
    ssl_context_accessor :verify_depth
    ssl_context_accessor :cert_store

    def ssl_timeout
      return nil unless @ssl_context
      @ssl_context.timeout
    end

    def ssl_timeout=(sec)
      raise ArgumentError, 'Net::HTTP#ssl_timeout= called but use_ssl=false' \
          unless use_ssl?
      @ssl_context ||= OpenSSL::SSL::SSLContext.new
      @ssl_context.timeout = sec
    end

    # For backward compatibility
    alias timeout= ssl_timeout=

    def peer_cert
      return nil if not use_ssl? or not @socket
      @socket.io.peer_cert
    end
  end

end