| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package main |
| 6 |
| 7 import ( |
| 8 "fmt" |
| 9 "log" |
| 10 "net" |
| 11 "net/http" |
| 12 "time" |
| 13 |
| 14 "golang.org/x/mobile/app" |
| 15 |
| 16 "mojo/public/go/application" |
| 17 "mojo/public/go/bindings" |
| 18 "mojo/public/go/system" |
| 19 |
| 20 "mojo/services/network/public/interfaces/net_address" |
| 21 "mojo/services/network/public/interfaces/network_service" |
| 22 "mojo/services/network/public/interfaces/tcp_bound_socket" |
| 23 "mojo/services/network/public/interfaces/tcp_connected_socket" |
| 24 "mojo/services/network/public/interfaces/tcp_server_socket" |
| 25 ) |
| 26 |
| 27 //#include "mojo/public/c/system/types.h" |
| 28 import "C" |
| 29 |
| 30 type MojoConnection struct { |
| 31 sendStream system.ProducerHandle |
| 32 receiveStream system.ConsumerHandle |
| 33 socket system.MessagePipeHandle |
| 34 localAddr net.Addr |
| 35 remoteAddr net.Addr |
| 36 } |
| 37 |
| 38 // Implements net.Conn. |
| 39 func (c *MojoConnection) Read(b []byte) (int, error) { |
| 40 l := len(b) |
| 41 r, read := c.receiveStream.BeginReadData(l, system.MOJO_READ_DATA_FLAG_N
ONE) |
| 42 if r != system.MOJO_RESULT_OK { |
| 43 return 0, fmt.Errorf("can't read %v bytes: %v", l, r) |
| 44 } |
| 45 if l > len(read) { |
| 46 l = len(read) |
| 47 } |
| 48 copy(b, read[:l]) |
| 49 if r := c.receiveStream.EndReadData(l); r != system.MOJO_RESULT_OK { |
| 50 return 0, fmt.Errorf("can't read %v bytes: %v", l, r) |
| 51 } |
| 52 return l, nil |
| 53 } |
| 54 |
| 55 // Implements net.Conn. |
| 56 func (c *MojoConnection) Write(b []byte) (int, error) { |
| 57 l := len(b) |
| 58 r, buf := c.sendStream.BeginWriteData(l, system.MOJO_WRITE_DATA_FLAG_ALL
_OR_NONE) |
| 59 if r != system.MOJO_RESULT_OK { |
| 60 return 0, fmt.Errorf("can't write %v bytes: %v", l, r) |
| 61 } |
| 62 copy(buf, b) |
| 63 if r := c.sendStream.EndWriteData(l); r != system.MOJO_RESULT_OK { |
| 64 return 0, fmt.Errorf("can't write %v bytes: %v", l, r) |
| 65 } |
| 66 return l, nil |
| 67 } |
| 68 |
| 69 // Implements net.Conn. |
| 70 func (c *MojoConnection) Close() error { |
| 71 c.sendStream.Close() |
| 72 c.receiveStream.Close() |
| 73 c.socket.Close() |
| 74 return nil |
| 75 } |
| 76 |
| 77 // Implements net.Conn. |
| 78 func (c *MojoConnection) LocalAddr() net.Addr { |
| 79 return c.localAddr |
| 80 } |
| 81 |
| 82 // Implements net.Conn. |
| 83 func (c *MojoConnection) RemoteAddr() net.Addr { |
| 84 return c.remoteAddr |
| 85 } |
| 86 |
| 87 // Implements net.Conn. |
| 88 func (c *MojoConnection) SetDeadline(t time.Time) error { |
| 89 if err := c.SetReadDeadline(t); err != nil { |
| 90 return err |
| 91 } |
| 92 return c.SetWriteDeadline(t) |
| 93 } |
| 94 |
| 95 // Implements net.Conn. |
| 96 func (c *MojoConnection) SetReadDeadline(t time.Time) error { |
| 97 // Do nothing. |
| 98 return nil |
| 99 } |
| 100 |
| 101 // Implements net.Conn. |
| 102 func (c *MojoConnection) SetWriteDeadline(t time.Time) error { |
| 103 // Do nothing. |
| 104 return nil |
| 105 } |
| 106 |
| 107 type MojoListener struct { |
| 108 serverSocket *tcp_server_socket.TcpServerSocketProxy |
| 109 } |
| 110 |
| 111 // Implements net.Listener. |
| 112 func (l *MojoListener) Accept() (net.Conn, error) { |
| 113 r, sendProducer, sendConsumer := system.GetCore().CreateDataPipe(nil) |
| 114 if r != system.MOJO_RESULT_OK { |
| 115 panic(fmt.Sprintf("can't create data pipe: %v", r)) |
| 116 } |
| 117 r, receiveProducer, receiveConsumer := system.GetCore().CreateDataPipe(n
il) |
| 118 if r != system.MOJO_RESULT_OK { |
| 119 panic(fmt.Sprintf("can't create data pipe: %v", r)) |
| 120 } |
| 121 request, pointer := tcp_connected_socket.CreateMessagePipeForTcpConnecte
dSocket() |
| 122 networkError, remoteAddress, err := l.serverSocket.Accept(sendConsumer,
receiveProducer, request) |
| 123 if err != nil { |
| 124 return nil, err |
| 125 } |
| 126 if networkError.Code != 0 { |
| 127 return nil, fmt.Errorf("%s", *networkError.Description) |
| 128 } |
| 129 |
| 130 var addr net.Addr |
| 131 if remoteAddress.Ipv4 != nil { |
| 132 addr = &net.TCPAddr{ |
| 133 IP: remoteAddress.Ipv4.Addr[:4], |
| 134 Port: int(remoteAddress.Ipv4.Port), |
| 135 } |
| 136 } else { |
| 137 addr = &net.TCPAddr{ |
| 138 IP: remoteAddress.Ipv6.Addr[:16], |
| 139 Port: int(remoteAddress.Ipv6.Port), |
| 140 } |
| 141 } |
| 142 return &MojoConnection{ |
| 143 sendProducer, |
| 144 receiveConsumer, |
| 145 pointer.PassMessagePipe(), |
| 146 l.Addr(), |
| 147 addr, |
| 148 }, nil |
| 149 } |
| 150 |
| 151 // Implements net.Listener. |
| 152 func (l *MojoListener) Close() error { |
| 153 l.serverSocket.Close_proxy() |
| 154 return nil |
| 155 } |
| 156 |
| 157 // Implements net.Listener. |
| 158 func (l *MojoListener) Addr() net.Addr { |
| 159 return &net.TCPAddr{ |
| 160 IP: []byte{127, 0, 0, 1}, |
| 161 Port: 8080, |
| 162 } |
| 163 } |
| 164 |
| 165 type HttpServerDelegate struct { |
| 166 networkService *network_service.NetworkServiceProxy |
| 167 tcpBoundSocket *tcp_bound_socket.TcpBoundSocketProxy |
| 168 serverSocket *tcp_server_socket.TcpServerSocketProxy |
| 169 } |
| 170 |
| 171 func (d *HttpServerDelegate) InitTCPBoundSocket() error { |
| 172 addr := &net_address.NetAddress{ |
| 173 net_address.NetAddressFamily_IpV4, |
| 174 &net_address.NetAddressIPv4{ |
| 175 8080, |
| 176 [4]uint8{127, 0, 0, 1}, |
| 177 }, |
| 178 nil, |
| 179 } |
| 180 request, pointer := tcp_bound_socket.CreateMessagePipeForTcpBoundSocket(
) |
| 181 networkError, _, err := d.networkService.CreateTcpBoundSocket(addr, requ
est) |
| 182 if err != nil { |
| 183 return err |
| 184 } |
| 185 if networkError.Code != 0 { |
| 186 return fmt.Errorf("%s", *networkError.Description) |
| 187 } |
| 188 d.tcpBoundSocket = tcp_bound_socket.NewTcpBoundSocketProxy(pointer, bind
ings.GetAsyncWaiter()) |
| 189 return nil |
| 190 } |
| 191 |
| 192 func (d *HttpServerDelegate) InitServerSocket() error { |
| 193 request, pointer := tcp_server_socket.CreateMessagePipeForTcpServerSocke
t() |
| 194 networkError, err := d.tcpBoundSocket.StartListening(request) |
| 195 if err != nil { |
| 196 return err |
| 197 } |
| 198 if networkError.Code != 0 { |
| 199 return fmt.Errorf("%s", *networkError.Description) |
| 200 } |
| 201 d.serverSocket = tcp_server_socket.NewTcpServerSocketProxy(pointer, bind
ings.GetAsyncWaiter()) |
| 202 return nil |
| 203 } |
| 204 |
| 205 func (d *HttpServerDelegate) Initialize(ctx application.Context) { |
| 206 request, pointer := network_service.CreateMessagePipeForNetworkService() |
| 207 ctx.ConnectToApplication("mojo:network_service").ConnectToService(&reque
st) |
| 208 d.networkService = network_service.NewNetworkServiceProxy(pointer, bindi
ngs.GetAsyncWaiter()) |
| 209 |
| 210 if err := d.InitTCPBoundSocket(); err != nil { |
| 211 log.Printf("can't create TCP socket: %v\n", err) |
| 212 return |
| 213 } |
| 214 if err := d.InitServerSocket(); err != nil { |
| 215 log.Printf("can't create server socket: %v\n", err) |
| 216 return |
| 217 } |
| 218 |
| 219 http.HandleFunc("/go", func(w http.ResponseWriter, r *http.Request) { |
| 220 fmt.Fprintf(w, "Hello, Go http server!") |
| 221 }) |
| 222 l := &MojoListener{d.serverSocket} |
| 223 if err := http.Serve(l, nil); err != nil { |
| 224 log.Printf("can't serve request: %v\n", err) |
| 225 return |
| 226 } |
| 227 } |
| 228 |
| 229 func (d *HttpServerDelegate) AcceptConnection(c *application.Connection) { |
| 230 c.Close() |
| 231 } |
| 232 |
| 233 func (d *HttpServerDelegate) Quit() { |
| 234 d.networkService.Close_proxy() |
| 235 d.tcpBoundSocket.Close_proxy() |
| 236 d.serverSocket.Close_proxy() |
| 237 } |
| 238 |
| 239 //export MojoMain |
| 240 func MojoMain(handle C.MojoHandle) C.MojoResult { |
| 241 application.Run(&HttpServerDelegate{}, system.MojoHandle(handle)) |
| 242 return C.MOJO_RESULT_OK |
| 243 } |
| 244 |
| 245 func main() { |
| 246 app.Run(app.Callbacks{}) |
| 247 } |
| OLD | NEW |