设为首页 收藏本站
查看: 294|回复: 0

[经验分享] [转载] Apache模块开发/用C语言扩展apache(1:简述)

[复制链接]

尚未签到

发表于 2017-1-7 12:28:10 | 显示全部楼层 |阅读模式
 

        Apache是一个非常稳定而且非常open的web server,它的很多功能都可以通过plugin的方式去扩展。

  比如:mod_proxy使得apache可以作代理, mod_rewrite使得apache可以实现非常强大的url mapping和rewritting
  功能,你是否也想自己来开发一个apache module呢?网上这方面的文章非常的少,而且全是E文,
  希望我的这篇文章能够给你一些实质性的帮助。
          开发apache module之前,我们有必要先分析一下其源代码。

$ cd httpd-2.2.4/
$ ls
  其中:server/目录是apache核心程序的代码
              include/目录存放主要的头文件
              srclib/目录存放apr和apr-util代码(这两个是什么,后面介绍)
              modules/目录下存放目前已经有的各种module(可以看看这些代码先)

$ cd include/
  先分析一下apache的头文件

$ vi httpd.h
  第766行,这个结构非常的重要,后面编写模块时都要用到这个结构,所以分析一下。
  每个http request都会对应这个结构的一个实例。
  由于apache的源代码都有很详细的英文注释,所以我也不翻译了。

 
