From cc0044c4eed174e30a6197a24db43cfd61a20613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= Date: Tue, 3 Aug 2010 15:25:08 +0200 Subject: [PATCH] Fix http method parser, add inlined g_string_append_len --- include/lighttpd/lighttpd-glue.h | 2 +- include/lighttpd/utils.h | 20 ++++++++- src/main/http_request_parser.rl | 2 +- src/main/lighttpd-glue.c | 74 +++++++++++++++++++++----------- src/modules/mod_progress.c | 2 +- 5 files changed, 71 insertions(+), 29 deletions(-) diff --git a/include/lighttpd/lighttpd-glue.h b/include/lighttpd/lighttpd-glue.h index f63daa0..81c2e32 100644 --- a/include/lighttpd/lighttpd-glue.h +++ b/include/lighttpd/lighttpd-glue.h @@ -8,7 +8,7 @@ /* returns the description for a given http status code and sets the len to the length of the returned string */ LI_API gchar *li_http_status_string(guint status_code, guint *len); /* returns the liHttpMethod enum entry matching the given string */ -LI_API liHttpMethod li_http_method_from_string(gchar *method_str); +LI_API liHttpMethod li_http_method_from_string(const gchar *method_str, gssize len); /* returns the http method as a string and sets len to the length of the returned string */ LI_API gchar *li_http_method_string(liHttpMethod method, guint *len); /* returns the http version as a string and sets len to the length of the returned string */ diff --git a/include/lighttpd/utils.h b/include/lighttpd/utils.h index 10bff0f..a672e60 100644 --- a/include/lighttpd/utils.h +++ b/include/lighttpd/utils.h @@ -102,6 +102,9 @@ LI_API gsize li_dirent_buf_size(DIR * dirp); LI_API void li_apr_sha1_base64(GString *dest, const GString *passwd); +INLINE GString* _li_g_string_append_len(GString *s, const gchar *val, gssize len); +INLINE void li_g_string_clear(GString *s); + /* error log helper functions */ #define LI_REMOVE_PATH_FROM_FILE 1 LI_API const char *li_remove_path(const char *path); @@ -120,8 +123,6 @@ LI_API GQuark li_sys_error_quark(); LI_API gboolean _li_set_sys_error(GError **error, const gchar *msg, const gchar *file, int lineno); -#endif - /* inline implementations */ INLINE void li_path_append_slash(GString *path) { @@ -134,3 +135,18 @@ INLINE GString li_const_gstring(const gchar *str, gsize len) { GString gs = { (gchar*) str, len, 0 }; return gs; } + +#ifndef g_string_append_len +# define g_string_append_len _li_g_string_append_len +#endif + +INLINE GString* _li_g_string_append_len(GString *s, const gchar *val, gssize len) { + return g_string_insert_len(s, -1, val, len); +} + +INLINE void li_g_string_clear(GString *s) { + s->len = 0; + s->str[0] = '\0'; +} + +#endif diff --git a/src/main/http_request_parser.rl b/src/main/http_request_parser.rl index 1dda712..ae320aa 100644 --- a/src/main/http_request_parser.rl +++ b/src/main/http_request_parser.rl @@ -100,7 +100,7 @@ | "MOVE" %{ ctx->request->http_method = LI_HTTP_METHOD_MOVE; } | "PROPPATCH" %{ ctx->request->http_method = LI_HTTP_METHOD_PROPPATCH; } | "REPORT" %{ ctx->request->http_method = LI_HTTP_METHOD_REPORT; } - | "CHKECOUT" %{ ctx->request->http_method = LI_HTTP_METHOD_CHECKOUT; } + | "CHECKOUT" %{ ctx->request->http_method = LI_HTTP_METHOD_CHECKOUT; } | "CHECKIN" %{ ctx->request->http_method = LI_HTTP_METHOD_CHECKIN; } | "VERSION-CONTROL" %{ ctx->request->http_method = LI_HTTP_METHOD_VERSION_CONTROL; } | "UNCHECKOUT" %{ ctx->request->http_method = LI_HTTP_METHOD_UNCHECKOUT; } diff --git a/src/main/lighttpd-glue.c b/src/main/lighttpd-glue.c index 5a8d273..b672c92 100644 --- a/src/main/lighttpd-glue.c +++ b/src/main/lighttpd-glue.c @@ -93,7 +93,7 @@ gchar *li_http_method_string(liHttpMethod method, guint *len) { case LI_HTTP_METHOD_REPORT: SET_LEN_AND_RETURN_STR("REPORT"); case LI_HTTP_METHOD_CHECKOUT: SET_LEN_AND_RETURN_STR("CHECKOUT"); case LI_HTTP_METHOD_CHECKIN: SET_LEN_AND_RETURN_STR("CHECKIN"); - case LI_HTTP_METHOD_VERSION_CONTROL: SET_LEN_AND_RETURN_STR("VERSION_CONTROL"); + case LI_HTTP_METHOD_VERSION_CONTROL: SET_LEN_AND_RETURN_STR("VERSION-CONTROL"); case LI_HTTP_METHOD_UNCHECKOUT: SET_LEN_AND_RETURN_STR("UNCHECKOUT"); case LI_HTTP_METHOD_MKACTIVITY: SET_LEN_AND_RETURN_STR("MKACTIVITY"); case LI_HTTP_METHOD_MERGE: SET_LEN_AND_RETURN_STR("MERGE"); @@ -107,33 +107,59 @@ gchar *li_http_method_string(liHttpMethod method, guint *len) { return NULL; } -liHttpMethod li_http_method_from_string(gchar *method_str) { - if (g_str_equal(method_str, "GET")) return LI_HTTP_METHOD_GET; - else if (g_str_equal(method_str, "POST")) return LI_HTTP_METHOD_POST; - else if (g_str_equal(method_str, "HEAD")) return LI_HTTP_METHOD_HEAD; - else if (g_str_equal(method_str, "OPTIONS")) return LI_HTTP_METHOD_OPTIONS; - else if (g_str_equal(method_str, "PROPFIND")) return LI_HTTP_METHOD_PROPFIND; - else if (g_str_equal(method_str, "MKCOL")) return LI_HTTP_METHOD_MKCOL; - else if (g_str_equal(method_str, "PUT")) return LI_HTTP_METHOD_PUT; - else if (g_str_equal(method_str, "DELETE")) return LI_HTTP_METHOD_DELETE; - else if (g_str_equal(method_str, "COPY")) return LI_HTTP_METHOD_COPY; - else if (g_str_equal(method_str, "MOVE")) return LI_HTTP_METHOD_MOVE; - else if (g_str_equal(method_str, "PROPPATCH")) return LI_HTTP_METHOD_PROPPATCH; - else if (g_str_equal(method_str, "REPORT")) return LI_HTTP_METHOD_REPORT; - else if (g_str_equal(method_str, "CHECKOUT")) return LI_HTTP_METHOD_CHECKOUT; - else if (g_str_equal(method_str, "CHECKIN")) return LI_HTTP_METHOD_CHECKIN; - else if (g_str_equal(method_str, "VERSION_CONTROL")) return LI_HTTP_METHOD_VERSION_CONTROL; - else if (g_str_equal(method_str, "UNCHECKOUT")) return LI_HTTP_METHOD_UNCHECKOUT; - else if (g_str_equal(method_str, "MKACTIVITY")) return LI_HTTP_METHOD_MKACTIVITY; - else if (g_str_equal(method_str, "MERGE")) return LI_HTTP_METHOD_MERGE; - else if (g_str_equal(method_str, "LOCK")) return LI_HTTP_METHOD_LOCK; - else if (g_str_equal(method_str, "UNLOCK")) return LI_HTTP_METHOD_UNLOCK; - else if (g_str_equal(method_str, "LABEL")) return LI_HTTP_METHOD_LABEL; - else if (g_str_equal(method_str, "CONNECT")) return LI_HTTP_METHOD_CONNECT; +#define METHOD_ENUM(x) do { if (0 == strncmp(#x, method_str, len)) return LI_HTTP_METHOD_##x; } while (0) +#define METHOD_ENUM2(x, y) do { if (0 == strncmp(x, method_str, len)) return LI_HTTP_METHOD_##y; } while (0) + +liHttpMethod li_http_method_from_string(const gchar* method_str, gssize len) { + switch (len) { + case 3: + METHOD_ENUM(GET); + METHOD_ENUM(PUT); + break; + case 4: + METHOD_ENUM(POST); + METHOD_ENUM(HEAD); + METHOD_ENUM(COPY); + METHOD_ENUM(MOVE); + METHOD_ENUM(LOCK); + break; + case 5: + METHOD_ENUM(MKCOL); + METHOD_ENUM(MERGE); + METHOD_ENUM(LABEL); + break; + case 6: + METHOD_ENUM(UNLOCK); + METHOD_ENUM(DELETE); + METHOD_ENUM(REPORT); + break; + case 7: + METHOD_ENUM(OPTIONS); + METHOD_ENUM(CONNECT); + METHOD_ENUM(CHECKIN); + break; + case 8: + METHOD_ENUM(PROPFIND); + METHOD_ENUM(CHECKOUT); + break; + case 9: + METHOD_ENUM(PROPPATCH); + break; + case 10: + METHOD_ENUM(UNCHECKOUT); + METHOD_ENUM(MKACTIVITY); + break; + case 15: + METHOD_ENUM2("VERSION-CONTROL", VERSION_CONTROL); + break; + } return LI_HTTP_METHOD_UNSET; } +#undef METHOD_ENUM +#undef METHOD_ENUM2 + gchar *li_http_version_string(liHttpVersion method, guint *len) { switch (method) { case LI_HTTP_VERSION_1_1: SET_LEN_AND_RETURN_STR("HTTP/1.1"); diff --git a/src/modules/mod_progress.c b/src/modules/mod_progress.c index 699d208..07ba440 100644 --- a/src/modules/mod_progress.c +++ b/src/modules/mod_progress.c @@ -448,7 +448,7 @@ static gboolean progress_methods_parse(liServer *srv, liWorker *wrk, liPlugin *p return FALSE; } - method = li_http_method_from_string(v->data.string->str); + method = li_http_method_from_string(GSTR_LEN(v->data.string)); if (method == LI_HTTP_METHOD_UNSET) { ERROR(srv, "progress.methods: unknown method: %s", v->data.string->str); return FALSE;