@@ -31,12 +31,11 @@ type Client struct {
3131func NewClient (useragent string , dnServer string ) * Client {
3232 return & Client {
3333 client : & http.Client {
34- Timeout : 1 * time .Minute ,
34+ Timeout : 2 * time .Minute ,
3535 Transport : & uaTransport {
3636 T : & http.Transport {
37- Proxy : http .ProxyFromEnvironment ,
38- TLSHandshakeTimeout : 10 * time .Second ,
39- ResponseHeaderTimeout : 10 * time .Second ,
37+ Proxy : http .ProxyFromEnvironment ,
38+ TLSHandshakeTimeout : 10 * time .Second ,
4039 DialContext : (& net.Dialer {
4140 Timeout : 10 * time .Second ,
4241 }).DialContext ,
@@ -48,9 +47,8 @@ func NewClient(useragent string, dnServer string) *Client {
4847 Timeout : 15 * time .Minute ,
4948 Transport : & uaTransport {
5049 T : & http.Transport {
51- Proxy : http .ProxyFromEnvironment ,
52- TLSHandshakeTimeout : 10 * time .Second ,
53- ResponseHeaderTimeout : 10 * time .Second ,
50+ Proxy : http .ProxyFromEnvironment ,
51+ TLSHandshakeTimeout : 10 * time .Second ,
5452 DialContext : (& net.Dialer {
5553 Timeout : 10 * time .Second ,
5654 }).DialContext ,
@@ -185,24 +183,24 @@ func (c *Client) CheckForUpdate(ctx context.Context, creds Credentials) (bool, e
185183
186184// LongPollWait sends a signed message to a DNClient API endpoint that will block, returning only
187185// if there is an action the client should take before the timeout (config updates, debug commands)
188- func (c * Client ) LongPollWait (ctx context.Context , creds Credentials , supportedActions []string ) (string , error ) {
186+ func (c * Client ) LongPollWait (ctx context.Context , creds Credentials , supportedActions []string ) (* message. LongPollWaitResponse , error ) {
189187 value , err := json .Marshal (message.LongPollWaitRequest {
190188 SupportedActions : supportedActions ,
191189 })
192190 if err != nil {
193- return "" , fmt .Errorf ("failed to marshal DNClient message: %s" , err )
191+ return nil , fmt .Errorf ("failed to marshal DNClient message: %s" , err )
194192 }
195193
196194 respBody , err := c .postDNClient (ctx , message .LongPollWait , value , creds .HostID , creds .Counter , creds .PrivateKey )
197195 if err != nil {
198- return "" , fmt .Errorf ("failed to post message to dnclient api: %w" , err )
196+ return nil , fmt .Errorf ("failed to post message to dnclient api: %w" , err )
199197 }
200198 result := message.LongPollWaitResponseWrapper {}
201199 err = json .Unmarshal (respBody , & result )
202200 if err != nil {
203- return "" , fmt .Errorf ("failed to interpret API response: %s" , err )
201+ return nil , fmt .Errorf ("failed to interpret API response: %s" , err )
204202 }
205- return result .Data . Action , nil
203+ return & result .Data , nil
206204}
207205
208206// DoUpdate sends a signed message to the DNClient API to fetch the new configuration update. During this call a new
@@ -282,6 +280,19 @@ func (c *Client) DoUpdate(ctx context.Context, creds Credentials) ([]byte, []byt
282280 return result .Config , dhPrivkeyPEM , newCreds , nil
283281}
284282
283+ func (c * Client ) CommandResponse (ctx context.Context , creds Credentials , responseToken string , response any ) error {
284+ value , err := json .Marshal (message.CommandResponseRequest {
285+ ResponseToken : responseToken ,
286+ Response : response ,
287+ })
288+ if err != nil {
289+ return fmt .Errorf ("failed to marshal DNClient message: %s" , err )
290+ }
291+
292+ _ , err = c .postDNClient (ctx , message .CommandResponse , value , creds .HostID , creds .Counter , creds .PrivateKey )
293+ return err
294+ }
295+
285296func (c * Client ) StreamCommandResponse (ctx context.Context , creds Credentials , responseToken string ) (* StreamController , error ) {
286297 value , err := json .Marshal (message.CommandResponseRequest {
287298 ResponseToken : responseToken ,
@@ -313,13 +324,11 @@ func (c *Client) streamingPostDNClient(ctx context.Context, reqType string, valu
313324 sc := & StreamController {w : pw , done : done }
314325
315326 go func () {
316- defer func () {
317- close (done )
318- }()
327+ defer close (done )
319328
320329 resp , err := c .streamingClient .Do (req )
321330 if err != nil {
322- sc .err .Store (fmt .Errorf ("failed to call dnclient endpoint: %s " , err ))
331+ sc .err .Store (fmt .Errorf ("failed to call dnclient endpoint: %w " , err ))
323332 return
324333 }
325334 defer resp .Body .Close ()
@@ -362,7 +371,7 @@ func (c *Client) postDNClient(ctx context.Context, reqType string, value []byte,
362371 }
363372 resp , err := c .client .Do (req )
364373 if err != nil {
365- return nil , fmt .Errorf ("failed to call dnclient endpoint: %s " , err )
374+ return nil , fmt .Errorf ("failed to call dnclient endpoint: %w " , err )
366375 }
367376 defer resp .Body .Close ()
368377
@@ -409,14 +418,18 @@ func (sc *StreamController) Err() error {
409418 return err .(error )
410419}
411420
412- // Write implements the io.Writer interface for StreamController. It writes to the request body. It never returns an
413- // error. If the StreamController has already encountered an error, Write will return immediately without writing.
414- // To check for errors, call Err.
415- func (sc * StreamController ) Write (p []byte ) (n int , err error ) {
421+ // Write implements the io.Writer interface for StreamController. It writes to the request body. If the StreamController
422+ // has already encountered an error, it will be returned and nothing will be written.
423+ func (sc * StreamController ) Write (p []byte ) (int , error ) {
416424 if sc .Err () != nil {
417425 return 0 , sc .Err ()
418426 }
419- return sc .w .Write (p )
427+
428+ n , err := sc .w .Write (p )
429+ if err != nil {
430+ sc .err .Store (err )
431+ }
432+ return n , err
420433}
421434
422435// Close closes the StreamController, signaling that the request body is complete and the response can be read.
0 commit comments