Server Setup notes-use the Apache plugin to parse simple requests

Source: Internet
Author: User

In general, for a request, the server parses it to determine the legitimacy of the request and the path to travel. This section explains how to obtain the requested data. (reprint please indicate CSDN blog for breaksoftware)

We created a handler engineering--get_request using the methods in the article "Server Setup notes-compiling Apache and its plugins". The entry function that we can manipulate in the project is

static int Get_request_handler (Request_rec *r) {    R->content_type = "text/html";  
With this entry function, the data we can get directly is the Request_rec struct object pointer r. By accessing the source code, we get its definition
/** * @brief A structure that represents the current request */struct Request_rec {/** The pool associated with the RE    Quest */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 it's an external redirect */Request_rec *next;    /** Pointer to the previous request if it's 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, only * protocol.c should ever touch ... *//** Firs    T 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_PR OXY, Proxyreq_reverse, *                 Proxyreq_response */int proxyreq;    /** HEAD request, as opposed to GET */int header_only; /** Protocol version number of Protocol;    1.1 = 1001 */int proto_num;    /** Protocol string, as given to us, or http/0.9 */char *protocol;    /** 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, ways;  Also, protocol, etc.     Outside of PROTOCOL.C, * look, but don ' t touch.    *//** M_get, M_post, etc. */int method_number; /** Request method (eg. GET, HEAD, POST, etc.)    */const char *method;     /** * ' allowed ' is a bitvector of the allowed methods.  * * A handler must ensure that the request method was one that * it's capable of handling. Generally modules should decline * Any request methods they does 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 was used * to construct the ' Allow: ' header required for OPTIONS requests, * and Http_method_not_a     Llowed and http_not_implemented status codes.  * * Since the Default_handler deals with options, all modules can * usually decline-deal with options.     TRACE is always allowed, * modules don ' t need to set it explicitly. * * Since the Default_handler would always handle a GET, a * module which does *not* implement GET should probabl  Y return * http_method_not_allowed.     Unfortunately this means a Script GET * handler can ' t is 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 was 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 *//** the Range:header */const char *range;    /** the "real" content length */apr_off_t clength;    /** sending chunked transfer-coding */int chunked; /** 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 response?    */unsigned expecting_100; /** the optional kept body of the request.    */Apr_bucket_brigade *kept_body; /** for Ap_body_to_table (): Parsed body */* xxx:ap_body_to_table has been removed. Remove body_table too or * xxx:keep it to reintroduce ap_body_to_table without major bump?    */apr_table_t *body_table; /** Remaining bytes LeftTo read from the request body */apr_off_t remaining;    /** number of bytes that has been read from the request body */apr_off_t read_length;  /* MIME header environments, in and out. Also, an array containing * environment variables to being passed to subprocesses, so people can * write modules to a     DD to that environment. * * The difference between headers_out and Err_headers_out is, the * latter be printed even on error, and per     Sist across Internal redirects * (so the headers printed for errordocument handlers would 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 is used for sub processes */apr_table_t *subprocess_env;    /** Notes from the one module to another */apr_table_t *notes;  /* Content_Type, Handler, content_encoding, and all content_languages * must be lowercased strings.     They may is pointers to static strings;     * They should not being 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 do we *really* dispatch on * */** 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 is made, this gets set to the user name.    */char *user; /** If an AuthentiCation check is made, this gets set to the auth type.    */char *ap_auth_type;     /* 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;  /** * 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_defaul T_path_info indicates they *may follow existing conventions.     This was set to the * user ' s preference upon hook_very_first of the fixups.    */int used_path_info;    /** A flag to determine if the EOS bucket has been sent yet */int eos_sent; /* Various other config info which. htaccess files * These is 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; /** Optional request Log level configuration. Would usually point * to a server or Per_dir config, i.e. must is copied before * modifying * * CONST struct AP    _logconf *log; /** Id to identify request in Access and error log.     Set when the first * error log entry for this request is generated.    */const char *log_id; /** * A linked list of the. htaccess configurationdirectives * accessed by this request.     * n.b. Always add to the head of the list, _never_ to the end. * That is, a sub request ' s list can (temporarily) point to a parent's list */const struct Htaccess_result *htacce    ss    /** A List of output filters to is used for this request */struct ap_filter_t *output_filters;    /** A List of input filters to is used for this request */struct ap_filter_t *input_filters; /** A List of protocol level output filters to is used for this * request */struct ap_filter_t *proto_output_filt    ERs /** A List of protocol level input filters to being used for this * request */struct ap_filter_t *proto_input_filter    S    /** This response can is cached */int no_cache;    /** there is no. local copy of this response */int no_local_copy; /** Mutex protect callbacks registered with Ap_mpm_register_timed_callback * from being run before the original handle R finishes running */Apr_thread_mutex_t *invoke_mtx;    /** A struct containing the components of the URI */apr_uri_t Parsed_uri;    /** finfo.protection (St_mode) set to zero if no such file */apr_finfo_t Finfo;     /** remote Address information from Conn_rec, can is overridden if * necessary by a module.     * This is the address of that originated the request.    */apr_sockaddr_t *useragent_addr;    Char *useragent_ip;    /** MIME Trailer Environment from the request */apr_table_t *trailers_in; /** MIME Trailer Environment from the response */apr_table_t *trailers_out;};
This is a very large structure, it is all-encompassing. It is difficult for beginners to fully understand what they are. And our needs are simple, and we're going to list data that we might need to be concerned about.

    /** first line of request */    char *the_request;

The first row of data requested

    /** Protocol version number of Protocol; 1.1 = 1001 */    int proto_num;    /** Protocol string, as given to us, or http/0.9 */    char *protocol;    /** host, as set by full URI or Host: */    const char *hostname;
Version of the Protocol and type of request
    /** time when the request started */    apr_time_t request_time;
Time of request
    /** 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;
UrlDecode URI, UrlDecode URI, and file path to process the request
    /** the path_info extracted from this request */    char *path_info;    /** the Query_args extracted from this request */    char *args;
Paths and parameters in the request
    /** A struct containing the components of the URI */    apr_uri_t Parsed_uri;
Detailed results of request parsing
    Char *useragent_ip;

IP of the requesting source

/** MIME Header Environment from the request */    apr_table_t *headers_in;
HTTP header information saved in table Form

We can easily write routines for the underlying data types

if (r->the_request) {ap_rprintf (R, "The Request:%s\n", r->the_request);} else {ap_rprintf (R, "The request is Null\n");} if (r->protocol) {ap_rprintf (R, "protocol:%s\n", R->protocol);} else {ap_rprintf (R, "protocol is Null\n");} ap_rprintf (R, "Proto_num is%d\n", r->proto_num);
For the request time apr_time_t type, we can refer to the module in the "Server Erection note--apache Module Development Basics". We look at the source code, you can write out the following routines

static void Print_time (request_rec* r) {if (!r) {ap_rprintf (R, "Request_rec pointer is null\n"); return;} Char data_str[128] = {0};apr_status_t status = Apr_ctime (Data_str, r->request_time); if (apr_success! = status) {AP_RPR INTF (R, "Apr_ctime error\n");} else {ap_rprintf (R, "ctime\t:\t%s\n", Data_str);} apr_time_exp_t Exp_t;memset (&exp_t, 0, sizeof (exp_t)); status = Apr_time_exp_gmt (&exp_t, r->request_time); if (apr_success! = status) {ap_rprintf (R, "Apr_time_exp_gmt error\n");} else {ap_rprintf (R, "exp time\t:\n"), ap_rprintf (R, "\ttm_usec\t:\t%d\n", exp_t.tm_usec); ap_rprintf (R, "\ttm_sec\t:\t %d\n ", exp_t.tm_sec); ap_rprintf (R," \ttm_min\t:\t%d\n ", exp_t.tm_min); ap_rprintf (R," \ttm_hour\t:\t%d\n ", exp_t.tm_ hour); Ap_rprintf (R, "\ttm_mday\t:\t%d\n", Exp_t.tm_mday); ap_rprintf (R, "\ttm_mon\t:\t%d\n", Exp_t.tm_mon); ap_ rprintf (R, "\ttm_year\t:\t%d\n", Exp_t.tm_year), ap_rprintf (R, "\ttm_wday\t:\t%d\n", Exp_t.tm_wday); ap_rprintf (R, "\ Ttm_yday\t:\t%d\n ", exp_t.tm_yday); ap_rprintf (R," \ttm_isdst\t:\t%d\n ", EXP_T.TM_ISDST); ap_rprintf (R," \ttm_gmtoff\t:\t%d\n ", Exp_t.tm_gmtoff);}} 
The definition of apr_time_exp_t is in "apr_time.h".

/** * A Structure similar to ANSI struct TM with the following differences: *-tm_usec isn ' t an ANSI field *-Tm_gmtoff isn ' t    An ANSI field (it ' s a bsdism) */struct apr_time_exp_t {/** microseconds past tm_sec */apr_int32_t tm_usec;    /** (0-61) seconds past Tm_min * * apr_int32_t tm_sec;    /** (0-59) minutes past Tm_hour * * apr_int32_t tm_min;    /** (0-23) hours past midnight * * apr_int32_t tm_hour;    /** (1-31) Day of the month */apr_int32_t tm_mday;    /** (0-11) month of the year */apr_int32_t Tm_mon;    /** year since 1900 * * apr_int32_t tm_year;    /** (0-6) days since Sunday * * apr_int32_t tm_wday;    /** (0-365) days since January 1 * * apr_int32_t tm_yday;    /** Daylight Saving Time */apr_int32_t TM_ISDST; /** seconds east of UTC */apr_int32_t Tm_gmtoff;}; 
For the parsed request struct apr_uri_t routine is also very simple, I will not list it, just the structure of the definition of a paste. You can see it all at once.

/** * A structure to encompass all of the fields in A Uri */struct apr_uri_t {/** scheme ("http"/"FTP"/...) */char    *scheme;    /** combined [user[:p assword]\@]host[:p ORT] */char *hostinfo;    /** user name, as in http://user:passwd\ @host:p ort/*/char *user;    /** password, as in http://user:passwd\ @host:p ort/*/char *password;    /** hostname from URI (or from Host:header) */char *hostname;    /** Port string (integer representation is in "port") */char *port_str;    /** the request path (or NULL if only scheme://host is given) */char *path;    /** everything after a '? ' in the path, if present */char *query;    /** Trailing "#fragment" string, if present */char *fragment;    /** structure returned from gethostbyname () */struct hostent *hostent;        /** the port number, numeric, valid only if port_str! = NULL */apr_port_t port;    /** has the structure been initialized * * unsigned is_initialized:1; /** has the DNS been lookedUp yet */unsigned dns_looked_up:1; /** has the DNS been resolved yet */unsigned dns_resolved:1;};
The trouble with these routines is the parsing of apr_table_t. Because it is difficult to find the traversal code on the table, so I can only refer to the code in Apr_table_clone to the following

static void Print_table (Request_rec *r, const apr_table_t* t) {const apr_array_header_t* array = apr_table_elts (t); Apr_ta  ble_entry_t* ELTs = (apr_table_entry_t*) array->elts;for (int i = 0; i < array->nelts; i++) {ap_rprintf (R, "\t%s: %s\n ", Elts[i].key, Elts[i].val);}}
We're asking for a url:http://192.168.191.129/ap%26ac%3ahe?a=b#c.

It returns as follows

Headers_in starthost:192.168.191.129connection:keep-alivecache-control:max-age=0accept:text/html,application/ xhtml+xml,application/xml;q=0.9,*/*;q=0.8user-agent:mozilla/5.0 (Windows NT 6.1; WOW64) applewebkit/537.36 (khtml, like Gecko) chrome/28.0.1500.72 safari/537.36accept-encoding:gzip,deflate, sdchaccept-language:zh-cn,zh;q=0.8headers_in endheaders_out startheaders_out endthe request:get/ap%26ac%3ahe?a=b Http/1.1protocol:http/1.1proto_num is 1001method:gethost name:192.168.191.129unparsed URI:/AP%26AC%3aHE?a=buri:/ Ap&ac:hefilename:/usr/local/apache2/htdocs/ap&ac:hepath Info:args:a=buser is NULLlog ID is NULLuseragent IP : 192.168.191.1ctime:mon Feb 18:20:39 2015exp time:tm_usec:200039tm_sec:39tm_min:20tm_hour:10tm_mday:16tm_mon:1tm _year:115tm_wday:1tm_yday:46tm_isdst:0tm_gmtoff:0scheme is Nullhostinfo are Nulluser is NULLpassword are NULLhostname is Nullport_str is Nullpath:/ap&ac:hequery:a=bfragment are nullthe sample page from Mod_gEt_request.c 


Server Setup notes-use the Apache plugin to parse simple requests

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.