]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect/http_method: move all tests into tests/
authorVictor Julien <victor@inliniac.net>
Sun, 25 Nov 2018 15:40:49 +0000 (16:40 +0100)
committerVictor Julien <victor@inliniac.net>
Tue, 29 Jan 2019 12:27:57 +0000 (13:27 +0100)
src/Makefile.am
src/detect-engine-file.c
src/detect-engine-hmd.h [deleted file]
src/detect-engine-mpm.c
src/detect-engine-register.c
src/detect-http-method.c
src/runmode-unittests.c
src/tests/detect-http-method.c [moved from src/detect-engine-hmd.c with 69% similarity]

index 2316f3057c68d758731463b1019cea0de61cdce1..d741e01e96035cbc8cefe2c0753f0dc2dbed0382 100644 (file)
@@ -134,7 +134,6 @@ detect-engine-filedata.c detect-engine-filedata.h \
 detect-engine-hcbd.c detect-engine-hcbd.h \
 detect-engine-hcd.c detect-engine-hcd.h \
 detect-engine-hhhd.c detect-engine-hhhd.h \
-detect-engine-hmd.c detect-engine-hmd.h \
 detect-engine-hrhd.c detect-engine-hrhd.h \
 detect-engine-hrhhd.c detect-engine-hrhhd.h \
 detect-engine-hsbd.c detect-engine-hsbd.h \
index e973e1b29df054af84e4d003a6fdb0dfe9cbb500..633dac6d59abe1bf89017d3bff47a718d97037dd 100644 (file)
@@ -34,7 +34,6 @@
 
 #include "detect-engine-hcbd.h"
 #include "detect-engine-hrhd.h"
-#include "detect-engine-hmd.h"
 #include "detect-engine-hcd.h"
 #include "detect-engine-dcepayload.h"
 #include "detect-engine-file.h"
diff --git a/src/detect-engine-hmd.h b/src/detect-engine-hmd.h
deleted file mode 100644 (file)
index f5f09f2..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright (C) 2007-2010 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/** \file
- *
- * \author Anoop Saldanha <anoopsaldanha@gmail.com>
- */
-
-#ifndef __DETECT_ENGINE_HMD_H__
-#define __DETECT_ENGINE_HMD_H__
-
-#include "app-layer-htp.h"
-
-int DetectEngineInspectHttpMethod(ThreadVars *tv,
-        DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
-        const Signature *s, const SigMatchData *smd,
-        Flow *f, uint8_t flags, void *alstate, void *tx, uint64_t tx_id);
-
-int PrefilterTxMethodRegister(DetectEngineCtx *de_ctx,
-        SigGroupHead *sgh, MpmCtx *mpm_ctx);
-
-void DetectEngineHttpMethodRegisterTests(void);
-
-#endif /* __DETECT_ENGINE_HMD_H__ */
index 673465ef0f86c30178c748243216f966aba312a4..4902f5572684899adea8d6b5b924654d9a1c5927 100644 (file)
@@ -50,7 +50,6 @@
 #include "detect-content.h"
 
 #include "detect-engine-payload.h"
-#include "detect-engine-hmd.h"
 #include "detect-engine-hrhd.h"
 #include "detect-engine-hcd.h"
 #include "detect-engine-hhhd.h"
index 5aca32150e0abbc3c283be8f06a0ce9fb95b4cc3..1d3e8fced718fdb20e667c1fa18df4a938635490 100644 (file)
 #include "detect-engine-hcbd.h"
 #include "detect-engine-hsbd.h"
 #include "detect-engine-hrhd.h"
-#include "detect-engine-hmd.h"
 #include "detect-engine-hcd.h"
 #include "detect-engine-hsmd.h"
 #include "detect-engine-hscd.h"
index 8ba7c4d34b7e93339a0e3f0b3b4f0b18a195d3d2..48a96aac018e5ca09ace46eaa5a43e6e3eb43954 100644 (file)
 
 #include "app-layer-htp.h"
 #include "detect-http-method.h"
-#include "detect-engine-hmd.h"
 #include "stream-tcp.h"
 
 static int g_http_method_buffer_id = 0;
 static int DetectHttpMethodSetup(DetectEngineCtx *, Signature *, const char *);
+#ifdef UNITTESTS
 void DetectHttpMethodRegisterTests(void);
+#endif
 void DetectHttpMethodFree(void *);
 static _Bool DetectHttpMethodValidateCallback(const Signature *s, const char **sigerror);
 static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx,
@@ -79,7 +80,9 @@ void DetectHttpMethodRegister(void)
     sigmatch_table[DETECT_AL_HTTP_METHOD].url = DOC_URL DOC_VERSION "/rules/http-keywords.html#http-method";
     sigmatch_table[DETECT_AL_HTTP_METHOD].Match = NULL;
     sigmatch_table[DETECT_AL_HTTP_METHOD].Setup = DetectHttpMethodSetup;
+#ifdef UNITTESTS
     sigmatch_table[DETECT_AL_HTTP_METHOD].RegisterTests = DetectHttpMethodRegisterTests;
+#endif
     sigmatch_table[DETECT_AL_HTTP_METHOD].flags |= SIGMATCH_NOOPT;
 
     DetectAppLayerInspectEngineRegister2("http_method", ALPROTO_HTTP,
@@ -175,726 +178,9 @@ static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx,
     return buffer;
 }
 
