feat(lsm): require changes to be committed before writing to persistent
storagefeature/50-one-time-keys
							parent
							
								
									d64fec048f
								
							
						
					
					
						commit
						3dce25239b
					
				|  | @ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 
 | ||||
| ## [Unreleased](https://git.rustybever.be/Chewing_Bever/lander/src/branch/dev) | ||||
| 
 | ||||
| ## Fixed | ||||
| 
 | ||||
| * Failed uploads now no longer leave behind a partial entry file | ||||
| 
 | ||||
| ## [0.2.1](https://git.rustybever.be/Chewing_Bever/lander/src/tag/0.2.1) | ||||
| 
 | ||||
| ### Added | ||||
|  |  | |||
|  | @ -51,6 +51,8 @@ lnm_http_step_err lander_post_paste_secure(lnm_http_conn *conn); | |||
| 
 | ||||
| lnm_http_step_err lander_stream_body_to_entry(lnm_http_conn *conn); | ||||
| 
 | ||||
| lnm_http_step_err lander_commit_entry(lnm_http_conn *conn); | ||||
| 
 | ||||
| lnm_http_step_err lander_post_redirect_body_to_attr(lnm_http_conn *conn); | ||||
| 
 | ||||
| lnm_http_step_err lander_remove_entry(lnm_http_conn *conn); | ||||
|  |  | |||
|  | @ -159,6 +159,15 @@ lsm_error lsm_store_open_read(lsm_entry_handle **out, lsm_store *store, | |||
| lsm_error lsm_store_open_write(lsm_entry_handle **out, lsm_store *store, | ||||
|                                const lsm_str *key); | ||||
| 
 | ||||
| /**
 | ||||
|  * Commit any changes to the persistent storage. Any changes, insertions or | ||||
|  * deletions that occured without a commit are reverted when the handle is | ||||
|  * closed. | ||||
|  * | ||||
|  * @param handle handle to the entry | ||||
|  */ | ||||
| lsm_error lsm_entry_commit(lsm_entry_handle *handle); | ||||
| 
 | ||||
| /**
 | ||||
|  * Close an open entry handle. | ||||
|  * | ||||
|  |  | |||
|  | @ -157,7 +157,8 @@ lsm_error lsm_entry_data_open_read(lsm_entry_handle *handle); | |||
| lsm_error lsm_entry_data_open_write(lsm_entry_handle *handle); | ||||
| 
 | ||||
| /**
 | ||||
|  * Remove the entry's data file if present and close its handle. | ||||
|  * Remove the entry's data file if present and close its handle. Any uncommitted | ||||
|  * changes will be reverted. | ||||
|  * | ||||
|  * @param handle handle to the entry | ||||
|  */ | ||||
|  |  | |||
|  | @ -58,31 +58,42 @@ lsm_error lsm_entry_handle_init(lsm_entry_handle **out) { | |||
|   return lsm_error_ok; | ||||
| } | ||||
| 
 | ||||
| void lsm_entry_close(lsm_entry_handle *handle) { | ||||
|   if (handle->f != NULL) { | ||||
|     fclose(handle->f); | ||||
|   } | ||||
| 
 | ||||
|   bool state_new = handle->states & lsm_entry_handle_state_new; | ||||
|   bool state_removed = handle->states & lsm_entry_handle_state_removed; | ||||
|   /* bool state_updated = handle->states & lsm_entry_handle_state_updated; */ | ||||
| lsm_error lsm_entry_commit(lsm_entry_handle *handle) { | ||||
|   uint8_t state_new = handle->states & lsm_entry_handle_state_new; | ||||
|   uint8_t state_removed = handle->states & lsm_entry_handle_state_removed; | ||||
| 
 | ||||
|   // Clean new entry
 | ||||
|   if (state_new && !state_removed) { | ||||
|     lsm_entry_disk_insert(handle); | ||||
|   } | ||||
|   // New entry that was removed before being written to disk; only its data file
 | ||||
|   // needs to be removed if present
 | ||||
|   else if (state_new && state_removed) { | ||||
|     lsm_entry_data_remove(handle); | ||||
| 
 | ||||
|     lsm_entry_free(handle->wrapper->entry); | ||||
|     handle->wrapper->entry = NULL; | ||||
|     LSM_RES(lsm_entry_disk_insert(handle)); | ||||
|   } | ||||
|   // Previously stored entry that needs to be removed; should be removed from db
 | ||||
|   // file as well
 | ||||
|   else if (state_removed && !state_new) { | ||||
|     lsm_entry_disk_remove(handle); | ||||
|     LSM_RES(lsm_entry_disk_remove(handle)); | ||||
| 
 | ||||
|     lsm_entry_free(handle->wrapper->entry); | ||||
|     handle->wrapper->entry = NULL; | ||||
|   } | ||||
| 
 | ||||
|   // Reset states after committing current changes
 | ||||
|   handle->states = 0; | ||||
| 
 | ||||
|   return lsm_error_ok; | ||||
| } | ||||
| 
 | ||||
| void lsm_entry_close(lsm_entry_handle *handle) { | ||||
|   if (handle->f != NULL) { | ||||
|     fclose(handle->f); | ||||
|     handle->f = NULL; | ||||
|   } | ||||
| 
 | ||||
|   uint8_t state_new = handle->states & lsm_entry_handle_state_new; | ||||
|   /* bool state_updated = handle->states & lsm_entry_handle_state_updated; */ | ||||
| 
 | ||||
|   // New entries create a wrapper in the trie that should be removed if not
 | ||||
|   // committed
 | ||||
|   if (state_new) { | ||||
|     lsm_entry_data_remove(handle); | ||||
| 
 | ||||
|     lsm_entry_free(handle->wrapper->entry); | ||||
|     handle->wrapper->entry = NULL; | ||||
|  | @ -328,7 +339,6 @@ lsm_error lsm_entry_data_open_read(lsm_entry_handle *handle) { | |||
|   return lsm_error_ok; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| lsm_error lsm_entry_data_remove(lsm_entry_handle *handle) { | ||||
|   const lsm_entry *entry = handle->wrapper->entry; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| #include <string.h> | ||||
| 
 | ||||
| #include "lnm/http/loop.h" | ||||
| #include "lnm/log.h" | ||||
| #include "lnm/loop.h" | ||||
| 
 | ||||
| #include "lander.h" | ||||
|  | @ -25,3 +26,12 @@ lnm_http_step_err lander_stream_body_to_entry(lnm_http_conn *conn) { | |||
|              ? lnm_http_step_err_done | ||||
|              : lnm_http_step_err_io_needed; | ||||
| } | ||||
| 
 | ||||
| lnm_http_step_err lander_commit_entry(lnm_http_conn *conn) { | ||||
|   lnm_http_loop_ctx *ctx = conn->ctx; | ||||
|   lander_ctx *c_ctx = ctx->c; | ||||
| 
 | ||||
|   lsm_entry_commit(c_ctx->entry); | ||||
| 
 | ||||
|   return lnm_http_step_err_done; | ||||
| } | ||||
|  |  | |||
							
								
								
									
										11
									
								
								src/main.c
								
								
								
								
							
							
						
						
									
										11
									
								
								src/main.c
								
								
								
								
							|  | @ -3,6 +3,7 @@ | |||
| #include <time.h> | ||||
| 
 | ||||
| #include "lnm/http/loop.h" | ||||
| #include "lnm/http/route.h" | ||||
| #include "lnm/log.h" | ||||
| 
 | ||||
| #include "lander.h" | ||||
|  | @ -30,54 +31,64 @@ lnm_http_loop *loop_init(lander_gctx *gctx, const char *api_key) { | |||
|   lnm_http_router_add(&route, router, lnm_http_method_delete, "/:key"); | ||||
|   lnm_http_route_step_append(route, lnm_http_loop_step_auth, false); | ||||
|   lnm_http_route_step_append(route, lander_remove_entry, false); | ||||
|   lnm_http_route_step_append(route, lander_commit_entry, true); | ||||
| 
 | ||||
|   lnm_http_router_add(&route, router, lnm_http_method_post, "/s/"); | ||||
|   lnm_http_route_step_append(route, lnm_http_loop_step_auth, false); | ||||
|   lnm_http_route_step_append(route, lander_post_redirect, false); | ||||
|   lnm_http_route_step_append(route, lnm_http_loop_step_body_to_buf, false); | ||||
|   lnm_http_route_step_append(route, lander_post_redirect_body_to_attr, false); | ||||
|   lnm_http_route_step_append(route, lander_commit_entry, true); | ||||
| 
 | ||||
|   lnm_http_router_add(&route, router, lnm_http_method_post, "/sl/"); | ||||
|   lnm_http_route_step_append(route, lnm_http_loop_step_auth, false); | ||||
|   lnm_http_route_step_append(route, lander_post_redirect_secure, false); | ||||
|   lnm_http_route_step_append(route, lnm_http_loop_step_body_to_buf, false); | ||||
|   lnm_http_route_step_append(route, lander_post_redirect_body_to_attr, false); | ||||
|   lnm_http_route_step_append(route, lander_commit_entry, true); | ||||
| 
 | ||||
|   lnm_http_router_add(&route, router, lnm_http_method_post, "/s/:key"); | ||||
|   lnm_http_route_step_append(route, lnm_http_loop_step_auth, false); | ||||
|   lnm_http_route_step_append(route, lander_post_redirect, false); | ||||
|   lnm_http_route_step_append(route, lnm_http_loop_step_body_to_buf, false); | ||||
|   lnm_http_route_step_append(route, lander_post_redirect_body_to_attr, false); | ||||
|   lnm_http_route_step_append(route, lander_commit_entry, true); | ||||
| 
 | ||||
|   lnm_http_router_add(&route, router, lnm_http_method_post, "/p/"); | ||||
|   lnm_http_route_step_append(route, lnm_http_loop_step_auth, false); | ||||
|   lnm_http_route_step_append(route, lander_post_paste, false); | ||||
|   lnm_http_route_step_append(route, lander_stream_body_to_entry, false); | ||||
|   lnm_http_route_step_append(route, lander_commit_entry, true); | ||||
| 
 | ||||
|   lnm_http_router_add(&route, router, lnm_http_method_post, "/pl/"); | ||||
|   lnm_http_route_step_append(route, lnm_http_loop_step_auth, false); | ||||
|   lnm_http_route_step_append(route, lander_post_paste_secure, false); | ||||
|   lnm_http_route_step_append(route, lander_stream_body_to_entry, false); | ||||
|   lnm_http_route_step_append(route, lander_commit_entry, true); | ||||
| 
 | ||||
|   lnm_http_router_add(&route, router, lnm_http_method_post, "/p/:key"); | ||||
|   lnm_http_route_step_append(route, lnm_http_loop_step_auth, false); | ||||
|   lnm_http_route_step_append(route, lander_post_paste, false); | ||||
|   lnm_http_route_step_append(route, lander_stream_body_to_entry, false); | ||||
|   lnm_http_route_step_append(route, lander_commit_entry, true); | ||||
| 
 | ||||
|   lnm_http_router_add(&route, router, lnm_http_method_post, "/f/"); | ||||
|   lnm_http_route_step_append(route, lnm_http_loop_step_auth, false); | ||||
|   lnm_http_route_step_append(route, lander_post_file, false); | ||||
|   lnm_http_route_step_append(route, lander_stream_body_to_entry, false); | ||||
|   lnm_http_route_step_append(route, lander_commit_entry, true); | ||||
| 
 | ||||
|   lnm_http_router_add(&route, router, lnm_http_method_post, "/fl/"); | ||||
|   lnm_http_route_step_append(route, lnm_http_loop_step_auth, false); | ||||
|   lnm_http_route_step_append(route, lander_post_file_secure, false); | ||||
|   lnm_http_route_step_append(route, lander_stream_body_to_entry, false); | ||||
|   lnm_http_route_step_append(route, lander_commit_entry, true); | ||||
| 
 | ||||
|   lnm_http_router_add(&route, router, lnm_http_method_post, "/f/:key"); | ||||
|   lnm_http_route_step_append(route, lnm_http_loop_step_auth, false); | ||||
|   lnm_http_route_step_append(route, lander_post_file, false); | ||||
|   lnm_http_route_step_append(route, lander_stream_body_to_entry, false); | ||||
|   lnm_http_route_step_append(route, lander_commit_entry, true); | ||||
| 
 | ||||
|   lnm_http_loop_router_set(hl, router); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue