diff --git a/src/include/mk_header.h b/src/include/mk_header.h
index fa62a98..40609ac 100644
--- a/src/include/mk_header.h
+++ b/src/include/mk_header.h
@@ -96,6 +96,9 @@ struct header_status_response {
 /* Accept ranges */
 #define MK_HEADER_ACCEPT_RANGES "Accept-Ranges: bytes" MK_CRLF
 
+/* Allowed methods */
+#define MK_HEADER_ALLOWED_METHODS "Allow:" MK_CRLF
+
 #define MK_HEADER_CONN_KA "Connection: Keep-Alive" MK_CRLF
 #define MK_HEADER_CONN_CLOSE "Connection: Close" MK_CRLF
 #define MK_HEADER_CONTENT_LENGTH "Content-Length: "
diff --git a/src/include/mk_http.h b/src/include/mk_http.h
index 0201fc6..3936869 100644
--- a/src/include/mk_http.h
+++ b/src/include/mk_http.h
@@ -30,12 +30,19 @@
 #define HTTP_METHOD_HEAD            2
 #define HTTP_METHOD_PUT             3
 #define HTTP_METHOD_DELETE          4
+#define HTTP_METHOD_OPTIONS         5
+
+/* Available methods */
+#define HTTP_METHOD_AVAILABLE   \
+    HTTP_METHOD_GET_STR "," HTTP_METHOD_POST_STR "," HTTP_METHOD_HEAD_STR ","  \
+    HTTP_METHOD_PUT_STR "," HTTP_METHOD_DELETE_STR "," HTTP_METHOD_OPTIONS_STR
 
 #define HTTP_METHOD_GET_STR         "GET"
 #define HTTP_METHOD_POST_STR        "POST"
 #define HTTP_METHOD_HEAD_STR        "HEAD"
 #define HTTP_METHOD_PUT_STR         "PUT"
 #define HTTP_METHOD_DELETE_STR      "DELETE"
+#define HTTP_METHOD_OPTIONS_STR     "OPTIONS"
 
 #define HTTP_PROTOCOL_UNKNOWN (-1)
 #define HTTP_PROTOCOL_09 (9)
@@ -53,6 +60,7 @@ extern const mk_pointer mk_http_method_post_p;
 extern const mk_pointer mk_http_method_head_p;
 extern const mk_pointer mk_http_method_put_p;
 extern const mk_pointer mk_http_method_delete_p;
+extern const mk_pointer mk_http_method_options_p;
 extern const mk_pointer mk_http_method_null_p;
 
 extern const mk_pointer mk_http_protocol_09_p;
diff --git a/src/include/mk_request.h b/src/include/mk_request.h
index a95c526..bd3a963 100644
--- a/src/include/mk_request.h
+++ b/src/include/mk_request.h
@@ -116,6 +116,7 @@ struct response_headers
     int connection;
 
     time_t last_modified;
+    mk_pointer allow_methods;
     mk_pointer content_type;
     mk_pointer content_encoding;
     char *location;
diff --git a/src/mk_header.c b/src/mk_header.c
index 60811de..b9a1c63 100644
--- a/src/mk_header.c
+++ b/src/mk_header.c
@@ -42,6 +42,7 @@
 const mk_pointer mk_header_short_date = mk_pointer_init(MK_HEADER_SHORT_DATE);
 const mk_pointer mk_header_short_location = mk_pointer_init(MK_HEADER_SHORT_LOCATION);
 const mk_pointer mk_header_short_ct = mk_pointer_init(MK_HEADER_SHORT_CT);
+const mk_pointer mk_header_allow = mk_pointer_init(MK_HEADER_ALLOWED_METHODS);
 
 const mk_pointer mk_header_conn_ka = mk_pointer_init(MK_HEADER_CONN_KA);
 const mk_pointer mk_header_conn_close = mk_pointer_init(MK_HEADER_CONN_CLOSE);
@@ -228,6 +229,14 @@ int mk_header_send(int fd, struct client_session *cs,
                          strlen(sh->location), mk_iov_crlf, MK_IOV_FREE_BUF);
     }
 
