/ctdl/u/username/userpic is now complete
authorArt Cancro <ajc@citadel.org>
Mon, 17 Sep 2018 01:54:19 +0000 (21:54 -0400)
committerArt Cancro <ajc@citadel.org>
Mon, 17 Sep 2018 01:54:19 +0000 (21:54 -0400)
webcit-ng/ctdlclient.c
webcit-ng/room_functions.c
webcit-ng/user_functions.c
webcit-ng/webcit.h

index 0a5e1fbcd47492b64781f24f7d12c93fc775c1e2..2467b1237c5f3c7bc9b510d801579fb3603794a4 100644 (file)
@@ -18,9 +18,29 @@ struct ctdlsession *cpool = NULL;                            // linked list of connections to the Citade
 pthread_mutex_t cpool_mutex = PTHREAD_MUTEX_INITIALIZER;       // Lock it before modifying
 
 
+/*
+ * Read a specific number of bytes of binary data from the Citadel server.
+ * Returns the number of bytes read or -1 for error.
+ */
+int ctdl_read_binary(struct ctdlsession *ctdl, char *buf, int bytes_requested)
+{
+       int bytes_read = 0;
+       int c = 0;
+
+       while (bytes_read < bytes_requested) {
+               c = read(ctdl->sock, &buf[bytes_read], bytes_requested-bytes_read);
+               if (c <= 0) {
+                       syslog(LOG_DEBUG, "Socket error or zero-length read");
+                       return (-1);
+               }
+               bytes_read += c;
+       }
+       return (bytes_read);
+}
+
+
 /*
  * Read a newline-terminated line of text from the Citadel server.
- * Implemented in terms of client_read() and is therefore transparent...
  * Returns the string length or -1 for error.
  */
 int ctdl_readline(struct ctdlsession *ctdl, char *buf, int maxbytes)
index 403e83f70c2b1d9d43d462c065ceb1067590e95d..75ef7bcf589edc7720a830b1c1b05fb874238283 100644 (file)
@@ -28,7 +28,7 @@ long *get_msglist(struct ctdlsession *c, char *which_msgs)
 
        ctdl_printf(c, "MSGS %s", which_msgs);
        ctdl_readline(c, buf, sizeof(buf));
