shamblett / coap

A Coap package for dart
Other
16 stars 13 forks source link

Method not allowed with post request #103

Closed pfalentin closed 2 years ago

pfalentin commented 2 years ago

Hello,

I’m trying to connect to my Ikea lights with Flutter. My issue is that when I try to do a post request the response is Code: 4.05 Method Not Allowed which is weird because a post request should be allowed.

When I do the exact same request from command line there is no issue (with the SECURITY_CODE and PRE_SHARED_KEY replaced of course) :

Request: coap-client-openssl -m post -u "Client_identity" -k "SECURITY_CODE" -e '{"9090":"IDENTITY"}' "coaps://192.168.1.41:5684/15011/9063" Response: {"9091":"PRE_SHARED_KEY","9029":"1.19.0026"}

Could you have a look to my code and tell me what’s wrong? I would be very grateful if you could help me to get this working, I really want to play with this!

If you are curious the request I try to do is the one described here: https://github.com/home-assistant-libs/pytradfri/issues/90

Here is a minimum example followed by my pubspec

import 'package:flutter/material.dart';
import 'package:coap/coap.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Test lights',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: const TestWidget());
  }
}

class TestWidget extends StatefulWidget {
  const TestWidget({
    Key? key,
  }) : super(key: key);

  @override
  State<TestWidget> createState() => _TestWidgetState();
}

class _TestWidgetState extends State<TestWidget> {
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: TextButton(
          child: const Text('Test button'),
          onPressed: () async {
            final conf = DtlsConfig();

            var credentials = PskCredentials(
              identity: 'Client_identity',
              preSharedKey: 'SECURITY_CODE',
            );

            PskCredentials pskCredentialsCallback(final String indentity) => credentials;

            final uri = Uri(
              scheme: 'coaps',
              host: '192.168.1.41',
              port: conf.defaultSecurePort,
            );

            final client = CoapClient(
              uri,
              conf,
              pskCredentialsCallback: pskCredentialsCallback,
            );

            try {
              client.events.on<Object>().listen(print);

              final response = await client.post(
                '15011/9063',
                payload: '{"9090":"IDENTITY"}',
              );
            } on Exception catch (e) {
              print('CoAP encountered an exception: $e');
            }

            client.close();
          },
        ),
      ),
    );
  }
}

class DtlsConfig extends DefaultCoapConfig {
  @override
  final dtlsBackend = DtlsBackend.TinyDtls;
}
name: auto_lights
description: A new Flutter project.

publish_to: 'none' # Remove this line if you wish to publish to pub.dev

version: 1.0.0+1

environment:
  sdk: ">=2.17.1 <3.0.0"

dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^1.0.2
  coap: ^4.1.0
  dart_tinydtls_libs: ^0.1.1
  dart_tinydtls: ^1.0.1

dev_dependencies:
  flutter_test:
    sdk: flutter

  flutter_lints: ^2.0.0
flutter:
  uses-material-design: true
shamblett commented 2 years ago

@JosefWN and @JKRhb does this ring any bells with you guys?

pfalentin commented 2 years ago

If it’s any help here is the full response log:

I/flutter ( 9077): CoapSendingRequestEvent:
I/flutter ( 9077): <<< Request Message >>>
I/flutter ( 9077): Type: 0, Code: POST, Id: 55881, Token: '7c6755137c833276',
I/flutter ( 9077): Options: [
I/flutter ( 9077):   Uri Port: 5684,
I/flutter ( 9077):   Uri Paths: 15011/9063,
I/flutter ( 9077):   Content-Type: text/plain,
I/flutter ( 9077):   Max Age: 60,
I/flutter ( 9077):   Accept: text/plain,
I/flutter ( 9077):   Size 1: 0,
I/flutter ( 9077):   Size 2: 0,
I/flutter ( 9077): ],
I/flutter ( 9077): Payload: {"9090":"IDENTITY"}
I/flutter ( 9077): CoapDataReceivedEvent:
I/flutter ( 9077): [104, 133, 218, 73, 124, 103, 85, 19, 124, 131, 50, 118, 255, 77, 101, 116, 104, 111, 100, 32, 78, 111, 116, 32, 65, 108, 108, 111, 119, 101, 100] from InternetAddress('192.168.1.41', IPv4)
I/flutter ( 9077): CoapReceivingResponseEvent:
I/flutter ( 9077): <<< Response Message >>>
I/flutter ( 9077): Type: 2, Code: 4.05 Method Not Allowed, Id: 55881, Token: '7c6755137c833276',
I/flutter ( 9077): Options: [
I/flutter ( 9077):   Content-Type: application/octet-stream,
I/flutter ( 9077):   Max Age: 60,
I/flutter ( 9077):   Size 1: 0,
I/flutter ( 9077):   Size 2: 0,
I/flutter ( 9077): ],
I/flutter ( 9077): Payload: Method Not Allowed
I/flutter ( 9077): CoapAcknowledgedEvent:
I/flutter ( 9077): <<< Request Message >>>
I/flutter ( 9077): Type: 0, Code: POST, Id: 55881, Token: '7c6755137c833276',
I/flutter ( 9077): Options: [
I/flutter ( 9077):   Uri Port: 5684,
I/flutter ( 9077):   Uri Paths: 15011/9063,
I/flutter ( 9077):   Content-Type: text/plain,
I/flutter ( 9077):   Max Age: 60,
I/flutter ( 9077):   Accept: text/plain,
I/flutter ( 9077):   Size 1: 0,
I/flutter ( 9077):   Size 2: 0,
I/flutter ( 9077): ],
I/flutter ( 9077): Payload: {"9090":"IDENTITY"}
I/flutter ( 9077): CoapCompletedEvent:
I/flutter ( 9077): Exchange for request 55881 (token '7c6755137c833276')
I/flutter ( 9077): CoapRespondEvent:
I/flutter ( 9077): <<< Response Message >>>
I/flutter ( 9077): Type: 2, Code: 4.05 Method Not Allowed, Id: 55881, Token: '7c6755137c833276',
I/flutter ( 9077): Options: [
I/flutter ( 9077):   Content-Type: application/octet-stream,
I/flutter ( 9077):   Max Age: 60,
I/flutter ( 9077):   Size 1: 0,
I/flutter ( 9077):   Size 2: 0,
I/flutter ( 9077): ],
I/flutter ( 9077): Payload: Method Not Allowed
JosefWN commented 2 years ago

