Skip to content

finally get pure C version working #1

Merged
merged 1 commit into from Feb 22, 2012
View
2 .gitignore
@@ -0,0 +1,2 @@
+chello/mongo-c-driver
+chello/server
View
15 chello/rakefile
@@ -0,0 +1,15 @@
+include FileUtils
+
+desc "build all"
+task :default do
+ files = "server.c users.c mongo-c-driver/src/*.c"
+ sh "gcc #{files} -o server -O3 -Imongo-c-driver/src -lmicrohttpd --std=c99"
+end
+
+desc "install dependencies"
+task :install do
+ sh "brew install libmicrohttpd"
+ sh "git clone https://github.com/mongodb/mongo-c-driver"
+ cd "mongo-c-driver"
+ sh "git checkout v0.4"
+end
View
113 chello/server.c
@@ -0,0 +1,113 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "users.h"
+#include <microhttpd.h>
+
+static mongo conn[1];
+
+#define append(s, l) \
+ if(len + l + 1 > cap) {\
+ cap = cap * 2 + l;\
+ buf = realloc(buf, cap);\
+ }\
+ strcpy(buf + len, s);\
+ len += l;
+
+static void render_index(struct MHD_Connection* http_conn, User* users, int users_len) {
+ static const char* init =
+ "<!DOCTYPE html><html><head><title>C Hello</title></head>"
+ "<body><h1>Home#index</h1>";
+ static char* finl =
+ "</body></html>\r\n";
+
+ int i;
+ size_t len = 0;
+ size_t cap = 300;
+ char* buf = (char*)malloc(cap * sizeof(char));
+ struct MHD_Response* resp;
+
+ append(init, strlen(init));
+ for(i = 0; i < users_len; i++) {
+ append("<h3>", 4);
+ if(users[i].name){
+ append(users[i].name, users[i].name_len);
+ }
+ append("</h3>", 5);
+ append("<p>", 3);
+ if(users[i].bio){
+ append(users[i].bio, users[i].bio_len);
+ }
+ append("</p>", 4);
+ }
+ append(finl, strlen(finl));
+
+ resp = MHD_create_response_from_data(len, buf, MHD_NO, MHD_NO);
+ MHD_queue_response(http_conn, MHD_HTTP_OK, resp);
+ MHD_destroy_response(resp);
+ free(buf);
+}
+
+static int serve(void *cls, struct MHD_Connection* http_conn,
+ const char* url, const char* method,
+ const char* version, const char* upload_data,
+ size_t* upload_data_size, void** ptr) {
+
+ // first time only headers are valid
+ static int dummy;
+ if (&dummy != *ptr) {
+ *ptr = &dummy;
+ return MHD_YES;
+ }
+
+ if (strcmp(method, "GET") == 0) {
+ User users[100];
+ int len = users_search(conn, users, 100);
+ render_index(http_conn, users, len);
+ users_free(users, len);
+ return MHD_YES;
+ } else {
+ return MHD_NO;
+ }
+}
+
+int main(int argc, char const *argv[]) {
+ struct MHD_Daemon* d;
+ int port;
+ long long status;
+
+ if (argc != 2) {
+ printf("usage: ./server <port>\n");
+ return 1;
+ } else {
+ port = atoi(argv[1]);
+ if (port <= 0 || port > 65535) {
+ printf("port should be ranged in 1-65535\n");
+ return 1;
+ }
+ }
+
+ status = mongo_connect(conn, "127.0.0.1", 27017);
+ if(status != MONGO_OK) {
+ printf("failed to connect mongo\n");
+ exit(-1);
+ }
+
+ // install int actions
+ // action.sa_handler = finalize;
+ // sigemptyset(&action.sa_mask);
+ // action.sa_flags = 0;
+ // sigaction (SIGINT, &action, NULL);
+
+ d = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION, 8080, NULL, NULL,
+ &serve, NULL, MHD_OPTION_END);
+ if (d != NULL) {
+ pause();
+ MHD_stop_daemon(d);
+ }
+
+ mongo_destroy(conn);
+ return 0;
+}
View
62 chello/users.c
@@ -0,0 +1,62 @@
+#include <string.h>
+#include <stdlib.h>
+#include <mongo.h>
+#include "users.h"
+
+static char* new_str(const char* str, int len) {
+ char* new_s = (char*)malloc(len);
+ strcpy(new_s, str);
+ return new_s;
+}
+
+static const char* get_field_value(bson_iterator* iterator, mongo_cursor* cursor, char* field) {
+ if(bson_find(iterator, mongo_cursor_bson(cursor), field)) {
+ return bson_iterator_string(iterator);
+ }else{
+ return NULL;
+ }
+}
+
+int users_search(mongo* conn, User* users, int limit) {
+ int pos = 0;
+ mongo_cursor cursor[1];
+ bson_iterator iterator[1];
+ mongo_cursor_init(cursor, conn, "ruby-mongo-console.users");
+ // mongo_cursor_set_query
+ mongo_cursor_set_limit(cursor, limit);
+
+ while(mongo_cursor_next(cursor) == MONGO_OK) {
+ const char* s;
+
+ s = get_field_value(iterator, cursor, "name");
+ if (s) {
+ users[pos].name_len = strlen(s);
+ users[pos].name = new_str(s, users[pos].name_len);
+ } else {
+ users[pos].name_len = 0;
+ users[pos].name = NULL;
+ }
+
+ s = get_field_value(iterator, cursor, "bio");
+ if (s) {
+ users[pos].bio_len = strlen(s);
+ users[pos].bio = new_str(s, users[pos].bio_len);
+ } else {
+ users[pos].bio_len = 0;
+ users[pos].bio = NULL;
+ }
+
+ pos++;
+ }
+
+ mongo_cursor_destroy(cursor);
+ return pos;
+}
+
+void users_free(User* users, int count) {
+ int i;
+ for(i = 0; i < count; i++) {
+ free(users[i].name);
+ free(users[i].bio);
+ }
+}
View
13 chello/users.h
@@ -0,0 +1,13 @@
+#include <mongo.h>
+
+typedef struct {
+ char* name;
+ int name_len;
+ char* bio;
+ int bio_len;
+} User;
+
+// return len
+int users_search(mongo* conn, User* users, int count);
+
+void users_free(User* users, int count);
Something went wrong with that request. Please try again.