/* 使用方法: 自己先用 r->method_number 判斷是 M_GET 或 M_POST */ #include "mod_ptt.h" unsigned char xtoc(char ch1, char ch2) { unsigned char d, up1, up2; if (!isxdigit(ch1) || !isxdigit(ch2)) return ' '; up1 = toupper(ch1); up2 = toupper(ch2); if (up1>='0' && up1<='9') d = up1-'0'; else d = up1-'A'+10; d <<= 4; if (up2>='0' && up2<='9') d += up2-'0'; else d += up2-'A'+10; return d; } char * cstoxs(pool *p, char *str) { char * newstr = pstrdup(p,""), *po = str; for(po = str; *po; po++) { if(isprint(*po) && *po!=' ') newstr=psprintf(p, "%s%c", newstr,*po); else newstr=psprintf(p, "%s%%%X", newstr, *po& 0xFF); } return newstr; } int // Ptt: 我重寫拿掉mygetchar 並加上fileupload的功能 inital_postdata(request_rec *r, int *fileupload, char *boundary, char **data) { char *buf, *mb; int size, off = 0, len_read; void (*handler)(); buf = table_get(r->subprocess_env,"CONTENT_TYPE"); if(!buf || (strncasecmp(buf,"application/x-www-form-urlencoded",33) && strncasecmp(buf,"multipart/form-data",19))) return -1; if(!strncasecmp(buf,"multipart/form-data",19)) { if(!fileupload) return -1; *fileupload=1; mb = strchr(buf,'='); if(mb) { strcpy(boundary,mb+1); strtok(boundary, " ;\n"); } else return -1; } buf = table_get(r->subprocess_env,"CONTENT_LENGTH"); if(buf==NULL) return -1; size = atoi(buf); mb = (char *)palloc(r->pool,(size+1)*sizeof(char)); if(!mb || (setup_client_block(r ,REQUEST_CHUNKED_ERROR) != 0) || (should_client_block(r) == 0)) return -1; hard_timeout("args.c copy script args", r); handler = signal(SIGPIPE, SIG_IGN); while(size-off > 0 && (len_read = get_client_block (r, mb + off, size - off)) > 0) { off += len_read; } signal(SIGPIPE, handler); kill_timeout(r); if(len_read < 0) return -1; // 讀的中途有中斷 mb[size]=0; // Ptt:截掉不需要吧 因為不是用字串處理方式 (*data) = mb; return size; } #define ENCODED_NAME " name=\"" #define ENCODED_FILENAME " filename=\"" #define ENCODED_CONTENT "Content-Type: " //#define FILEDATAFILE DATABASEDIR "/" FDATA int unescape(request_rec *r, char** name, char** value) { static char *sp=NULL, boundary[150]; static int fileupload, boundarylen, dsize; pool *p = r->pool; char ch, ch1, *dp, *p0, *p1, *temp_sp, *ftype; int type; if (sp==NULL) { fileupload=0; switch (r->method_number) { case M_GET: if (r->args) sp = pstrdup(p, r->args); else {sp=NULL; return -1;} break; case M_POST: if ((dsize = inital_postdata(r, &fileupload, boundary,&sp))<0) {sp=NULL; return -1; } if(fileupload) boundarylen = strlen(boundary); break; default: sp=NULL; return -1; } } if(fileupload) { if(dsize >0 && (temp_sp = memstr(sp, boundary, dsize))) { temp_sp += boundarylen; p0 = strstr(temp_sp, "\r\n\r\n"); p1 = strstr(temp_sp, "\n\n"); if(!((*name) = strstr(temp_sp, ENCODED_NAME))) {sp=NULL; return -1; } (*name) += strlen(ENCODED_NAME); strtok((*name) + 1 , "\""); if( (!p0 && p1) || (p0 && p1 && p13) { fileheader_t *file=(fileheader_t *)pcalloc(p, sizeof(fileheader_t)); if((ftype = strstr(p0 + 1, ENCODED_CONTENT))) { ftype += strlen(ENCODED_CONTENT); strtok(ftype, "\r\n"); } while(p0 > dp && *p0 !='/' && *p0 !='\\') p0--; strcpy(file->name, p0+1); strcpy(file->content_type, ftype); file->icontent_type = filetype(ftype); // if(file->icontent_type & (FILE_TXT | FILE_HTML)) // file->size = strlen(sp); // else file->size = temp_sp - sp - type; file->uploadtime = time(NULL); file->data = (*value); (*value) = (char *)file; } else { (*value) = NULL; } } dsize -= (temp_sp - sp); sp = temp_sp; return 1; } else { sp=NULL; return -1; } } dp = (*name) = sp; while(1) { ch = *sp++; switch(ch) { case '+': *dp++ = ' '; break; case '=': *dp++ = '\0'; (*value) = dp; break; case '&': case '|': *dp++ = '\0'; return 1; case '\0': case EOF: *dp = '\0'; sp=NULL; return 0; case '%': ch = *sp++; ch1 = *sp++; *dp++ = xtoc(ch, ch1); break; default: *dp++=ch; break; } } }