summaryrefslogtreecommitdiffstats
path: root/debian/perl-framework/c-modules/nntp_like/mod_nntp_like.c
diff options
context:
space:
mode:
Diffstat (limited to 'debian/perl-framework/c-modules/nntp_like/mod_nntp_like.c')
-rw-r--r--debian/perl-framework/c-modules/nntp_like/mod_nntp_like.c181
1 files changed, 181 insertions, 0 deletions
diff --git a/debian/perl-framework/c-modules/nntp_like/mod_nntp_like.c b/debian/perl-framework/c-modules/nntp_like/mod_nntp_like.c
new file mode 100644
index 0000000..0fad8ce
--- /dev/null
+++ b/debian/perl-framework/c-modules/nntp_like/mod_nntp_like.c
@@ -0,0 +1,181 @@
+#define HTTPD_TEST_REQUIRE_APACHE 2
+
+/*
+ * purpose of this module is to test protocol modules that need to
+ * send data to the client before reading any request data.
+ * in this case, mod_ssl needs to handshake before sending data to the client.
+ * t/protocol/nntp-like.t tests both with and without ssl
+ * to make sure the protocol code works in both cases.
+ */
+
+#if CONFIG_FOR_HTTPD_TEST
+
+<VirtualHost mod_nntp_like>
+ NNTPLike On
+</VirtualHost>
+
+<IfModule @ssl_module@>
+ <VirtualHost mod_nntp_like_ssl>
+ NNTPLike On
+ SSLEngine On
+ </VirtualHost>
+</IfModule>
+
+#endif
+
+#include "httpd.h"
+#include "http_config.h"
+#include "http_protocol.h"
+#include "http_connection.h"
+#include "http_request.h"
+#include "http_log.h"
+#include "ap_config.h"
+#include "util_filter.h"
+#include "apr_buckets.h"
+#include "apr_strings.h"
+
+module AP_MODULE_DECLARE_DATA nntp_like_module;
+
+typedef struct {
+ int enabled;
+} nntp_like_srv_cfg_t;
+
+static void *nntp_like_srv_cfg_create(apr_pool_t *p, server_rec *s)
+{
+ nntp_like_srv_cfg_t *cfg = apr_palloc(p, sizeof(*cfg));
+
+ cfg->enabled = 0;
+
+ return cfg;
+}
+
+static const char *nntp_like_cmd_enable(cmd_parms *cmd, void *dummy, int arg)
+{
+ nntp_like_srv_cfg_t *cfg =
+ ap_get_module_config(cmd->server->module_config,
+ &nntp_like_module);
+ cfg->enabled = arg;
+
+ return NULL;
+}
+
+/* this function just triggers the SSL handshake.
+ * normally that would happen in a protocol such as HTTP when
+ * the client request is read. however, with certain protocols
+ * such as NNTP, the server sends a response before the client
+ * sends a request
+ *
+ * if SSL is not enabled, this function is a noop
+ */
+static apr_status_t nntp_like_init_connection(conn_rec *c)
+{
+ apr_bucket_brigade *bb;
+ apr_status_t rv;
+
+ bb = apr_brigade_create(c->pool, c->bucket_alloc);
+
+ rv = ap_get_brigade(c->input_filters, bb, AP_MODE_INIT,
+ APR_BLOCK_READ, 0);
+
+ apr_brigade_destroy(bb);
+
+ return rv;
+}
+
+static apr_status_t nntp_like_send_welcome(conn_rec *c)
+{
+ apr_bucket *bucket;
+ apr_bucket_brigade *bb = apr_brigade_create(c->pool, c->bucket_alloc);
+
+#define NNTP_LIKE_WELCOME \
+ "200 localhost - ready\r\n"
+
+ bucket = apr_bucket_immortal_create(NNTP_LIKE_WELCOME,
+ sizeof(NNTP_LIKE_WELCOME)-1,
+ c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(bb, bucket);
+ APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_flush_create(c->bucket_alloc));
+
+ return ap_pass_brigade(c->output_filters, bb);
+}
+
+static int nntp_like_pre_connection(conn_rec *c, void *csd)
+{
+ nntp_like_srv_cfg_t *cfg =
+ ap_get_module_config(c->base_server->module_config,
+ &nntp_like_module);
+
+ if (cfg->enabled) {
+ apr_socket_timeout_set(csd, c->base_server->keep_alive_timeout);
+ }
+
+ return DECLINED;
+}
+
+static int nntp_like_process_connection(conn_rec *c)
+{
+ apr_bucket_brigade *bb;
+ apr_status_t rv;
+ nntp_like_srv_cfg_t *cfg =
+ ap_get_module_config(c->base_server->module_config,
+ &nntp_like_module);
+
+ if (!cfg->enabled) {
+ return DECLINED;
+ }
+
+ /* handshake if talking over SSL */
+ if ((rv = nntp_like_init_connection(c)) != APR_SUCCESS) {
+ return rv;
+ }
+
+ /* send the welcome message */
+ if ((rv = nntp_like_send_welcome(c)) != APR_SUCCESS) {
+ return rv;
+ }
+
+ do {
+ bb = apr_brigade_create(c->pool, c->bucket_alloc);
+
+ if ((rv = ap_get_brigade(c->input_filters, bb,
+ AP_MODE_GETLINE,
+ APR_BLOCK_READ, 0)) != APR_SUCCESS ||
+ APR_BRIGADE_EMPTY(bb))
+ {
+ apr_brigade_destroy(bb);
+ break;
+ }
+
+ APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_flush_create(c->bucket_alloc));
+
+ rv = ap_pass_brigade(c->output_filters, bb);
+ } while (rv == APR_SUCCESS);
+
+ return OK;
+}
+
+static void nntp_like_register_hooks(apr_pool_t *p)
+{
+ ap_hook_pre_connection(nntp_like_pre_connection, NULL, NULL,
+ APR_HOOK_MIDDLE);
+ ap_hook_process_connection(nntp_like_process_connection,
+ NULL, NULL,
+ APR_HOOK_MIDDLE);
+}
+
+static const command_rec nntp_like_cmds[] =
+{
+ AP_INIT_FLAG("NNTPLike", nntp_like_cmd_enable, NULL, RSRC_CONF,
+ "enable nntp like protocol on this host"),
+ { NULL }
+};
+
+module AP_MODULE_DECLARE_DATA nntp_like_module = {
+ STANDARD20_MODULE_STUFF,
+ NULL, /* create per-dir config structures */
+ NULL, /* merge per-dir config structures */
+ nntp_like_srv_cfg_create, /* create per-server config structures */
+ NULL, /* merge per-server config structures */
+ nntp_like_cmds, /* table of config file commands */
+ nntp_like_register_hooks /* register hooks */
+};