root/http/markread.cc

Revision 7eb42bed950e3f81ef9f0d39432e07c55f12cc22, 5.0 KB (checked in by Antti-Juhani Kaijanaho <antti-juhani@…>, 21 months ago)

[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@…>

  • Property mode set to 100644
Line 
1/*  This file is part of Alue, the multiprotocol Internet discussion daemon
2
3    Copyright © 2010 Antti-Juhani Kaijanaho
4
5    Alue is free software: you can redistribute it and/or modify it
6    under the terms of the GNU General Public License as published by
7    the Free Software Foundation, either version 3 of the License, or
8    (at your option) any later version.
9
10    Alue is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with Alue.  If not, see <http://www.gnu.org/licenses/>.
17
18 */
19
20#include "error_resource.hh"
21#include "reauthn_resource.hh"
22#include "redir_resource.hh"
23#include "resource.hh"
24#include "request.hh"
25#include "../db/db.hh"
26
27namespace http
28{
29        class markread : public resource
30        {
31                server::conn_cb cb;
32                class noauth {};        public:
33                markread(server::conn_cb cb)
34                        : cb(cb)
35                        {}
36
37                bool action(boost::shared_ptr<request> req);
38
39                boost::shared_ptr<response> operator()
40                (boost::shared_ptr<request> req, response::factory);
41        };
42
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
73        boost::shared_ptr<response> markread::operator()
74        (boost::shared_ptr<request> req, response::factory rf)
75        {
76                if (req->get_path() == "/markread")
77                {
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");
94                        boost::shared_ptr<redir_resource> r
95                                (new redir_resource(cb, redir.to_string(),
96                                                    "303 See other"));
97                        throw resource_exception(r);
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                }
125        }
126}
127
128namespace
129{
130        class factory : public server::http_resource_factory
131        {
132        public:
133                factory() {
134                        server::register_http_resource("/markread", this);
135                        server::register_http_resource("/markread/ajax", this);
136                }
137                boost::shared_ptr<http::resource> operator()
138                (server::conn_cb cb, std::string) {
139                        boost::shared_ptr<http::resource> rv
140                                (new http::markread(cb));
141                        return rv;
142                }
143        };
144        factory f;
145}
Note: See TracBrowser for help on using the browser.