summaryrefslogtreecommitdiff
path: root/ext/openssl/lib/net/https.rb
blob: 0f5cb13407ab316a5cc330d9f840945a72a379dc (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
174
175
176
177
178
179
=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.

== class Net::HTTP

== Example

Simple HTTP client is here:

    require 'net/http'
    host, port, path = "localhost", 80, "/"
    if %r!http://(.*?)(?::(\d+))?(/.*)! =~ ARGV[0]
      host   = $1
      port   = $2.to_i if $2
      path   = $3
    end
    h = Net::HTTP.new(host, port)
    h.get2(path){ |resp| print resp.body }

It can be replaced by follow one:

    require 'net/https'
    host, port, path = "localhost", 80, "/"
    if %r!(https?)://(.*?)(?::(\d+))?(/.*)! =~ ARGV[0]
      scheme = $1
      host   = $2
      port   = $3 ? $3.to_i : ((scheme == "http") ? 80 : 443)
      path   = $4
    end
    h = Net::HTTP.new(host, port)
    h.use_ssl = true if scheme == "https" # enable SSL/TLS
    h.get2(path){ |resp| print resp.body }

=== Instance Methods

: use_ssl
    returns ture 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|))
    Sets an OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object.
    (This method is appeared in Michal Rokos's OpenSSL extention.)

: key_file=((|path|))
    Sets a private key file to use in PEM format.

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

: cert_file=((|path|))
    Sets pathname of a X.509 certification file in PEM format.

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

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

: 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=((|proc|))
    Sets the verify callback for the server certification verification.

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

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

=end

require 'net/protocols'
require 'net/http'

module Net
  class HTTP
    class Conn < HTTPRequest
      REQUEST_HAS_BODY=false
      RESPONSE_HAS_BODY=false
      METHOD="connect"

      def initialize
        super nil, nil
      end

      def exec( sock, addr, port, ver )
        @socket = sock
        request(addr, port, ver)
      end

      def request( addr, port, ver )
        @socket.writeline sprintf('CONNECT %s:%s HTTP/%s', addr, port, ver)
        @socket.writeline ''
      end
    end

    module ProxyMod
      def edit_path( path )
        if use_ssl
          'https://' + addr_port + path
        else
          'http://' + addr_port + path
        end
      end
    end

    def self.socket_type
      SSLIO
    end

    attr_accessor :use_ssl
    attr_writer :key, :cert
    attr_writer :ca_file, :ca_path
    attr_writer :verify_mode, :verify_callback, :verify_depth
    attr_writer :cert_store, :timeout
    attr_reader :peer_cert

    alias :default_initialize :initialize

    def initialize(*args)
      default_initialize(*args)
      @key = @cert = @ca_file = @ca_path = @verify_mode =
      @verify_callback = @verify_depth = @timeout = @cert_store = nil
    end

    def on_connect
      if use_ssl
        if proxy?
          Conn.new.exec(@socket, @address, @port, "1.0")
          resp = HTTPResponse.read_new(@socket)
          if resp.code != '200'
            raise resp.message
          end
        end
        @socket.key             = @key       if @key
        @socket.cert            = @cert      if @cert
        @socket.ca_file         = @ca_file
        @socket.ca_path         = @ca_path
        @socket.verify_mode     = @verify_mode
        @socket.verify_callback = @verify_callback
        @socket.verify_depth    = @verify_depth
        @socket.timeout         = @timeout
        @socket.cert_store      = @cert_store
        @socket.ssl_connect
        @peer_cert = @socket.peer_cert
      end
    end

  end
end