Account *accountCreate(sqlite3 *DB, char *name, char *email, char *username, char *password) { int rc; Account *account = NULL; sqlite3_stmt *statement; rc = sqlite3_prepare_v2( DB, "INSERT INTO accounts(createdAt, name, email, username, password)" " VALUES ( ?, ?, ?, ?, ?)", -1, &statement, NULL); if (rc != SQLITE_OK) return NULL; char *escapedName = bsEscape(name); char *escapedEmail = bsEscape(email); if (sqlite3_bind_int(statement, 1, time(NULL)) != SQLITE_OK) goto fail; if (sqlite3_bind_text(statement, 2, escapedName, -1, NULL) != SQLITE_OK) goto fail; if (sqlite3_bind_text(statement, 3, escapedEmail, -1, NULL) != SQLITE_OK) goto fail; if (sqlite3_bind_text(statement, 4, username, -1, NULL) != SQLITE_OK) goto fail; if (sqlite3_bind_text(statement, 5, password, -1, NULL) != SQLITE_OK) goto fail; if (sqlite3_step(statement) == SQLITE_DONE) { account = accountGetByEmail(DB, email); } fail: bsDel(escapedName); bsDel(escapedEmail); sqlite3_finalize(statement); return account; }
static inline ListCell *parseQS(char *path) { ListCell *qs = NULL; char *copy = bsNew(path); char *segment, *key, *value; bool s = true; for (;;) { if (s) {segment = strtok(copy, "="); s = false;} else {segment = strtok(NULL, "=");} if (segment == NULL) break; if (*(segment + strlen(segment) + 1) == '&') continue; key = segment; segment = strtok(NULL, "&\0"); if (segment == NULL) break; key = urldecode(key); value = urldecode(segment); qs = listCons(kvNew(key, value), sizeof(KV), qs); bsDel(key); bsDel(value); } bsDel(copy); return qs; }
void requestDel(Request *req) { if (req->path != NULL) bsDel(req->path); if (req->uri != NULL) bsDel(req->uri); if (req->queryString != NULL) kvDelList(req->queryString); if (req->postBody != NULL) kvDelList(req->postBody); if (req->headers != NULL) kvDelList(req->headers); if (req->cookies != NULL) kvDelList(req->cookies); if (req->account != NULL) accountDel(req->account); free(req); }
static inline ListCell *parseCookies(char *header) { ListCell *cookies = NULL; char *copy = bsNew(header); char *segment, *key; bool s = true; for (;;) { if (s) {segment = strtok(copy, "="); s = false;} else {segment = strtok(NULL, "=");} if (segment == NULL) break; if (*segment == ' ') segment += 1; key = segment; segment = strtok(NULL, ";\0"); if (segment == NULL) break; cookies = listCons(kvNew(key, segment), sizeof(KV), cookies); } bsDel(copy); return cookies; }
char *bsEscape(char *bs) { char *copy = bsNew(bs); char *res = bsNew(""); char *c = copy; char *p = copy; while (*c != '\0') { if (*c == '<') { *c = '\0'; bsLCat(&res, p); bsLCat(&res, "<"); p = c + 1; } else if (*c == '>') { *c = '\0'; bsLCat(&res, p); bsLCat(&res, ">"); p = c + 1; } c++; } bsLCat(&res, p); bsDel(copy); return res; }
Post *postCreate(sqlite3 *DB, int authorId, char *body) { int rc, t; Post *post = NULL; sqlite3_stmt *statement; t = time(NULL); rc = sqlite3_prepare_v2( DB, "INSERT INTO posts(createdAt, author, body)" " VALUES ( ?, ?, ?)", -1, &statement, NULL); if (rc != SQLITE_OK) return NULL; char *escapedBody = bsEscape(body); if (sqlite3_bind_int(statement, 1, t) != SQLITE_OK) goto fail; if (sqlite3_bind_int(statement, 2, authorId) != SQLITE_OK) goto fail; if (sqlite3_bind_text(statement, 3, escapedBody, -1, NULL) != SQLITE_OK) goto fail; if (sqlite3_step(statement) == SQLITE_DONE) { post = postNew(sqlite3_last_insert_rowid(DB), t, authorId, body); } fail: bsDel(escapedBody); sqlite3_finalize(statement); return post; }
void do_response(Request *req, Response ** res, sqlite3 *db) { if (!req->account) return; int id = -1; char *idStr = NULL; if((idStr = kvFindList(req->queryString, "id"))){ sscanf(idStr, "%d", &id); } Post *post = postGetById(db, id); if (!post) goto fail; likeDel(likeCreate(db, req->account->id, post->authorId, post->id)); if (kvFindList(req->queryString, "r")) { char sbuff[1024]; sprintf(sbuff, "/profile?id=%d", post->authorId); bsDel(idStr); *res = responseNewRedirect(sbuff); } fail: *res = responseNewRedirect("/dashboard"); }
void responseDel(Response *response) { if (response->headers) kvDelList(response->headers); if (response->body) bsDel(response->body); free(response); }
Session *sessionCreate(sqlite3 *DB, char *username, char *password) { int aid; char *sid = NULL; Session *session = NULL; sqlite3_stmt *statement; if (sqlite3_prepare_v2(DB, "SELECT id" " FROM accounts" " WHERE username = ?" " AND password = ?", -1, &statement, NULL) != SQLITE_OK) { return NULL; } if (sqlite3_bind_text(statement, 1, username, -1, NULL) != SQLITE_OK) goto fail; if (sqlite3_bind_text(statement, 2, password, -1, NULL) != SQLITE_OK) goto fail; if (sqlite3_step(statement) != SQLITE_ROW) goto fail; sid = bsRandom(24, username); aid = sqlite3_column_int(statement, 0); sqlite3_finalize(statement); if (sqlite3_prepare_v2(DB, "INSERT INTO sessions(createdAt, account, session)" " VALUES ( ?, ?, ?)", -1, &statement, NULL) != SQLITE_OK) { goto fail; } if (sqlite3_bind_int(statement, 1, time(NULL)) != SQLITE_OK) goto fail; if (sqlite3_bind_int(statement, 2, aid) != SQLITE_OK) goto fail; if (sqlite3_bind_text(statement, 3, sid, -1, NULL) != SQLITE_OK) goto fail; if (sqlite3_step(statement) != SQLITE_DONE) goto fail; session = sessionGetBySId(DB, sid); fail: if (sid) bsDel(sid); sqlite3_finalize(statement); return session; }
void accountDel(Account *account) { bsDel(account->name); bsDel(account->email); bsDel(account->username); free(account); }
void postDel(Post *post) { bsDel(post->body); free(post); }
void sessionDel(Session *session) { bsDel(session->sessionId); free(session); }