html render replaced by json render in the C server. next needs to be the json-to...
authorArt Cancro <ajc@citadel.org>
Sun, 18 Feb 2018 00:18:15 +0000 (19:18 -0500)
committerArt Cancro <ajc@citadel.org>
Sun, 18 Feb 2018 00:18:15 +0000 (19:18 -0500)
libcitadel/lib/json.c
libcitadel/lib/libcitadel.h
libcitadel/lib/wildfire.c
webcit-ng/forum_view.c
webcit-ng/room_functions.c
webcit-ng/static/js/views.js
webcit-ng/webcit.h

index b166745..7f61181 100644 (file)
@@ -121,7 +121,7 @@ JsonValue *NewJsonBigNumber(const char *Key, long keylen, double Number)
 }
 
 
-JsonValue *NewJsonString(const char *Key, long keylen, StrBuf *CopyMe)
+JsonValue *NewJsonString(const char *Key, long keylen, StrBuf *CopyMe, int copy_or_smash)
 {
        JsonValue *Ret;
 
@@ -132,7 +132,18 @@ JsonValue *NewJsonString(const char *Key, long keylen, StrBuf *CopyMe)
        {
                Ret->Name = NewStrBufPlain(Key, keylen);
        }
-       Ret->Value = NewStrBufDup(CopyMe);
+       if (copy_or_smash == NEWJSONSTRING_COPYBUF)
+       {
+               Ret->Value = NewStrBufDup(CopyMe);
+       }
+       else if (copy_or_smash == NEWJSONSTRING_SMASHBUF)
+       {
+               Ret->Value = CopyMe;
+       }
+       else
+       {
+               Ret->Value = NULL;              // error condition
+       }
        return Ret;
 }
 
index a6d66c5..3e86d07 100644 (file)
@@ -28,7 +28,7 @@
 #include <sys/types.h>
 #include <netinet/in.h>
 
-#define LIBCITADEL_VERSION_NUMBER      917
+#define LIBCITADEL_VERSION_NUMBER      918
 
 /*
  * Here's a bunch of stupid magic to make the MIME parser portable.
@@ -613,7 +613,11 @@ JsonValue *NewJsonNumber(const char *Key, long keylen, long Number);
 
 JsonValue *NewJsonBigNumber(const char *Key, long keylen, double Number);
 
-JsonValue *NewJsonString(const char *Key, long keylen, StrBuf *CopyMe);
+enum {
+       NEWJSONSTRING_COPYBUF,          // make a copy of the StrBuf, source is left alone
+       NEWJSONSTRING_SMASHBUF          // smash the source StrBuf, the json object now owns that memory
+};
+JsonValue *NewJsonString(const char *Key, long keylen, StrBuf *CopyMe, int copy_or_smash);
 
 JsonValue *NewJsonPlainString(const char *Key, long keylen, const char *CopyMe, long len);
 
index 1958f59..c1fd2e3 100644 (file)
@@ -58,8 +58,7 @@ JsonValue *WildFireMessage(const char *Filename, long fnlen,
        JsonArrayAppend(Ret, WFInfo(Filename, fnlen,
                                    LineNo, Type));
 
-       JsonArrayAppend(Ret, 
-                       NewJsonString(NULL, 0, Msg));
+       JsonArrayAppend(Ret, NewJsonString(NULL, 0, Msg, NEWJSONSTRING_COPYBUF));
        return Ret;
 }
 
@@ -275,28 +274,16 @@ JsonValue *WildFireException(const char *Filename, long FileLen,
        JsonValue *Val;
        Val = NewJsonArray(NULL, 0);
 
-       JsonArrayAppend(Val, WFInfo(Filename, FileLen,
-                                   LineNo, eEXCEPTION));
-
-       ExcClass = NewJsonObject(WF_MsgStrs[eTRACE].Key, 
-                                WF_MsgStrs[eTRACE].len);
-       
+       JsonArrayAppend(Val, WFInfo(Filename, FileLen, LineNo, eEXCEPTION));
+       ExcClass = NewJsonObject(WF_MsgStrs[eTRACE].Key, WF_MsgStrs[eTRACE].len);
        JsonArrayAppend(Val, ExcClass);
-       JsonObjectAppend(ExcClass, 
-                        NewJsonPlainString(HKEY("Class"), 
-                                           HKEY("Exception")));
-       JsonObjectAppend(ExcClass, 
-                        NewJsonString(HKEY("Message"), Message));
-       JsonObjectAppend(ExcClass, 
-                        NewJsonPlainString(HKEY("File"), 
-                                           Filename, FileLen));
+       JsonObjectAppend(ExcClass, NewJsonPlainString(HKEY("Class"), HKEY("Exception")));
+       JsonObjectAppend(ExcClass, NewJsonString(HKEY("Message"), Message, NEWJSONSTRING_COPYBUF));
+       JsonObjectAppend(ExcClass, NewJsonPlainString(HKEY("File"), Filename, FileLen));
 /*
-       JsonObjectAppend(ExcClass, 
-                        NewJsonPlainString(HKEY("Type"), 
-                                           HKEY("throw")));
+       JsonObjectAppend(ExcClass, NewJsonPlainString(HKEY("Type"), HKEY("throw")));
 */
