/* XFF version: takes IP from X-Forwarded-For header */ void vcl_geoip_country_set_header_xff(const struct sess *sp) { vcl_string hval[HEADER_MAXLEN]; vcl_string *ip = VRT_GetHdr(sp, HDR_REQ, "\020X-Forwarded-For:"); if (ip) { geoip_lookup_country(ip, hval); VRT_SetHdr(sp, HDR_REQ, "\011X-Geo-IP:", hval, vrt_magic_string_end); } else { VCL_Log("geoip: no ip from X-Forwarded-For"); VRT_SetHdr(sp, HDR_REQ, "\011X-Geo-IP:", "", vrt_magic_string_end); } }
static int vmod_Hook_vcl_error(struct sess *sp){ int status=VRT_r_obj_status(sp); if ( status == 301 || status == 302 || status == 303 ){ char * location = VRT_GetHdr(sp, HDR_REQ, "\030X-VMODREDIRECT-Location:"); if(location != 0){ VRT_SetHdr(sp, HDR_OBJ, "\011Location:" , location , vrt_magic_string_end); VRT_done(sp, VCL_RET_DELIVER); } } return(vmod_redirect_Hook_vcl_error(sp)); }
int vmod_parse(struct sess *sp,const char* tgHeadName,unsigned setParam,const char* paramPrefix,unsigned parseMulti,unsigned parseFile){ #ifdef DEBUG_SYSLOG syslog(6,"parse:start"); #endif /* struct sess *sp, OK const char* tgHeadName, OK const char* paramPrefix, url, unsigned setParam, url, unsigned parseMulti, OK unsigned parseFile OK */ //デバッグでReInitとかrestartの時に不具合でないかチェック(ロールバックも) //Content = pipeline.e-bの時はRxbuf確保をしない(必要ないので) //mix形式をurlencodeに切り替える(組み換えで安全に)<-完了 /* string(41) "submitter\"=a&submitter2=b&submitter3=vcc" string(42) "submitter%5C=a&submitter2=b&submitter3=vcc" string(39) "submitter=a&submitter2=b&submitter3=vcc" string(39) "submitter=a&submitter2=b&submitter3=vcc" string(83) "submitter=%e3%81%82%e3%81%84%e3%81%86%e3%81%88%e3%81%8a&submitter2=b&submitter3=vcc" string(83) "submitter=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A&submitter2=b&submitter3=vcc" 1 =成功 -1 =エラー ワークスペースサイズが足りない -2 =エラー target/ContentLengthがない/不正 -3 =エラー 指定ContentLengthに満たないデータ -4 =エラー 未対応形式 if (!( !VRT_strcmp(VRT_r_req_request(sp), "POST") || !VRT_strcmp(VRT_r_req_request(sp), "PUT") )){return "";} */ unsigned long content_length,orig_content_length; char *h_clen_ptr, *h_ctype_ptr, *body; int buf_size, rsize; char buf[1024],tgHead[256]; unsigned multipart = 0; ////////////////////////////// //build tgHead int hsize = strlen(tgHeadName) +1; if(hsize > 1){ if(hsize > 255){ #ifdef DEBUG_SYSLOG syslog(6,"parse:err -2"); #endif return -2; } tgHead[0] = hsize; tgHead[1] = 0; snprintf(tgHead +1,255,"%s:",tgHeadName); }else{ tgHead[0] = 0; } ////////////////////////////// //check Content-Type #ifdef DEBUG_SYSLOG syslog(6,"GetHdr Content-Type:"); #endif h_ctype_ptr = VRT_GetHdr(sp, HDR_REQ, "\015Content-Type:"); if(h_ctype_ptr != NULL){ if (h_ctype_ptr == strstr(h_ctype_ptr, "application/x-www-form-urlencoded")) { //application/x-www-form-urlencoded }else if(h_ctype_ptr == strstr(h_ctype_ptr, "multipart/form-data") && parseMulti){ //multipart/form-data multipart = 1; }else{ #ifdef DEBUG_SYSLOG syslog(6,"parse:err -4"); #endif return -4; } }else{ //none support type #ifdef DEBUG_SYSLOG syslog(6,"parse:err -4"); #endif return -4; } ////////////////////////////// //check Content-Length #ifdef DEBUG_SYSLOG syslog(6,"GetHdr Content-Length:"); #endif h_clen_ptr = VRT_GetHdr(sp, HDR_REQ, "\017Content-Length:"); if (!h_clen_ptr) { //can't get #ifdef DEBUG_SYSLOG syslog(6,"parse:err -2"); #endif return -2; } orig_content_length = content_length = strtoul(h_clen_ptr, NULL, 10); if (content_length <= 0) { //illegal length #ifdef DEBUG_SYSLOG syslog(6,"parse:err -2"); #endif return -2; } ////////////////////////////// //Check POST data is loaded #ifdef DEBUG_HTCREAD if(0 == 1){ #else if(sp->htc->pipeline.b != NULL && Tlen(sp->htc->pipeline) == content_length){ #endif #ifdef DEBUG_SYSLOG syslog(6,"noread"); #endif //complete read body = sp->htc->pipeline.b; }else{ #ifdef DEBUG_SYSLOG syslog(6,"read"); #endif //incomplete read int rxbuf_size = Tlen(sp->htc->rxbuf); /////////////////////////////////////////////// //use ws int u = WS_Reserve(sp->wrk->ws, 0); if(u < content_length + rxbuf_size + 1){ #ifdef DEBUG_SYSLOG syslog(6,"parse:err -1"); #endif return -1; } body = (char*)sp->wrk->ws->f; memcpy(body, sp->htc->rxbuf.b, rxbuf_size); sp->htc->rxbuf.b = body; body += rxbuf_size; body[0]= 0; sp->htc->rxbuf.e = body; WS_Release(sp->wrk->ws,content_length + rxbuf_size + 1); /////////////////////////////////////////////// ////////////////////////////// //read post data while (content_length) { if (content_length > sizeof(buf)) { buf_size = sizeof(buf) - 1; } else { buf_size = content_length; } // read body data into 'buf' //rsize = HTC_Read(sp->htc, buf, buf_size); rsize = vmod_HTC_Read(sp->wrk, sp->htc, buf, buf_size); if (rsize <= 0) { #ifdef DEBUG_SYSLOG syslog(6,"parse:err -3"); #endif return -3; } hsize += rsize; content_length -= rsize; strncat(body, buf, buf_size); } sp->htc->pipeline.b = body; sp->htc->pipeline.e = body + orig_content_length; } ////////////////////////////// //decode form #ifdef DEBUG_SYSLOG syslog(6,"content-size (orig)%d (read)%d",orig_content_length,strlen(body)); #endif int ret = 1; if(multipart){ ret = decodeForm_multipart(sp, body,tgHead,parseFile,paramPrefix,setParam); }else{ if(tgHead[0] != 0) VRT_SetHdr(sp, HDR_REQ, tgHead, body, vrt_magic_string_end); if(setParam) ret = decodeForm_urlencoded(sp, body,paramPrefix); } #ifdef DEBUG_SYSLOG syslog(6,"parse:end %d",ret); #endif return ret; }
int decodeForm_multipart(struct sess *sp,char *body,char *tgHead,unsigned parseFile,const char *paramPrefix, unsigned setParam){ char *prefix; char defPrefix[] = "X-VMODPOST-"; if(!setParam){ prefix = defPrefix; }else{ prefix = (char*)paramPrefix; } int prefix_len = strlen(prefix); char tmp; char head[256]; char sk_boundary[258]; char *raw_boundary, *h_ctype_ptr; char *p_start, *p_end, *p_body_end, *name_line_end, *name_line_end_tmp, *start_body, *sc_name, *sc_filename; int hsize, boundary_size ,idx; char *tmpbody = body; int encoded_size= 0; char *basehead = 0; char *curhead; int ll_u, ll_head_len, ll_size; int ll_entry_count = 0; int u; char *orig_cv_body, *cv_body, *h_val; ////////////////////////////// //get boundary #ifdef DEBUG_SYSLOG syslog(6,"GetHdr Content-Type:"); #endif h_ctype_ptr = VRT_GetHdr(sp, HDR_REQ, "\015Content-Type:"); raw_boundary = strstr(h_ctype_ptr,"; boundary="); if(!raw_boundary || strlen(raw_boundary) > 255){ #ifdef DEBUG_SYSLOG syslog(6,"parse:decodeForm_multipart boudary size>255"); #endif return -5; } raw_boundary +=11; sk_boundary[0] = '-'; sk_boundary[1] = '-'; sk_boundary[2] = 0; strncat(sk_boundary,raw_boundary,strlen(raw_boundary)); boundary_size = strlen(sk_boundary); p_start = strstr(tmpbody,sk_boundary); while(1){ /////////////////////////////////////////////// //search data if(!p_start) break; //boundary p_end = strstr(p_start + 1,sk_boundary); if(!p_end) break; //name sc_name = strstr(p_start +boundary_size,"name=\""); if(!sc_name) break; sc_name+=6; //line end name_line_end = strstr(sc_name,"\"\r\n"); name_line_end_tmp = strstr(sc_name,"\"; "); if(!name_line_end) break; if(name_line_end_tmp && name_line_end_tmp < name_line_end) name_line_end = name_line_end_tmp; //body start_body = strstr(sc_name,"\r\n\r\n"); if(!start_body) break; //filename sc_filename = strstr(sc_name,"; filename"); /////////////////////////////////////////////// //build head if((name_line_end -1)[0]=='\\'){ idx = 1; }else{ idx=0; } tmp = name_line_end[idx]; name_line_end[idx] = 0; hsize = strlen(sc_name) + prefix_len +1; if(hsize > 255) return -5; head[0] = hsize; head[1] = 0; snprintf(head +1,255,"%s%s:",prefix,sc_name); name_line_end[idx] = tmp; /////////////////////////////////////////////// //filecheck if(!parseFile){ if(sc_filename && sc_filename < start_body){ //content is file(skip) p_start = p_end; continue; } } /////////////////////////////////////////////// //create linked list //use ws ll_u = WS_Reserve(sp->wrk->ws, 0); ll_head_len = strlen(head +1) +1; ll_size = ll_head_len + sizeof(char*)+2; if(ll_u < ll_size){ #ifdef DEBUG_SYSLOG syslog(6,"parse:decodeForm_multipart more ws size"); #endif return -1; } if(!basehead){ curhead = (char*)sp->wrk->ws->f; basehead = curhead; }else{ ((char**)curhead)[0] = (char*)sp->wrk->ws->f; curhead = (char*)sp->wrk->ws->f; } ++ll_entry_count; memcpy(curhead,head,ll_head_len); curhead +=ll_head_len; memset(curhead,0,sizeof(char*)+1); ++curhead; WS_Release(sp->wrk->ws,ll_size); /////////////////////////////////////////////// /////////////////////////////////////////////// //url encode & set header p_body_end = p_end -2; start_body +=4; tmp = p_body_end[0]; p_body_end[0] = 0; //bodyをURLエンコードする if(!url_encode_setHdr(sp,start_body,head,&encoded_size)){ //メモリない p_body_end[0] = tmp; return -1; } encoded_size -= prefix_len; p_body_end[0] = tmp; /////////////////////////////////////////////// //check last boundary if(!p_end) break; p_start = p_end; } if(tgHead[0] == 0 && !setParam){ #ifdef DEBUG_SYSLOG syslog(6,"parse:decodeForm_multipart head 0 & no set param [OK]"); #endif return 1; } ////////////// //genarate x-www-form-urlencoded format data ////////////// //use ws if(tgHead[0] == 0){ orig_cv_body = cv_body = NULL; }else{ u = WS_Reserve(sp->wrk->ws, 0); if(u < encoded_size + 1){ #ifdef DEBUG_SYSLOG syslog(6,"parse:decodeForm_multipart more ws size(2)"); #endif return -1; } orig_cv_body = cv_body = (char*)sp->wrk->ws->f; WS_Release(sp->wrk->ws,encoded_size+1); } ////////////// for(int i=0;i<ll_entry_count;++i){ if(cv_body){ hsize = basehead[0] -prefix_len; memcpy(cv_body,basehead+1+prefix_len,hsize); cv_body += hsize - 1; cv_body[0] ='='; ++cv_body; #ifdef DEBUG_SYSLOG syslog(6,"GetHdr %s",basehead +1); #endif h_val = VRT_GetHdr(sp,HDR_REQ,basehead); } if(!setParam){ //remove header VRT_SetHdr(sp, HDR_REQ, basehead, 0); } if(cv_body){ memcpy(cv_body,h_val,strlen(h_val)); cv_body +=strlen(h_val); cv_body[0] ='&'; ++cv_body; } basehead = *(char**)(basehead+strlen(basehead+1)+2); } if(cv_body){ orig_cv_body[encoded_size - 1] =0; } if(tgHead[0] == 0){ #ifdef DEBUG_SYSLOG syslog(6,"parse:decodeForm_multipart head 0 [OK]"); #endif return 1; } VRT_SetHdr(sp, HDR_REQ, tgHead, orig_cv_body, vrt_magic_string_end); return 1; }