1

我为 Lighttpd 制作了一个简单的模块来试验它。如果我只是登录到我的计算机的 IP 地址(从另一台计算机)并且我计算机中的网络服务器(lighttpd)应该发送一个简单的响应。该模块的源代码如下:

#include "base.h"
#include "log.h"
#include "buffer.h"
#include <stdio.h>
#include "plugin.h"
#include<sys/stat.h>
#include<sys/types.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "stat_cache.h"
#include "etag.h"
#include "http_chunk.h"
#include "response.h"
/* plugin config for all request/connections */


typedef struct {
    array *match;
} plugin_config;



typedef struct {
    PLUGIN_DATA;

    buffer *match_buf;

    plugin_config **config_storage;

    plugin_config conf;
} plugin_data;



typedef struct {
    size_t foo;
} handler_ctx;



static handler_ctx * handler_ctx_init() {
    handler_ctx * hctx;

    hctx = calloc(1, sizeof(*hctx));

    return hctx;
}



static void handler_ctx_free(handler_ctx *hctx) {

    free(hctx);
}

/* init the plugin data */
INIT_FUNC(mod_helloworld_init) {
    plugin_data *p;

    p = calloc(1, sizeof(*p));

    p->match_buf = buffer_init();

    return p;
}



/* detroy the plugin data */
FREE_FUNC(mod_helloworld_free) {
    plugin_data *p = p_d;

    UNUSED(srv);

    if (!p) return HANDLER_GO_ON;

    if (p->config_storage) {
        size_t i;

        for (i = 0; i < srv->config_context->used; i++) {
            plugin_config *s = p->config_storage[i];

            if (!s) continue;

            array_free(s->match);

            free(s);
        }
        free(p->config_storage);
    }

    buffer_free(p->match_buf);

    free(p);

    return HANDLER_GO_ON;
}



/* handle plugin config and check values */

SETDEFAULTS_FUNC(mod_helloworld_set_defaults) {
    plugin_data *p = p_d;
    size_t i = 0;

    config_values_t cv[] = {
    { "helloworld.array",NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION},       /* 0 */
    { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
    };

    if (!p) return HANDLER_ERROR;

    p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));

    for (i = 0; i < srv->config_context->used; i++) {
        plugin_config *s;

        s = calloc(1, sizeof(plugin_config));
        s->match    = array_init();

        cv[0].destination = s->match;

        p->config_storage[i] = s;

        if (0 != config_insert_values_global(srv, ((data_config*)srv->config_context->data[i])->value, cv)) {
            return HANDLER_ERROR;
        }
    }

    return HANDLER_GO_ON;
}

#define PATCH(x) \
    p->conf.x = s->x;
static int mod_helloworld_patch_connection(server *srv, connection *con, plugin_data *p) {
    size_t i, j;
    plugin_config *s = p->config_storage[0];

    PATCH(match);

    /* skip the first, the global context */
    for (i = 1; i < srv->config_context->used; i++) {
        data_config *dc = (data_config *)srv->config_context->data[i];
        s = p->config_storage[i];

        /* condition didn't match */
        if (!config_check_cond(srv, con, dc)) continue;

        /* merge config */
        for (j = 0; j < dc->value->used; j++) {
            data_unset *du = dc->value->data[j];

            if (buffer_is_equal_string(du->key, CONST_STR_LEN("helloworld.array"))) {
                PATCH(match);
            }
        }
    }

    return 0;
}
#undef PATCH

URIHANDLER_FUNC(mod_helloworld_uri_handler) {


UNUSED(p_d);

// Send body data to requestor
char buffer[] = { '<', 'h', 't', 'm', 'l', '>' , '<', 'h', 'e', 'a', 'd', '>', '<', 't', 'i', 't', 'l', 'e', '>', '1', '<', '/', 't', 'i', 't', 'l', 'e', '>', '<', '/', 'h', 'e', 'a', 'd', '>', '<', '/', 'h', 't', 'm', 'l', '>'};

    char textValue[32];
    sprintf(textValue, "%d", sizeof(buffer));

response_header_overwrite(srv, con, CONST_STR_LEN("Content-Length"), textValue, strlen(textValue));
chunkqueue_append_mem(con->write_queue, buffer, sizeof(buffer)); 

//
con->http_status = 200;
return HANDLER_FINISHED;

}


int mod_helloworld_plugin_init(plugin *p) {
    p->version     = LIGHTTPD_VERSION_ID;
    p->name        = buffer_init_string("helloworld");

    p->init        = mod_helloworld_init;
    p->handle_subrequest_start  = mod_helloworld_uri_handler;
    p->set_defaults  = mod_helloworld_set_defaults;
    p->cleanup     = mod_helloworld_free;

    p->data        = NULL;

    return 0;
}

通过使用此模块,Web 服务器应该响应标题为“1”的 html 页面。但是现在我看到 lighttpd 发送响应的时间很晚,因此请求有时会超时。我不太明白有什么问题。任何人都可以检查并帮助我解决它吗?我想只有 Lighttpd 的用户可能知道这个问题的解决方案。即使没有使用 Lighttpd,如果有人可以帮助我解决这个问题,我也会很感激。谢谢你。

4

1 回答 1

2

尝试添加:

con->file_finished = 1;

后:

con->http_status = 200;

That tells the engine that the request is complete (why HANDLER_FINISHED doesn't do that is a question for another day).

于 2012-06-16T20:38:13.077 回答