-       JsonObjectAppend(ExcClass, 
-                        NewJsonNumber(HKEY("Line"), LineNo));
+       JsonObjectAppend(ExcClass, NewJsonNumber(HKEY("Line"), LineNo));
 
 #ifdef HAVE_BACKTRACE
        {
@@ -338,14 +325,10 @@ JsonValue *WildFireException(const char *Filename, long FileLen,
 
                        Frame = NewJsonObject(NULL, 0);
                        JsonArrayAppend(Trace, Frame);
-                       JsonObjectAppend(Frame, 
-                                        NewJsonString(HKEY("function"), Function));
-                       JsonObjectAppend(Frame, 
-                                        NewJsonString(HKEY("file"), FileName));
-                       JsonObjectAppend(Frame, 
-                                        NewJsonNumber(HKEY("line"), FunctionLine));
-                       JsonObjectAppend(Frame, 
-                                        NewJsonArray(HKEY("args")));/* not supportet... */
+                       JsonObjectAppend(Frame, NewJsonString(HKEY("function"), Function, NEWJSONSTRING_COPYBUF));
+                       JsonObjectAppend(Frame, NewJsonString(HKEY("file"), FileName, NEWJSONSTRING_COPYBUF));
+                       JsonObjectAppend(Frame, NewJsonNumber(HKEY("line"), FunctionLine));
+                       JsonObjectAppend(Frame, NewJsonArray(HKEY("args"))); // not supported
 
                        FunctionLine = 0;
                        FlushStrBuf(FileName);
index 016b811..6d8a8a3 100644 (file)
@@ -295,7 +295,6 @@ void flat_view(struct http_transaction *h, struct ctdlsession *c, char *which)
        return;
 }
 
-#endif
 
 // render one message (entire transaction)     FIXME EXTERMINATE
 //
@@ -314,12 +313,101 @@ void html_render_one_message(struct http_transaction *h, struct ctdlsession *c,
        return;
 }
 
+#endif
 
 // Fetch a single message and return it in JSON format for client-side rendering
 //
 void json_render_one_message(struct http_transaction *h, struct ctdlsession *c, long msgnum)
 {
-       JsonValue *j = NULL;                            // FIXME do something useful
+       StrBuf *raw_msg = NULL;
+       StrBuf *sanitized_msg = NULL;
+       char buf[1024];
+       char content_transfer_encoding[1024] = { 0 };
+       char content_type[1024] = { 0 };
+       char author[128] = { 0 };
+       char datetime[128] = { 0 } ;
+
+       setup_for_forum_view(c);
+
+       ctdl_printf(c, "MSG4 %ld", msgnum);
+       ctdl_readline(c, buf, sizeof(buf));
+       if (buf[0] != '1') {
+               do_404(h);
+               return;
+       }
+
+       JsonValue *j = NewJsonObject(HKEY("message"));
+
+       while ( (ctdl_readline(c, buf, sizeof(buf)) >= 0) && (strcmp(buf, "text")) && (strcmp(buf, "000")) ) {
+               // citadel header parsing here
+               if (!strncasecmp(buf, "from=", 5)) {
+                       JsonObjectAppend(j, NewJsonPlainString( HKEY("from"), &buf[5], -1));
+               }
+               if (!strncasecmp(buf, "rfca=", 5)) {
+                       JsonObjectAppend(j, NewJsonPlainString( HKEY("from"), &buf[5], -1));
+               }
+               if (!strncasecmp(buf, "time=", 5)) {
+                       time_t tt;
+                       struct tm tm;
+                       tt = atol(&buf[5]);
+                       localtime_r(&tt, &tm);
+                       strftime(datetime, sizeof datetime, "%c", &tm);
+                       JsonObjectAppend(j, NewJsonPlainString( HKEY("time"), datetime, -1));
+               }
+       }
+
+       if (!strcmp(buf, "text")) {
+               while ( (ctdl_readline(c, buf, sizeof(buf)) >= 0) && (strcmp(buf, "")) && (strcmp(buf, "000")) ) {
+                       // rfc822 header parsing here
+                       if (!strncasecmp(buf, "Content-transfer-encoding:", 26)) {
+                               strcpy(content_transfer_encoding, &buf[26]);
+                               striplt(content_transfer_encoding);
+                       }
+                       if (!strncasecmp(buf, "Content-type:", 13)) {
+                               strcpy(content_type, &buf[13]);
+                               striplt(content_type);
+                       }
+               }
+               raw_msg = ctdl_readtextmsg(c);
+       }
+       else {
+               raw_msg = NULL;
+       }
+
+       if (raw_msg) {
+
+               // These are the encodings we know how to handle.  Decode in-place.
+
+               if (!strcasecmp(content_transfer_encoding, "base64")) {
+                       StrBufDecodeBase64(raw_msg);
+               }
+               if (!strcasecmp(content_transfer_encoding, "quoted-printable")) {
+                       StrBufDecodeQP(raw_msg);
+               }
+
+               // At this point, raw_msg contains the decoded message.
+               // Now run through the renderers we have available.
+
+               if (!strncasecmp(content_type, "text/html", 9)) {
+                       sanitized_msg = html2html("UTF-8", 0, c->room, msgnum, raw_msg);
+               }
+               else if (!strncasecmp(content_type, "text/plain", 10)) {
+                       sanitized_msg = text2html("UTF-8", 0, c->room, msgnum, raw_msg);
+               }
+               else if (!strncasecmp(content_type, "text/x-citadel-variformat", 25)) {
+                       sanitized_msg = variformat2html(raw_msg);
+               }
+               else {
+                       sanitized_msg = NewStrBufPlain(HKEY("<i>No renderer for this content type</i><br>"));
+               }
+               FreeStrBuf(&raw_msg);
+
+               // If sanitized_msg is not NULL, we have rendered the message and can output it.
+
+               if (sanitized_msg) {
+                       JsonObjectAppend(j, NewJsonString(HKEY("text"), sanitized_msg, NEWJSONSTRING_SMASHBUF));
+               }
+       }
 
        StrBuf *sj = NewStrBuf();
        SerializeJson(sj, j, 1);                        // '1' == free the source object
index 8136ced..a2dfc7b 100644 (file)
@@ -193,10 +193,6 @@ void object_in_room(struct http_transaction *h, struct ctdlsession *c)
                        {
                                json_render_one_message(h, c, msgnum);
                        }
-                       else if (!strcasecmp(buf, "html"))                      // FIXME exterminate this, we don't want any server-side rendering
-                       {
-                               html_render_one_message(h, c, msgnum);
-                       }
                        else
                        {
                                download_mime_component(h, c, msgnum, buf);
index 5b3c478..bfa45f5 100644 (file)
@@ -155,7 +155,7 @@ function render_messages(msgs, prefix, view)
 function render_one(div, msgnum, view)
 {
        var request = new XMLHttpRequest();
-       request.open("GET", "/ctdl/r/" + escapeHTMLURI(current_room) + "/" + msgs[i] + "/html", true);
+       request.open("GET", "/ctdl/r/" + escapeHTMLURI(current_room) + "/" + msgs[i] + "/json", true);
        request.onreadystatechange = function()
        {
                if (this.readyState === 4)
index 5321c9b..69a6bc0 100644 (file)
@@ -147,8 +147,6 @@ void dav_get_message(struct http_transaction *h, struct ctdlsession *c, long msg
 void dav_put_message(struct http_transaction *h, struct ctdlsession *c, char *euid, long old_msgnum);
 ssize_t ctdl_write(struct ctdlsession *ctdl, const void *buf, size_t count);
 int login_to_citadel(struct ctdlsession *c, char *auth, char *resultbuf);
-void threaded_view(struct http_transaction *h, struct ctdlsession *c, char *which);
-void flat_view(struct http_transaction *h, struct ctdlsession *c, char *which);
 StrBuf *ctdl_readtextmsg(struct ctdlsession *ctdl);
 StrBuf *html2html(const char *supplied_charset, int treat_as_wiki, char *roomname, long msgnum, StrBuf *Source);
 void download_mime_component(struct http_transaction *h, struct ctdlsession *c, long msgnum, char *partnum);
@@ -164,4 +162,3 @@ void do_404(struct http_transaction *h);
 void do_412(struct http_transaction *h);
 void UrlizeText(StrBuf* Target, StrBuf *Source, StrBuf *WrkBuf);
 void json_render_one_message(struct http_transaction *h, struct ctdlsession *c, long msgnum);
-void html_render_one_message(struct http_transaction *h, struct ctdlsession *c, long msgnum);