chesterpolo / mongoose

Automatically exported from code.google.com/p/mongoose
MIT License
0 stars 0 forks source link

[ENHANCEMENT] Enable convenient access to the URL segments #115

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Mongoose is QUITE nice: one thing I really wanted was a clean way to
extract the URL segments. An example would be a url like
/product/1/picture/4: I wanted a clean way of extracting one of the bits
and pieces. Since this url is stored in request_info.uri, the usage I'd
like to see is:

mg_url_element * url = mg_parse_url(request_info); // parses into a linked
list (list members allocated with malloc)
mg_url_element * pos = mg_get_url_element_at(url, 4); // retrieves the 4th
segment (4) or NULL if there are not that many segments: its using a
1-based index
mg_url_free(url); // recursively free()'s the allocated list members

Each mg_url_element has an element pointer, which is the text string for
that segment, a position, which is used by mg_get_url_element_at(), and a
pointer to the next segment (which is null if this is the last segment).

Not sure what the best way of doing this is, but its comparatively small so
I'll just dump the diff -u output inline:

+++ mongoose.h  Fri Jan 08 07:12:50 2010
@@ -242,6 +242,31 @@
  */
 void mg_show_usage_string(FILE *fp);

+/*
+ * Used to contain the decomposed parts of a URL.
+ */
+struct mg_url_element
+{
+       char * element;
+       unsigned int position;
+       struct mg_url_element * next;
+};
+
+/*
+ * Deconstruct the URL into its component parts.
+ */
+struct mg_url_element * mg_parse_url(const struct mg_request_info * req);
+
+/*
+ * Fetch a specific position, or null if its not set
+ */
+struct mg_url_element * mg_get_url_element_at(struct mg_url_element *
root, int position);
+
+/*
+ * Free the deconstructed URL.
+ */
+void mg_free_parsed_url(struct mg_url_element * elements);
+

--- ..\..\..\..\..\..\Desktop\mongoose\mongoose\mongoose.c      Wed Jul 08
17:08:24 2009
+++ mongoose.c  Thu Jan 14 02:16:07 2010
@@ -46,7 +46,9 @@
 #include <stdio.h>

 #if defined(_WIN32)            /* Windows specific #includes and #defines */
+#ifndef _WIN32_WINNT
 #define        _WIN32_WINNT    0x0400  /* To make it link in VS2005 */
+#endif
 #include <windows.h>

 #ifndef _WIN32_WCE
@@ -98,6 +100,7 @@
 #define UINT64_FMT             "I64"

 #define        SHUT_WR                 1
+#define strtok_r               strtok_s
 #define        snprintf                _snprintf
 #define        vsnprintf               _vsnprintf
 #define        sleep(x)                Sleep((x) * 1000)
@@ -4726,4 +4729,61 @@
        start_thread(ctx, (mg_thread_func_t) master_thread, ctx);

        return (ctx);
+}
+
+/*
+ * Deconstruct the URL into its component parts.
+ */
+struct mg_url_element * mg_parse_url(const struct mg_request_info * req)
+{
+       struct mg_url_element * root = NULL, * current = NULL;
+       char * piece, * save_ptr = NULL;
+       int i = strlen(req->uri)+1, j = 1;
+       char * uri;
+       uri = (char *)malloc(sizeof(char) * i);
+
+       snprintf(uri, i, "%s", req->uri);
+       piece = strtok_r(uri, "/", &save_ptr);
+       while(piece != NULL){
+               if(current == NULL){
+                       current = (struct mg_url_element
*)malloc(sizeof(struct mg_url_element));
+               }else{
+                       current->next = (struct mg_url_element
*)malloc(sizeof(struct mg_url_element));
+                       current = current->next;
+               }
+               current->next = NULL;
+               i = strlen(piece)+1;
+               current->element = (char *)malloc(i*sizeof(char));
+               snprintf(current->element, i, "%s", piece);
+               current->position = j;
+               ++j;
+               if(root == NULL) root = current;
+               piece = strtok_r(NULL, "/", &save_ptr);
+       }
+       free(uri);
+       return root;
+}
+
+struct mg_url_element * mg_get_url_element_at(struct mg_url_element *
root, int position)
+{
+       struct mg_url_element * next = root;
+       while(next != NULL){
+               if(next->position == position) break;
+               next = next->next;
+       }
+       return next;
+}
+
+/*
+ * Free the deconstructed URL.
+ */
+void mg_free_parsed_url(struct mg_url_element * elements)
+{
+       struct mg_url_element * next = elements, * component;
+       while(next != NULL){
+               component = next;
+               next = component->next;
+               free(component->element);
+               free(component);
+       }
 }

I'm using this now and it appears to work fine: as always, corrections
would be appreciated.

This is NOT a Defect: unfortunately googlecode's issue system only allows
items to be described as defects, as opposed to requests for enhancement.

Thanks for putting together quite so smashing an interface: embedding this
is a dream compared to most other libraries I've seen.

Original issue reported on code.google.com by fomoj...@gmail.com on 14 Jan 2010 at 4:38

GoogleCodeExporter commented 9 years ago
Not sure this functionality is general enough to be included in the codebase.
Also, please mind the bindings to other languages like C# and Python. Exporting 
things 
like linked lists could be tricky. That is why in the API I am trying to use 
most basic 
types like integer and strings.

Original comment by valenok on 24 Feb 2010 at 9:23