| OLD | NEW |
| 1 // Copyright 2015 The LUCI Authors. All rights reserved. | 1 // Copyright 2015 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
| 4 | 4 |
| 5 package streamclient | 5 package streamclient |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "encoding/json" | 8 "encoding/json" |
| 9 "fmt" | 9 "fmt" |
| 10 "io" | 10 "io" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 // <protocol>:<protocol-specific-spec> | 36 // <protocol>:<protocol-specific-spec> |
| 37 // | 37 // |
| 38 // Supported protocols and their respective specs are: | 38 // Supported protocols and their respective specs are: |
| 39 // - unix:/path/to/socket describes a stream server listening on UNIX domain | 39 // - unix:/path/to/socket describes a stream server listening on UNIX domain |
| 40 // socket at "/path/to/socket". | 40 // socket at "/path/to/socket". |
| 41 // | 41 // |
| 42 // Windows-only: | 42 // Windows-only: |
| 43 // - net.pipe:name describes a stream server listening on Windows named pipe | 43 // - net.pipe:name describes a stream server listening on Windows named pipe |
| 44 // "\\.\pipe\name". | 44 // "\\.\pipe\name". |
| 45 func New(path string) (Client, error) { | 45 func New(path string) (Client, error) { |
| 46 » return DefaultRegistry.NewClient(path) | 46 » return defaultRegistry.NewClient(path) |
| 47 } | 47 } |
| 48 | 48 |
| 49 func (c *clientImpl) NewStream(f streamproto.Flags) (Stream, error) { | 49 func (c *clientImpl) NewStream(f streamproto.Flags) (Stream, error) { |
| 50 p := f.Properties() | 50 p := f.Properties() |
| 51 if err := p.Validate(); err != nil { | 51 if err := p.Validate(); err != nil { |
| 52 return nil, fmt.Errorf("streamclient: invalid stream properties:
%s", err) | 52 return nil, fmt.Errorf("streamclient: invalid stream properties:
%s", err) |
| 53 } | 53 } |
| 54 | 54 |
| 55 client, err := c.factory() | 55 client, err := c.factory() |
| 56 if err != nil { | 56 if err != nil { |
| 57 return nil, err | 57 return nil, err |
| 58 } | 58 } |
| 59 ownsClient := true | 59 ownsClient := true |
| 60 defer func() { | 60 defer func() { |
| 61 // If we haven't written out the connection, close. | 61 // If we haven't written out the connection, close. |
| 62 if ownsClient { | 62 if ownsClient { |
| 63 client.Close() | 63 client.Close() |
| 64 } | 64 } |
| 65 }() | 65 }() |
| 66 | 66 |
| 67 data, err := json.Marshal(f) | 67 data, err := json.Marshal(f) |
| 68 if err != nil { | 68 if err != nil { |
| 69 return nil, fmt.Errorf("failed to marshal properties JSON: %s",
err) | 69 return nil, fmt.Errorf("failed to marshal properties JSON: %s",
err) |
| 70 } | 70 } |
| 71 | 71 |
| 72 // Perform the handshake: magic + size(data) + data. | 72 // Perform the handshake: magic + size(data) + data. |
| 73 s := &streamImpl{ | 73 s := &streamImpl{ |
| 74 Properties: p, | |
| 75 WriteCloser: client, | 74 WriteCloser: client, |
| 75 props: p, |
| 76 } | 76 } |
| 77 if _, err := s.writeRaw(streamproto.ProtocolFrameHeaderMagic); err != ni
l { | 77 if _, err := s.writeRaw(streamproto.ProtocolFrameHeaderMagic); err != ni
l { |
| 78 return nil, fmt.Errorf("failed to write magic number: %s", err) | 78 return nil, fmt.Errorf("failed to write magic number: %s", err) |
| 79 } | 79 } |
| 80 if err := s.writeRecord(data); err != nil { | 80 if err := s.writeRecord(data); err != nil { |
| 81 return nil, fmt.Errorf("failed to write properties: %s", err) | 81 return nil, fmt.Errorf("failed to write properties: %s", err) |
| 82 } | 82 } |
| 83 | 83 |
| 84 ownsClient = false // Passing ownership to caller. | 84 ownsClient = false // Passing ownership to caller. |
| 85 return s, nil | 85 return s, nil |
| 86 } | 86 } |
| OLD | NEW |