[英]Apache Module: Output Keeps Growing on Each Request
I have an idea for a project based on the Apache module API. 我对基于Apache模块API的项目有一个想法。 So, I am writing my first Apache module to learn the API- just a simple hostname lookup:
因此,我正在编写我的第一个Apache模块以学习API-只是一个简单的主机名查找:
URL: http://localhost/hostname/stackoverflow.com
Response data:
Host: stackoverflow.com
Address: 69.59.196.211
Address type: AF_INET
When the request does not include a hostname after the handler path, I just want the Response data to say: 当请求在处理程序路径之后不包含主机名时,我只希望Response数据说:
"Hostname not found in request."
“在请求中找不到主机名。”
All of this is working, except one thing: the error response keeps getting appended to on subsequent requests that produce the error result. 所有这一切都有效,除了一件事:错误响应不断附在产生错误结果的后续请求上。 This does not happen with the hostname lookup result (when the hostname is provided).
主机名查找结果不会发生这种情况(提供主机名时)。 Example of the issue:
问题示例:
Request 1: http://192.168.1.3/hostname
Response data:
Hostname not found in request.
Request 2: http://192.168.1.3/hostname
Response data:
Hostname not found in request.
Hostname not found in request.
Request 3: http://192.168.1.3/hostname
Response data:
Hostname not found in request.
Hostname not found in request.
Hostname not found in request.
I'm sure I've done something wrong with my output buffer in the error case - anyone able to point out the problem? 在发生错误的情况下,我确定我的输出缓冲区做错了什么—有人能指出问题吗? Here is the code:
这是代码:
#include <sys/types.h>
#include <netdb.h>
#include <stdio.h>
#include <stdarg.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "httpd.h"
#include "http_log.h"
#include "http_config.h"
static void log_info(request_rec *r, const char *fmt, ...){
char log_msg[100];
memset(log_msg,100,0x00);
va_list args;
va_start(args,fmt);
vsprintf(log_msg,fmt,args);
va_end(args);
ap_log_error(APLOG_MARK,APLOG_INFO,APR_SUCCESS,r->server,log_msg,NULL);
}
static void log_err(request_rec *r, const char *fmt, ...){
char log_msg[100];
memset(log_msg,100,0x00);
va_list args;
va_start(args,fmt);
vsprintf(log_msg,fmt,args);
va_end(args);
ap_log_error(APLOG_MARK,APLOG_ERR,APR_SUCCESS,r->server,log_msg,NULL);
}
int count_chrinstr(const char *haystack, const char needle){
int n=0;
char *next;
while( (next=strchr(haystack,needle)) != NULL ){
haystack=next+1;
n++;
}
return n;
}
void parse_uri(char *uri, char *pieces[]){
int i=0;
char *next_tok=strtok(uri,"/");
while( next_tok != NULL ){
pieces[i]=next_tok;
i++;
next_tok=strtok(NULL,"/");
}
}
void lookup_hostname(request_rec *r, char *output){
int num_parts=count_chrinstr(r->uri,'/');
log_info(r,"Number of parts: %d",num_parts);
if(num_parts<2){
log_err(r,"Hostname not found in request, exiting.",NULL);
strcat(output,"Hostname not found in request.<br>\n");
return;
}
char *pieces[num_parts];
parse_uri(r->uri,pieces);
char *host_entered=pieces[1];
struct hostent *h=gethostbyname(host_entered);
//host
output += sprintf(output,"Host: %s<br>\n", h->h_name);
//aliases
int i=0;
while(h->h_aliases[i] != NULL){
output += sprintf(output,"Alias: %s<br>\n",h->h_aliases[i]);
i++;
}
//addresses
i=0;
while(h->h_addr_list[i] != NULL){
char *net_addr=inet_ntoa( *(struct in_addr*)(h->h_addr_list[i]));
output += sprintf(output,"Address: %s<br>\n",net_addr);
i++;
}
log_info(r,"Added addresses to output.",NULL);
//address type
if(h->h_addrtype != NULL){
switch(h->h_addrtype){
case 2:
strcat(output,"Address type: AF_INET<br>\n");
break;
case 10:
strcat(output,"Address type: AF_INET6<br>\n");
break;
default:
strcat(output,"Address type: Unknown<br>\n");
break;
}
}
}
static int hostname_handler(request_rec *r) {
if (!r->handler || strcasecmp(r->handler, "hostname") != 0) {
return DECLINED;
}
if (r->method_number != M_GET) {
return HTTP_METHOD_NOT_ALLOWED;
}
char result[10000];
memset(result,10000,0x00);
log_info(r,"Starting hostname lookup.",NULL);
lookup_hostname(r,result);
ap_set_content_type(r, "text/html");
ap_rputs(result, r);
ap_finalize_request_protocol(r);
return OK;
}
static void hostname_hooks(apr_pool_t *pool) {
ap_hook_handler(hostname_handler, NULL, NULL, APR_HOOK_MIDDLE);
}
module AP_MODULE_DECLARE_DATA hostname_module = {
STANDARD20_MODULE_STUFF,
NULL,
NULL,
NULL,
NULL,
NULL,
hostname_hooks
};
Thanks in advance, 提前致谢,
-aj -AJ
You have the parameters to memset
around the wrong way: 你有参数
memset
周围的错误的方式:
memset(result,10000,0x00);
That line uses a count of zero, which means it does nothing. 该行的计数为零,这意味着它什么也不做。 Instead of using memset, you could just do this:
除了使用memset之外,您还可以这样做:
char result[10000] = { 0 };
This will initialise the entire array to zero (objects in C are never partially initialised). 这会将整个数组初始化为零(C中的对象永远不会部分初始化)。
Alternatively, you could set just the first character to zero, since that will also make strcat
do the right thing: 另外,您可以将第一个字符设置为零,因为这也会使
strcat
做正确的事情:
char result[10000];
result[0] = '\0';
(Also, you should be passing the buffer size to lookup_hostname
and using strncat
/ snprintf
instead of strcat
/ sprintf
). (此外,您应该将缓冲区大小传递给
lookup_hostname
并使用strncat
/ snprintf
而不是strcat
/ sprintf
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.