/**
* @brief A structure that represents the current request
*/
struct request_rec {
/** The pool associated with the request */
apr_pool_t *pool;
/** The connection to the client */
conn_rec *connection;
/** The virtual host for this request */
server_rec *server;
/** Pointer to the redirected request if this is an external redirect */
request_rec *next;
/** Pointer to the previous request if this is an internal redirect */
request_rec *prev;
/** Pointer to the main request if this is a sub-request
* (see http_request.h) */
request_rec *main;
/* Info about the request itself... we begin with stuff that only
* protocol.c should ever touch...
*/
/** First line of request */
char *the_request;
/** HTTP/0.9, "simple" request (e.g. GET /foo\n w/no headers) */
int assbackwards;
/** A proxy request (calculated during post_read_request/translate_name)
*  possible values PROXYREQ_NONE, PROXYREQ_PROXY, PROXYREQ_REVERSE,
*                  PROXYREQ_RESPONSE
*/
int proxyreq;
/** HEAD request, as opposed to GET */
int header_only;
/** Protocol string, as given to us, or HTTP/0.9 */
char *protocol;
/** Protocol version number of protocol; 1.1 = 1001 */
int proto_num;
/** Host, as set by full URI or Host: */
const char *hostname;
/** Time when the request started */
apr_time_t request_time;
/** Status line, if set by script */
const char *status_line;
/** Status line */
int status;
/* Request method, two ways; also, protocol, etc..  Outside of protocol.c,
* look, but don't touch.
*/
/** Request method (eg. GET, HEAD, POST, etc.) */
const char *method;
/** M_GET, M_POST, etc. */
int method_number;
/**
*  'allowed' is a bitvector of the allowed methods.
*
*  A handler must ensure that the request method is one that
*  it is capable of handling.  Generally modules should DECLINE
*  any request methods they do not handle.  Prior to aborting the
*  handler like this the handler should set r->allowed to the list
*  of methods that it is willing to handle.  This bitvector is used
*  to construct the "Allow:" header required for OPTIONS requests,
*  and HTTP_METHOD_NOT_ALLOWED and HTTP_NOT_IMPLEMENTED status codes.
*
*  Since the default_handler deals with OPTIONS, all modules can
*  usually decline to deal with OPTIONS.  TRACE is always allowed,
*  modules don't need to set it explicitly.
*
*  Since the default_handler will always handle a GET, a
*  module which does *not* implement GET should probably return
*  HTTP_METHOD_NOT_ALLOWED.  Unfortunately this means that a Script GET
*  handler can't be installed by mod_actions.
*/
apr_int64_t allowed;
/** Array of extension methods */
apr_array_header_t *allowed_xmethods;
/** List of allowed methods */
ap_method_list_t *allowed_methods;
/** byte count in stream is for body */
apr_off_t sent_bodyct;
/** body byte count, for easy access */
apr_off_t bytes_sent;
/** Last modified time of the requested resource */
apr_time_t mtime;
/* HTTP/1.1 connection-level features */
/** sending chunked transfer-coding */
int chunked;
/** The Range: header */
const char *range;
/** The "real" content length */
apr_off_t clength;
/** Remaining bytes left to read from the request body */
apr_off_t remaining;
/** Number of bytes that have been read  from the request body */
apr_off_t read_length;
/** Method for reading the request body
* (eg. REQUEST_CHUNKED_ERROR, REQUEST_NO_BODY,
*  REQUEST_CHUNKED_DECHUNK, etc...) */
int read_body;
/** reading chunked transfer-coding */
int read_chunked;
/** is client waiting for a 100 response? */
unsigned expecting_100;
/* MIME header environments, in and out.  Also, an array containing
* environment variables to be passed to subprocesses, so people can
* write modules to add to that environment.
*
* The difference between headers_out and err_headers_out is that the
* latter are printed even on error, and persist across internal redirects
* (so the headers printed for ErrorDocument handlers will have them).
*
* The 'notes' apr_table_t is for notes from one module to another, with no
* other set purpose in mind...
*/
/** MIME header environment from the request */
apr_table_t *headers_in;
/** MIME header environment for the response */
apr_table_t *headers_out;
/** MIME header environment for the response, printed even on errors and
* persist across internal redirects */
apr_table_t *err_headers_out;
/** Array of environment variables to be used for sub processes */
apr_table_t *subprocess_env;
/** Notes from one module to another */
apr_table_t *notes;
/* content_type, handler, content_encoding, and all content_languages
* MUST be lowercased strings.  They may be pointers to static strings;
* they should not be modified in place.
*/
/** The content-type for the current request */
const char *content_type;/* Break these out --- we dispatch on 'em */
/** The handler string that we use to call a handler function */
const char *handler;/* What we *really* dispatch on */
/** How to encode the data */
const char *content_encoding;
/** Array of strings representing the content languages */
apr_array_header_t *content_languages;
/** variant list validator (if negotiated) */
char *vlist_validator;
/** If an authentication check was made, this gets set to the user name. */
char *user;
/** If an authentication check was made, this gets set to the auth type. */
char *ap_auth_type;
/** This response can not be cached */
int no_cache;
/** There is no local copy of this response */
int no_local_copy;
/* What object is being requested (either directly, or via include
* or content-negotiation mapping).
*/
/** The URI without any parsing performed */
char *unparsed_uri;
/** The path portion of the URI, or "/" if no path provided */
char *uri;
/** The filename on disk corresponding to this response */
char *filename;
/* XXX: What does this mean? Please define "canonicalize" -aaron */
/** The true filename, we canonicalize r->filename if these don't match */
char *canonical_filename;
/** The PATH_INFO extracted from this request */
char *path_info;
/** The QUERY_ARGS extracted from this request */
char *args;
/**  finfo.protection (st_mode) set to zero if no such file */
apr_finfo_t finfo;
/** A struct containing the components of URI */
apr_uri_t parsed_uri;
/**
* Flag for the handler to accept or reject path_info on
* the current request.  All modules should respect the
* AP_REQ_ACCEPT_PATH_INFO and AP_REQ_REJECT_PATH_INFO
* values, while AP_REQ_DEFAULT_PATH_INFO indicates they
* may follow existing conventions.  This is set to the
* user's preference upon HOOK_VERY_FIRST of the fixups.
*/
int used_path_info;
/* Various other config info which may change with .htaccess files
* These are config vectors, with one void* pointer for each module
* (the thing pointed to being the module's business).
*/
/** Options set in config files, etc. */
struct ap_conf_vector_t *per_dir_config;
/** Notes on *this* request */
struct ap_conf_vector_t *request_config;
/**
* A linked list of the .htaccess configuration directives
* accessed by this request.
* N.B. always add to the head of the list, _never_ to the end.
* that way, a sub request's list can (temporarily) point to a parent's list
*/
const struct htaccess_result *htaccess;
/** A list of output filters to be used for this request */
struct ap_filter_t *output_filters;
/** A list of input filters to be used for this request */
struct ap_filter_t *input_filters;
/** A list of protocol level output filters to be used for this
*  request */
struct ap_filter_t *proto_output_filters;
/** A list of protocol level input filters to be used for this
*  request */
struct ap_filter_t *proto_input_filters;
/** A flag to determine if the eos bucket has been sent yet */
int eos_sent;
/* Things placed at the end of the record to avoid breaking binary
* compatibility.  It would be nice to remember to reorder the entire
* record to improve 64bit alignment the next time we need to break
* binary compatibility for some other reason.
*/
};
   可以看到源码中有很多apr_开头的结构,这个是什么呢?下节介绍一下。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-325124-1-1.html 上篇帖子: 【转】Apache Http Server和Tomcat 之区别 下篇帖子: Unable to load bean org.apache.struts2.dispatcher.
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表