Changeset: b0d4d943156d for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=b0d4d943156d Modified Files: monetdb5/mal/mal_http_daemon.c sql/backends/monet5/rest/rest_jsonstore.c sql/backends/monet5/rest/rest_jsonstore.h sql/backends/monet5/rest/rest_jsonstore_handle_get.c sql/backends/monet5/rest/rest_jsonstore_handle_get.h Branch: default Log Message:
improve http request handling and add rest functions diffs (truncated from 325 to 300 lines): diff --git a/monetdb5/mal/mal_http_daemon.c b/monetdb5/mal/mal_http_daemon.c --- a/monetdb5/mal/mal_http_daemon.c +++ b/monetdb5/mal/mal_http_daemon.c @@ -57,6 +57,29 @@ struct connection_info_struct }; static int +send_page (struct MHD_Connection *connection, const char * url, + const char * method, char *page, char * postdata) +{ + int ret; + int rest; + struct MHD_Response *response; + + rest = (*http_handler)(url, method, &page, postdata); + (void)rest; + response = + MHD_create_response_from_buffer (strlen (page), + (void *) page, + MHD_RESPMEM_MUST_COPY); + if (!response) + return MHD_NO; + + ret = MHD_queue_response (connection, MHD_HTTP_OK, response); + MHD_destroy_response (response); + + return ret; +} + +static int iterate_post (void *coninfo_cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, @@ -72,9 +95,9 @@ iterate_post (void *coninfo_cls, enum MH (void)off; if (strcmp (key, "json") == 0) - { + { if ((size > 0) && (size <= MAXNAMESIZE)) - { + { char *answerstring; answerstring = malloc (MAXANSWERSIZE); if (!answerstring) @@ -87,7 +110,7 @@ iterate_post (void *coninfo_cls, enum MH con_info->answerstring = NULL; return MHD_NO; - } + } return MHD_YES; } @@ -106,11 +129,11 @@ request_completed (void *cls, struct MHD return; if (con_info->connectiontype == POST) - { + { MHD_destroy_post_processor (con_info->postprocessor); if (con_info->answerstring) free (con_info->answerstring); - } + } free (con_info); *con_cls = NULL; @@ -122,15 +145,12 @@ answer_to_connection (void *cls, struct const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls) { - struct MHD_Response *response; - int ret; - int rest; char * page = NULL; - struct connection_info_struct *con_info = *con_cls; + struct connection_info_struct *con_info; + int *done = cls; + char *errorpage = + "<html><body>This doesn't seem to be right.</body></html>"; - (void)cls; - (void)url; - (void)method; (void)version; if (*con_cls == NULL) { @@ -142,7 +162,7 @@ answer_to_connection (void *cls, struct if (strcmp (method, "POST") == 0) { con_info->postprocessor = MHD_create_post_processor (connection, POSTBUFFERSIZE, - iterate_post, (void *) con_info); + iterate_post, (void *) con_info); if (con_info->postprocessor == NULL) { free (con_info); @@ -157,31 +177,48 @@ answer_to_connection (void *cls, struct } if (strcmp (method, "POST") == 0) { + con_info = *con_cls; if (*upload_data_size != 0) { MHD_post_process (con_info->postprocessor, upload_data, - *upload_data_size); + *upload_data_size); *upload_data_size = 0; + return MHD_YES; } else if (con_info->answerstring != NULL) { - // return send_page (connection, con_info->answerstring); - //return MHD_NO; + return send_page(connection, url, method, page, + con_info->answerstring); } } - rest = (*http_handler)(url, method, &page, con_info->answerstring); - (void)rest; - response = - MHD_create_response_from_buffer (strlen (page), (void *) page, - MHD_RESPMEM_MUST_COPY); - ret = MHD_queue_response (connection, MHD_HTTP_OK, response); - MHD_destroy_response (response); + if (strcmp (method, "PUT") == 0) { + if (*upload_data_size != 0) { + char *answerstring; + // TODO: check free answerstring + answerstring = malloc (MAXANSWERSIZE); + if (!answerstring) + return MHD_NO; - return ret; + snprintf (answerstring, MAXANSWERSIZE, "%s", upload_data); + con_info->answerstring = answerstring; + *upload_data_size = 0; + return send_page(connection, url, method, page, + con_info->answerstring); + } + *done = 1; + } + + if ((strcmp (method, "GET") == 0) || + (strcmp (method, "DELETE") == 0)) { + return send_page(connection, url, method, page, + con_info->answerstring); + } + return send_page (connection, url, method, page, errorpage); } static void handleHttpdaemon(void *dummy) { - http_daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY, PORT, NULL, NULL, - &answer_to_connection, NULL, + int done_flag = 0; + http_daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY|MHD_USE_DEBUG, PORT, NULL, NULL, + &answer_to_connection, &done_flag, MHD_OPTION_NOTIFY_COMPLETED, request_completed, NULL, MHD_OPTION_END); diff --git a/sql/backends/monet5/rest/rest_jsonstore.c b/sql/backends/monet5/rest/rest_jsonstore.c --- a/sql/backends/monet5/rest/rest_jsonstore.c +++ b/sql/backends/monet5/rest/rest_jsonstore.c @@ -103,7 +103,7 @@ mserver_browser_get(const UriUriA uri) { } else { // The first path element is a table name // we cannot check this here, so we assume the table exists - mserver_rest_command = MONETDB_REST_DB_INFO; + mserver_rest_command = MONETDB_REST_DB_GETDOCID; fprintf(stderr, "url: %s\n", uri.pathHead->text.first); } } @@ -132,6 +132,14 @@ mserver_browser_put(const UriUriA uri) { mserver_rest_command = MONETDB_REST_CREATE_DB; fprintf(stderr, "url: %s\n", uri.pathHead->text.first); } + } else { + if (strcmp(uri.pathHead->text.first, API_SPECIAL_CHAR) < 0) { + // This path element is on of the special cases + mserver_rest_command = MONETDB_REST_UNKWOWN_SPECIAL; + } else { + mserver_rest_command = MONETDB_REST_DB_UPDATE_DOC; + fprintf(stderr, "url: %s\n", uri.pathHead->text.first); + } } } else { // A absolutePath with an empty pathHead means the root url @@ -196,12 +204,24 @@ mserver_browser_post(const UriUriA uri) static char * get_dbname(UriUriA uri) { + size_t len; + char * dbname; + //len = strlen(uri.pathHead->text.first); + len = uri.pathHead->text.afterLast - uri.pathHead->text.first; + dbname = malloc(len + 1); + strncpy(dbname, uri.pathHead->text.first, len); + dbname[len] = '\0'; + return dbname; +} + +static +char * get_docid(UriUriA uri) { int len; - char * dbname; - len = strlen(uri.pathHead->text.first); - dbname = malloc(len + 1); - strcpy(dbname, uri.pathHead->text.first); - return dbname; + char * docid; + len = strlen(uri.pathHead->next->text.first); + docid = malloc(len + 1); + strcpy(docid, uri.pathHead->next->text.first); + return docid; } int @@ -211,6 +231,7 @@ handle_http_request (const char *url, co int ret; int mserver_rest_command = 0; char * dbname = NULL; + char * docid = NULL; UriParserStateA state; UriUriA uri; @@ -260,6 +281,16 @@ handle_http_request (const char *url, co dbname = get_dbname(uri); RESTdbInfo(page, dbname); break; + case MONETDB_REST_DB_GETDOCID: + dbname = get_dbname(uri); + docid = get_docid(uri); + RESTgetDoc(page, dbname, docid); + break; + case MONETDB_REST_DB_UPDATE_DOC: + dbname = get_dbname(uri); + docid = get_docid(uri); + RESTupdateDoc(page, dbname, postdata, docid); + break; default: // error, unknown command ret = 1; diff --git a/sql/backends/monet5/rest/rest_jsonstore.h b/sql/backends/monet5/rest/rest_jsonstore.h --- a/sql/backends/monet5/rest/rest_jsonstore.h +++ b/sql/backends/monet5/rest/rest_jsonstore.h @@ -44,6 +44,8 @@ #define MONETDB_REST_NO_PARAMETER_ALLOWED 8 #define MONETDB_REST_MISSING_DATABASENAME 9 #define MONETDB_REST_POST_NEW_DOC 10 +#define MONETDB_REST_DB_GETDOCID 11 +#define MONETDB_REST_DB_UPDATE_DOC 12 #define MONETDB_REST_PATH_ALLDBS "_all_dbs" #define MONETDB_REST_PATH_UUIDS "_uuids" diff --git a/sql/backends/monet5/rest/rest_jsonstore_handle_get.c b/sql/backends/monet5/rest/rest_jsonstore_handle_get.c --- a/sql/backends/monet5/rest/rest_jsonstore_handle_get.c +++ b/sql/backends/monet5/rest/rest_jsonstore_handle_get.c @@ -89,7 +89,7 @@ str RESTwelcome(char **result) str RESTallDBs(char **result) { str msg = MAL_SUCCEED; - char * querytext = "select substring(name, 6, length(name) -5) from tables where name like 'json_%';"; + char * querytext = "select substring(name, 6, length(name) -5) as name from tables where name like 'json_%';"; msg = RESTsqlQuery(result, querytext); return msg; } @@ -143,7 +143,7 @@ str RESTdeleteDB(char ** result, char * str RESTcreateDoc(char ** result, char * dbname, const char * doc) { str msg = MAL_SUCCEED; - int len = strlen(dbname) + 32 + strlen(doc)+ 72; + size_t len = strlen(dbname) + 2 * strlen(doc)+ 78; char * querytext = NULL; querytext = malloc(len); @@ -174,3 +174,39 @@ str RESTdbInfo(char **result, char * dbn } return msg; } + +str RESTgetDoc(char ** result, char * dbname, const char * doc_id) +{ + str msg = MAL_SUCCEED; + size_t len = strlen(dbname) + strlen(doc_id) + 36; + char * querytext = NULL; + + querytext = malloc(len); + snprintf(querytext, len, "SELECT * FROM json_%s WHERE _id = '%s';", dbname, doc_id); + + msg = RESTsqlQuery(result, querytext); + if (querytext != NULL) { + free(querytext); + } + return msg; + +} + +str RESTupdateDoc(char ** result, char * dbname, const char * doc, const char * doc_id) +{ + str msg = MAL_SUCCEED; + size_t len = strlen(doc_id) + strlen(dbname) + 2 * strlen(doc) + 74; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org http://mail.monetdb.org/mailman/listinfo/checkin-list