#include <Form.h>
Collaboration diagram for Cgi::Form:
Public Member Functions | |
Form (FILE *=stdin) | |
Default constructor (used in POST operations). | |
Form (char *query_string, int length) | |
Another constructor (used in GET operations). | |
~Form () | |
void | EnableRaw (bool) |
void | strcpyval (char *, char *, size_t) |
bool | getfirst (char *, short) |
bool | getnext (char *, short) |
bool | getfirst (char *, short, char *, short) |
bool | getnext (char *, short, char *, short) |
int | getvalue (const std::string &, char *, short) |
std::string | getvalue (const std::string &) |
size_t | getlength (char *) |
cgi_v & | getbase () |
char * | GetBoundary () |
Private Member Functions | |
Form (const Form &) | |
Form & | operator= (const Form &) |
Private Attributes | |
cgi_v | m_cgi |
cgi_v::iterator | m_current |
char * | m_strBoundary |
bool | raw |
Definition at line 61 of file Form.h.
Cgi::Form::Form | ( | FILE * | = stdin |
) |
Default constructor (used in POST operations).
Input is read from stdin. Number of characters to read can be found in the environment variable CONTENT_LENGTH.
Definition at line 59 of file Form.cpp.
References DEB, Cgi::Parse::EnableQuote(), Cgi::Parse::getrest(), Cgi::Parse::getword(), m_cgi, m_current, and m_strBoundary.
00060 :m_strBoundary(NULL) 00061 ,raw(false) 00062 { 00063 CGI *cgi = NULL; 00064 char *c_t = getenv("CONTENT_TYPE"); 00065 char *c_l = getenv("CONTENT_LENGTH"); 00066 int extra = 2; 00067 char name[200]; 00068 char slask[8888]; 00069 00070 // cgibase = NULL; 00071 m_current = m_cgi.end(); //NULL; 00072 *name = 0; 00073 00074 if (c_t && !strncmp(c_t, "multipart/form-data",19)) 00075 { 00076 Parse pa(c_t,";="); 00077 char *tempcmp = NULL; 00078 int tc = 0; 00079 int l = 0; 00080 DEB( fprintf(fil,"Form:: multipart/form-data<br>\n");) 00081 pa.getword(slask); 00082 while (*slask) 00083 { 00084 DEB( fprintf(fil,"Content-type parse: '%s'\n",slask);) 00085 if (!strcmp(slask,"boundary")) 00086 { 00087 m_strBoundary = new char[200]; 00088 pa.getword(m_strBoundary); 00089 l = strlen(m_strBoundary); 00090 tempcmp = new char[l + extra]; 00091 } 00092 // 00093 pa.getword(slask); 00094 } 00095 if (m_strBoundary) 00096 { 00097 char content_type[200]; 00098 char current_name[200]; 00099 char current_filename[200]; 00100 DEB( fprintf(fil,"Form:: boundary = '%s'<br>\n",m_strBoundary);) 00101 fgets(slask, 200, infil); 00102 while (!feof(infil)) 00103 { 00104 while (strlen(slask) && (slask[strlen(slask) - 1] == 13 || slask[strlen(slask) - 1] == 10)) 00105 slask[strlen(slask) - 1] = 0; 00106 *content_type = 0; 00107 *current_name = 0; 00108 *current_filename = 0; 00109 if ((strstr(slask,m_strBoundary) || strstr(m_strBoundary,slask)) && strcmp(slask, m_strBoundary)) 00110 { 00111 strcpy(m_strBoundary, slask); 00112 l = strlen(m_strBoundary); 00113 delete[] tempcmp; 00114 tempcmp = new char[l + extra]; 00115 } 00116 if (!strcmp(slask, m_strBoundary)) 00117 { 00118 // Get headers until empty line 00119 fgets(slask, 200, infil); 00120 while (strlen(slask) && (slask[strlen(slask) - 1] == 13 || slask[strlen(slask) - 1] == 10)) 00121 slask[strlen(slask) - 1] = 0; 00122 while (!feof(infil) && *slask) 00123 { 00124 DEB( fprintf(fil,"Field header: '%s'\n",slask);) 00125 Parse pa(slask,";"); 00126 pa.getword(slask); 00127 if (!strcmp(slask,"Content-type:")) 00128 { 00129 pa.getword(content_type); 00130 } 00131 else 00132 if (!strcmp(slask,"Content-Disposition:")) 00133 { 00134 pa.getword(slask); 00135 if (!strcmp(slask,"form-data")) 00136 { 00137 DEB( fprintf(fil,"Form:: Content-Disposition: form-data;<br>\n");) 00138 pa.EnableQuote(true); 00139 pa.getword(slask); 00140 while (*slask) 00141 { 00142 Parse pa2(slask,"="); 00143 pa2.getword(name); // 'name' or 'filename' 00144 pa2.getrest(slask); // value 00145 if (!strcmp(name,"name")) 00146 { 00147 if (*slask == '"') 00148 { 00149 strcpy(current_name, slask + 1); 00150 current_name[strlen(current_name) - 1] = 0; 00151 } 00152 else 00153 { 00154 strcpy(current_name,slask); 00155 } 00156 DEB( fprintf(fil,"Form:: name = '%s'<br>\n",current_name);) 00157 } 00158 else 00159 if (!strcmp(name,"filename")) 00160 { 00161 if (*slask == '"') 00162 { 00163 strcpy(current_filename, slask + 1); 00164 current_filename[strlen(current_filename) - 1] = 0; 00165 } 00166 else 00167 { 00168 strcpy(current_filename,slask); 00169 } 00170 DEB( fprintf(fil,"Form:: filename = '%s'<br>\n",current_filename);) 00171 int x = -1; 00172 for (int i = 0; i < (int)strlen(current_filename); i++) 00173 { 00174 if (current_filename[i] == '/' || current_filename[i] == '\\') 00175 x = i + 1; 00176 } 00177 if (x > -1) 00178 { 00179 memmove(current_filename,current_filename + x,strlen(current_filename + x) + 1); 00180 } 00181 } 00182 pa.getword(slask); 00183 } 00184 } 00185 } 00186 // get next header value 00187 fgets(slask, 200, infil); 00188 while (strlen(slask) && (slask[strlen(slask) - 1] == 13 || slask[strlen(slask) - 1] == 10)) 00189 slask[strlen(slask) - 1] = 0; 00190 } 00191 // Read content, save...? 00192 if (!*current_filename) // not a file 00193 { 00194 std::string val; 00195 fgets(slask,1000,infil); 00196 while (!feof(infil) && strncmp(slask,m_strBoundary,strlen(m_strBoundary))) 00197 { 00198 DEB( fprintf(fil," * Content: %s",slask);) 00199 val += slask; 00200 fgets(slask,1000,infil); 00201 } 00202 DEB( fprintf(fil," * End of Content: %s",slask);) 00203 // remove trailing cr/linefeed 00204 while (val.size() && (val[val.size() - 1] == 13 || val[val.size() - 1] == 10)) 00205 { 00206 val = val.substr(0,val.size() - 1); 00207 } 00208 cgi = new CGI; 00209 cgi -> name = new char[strlen(current_name) + 1]; 00210 strcpy(cgi -> name,current_name); 00211 cgi -> value = new char[val.size() + 1]; //strlen(slask) + 1]; 00212 strcpy(cgi -> value,val.c_str() ); 00213 cgi -> path = NULL; 00214 // addlist(&cgibase, (LIST *)cgi); 00215 m_cgi.push_back(cgi); 00216 } 00217 else 00218 if (*current_filename) 00219 { 00220 DEB( fprintf(fil,"Form:: save file<br>\n");) 00221 // read until m_strBoundary... 00222 FILE *fil; 00223 int out = 0; 00224 char c; 00225 char fn[1000]; 00226 #ifdef WIN32 00227 { 00228 char tmp_path[1000]; 00229 ::GetTempPath(1000, tmp_path); 00230 if (tmp_path[strlen(tmp_path) - 1] != '\\') 00231 { 00232 strcat(tmp_path, "\\"); 00233 } 00234 sprintf(fn,"%s%s",tmp_path,current_filename); 00235 } 00236 #else 00237 sprintf(fn,"/tmp/%s",current_filename); 00238 #endif 00239 if ((fil = fopen(fn, "wb")) != NULL) 00240 { 00241 fread(&c,1,1,infil); 00242 while (!feof(infil)) 00243 { 00244 if (out) 00245 { 00246 fwrite(&tempcmp[tc],1,1,fil); 00247 } 00248 tempcmp[tc] = c; 00249 tc++; 00250 if (tc >= l + extra) 00251 { 00252 tc = 0; 00253 out = 1; 00254 } 00255 // fwrite(&c,1,1,fil); 00256 if (tc) 00257 { 00258 if (!strncmp(tempcmp + tc + extra, m_strBoundary, l - tc) && 00259 !strncmp(tempcmp, m_strBoundary + l - tc, tc)) 00260 { 00261 break; 00262 } 00263 } 00264 else 00265 { 00266 if (!strncmp(tempcmp + extra, m_strBoundary, l)) 00267 { 00268 break; 00269 } 00270 } 00271 fread(&c,1,1,infil); 00272 } 00273 fclose(fil); 00274 00275 cgi = new CGI; 00276 cgi -> name = new char[strlen(current_name) + 1]; 00277 strcpy(cgi -> name,current_name); 00278 cgi -> value = new char[strlen(fn) + 1]; 00279 strcpy(cgi -> value,fn); 00280 cgi -> path = new char[strlen(fn) + 1]; 00281 strcpy(cgi -> path,fn); 00282 // addlist(&cgibase, (LIST *)cgi); 00283 m_cgi.push_back(cgi); 00284 00285 strcpy(slask, m_strBoundary); 00286 fgets(slask + strlen(slask), 200, infil); // next line 00287 } 00288 else 00289 { 00290 // couldn't open file 00291 DEB( fprintf(fil,"Form:: couldn't create '%s'...<br>\n",fn);) 00292 break; 00293 } 00294 } 00295 else 00296 { 00297 // bad input? 00298 DEB( fprintf(fil,"Form:: bad input?<br>\n");) 00299 break; 00300 } 00301 } 00302 else 00303 { 00304 // Probably '<m_strBoundary>--' 00305 DEB( fprintf(fil,"Form:: end of boundary<br>\n");) 00306 break; 00307 } 00308 DEB( fprintf(fil,"Form:: ready for next field<br>\n");) 00309 } // while (!feof(infil)) 00310 } // if (m_strBoundary) 00311 if (tempcmp) 00312 { 00313 delete[] tempcmp; 00314 } 00315 DEB( fprintf(fil,"\n");) 00316 } 00317 else 00318 { 00319 int i = 0; 00320 int cl = c_l ? atoi(c_l) : -1; 00321 char c,chigh,clow; 00322 00323 // cgibase = NULL; 00324 m_current = m_cgi.end(); //NULL; 00325 00326 *name = 0; 00327 00328 fread(&c,1,1,infil); 00329 cl--; 00330 while (cl >= 0 && !feof(infil)) 00331 { 00332 switch (c) 00333 { 00334 case '=': /* end of name */ 00335 slask[i] = 0; 00336 i = 0; 00337 strcpy(name,slask); 00338 break; 00339 case '&': /* end of value */ 00340 slask[i] = 0; 00341 i = 0; 00342 cgi = new CGI; 00343 cgi -> name = new char[strlen(name) + 1]; 00344 strcpy(cgi -> name,name); 00345 cgi -> value = new char[strlen(slask) + 1]; 00346 strcpy(cgi -> value,slask); 00347 cgi -> path = NULL; 00348 DEB( fprintf(fil,"\nform '%s' = '%s'<br>\n",name,slask);) 00349 // addlist(&cgibase, (LIST *)cgi); 00350 m_cgi.push_back(cgi); 00351 break; 00352 case '+': /* space */ 00353 slask[i++] = ' '; 00354 break; 00355 case '%': /* hex value */ 00356 fread(&chigh,1,1,infil); 00357 cl--; 00358 chigh -= 48; 00359 chigh &= 0xff - 32; 00360 if (chigh > 9) 00361 chigh -= 7; 00362 fread(&clow,1,1,infil); 00363 cl--; 00364 clow -= 48; 00365 clow &= 0xff - 32; 00366 if (clow > 9) 00367 clow -= 7; 00368 slask[i++] = (char)(chigh * 16 + clow); 00369 break; 00370 default: /* just another char */ 00371 slask[i++] = c; 00372 break; 00373 } 00374 // 00375 if (cl > 0) 00376 { 00377 fread(&c,1,1,infil); 00378 } 00379 cl--; 00380 } 00381 slask[i] = 0; 00382 i = 0; 00383 cgi = new CGI; 00384 cgi -> name = new char[strlen(name) + 1]; 00385 strcpy(cgi -> name,name); 00386 cgi -> value = new char[strlen(slask) + 1]; 00387 strcpy(cgi -> value,slask); 00388 cgi -> path = NULL; 00389 DEB( fprintf(fil,"\nform '%s' = '%s'<br>\n",name,slask);) 00390 // addlist(&cgibase, (LIST *)cgi); 00391 m_cgi.push_back(cgi); 00392 } 00393 }
Cgi::Form::Form | ( | char * | query_string, | |
int | length | |||
) |
Another constructor (used in GET operations).
Input is read from the environment variable QUERY_STRING.
query_string | The httpd server provided QUERY_STRING | |
length | Query string length. |
Definition at line 398 of file Form.cpp.
References m_cgi, and m_current.
00399 :m_strBoundary(NULL) 00400 ,raw(false) 00401 { 00402 CGI *cgi = NULL; 00403 char slask[8888]; 00404 char name[200]; 00405 int i = 0; 00406 char c,chigh,clow; 00407 int ptr = 0; 00408 00409 // cgibase = NULL; 00410 m_current = m_cgi.end(); //NULL; 00411 00412 *name = 0; 00413 00414 ptr = 0; 00415 while (ptr < l) 00416 { 00417 c = buffer[ptr++]; 00418 switch (c) 00419 { 00420 case '=': /* end of name */ 00421 slask[i] = 0; 00422 i = 0; 00423 strcpy(name,slask); 00424 break; 00425 case '&': /* end of value */ 00426 slask[i] = 0; 00427 i = 0; 00428 cgi = new CGI; 00429 cgi -> name = new char[strlen(name) + 1]; 00430 strcpy(cgi -> name,name); 00431 cgi -> value = new char[strlen(slask) + 1]; 00432 strcpy(cgi -> value,slask); 00433 cgi -> path = NULL; 00434 // addlist(&cgibase, (LIST *)cgi); 00435 m_cgi.push_back(cgi); 00436 break; 00437 case '+': /* space */ 00438 slask[i++] = ' '; 00439 break; 00440 case '%': /* hex value */ 00441 chigh = buffer[ptr++]; 00442 chigh -= 48; 00443 chigh &= 0xff - 32; 00444 if (chigh > 9) 00445 chigh -= 7; 00446 clow = buffer[ptr++]; 00447 clow -= 48; 00448 clow &= 0xff - 32; 00449 if (clow > 9) 00450 clow -= 7; 00451 slask[i++] = (char)(chigh * 16 + clow); 00452 break; 00453 default: /* just another char */ 00454 slask[i++] = c; 00455 break; 00456 } 00457 } 00458 slask[i] = 0; 00459 i = 0; 00460 cgi = new CGI; 00461 cgi -> name = new char[strlen(name) + 1]; 00462 strcpy(cgi -> name,name); 00463 cgi -> value = new char[strlen(slask) + 1]; 00464 strcpy(cgi -> value,slask); 00465 cgi -> path = NULL; 00466 // addlist(&cgibase, (LIST *)cgi); 00467 m_cgi.push_back(cgi); 00468 }
Cgi::Form::~Form | ( | ) |
Definition at line 470 of file Form.cpp.
References m_cgi, and m_strBoundary.
00471 { 00472 CGI *cgi = NULL; //,*tmp; 00473 00474 // for (cgi = cgibase; cgi; cgi = tmp) 00475 for (cgi_v::iterator it = m_cgi.begin(); it != m_cgi.end(); it++) 00476 { 00477 cgi = *it; 00478 delete[] cgi -> name; 00479 delete[] cgi -> value; 00480 if (cgi -> path) 00481 { 00482 unlink(cgi -> path); 00483 delete[] cgi -> path; 00484 } 00485 // tmp = cgi -> next; 00486 delete cgi; 00487 } 00488 if (m_strBoundary) 00489 { 00490 delete[] m_strBoundary; 00491 } 00492 }
void Cgi::Form::EnableRaw | ( | bool | ) |
void Cgi::Form::strcpyval | ( | char * | , | |
char * | , | |||
size_t | ||||
) |
Definition at line 501 of file Form.cpp.
Referenced by getnext(), and getvalue().
00502 { 00503 *v = 0; 00504 for (size_t i = 0; i < strlen(value); i++) 00505 { 00506 if (value[i] == '<') 00507 { 00508 if (strlen(v) < len - 4) 00509 sprintf(v + strlen(v),"<"); 00510 } 00511 else 00512 if (value[i] == '>') 00513 { 00514 if (strlen(v) < len - 4) 00515 sprintf(v + strlen(v),">"); 00516 } 00517 else 00518 if (value[i] == '&') 00519 { 00520 if (strlen(v) < len - 5) 00521 sprintf(v + strlen(v),"&"); 00522 } 00523 else 00524 { 00525 if (strlen(v) < len - 1) 00526 sprintf(v + strlen(v),"%c",value[i]); 00527 } 00528 } 00529 // v[len - 1] = 0; 00530 }
bool Cgi::Form::getfirst | ( | char * | , | |
short | ||||
) |
bool Cgi::Form::getnext | ( | char * | , | |
short | ||||
) |
Definition at line 541 of file Form.cpp.
References m_cgi, and m_current.
Referenced by getfirst().
00542 { 00543 if (m_current != m_cgi.end() ) 00544 { 00545 CGI *current = *m_current; 00546 strncpy(n,current -> name,len - 1); 00547 n[len - 1] = 0; 00548 m_current++; //current = current -> next; 00549 return true; 00550 } else 00551 *n = 0; 00552 return false; 00553 }
bool Cgi::Form::getfirst | ( | char * | , | |
short | , | |||
char * | , | |||
short | ||||
) |
bool Cgi::Form::getnext | ( | char * | , | |
short | , | |||
char * | , | |||
short | ||||
) |
Definition at line 563 of file Form.cpp.
References m_cgi, m_current, raw, and strcpyval().
00564 { 00565 if (m_current != m_cgi.end() ) 00566 { 00567 CGI *current = *m_current; 00568 strncpy(n,current -> name,len - 1); 00569 n[len - 1] = 0; 00570 if (raw) 00571 { 00572 strncpy(v,current -> value,vlen - 1); 00573 v[vlen - 1] = 0; 00574 } 00575 else 00576 { 00577 strcpyval(v,current -> value,vlen); 00578 } 00579 m_current++; // = current -> next; 00580 return true; 00581 } else 00582 *n = 0; 00583 return false; 00584 }
int Cgi::Form::getvalue | ( | const std::string & | , | |
char * | , | |||
short | ||||
) |
Definition at line 587 of file Form.cpp.
References m_cgi, raw, and strcpyval().
00588 { 00589 CGI *cgi = NULL; 00590 int r = 0; 00591 00592 // for (cgi = cgibase; cgi; cgi = cgi -> next) 00593 for (cgi_v::iterator it = m_cgi.begin(); it != m_cgi.end(); it++) 00594 { 00595 cgi = *it; 00596 if (!strcmp(cgi -> name,n.c_str())) 00597 break; 00598 cgi = NULL; 00599 } 00600 if (cgi) 00601 { 00602 if (raw) 00603 { 00604 strncpy(v,cgi -> value,len - 1); 00605 v[len - 1] = 0; 00606 } 00607 else 00608 { 00609 strcpyval(v,cgi -> value,len); 00610 } 00611 r++; 00612 } else 00613 *v = 0; 00614 00615 return r; 00616 }
std::string Cgi::Form::getvalue | ( | const std::string & | ) |
Definition at line 618 of file Form.cpp.
References m_cgi.
00619 { 00620 // for (CGI *cgi = cgibase; cgi; cgi = cgi -> next) 00621 for (cgi_v::iterator it = m_cgi.begin(); it != m_cgi.end(); it++) 00622 { 00623 CGI *cgi = *it; 00624 if (!strcmp(cgi -> name,n.c_str() )) 00625 { 00626 return cgi -> value; 00627 } 00628 } 00629 return ""; 00630 }
size_t Cgi::Form::getlength | ( | char * | ) |
Definition at line 632 of file Form.cpp.
00633 { 00634 CGI *cgi = NULL; 00635 size_t l; 00636 00637 // for (cgi = cgibase; cgi; cgi = cgi -> next) 00638 for (cgi_v::iterator it = m_cgi.begin(); it != m_cgi.end(); it++) 00639 { 00640 cgi = *it; 00641 if (!strcmp(cgi -> name,n)) 00642 break; 00643 cgi = NULL; 00644 } 00645 l = cgi ? strlen(cgi -> value) : 0; 00646 if (cgi && !raw) 00647 { 00648 for (size_t i = 0; i < strlen(cgi -> value); i++) 00649 { 00650 switch (cgi -> value[i]) 00651 { 00652 case '<': // < 00653 case '>': // > 00654 l += 4; 00655 break; 00656 case '&': // & 00657 l += 5; 00658 break; 00659 } 00660 } 00661 } 00662 return l; //cgi ? strlen(cgi -> value) : 0; 00663 }
cgi_v& Cgi::Form::getbase | ( | ) | [inline] |
char * Cgi::Form::GetBoundary | ( | ) |
Definition at line 666 of file Form.cpp.
References m_strBoundary.
00667 { 00668 return m_strBoundary ? m_strBoundary : (char *)""; 00669 }
cgi_v Cgi::Form::m_cgi [private] |
Definition at line 105 of file Form.h.
Referenced by Form(), getbase(), getfirst(), getlength(), getnext(), getvalue(), and ~Form().
cgi_v::iterator Cgi::Form::m_current [private] |
char* Cgi::Form::m_strBoundary [private] |
bool Cgi::Form::raw [private] |
Definition at line 109 of file Form.h.
Referenced by EnableRaw(), getlength(), getnext(), and getvalue().