Gnome Shell Extension: Send Request with Authorization Bearer Headers

799 views Asked by At

I am trying to build a gnome shell extension (using gjs) that I need to communicate with an external REST API. In order to do so, I need to accompany my requests with the header: Authorization: Bearer <token> and with a Content-Type: application/json.

I have looked all over for questions like this and I did find some similar ones but none of them works. The documentation is not helpful at all, and, if anything, it has only confused me more.

With curl I could send that request as follows:

curl -X GET -H "Authorization: Bearer <token>" -H "Content-Type: application/json" <url>

So far, I have only created extensions that send simple GET requests with no headers. Then I would do the following:

const Soup = imports.gi.Soup;
let soupSyncSession = new Soup.SessionSync();

let message = Soup.Message.new('GET', url);
let responseCode = soupSyncSession.send_message(message);
let res;
if(responseCode == 200) {
    res = JSON.parse(message['response-body'].data);
}

Any idea on how I can add the headers? Any help would be appreciated!

2

There are 2 answers

0
ptomato On BEST ANSWER

message.request_headers is a Soup.MessageHeaders object to which you can append() the authorization and content type headers.

Additionally there is a convenient set_content_type() method for the content type header specifically.

0
geoph9 On

EDIT:

By using @ptomato's answer I ended up using the following code:

function send_request(url, type='GET') {
    let message = Soup.Message.new(type, url);
    message.request_headers.append(
        'Authorization',
        `Bearer ${token}`
    )
    message.request_headers.set_content_type("application/json", null);
    let responseCode = soupSyncSession.send_message(message);
    let out;
    if(responseCode == 200) {
        try {
            out = JSON.parse(message['response-body'].data);
        } catch(error) {
            log(error);
        }
    }
    return out;
}

Initial Comment:

So, I managed to find a workaround but it is not efficient and so I will not mark it as the accepted answer. If anyone knows how to answer my question using Soup, please answer!

My workaround involves using the imports.misc.util file which includes the function spawnCommandLine for executing shell commands. So, I used curl in order to download the json to a file (the path variable below):

Util.spawnCommandLine(`/usr/bin/curl -X ${type} -H "Authorization: Bearer ${token}" -H "Content-Type: application/json" ${url} -o ${path}`);

and then I read the contents by using the following:

let text = GLib.file_get_contents(path)[1];
let json_result = JSON.parse(text);

This is not efficient at all and there should be an easier way around. But, until that is found, I hope this will be able to help someone else.