I think I might have found the bug, can you try to construct the request without using client.post? Something like:

final request = CoapRequest.newPost()
  ..uriPath = '15011/9063'
  ..payloadString = '{"9090":"IDENTITY"}';
final response = await client.send(request);
pfalentin commented 2 years ago

You found it! It works with the request constructed manually without using client.post. Thanks a lot it was quick!

Here is the log of the working request:

I/flutter (10534): CoapSendingRequestEvent:
I/flutter (10534): <<< Request Message >>>
I/flutter (10534): Type: 0, Code: POST, Id: 1201, Token: 'c6f644bb119e84d7',
I/flutter (10534): Options: [
I/flutter (10534):   Uri Port: 5684,
I/flutter (10534):   Uri Paths: 15011/9063,
I/flutter (10534):   Content-Type: text/plain,
I/flutter (10534):   Max Age: 60,
I/flutter (10534):   Accept: text/plain,
I/flutter (10534):   Size 1: 0,
I/flutter (10534):   Size 2: 0,
I/flutter (10534): ],
I/flutter (10534): Payload: {"9090":"IDENTITY190"}
I/flutter (10534): CoapDataReceivedEvent:
I/flutter (10534): [104, 65, 4, 177, 198, 246, 68, 187, 17, 158, 132, 215, 255, 123, 34, 57, 48, 57, 49, 34, 58, 34, 76, 111, 122, 114, 109, 99, 107, 109, 80, 72, 85, 79, 110, 68, 97, 117, 34, 44, 34, 57, 48, 50, 57, 34, 58, 34, 49, 46, 49, 57, 46, 48, 48, 50, 54, 34, 125] from InternetAddress('192.168.1.41', IPv4)
I/flutter (10534): CoapReceivingResponseEvent:
I/flutter (10534): <<< Response Message >>>
I/flutter (10534): Type: 2, Code: 2.01 Created, Id: 1201, Token: 'c6f644bb119e84d7',
I/flutter (10534): Options: [
I/flutter (10534):   Content-Type: application/octet-stream,
I/flutter (10534):   Max Age: 60,
I/flutter (10534):   Size 1: 0,
I/flutter (10534):   Size 2: 0,
I/flutter (10534): ],
I/flutter (10534): Payload: {"9091":"LozrmckmPHUOnDau","9029":"1.19.0026"}
I/flutter (10534): CoapAcknowledgedEvent:
I/flutter (10534): <<< Request Message >>>
I/flutter (10534): Type: 0, Code: POST, Id: 1201, Token: 'c6f644bb119e84d7',
I/flutter (10534): Options: [
I/flutter (10534):   Uri Port: 5684,
I/flutter (10534):   Uri Paths: 15011/9063,
I/flutter (10534):   Content-Type: text/plain,
I/flutter (10534):   Max Age: 60,
I/flutter (10534):   Accept: text/plain,
I/flutter (10534):   Size 1: 0,
I/flutter (10534):   Size 2: 0,
I/flutter (10534): ],
I/flutter (10534): Payload: {"9090":"IDENTITY190"}
I/flutter (10534): CoapCompletedEvent:
I/flutter (10534): Exchange for request 1201 (token 'c6f644bb119e84d7')
I/flutter (10534): CoapRespondEvent:
I/flutter (10534): <<< Response Message >>>
I/flutter (10534): Type: 2, Code: 2.01 Created, Id: 1201, Token: 'c6f644bb119e84d7',
I/flutter (10534): Options: [
I/flutter (10534):   Content-Type: application/octet-stream,
I/flutter (10534):   Max Age: 60,
I/flutter (10534):   Size 1: 0,
I/flutter (10534):   Size 2: 0,
I/flutter (10534): ],
I/flutter (10534): Payload: {"9091":"LozrmckmPHUOnDau","9029":"1.19.0026"}
JosefWN commented 2 years ago

This should now be fixed on master, please let me know if you still have issues!

shamblett commented 2 years ago

Believe this has been addressed. Package re released at version 5.0.0.