Strange return on an AXIS camera API call

Hi all,

I've been working on making API calls to an AXIS camera and have found that simpler calls seem to be working fine but more complex calls have been giving me strange responses.

For example, calls to move my camera have no issues. However, calls that involve sending body information are returning strange responses.

The current call I am working with is:

import httplib
import urllib2
import urllib
import json

url = "http://***/axis-cgi/streamprofile.cgi"

data = {
  "apiVersion": "1.0",
  "context": "my context",
  "method": "list",
  "params": {
    "streamProfileName": []
  }
}

method = "POST"


password = urllib2.HTTPPasswordMgrWithDefaultRealm()
password.add_password(None, url, "***", "***")
handler = urllib2.HTTPDigestAuthHandler(password)

opener = urllib2.build_opener(handler)

request = urllib2.Request(url, data=data)

# headers
request.add_header("Content-Type","application/json")
request.add_header("Accept","*/*")
request.add_header("Accept-Encoding","gzip, deflate, br, compress, identity, *")
request.add_header("Connection","keep-alive")

# overload the get method 
request.get_method = lambda: method

connection = opener.open(request)
print connection.read()

The return from the camera with this call is:
image

Note: This return is only possible by the 'Accept-Encoding' header because without it you perpetually get JSON formatting errors.

This general call is absolutely possible as it works wonderfully in Postman but there seems to be a disconnect between what I'm attempting to do in Ignition and what I can do with Postman for example.

Has anyone ran into this particular problem before? If so, do you know how to fix it? (Or a different way to extract the information from the response in Ignition, any ideas, etc)

Thank you,

Cam

You should prefer system.net.httpClient over any Jython stdlib builtins; it's going to be more performant and interact with the rest of Ignition better.

That said, your accept encoding speciifies a bunch of possible compression types. Are you sure that's not just the raw value of that encoding process being dumped out as a string?
What does the Postman request that works look like?

Hi Paul,

Thank you for your fast response!

I originally wanted to use the system.net.httpClient function, however, the authentication type to work with AXIS cameras is digest authentication and the system function cannot accept that type.

It does accept several types but I'm fairly certain the encoding type is 'br'.
I'm not sure if it is just the raw value or not unfortunately. I've been playing around with it a lot the last little bit and cant seem to get it to output anything other than that. And the length of the response never changes regardless of additions that appear in the Postman response.

The Postman request and response looks like this:


What are the header values in the response?

This may also be of interest:
image

More or less the same request but different response lengths

You're getting a binary response that needs to be decompressed using the "brotli" compression scheme.

Try Accept-Encoding: identity

This should get you plaintext.

Noted. I will go look into it and learn about it.

Also, I'm assuming you wanted me to add it to the header.

The only issue is that if I don't have 'br' in the 'Accept-Encoding' I get JSON formatting errors.
image

By this do you mean a JSON response from the server you aren't expecting, indicating some kind of internal error/code?

Yeah, it does not like it if 'br' is not indicated. The data in the original post is straight off their website (so I don't know why its giving formatting errors here) so I could mitigate unexpected errors till I had this working.

https://www.axis.com/vapix-library/subjects/t10175981/section/t10149933/display

You are constructing a urllib2.Request with a dictionary object. There's nothing in the docs that suggest it will turn this into a JSON string for you.

So maybe you are just sending invalid JSON. And you'd probably get the same error message if you could manage to decode the compressed binary.

In this version yes. I was orignally using the " urllib.urlencode" function the dictionary object right before passing it into the Request. It did not seem to make any difference so I excluded it.

That would be really funny if it was the same error, just encoded.

I'll go look for different ways to pass it in :slight_smile:

that's not what you want.

Try system.util.jsonEncode.

It does give a new encoded response which is nice! However, I'm thinking its still not quite right as the lengths of this response and the Postman response are different
(116 is the content/response length of the Postman header)

Well ditch the br now and try just identity. You are unlikely to successfully decode a compressed response.

Yes! You were correct!

Thank you @Kevin.Herron and @PGriffith for your help! I really do appreciate it! :slight_smile:

1 Like