Ah, I solved my little puzzle if anyone is interested:

I needed to get a JSON dump of my dictionary before encoding.

        data = json.dumps(flow).encode('utf-8')
        request = urllib.request.Request(url, data)
        response = urllib.request.urlopen(request)

So what is the difference, well *json.dumps* output is encoded as a single
element. Using *urllib.parse.urlencode* encodes each element separately.

*urllib.parse.urlencode -->*
b'dpid=69133577248&cookie=1&cookie_mask=1&table_id=0&idle_timeout=0&hard_timeout=0&priority=0&flags=1&match=%7B%27in_port%27%3A+7%7D&actions=%5B%5D'

*json.dumps             --> *b'{"dpid": 69133577248, "cookie": 1,
"cookie_mask": 1, "table_id": 0, "idle_timeout": 0, "hard_timeout": 0,
"priority": 0, "flags": 1, "match": {"in_port": 7}, "actions": []}'

Another way I found works is to convert the dictionary to a string
(actually that appears to be what json.dumps does)

*urllib.parse.urlencode --> *
b'dpid=69133577248&cookie=1&cookie_mask=1&table_id=0&idle_timeout=0&hard_timeout=0&priority=0&flags=1&match=%7B%27in_port%27%3A+8%7D&actions=%5B%5D'

*json.dumps             -->* b'{"dpid": 69133577248, "cookie": 1,
"cookie_mask": 1, "table_id": 0, "idle_timeout": 0, "hard_timeout": 0,
"priority": 0, "flags": 1, "match": {"in_port": 8}, "actions": []}'

*string                 -->* b"{'dpid': 69133577248, 'cookie': 1,
'cookie_mask': 1, 'table_id': 0, 'idle_timeout': 0, 'hard_timeout': 0,
'priority': 0, 'flags': 1, 'match': {'in_port': 8}, 'actions': []}"

as this code option works too.

        data = str(flow).encode('utf-8')
        request = urllib.request.Request(url, data)
        response = urllib.request.urlopen(request)

regards,

Diarmuid
--

*Irish by birth, located in Uganda but Munster by the grace of God.*




On Sat, 16 Mar 2019 at 13:45, Diarmuid O Briain <diarm...@obriain.com>
wrote:

> Hi,
>
> I have been trying to use the 'ryu.app.ofctl_rest
> <https://ryu.readthedocs.io/en/latest/app/ofctl_rest.html#id10>'
> interface. Using cURL is fine. Take the following drop rule for example,
> works fine.
>
> curl -X POST -d "{'dpid': '69133577248', 'cookie': 1, 'cookie_mask': 1,
> 'table_id': 0, 'idle_timeout': 0, 'hard_timeout': 0, 'priority': 0,
> 'flags': 1, 'match': {'in_port': 3}, 'actions': []}"
> http://198.8.8.235:8080/stats/flowentry/add
>
> Now taking the exact same dictionary and URL I try to apply the rul via
> python3 urllib. Here is the code snippet. I print out the encoded data to
> check it. It fails with a 400 error:
>
> *flow = {'dpid': '69133577248', 'cookie': 1, 'cookie_mask': 1, 'table_id':
> 0, 'idle_timeout': 0, 'hard_timeout': 0, 'priority': 0, 'flags': 1,
> 'match': {'in_port': 3}, 'actions': []}*
> *url = http://198.8.8.235:8080/stats/flowentry/add
> <http://198.8.8.235:8080/stats/flowentry/add>*
>
> *data = urllib.parse.urlencode(flow).encode('utf-8')*
> *print('ENCODED DATA -->', data)*
> *with urllib.request.urlopen(url, data) as response:*
> *    print (response.read().decode('utf-8'))*
>
> ENCODED DATA -->
> b'dpid=69133577248&cookie=1&cookie_mask=1&table_id=0&idle_timeout=0&hard_timeout=0&priority=0&flags=1&match=%7B%27in_port%27%3A+3%7D&actions=%5B%5D'
> Traceback (most recent call last):
>   File "/usr/local/bin/diddly", line 177, in <module>
>     main()
>   File "/usr/local/bin/diddly", line 125, in main
>     diddly_switch.diddly_switch(diddly_args)
>   File "/usr/local/lib/python3.6/dist-packages/diddly.py", line 4481, in
> diddly_switch
>     diddlySdn._add_flow(self, dict3_['switch_number'], {'match': {
> "in_port": p}, 'actions': []})  #>>> [diddly_switch] >>>
>   File "/usr/local/lib/python3.6/dist-packages/diddly.py", line 6834, in
> _add_flow
>     with urllib.request.urlopen(url_, data) as response:
>   File "/usr/lib/python3.6/urllib/request.py", line 223, in urlopen
>     return opener.open(url, data, timeout)
>   File "/usr/lib/python3.6/urllib/request.py", line 532, in open
>     response = meth(req, response)
>   File "/usr/lib/python3.6/urllib/request.py", line 642, in http_response
>     'http', request, response, code, msg, hdrs)
>   File "/usr/lib/python3.6/urllib/request.py", line 570, in error
>     return self._call_chain(*args)
>   File "/usr/lib/python3.6/urllib/request.py", line 504, in _call_chain
>     result = func(*args)
>   File "/usr/lib/python3.6/urllib/request.py", line 650, in
> http_error_default
>     raise HTTPError(req.full_url, code, msg, hdrs, fp)
> urllib.error.HTTPError: HTTP Error 400: Bad Request
>
> --
>
> *Irish by birth, located in Uganda but Munster by the grace of God.*
>
>
>
_______________________________________________
Ryu-devel mailing list
Ryu-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to