Changeset 7eb42bed950e3f81ef9f0d39432e07c55f12cc22

Show
Ignore:
Timestamp:
08/24/10 21:54:44 (21 months ago)
Author:
Antti-Juhani Kaijanaho <antti-juhani@…>
Children:
7ccc366e52cc1e51e123b39fccaf56267361ca58
Parents:
751fac6b567d675afee10e627efb5cf786ce5c83
git-committer:
Antti-Juhani Kaijanaho <antti-juhani@…> (08/24/10 21:54:44)
Message:

[http::markread] Separate the AJAX interface from the regular POST service

Protocol for AJAX mark-read:

  • URL is /markread/ajax
  • msgid is required
  • format=txt is recommended for future compatibility
  • if mark action desired, POST without the undo field
  • if unmark action desired, POST with undo=yes
  • if just want to query, GET
  • responses are:
    • AJAX YES if the message is now marked read
    • AJAX NO if the message is now not marked read
    • AJAX ERR followed by error code indicates and error:
      • AJAX ERR NOAUTH if connection is not authenticated
      • AJAX ERR NOMSG if the message is not in the database
  • responses are always terminated by CRLF (\r\n)
  • for future compatibility, ignore anything after the first line in the response

Of course, HTTP errors occur when they occur.

Signed-off-by: Antti-Juhani Kaijanaho <antti-juhani@…>

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • http/markread.cc

    r751fac6 r7eb42be  
    2323#include "resource.hh" 
    2424#include "request.hh" 
     25#include "../db/db.hh" 
    2526 
    2627namespace http 
     
    2930        { 
    3031                server::conn_cb cb; 
    31         public: 
     32                class noauth {};        public: 
    3233                markread(server::conn_cb cb) 
    3334                        : cb(cb) 
    3435                        {} 
     36 
     37                bool action(boost::shared_ptr<request> req); 
    3538 
    3639                boost::shared_ptr<response> operator() 
     
    3841        }; 
    3942 
     43        bool markread::action(boost::shared_ptr<request> req) 
     44        { 
     45                enum { QUERY, MARK, UNMARK } action; 
     46                action = req->get_method() == "POST" 
     47                        ? (req->get_form_field("undo") != "yes" 
     48                           ? MARK 
     49                           : UNMARK) 
     50                        : QUERY; 
     51 
     52                db::user::ptr u = req->get_user(); 
     53                if (!u) throw noauth(); 
     54 
     55                std::string msgid = req->get_form_field("msgid"); 
     56 
     57                cb.dbase().lookup_msgid(msgid); 
     58 
     59                switch (action) 
     60                { 
     61                case QUERY: 
     62                        break; 
     63                case MARK: 
     64                        u->mark_read(msgid); 
     65                        break; 
     66                case UNMARK: 
     67                        u->unmark_read(msgid); 
     68                        break; 
     69                } 
     70                return u->has_read(msgid); 
     71        } 
     72 
    4073        boost::shared_ptr<response> markread::operator() 
    4174        (boost::shared_ptr<request> req, response::factory rf) 
    4275        { 
    43                 db::user::ptr u = req->get_user(); 
    44  
    45                 if (!u) 
     76                if (req->get_path() == "/markread") 
    4677                { 
    47                         boost::shared_ptr<resource> r 
    48                                 (new reauthn_resource(cb)); 
    49                         throw resource_exception(r); 
    50                 } 
    51  
    52                 std::string ajax = req->get_form_field("ajax"); 
    53                 bool value = req->get_form_field("undo") != "yes"; 
    54                 std::string msgid = req->get_form_field("msgid"); 
    55                 ::uri redir = req->get_form_field("redir"); 
    56                 redir.replace_query_param("markread","no"); 
    57  
    58                 if (req->get_method() == "POST") 
    59                 { 
    60                         if (value) 
    61                                 u->mark_read(msgid); 
    62                         else 
    63                                 u->unmark_read(msgid); 
    64                 } 
    65                 if (ajax.empty() || ajax == "no") 
    66                 { 
     78                        try 
     79                        { 
     80                                action(req); 
     81                        } 
     82                        catch (noauth) 
     83                        { 
     84                                boost::shared_ptr<resource> r 
     85                                        (new reauthn_resource(cb)); 
     86                                throw resource_exception(r); 
     87                        } 
     88                        catch (db::no_such_article) 
     89                        { 
     90                                ; 
     91                        } 
     92                        ::uri redir = req->get_form_field("redir"); 
     93                        redir.replace_query_param("markread","no"); 
    6794                        boost::shared_ptr<redir_resource> r 
    6895                                (new redir_resource(cb, redir.to_string(), 
    6996                                                    "303 See other")); 
    7097                        throw resource_exception(r); 
    71                 } 
    72                 boost::shared_ptr<response> rv = rf("200 Ok"); 
    73                 std::ostream &os = rv->body("text/plain"); 
    74                 os << "AJAX " 
    75                    << (u->has_read(msgid) ? "YES" : "NO") 
    76                    << "\r\n"; 
    77                 return rv; 
     98                } 
     99                if (req->get_path() == "/markread/ajax") 
     100                { 
     101                        std::string res; 
     102                        try 
     103                        { 
     104                                res = action(req) ? "YES" : "NO"; 
     105                        } 
     106                        catch (noauth) 
     107                        { 
     108                                res = "ERR NOAUTH"; 
     109                        } 
     110                        catch (db::no_such_article) 
     111                        { 
     112                                res = "ERR NOMSG"; 
     113                        } 
     114                        boost::shared_ptr<response> rv = rf("200 Ok"); 
     115                        std::ostream &os = rv->body("text/plain"); 
     116                        os << "AJAX " << res << "\r\n"; 
     117                        return rv; 
     118                } 
     119                else 
     120                { 
     121                        boost::shared_ptr<error_resource> r 
     122                                (new error_resource(cb, "404 Not found")); 
     123                        throw resource_exception(r); 
     124                } 
    78125        } 
    79126} 
     127 
    80128namespace 
    81129{ 
     
    85133                factory() { 
    86134                        server::register_http_resource("/markread", this); 
     135                        server::register_http_resource("/markread/ajax", this); 
    87136                } 
    88137                boost::shared_ptr<http::resource> operator()