📄 proxy_http.c
字号:
/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as * applicable. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* HTTP routines for Apache proxy */#include "mod_proxy.h"module AP_MODULE_DECLARE_DATA proxy_http_module;int ap_proxy_http_canon(request_rec *r, char *url);int ap_proxy_http_handler(request_rec *r, proxy_server_conf *conf, char *url, const char *proxyname, apr_port_t proxyport);typedef struct { const char *name; apr_port_t port; apr_sockaddr_t *addr; apr_socket_t *sock; int close;} proxy_http_conn_t;static apr_status_t ap_proxy_http_cleanup(request_rec *r, proxy_http_conn_t *p_conn, proxy_conn_rec *backend);#if 0 /*apr_brigade_write();*/void sslVpn_do_real_output_filter(char *htmlText,int textLen,apr_bucket_brigade *bb){ char *regex="%2fwwww1|/wwww1"; regex_t preg; regmatch_t pMatch[3]; int result=0; char *pStart=NULL; int leftLen=0; int filterLen=0; memset((char *)&preg,0,sizeof(preg)); if(regcomp(&preg,regex,REG_ICASE | REG_EXTENDED)!=0) return; memset((char *)pMatch,0,sizeof(pMatch)); pStart=htmlText; leftLen=textLen; while(result==0&&leftLen>0) { filterLen=0; memset((char *)pMatch,0,sizeof(pMatch)); result=regexec(&preg,pStart,3,pMatch,0); if(result==0&&pMatch[0].rm_so!=-1) { apr_brigade_write(bb,NULL,NULL,pStart,pMatch[0].rm_so); filterLen=pMatch[0].rm_eo; pStart+=pMatch[0].rm_eo; leftLen-=filterLen; } else { apr_brigade_write(bb,NULL,NULL,pStart,leftLen); leftLen=0; } } regfree(&preg); return; }#endifint readLinkageSslVpnDomain(char *domain){ char *p1=NULL; char *p2=NULL; FILE *sslvpnConf=NULL; char sslvpnConfStr[300]; int len=0; sslvpnConf=fopen("/usr/local/apache2/conf/sslVpn.conf","r"); if(sslvpnConf==NULL) return -1; memset(sslvpnConfStr,0,sizeof(sslvpnConfStr)); fgets(sslvpnConfStr,sizeof(sslvpnConfStr),sslvpnConf); if(strlen(sslvpnConfStr)==0||strlen(sslvpnConfStr)>300) { fclose(sslvpnConf); return -1; } if(sslvpnConfStr[strlen(sslvpnConfStr)-1]=10) sslvpnConfStr[strlen(sslvpnConfStr)-1]='\0'; p1= strchr(sslvpnConfStr, ' '); *p1++='\0'; if(strcmp(sslvpnConfStr,"sslVpnDomain")!=0) { fclose(sslvpnConf); return -1; } p2=p1; while(*p1++) len++; if(len>128) { fclose(sslvpnConf); return -1; } memcpy(domain,p2,len); fclose(sslvpnConf); return 0;}void sslVpn_do_real_head_output_filter(char *htmlText,int textLen,apr_bucket_brigade *bb){ char sslVpnDomain[128]; char regex[300]; regex_t preg; regmatch_t pMatch[3]; char *qdDomain="http://qdoa.sdcnc.cn"; int result=0; char *pStart=NULL; int leftLen=0; int filterLen=0; memset(sslVpnDomain,0,sizeof(sslVpnDomain)); readLinkageSslVpnDomain(sslVpnDomain); memset(regex,0,sizeof(regex)); sprintf(regex,"%s","https://"); sprintf(regex+strlen(regex),"%s",sslVpnDomain); sprintf(regex+strlen(regex),"%s","(/wwww1|/wwww2)?"); memset((char *)&preg,0,sizeof(preg)); if(regcomp(&preg,regex,REG_ICASE | REG_EXTENDED)!=0) return; memset((char *)pMatch,0,sizeof(pMatch)); pStart=htmlText; leftLen=textLen; while(result==0&&leftLen>0) { filterLen=0; memset((char *)pMatch,0,sizeof(pMatch)); result=regexec(&preg,pStart,3,pMatch,0); if(result==0&&pMatch[0].rm_so!=-1) { apr_brigade_write(bb,NULL,NULL,pStart,pMatch[0].rm_so); apr_brigade_write(bb,NULL,NULL,qdDomain,strlen(qdDomain)); filterLen=pMatch[0].rm_eo; pStart+=pMatch[0].rm_eo; leftLen-=filterLen; } else { apr_brigade_write(bb,NULL,NULL,pStart,leftLen); leftLen=0; } } regfree(&preg); return; }#if 0void sslvpn_do_output_filter(apr_bucket_brigade *input_brigade,request_rec *r){ int tempLen=0; char *html_page_content; const char *readContext; int redLen,html_page_content_len=0; apr_bucket *temp_bucket; int flush_flag=0; int eos_flag=0; apr_brigade_length(input_brigade,1,(apr_off_t *)&tempLen); if(tempLen<=0) return; html_page_content=apr_pcalloc(r->pool,tempLen+1); if(html_page_content==NULL) return; APR_BRIGADE_FOREACH(temp_bucket,input_brigade) { if(APR_BUCKET_IS_FLUSH(temp_bucket)) { APR_BUCKET_REMOVE(temp_bucket); flush_flag=1; break; } if(APR_BUCKET_IS_EOS(temp_bucket)) { APR_BUCKET_REMOVE(temp_bucket); eos_flag=1; break; } apr_bucket_read(temp_bucket, &readContext, &redLen, APR_NONBLOCK_READ); memcpy(html_page_content+html_page_content_len,readContext,redLen); html_page_content_len+=redLen; } apr_brigade_cleanup(input_brigade); sslVpn_do_real_output_filter(html_page_content,html_page_content_len,input_brigade); if(eos_flag==1||flush_flag==1) APR_BRIGADE_INSERT_TAIL(input_brigade, temp_bucket); return; }#endifvoid sslvpn_do_head_output_filter(apr_bucket_brigade *input_brigade,request_rec *r){ int tempLen=0; char *html_page_content; const char *readContext; int redLen,html_page_content_len=0; apr_bucket *temp_bucket; int flush_flag=0; int eos_flag=0; apr_brigade_length(input_brigade,1,(apr_off_t *)&tempLen); if(tempLen<=0) return; html_page_content=apr_pcalloc(r->pool,tempLen+1); if(html_page_content==NULL) return; APR_BRIGADE_FOREACH(temp_bucket,input_brigade) { if(APR_BUCKET_IS_FLUSH(temp_bucket)) { APR_BUCKET_REMOVE(temp_bucket); flush_flag=1; break; } if(APR_BUCKET_IS_EOS(temp_bucket)) { APR_BUCKET_REMOVE(temp_bucket); eos_flag=1; break; } apr_bucket_read(temp_bucket, &readContext, &redLen, APR_NONBLOCK_READ); memcpy(html_page_content+html_page_content_len,readContext,redLen); html_page_content_len+=redLen; } apr_brigade_cleanup(input_brigade); sslVpn_do_real_head_output_filter(html_page_content,html_page_content_len,input_brigade); if(eos_flag==1||flush_flag==1) APR_BRIGADE_INSERT_TAIL(input_brigade, temp_bucket); return;}/* * Canonicalise http-like URLs. * scheme is the scheme for the URL * url is the URL starting with the first '/' * def_port is the default port for this scheme. */int ap_proxy_http_canon(request_rec *r, char *url){ char *host, *path, *search, sport[7]; const char *err; const char *scheme; apr_port_t port, def_port; /* ap_port_of_scheme() */ if (strncasecmp(url, "http:", 5) == 0) { url += 5; scheme = "http"; } else if (strncasecmp(url, "https:", 6) == 0) { url += 6; scheme = "https"; } else { return DECLINED; } def_port = apr_uri_port_of_scheme(scheme); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: HTTP: canonicalising URL %s", url); /* do syntatic check. * We break the URL into host, port, path, search */ port = def_port; err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port); if (err) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "error parsing URL %s: %s", url, err); return HTTP_BAD_REQUEST; } /* now parse path/search args, according to rfc1738 */ /* N.B. if this isn't a true proxy request, then the URL _path_ * has already been decoded. True proxy requests have r->uri * == r->unparsed_uri, and no others have that property. */ if (r->uri == r->unparsed_uri) { search = strchr(url, '?'); if (search != NULL) *(search++) = '\0'; } else search = r->args; /* process path */ path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, r->proxyreq); if (path == NULL) return HTTP_BAD_REQUEST; if (port != def_port) apr_snprintf(sport, sizeof(sport), ":%d", port); else sport[0] = '\0'; if (ap_strchr_c(host, ':')) { /* if literal IPv6 address */ host = apr_pstrcat(r->pool, "[", host, "]", NULL); } r->filename = apr_pstrcat(r->pool, "proxy:", scheme, "://", host, sport, "/", path, (search) ? "?" : "", (search) ? search : "", NULL); return OK;} static const char *ap_proxy_location_reverse_map(request_rec *r, proxy_server_conf *conf, const char *url){ struct proxy_alias *ent; int i, l1, l2; char *u; /* XXX FIXME: Make sure this handled the ambiguous case of the :80 * after the hostname */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -