Class: EventMachine::Wssh::TLS

Inherits:
Object
  • Object
show all
Extended by:
Service
Defined in:
lib/em/wssh/tls.rb,
lib/em/wssh/uri.rb

Constant Summary collapse

Chunk =
0x10000

Instance Attribute Summary

Attributes included from Service

#options

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Service

daemonize!, daemonize?, getopt, go!, helptions, homebase, loop!, mkdir, path, pid

Constructor Details

#initialize(client) ⇒ TLS

Returns a new instance of TLS.



28
29
30
31
32
# File 'lib/em/wssh/tls.rb', line 28

def initialize client
  @count=self.class.count
  @client=client
  @t1=Thread.new{cloop!}
end

Class Method Details

.countObject



23
24
25
26
# File 'lib/em/wssh/tls.rb', line 23

def self.count
  @n||=0
  @n+=1
end

.run!(host) ⇒ Object



13
14
15
16
17
18
19
20
21
# File 'lib/em/wssh/tls.rb', line 13

def self.run! host
  @@host=host
  s=TCPServer.new '127.0.0.1', 0
  log "WSTunnel on #{s.addr} -> #{host}"
  Thread.new do
    new s.accept while true
  end
  s.addr[1]
end

.wrap(uri) ⇒ Object



8
9
10
11
12
13
14
15
16
17
# File 'lib/em/wssh/uri.rb', line 8

def self.wrap uri
  return uri unless Gem.win_platform?
  z = URI uri
  return uri unless %w(wss https).include? z.scheme
  require_relative 'tls'
  z.port=TLS.run! z.host
  z.scheme='ws'
  z.host='localhost'
  z.to_s
end

Instance Method Details

#cloopObject



79
80
81
82
83
84
85
86
87
88
89
# File 'lib/em/wssh/tls.rb', line 79

def cloop
  h=headerz! headerz
  if h.length<1
    @client.write "HTTP/1.0 500 Invalid request\r\n"
    return
  end
  @headers=h
  @server=connect!
  @t2=Thread.new{sloop!}
  @server.write @client.readpartial Chunk until @client.eof
end

#cloop!Object



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/em/wssh/tls.rb', line 38

def cloop!
  begin
    log "Connected from", @client.peeraddr
    cloop
  rescue=>e
    log "Client error", e
  ensure
    log "Client disconnected"
    @client.close
    @t2.exit if @t2
  end
end

#connect!Object



69
70
71
72
73
74
75
76
77
# File 'lib/em/wssh/tls.rb', line 69

def connect!
  srv=Socket.tcp @@host, 443
  ctx=OpenSSL::SSL::SSLContext.new
  ctx.set_params verify_mode: OpenSSL::SSL::VERIFY_PEER
  srv=OpenSSL::SSL::SSLSocket.new srv, ctx
  srv.hostname=@@host if srv.respond_to? :hostname=
  srv.connect
  srv
end

#headerzObject



51
52
53
54
55
56
57
58
59
# File 'lib/em/wssh/tls.rb', line 51

def headerz
  r=[]
  until @client.eof
    s=@client.gets.strip
    break if 0==s.length
    r << s
  end
  r
end

#headerz!(headers) ⇒ Object



61
62
63
64
65
66
67
# File 'lib/em/wssh/tls.rb', line 61

def headerz! headers
  return headers if headers.length<1
  verb=headers.shift
  [verb]+
  %w(Host Origin).map{|h| "#{h}: #{@@host}"}+
  headers.reject{|h| /^(?:host|origin):/i.match h}
end

#log(*msg) ⇒ Object



34
35
36
# File 'lib/em/wssh/tls.rb', line 34

def log *msg
  self.class.log "<&#{@count}>", *msg
end

#sloopObject



104
105
106
107
108
# File 'lib/em/wssh/tls.rb', line 104

def sloop
  @server.write @headers*"\r\n"+"\r\n"*2
  @headers=nil
  @client.write @server.readpartial Chunk until @server.eof
end

#sloop!Object



91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/em/wssh/tls.rb', line 91

def sloop!
  begin
    log "Connected to server;", "Verify=#{@server.verify_result}"
    sloop
  rescue=>e
    log "Server error", e
  ensure
    log "Server disconnected"
    @server.close
    @t1.exit
  end
end