feat: fully support redirect & paste routes
	
		
			
	
		
	
	
		
			
				
	
				ci/woodpecker/pr/woodpecker Pipeline failed
				
					Details
				
			
		
	
				
					
				
			
				
	
				ci/woodpecker/pr/woodpecker Pipeline failed
				
					Details
				
			
		
	
							parent
							
								
									58e2d8a02e
								
							
						
					
					
						commit
						a6257a923d
					
				|  | @ -16,9 +16,9 @@ http_route lander_routes[] = { | |||
|      .path = "^/s\\(l\\?\\)/\\([^/]*\\)$", | ||||
|      .steps = {http_loop_step_auth, http_loop_step_body_to_buf, | ||||
|                lander_post_redirect, NULL}}, | ||||
|     {.type = http_route_literal, | ||||
|     {.type = http_route_regex, | ||||
|      .method = http_post, | ||||
|      .path = "/p/", | ||||
|      .path = "^/p\\(l\\?\\)/\\([^/]*\\)$", | ||||
|      .steps = {http_loop_step_auth, lander_post_paste, | ||||
|                http_loop_step_body_to_file, http_loop_step_switch_res, NULL}}, | ||||
| }; | ||||
|  |  | |||
|  | @ -2,12 +2,63 @@ | |||
| #include "lander.h" | ||||
| #include "log.h" | ||||
| 
 | ||||
