2 * Forum view (threaded/flat)
4 * Copyright (c) 1996-2018 by the citadel.org team
6 * This program is open source software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 3.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
27 // Commands we need to send to Citadel Server before we begin rendering forum view.
28 // These are common to flat and threaded views.
30 void setup_for_forum_view(struct ctdlsession *c)
33 ctdl_printf(c, "MSGP text/html|text/plain"); // Declare the MIME types we know how to render
34 ctdl_readline(c, buf, sizeof(buf)); // Ignore the response
35 ctdl_printf(c, "MSGP dont_decode"); // Tell the server we will decode base64/etc client-side
36 ctdl_readline(c, buf, sizeof(buf)); // Ignore the response
40 // Fetch a single message and return it in JSON format for client-side rendering
42 void json_render_one_message(struct http_transaction *h, struct ctdlsession *c, long msgnum)
44 StrBuf *raw_msg = NULL;
45 StrBuf *sanitized_msg = NULL;
47 char content_transfer_encoding[1024] = { 0 };
48 char content_type[1024] = { 0 };
49 char author[128] = { 0 };
50 char datetime[128] = { 0 };
52 setup_for_forum_view(c);
54 ctdl_printf(c, "MSG4 %ld", msgnum);
55 ctdl_readline(c, buf, sizeof(buf));
61 JsonValue *j = NewJsonObject(HKEY("message"));
63 while ((ctdl_readline(c, buf, sizeof(buf)) >= 0) && (strcmp(buf, "text")) && (strcmp(buf, "000"))) {
64 // citadel header parsing here
65 if (!strncasecmp(buf, "from=", 5)) {
66 JsonObjectAppend(j, NewJsonPlainString(HKEY("from"), &buf[5], -1));
68 if (!strncasecmp(buf, "rfca=", 5)) {
69 JsonObjectAppend(j, NewJsonPlainString(HKEY("from"), &buf[5], -1));
71 if (!strncasecmp(buf, "time=", 5)) {
75 localtime_r(&tt, &tm);
76 strftime(datetime, sizeof datetime, "%c", &tm);
77 JsonObjectAppend(j, NewJsonPlainString(HKEY("time"), datetime, -1));
81 if (!strcmp(buf, "text")) {
82 while ((ctdl_readline(c, buf, sizeof(buf)) >= 0) && (strcmp(buf, "")) && (strcmp(buf, "000"))) {
83 // rfc822 header parsing here
84 if (!strncasecmp(buf, "Content-transfer-encoding:", 26)) {
85 strcpy(content_transfer_encoding, &buf[26]);
86 striplt(content_transfer_encoding);
88 if (!strncasecmp(buf, "Content-type:", 13)) {
89 strcpy(content_type, &buf[13]);
90 striplt(content_type);
93 raw_msg = ctdl_readtextmsg(c);
100 // These are the encodings we know how to handle. Decode in-place.
102 if (!strcasecmp(content_transfer_encoding, "base64")) {
103 StrBufDecodeBase64(raw_msg);
105 if (!strcasecmp(content_transfer_encoding, "quoted-printable")) {
106 StrBufDecodeQP(raw_msg);
108 // At this point, raw_msg contains the decoded message.
109 // Now run through the renderers we have available.
111 if (!strncasecmp(content_type, "text/html", 9)) {
112 sanitized_msg = html2html("UTF-8", 0, c->room, msgnum, raw_msg);
113 } else if (!strncasecmp(content_type, "text/plain", 10)) {
114 sanitized_msg = text2html("UTF-8", 0, c->room, msgnum, raw_msg);
115 } else if (!strncasecmp(content_type, "text/x-citadel-variformat", 25)) {
116 sanitized_msg = variformat2html(raw_msg);
118 sanitized_msg = NewStrBufPlain(HKEY("<i>No renderer for this content type</i><br>"));
120 FreeStrBuf(&raw_msg);
122 // If sanitized_msg is not NULL, we have rendered the message and can output it.
125 JsonObjectAppend(j, NewJsonString(HKEY("text"), sanitized_msg, NEWJSONSTRING_SMASHBUF));
129 StrBuf *sj = NewStrBuf();
130 SerializeJson(sj, j, 1); // '1' == free the source object
132 add_response_header(h, strdup("Content-type"), strdup("application/json"));
133 h->response_code = 200;
134 h->response_string = strdup("OK");
135 h->response_body_length = StrLength(sj);
136 h->response_body = SmashStrBuf(&sj);