Category Archives: Open source

Allowing digest auth with CORS on Chrome and LIGHTTPD

LigHTTPD is a very popular web server to use nowadays and it powers a lot of devices. I’ve mainly seen it in rasberry pi’s and other smaller servers but it’s powerful nonetheless.

Today I did some fiddling around with CORS to get data passed through another domain than the site was residing on. It all seemed fairly easy as it’s just a simple header to add to your server response, as described on enable cors

Turned out it wasn’t that easy. The server with the APIs are armed with Digest authentication for authorization and chrome has made it a must to send HTTP OPTIONS to check some parameters from the server.

Chrome needs in order to authenticate:

  • Access-Control-Allow-Origin: *
  • Access-Control-Expose-Headers: WWW-Authenticate
  • Access-Control-Allow-Headers: Authorization
  • Access-Control-Allow-Methods: POST, GET, OPTIONS

That’s easy enough with LigHTTPDs extra environment header in the server configuration:

setenv.add-response-header = (
"Access-Control-Allow-Origin" => "*",
"Access-Control-Expose-Headers" => "WWW-Authenticate",
"Access-Control-Allow-Headers" => "Authorization",
"Access-Control-Allow-Methods" => "POST, GET, OPTIONS"

)

But, that isn’t enough. If you have set up a rule in your server configuration that you require to authenticate, Chrome will fail when it gets 401 on it’s OPTION request and will not continue. In order to get that worked around I had to do some modifications in mod_auth to make sure it doesn’t authenticate on HTTP OPTIONS. It was an easy hack to implement once you figured out the functions and where to look.

All the needed code was:

//Hack to make OPTIONS pass through AUTH filter with just sending the headers needed by CORS on Chrome
const char *htm = get_http_method_name(con->request.http_method);
if(strcmp(htm,"OPTIONS") == 0){
con->http_status = 200;
con->mode = DIRECT;
return HANDLER_FINISHED;
}

I’ve attached the modified .c file for some convenience. I used the latest (to date) official release 1.4.39. Hope this helps anyone out there who needs to use digest over CORS with LigHTTPD.

mod_auth

/Marcus

Running Python on Axis devices

Axis’ platform for running applications on the camera itself is really great. For you who haven’t seen ACAP share I really suggest you click yourself over there to see what it’s all about.

As mentioned in other posts, Axis have created an embedded platform where you can install applications on the different devices to add features to the edge. This can be analytics that is looking for something unique like a people counter or advanced cross line-type detection. It can also be for simpler tasks like sending a message using a service platform similar to the pushbullet integration that I published here some time ago.

The only downside is that to develop these applications you have to know C which can be tough for the average script kiddie who just wants to perform something small. So, in order to solve some of the more simple scripting that you can be interested in doing. On ACAP Share there’s a PHP application that allows someone to write a PHP script that can be executed on a camera. This is a great application if you’re looking to use smaller APIs for your task.

PHP is extremely popular and allows you to do a number of great things. Python is another extremely popular language. Soo.. Enough said, below is the compiled ACAP and how to build it if you have the environment.

Build script:

buildpython

The python binary itself:

Python_2.7.1_1_0_mipsisa32r2el

Recommended FW: 5.80+. The reason is that the package is pretty big and will need some space. We’ve seen problems with 5.60 and 5.70 firmware that doesn’t allow the package to go through due to it’s size. After 5.80 it seems fine though. (Yes, python is a big library)

It’s build to run on the MIPS architecture, meaning it will work on ARTPEC-4 and ARTPEC-5 devices but that’s it. Python version is 2.7.1 with some limitation built to it (see buildpython.sh)

When you upload the binary there’s an attached python script in that folder. Edit that and make sure you run a continuous loop on it to perform whatever you want to achieve.

ACAP is actually so powerful that you can create your own applications that are essentially script that runs off another application. To start a python script from the command line, use:

LD_LIBRARY_PATH=/usr/local/packages/python_2_7_1/lib /usr/local/packages/python_2_7_1/bin/python /path/to/script.py

This can be called from system(); as well in your C application.

Hopefully this can save some time for people who’re interested in developing in python on Axis devices.

/Marcus

Axis Parameter Class for Python

A couple of days ago I was in need of making some scripts that removed duplicate parameter groups on a couple of Axis devices. For those of you who don’t know, Axis creates Digital Surveillance Cameras with IP technology, which in practice means that It’s surveillance cameras running Linux.

All Axis devices offers an open API for developers who want to develop  that uses Axis devices. The most frequent API used is the Parameter API, that allows to change basic settings, create motion detection windows, events with triggers and so on. And this is the API that I had to implement a class for.

The class is written in Python and is pretty much an object oriented interface. Example