+    /* allowed methods */
+    if (sh->allow_methods.len > 0) {
+        mk_iov_add_entry(iov,
+                         mk_header_allow.data,
+                         mk_header_allow.len,
+                         sh->allow_methods, MK_IOV_NOT_FREE_BUF) ;
+    }
+
     /* Content type */
     if (sh->content_type.len > 0) {
         mk_iov_add_entry(iov,
diff --git a/src/mk_http.c b/src/mk_http.c
index 0f8a976..2d27228 100644
--- a/src/mk_http.c
+++ b/src/mk_http.c
@@ -51,6 +51,7 @@ const mk_pointer mk_http_method_post_p = mk_pointer_init(HTTP_METHOD_POST_STR);
 const mk_pointer mk_http_method_head_p = mk_pointer_init(HTTP_METHOD_HEAD_STR);
 const mk_pointer mk_http_method_put_p = mk_pointer_init(HTTP_METHOD_PUT_STR);
 const mk_pointer mk_http_method_delete_p = mk_pointer_init(HTTP_METHOD_DELETE_STR);
+const mk_pointer mk_http_method_options_p = mk_pointer_init(HTTP_METHOD_OPTIONS_STR);
 const mk_pointer mk_http_method_null_p = { NULL, 0 };
 
 const mk_pointer mk_http_protocol_09_p = mk_pointer_init(HTTP_PROTOCOL_09_STR);
@@ -81,6 +82,10 @@ int mk_http_method_check(mk_pointer method)
         return HTTP_METHOD_DELETE;
     }
 
+    if (strncmp(method.data, HTTP_METHOD_OPTIONS_STR, method.len) == 0) {
+        return HTTP_METHOD_OPTIONS;
+    }
+
     return HTTP_METHOD_UNKNOWN;
 }
 
@@ -89,16 +94,16 @@ mk_pointer mk_http_method_check_str(int method)
     switch (method) {
     case HTTP_METHOD_GET:
         return mk_http_method_get_p;
-
     case HTTP_METHOD_POST:
         return mk_http_method_post_p;
-
     case HTTP_METHOD_HEAD:
         return mk_http_method_head_p;
     case HTTP_METHOD_PUT:
         return mk_http_method_put_p;
     case HTTP_METHOD_DELETE:
         return mk_http_method_delete_p;
+    case HTTP_METHOD_OPTIONS:
+        return mk_http_method_options_p;
     }
     return mk_http_method_null_p;
 }
@@ -205,11 +210,11 @@ static int mk_http_range_parse(struct session_request *sr)
 int mk_http_method_get(char *body)
 {
     int int_method, pos = 0;
-    int max_len_method = 7;
+    int max_len_method = 8;
     mk_pointer method;
 
     /* Max method length is 6 (GET/POST/HEAD/PUT/DELETE) */
-    pos = mk_string_char_search(body, ' ', 7);
+    pos = mk_string_char_search(body, ' ', max_len_method);
     if (mk_unlikely(pos <= 2 || pos >= max_len_method)) {
         return HTTP_METHOD_UNKNOWN;
     }
@@ -483,6 +488,31 @@ int mk_http_init(struct client_session *cs, struct session_request *sr)
         return mk_request_error(MK_SERVER_NOT_IMPLEMENTED, cs, sr);
     }
 
+    /* counter connections */
+    sr->headers.pconnections_left = (int)
+        (config->max_keep_alive_request - cs->counter_connections);
+
+    /* Set default value */
+    mk_header_set_http_status(sr, MK_HTTP_OK);
+    sr->headers.location = NULL;
+    sr->headers.content_length = 0;
+
+    /*
+     * For OPTIONS method, we let the plugin handle it and
+     * return without any content.
+     */
+    if ( sr->method == HTTP_METHOD_OPTIONS ) {
+        sr->headers.allow_methods.data = HTTP_METHOD_AVAILABLE;
+        sr->headers.allow_methods.len = strlen(HTTP_METHOD_AVAILABLE) + 1;
+
+        mk_pointer_reset(&sr->headers.content_type);
+        mk_header_send(cs->socket, cs, sr);
+        return EXIT_NORMAL;
+    }
+    else {
+        mk_pointer_reset(&sr->headers.allow_methods);
+    }
+
     /* read permissions and check file */
     if (sr->file_info.read_access == MK_FALSE) {
         return mk_request_error(MK_CLIENT_FORBIDDEN, cs, sr);
@@ -503,11 +533,6 @@ int mk_http_init(struct client_session *cs, struct session_request *sr)
         return mk_request_error(MK_CLIENT_NOT_FOUND, cs, sr);
     }
 
-    /* counter connections */
-    sr->headers.pconnections_left = (int)
-        (config->max_keep_alive_request - cs->counter_connections);
-
-
     sr->headers.last_modified = sr->file_info.last_modification;
 
     if (sr->if_modified_since.data && sr->method == HTTP_METHOD_GET) {
@@ -525,8 +550,6 @@ int mk_http_init(struct client_session *cs, struct session_request *sr)
             return EXIT_NORMAL;
         }
     }
-    mk_header_set_http_status(sr, MK_HTTP_OK);
-    sr->headers.location = NULL;
 
     /* Object size for log and response headers */
     sr->headers.content_length = sr->file_info.size;