-       if (buf[0] == '1')
+       if (buf[0] == '1') {
                do {
                        if (num_msgs >= num_alloc) {
                                if (num_alloc == 0) {
@@ -42,6 +42,7 @@ long *get_msglist(struct ctdlsession *c, char *which_msgs)
                        ctdl_readline(c, buf, sizeof(buf));
                        msglist[num_msgs++] = atol(buf);
                } while (strcmp(buf, "000"));   // this makes the last element a "0" terminator
+       }
        return msglist;
 }
 
@@ -57,8 +58,7 @@ int match_etags(char *taglist, long msgnum)
        int i = 0;
        char tag[1024];
 
-       if (msgnum <= 0)        // no msgnum?  no match.
-       {
+       if (msgnum <= 0) {                                      // no msgnum?  no match.
                return (0);
        }
 
@@ -67,24 +67,21 @@ int match_etags(char *taglist, long msgnum)
                striplt(tag);
                char *lq = (strchr(tag, '"'));
                char *rq = (strrchr(tag, '"'));
-               if (lq < rq)    // has two double quotes
-               {
+               if (lq < rq) {                                  // has two double quotes
                        strcpy(rq, "");
                        strcpy(tag, ++lq);
                }
                striplt(tag);
-               if (!strcmp(tag, "*"))  // wildcard match
-               {
+               if (!strcmp(tag, "*")) {                        // wildcard match
                        return (1);
                }
                long tagmsgnum = atol(tag);
-               if ((tagmsgnum > 0) && (tagmsgnum == msgnum))   // match
-               {
+               if ((tagmsgnum > 0) && (tagmsgnum == msgnum)) { // match
                        return (1);
                }
        }
 
-       return (0);             // no match
+       return (0);                                             // no match
 }
 
 
index b3d360f000b539635acdefdc8ac2cb8caf7b0f46..10e81211fae477d89ded8489640db3fbe28309cf 100644 (file)
 /*
  * Fetch a user photo (avatar)
  */
-void fetch_user_photo(struct http_transaction *h, struct ctdlsession *c)
+void fetch_user_photo(struct http_transaction *h, struct ctdlsession *c, char *username)
 {
-       char username[1024];
+       char buf[1024];
+       int content_length = 0;
+       char content_type[1024];
+       char *image = NULL;
+       int actual_length = 0;
+
+       ctdl_printf(c, "DLUI %s", username);
+       ctdl_readline(c, buf, sizeof(buf));
+       if (buf[0] == '6') {
+               content_length = extract_int(&buf[4], 0);
+               extract_token(content_type, &buf[4], 3, '|', sizeof content_type);
+
+               image = malloc(content_length);
+               if (image == NULL) {
+                       do_502(h);
+                       return;
+               }
+               actual_length = ctdl_read_binary(c, image, content_length);
 
-       extract_token(username, h->uri, 3, '/', sizeof username);
+               add_response_header(h, strdup("Content-type"), strdup(content_type));
+               h->response_code = 200;
+               h->response_string = strdup("OK");
+               h->response_body_length = actual_length;
+               h->response_body = image;
+               return;
+       }
 
-       do_404(h);      // FIXME finish this
+       do_404(h);
 }
 
 
 /*
  * Fetch a user bio (profile)
  */
-void fetch_user_bio(struct http_transaction *h, struct ctdlsession *c)
+void fetch_user_bio(struct http_transaction *h, struct ctdlsession *c, char *username)
 {
-       char username[1024];
-
-       extract_token(username, h->uri, 3, '/', sizeof username);
-
        do_404(h);      // FIXME finish this
 }
 
@@ -44,21 +63,19 @@ void fetch_user_bio(struct http_transaction *h, struct ctdlsession *c)
 /*
  * Client requested an object related to a user.
  */
-void object_in_user(struct http_transaction *h, struct ctdlsession *c)
+void object_in_user(struct http_transaction *h, struct ctdlsession *c, char *requested_username)
 {
-       char buf[1024];
-       long msgnum = (-1);
-       char unescaped_euid[1024];
+       char object_name[1024];
 
-       extract_token(buf, h->uri, 4, '/', sizeof buf);
+       extract_token(object_name, h->uri, 4, '/', sizeof object_name);
 
-       if (!strcasecmp(buf, "userpic")) {              // user photo (avatar)
-               fetch_user_photo(h, c);
+       if (!strcasecmp(object_name, "userpic")) {              // user photo (avatar)
+               fetch_user_photo(h, c, requested_username);
                return;
        }
 
-       if (!strcasecmp(buf, "bio")) {                  // user bio (profile)
-               fetch_user_bio(h, c);
+       if (!strcasecmp(object_name, "bio")) {                  // user bio (profile)
+               fetch_user_bio(h, c, requested_username);
                return;
        }
 
@@ -71,7 +88,7 @@ void object_in_user(struct http_transaction *h, struct ctdlsession *c)
  * Handle REST/DAV requests for the user itself (such as /ctdl/u/username
  * or /ctdl/i/username/ but *not* specific properties of the user)
  */
-void the_user_itself(struct http_transaction *h, struct ctdlsession *c)
+void the_user_itself(struct http_transaction *h, struct ctdlsession *c, char *username)
 {
        do_404(h);
 }
@@ -98,40 +115,34 @@ void ctdl_u(struct http_transaction *h, struct ctdlsession *c)
        extract_token(requested_username, h->uri, 3, '/', sizeof requested_username);
        unescape_input(requested_username);
 
-       if (IsEmptyStr(requested_username)) {   //      /ctdl/u/
+       if (IsEmptyStr(requested_username)) {                           //      /ctdl/u/
                user_list(h, c);
                return;
        }
 
-       // Try to access the user...
-       if (strcasecmp(requested_username, c->room)) {
-               do_404(h);
-       } else {
-               do_404(h);
-               return;
-       }
+       // At this point we have extracted the name of the user we're interested in.
+       // FIXME should we validate it?
 
-       // At this point we have accessed the requested user account.
-       if (num_tokens(h->uri, '/') == 4) {     //      /ctdl/u/username
-               the_user_itself(h, c);
+       if (num_tokens(h->uri, '/') == 4) {                             //      /ctdl/u/username
+               the_user_itself(h, c, requested_username);
                return;
        }
 
        extract_token(buf, h->uri, 4, '/', sizeof buf);
        if (num_tokens(h->uri, '/') == 5) {
                if (IsEmptyStr(buf)) {
-                       the_user_itself(h, c);  //      /ctdl/u/username/       ( same as /ctdl/u/username )
+                       the_user_itself(h, c, requested_username);      //      /ctdl/u/username/       ( same as /ctdl/u/username )
                } else {
-                       object_in_user(h, c);   //      /ctdl/u/username/object
+                       object_in_user(h, c, requested_username);       //      /ctdl/u/username/object
                }
                return;
        }
 
        if (num_tokens(h->uri, '/') == 6) {
-               object_in_user(h, c);   //      /ctdl/u/username/object/ or possibly /ctdl/u/username/object/component
+               object_in_user(h, c, requested_username);               //      /ctdl/u/username/object/ or possibly /ctdl/u/username/object/component
                return;
        }
 
-       // If we get to this point, the client specified a valid user but requested an action we don't know how to perform.
+       // If we get to this point, the client requested an action we don't know how to perform.
        do_404(h);
 }
index af08f6fddb2c3d307c1c76fe1705f748f564347a..36f47acf72582bb5f6261ad1f240fd98eb641f1b 100644 (file)
@@ -157,6 +157,7 @@ void download_mime_component(struct http_transaction *h, struct ctdlsession *c,
 StrBuf *text2html(const char *supplied_charset, int treat_as_wiki, char *roomname, long msgnum, StrBuf *Source);
 StrBuf *variformat2html(StrBuf *Source);
 int ctdl_readline(struct ctdlsession *ctdl, char *buf, int maxbytes);
+int ctdl_read_binary(struct ctdlsession *ctdl, char *buf, int bytes_requested);
 void ctdl_c(struct http_transaction *h, struct ctdlsession *c);
 int webserver(char *webserver_interface, int webserver_port, int webserver_protocol);
 void ctdl_printf(struct ctdlsession *ctdl, const char *format,...);