/** * Copyright (C) 2009 Gabriel Falcão * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ using Soup; using GLib; using Gee; namespace Ainur { /* Auxiliary functions */ private HashTable map_to_table (HashMap hs) { HashTable ret = new HashTable(GLib.str_hash, GLib.str_equal); foreach (string key in hs.get_keys()) { ret.replace("%s".printf(key), "%s".printf(hs.get(key))); } return ret; } public string form_encode_hashmap (HashMap hmap) { if (hmap.size == 0) return ""; HashTable dlist = map_to_table (hmap); return "%s".printf(form_encode_hash (dlist)); } public HashMap new_hash () { HashMap hs = new HashMap (GLib.str_hash, GLib.str_equal); return hs; } public string hash_to_json (HashMap dict) { StringBuilder bstring = new StringBuilder(); var keys = dict.get_keys(); foreach (string key in keys) { string value = dict.get (key); bstring.append_printf("\"%s\": \"%s\"", (string)key, (string)value); bstring.append_unichar(','); } bstring.erase (bstring.len - 1, 1); return "{%s}".printf(bstring.str); } /* data types */ public class Methods { public static const Quark GET = Quark.from_string("GET"); public static const Quark POST = Quark.from_string("POST"); public static const Quark PUT = Quark.from_string("PUT"); public static const Quark DELETE = Quark.from_string("DELETE"); public static const Quark HEAD = Quark.from_string("HEAD"); } /* classes */ public class HttpResponse : GLib.Object { public uint status_code; public string body; private Message message; public HttpResponse (Message msg, uint status) { this.status_code = status; this.body = msg.response_body.data; this.message = msg; } } public class HttpBackend : GLib.Object { private const string ENCODE = "application/x-www-form-urlencoded"; private HashMap headers; private HashMap body; public bool is_connected; public string login_url; public string logout_url; public string username; public string password; public HashMap other_credentials; public SessionSync session; public HttpBackend (string username, string password, bool connect_now=false, HashMap? other_credentials=null) { this.username = username; this.password = password; this.is_connected = false; this.other_credentials = other_credentials == null ? new_hash() : other_credentials; this.session = new SessionSync(); this.headers = new_hash(); this.body = new_hash(); if (connect_now == true) this.connect(); } ~HttpBackend () { this.disconnect(); } private void handle_cookies (Message msg) { string cookies; cookies = msg.response_headers.get("set-cookie"); if (cookies != null) this.headers.set("Cookie", cookies); } private void debug (HttpResponse response) { if (response.status_code >= 300) { try { if (response.body != null) FileUtils.set_contents("debug.html", response.body); else GLib.warning ("Response body null. Is server up?"); } catch (FileError err) { GLib.critical ("ERROR ON DEBUGGING: %s", err.message); } } } public HttpResponse request (string url, Quark method, HashMap? body=null, HashMap? headers=null) { uint status; string bodydata; HttpResponse response; HashTable table; URI uri; Message msg = new Message(method.to_string(), url); uri = msg.get_uri().copy(); if (body == null) body = this.body; switch (method.to_string ()) { case "GET": case "HEAD": table = map_to_table (body); uri.set_query_from_form (table); msg.set_uri(uri); bodydata = ""; break; default: bodydata = form_encode_hashmap(body); break; } msg.set_request(this.ENCODE, MemoryUse.COPY, bodydata, bodydata.length); status = this.session.send_message(msg); this.handle_cookies (msg); response = new HttpResponse (msg, status); this.debug(response); return response; } public bool connect () { HttpResponse r = this.request ("http://localhost:8000/", Methods.POST); if (r.status_code == 200) { this.is_connected = true; } return true; } public bool disconnect () { return true; } } }