param1 = AxisParameter("Motion.M0.Left","1120")
#param1.name = Motion.M0.Left, param1.value = "1120"
param2 = AxisParameter("Properties.Resolution")
#param2.name = Properties.Resolution, param2.value = None

Here we have two parameters that can be accessed from the class. param1 contains a parameter with an assigned value to it, this can be used to modify an already existing parameter. param2 contains a parameter name, but have no idea of the value of it, better used to receive the parameters

To use the class, you must first import the data from it.

from AxisParameterClass import * #import both the working class and the information class

paramclass = AxisParameterClass("some.ip","username","password","vapixversion")

All arguments are optional and can be set later with the following functions

  • setIP
  • setCredentials
  • setVapixVersion

Axis currently have two API’s for handling vapix parameters. The only big difference is the URL, but still. The class will automatically try to determine the vapix version if not set before.

Receive parameters

To get parameters from a device, simply create a parameter that you’re interesting, both groups and subgroups are fine to use:

paramclass.getParameters([AxisParameter('Motion'), AxisParameter('Properties'), AxisParameter('NonExistent')])

The class will return a list of all parameters that matches the search. Is a parameter not found, the Parameter will be returned with the value None. All parameters that are found have their value as a string.

Remove parameters

Just as add. Create your list, and send to

paramclass.removeParameters([AxisParameter('Motion')])

Parameters returned have a status parameter that refers if the parameter was removed or not:

AxisParameter.status = "OK" #removed
AxisParameter.status = "Error" #not removed.

Update Parameters (Implementation still needs some work)

To update, pass the list into

paramclass.updateParameters([AxisParameter('Motion.M0.Left','1123')] )

If all works, the parameters returned will contain the same result as what you passed in.

 

Download

It can all be downloaded from github, licensed under MIT, so feel free to do whatever you like with it 🙂
https://github.com/marcusfollrud/AxisParameterPython 

Adding bit.ly support to mu-feeder

My twitterfeed haven’t been working for  a while now. The last update was 2009-11-25, so I went out googling on “twitterfeed replacement” and found mu-feeder. A small python script that publish your blog entrys (or whatever RSS feed that you might have) to twitter. It’s very sweet but i missed the bit.ly support.

But, since it’s open source, there’s nothing that you can’t do about it :). I went out hunting and i found python-bitly. A library for the bit.ly API!

After some tweaking in the bitly file I got it working.

Step 1: Download mu-feeder and unpack it.
Step 2: Download the modified bitly file and put it in mu-feeder/shorteners (diff here)
Step 3:  Edit your mu-feeder settings.py. set URL_SHORTENING_SERVICE to “bitly” and URL_SHORTENER_LOGIN plus URL_SHORTENER_PASSWORD to your bit.ly username and the API key that you have on bit.ly.

That’s it. Now it should work just fine :).

Have a nice weekend.
Marcus

Publish to WordPress plasmoid v0.02

Igårkväll satt jag och skissade lite på hur framtida versioner av wordpress-plasmoiden skulle kunna se ut.

Jag använde mig utav QT Designer för att göra själva moc-upen och det blev såhär:

Wordpress Plasmoid

Wordpress Plasmoid

Plasmoiden blir lite större, men känns mer komplett, med möjligheterna att:

  • Lägga till taggar
  • Markera flera kategorier
  • Editera i redan skapade bloggposter
  • Förhandsvisa material

Jag tror det kan bli riktigt bra!
Funderar även på hur mycket jobb det skulle vara att lägga in bilder med drag-n-dropfunktionalitet. WordPress libbet som är integrerat stöder det, men det är nog lite jobb att ställa in storlek med en extra dialogruta. Vi får helt enkelt se.

Publish to WordPress Plasmoid

Vill du blogga på din wordpressblogg utan att aktivt gå in via din webbläsare?

Isåfall har jag en lösning att erbjuda dig 🙂

Publish to WordPress Plasmoid är en plasmoid till KDE4 som enkelt låter dig skriva ett blogginlägg utan att gå in direkt på själva bloggsidan.

Den är väldigt enkelt skriven och är baserad på pyKDE och wordpresslib.

Just nu erbjuder den inget annat än det mest simpla. Att skapa ett inlägg med enbart en titel och text.

Funktioner som skulle kunna integreras är taggar,kategorier och inmatning av bilder. Men, det har jag inte gjort i denna release.

Vill du testa den?
Ladda ner här

Kolla källkoden på github (GPL licensierad):
http://github.com/marcusfollrud/Publish-to-Wordpress-plasmoid/tree/master

Kontaka mig gärna ifall du skulle vilja hjälpa till med något!
mail: marcus.follrud<canelbull>gmail.com