-#ifdef UNITTESTS /* UNITTESTS */
-
-#include "detect-isdataat.h"
-#include "stream-tcp-reassemble.h"
-
-/** \test Check a signature with content */
-static int DetectHttpMethodTest01(void)
-{
-    DetectEngineCtx *de_ctx = NULL;
-    int result = 0;
-
-    if ( (de_ctx = DetectEngineCtxInit()) == NULL)
-        goto end;
-
-    de_ctx->flags |= DE_QUIET;
-    de_ctx->sig_list = SigInit(de_ctx,
-                               "alert tcp any any -> any any "
-                               "(msg:\"Testing http_method\"; "
-                               "content:\"GET\"; "
-                               "http_method; sid:1;)");
-
-    if (de_ctx->sig_list != NULL) {
-        result = 1;
-    } else {
-        printf("sig parse failed: ");
-    }
-
- end:
-    if (de_ctx != NULL)
-        DetectEngineCtxFree(de_ctx);
-    return result;
-}
-
-/** \test Check a signature without content (fail) */
-static int DetectHttpMethodTest02(void)
-{
-    DetectEngineCtx *de_ctx = NULL;
-    int result = 0;
-
-    if ( (de_ctx = DetectEngineCtxInit()) == NULL)
-        goto end;
-
-    de_ctx->flags |= DE_QUIET;
-    de_ctx->sig_list = SigInit(de_ctx,
-                               "alert tcp any any -> any any "
-                               "(msg:\"Testing http_method\"; "
-                               "http_method; sid:1;)");
-
-    if (de_ctx->sig_list == NULL) {
-        result = 1;
-    }
-
- end:
-    if (de_ctx != NULL)
-        DetectEngineCtxFree(de_ctx);
-    return result;
-}
-
-/** \test Check a signature with parameter (fail) */
-static int DetectHttpMethodTest03(void)
-{
-    DetectEngineCtx *de_ctx = NULL;
-    int result = 0;
-
-    if ( (de_ctx = DetectEngineCtxInit()) == NULL)
-        goto end;
-
-    de_ctx->flags |= DE_QUIET;
-    de_ctx->sig_list = SigInit(de_ctx,
-                               "alert tcp any any -> any any "
-                               "(msg:\"Testing http_method\"; "
-                               "content:\"foobar\"; "
-                               "http_method:\"GET\"; sid:1;)");
-
-    if (de_ctx->sig_list == NULL) {
-        result = 1;
-    }
-
- end:
-    if (de_ctx != NULL)
-        DetectEngineCtxFree(de_ctx);
-    return result;
-}
-
-/** \test Check a signature with fast_pattern (should work) */
-static int DetectHttpMethodTest04(void)
-{
-    DetectEngineCtx *de_ctx = NULL;
-    int result = 0;
-
-    if ( (de_ctx = DetectEngineCtxInit()) == NULL)
-        goto end;
-
-    de_ctx->flags |= DE_QUIET;
-    de_ctx->sig_list = SigInit(de_ctx,
-                               "alert tcp any any -> any any "
-                               "(msg:\"Testing http_method\"; "
-                               "content:\"GET\"; "
-                               "fast_pattern; "
-                               "http_method; sid:1;)");
-
-    if (de_ctx->sig_list != NULL) {
-        result = 1;
-    }
-
- end:
-    if (de_ctx != NULL)
-        DetectEngineCtxFree(de_ctx);
-    return result;
-}
-
-/** \test Check a signature with rawbytes (fail) */
-static int DetectHttpMethodTest05(void)
-{
-    DetectEngineCtx *de_ctx = NULL;
-    int result = 0;
-
-    if ( (de_ctx = DetectEngineCtxInit()) == NULL)
-        goto end;
-
-    de_ctx->flags |= DE_QUIET;
-    de_ctx->sig_list = SigInit(de_ctx,
-                               "alert tcp any any -> any any "
-                               "(msg:\"Testing http_method\"; "
-                               "content:\"GET\"; "
-                               "rawbytes; "
-                               "http_method; sid:1;)");
-
-    if (de_ctx->sig_list == NULL) {
-        result = 1;
-    }
-
- end:
-    if (de_ctx != NULL)
-        DetectEngineCtxFree(de_ctx);
-    return result;
-}
-
-/** \test setting the nocase flag */
-static int DetectHttpMethodTest12(void)
-{
-    DetectEngineCtx *de_ctx = NULL;
-    int result = 0;
-
-    if ( (de_ctx = DetectEngineCtxInit()) == NULL)
-        goto end;
-
-    de_ctx->flags |= DE_QUIET;
-
-    if (DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
-                               "(content:\"one\"; http_method; nocase; sid:1;)") == NULL) {
-        printf("DetectEngineAppend == NULL: ");
-        goto end;
-    }
-    if (DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
-                               "(content:\"one\"; nocase; http_method; sid:2;)") == NULL) {
-        printf("DetectEngineAppend == NULL: ");
-        goto end;
-    }
-
-    if (de_ctx->sig_list->sm_lists[g_http_method_buffer_id] == NULL) {
-        printf("de_ctx->sig_list->sm_lists[g_http_method_buffer_id] == NULL: ");
-        goto end;
-    }
-
-    DetectContentData *hmd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_method_buffer_id]->ctx;
-    DetectContentData *hmd2 = (DetectContentData *)de_ctx->sig_list->next->sm_lists_tail[g_http_method_buffer_id]->ctx;
-
-    if (!(hmd1->flags & DETECT_CONTENT_NOCASE)) {
-        printf("nocase flag not set on sig 1: ");
-        goto end;
-    }
-
-    if (!(hmd2->flags & DETECT_CONTENT_NOCASE)) {
-        printf("nocase flag not set on sig 2: ");
-        goto end;
-    }
-    result = 1;
-
- end:
-    DetectEngineCtxFree(de_ctx);
-    return result;
-}
-
-/** \test Check a signature with method + within and pcre with /M (should work) */
-static int DetectHttpMethodTest13(void)
-{
-    DetectEngineCtx *de_ctx = NULL;
-    int result = 0;
-
-    if ( (de_ctx = DetectEngineCtxInit()) == NULL)
-        goto end;
-
-    de_ctx->flags |= DE_QUIET;
-    de_ctx->sig_list = SigInit(de_ctx,
-                               "alert tcp any any -> any any "
-                               "(msg:\"Testing http_method\"; "
-                               "pcre:\"/HE/M\"; "
-                               "content:\"AD\"; "
-                               "within:2; http_method; sid:1;)");
-
-    if (de_ctx->sig_list != NULL) {
-        result = 1;
-    }
-
- end:
-    if (de_ctx != NULL)
-        DetectEngineCtxFree(de_ctx);
-    return result;
-}
-
-/** \test Check a signature with method + within and pcre without /M (should fail) */
-static int DetectHttpMethodTest14(void)
-{
-    DetectEngineCtx *de_ctx = NULL;
-    int result = 0;
-
-    if ( (de_ctx = DetectEngineCtxInit()) == NULL)
-        goto end;
-
-    de_ctx->flags |= DE_QUIET;
-    de_ctx->sig_list = SigInit(de_ctx,
-                               "alert tcp any any -> any any "
-                               "(msg:\"Testing http_method\"; "
-                               "pcre:\"/HE/\"; "
-                               "content:\"AD\"; "
-                               "http_method; within:2; sid:1;)");
-
-    if (de_ctx->sig_list != NULL) {
-        result = 1;
-    }
-
- end:
-    if (de_ctx != NULL)
-        DetectEngineCtxFree(de_ctx);
-    return result;
-}
-
-/** \test Check a signature with method + within and pcre with /M (should work) */
-static int DetectHttpMethodTest15(void)
-{
-    DetectEngineCtx *de_ctx = NULL;
-    int result = 0;
-
-    if ( (de_ctx = DetectEngineCtxInit()) == NULL)
-        goto end;
-
-    de_ctx->flags |= DE_QUIET;
-    de_ctx->sig_list = SigInit(de_ctx,
-                               "alert tcp any any -> any any "
-                               "(msg:\"Testing http_method\"; "
-                               "pcre:\"/HE/M\"; "
-                               "content:\"AD\"; "
-                               "http_method; within:2; sid:1;)");
-
-    if (de_ctx->sig_list != NULL) {
-        result = 1;
-    }
-
- end:
-    if (de_ctx != NULL)
-        DetectEngineCtxFree(de_ctx);
-    return result;
-}
-/** \test Check a signature with an known request method */
-static int DetectHttpMethodSigTest01(void)
-{
-    int result = 0;
-    Flow f;
-    uint8_t httpbuf1[] = "GET / HTTP/1.0\r\n"
-                         "Host: foo.bar.tld\r\n"
-                         "\r\n";
-    uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
-    TcpSession ssn;
-    Packet *p = NULL;
-    Signature *s = NULL;
-    ThreadVars th_v;
-    DetectEngineThreadCtx *det_ctx;
-    HtpState *http_state = NULL;
-    AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
-
-    memset(&th_v, 0, sizeof(th_v));
-    memset(&f, 0, sizeof(f));
-    memset(&ssn, 0, sizeof(ssn));
-
-    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
-
-    FLOW_INITIALIZE(&f);
-    f.protoctx = (void *)&ssn;
-    f.proto = IPPROTO_TCP;
-    f.flags |= FLOW_IPV4;
-
-    p->flow = &f;
-    p->flowflags |= FLOW_PKT_TOSERVER;
-    p->flowflags |= FLOW_PKT_ESTABLISHED;
-    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
-    f.alproto = ALPROTO_HTTP;
-
-    StreamTcpInitConfig(TRUE);
-
-    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
-    if (de_ctx == NULL) {
-        goto end;
-    }
-
-    de_ctx->flags |= DE_QUIET;
-
-    s = de_ctx->sig_list = SigInit(de_ctx,
-                                   "alert tcp any any -> any any "
-                                   "(msg:\"Testing http_method\"; "
-                                   "content:\"GET\"; "
-                                   "http_method; sid:1;)");
-    if (s == NULL) {
-        goto end;
-    }
-
-    s = s->next = SigInit(de_ctx,
-                          "alert tcp any any -> any any "
-                          "(msg:\"Testing http_method\"; "
-                          "content:\"POST\"; "
-                          "http_method; sid:2;)");
-    if (s == NULL) {
-        goto end;
-    }
-
-    SigGroupBuild(de_ctx);
-    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
-
-    FLOWLOCK_WRLOCK(&f);
-    int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
-                                STREAM_TOSERVER, httpbuf1, httplen1);
-    if (r != 0) {
-        SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
-        FLOWLOCK_UNLOCK(&f);
-        goto end;
-    }
-    FLOWLOCK_UNLOCK(&f);
-
-    http_state = f.alstate;
-    if (http_state == NULL) {
-        SCLogDebug("no http state: ");
-        goto end;
-    }
-
-    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
-
-    if (!(PacketAlertCheck(p, 1))) {
-        goto end;
-    }
-    if (PacketAlertCheck(p, 2)) {
-        goto end;
-    }
-
-    result = 1;
-
-end:
-    if (alp_tctx != NULL)
-        AppLayerParserThreadCtxFree(alp_tctx);
-    if (de_ctx != NULL)
-        DetectEngineCtxFree(de_ctx);
-
-    StreamTcpFreeConfig(TRUE);
-    FLOW_DESTROY(&f);
-    UTHFreePackets(&p, 1);
-    return result;
-}
-
-/** \test Check a signature with an unknown request method */
-static int DetectHttpMethodSigTest02(void)
-{
-    int result = 0;
-    Flow f;
-    uint8_t httpbuf1[] = "FOO / HTTP/1.0\r\n"
-                         "Host: foo.bar.tld\r\n"
-                         "\r\n";
-    uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
-    TcpSession ssn;
-    Packet *p = NULL;
-    Signature *s = NULL;
-    ThreadVars th_v;
-    DetectEngineThreadCtx *det_ctx = NULL;
-    HtpState *http_state = NULL;
-    AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
-
-    memset(&th_v, 0, sizeof(th_v));
-    memset(&f, 0, sizeof(f));
-    memset(&ssn, 0, sizeof(ssn));
-
-    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
-
-    FLOW_INITIALIZE(&f);
-    f.protoctx = (void *)&ssn;
-    f.proto = IPPROTO_TCP;
-    f.flags |= FLOW_IPV4;
-
-    p->flow = &f;
-    p->flowflags |= FLOW_PKT_TOSERVER;
-    p->flowflags |= FLOW_PKT_ESTABLISHED;
-    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
-    f.alproto = ALPROTO_HTTP;
-
-    StreamTcpInitConfig(TRUE);
-
-    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
-    if (de_ctx == NULL) {
-        goto end;
-    }
-
-    de_ctx->flags |= DE_QUIET;
-
-    s = de_ctx->sig_list = SigInit(de_ctx,
-                                   "alert tcp any any -> any any "
-                                   "(msg:\"Testing http_method\"; "
-                                   "content:\"FOO\"; "
-                                   "http_method; sid:1;)");
-    if (s == NULL) {
-        goto end;
-    }
-
-    s = s->next = SigInit(de_ctx,
-                          "alert tcp any any -> any any "
-                          "(msg:\"Testing http_method\"; "
-                          "content:\"BAR\"; "
-                          "http_method; sid:2;)");
-    if (s == NULL) {
-        goto end;
-    }
-
-    SigGroupBuild(de_ctx);
-    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
-
-    FLOWLOCK_WRLOCK(&f);
-    int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
-                                STREAM_TOSERVER, httpbuf1, httplen1);
-    if (r != 0) {
-        SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
-        FLOWLOCK_UNLOCK(&f);
-        goto end;
-    }
-    FLOWLOCK_UNLOCK(&f);
-
-    http_state = f.alstate;
-    if (http_state == NULL) {
-        SCLogDebug("no http state: ");
-        goto end;
-    }
-
-    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
-
-    if (!(PacketAlertCheck(p, 1))) {
-        goto end;
-    }
-    if (PacketAlertCheck(p, 2)) {
-        goto end;
-    }
-
-    result = 1;
-
-end:
-    if (alp_tctx != NULL)
-        AppLayerParserThreadCtxFree(alp_tctx);
-    if (det_ctx != NULL)
-        DetectEngineThreadCtxDeinit(&th_v, (void *) det_ctx);
-    if (de_ctx != NULL)
-        DetectEngineCtxFree(de_ctx);
-
-    StreamTcpFreeConfig(TRUE);
-    FLOW_DESTROY(&f);
-    UTHFreePackets(&p, 1);
-    return result;
-}
-
-/** \test Check a signature against an unparsable request */
-static int DetectHttpMethodSigTest03(void)
-{
-    int result = 0;
-    Flow f;
-    uint8_t httpbuf1[] = " ";
-    uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
-    TcpSession ssn;
-    Packet *p = NULL;
-    Signature *s = NULL;
-    ThreadVars th_v;
-    DetectEngineThreadCtx *det_ctx;
-    HtpState *http_state = NULL;
-    AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
-
-    memset(&th_v, 0, sizeof(th_v));
-    memset(&f, 0, sizeof(f));
-    memset(&ssn, 0, sizeof(ssn));
-
-    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
-
-    FLOW_INITIALIZE(&f);
-    f.protoctx = (void *)&ssn;
-    f.proto = IPPROTO_TCP;
-    f.flags |= FLOW_IPV4;
-
-    p->flow = &f;
-    p->flowflags |= FLOW_PKT_TOSERVER;
-    p->flowflags |= FLOW_PKT_ESTABLISHED;
-    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
-    f.alproto = ALPROTO_HTTP;
-
-    StreamTcpInitConfig(TRUE);
-
-    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
-    if (de_ctx == NULL) {
-        goto end;
-    }
-
-    de_ctx->flags |= DE_QUIET;
-
-    s = de_ctx->sig_list = SigInit(de_ctx,
-                                   "alert tcp any any -> any any "
-                                   "(msg:\"Testing http_method\"; "
-                                   "content:\"GET\"; "
-                                   "http_method; sid:1;)");
-    if (s == NULL) {
-        SCLogDebug("Bad signature");
-        goto end;
-    }
-
-    SigGroupBuild(de_ctx);
-    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
-
-    FLOWLOCK_WRLOCK(&f);
-    int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
-                                STREAM_TOSERVER, httpbuf1, httplen1);
-    if (r != 0) {
-        SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
-        FLOWLOCK_UNLOCK(&f);
-        goto end;
-    }
-    FLOWLOCK_UNLOCK(&f);
-
-    http_state = f.alstate;
-    if (http_state == NULL) {
-        SCLogDebug("no http state: ");
-        goto end;
-    }
-
-    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
-
-    if (PacketAlertCheck(p, 1)) {
-        goto end;
-    }
-
-    result = 1;
-
-end:
-    if (alp_tctx != NULL)
-        AppLayerParserThreadCtxFree(alp_tctx);
-    if (de_ctx != NULL)
-        DetectEngineCtxFree(de_ctx);
-
-    StreamTcpFreeConfig(TRUE);
-    FLOW_DESTROY(&f);
-    UTHFreePackets(&p, 1);
-    return result;
-}
-
-/** \test Check a signature with an request method and negation of the same */
-static int DetectHttpMethodSigTest04(void)
-{
-    int result = 0;
-    Flow f;
-    uint8_t httpbuf1[] = "GET / HTTP/1.0\r\n"
-                         "Host: foo.bar.tld\r\n"
-                         "\r\n";
-    uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
-    TcpSession ssn;
-    Packet *p = NULL;
-    Signature *s = NULL;
-    ThreadVars th_v;
-    DetectEngineThreadCtx *det_ctx = NULL;
-    HtpState *http_state = NULL;
-    AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
-
-    memset(&th_v, 0, sizeof(th_v));
-    memset(&f, 0, sizeof(f));
-    memset(&ssn, 0, sizeof(ssn));
-
-    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
-
-    FLOW_INITIALIZE(&f);
-    f.protoctx = (void *)&ssn;
-    f.proto = IPPROTO_TCP;
-    f.flags |= FLOW_IPV4;
-
-    p->flow = &f;
-    p->flowflags |= FLOW_PKT_TOSERVER;
-    p->flowflags |= FLOW_PKT_ESTABLISHED;
-    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
-    f.alproto = ALPROTO_HTTP;
-
-    StreamTcpInitConfig(TRUE);
-
-    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
-    if (de_ctx == NULL) {
-        goto end;
-    }
-
-    de_ctx->flags |= DE_QUIET;
-
-    s = de_ctx->sig_list = SigInit(de_ctx,
-            "alert tcp any any -> any any (msg:\"Testing http_method\"; "
-            "content:\"GET\"; http_method; sid:1;)");
-    if (s == NULL) {
-        goto end;
-    }
-
-    s = s->next = SigInit(de_ctx,
-            "alert tcp any any -> any any (msg:\"Testing http_method\"; "
-            "content:!\"GET\"; http_method; sid:2;)");
-    if (s == NULL) {
-        goto end;
-    }
-
-    SigGroupBuild(de_ctx);
-    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
-
-    FLOWLOCK_WRLOCK(&f);
-    int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
-                                STREAM_TOSERVER, httpbuf1, httplen1);
-    if (r != 0) {
-        SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
-        FLOWLOCK_UNLOCK(&f);
-        goto end;
-    }
-    FLOWLOCK_UNLOCK(&f);
-
-    http_state = f.alstate;
-    if (http_state == NULL) {
-        SCLogDebug("no http state: ");
-        goto end;
-    }
-
-    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
-
-    if (!(PacketAlertCheck(p, 1))) {
-        printf("sid 1 didn't match but should have: ");
-        goto end;
-    }
-    if (PacketAlertCheck(p, 2)) {
-        printf("sid 2 matched but shouldn't have: ");
-        goto end;
-    }
-
-    result = 1;
-
-end:
-    if (alp_tctx != NULL)
-        AppLayerParserThreadCtxFree(alp_tctx);
-    if (det_ctx != NULL) {
-        DetectEngineThreadCtxDeinit(&th_v, (void *) det_ctx);
-    }
-    if (de_ctx != NULL) {
-        DetectEngineCtxFree(de_ctx);
-    }
-
-    StreamTcpFreeConfig(TRUE);
-    FLOW_DESTROY(&f);
-    UTHFreePackets(&p, 1);
-    return result;
-}
-
-static int DetectHttpMethodIsdataatParseTest(void)
-{
-    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
-    FAIL_IF_NULL(de_ctx);
-    de_ctx->flags |= DE_QUIET;
-
-    Signature *s = DetectEngineAppendSig(de_ctx,
-            "alert tcp any any -> any any ("
-            "content:\"one\"; http_method; "
-            "isdataat:!4,relative; sid:1;)");
-    FAIL_IF_NULL(s);
-
-    SigMatch *sm = s->init_data->smlists_tail[g_http_method_buffer_id];
-    FAIL_IF_NULL(sm);
-    FAIL_IF_NOT(sm->type == DETECT_ISDATAAT);
-
-    DetectIsdataatData *data = (DetectIsdataatData *)sm->ctx;
-    FAIL_IF_NOT(data->flags & ISDATAAT_RELATIVE);
-    FAIL_IF_NOT(data->flags & ISDATAAT_NEGATED);
-    FAIL_IF(data->flags & ISDATAAT_RAWBYTES);
-
-    DetectEngineCtxFree(de_ctx);
-    PASS;
-}
-
-#endif /* UNITTESTS */
-
-/**
- * \brief this function registers unit tests for DetectHttpMethod
- */
-void DetectHttpMethodRegisterTests(void)
-{
-#ifdef UNITTESTS /* UNITTESTS */
-    SCLogDebug("Registering tests for DetectHttpMethod...");
-    UtRegisterTest("DetectHttpMethodTest01", DetectHttpMethodTest01);
-    UtRegisterTest("DetectHttpMethodTest02", DetectHttpMethodTest02);
-    UtRegisterTest("DetectHttpMethodTest03", DetectHttpMethodTest03);
-    UtRegisterTest("DetectHttpMethodTest04", DetectHttpMethodTest04);
-    UtRegisterTest("DetectHttpMethodTest05", DetectHttpMethodTest05);
-    UtRegisterTest("DetectHttpMethodTest12 -- nocase flag",
-                   DetectHttpMethodTest12);
-    UtRegisterTest("DetectHttpMethodTest13", DetectHttpMethodTest13);
-    UtRegisterTest("DetectHttpMethodTest14", DetectHttpMethodTest14);
-    UtRegisterTest("DetectHttpMethodTest15", DetectHttpMethodTest15);
-    UtRegisterTest("DetectHttpMethodSigTest01", DetectHttpMethodSigTest01);
-    UtRegisterTest("DetectHttpMethodSigTest02", DetectHttpMethodSigTest02);
-    UtRegisterTest("DetectHttpMethodSigTest03", DetectHttpMethodSigTest03);
-    UtRegisterTest("DetectHttpMethodSigTest04", DetectHttpMethodSigTest04);
-
-    UtRegisterTest("DetectHttpMethodIsdataatParseTest",
-            DetectHttpMethodIsdataatParseTest);
-#endif /* UNITTESTS */
-}
+#ifdef UNITTESTS
+#include "tests/detect-http-method.c"
+#endif
 
 /**
  * @}
index 926d8f9d89ba230389bdd2f9de9c60d10bf5569b..dcc31c6f5619b62668f4fe71e5b2c76b5a8befca 100644 (file)
@@ -39,7 +39,6 @@
 #include "detect-engine-hcbd.h"
 #include "detect-engine-hsbd.h"
 #include "detect-engine-hrhd.h"
-#include "detect-engine-hmd.h"
 #include "detect-engine-hcd.h"
 #include "detect-engine-hsmd.h"
 #include "detect-engine-hscd.h"
@@ -200,7 +199,6 @@ static void RegisterUnittests(void)
     DetectEngineHttpClientBodyRegisterTests();
     DetectEngineHttpServerBodyRegisterTests();
     DetectEngineHttpRawHeaderRegisterTests();
-    DetectEngineHttpMethodRegisterTests();
     DetectEngineHttpCookieRegisterTests();
     DetectEngineHttpStatMsgRegisterTests();
     DetectEngineHttpStatCodeRegisterTests();
similarity index 69%
rename from src/detect-engine-hmd.c
rename to src/tests/detect-http-method.c
index f8a3df7ea4d3daf9f44dd67d5fa7974a07e51f0d..e0a815b2a293d39b06e1d8f7717697465ccd7b75 100644 (file)
  *
  */
 
