liquid_feedback_frontend
annotate fastpath/getpic.c @ 4:80c215dbf076
Version alpha5
Many optical changes and improved usability
Support for different wiki-formatting-engines
Help system
Many optical changes and improved usability
Support for different wiki-formatting-engines
Help system
| author | bsw/jbe | 
|---|---|
| date | Thu Dec 10 12:00:00 2009 +0100 (2009-12-10) | 
| parents | |
| children | afd9f769c7ae | 
| rev | line source | 
|---|---|
| bsw/jbe@4 | 1 #include <stdlib.h> | 
| bsw/jbe@4 | 2 #include <stdio.h> | 
| bsw/jbe@4 | 3 #include <libpq-fe.h> | 
| bsw/jbe@4 | 4 #include <string.h> | 
| bsw/jbe@4 | 5 #include <regex.h> | 
| bsw/jbe@4 | 6 #include <sys/types.h> | 
| bsw/jbe@4 | 7 #include <sys/stat.h> | 
| bsw/jbe@4 | 8 #include <unistd.h> | 
| bsw/jbe@4 | 9 | 
| bsw/jbe@4 | 10 #ifndef GETPIC_CONNINFO | 
| bsw/jbe@4 | 11 #define GETPIC_CONNINFO "dbname=liquid_feedback" | 
| bsw/jbe@4 | 12 #endif | 
| bsw/jbe@4 | 13 | 
| bsw/jbe@4 | 14 #ifndef GETPIC_DEFAULT_AVATAR | 
| bsw/jbe@4 | 15 #define GETPIC_DEFAULT_AVATAR "/opt/liquid_feedback_testing/app/static/avatar.jpg" | 
| bsw/jbe@4 | 16 #endif | 
| bsw/jbe@4 | 17 | 
| bsw/jbe@4 | 18 int main(int argc, const char * const *argv) { | 
| bsw/jbe@4 | 19 PGconn *conn; | 
| bsw/jbe@4 | 20 PGresult *dbr; | 
| bsw/jbe@4 | 21 | 
| bsw/jbe@4 | 22 char *cookies = getenv("HTTP_COOKIE"); | 
| bsw/jbe@4 | 23 | 
| bsw/jbe@4 | 24 char *args_string; | 
| bsw/jbe@4 | 25 char *member_id; | 
| bsw/jbe@4 | 26 char *image_type; | 
| bsw/jbe@4 | 27 | 
| bsw/jbe@4 | 28 char *sql_session_params[1]; | 
| bsw/jbe@4 | 29 char *sql_member_image_params[2]; | 
| bsw/jbe@4 | 30 | 
| bsw/jbe@4 | 31 ssize_t start, length; | 
| bsw/jbe@4 | 32 | 
| bsw/jbe@4 | 33 char *session_ident; | 
| bsw/jbe@4 | 34 | 
| bsw/jbe@4 | 35 regex_t session_ident_regex; | 
| bsw/jbe@4 | 36 regmatch_t session_ident_regmatch[2]; | 
| bsw/jbe@4 | 37 | 
| bsw/jbe@4 | 38 cookies = getenv("HTTP_COOKIE"); | 
| bsw/jbe@4 | 39 | 
| bsw/jbe@4 | 40 args_string = getenv("QUERY_STRING"); | 
| bsw/jbe@4 | 41 | 
| bsw/jbe@4 | 42 if (!cookies || !args_string) { | 
| bsw/jbe@4 | 43 fputs("Status: 403 Access Denied\n\n", stdout); | 
| bsw/jbe@4 | 44 return 0; | 
| bsw/jbe@4 | 45 } | 
| bsw/jbe@4 | 46 | 
| bsw/jbe@4 | 47 member_id = strtok(args_string, "+"); | 
| bsw/jbe@4 | 48 image_type = strtok(NULL, "+"); | 
| bsw/jbe@4 | 49 | 
| bsw/jbe@4 | 50 sql_member_image_params[0] = member_id; | 
| bsw/jbe@4 | 51 sql_member_image_params[1] = image_type; | 
| bsw/jbe@4 | 52 | 
| bsw/jbe@4 | 53 // get session from cookie | 
| bsw/jbe@4 | 54 | 
| bsw/jbe@4 | 55 // TODO improve regex to fit better | 
| bsw/jbe@4 | 56 if (regcomp(&session_ident_regex, "liquid_feedback_session=([a-zA-Z0-9]+)", REG_EXTENDED) != 0) { | 
| bsw/jbe@4 | 57 // shouldn't happen | 
| bsw/jbe@4 | 58 abort(); | 
| bsw/jbe@4 | 59 } | 
| bsw/jbe@4 | 60 | 
| bsw/jbe@4 | 61 if (regexec(&session_ident_regex, cookies, 2, session_ident_regmatch, 0) != 0) { | 
| bsw/jbe@4 | 62 fputs("Status: 403 Access Denied\n\n", stdout); | 
| bsw/jbe@4 | 63 return 0; | 
| bsw/jbe@4 | 64 } | 
| bsw/jbe@4 | 65 | 
| bsw/jbe@4 | 66 start = session_ident_regmatch[1].rm_so; | 
| bsw/jbe@4 | 67 length = session_ident_regmatch[1].rm_eo - session_ident_regmatch[1].rm_so; | 
| bsw/jbe@4 | 68 | 
| bsw/jbe@4 | 69 session_ident = malloc(length + 1); | 
| bsw/jbe@4 | 70 | 
| bsw/jbe@4 | 71 strncpy(session_ident, cookies + start, length); | 
| bsw/jbe@4 | 72 | 
| bsw/jbe@4 | 73 session_ident[length] = 0; | 
| bsw/jbe@4 | 74 | 
| bsw/jbe@4 | 75 sql_session_params[0] = session_ident; | 
| bsw/jbe@4 | 76 | 
| bsw/jbe@4 | 77 | 
| bsw/jbe@4 | 78 // connect to database | 
| bsw/jbe@4 | 79 | 
| bsw/jbe@4 | 80 conn = PQconnectdb(GETPIC_CONNINFO); | 
| bsw/jbe@4 | 81 if (!conn) { | 
| bsw/jbe@4 | 82 fputs("Could not create PGconn structure.\n", stderr); | 
| bsw/jbe@4 | 83 return 1; | 
| bsw/jbe@4 | 84 } | 
| bsw/jbe@4 | 85 if (PQstatus(conn) != CONNECTION_OK) { | 
| bsw/jbe@4 | 86 fputs(PQerrorMessage(conn), stderr); | 
| bsw/jbe@4 | 87 return 1; | 
| bsw/jbe@4 | 88 } | 
| bsw/jbe@4 | 89 | 
| bsw/jbe@4 | 90 // check session | 
| bsw/jbe@4 | 91 dbr = PQexecParams(conn, | 
| bsw/jbe@4 | 92 "SELECT NULL FROM session JOIN member ON member.id = session.member_id WHERE session.ident = $1 AND member.active", | 
| bsw/jbe@4 | 93 1, NULL, sql_session_params, NULL, NULL, 0 | 
| bsw/jbe@4 | 94 ); | 
| bsw/jbe@4 | 95 | 
| bsw/jbe@4 | 96 if (PQresultStatus(dbr) != PGRES_TUPLES_OK) { | 
| bsw/jbe@4 | 97 fputs(PQresultErrorMessage(dbr), stderr); | 
| bsw/jbe@4 | 98 return 1; | 
| bsw/jbe@4 | 99 } | 
| bsw/jbe@4 | 100 | 
| bsw/jbe@4 | 101 if (PQntuples(dbr) != 1) { | 
| bsw/jbe@4 | 102 fputs("Status: 403 Access Denied\n\n", stdout); | 
| bsw/jbe@4 | 103 return 0; | 
| bsw/jbe@4 | 104 } | 
| bsw/jbe@4 | 105 | 
| bsw/jbe@4 | 106 | 
| bsw/jbe@4 | 107 // get picture | 
| bsw/jbe@4 | 108 dbr = PQexecParams(conn, | 
| bsw/jbe@4 | 109 "SELECT content_type, data " | 
| bsw/jbe@4 | 110 "FROM member_image " | 
| bsw/jbe@4 | 111 "WHERE member_id = $1 " | 
| bsw/jbe@4 | 112 "AND image_type = $2 " | 
| bsw/jbe@4 | 113 "AND scaled " | 
| bsw/jbe@4 | 114 "LIMIT 1;", | 
| bsw/jbe@4 | 115 2, NULL, sql_member_image_params, NULL, NULL, 1 | 
| bsw/jbe@4 | 116 ); | 
| bsw/jbe@4 | 117 | 
| bsw/jbe@4 | 118 if (PQresultStatus(dbr) != PGRES_TUPLES_OK) { | 
| bsw/jbe@4 | 119 fputs(PQresultErrorMessage(dbr), stderr); | 
| bsw/jbe@4 | 120 return 1; | 
| bsw/jbe@4 | 121 } | 
| bsw/jbe@4 | 122 if (PQntuples(dbr) > 1) { | 
| bsw/jbe@4 | 123 return 1; | 
| bsw/jbe@4 | 124 } | 
| bsw/jbe@4 | 125 fputs("Cache-Control: private; max-age=86400\n", stdout); | 
| bsw/jbe@4 | 126 if (PQntuples(dbr) == 0) { | 
| bsw/jbe@4 | 127 struct stat sb; | 
| bsw/jbe@4 | 128 PQclear(dbr); | 
| bsw/jbe@4 | 129 PQfinish(conn); | 
| bsw/jbe@4 | 130 fputs("Content-Type: image/jpeg\n\n", stdout); | 
| bsw/jbe@4 | 131 if (stat(GETPIC_DEFAULT_AVATAR, &sb)) return 1; | 
| bsw/jbe@4 | 132 fprintf(stdout, "Content-Length: %i\n", sb.st_size); | 
| bsw/jbe@4 | 133 execl("/bin/cat", "cat", GETPIC_DEFAULT_AVATAR, NULL); | 
| bsw/jbe@4 | 134 return 1; | 
| bsw/jbe@4 | 135 } else { | 
| bsw/jbe@4 | 136 if (PQnfields(dbr) < 0) { | 
| bsw/jbe@4 | 137 fputs("Too few columns returned by database.\n", stderr); | 
| bsw/jbe@4 | 138 return 1; | 
| bsw/jbe@4 | 139 } | 
| bsw/jbe@4 | 140 if (PQfformat(dbr, 0) != 1 || PQfformat(dbr, 1) != 1) { | 
| bsw/jbe@4 | 141 fputs("Database did not return data in binary format.\n", stderr); | 
| bsw/jbe@4 | 142 return 1; | 
| bsw/jbe@4 | 143 } | 
| bsw/jbe@4 | 144 if (PQgetisnull(dbr, 0, 0) || PQgetisnull(dbr, 0, 1)) { | 
| bsw/jbe@4 | 145 fputs("Unexpected NULL in database result.\n", stderr); | 
| bsw/jbe@4 | 146 return 1; | 
| bsw/jbe@4 | 147 } | 
| bsw/jbe@4 | 148 fputs("Content-Type: ", stdout); | 
| bsw/jbe@4 | 149 fprintf(stdout, "Content-Length: %i\n", PQgetlength(dbr, 0, 1)); | 
| bsw/jbe@4 | 150 fwrite(PQgetvalue(dbr, 0, 0), PQgetlength(dbr, 0, 0), 1, stdout); | 
| bsw/jbe@4 | 151 fputs("\n\n", stdout); | 
| bsw/jbe@4 | 152 fwrite(PQgetvalue(dbr, 0, 1), PQgetlength(dbr, 0, 1), 1, stdout); | 
| bsw/jbe@4 | 153 } | 
| bsw/jbe@4 | 154 PQclear(dbr); | 
| bsw/jbe@4 | 155 PQfinish(conn); | 
| bsw/jbe@4 | 156 return 0; | 
| bsw/jbe@4 | 157 } |