liquid_feedback_frontend
diff 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 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/fastpath/getpic.c Thu Dec 10 12:00:00 2009 +0100 1.3 @@ -0,0 +1,157 @@ 1.4 +#include <stdlib.h> 1.5 +#include <stdio.h> 1.6 +#include <libpq-fe.h> 1.7 +#include <string.h> 1.8 +#include <regex.h> 1.9 +#include <sys/types.h> 1.10 +#include <sys/stat.h> 1.11 +#include <unistd.h> 1.12 + 1.13 +#ifndef GETPIC_CONNINFO 1.14 +#define GETPIC_CONNINFO "dbname=liquid_feedback" 1.15 +#endif 1.16 + 1.17 +#ifndef GETPIC_DEFAULT_AVATAR 1.18 +#define GETPIC_DEFAULT_AVATAR "/opt/liquid_feedback_testing/app/static/avatar.jpg" 1.19 +#endif 1.20 + 1.21 +int main(int argc, const char * const *argv) { 1.22 + PGconn *conn; 1.23 + PGresult *dbr; 1.24 + 1.25 + char *cookies = getenv("HTTP_COOKIE"); 1.26 + 1.27 + char *args_string; 1.28 + char *member_id; 1.29 + char *image_type; 1.30 + 1.31 + char *sql_session_params[1]; 1.32 + char *sql_member_image_params[2]; 1.33 + 1.34 + ssize_t start, length; 1.35 + 1.36 + char *session_ident; 1.37 + 1.38 + regex_t session_ident_regex; 1.39 + regmatch_t session_ident_regmatch[2]; 1.40 + 1.41 + cookies = getenv("HTTP_COOKIE"); 1.42 + 1.43 + args_string = getenv("QUERY_STRING"); 1.44 + 1.45 + if (!cookies || !args_string) { 1.46 + fputs("Status: 403 Access Denied\n\n", stdout); 1.47 + return 0; 1.48 + } 1.49 + 1.50 + member_id = strtok(args_string, "+"); 1.51 + image_type = strtok(NULL, "+"); 1.52 + 1.53 + sql_member_image_params[0] = member_id; 1.54 + sql_member_image_params[1] = image_type; 1.55 + 1.56 + // get session from cookie 1.57 + 1.58 + // TODO improve regex to fit better 1.59 + if (regcomp(&session_ident_regex, "liquid_feedback_session=([a-zA-Z0-9]+)", REG_EXTENDED) != 0) { 1.60 + // shouldn't happen 1.61 + abort(); 1.62 + } 1.63 + 1.64 + if (regexec(&session_ident_regex, cookies, 2, session_ident_regmatch, 0) != 0) { 1.65 + fputs("Status: 403 Access Denied\n\n", stdout); 1.66 + return 0; 1.67 + } 1.68 + 1.69 + start = session_ident_regmatch[1].rm_so; 1.70 + length = session_ident_regmatch[1].rm_eo - session_ident_regmatch[1].rm_so; 1.71 + 1.72 + session_ident = malloc(length + 1); 1.73 + 1.74 + strncpy(session_ident, cookies + start, length); 1.75 + 1.76 + session_ident[length] = 0; 1.77 + 1.78 + sql_session_params[0] = session_ident; 1.79 + 1.80 + 1.81 + // connect to database 1.82 + 1.83 + conn = PQconnectdb(GETPIC_CONNINFO); 1.84 + if (!conn) { 1.85 + fputs("Could not create PGconn structure.\n", stderr); 1.86 + return 1; 1.87 + } 1.88 + if (PQstatus(conn) != CONNECTION_OK) { 1.89 + fputs(PQerrorMessage(conn), stderr); 1.90 + return 1; 1.91 + } 1.92 + 1.93 + // check session 1.94 + dbr = PQexecParams(conn, 1.95 + "SELECT NULL FROM session JOIN member ON member.id = session.member_id WHERE session.ident = $1 AND member.active", 1.96 + 1, NULL, sql_session_params, NULL, NULL, 0 1.97 + ); 1.98 + 1.99 + if (PQresultStatus(dbr) != PGRES_TUPLES_OK) { 1.100 + fputs(PQresultErrorMessage(dbr), stderr); 1.101 + return 1; 1.102 + } 1.103 + 1.104 + if (PQntuples(dbr) != 1) { 1.105 + fputs("Status: 403 Access Denied\n\n", stdout); 1.106 + return 0; 1.107 + } 1.108 + 1.109 + 1.110 + // get picture 1.111 + dbr = PQexecParams(conn, 1.112 + "SELECT content_type, data " 1.113 + "FROM member_image " 1.114 + "WHERE member_id = $1 " 1.115 + "AND image_type = $2 " 1.116 + "AND scaled " 1.117 + "LIMIT 1;", 1.118 + 2, NULL, sql_member_image_params, NULL, NULL, 1 1.119 + ); 1.120 + 1.121 + if (PQresultStatus(dbr) != PGRES_TUPLES_OK) { 1.122 + fputs(PQresultErrorMessage(dbr), stderr); 1.123 + return 1; 1.124 + } 1.125 + if (PQntuples(dbr) > 1) { 1.126 + return 1; 1.127 + } 1.128 + fputs("Cache-Control: private; max-age=86400\n", stdout); 1.129 + if (PQntuples(dbr) == 0) { 1.130 + struct stat sb; 1.131 + PQclear(dbr); 1.132 + PQfinish(conn); 1.133 + fputs("Content-Type: image/jpeg\n\n", stdout); 1.134 + if (stat(GETPIC_DEFAULT_AVATAR, &sb)) return 1; 1.135 + fprintf(stdout, "Content-Length: %i\n", sb.st_size); 1.136 + execl("/bin/cat", "cat", GETPIC_DEFAULT_AVATAR, NULL); 1.137 + return 1; 1.138 + } else { 1.139 + if (PQnfields(dbr) < 0) { 1.140 + fputs("Too few columns returned by database.\n", stderr); 1.141 + return 1; 1.142 + } 1.143 + if (PQfformat(dbr, 0) != 1 || PQfformat(dbr, 1) != 1) { 1.144 + fputs("Database did not return data in binary format.\n", stderr); 1.145 + return 1; 1.146 + } 1.147 + if (PQgetisnull(dbr, 0, 0) || PQgetisnull(dbr, 0, 1)) { 1.148 + fputs("Unexpected NULL in database result.\n", stderr); 1.149 + return 1; 1.150 + } 1.151 + fputs("Content-Type: ", stdout); 1.152 + fprintf(stdout, "Content-Length: %i\n", PQgetlength(dbr, 0, 1)); 1.153 + fwrite(PQgetvalue(dbr, 0, 0), PQgetlength(dbr, 0, 0), 1, stdout); 1.154 + fputs("\n\n", stdout); 1.155 + fwrite(PQgetvalue(dbr, 0, 1), PQgetlength(dbr, 0, 1), 1, stdout); 1.156 + } 1.157 + PQclear(dbr); 1.158 + PQfinish(conn); 1.159 + return 0; 1.160 +}