-#include "suricata-common.h"
-#include "suricata.h"
-#include "decode.h"
-
-#include "detect.h"
-#include "detect-engine.h"
-#include "detect-engine-hmd.h"
-#include "detect-engine-mpm.h"
-#include "detect-parse.h"
-#include "detect-engine-state.h"
-#include "detect-engine-content-inspection.h"
-#include "detect-engine-prefilter.h"
-
-#include "flow-util.h"
-#include "util-debug.h"
-#include "util-print.h"
-#include "flow.h"
-
-#include "stream-tcp.h"
-
-#include "app-layer-parser.h"
-
-#include "util-unittest.h"
-#include "util-unittest-helper.h"
-#include "app-layer.h"
-#include "app-layer-htp.h"
-#include "app-layer-protos.h"
-#include "util-validate.h"
-
-/** \brief HTTP Method Mpm prefilter callback
- *
- *  \param det_ctx detection engine thread ctx
- *  \param p packet to inspect
- *  \param f flow to inspect
- *  \param txv tx to inspect
- *  \param pectx inspection context
- *
- *  \retval ret number of matches
- */
-static void PrefilterTxMethod(DetectEngineThreadCtx *det_ctx,
-        const void *pectx,
-        Packet *p, Flow *f, void *txv,
-        const uint64_t idx, const uint8_t flags)
-{
-    SCEnter();
-
-    const MpmCtx *mpm_ctx = (MpmCtx *)pectx;
-    htp_tx_t *tx = (htp_tx_t *)txv;
-
-    if (tx->request_method == NULL)
-        return;
-
-    const uint32_t buffer_len = bstr_len(tx->request_method);
-    const uint8_t *buffer = bstr_ptr(tx->request_method);
-
-    if (buffer_len >= mpm_ctx->minlen) {
-        (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
-                &det_ctx->mtcu, &det_ctx->pmq, buffer, buffer_len);
-    }
-}
-
-int PrefilterTxMethodRegister(DetectEngineCtx *de_ctx,
-        SigGroupHead *sgh, MpmCtx *mpm_ctx)
-{
-    return PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxMethod,
-        ALPROTO_HTTP, HTP_REQUEST_LINE,
-        mpm_ctx, NULL, "http_method");
-}
-
-/**
- * \brief Do the http_method content inspection for a signature.
- *
- * \param de_ctx  Detection engine context.
- * \param det_ctx Detection engine thread context.
- * \param s       Signature to inspect.
- * \param f       Flow.
- * \param flags   App layer flags.
- * \param state   App layer state.
- *
- * \retval 0 No match.
- * \retval 1 Match.
- */
-int DetectEngineInspectHttpMethod(ThreadVars *tv,
-        DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
-        const Signature *s, const SigMatchData *smd,
-        Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
-{
-    htp_tx_t *tx = (htp_tx_t *)txv;
-    if (tx->request_method == NULL) {
-        if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_REQUEST_LINE)
-            return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
-        else
-            return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
-    }
-
-    det_ctx->buffer_offset = 0;
-    det_ctx->discontinue_matching = 0;
-    det_ctx->inspection_recursion_counter = 0;
-    int r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
-                                          f,
-                                          (uint8_t *)bstr_ptr(tx->request_method),
-                                          bstr_len(tx->request_method),
-                                          0, DETECT_CI_FLAGS_SINGLE,
-                                          DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
-    if (r == 1)
-        return DETECT_ENGINE_INSPECT_SIG_MATCH;
-    else
-        return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
-}
-
-/***********************************Unittests**********************************/
-
-#ifdef UNITTESTS
+#include "../suricata-common.h"
+#include "../suricata.h"
+#include "../flow-util.h"
+#include "../flow.h"
+#include "../app-layer-parser.h"
+
+#include "../util-unittest.h"
+#include "../util-unittest-helper.h"
+#include "../app-layer.h"
+#include "../app-layer-htp.h"
+#include "../app-layer-protos.h"
+#include "../detect-isdataat.h"
 
 /**
  * \test Test that the http_method content matches against a http request
@@ -1750,12 +1649,715 @@ end:
     return result;
 }
 
-#endif /* UNITTESTS */
+/** \test Check a signature with content */
+static int DetectHttpMethodTest01(void)
+{
+    DetectEngineCtx *de_ctx = NULL;
+    int result = 0;
+
+    if ( (de_ctx = DetectEngineCtxInit()) == NULL)
+        goto end;
+
+    de_ctx->flags |= DE_QUIET;
+    de_ctx->sig_list = SigInit(de_ctx,
+                               "alert tcp any any -> any any "
+                               "(msg:\"Testing http_method\"; "
+                               "content:\"GET\"; "
+                               "http_method; sid:1;)");
+
+    if (de_ctx->sig_list != NULL) {
+        result = 1;
+    } else {
+        printf("sig parse failed: ");
+    }
+
+ end:
+    if (de_ctx != NULL)
+        DetectEngineCtxFree(de_ctx);
+    return result;
+}
+
+/** \test Check a signature without content (fail) */
+static int DetectHttpMethodTest02(void)
+{
+    DetectEngineCtx *de_ctx = NULL;
+    int result = 0;
+
+    if ( (de_ctx = DetectEngineCtxInit()) == NULL)
+        goto end;
+
+    de_ctx->flags |= DE_QUIET;
+    de_ctx->sig_list = SigInit(de_ctx,
+                               "alert tcp any any -> any any "
+                               "(msg:\"Testing http_method\"; "
+                               "http_method; sid:1;)");
+
+    if (de_ctx->sig_list == NULL) {
+        result = 1;
+    }
+
+ end:
+    if (de_ctx != NULL)
+        DetectEngineCtxFree(de_ctx);
+    return result;
+}
+
+/** \test Check a signature with parameter (fail) */
+static int DetectHttpMethodTest03(void)
+{
+    DetectEngineCtx *de_ctx = NULL;
+    int result = 0;
+
+    if ( (de_ctx = DetectEngineCtxInit()) == NULL)
+        goto end;
+
+    de_ctx->flags |= DE_QUIET;
+    de_ctx->sig_list = SigInit(de_ctx,
+                               "alert tcp any any -> any any "
+                               "(msg:\"Testing http_method\"; "
+                               "content:\"foobar\"; "
+                               "http_method:\"GET\"; sid:1;)");
+
+    if (de_ctx->sig_list == NULL) {
+        result = 1;
+    }
+
+ end:
+    if (de_ctx != NULL)
+        DetectEngineCtxFree(de_ctx);
+    return result;
+}
+
+/** \test Check a signature with fast_pattern (should work) */
+static int DetectHttpMethodTest04(void)
+{
+    DetectEngineCtx *de_ctx = NULL;
+    int result = 0;
+
+    if ( (de_ctx = DetectEngineCtxInit()) == NULL)
+        goto end;
+
+    de_ctx->flags |= DE_QUIET;
+    de_ctx->sig_list = SigInit(de_ctx,
+                               "alert tcp any any -> any any "
+                               "(msg:\"Testing http_method\"; "
+                               "content:\"GET\"; "
+                               "fast_pattern; "
+                               "http_method; sid:1;)");
+
+    if (de_ctx->sig_list != NULL) {
+        result = 1;
+    }
+
+ end:
+    if (de_ctx != NULL)
+        DetectEngineCtxFree(de_ctx);
+    return result;
+}
+
+/** \test Check a signature with rawbytes (fail) */
+static int DetectHttpMethodTest05(void)
+{
+    DetectEngineCtx *de_ctx = NULL;
+    int result = 0;
+
+    if ( (de_ctx = DetectEngineCtxInit()) == NULL)
+        goto end;
+
+    de_ctx->flags |= DE_QUIET;
+    de_ctx->sig_list = SigInit(de_ctx,
+                               "alert tcp any any -> any any "
+                               "(msg:\"Testing http_method\"; "
+                               "content:\"GET\"; "
+                               "rawbytes; "
+                               "http_method; sid:1;)");
+
+    if (de_ctx->sig_list == NULL) {
+        result = 1;
+    }
+
+ end:
+    if (de_ctx != NULL)
+        DetectEngineCtxFree(de_ctx);
+    return result;
+}
+
+/** \test setting the nocase flag */
+static int DetectHttpMethodTest12(void)
+{
+    DetectEngineCtx *de_ctx = NULL;
+    int result = 0;
+
+    if ( (de_ctx = DetectEngineCtxInit()) == NULL)
+        goto end;
+
+    de_ctx->flags |= DE_QUIET;
+
+    if (DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
+                               "(content:\"one\"; http_method; nocase; sid:1;)") == NULL) {
+        printf("DetectEngineAppend == NULL: ");
+        goto end;
+    }
+    if (DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
+                               "(content:\"one\"; nocase; http_method; sid:2;)") == NULL) {
+        printf("DetectEngineAppend == NULL: ");
+        goto end;
+    }
+
+    if (de_ctx->sig_list->sm_lists[g_http_method_buffer_id] == NULL) {
+        printf("de_ctx->sig_list->sm_lists[g_http_method_buffer_id] == NULL: ");
+        goto end;
+    }
+
+    DetectContentData *hmd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_method_buffer_id]->ctx;
+    DetectContentData *hmd2 = (DetectContentData *)de_ctx->sig_list->next->sm_lists_tail[g_http_method_buffer_id]->ctx;
+
+    if (!(hmd1->flags & DETECT_CONTENT_NOCASE)) {
+        printf("nocase flag not set on sig 1: ");
+        goto end;
+    }
+
+    if (!(hmd2->flags & DETECT_CONTENT_NOCASE)) {
+        printf("nocase flag not set on sig 2: ");
+        goto end;
+    }
+    result = 1;
+
+ end:
+    DetectEngineCtxFree(de_ctx);
+    return result;
+}
+
+/** \test Check a signature with method + within and pcre with /M (should work) */
+static int DetectHttpMethodTest13(void)
+{
+    DetectEngineCtx *de_ctx = NULL;
+    int result = 0;
+
+    if ( (de_ctx = DetectEngineCtxInit()) == NULL)
+        goto end;
+
+    de_ctx->flags |= DE_QUIET;
+    de_ctx->sig_list = SigInit(de_ctx,
+                               "alert tcp any any -> any any "
+                               "(msg:\"Testing http_method\"; "
+                               "pcre:\"/HE/M\"; "
+                               "content:\"AD\"; "
+                               "within:2; http_method; sid:1;)");
+
+    if (de_ctx->sig_list != NULL) {
+        result = 1;
+    }
+
+ end:
+    if (de_ctx != NULL)
+        DetectEngineCtxFree(de_ctx);
+    return result;
+}
+
+/** \test Check a signature with method + within and pcre without /M (should fail) */
+static int DetectHttpMethodTest14(void)
+{
+    DetectEngineCtx *de_ctx = NULL;
+    int result = 0;
+
+    if ( (de_ctx = DetectEngineCtxInit()) == NULL)
+        goto end;
+
+    de_ctx->flags |= DE_QUIET;
+    de_ctx->sig_list = SigInit(de_ctx,
+                               "alert tcp any any -> any any "
+                               "(msg:\"Testing http_method\"; "
+                               "pcre:\"/HE/\"; "
+                               "content:\"AD\"; "
+                               "http_method; within:2; sid:1;)");
+
+    if (de_ctx->sig_list != NULL) {
+        result = 1;
+    }
+
+ end:
+    if (de_ctx != NULL)
+        DetectEngineCtxFree(de_ctx);
+    return result;
+}
+
+/** \test Check a signature with method + within and pcre with /M (should work) */
+static int DetectHttpMethodTest15(void)
+{
+    DetectEngineCtx *de_ctx = NULL;
+    int result = 0;
+
+    if ( (de_ctx = DetectEngineCtxInit()) == NULL)
+        goto end;
+
+    de_ctx->flags |= DE_QUIET;
+    de_ctx->sig_list = SigInit(de_ctx,
+                               "alert tcp any any -> any any "
+                               "(msg:\"Testing http_method\"; "
+                               "pcre:\"/HE/M\"; "
+                               "content:\"AD\"; "
+                               "http_method; within:2; sid:1;)");
+
+    if (de_ctx->sig_list != NULL) {
+        result = 1;
+    }
+
+ end:
+    if (de_ctx != NULL)
+        DetectEngineCtxFree(de_ctx);
+    return result;
+}
+/** \test Check a signature with an known request method */
+static int DetectHttpMethodSigTest01(void)
+{
+    int result = 0;
+    Flow f;
+    uint8_t httpbuf1[] = "GET / HTTP/1.0\r\n"
+                         "Host: foo.bar.tld\r\n"
+                         "\r\n";
+    uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
+    TcpSession ssn;
+    Packet *p = NULL;
+    Signature *s = NULL;
+    ThreadVars th_v;
+    DetectEngineThreadCtx *det_ctx;
+    HtpState *http_state = NULL;
+    AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+    memset(&th_v, 0, sizeof(th_v));
+    memset(&f, 0, sizeof(f));
+    memset(&ssn, 0, sizeof(ssn));
+
+    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
+
+    FLOW_INITIALIZE(&f);
+    f.protoctx = (void *)&ssn;
+    f.proto = IPPROTO_TCP;
+    f.flags |= FLOW_IPV4;
+
+    p->flow = &f;
+    p->flowflags |= FLOW_PKT_TOSERVER;
+    p->flowflags |= FLOW_PKT_ESTABLISHED;
+    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+    f.alproto = ALPROTO_HTTP;
+
+    StreamTcpInitConfig(TRUE);
+
+    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+    if (de_ctx == NULL) {
+        goto end;
+    }
+
+    de_ctx->flags |= DE_QUIET;
+
+    s = de_ctx->sig_list = SigInit(de_ctx,
+                                   "alert tcp any any -> any any "
+                                   "(msg:\"Testing http_method\"; "
+                                   "content:\"GET\"; "
+                                   "http_method; sid:1;)");
+    if (s == NULL) {
+        goto end;
+    }
+
+    s = s->next = SigInit(de_ctx,
+                          "alert tcp any any -> any any "
+                          "(msg:\"Testing http_method\"; "
+                          "content:\"POST\"; "
+                          "http_method; sid:2;)");
+    if (s == NULL) {
+        goto end;
+    }
+
+    SigGroupBuild(de_ctx);
+    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+    FLOWLOCK_WRLOCK(&f);
+    int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
+                                STREAM_TOSERVER, httpbuf1, httplen1);
+    if (r != 0) {
+        SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+        FLOWLOCK_UNLOCK(&f);
+        goto end;
+    }
+    FLOWLOCK_UNLOCK(&f);
+
+    http_state = f.alstate;
+    if (http_state == NULL) {
+        SCLogDebug("no http state: ");
+        goto end;
+    }
+
+    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
+
+    if (!(PacketAlertCheck(p, 1))) {
+        goto end;
+    }
+    if (PacketAlertCheck(p, 2)) {
+        goto end;
+    }
+
+    result = 1;
+
+end:
+    if (alp_tctx != NULL)
+        AppLayerParserThreadCtxFree(alp_tctx);
+    if (de_ctx != NULL)
+        DetectEngineCtxFree(de_ctx);
+
+    StreamTcpFreeConfig(TRUE);
+    FLOW_DESTROY(&f);
+    UTHFreePackets(&p, 1);
+    return result;
+}
+
+/** \test Check a signature with an unknown request method */
+static int DetectHttpMethodSigTest02(void)
+{
+    int result = 0;
+    Flow f;
+    uint8_t httpbuf1[] = "FOO / HTTP/1.0\r\n"
+                         "Host: foo.bar.tld\r\n"
+                         "\r\n";
+    uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
+    TcpSession ssn;
+    Packet *p = NULL;
+    Signature *s = NULL;
+    ThreadVars th_v;
+    DetectEngineThreadCtx *det_ctx = NULL;
+    HtpState *http_state = NULL;
+    AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+    memset(&th_v, 0, sizeof(th_v));
+    memset(&f, 0, sizeof(f));
+    memset(&ssn, 0, sizeof(ssn));
+
+    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
+
+    FLOW_INITIALIZE(&f);
+    f.protoctx = (void *)&ssn;
+    f.proto = IPPROTO_TCP;
+    f.flags |= FLOW_IPV4;
+
+    p->flow = &f;
+    p->flowflags |= FLOW_PKT_TOSERVER;
+    p->flowflags |= FLOW_PKT_ESTABLISHED;
+    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+    f.alproto = ALPROTO_HTTP;
+
+    StreamTcpInitConfig(TRUE);
+
+    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+    if (de_ctx == NULL) {
+        goto end;
+    }
+
+    de_ctx->flags |= DE_QUIET;
+
+    s = de_ctx->sig_list = SigInit(de_ctx,
+                                   "alert tcp any any -> any any "
+                                   "(msg:\"Testing http_method\"; "
+                                   "content:\"FOO\"; "
+                                   "http_method; sid:1;)");
+    if (s == NULL) {
+        goto end;
+    }
+
+    s = s->next = SigInit(de_ctx,
+                          "alert tcp any any -> any any "
+                          "(msg:\"Testing http_method\"; "
+                          "content:\"BAR\"; "
+                          "http_method; sid:2;)");
+    if (s == NULL) {
+        goto end;
+    }
+
+    SigGroupBuild(de_ctx);
+    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+    FLOWLOCK_WRLOCK(&f);
+    int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
+                                STREAM_TOSERVER, httpbuf1, httplen1);
+    if (r != 0) {
+        SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+        FLOWLOCK_UNLOCK(&f);
+        goto end;
+    }
+    FLOWLOCK_UNLOCK(&f);
+
+    http_state = f.alstate;
+    if (http_state == NULL) {
+        SCLogDebug("no http state: ");
+        goto end;
+    }
+
+    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
+
+    if (!(PacketAlertCheck(p, 1))) {
+        goto end;
+    }
+    if (PacketAlertCheck(p, 2)) {
+        goto end;
+    }
+
+    result = 1;
+
+end:
+    if (alp_tctx != NULL)
+        AppLayerParserThreadCtxFree(alp_tctx);
+    if (det_ctx != NULL)
+        DetectEngineThreadCtxDeinit(&th_v, (void *) det_ctx);
+    if (de_ctx != NULL)
+        DetectEngineCtxFree(de_ctx);
+
+    StreamTcpFreeConfig(TRUE);
+    FLOW_DESTROY(&f);
+    UTHFreePackets(&p, 1);
+    return result;
+}
+
+/** \test Check a signature against an unparsable request */
+static int DetectHttpMethodSigTest03(void)
+{
+    int result = 0;
+    Flow f;
+    uint8_t httpbuf1[] = " ";
+    uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
+    TcpSession ssn;
+    Packet *p = NULL;
+    Signature *s = NULL;
+    ThreadVars th_v;
+    DetectEngineThreadCtx *det_ctx;
+    HtpState *http_state = NULL;
+    AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+    memset(&th_v, 0, sizeof(th_v));
+    memset(&f, 0, sizeof(f));
+    memset(&ssn, 0, sizeof(ssn));
+
+    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
+
+    FLOW_INITIALIZE(&f);
+    f.protoctx = (void *)&ssn;
+    f.proto = IPPROTO_TCP;
+    f.flags |= FLOW_IPV4;
+
+    p->flow = &f;
+    p->flowflags |= FLOW_PKT_TOSERVER;
+    p->flowflags |= FLOW_PKT_ESTABLISHED;
+    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+    f.alproto = ALPROTO_HTTP;
+
+    StreamTcpInitConfig(TRUE);
+
+    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+    if (de_ctx == NULL) {
+        goto end;
+    }
+
+    de_ctx->flags |= DE_QUIET;
 
-void DetectEngineHttpMethodRegisterTests(void)
+    s = de_ctx->sig_list = SigInit(de_ctx,
+                                   "alert tcp any any -> any any "
+                                   "(msg:\"Testing http_method\"; "
+                                   "content:\"GET\"; "
+                                   "http_method; sid:1;)");
+    if (s == NULL) {
+        SCLogDebug("Bad signature");
+        goto end;
+    }
+
+    SigGroupBuild(de_ctx);
+    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+    FLOWLOCK_WRLOCK(&f);
+    int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
+                                STREAM_TOSERVER, httpbuf1, httplen1);
+    if (r != 0) {
+        SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+        FLOWLOCK_UNLOCK(&f);
+        goto end;
+    }
+    FLOWLOCK_UNLOCK(&f);
+
+    http_state = f.alstate;
+    if (http_state == NULL) {
+        SCLogDebug("no http state: ");
+        goto end;
+    }
+
+    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
+
+    if (PacketAlertCheck(p, 1)) {
+        goto end;
+    }
+
+    result = 1;
+
+end:
+    if (alp_tctx != NULL)
+        AppLayerParserThreadCtxFree(alp_tctx);
+    if (de_ctx != NULL)
+        DetectEngineCtxFree(de_ctx);
+
+    StreamTcpFreeConfig(TRUE);
+    FLOW_DESTROY(&f);
+    UTHFreePackets(&p, 1);
+    return result;
+}
+
+/** \test Check a signature with an request method and negation of the same */
+static int DetectHttpMethodSigTest04(void)
 {
+    int result = 0;
+    Flow f;
+    uint8_t httpbuf1[] = "GET / HTTP/1.0\r\n"
+                         "Host: foo.bar.tld\r\n"
+                         "\r\n";
+    uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
+    TcpSession ssn;
+    Packet *p = NULL;
+    Signature *s = NULL;
+    ThreadVars th_v;
+    DetectEngineThreadCtx *det_ctx = NULL;
+    HtpState *http_state = NULL;
+    AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+    memset(&th_v, 0, sizeof(th_v));
+    memset(&f, 0, sizeof(f));
+    memset(&ssn, 0, sizeof(ssn));
+
+    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
+
+    FLOW_INITIALIZE(&f);
+    f.protoctx = (void *)&ssn;
+    f.proto = IPPROTO_TCP;
+    f.flags |= FLOW_IPV4;
+
+    p->flow = &f;
+    p->flowflags |= FLOW_PKT_TOSERVER;
+    p->flowflags |= FLOW_PKT_ESTABLISHED;
+    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+    f.alproto = ALPROTO_HTTP;
+
+    StreamTcpInitConfig(TRUE);
+
+    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+    if (de_ctx == NULL) {
+        goto end;
+    }
+
+    de_ctx->flags |= DE_QUIET;
 
-#ifdef UNITTESTS
+    s = de_ctx->sig_list = SigInit(de_ctx,
+            "alert tcp any any -> any any (msg:\"Testing http_method\"; "
+            "content:\"GET\"; http_method; sid:1;)");
+    if (s == NULL) {
+        goto end;
+    }
+
+    s = s->next = SigInit(de_ctx,
+            "alert tcp any any -> any any (msg:\"Testing http_method\"; "
+            "content:!\"GET\"; http_method; sid:2;)");
+    if (s == NULL) {
+        goto end;
+    }
+
+    SigGroupBuild(de_ctx);
+    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+    FLOWLOCK_WRLOCK(&f);
+    int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
+                                STREAM_TOSERVER, httpbuf1, httplen1);
+    if (r != 0) {
+        SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+        FLOWLOCK_UNLOCK(&f);
+        goto end;
+    }
+    FLOWLOCK_UNLOCK(&f);
+
+    http_state = f.alstate;
+    if (http_state == NULL) {
+        SCLogDebug("no http state: ");
+        goto end;
+    }
+
+    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
+
+    if (!(PacketAlertCheck(p, 1))) {
+        printf("sid 1 didn't match but should have: ");
+        goto end;
+    }
+    if (PacketAlertCheck(p, 2)) {
+        printf("sid 2 matched but shouldn't have: ");
+        goto end;
+    }
+
+    result = 1;
+
+end:
+    if (alp_tctx != NULL)
+        AppLayerParserThreadCtxFree(alp_tctx);
+    if (det_ctx != NULL) {
+        DetectEngineThreadCtxDeinit(&th_v, (void *) det_ctx);
+    }
+    if (de_ctx != NULL) {
+        DetectEngineCtxFree(de_ctx);
+    }
+
+    StreamTcpFreeConfig(TRUE);
+    FLOW_DESTROY(&f);
+    UTHFreePackets(&p, 1);
+    return result;
+}
+
+static int DetectHttpMethodIsdataatParseTest(void)
+{
+    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+    FAIL_IF_NULL(de_ctx);
+    de_ctx->flags |= DE_QUIET;
+
+    Signature *s = DetectEngineAppendSig(de_ctx,
+            "alert tcp any any -> any any ("
+            "content:\"one\"; http_method; "
+            "isdataat:!4,relative; sid:1;)");
+    FAIL_IF_NULL(s);
+
+    SigMatch *sm = s->init_data->smlists_tail[g_http_method_buffer_id];
+    FAIL_IF_NULL(sm);
+    FAIL_IF_NOT(sm->type == DETECT_ISDATAAT);
+
+    DetectIsdataatData *data = (DetectIsdataatData *)sm->ctx;
+    FAIL_IF_NOT(data->flags & ISDATAAT_RELATIVE);
+    FAIL_IF_NOT(data->flags & ISDATAAT_NEGATED);
+    FAIL_IF(data->flags & ISDATAAT_RAWBYTES);
+
+    DetectEngineCtxFree(de_ctx);
+    PASS;
+}
+
+/**
+ * \brief this function registers unit tests for DetectHttpMethod
+ */
+void DetectHttpMethodRegisterTests(void)
+{
+    UtRegisterTest("DetectHttpMethodTest01", DetectHttpMethodTest01);
+    UtRegisterTest("DetectHttpMethodTest02", DetectHttpMethodTest02);
+    UtRegisterTest("DetectHttpMethodTest03", DetectHttpMethodTest03);
+    UtRegisterTest("DetectHttpMethodTest04", DetectHttpMethodTest04);
+    UtRegisterTest("DetectHttpMethodTest05", DetectHttpMethodTest05);
+    UtRegisterTest("DetectHttpMethodTest12 -- nocase flag",
+                   DetectHttpMethodTest12);
+    UtRegisterTest("DetectHttpMethodTest13", DetectHttpMethodTest13);
+    UtRegisterTest("DetectHttpMethodTest14", DetectHttpMethodTest14);
+    UtRegisterTest("DetectHttpMethodTest15", DetectHttpMethodTest15);
+    UtRegisterTest("DetectHttpMethodSigTest01", DetectHttpMethodSigTest01);
+    UtRegisterTest("DetectHttpMethodSigTest02", DetectHttpMethodSigTest02);
+    UtRegisterTest("DetectHttpMethodSigTest03", DetectHttpMethodSigTest03);
+    UtRegisterTest("DetectHttpMethodSigTest04", DetectHttpMethodSigTest04);
+
+    UtRegisterTest("DetectHttpMethodIsdataatParseTest",
+            DetectHttpMethodIsdataatParseTest);
     UtRegisterTest("DetectEngineHttpMethodTest01",
                    DetectEngineHttpMethodTest01);
     UtRegisterTest("DetectEngineHttpMethodTest02",
@@ -1790,10 +2392,8 @@ void DetectEngineHttpMethodRegisterTests(void)
                    DetectEngineHttpMethodTest16);
     UtRegisterTest("DetectEngineHttpMethodTest17",
                    DetectEngineHttpMethodTest17);
-#endif /* UNITTESTS */
-
-    return;
 }
+
 /**
  * @}
  */