| bool lander_post_redirect(event_loop_conn *conn) { | ||||
|   http_loop_ctx *ctx = conn->ctx; | ||||
| 
 | ||||
| // TODO entry leaks if key is already present
 | ||||
| static bool add_entry(char **key_ptr, int *key_len_ptr, http_loop_ctx *ctx, | ||||
|                       Entry *entry, bool random) { | ||||
|   // The first match group matches the "long" path
 | ||||
|   bool secure = | ||||
|       (ctx->req.regex_groups[1].rm_eo - ctx->req.regex_groups[1].rm_so) == 1; | ||||
| 
 | ||||
|   char *key; | ||||
|   int key_len = 0; | ||||
|   TrieExitCode res; | ||||
| 
 | ||||
|   if (random) { | ||||
|     res = trie_add_random(ctx->g->trie, &key, entry, secure); | ||||
| 
 | ||||
|     if (res == Ok) { | ||||
|       key_len = strlen(key); | ||||
|     } | ||||
|   } else { | ||||
|     key = (char *)&ctx->req.path[ctx->req.regex_groups[2].rm_so]; | ||||
|     key_len = ctx->req.regex_groups[2].rm_eo - ctx->req.regex_groups[2].rm_so; | ||||
| 
 | ||||
|     res = trie_add_len(ctx->g->trie, key, key_len, entry); | ||||
|   } | ||||
| 
 | ||||
|   switch (res) { | ||||
|   case Ok: | ||||
|     break; | ||||
|   case AlreadyPresent: | ||||
|     ctx->res.status = http_conflict; | ||||
|     return false; | ||||
|   default: | ||||
|     ctx->res.status = http_internal_server_error; | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   // Add a slash to the key and add it as the location header
 | ||||
|   char *buf = malloc(key_len + 2); | ||||
| 
 | ||||
|   memcpy(&buf[1], key, key_len); | ||||
|   buf[0] = '/'; | ||||
|   buf[key_len + 1] = '\0'; | ||||
| 
 | ||||
|   http_res_add_header(&ctx->res, http_header_location, buf, true); | ||||
| 
 | ||||
|   if (key_ptr != NULL) { | ||||
|     *key_ptr = key; | ||||
|   } | ||||
| 
 | ||||
|   if (key_len_ptr != NULL) { | ||||
|     *key_len_ptr = key_len; | ||||
|   } | ||||
| 
 | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| bool lander_post_redirect(event_loop_conn *conn) { | ||||
|   http_loop_ctx *ctx = conn->ctx; | ||||
|   bool random = | ||||
|       ctx->req.regex_groups[2].rm_eo == ctx->req.regex_groups[2].rm_so; | ||||
| 
 | ||||
|  | @ -18,60 +69,18 @@ bool lander_post_redirect(event_loop_conn *conn) { | |||
| 
 | ||||
|   Entry *new_entry = entry_new(Redirect, url); | ||||
| 
 | ||||
|   // The entry duplicates the string
 | ||||
|   free(url); | ||||
| 
 | ||||
|   // We don't check the result here, because we would perform the same action
 | ||||
|   // either way
 | ||||
|   char *key; | ||||
|   int key_len; | ||||
| 
 | ||||
|   if (random) { | ||||
|     TrieExitCode res = trie_add_random(ctx->g->trie, &key, new_entry, secure); | ||||
| 
 | ||||
|     if (res != Ok) { | ||||
|       error("trie_add_random failed with exit code %i", res); | ||||
| 
 | ||||
|       ctx->res.status = http_internal_server_error; | ||||
|       conn->state = event_loop_conn_state_res; | ||||
| 
 | ||||
|       return true; | ||||
|     } | ||||
| 
 | ||||
|     key_len = strlen(key); | ||||
|   } else { | ||||
|     key = (char *)&ctx->req.path[ctx->req.regex_groups[2].rm_so]; | ||||
|     key_len = ctx->req.regex_groups[2].rm_eo - ctx->req.regex_groups[2].rm_so; | ||||
| 
 | ||||
|     TrieExitCode res = trie_add_len(ctx->g->trie, key, key_len, new_entry); | ||||
| 
 | ||||
|     switch (res) { | ||||
|     case Ok: | ||||
|       break; | ||||
|     case AlreadyPresent: | ||||
|       ctx->res.status = http_conflict; | ||||
|       break; | ||||
|     default: | ||||
|       ctx->res.status = http_internal_server_error; | ||||
|     } | ||||
| 
 | ||||
|     if (res != Ok) { | ||||
|       error("trie_add_len failed with exit code %i", res); | ||||
| 
 | ||||
|       conn->state = event_loop_conn_state_res; | ||||
| 
 | ||||
|       return true; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Add a slash to the key and add it as the location header
 | ||||
|   char *buf = malloc(key_len + 2); | ||||
| 
 | ||||
|   memcpy(&buf[1], key, key_len); | ||||
|   buf[0] = '/'; | ||||
|   buf[key_len + 1] = '\0'; | ||||
|   add_entry(&key, NULL, ctx, new_entry, random); | ||||
| 
 | ||||
|   if (random) { | ||||
|     free(key); | ||||
|   } | ||||
| 
 | ||||
|   http_res_add_header(&ctx->res, http_header_location, buf, true); | ||||
| 
 | ||||
|   conn->state = event_loop_conn_state_res; | ||||
| 
 | ||||
|   return true; | ||||
|  | @ -79,37 +88,28 @@ bool lander_post_redirect(event_loop_conn *conn) { | |||
| 
 | ||||
| bool lander_post_paste(event_loop_conn *conn) { | ||||
|   http_loop_ctx *ctx = conn->ctx; | ||||
|   bool random = | ||||
|       ctx->req.regex_groups[2].rm_eo == ctx->req.regex_groups[2].rm_so; | ||||
| 
 | ||||
|   char *key; | ||||
|   int key_len; | ||||
|   Entry *new_entry = entry_new(Paste, ""); | ||||
|   TrieExitCode res = trie_add_random(ctx->g->trie, &key, new_entry, false); | ||||
| 
 | ||||
|   if (res != Ok) { | ||||
|     error("trie_add_random failed with exit code %i", res); | ||||
| 
 | ||||
|     ctx->res.status = http_internal_server_error; | ||||
|   if (!add_entry(&key, &key_len, ctx, new_entry, random)) { | ||||
|     conn->state = event_loop_conn_state_res; | ||||
| 
 | ||||
|     return true; | ||||
|   } | ||||
| 
 | ||||
|   // Add a slash to the key and add it as the location header
 | ||||
|   size_t key_len = strlen(key); | ||||
|   char *buf = malloc(key_len + 2); | ||||
| 
 | ||||
|   memcpy(&buf[1], key, key_len); | ||||
|   buf[0] = '/'; | ||||
|   buf[key_len + 1] = '\0'; | ||||
| 
 | ||||
|   http_res_add_header(&ctx->res, http_header_location, buf, true); | ||||
| 
 | ||||
|   // TODO free this
 | ||||
|   char *fname = malloc(8 + key_len); | ||||
|   sprintf(fname, "pastes/%s", key); | ||||
|   sprintf(fname, "pastes/%.*s", key_len, key); | ||||
| 
 | ||||
|   ctx->req.body_file_name = fname; | ||||
| 
 | ||||
|   free(key); | ||||
|   if (random) { | ||||
|     free(key); | ||||
|   } | ||||
| 
 | ||||
|   return true; | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue