Renamed chunk sources, added request parser, header management, test file.
parent
503e8d7859
commit
18413d698a
|
@ -13,5 +13,8 @@ gboolean parse_option(server *srv, const char *key, option *opt, option_mark *ma
|
|||
sopt = find_option(srv, key);
|
||||
if (!sopt) return FALSE;
|
||||
|
||||
/* TODO */
|
||||
UNUSED(opt);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
#include "base.h"
|
||||
#include "chunks.h"
|
||||
#include "chunk.h"
|
||||
#include "log.h"
|
||||
|
||||
/******************
|
||||
|
@ -179,35 +179,6 @@ read_chunk:
|
|||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
GString* chunk_extract(server *srv, connection *con, chunk_parser_mark from, chunk_parser_mark to) {
|
||||
GString *str = g_string_sized_new(0);
|
||||
chunk_parser_mark i;
|
||||
for ( i = from; i.ci.element != to.ci.element; chunkiter_next(&i.ci) ) {
|
||||
goffset len = chunkiter_length(i.ci);
|
||||
while (i.pos < len) {
|
||||
char *buf;
|
||||
off_t we_have;
|
||||
if (HANDLER_GO_ON != chunkiter_read(srv, con, i.ci, i.pos, len - i.pos, &buf, &we_have)) goto error;
|
||||
g_string_append_len(str, buf, we_have);
|
||||
i.pos += we_have;
|
||||
}
|
||||
i.pos = 0;
|
||||
}
|
||||
while (i.pos < to.pos) {
|
||||
char *buf;
|
||||
off_t we_have;
|
||||
if (HANDLER_GO_ON != chunkiter_read(srv, con, i.ci, i.pos, to.pos - i.pos, &buf, &we_have)) goto error;
|
||||
g_string_append_len(str, buf, we_have);
|
||||
i.pos += we_have;
|
||||
}
|
||||
|
||||
return str;
|
||||
|
||||
error:
|
||||
g_string_free(str, TRUE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/******************
|
||||
* chunk *
|
||||
******************/
|
|
@ -15,9 +15,6 @@ typedef struct chunkqueue chunkqueue;
|
|||
struct chunkiter;
|
||||
typedef struct chunkiter chunkiter;
|
||||
|
||||
struct chunk_parser_mark;
|
||||
typedef struct chunk_parser_mark chunk_parser_mark;
|
||||
|
||||
#include "base.h"
|
||||
|
||||
/* Open a file only once, so it shouldn't get lost;
|
||||
|
@ -69,11 +66,6 @@ struct chunkiter {
|
|||
GList *element;
|
||||
};
|
||||
|
||||
struct chunk_parser_mark {
|
||||
chunkiter ci;
|
||||
off_t pos;
|
||||
};
|
||||
|
||||
/******************
|
||||
* chunkfile *
|
||||
******************/
|
||||
|
@ -99,8 +91,6 @@ INLINE goffset chunkiter_length(chunkiter iter);
|
|||
*/
|
||||
LI_API handler_t chunkiter_read(server *srv, connection *con, chunkiter iter, off_t start, off_t length, char **data_start, off_t *data_len);
|
||||
|
||||
LI_API GString* chunk_extract(server *srv, connection *con, chunk_parser_mark from, chunk_parser_mark to);
|
||||
|
||||
/******************
|
||||
* chunk *
|
||||
******************/
|
|
@ -0,0 +1,78 @@
|
|||
|
||||
#include "chunk_parser.h"
|
||||
|
||||
void chunk_parser_init(chunk_parser_ctx *ctx, chunkqueue *cq) {
|
||||
ctx->cq = cq;
|
||||
ctx->bytes_in = 0;
|
||||
ctx->curi.element = NULL;
|
||||
ctx->start = 0;
|
||||
ctx->length = 0;
|
||||
ctx->buf = NULL;
|
||||
}
|
||||
|
||||
handler_t chunk_parser_prepare(chunk_parser_ctx *ctx) {
|
||||
if (NULL == ctx->curi.element) {
|
||||
ctx->curi = chunkqueue_iter(ctx->cq);
|
||||
if (NULL == ctx->curi.element) return HANDLER_WAIT_FOR_EVENT;
|
||||
}
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
handler_t chunk_parser_next(server *srv, connection *con, chunk_parser_ctx *ctx, char **p, char **pe) {
|
||||
off_t l;
|
||||
handler_t res;
|
||||
|
||||
if (NULL == ctx->curi.element) return HANDLER_WAIT_FOR_EVENT;
|
||||
|
||||
while (ctx->start >= (l = chunkiter_length(ctx->curi))) {
|
||||
chunkiter i = ctx->curi;
|
||||
/* Wait at the end of the last chunk if it gets extended */
|
||||
if (!chunkiter_next(&i)) return HANDLER_WAIT_FOR_EVENT;
|
||||
ctx->curi = i;
|
||||
ctx->start = 0;
|
||||
}
|
||||
|
||||
if (NULL == ctx->curi.element) return HANDLER_WAIT_FOR_EVENT;
|
||||
|
||||
if (HANDLER_GO_ON != (res = chunkiter_read(srv, con, ctx->curi, ctx->start, l - ctx->start, &ctx->buf, &ctx->length))) {
|
||||
return res;
|
||||
}
|
||||
|
||||
*p = ctx->buf;
|
||||
*pe = ctx->buf + ctx->length;
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
void chunk_parser_done(chunk_parser_ctx *ctx, goffset len) {
|
||||
ctx->bytes_in += len;
|
||||
ctx->start += len;
|
||||
}
|
||||
|
||||
GString* chunk_extract(server *srv, connection *con, chunk_parser_mark from, chunk_parser_mark to) {
|
||||
GString *str = g_string_sized_new(0);
|
||||
chunk_parser_mark i;
|
||||
for ( i = from; i.ci.element != to.ci.element; chunkiter_next(&i.ci) ) {
|
||||
goffset len = chunkiter_length(i.ci);
|
||||
while (i.pos < len) {
|
||||
char *buf;
|
||||
off_t we_have;
|
||||
if (HANDLER_GO_ON != chunkiter_read(srv, con, i.ci, i.pos, len - i.pos, &buf, &we_have)) goto error;
|
||||
g_string_append_len(str, buf, we_have);
|
||||
i.pos += we_have;
|
||||
}
|
||||
i.pos = 0;
|
||||
}
|
||||
while (i.pos < to.pos) {
|
||||
char *buf;
|
||||
off_t we_have;
|
||||
if (HANDLER_GO_ON != chunkiter_read(srv, con, i.ci, i.pos, to.pos - i.pos, &buf, &we_have)) goto error;
|
||||
g_string_append_len(str, buf, we_have);
|
||||
i.pos += we_have;
|
||||
}
|
||||
|
||||
return str;
|
||||
|
||||
error:
|
||||
g_string_free(str, TRUE);
|
||||
return NULL;
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
#ifndef _LIGHTTPD_CHUNK_PARSER_H_
|
||||
#define _LIGHTTPD_CHUNK_PARSER_H_
|
||||
|
||||
struct chunk_parser_ctx;
|
||||
typedef struct chunk_parser_ctx chunk_parser_ctx;
|
||||
|
||||
struct chunk_parser_mark;
|
||||
typedef struct chunk_parser_mark chunk_parser_mark;
|
||||
|
||||
#include "chunk.h"
|
||||
|
||||
struct chunk_parser_ctx {
|
||||
chunkqueue *cq;
|
||||
|
||||
goffset bytes_in;
|
||||
|
||||
/* current position
|
||||
* buf is curi[start..start+length)
|
||||
*/
|
||||
chunkiter curi;
|
||||
off_t start, length;
|
||||
char *buf;
|
||||
|
||||
int cs;
|
||||
};
|
||||
|
||||
struct chunk_parser_mark {
|
||||
chunkiter ci;
|
||||
off_t pos;
|
||||
};
|
||||
|
||||
LI_API void chunk_parser_init(chunk_parser_ctx *ctx, chunkqueue *cq);
|
||||
LI_API handler_t chunk_parser_prepare(chunk_parser_ctx *ctx);
|
||||
LI_API handler_t chunk_parser_next(server *srv, connection *con, chunk_parser_ctx *ctx, char **p, char **pe);
|
||||
LI_API void chunk_parser_done(chunk_parser_ctx *ctx, goffset len);
|
||||
|
||||
LI_API GString* chunk_extract(server *srv, connection *con, chunk_parser_mark from, chunk_parser_mark to);
|
||||
|
||||
INLINE chunk_parser_mark chunk_parser_getmark(chunk_parser_ctx *ctx, const char *fpc);
|
||||
|
||||
/********************
|
||||
* Inline functions *
|
||||
********************/
|
||||
|
||||
INLINE chunk_parser_mark chunk_parser_getmark(chunk_parser_ctx *ctx, const char *fpc) {
|
||||
chunk_parser_mark m;
|
||||
m.ci = ctx->curi;
|
||||
m.pos = ctx->start + fpc - ctx->buf;
|
||||
return m;
|
||||
}
|
||||
|
||||
#define GETMARK(FPC) (chunk_parser_getmark(&ctx->chunk_ctx, FPC))
|
||||
|
||||
#endif
|
|
@ -281,6 +281,8 @@ static gboolean condition_check_eval_int(server *srv, connection *con, condition
|
|||
assert(NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
|
||||
#include "http_headers.h"
|
||||
|
||||
static void _string_free(gpointer p) {
|
||||
g_string_free((GString*) p, TRUE);
|
||||
}
|
||||
|
||||
http_headers* http_headers_new() {
|
||||
http_headers* headers = g_slice_new0(http_headers);
|
||||
headers->table = g_hash_table_new_full(
|
||||
(GHashFunc) g_string_hash, (GEqualFunc) g_string_equal,
|
||||
_string_free, _string_free);
|
||||
return headers;
|
||||
}
|
||||
|
||||
void http_headers_free(http_headers* headers) {
|
||||
if (!headers) return;
|
||||
g_hash_table_destroy(headers->table);
|
||||
g_slice_free(http_headers, headers);
|
||||
}
|
||||
|
||||
/* Just insert the header (using lokey)
|
||||
*/
|
||||
static void header_insert(http_headers *headers, GString *lokey, GString *key, GString *value) {
|
||||
GString *newval = g_string_sized_new(key->len + value->len + 2);
|
||||
|
||||
g_string_append_len(newval, key->str, key->len);
|
||||
g_string_append_len(newval, ": ", 2);
|
||||
g_string_append_len(newval, value->str, value->len);
|
||||
|
||||
g_hash_table_insert(headers->table, lokey, newval);
|
||||
}
|
||||
|
||||
/** If header does not exist, just insert normal header. If it exists, append (", %s", value) */
|
||||
void http_header_append(http_headers *headers, GString *key, GString *value) {
|
||||
GString *lokey, *tval;
|
||||
|
||||
lokey = g_string_new_len(key->str, key->len);
|
||||
g_string_ascii_down(lokey);
|
||||
tval = (GString*) g_hash_table_lookup(headers->table, lokey);
|
||||
if (!tval) {
|
||||
header_insert(headers, lokey, key, value);
|
||||
} else {
|
||||
g_string_free(lokey, TRUE);
|
||||
g_string_append_len(tval, ", ", 2);
|
||||
g_string_append_len(tval, value->str, value->len);
|
||||
}
|
||||
}
|
||||
|
||||
/** If header does not exist, just insert normal header. If it exists, append ("\r\n%s: %s", key, value) */
|
||||
void http_header_insert(http_headers *headers, GString *key, GString *value) {
|
||||
GString *lokey, *tval;
|
||||
|
||||
lokey = g_string_new_len(key->str, key->len);
|
||||
g_string_ascii_down(lokey);
|
||||
tval = (GString*) g_hash_table_lookup(headers->table, lokey);
|
||||
if (!tval) {
|
||||
header_insert(headers, lokey, key, value);
|
||||
} else {
|
||||
g_string_free(lokey, TRUE);
|
||||
g_string_append_len(tval, "\r\n", 2);
|
||||
g_string_append_len(tval, key->str, key->len);
|
||||
g_string_append_len(tval, ": ", 2);
|
||||
g_string_append_len(tval, value->str, value->len);
|
||||
}
|
||||
}
|
||||
|
||||
/** If header does not exist, just insert normal header. If it exists, overwrite the value */
|
||||
void http_header_overwrite(http_headers *headers, GString *key, GString *value) {
|
||||
GString *lokey, *tval;
|
||||
|
||||
lokey = g_string_new_len(key->str, key->len);
|
||||
g_string_ascii_down(lokey);
|
||||
tval = (GString*) g_hash_table_lookup(headers->table, lokey);
|
||||
if (!tval) {
|
||||
header_insert(headers, lokey, key, value);
|
||||
} else {
|
||||
g_string_free(lokey, TRUE);
|
||||
g_string_truncate(tval, 0);
|
||||
g_string_append_len(tval, key->str, key->len);
|
||||
g_string_append_len(tval, ": ", 2);
|
||||
g_string_append_len(tval, value->str, value->len);
|
||||
}
|
||||
}
|
||||
|
||||
LI_API gboolean http_header_remove(http_headers *headers, GString *key) {
|
||||
GString *lokey;
|
||||
gboolean res;
|
||||
|
||||
lokey = g_string_new_len(key->str, key->len);
|
||||
g_string_ascii_down(lokey);
|
||||
res = g_hash_table_remove(headers->table, lokey);
|
||||
g_string_free(lokey, TRUE);
|
||||
return res;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef _LIGHTTPD_HTTP_HEADERS_H_
|
||||
#define _LIGHTTPD_HTTP_HEADERS_H_
|
||||
|
||||
struct http_headers;
|
||||
typedef struct http_headers http_headers;
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
struct http_headers {
|
||||
/** keys are lowercase header name, values contain the complete header */
|
||||
GHashTable *table;
|
||||
};
|
||||
|
||||
/* strings alweays get copied, so you should free key and value yourself */
|
||||
|
||||
LI_API http_headers* http_headers_new();
|
||||
LI_API void http_headers_free(http_headers* headers);
|
||||
|
||||
/** If header does not exist, just insert normal header. If it exists, append (", %s", value) */
|
||||
LI_API void http_header_append(http_headers *headers, GString *key, GString *value);
|
||||
/** If header does not exist, just insert normal header. If it exists, append ("\r\n%s: %s", key, value) */
|
||||
LI_API void http_header_insert(http_headers *headers, GString *key, GString *value);
|
||||
/** If header does not exist, just insert normal header. If it exists, overwrite the value */
|
||||
LI_API void http_header_overwrite(http_headers *headers, GString *key, GString *value);
|
||||
LI_API gboolean http_header_remove(http_headers *headers, GString *key);
|
||||
|
||||
#endif
|
|
@ -4,23 +4,15 @@
|
|||
struct http_request_ctx;
|
||||
typedef struct http_request_ctx http_request_ctx;
|
||||
|
||||
#include "chunks.h"
|
||||
#include "chunk_parser.h"
|
||||
#include "request.h"
|
||||
|
||||
struct http_request_ctx {
|
||||
chunkqueue *cq;
|
||||
|
||||
goffset bytes_in;
|
||||
|
||||
/* current position
|
||||
* buf is curi[start..start+length)
|
||||
*/
|
||||
chunkiter curi;
|
||||
off_t start, length;
|
||||
char *buf;
|
||||
|
||||
int cs;
|
||||
chunk_parser_ctx chunk_ctx;
|
||||
|
||||
chunk_parser_mark mark;
|
||||
|
||||
request *request;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,55 +1,109 @@
|
|||
|
||||
#include "http_request_parser.h"
|
||||
|
||||
static chunk_parser_mark getmark(http_request_ctx *ctx, const char *fpc) {
|
||||
chunk_parser_mark m;
|
||||
m.ci = ctx->curi;
|
||||
m.pos = ctx->start + fpc - ctx->buf;
|
||||
return m;
|
||||
}
|
||||
|
||||
/** Machine **/
|
||||
|
||||
#define _getString(M, FPC) (chunk_extract(srv, con, ctx->M, GETMARK(FPC)))
|
||||
#define getString(FPC) _getString(mark, FPC)
|
||||
|
||||
%%{
|
||||
|
||||
machine http_request_parser;
|
||||
variable cs ctx->chunk_ctx.cs;
|
||||
|
||||
CRLF = "\r\n";
|
||||
action mark { ctx->mark = GETMARK(fpc); }
|
||||
action done { fbreak; }
|
||||
|
||||
action mark { ctx->mark = getmark(ctx, fpc); }
|
||||
action method { ctx->request->http_method_str = getString(fpc); }
|
||||
action uri { ctx->request->uri.uri = getString(fpc); }
|
||||
|
||||
main := CRLF ;
|
||||
# RFC 2616
|
||||
OCTET = any;
|
||||
CHAR = ascii;
|
||||
UPALPHA = upper;
|
||||
LOALPHA = lower;
|
||||
ALPHA = alpha;
|
||||
DIGIT = digit;
|
||||
CTL = ( 0 .. 31 | 127 );
|
||||
CR = '\r';
|
||||
LF = '\n';
|
||||
SP = ' ';
|
||||
HT = '\t';
|
||||
DQUOTE = '"';
|
||||
|
||||
CRLF = CR LF;
|
||||
LWS = CRLF? (SP | HT)+; # linear white space
|
||||
TEXT = (OCTET - CTL) | LWS;
|
||||
HEX = [a-fA-F0-9];
|
||||
|
||||
Separators = [()<>@,;:\\\"/\[\]?={}] | SP | HT;
|
||||
Token = OCTET - Separators - CTL;
|
||||
|
||||
# original definition
|
||||
# Comment = "(" ( CText | Quoted_Pair | Comment )* ")";
|
||||
# CText = TEXT - [()];
|
||||
|
||||
Quoted_Pair = "\\" CHAR;
|
||||
Comment = ( TEXT | Quoted_Pair )*;
|
||||
QDText = TEXT - DQUOTE;
|
||||
Quoted_String = DQUOTE ( QDText | Quoted_Pair )* DQUOTE;
|
||||
|
||||
HTTP_Version = "HTTP" "/" DIGIT+ "." DIGIT+;
|
||||
#HTTP_URL = "http:" "//" Host ( ":" Port )? ( abs_path ( "?" query )? )?;
|
||||
|
||||
# RFC 2396
|
||||
|
||||
Mark = [\-_!~*\'()];
|
||||
Unreserved = alnum | Mark;
|
||||
Escaped = "%" HEX HEX;
|
||||
|
||||
PChar = Unreserved | Escaped | [:@&=+$,];
|
||||
Segment = PChar* ( ";" PChar* )*;
|
||||
Path_Segments = Segment ("/" Segment)*;
|
||||
Abs_Path = "/" Path_Segments;
|
||||
|
||||
Method = Token >mark %method;
|
||||
Request_URI = ("*" | ( any - CTL - SP )) >mark %uri;
|
||||
Request_Line = Method " " Request_URI " " HTTP_Version CRLF;
|
||||
|
||||
Field_Content = ( TEXT+ | ( Token | Separators | Quoted_String )+ );
|
||||
Field_Value = " "* (Field_Content+ ( Field_Content | LWS )*)? >mark;
|
||||
Message_Header = Token ":" Field_Value?;
|
||||
|
||||
main := (CRLF)* Request_Line (Message_Header CRLF)* CRLF @ done;
|
||||
}%%
|
||||
|
||||
%% write data;
|
||||
|
||||
void http_request_parse(server *srv, connection *con, http_request_ctx *ctx) {
|
||||
int cs = ctx->cs;
|
||||
while (cs != http_request_parser_error && cs != http_request_parser_first_final) {
|
||||
static int http_request_parser_has_error(http_request_ctx *ctx) {
|
||||
return ctx->chunk_ctx.cs == http_request_parser_error;
|
||||
}
|
||||
|
||||
static int http_request_parser_is_finished(http_request_ctx *ctx) {
|
||||
return ctx->chunk_ctx.cs >= http_request_parser_first_final;
|
||||
}
|
||||
|
||||
void http_request_parser_init(http_request_ctx *ctx, chunkqueue *cq) {
|
||||
%% write init;
|
||||
chunk_parser_init(&ctx->chunk_ctx, cq);
|
||||
}
|
||||
|
||||
handler_t http_request_parse(server *srv, connection *con, http_request_ctx *ctx) {
|
||||
handler_t res;
|
||||
|
||||
if (HANDLER_GO_ON != (res = chunk_parser_prepare(&ctx->chunk_ctx))) return res;
|
||||
|
||||
while (!http_request_parser_has_error(ctx) && !http_request_parser_is_finished(ctx)) {
|
||||
char *p, *pe;
|
||||
off_t l;
|
||||
|
||||
l = chunkiter_length(ctx->curi);
|
||||
if (ctx->start >= l) {
|
||||
chunkiter_next(&ctx->curi);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (HANDLER_GO_ON != chunkiter_read(srv, con, ctx->curi, ctx->start, l - ctx->start, &ctx->buf, &ctx->length)) {
|
||||
return;
|
||||
}
|
||||
|
||||
p = ctx->buf;
|
||||
pe = ctx->buf + ctx->length;
|
||||
if (HANDLER_GO_ON != (res = chunk_parser_next(srv, con, &ctx->chunk_ctx, &p, &pe))) return res;
|
||||
|
||||
%% write exec;
|
||||
|
||||
ctx->start += pe - p;
|
||||
ctx->bytes_in += pe - p;
|
||||
if (ctx->start >= l) {
|
||||
chunkiter_next(&ctx->curi);
|
||||
ctx->start = 0;
|
||||
}
|
||||
chunk_parser_done(&ctx->chunk_ctx, pe - p);
|
||||
}
|
||||
ctx->cs = cs;
|
||||
|
||||
if (http_request_parser_has_error(ctx)) return HANDLER_ERROR;
|
||||
if (http_request_parser_is_finished(ctx)) return HANDLER_GO_ON;
|
||||
return HANDLER_ERROR;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
#include "request.h"
|
||||
|
||||
request* request_new() {
|
||||
request *req = g_slice_new0(request);
|
||||
}
|
||||
|
||||
void request_free(request *req) {
|
||||
/* TODO */
|
||||
g_slice_free(request, req);
|
||||
}
|
|
@ -43,6 +43,8 @@ typedef struct request_uri request_uri;
|
|||
struct physical;
|
||||
typedef struct physical physical;
|
||||
|
||||
#include "http_headers.h"
|
||||
|
||||
struct request_uri {
|
||||
GString *uri, *orig_uri;
|
||||
|
||||
|
@ -70,10 +72,13 @@ struct request {
|
|||
|
||||
request_uri uri;
|
||||
|
||||
GArray *headers;
|
||||
http_headers *headers;
|
||||
/* Parsed headers: */
|
||||
GString *host;
|
||||
goffset content_length;
|
||||
};
|
||||
|
||||
LI_API request* request_new();
|
||||
LI_API void request_free(request *req);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
#include "base.h"
|
||||
|
||||
int request_test() {
|
||||
}
|
||||
|
||||
int main() {
|
||||
return 0;
|
||||
}
|
12
src/wscript
12
src/wscript
|
@ -9,8 +9,10 @@ common_uselib = 'glib '
|
|||
common_source='''
|
||||
actions.c
|
||||
base.c
|
||||
chunks.c
|
||||
chunk.c
|
||||
chunk_parser.c
|
||||
condition.c
|
||||
http_headers.c
|
||||
http_request_parser.rl
|
||||
log.c
|
||||
options.c
|
||||
|
@ -119,6 +121,14 @@ def build(bld):
|
|||
#lighty_mod(bld, 'mod_magnet', 'mod_magnet.c mod_magnet_cache.c', uselib = 'lua')
|
||||
#lighty_mod(bld, 'mod_deflate', 'mod_deflate.c', uselib = 'bzip zlib')
|
||||
#lighty_mod(bld, 'mod_webdav', 'mod_webdav.c', uselib = 'sqlite3 xml uuid')
|
||||
|
||||
tests = bld.new_task_gen('cc', 'program')
|
||||
tests.inst_var = 0
|
||||
tests.unit_test = 1
|
||||
tests.name = 'tests'
|
||||
tests.source = 'tests.c ' + common_source
|
||||
tests.target = 'tests'
|
||||
tests.uselib += 'lighty dl openssl pcre lua ' + common_uselib
|
||||
|
||||
def configure(conf):
|
||||
env = conf.env
|
||||
|
|
46
wscript
46
wscript
|
@ -449,46 +449,12 @@ class TestObject:
|
|||
return self.label
|
||||
|
||||
def run_tests():
|
||||
import UnitTest, Object
|
||||
env = Params.g_build.env()
|
||||
srctestnode = Params.g_build.m_srcnode.find_dir('tests')
|
||||
prepare = srctestnode.find_source('prepare.sh')
|
||||
runtests = srctestnode.find_source('run-tests.pl')
|
||||
cleanup = srctestnode.find_source('cleanup.sh')
|
||||
|
||||
print
|
||||
|
||||
import os
|
||||
os.environ['srcdir'] = srctestnode.abspath()
|
||||
os.environ['top_builddir'] = srctestnode.m_parent.abspath(env)
|
||||
if Params.g_options.verbose: os.environ['VERBOSE'] = '1'
|
||||
|
||||
Runner.exec_command_interact(prepare.abspath())
|
||||
print
|
||||
|
||||
singletest = '' # '*.t' or '.t' or ''
|
||||
if singletest:
|
||||
objsave = Object.g_allobjs
|
||||
|
||||
tests = []
|
||||
for f in srctestnode.files():
|
||||
if f.m_name.endswith(singletest):
|
||||
tests.append(TestObject(f.m_name, f.abspath()))
|
||||
Object.g_allobjs = tests
|
||||
|
||||
unittest = UnitTest.unit_test()
|
||||
unittest.want_to_see_test_output = Params.g_options.verbose
|
||||
unittest.want_to_see_test_error = Params.g_options.verbose
|
||||
unittest.run()
|
||||
unittest.print_results()
|
||||
|
||||
Object.g_allobjs = objsave
|
||||
else:
|
||||
Runner.exec_command_interact(runtests.abspath())
|
||||
print
|
||||
|
||||
Runner.exec_command_interact(cleanup.abspath())
|
||||
print
|
||||
import UnitTest
|
||||
unittest = UnitTest.unit_test()
|
||||
unittest.want_to_see_test_output = Params.g_options.verbose
|
||||
unittest.want_to_see_test_error = Params.g_options.verbose
|
||||
unittest.run()
|
||||
unittest.print_results()
|
||||
|
||||
def shutdown():
|
||||
if Params.g_commands['check']: run_tests()
|
||||
|
|
Loading…
Reference in New Issue