void createResponse(bufferevent *pBufferEvent) { struct evbuffer* pInputBuffer = bufferevent_get_input(pBufferEvent); struct evbuffer* pOutputBuffer = bufferevent_get_output(pBufferEvent); char *line; size_t size = 0; line = evbuffer_readln(pInputBuffer, &size, EVBUFFER_EOL_CRLF); std::string Request = std::string(line); //std::cout << Request << "\n"; //read method and path size_t nMethodEnd = Request.find(" "); std::string sMethod = std::string(Request, 0, nMethodEnd); //std::cout << sMethod << "\n"; size_t nPathEnd = Request.find(" ", nMethodEnd+1); std::string sRawPath = std::string(Request, nMethodEnd+1, nPathEnd-nMethodEnd-1); //std::cout << sRawPath << "\n"; size_t nDelimPos = sRawPath.find('?'); std::string sHalfRawPath = sRawPath.substr(0, nDelimPos); //std::cout << sHalfRawPath << "\n"; char* sTempPath = new char[sHalfRawPath.length()+1]; // at most the same size + term\0 urlDecode(sTempPath, sHalfRawPath.c_str()); std::string sPath = std::string(sTempPath); //std::cout << sPath << "\n"; if (Request.find(" ", nPathEnd+1) != std::string::npos) { // extra spaces in request //std::cout << "ERROR: extra spaces\n"; writeHeader(pOutputBuffer, STATUS_BAD_REQUEST, TYPE_HTML, MASSAGE_LENGTH_BAD_REQUEST); evbuffer_add(pOutputBuffer, MASSAGE_BAD_REQUEST, MASSAGE_LENGTH_BAD_REQUEST); return; } //Validate path if(!validatePath(sPath)) { //std::cout << "Warning: forbidden path\n"; writeHeader(pOutputBuffer, STATUS_FORBIDDEN, TYPE_HTML, MASSAGE_LENGTH_FORBIDDEN); evbuffer_add(pOutputBuffer, MASSAGE_FORBIDDEN, MASSAGE_LENGTH_FORBIDDEN); return; } //std::cout << "Ok: path ok\n"; //find target file std::string sRealPath = std::string(DOCUMENT_ROOT); sRealPath.append(std::string(sPath)); bool bIndex = false; if (sRealPath[sRealPath.length()-1] == '/') { //std::cout << "Ok: index\n"; sRealPath.append("index.html"); bIndex = true; } int fFile = open(sRealPath.c_str(), O_NONBLOCK|O_RDONLY); if (fFile == -1) { //std::cout << "Warning: file not opened\n"; if (bIndex) { writeHeader(pOutputBuffer, STATUS_FORBIDDEN, TYPE_HTML, MASSAGE_LENGTH_FORBIDDEN); evbuffer_add(pOutputBuffer, MASSAGE_FORBIDDEN, MASSAGE_LENGTH_FORBIDDEN); } else { writeHeader(pOutputBuffer, STATUS_NOT_FOUND, TYPE_HTML, MASSAGE_LENGTH_NOT_FOUND); evbuffer_add(pOutputBuffer, MASSAGE_NOT_FOUND, MASSAGE_LENGTH_NOT_FOUND); } return; } //std::cout << "Ok: file opened\n"; struct stat FileStats; fstat(fFile, &FileStats); if(!strcmp(sMethod.c_str(), METHOD_GET)) { //std::cout << "Ok: method \"get\"\n"; writeHeader(pOutputBuffer, STATUS_OK, getContentType(sRealPath), FileStats.st_size); evbuffer_add_file(pOutputBuffer, fFile, 0, FileStats.st_size); } else if(!strcmp(sMethod.c_str(), METHOD_HEAD)){ //std::cout << "Ok: method \"head\"\n"; // ctime gives only /n so we'll add proper CRLF writeHeader(pOutputBuffer, STATUS_OK, getContentType(sRealPath), FileStats.st_size); evbuffer_add(pOutputBuffer, CRLF, 2); } else { writeHeader(pOutputBuffer, STATUS_BAD_REQUEST, TYPE_HTML, MASSAGE_LENGTH_BAD_REQUEST); evbuffer_add(pOutputBuffer, MASSAGE_BAD_REQUEST, MASSAGE_LENGTH_BAD_REQUEST); } return; }
void ParseFile::uploadFile(const char* dir, const char* fileName) { std::string pathName = dir; pathName += "/"; pathName += fileName; const char* error = 0; FILE* file = 0; char* buffer = 0; do { file = fopen(pathName.c_str(), "rb"); if (file == 0) { error = "open file error!"; break; } fseek(file, 0, SEEK_END); size_t size = ftell(file); fseek(file, 0, SEEK_SET); buffer = new char[size]; if (buffer == 0) { error = "malloc buffer error!"; break; } if (fread(buffer, 1, size, file) != size) { error = "read file error!"; break; } fclose(file); file = 0; ParseManager::instance()->request(CCHttpRequest::kHttpPost, std::string("/1/files/") + fileName, buffer, size, this, (SEL_CallFuncND)&ParseFile::uploadFileFinished, getContentType(fileName)); }while(0); if (error) { FileInfo* result = 0; ParseError* parseError = new ParseError(); parseError->SetError(error); this->uploadFileCompleted(result, parseError); delete parseError; } if (file) { fclose(file); } if (buffer) { delete buffer; } }
void body::generateImpl (const generationContext& ctx, utility::outputStream& os, const string::size_type /* curLinePos */, string::size_type* newLinePos) const { // MIME-Multipart if (getPartCount() != 0) { string boundary; if (m_header.acquire() == NULL) { boundary = generateRandomBoundaryString(); } else { try { ref <const contentTypeField> ctf = m_header.acquire()->findField(fields::CONTENT_TYPE) .dynamicCast <const contentTypeField>(); boundary = ctf->getBoundary(); } catch (exceptions::no_such_field&) { // Warning: no content-type and no boundary string specified! boundary = generateRandomBoundaryString(); } catch (exceptions::no_such_parameter&) { // Warning: no boundary string specified! boundary = generateRandomBoundaryString(); } } const text prologText = getActualPrologText(ctx); const text epilogText = getActualEpilogText(ctx); if (!prologText.isEmpty()) { prologText.encodeAndFold(ctx, os, 0, NULL, text::FORCE_NO_ENCODING | text::NO_NEW_LINE_SEQUENCE); os << CRLF; } os << "--" << boundary; for (size_t p = 0 ; p < getPartCount() ; ++p) { os << CRLF; getPartAt(p)->generate(ctx, os, 0); os << CRLF << "--" << boundary; } os << "--" << CRLF; if (!epilogText.isEmpty()) { epilogText.encodeAndFold(ctx, os, 0, NULL, text::FORCE_NO_ENCODING | text::NO_NEW_LINE_SEQUENCE); os << CRLF; } if (newLinePos) *newLinePos = 0; } // Simple body else { // Generate the contents ref <contentHandler> contents = m_contents->clone(); contents->setContentTypeHint(getContentType()); contents->generate(os, getEncoding(), ctx.getMaxLineLength()); } }
int SendFileExRequestPacket::putContents( unsigned char * buf ) { int pos = 0; memset(buf, 0, 11);pos+=11; // 11 bytes 0x00 buf[pos++] = m_TransferType; // transfer File or custom-picture buf[pos++] = 0x00; buf[pos++] = 0x66; // unknown byte, 0x66, but sometimes is 0x67 // 2 bytes, 0x0000 ( if is Cancellation Request,this part still here? // no, if not QQ_IM_EX_REQUEST_CANCELED command, this part will be here.:) if(getContentType() != QQ_IM_EX_REQUEST_CANCELLED) pos+=EvaUtil::write16(buf+pos, 0x00); pos+=EvaUtil::write32(buf+pos, 1); // 4 bytes, 0x00000001 pos+=EvaUtil::write16(buf+pos, 0x00); // 2 bytes, 0x0000 pos+=EvaUtil::write16(buf+pos, m_SessionId); // can it be random number ? if(getContentType() != QQ_IM_EX_REQUEST_CANCELLED){ if(getContentType() == QQ_IM_EX_REQUEST_ACCEPTED){ pos+=EvaUtil::write32(buf+pos, m_WanIp); // big endian memset(buf+pos, 0, 8); pos+=8; }else { // this may include ip(4 bytes) and port(4 bytes) and 0x00000000(4 bytes) memset(buf+pos, 0, 12); pos+=12; } buf[pos++] = 0x02; // unknown, 0x02 or 0x04 if(getContentType() == QQ_IM_TCP_REQUEST) EvaUtil::write16(buf+pos, 0x0102); else memset(buf+pos, 0, 2); pos+=2; } pos+=EvaUtil::write32(buf+pos, 1); // unknown 4 bytes, 0x00000000 or 0x00000001 memset(buf+pos, 0, 2); pos+=2; if(getContentType() == QQ_IM_EX_REQUEST_ACCEPTED){ // QQ_IM_EX_REQUEST_ACCEPTED finished here memset(buf+pos, 0, 2); pos+=2; return pos; } if(getContentType() == QQ_IM_EX_REQUEST_CANCELLED){ // QQ_IM_EX_REQUEST_CANCELED finished here memset(buf+pos, 0, 6); pos+=6; return pos; } int offset = 0; if(getContentType() == QQ_IM_EX_UDP_REQUEST){ offset = pos; pos+=2; buf[pos++] = 0x01; // unknown pos+=2; // this part this the following part length again! so offset will be offset+3 } buf[pos++] = 0x20; buf[pos++] = 0x1f; int len = strlen(m_FileName.c_str()); memcpy(buf+pos, m_FileName.c_str(), len); pos+=len; buf[pos++] = 0x1f; #ifdef WIN32 char* strSize; strSize=(char*)_alloca(100); #else char strSize[100]; #endif memset(strSize, 100, 0); sprintf(strSize, "%d", m_FileSize); len = strlen(strSize); memcpy(buf+pos, strSize, len); pos+=len; buf[pos++] = 0x20; // chinese for "byte"(zijie) encoded in GB18030 buf[pos++] = 0xd7; buf[pos++] = 0xd6; buf[pos++] = 0xbd; buf[pos++] = 0xda; // now we set the 2 lengths EvaUtil::write16(buf+offset, pos-offset-2); EvaUtil::write16(buf+offset+3, pos-offset-2-3-2); // printf("\n----====== SendFileExRequestPacket::putContents ======----"); // for(int i=0; i<pos; i++){ // if(!(i%8)) printf("\n%d: ",i); // char t = buf[i]; // printf("%2x ", (uint8_t)t); // } // printf("\n ----====== UDP EX Request Sent ======----\n\n"); return pos; }
bool MailMessage::isMultipart() const { MediaType mediaType = getContentType(); return mediaType.matches("multipart"); }
// . returns -1 on error, 0 on success // . reads HTTP reply from filename given as argument, filters it, // and then writes it to stdout // . originally, we read from stdin, but popen was causing problems when called // from a thread on linux 2.4.17 with the old linux threads int main ( int argc , char *argv[] ) { // should have one and only 1 arg (excluding filename) if ( argc != 2 ) { fprintf(stderr,"gbfilter: usage: gbfilter <inputfilename>\n"); return -1; } // . read HTTP reply in from file, gigablast will give it to us there // . this should be the HTTP mime followed by the content char *buf = (char *)malloc ( MAX_READ_SIZE ); if ( ! buf ) { fprintf(stderr,"gbfilter:malloc:%s: %s: %s\n", argv[1],strerror(errno)); return -1; } // first and only arg is the input file to read from int fd = open ( argv[1] , O_RDONLY ); if ( fd < 0 ) { fprintf(stderr,"gbfilter:open: %s: %s\n", argv[1],strerror(errno)); free ( buf ); return -1; } int n = read ( fd , buf , MAX_READ_SIZE ); close ( fd ); // return -1 on read error if ( n < 0 ) { fprintf(stderr,"gbfilter:fread: %s\n",strerror(errno)); free ( buf ); return -1; } // warn if the doc was bigger than expected if ( n >= MAX_READ_SIZE ) fprintf(stderr,"gbfilter: WARNING: MAX_READ_SIZE " "needs boost\n"); //sleep(45); //srand(time(NULL)); //int32_t i = rand() % 30; //fprintf(stderr,"sleep(%"INT32")\n",i); //sleep(i); // if nothing came in then nothing goes out, we're done if ( n == 0 ) { free ( buf ) ; return 0; } // get the end of the mime of this HTTP reply int32_t mimeLen = getMimeLen ( buf , n ); // if it is -1, no mime boundary was found, so return an error if ( mimeLen < 0 ) { fprintf(stderr,"gbfilter: no mime boundary\n"); free ( buf ); return -1; } // . get the id from the input filename // . use that for out tmp files as well so parent caller can remove // our cruft if we core int32_t id ; char *p = argv[1]; // get id in the file while ( *p && ! isdigit(*p) ) p++; id = atol ( p ); // ... begin filter logic here ... // get the content type (the various types are #define'd above) char ctype = getContentType ( buf , mimeLen ); bool filter = false; if ( ctype == CT_PDF ) filter = true ; if ( ctype == CT_DOC ) filter = true ; if ( ctype == CT_XLS ) filter = true ; if ( ctype == CT_PPT ) filter = true ; if ( ctype == CT_PS ) filter = true ; if ( filter ) { int status = filterContent ( buf, n, mimeLen, ctype, id ); free ( buf ); return status; } // ... end filter logic here ... // if not filtered, write the input to stdout unaltered // no! make it 0 bytes! //int32_t w = fwrite ( buf , 1 , n , stdout ); //if ( w == n ) { free ( buf ) ; return 0; } free ( buf ); return 0; // note any errors fprintf(stderr,"gbfilter: fwrite: %s\n",strerror(errno)); free ( buf ); return -1; }
void body::generateImpl (const generationContext& ctx, utility::outputStream& os, const size_t /* curLinePos */, size_t* newLinePos) const { // MIME-Multipart if (getPartCount() != 0) { string boundary; if (!m_part) { boundary = generateRandomBoundaryString(); } else { // Use current boundary string, if specified. If no "Content-Type" field is // present, or the boundary is not specified, generate a random one shared_ptr <contentTypeField> ctf = m_part->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE); if (ctf) { if (ctf->hasBoundary()) { boundary = ctf->getBoundary(); } else { // No boundary string specified boundary = generateRandomBoundaryString(); } } else { // No Content-Type (and no boundary string specified) boundary = generateRandomBoundaryString(); } } const text prologText = getActualPrologText(ctx); const text epilogText = getActualEpilogText(ctx); if (!prologText.isEmpty()) { prologText.encodeAndFold(ctx, os, 0, NULL, text::FORCE_NO_ENCODING | text::NO_NEW_LINE_SEQUENCE); os << CRLF; } os << "--" << boundary; for (size_t p = 0 ; p < getPartCount() ; ++p) { os << CRLF; getPartAt(p)->generate(ctx, os, 0); os << CRLF << "--" << boundary; } os << "--" << CRLF; if (!epilogText.isEmpty()) { epilogText.encodeAndFold(ctx, os, 0, NULL, text::FORCE_NO_ENCODING | text::NO_NEW_LINE_SEQUENCE); os << CRLF; } if (newLinePos) *newLinePos = 0; } // Simple body else { // Generate the contents shared_ptr <contentHandler> contents = m_contents->clone(); contents->setContentTypeHint(getContentType()); contents->generate(os, getEncoding(), ctx.getMaxLineLength()); } }
void handleConnection(int socketfd) { static char buffer[BUFFER_SIZE+1]; static char* headers[HEADER_LIMIT+1]; int i; int headerCount=0; //int requestSize = read(socketfd,buffer,BUFFER_SIZE); int requestSize = readUntil(socketfd,crlfcrlfCheck,buffer,BUFFER_SIZE); if (requestSize ==0 || requestSize == -1) { fail("failed to read browser request"); } logText(buffer); int done = 0; char mode = 0; /* */ for (i=0;i<requestSize;i++) { switch(mode) { case '\r': if (buffer[i] == '\n') { buffer[i-1]=0; mode=0; done = (*headers[headerCount]==0) || (headerCount++ == HEADER_LIMIT); } break; case 0: headers[headerCount]=&buffer[i]; default: mode=buffer[i]; if (mode==0) done=1; /* catch headers containing zeros */ } if (done) break; } int bodyStart=i+1; int bodyLength=requestSize-bodyStart; headers[headerCount]=NULL; /*null terminated list*/ logFormat("%d header lines\n",headerCount); logText("we got some headers"); for (i=0; i<headerCount;i++) { logFormat("%d: %s\n",i,headers[i]); } logText("That was them headers"); /* logText("looking for User-Agent:"); char* userAgent=findHeader(0,headerCount,headers,"User-Agent:"); if (userAgent==NULL) {logText("No User-Agent");} else {logText(userAgent);} */ char* aCookie = findHeader(0,headerCount,headers,"Cookie:"); int uid=getUserInfo(aCookie); logFormat("uid of %d\n",uid); if (uid <= 0) { if (strncmp("POST /login ",headers[0],12) == 0 ) { //for a non-logged-in user POST to /login try and read user credentials. logText("Login request received"); char userpass[300]; struct passwd* pwd = NULL; strncpy(userpass,&buffer[bodyStart],300); if (userpass[299] == 0) { char* user = NULL; char* pass = NULL; user = strstr(userpass,"user="******"pass="******"I think the userName is '%s'\n",user); //logFormat("I think the passWord is '%s'\n",pass); pwd = checkUserPass(user,pass); free(pass); } char* resultPage; if (pwd != NULL) { logText("setting cookie"); char token[33]; token[32]='\0'; makeAuthenticationToken(pwd->pw_uid,token,32); char* pageHeaders; asprintf(&pageHeaders,"Set-Cookie: %s; Secure; HttpOnly\r\nLocation: %s\r\n",token,loginRedirect); logText(pageHeaders); resultPage= "<html><head></head><body" "<div>Login Successful</div>" "</body></html>"; sendHTMLPage(socketfd,"303 See Other",pageHeaders,resultPage); free(pageHeaders); } else { resultPage= "<html><head></head><body" "<div>Login Failed</div>" "</body></html>"; sendSimpleHTMLPage(socketfd,"401 Unauthorised",resultPage); } } else { sendLoginPage(socketfd); } } else { struct passwd *pw = getpwuid(uid); setgid(uid); setuid(uid); setenv("HOME",pw->pw_dir,1); setenv("USER",pw->pw_name,1); setenv("SHELL",pw->pw_shell,1); //if we get to here, the request sent a token identifying them as a //valid user and we have dropped privileges to be that user. //now we can set about serving the user request. #ifdef NOTANOS //support for a notanos websocket server. char* upgrade = findHeader(0,headerCount,headers,"Upgrade:"); if (upgrade) { //Try using websockets char* websocket_key = findHeader(0,headerCount,headers,"Sec-WebSocket-Key:"); char* websocket_protocol = findHeader(0,headerCount,headers,"Sec-WebSocket-Protocol:"); char* websocket_version = findHeader(0,headerCount,headers,"Sec-WebSocket-Version:"); char* origin = findHeader(0,headerCount,headers,"Origin:"); webSocketUpgrade(socketfd,websocket_key,websocket_protocol,websocket_version,origin); //webSocketUpgrade should never return } #endif if (strncmp("GET ",headers[0],4) == 0 ) { char* nameStart=headers[0]+4; int nameLen = strcspn(nameStart," "); char* urlName=strndup(nameStart,nameLen); char* fileName=url_decode(urlName); char* queryStart=strchr(fileName,'?'); if (queryStart != NULL) *queryStart++='\0'; logFormat("url request '%s'\n",urlName); logFormat("filename request '%s'\n",fileName); char* newFileName=expandFilename(fileName); free(fileName); fileName=newFileName; char* contentType=getContentType(fileName); struct stat fileInfo; int res=stat(fileName,&fileInfo); if (res !=0) { if (errno == EACCES) { sendSimpleHTMLPage(socketfd,"403 Forbidden","403: Forbidden"); } else { sendSimpleHTMLPage(socketfd,"404 Not Found","404: Not Found"); } } else { if (S_ISREG(fileInfo.st_mode)) { int filefd=open(fileName,O_RDONLY); if (filefd < 0) { sendSimpleHTMLPage(socketfd,"403 Forbidden","403: Forbidden"); } else { sendFileChunked(socketfd,"200 OK",filefd,contentType); close(filefd); } } else if (S_ISDIR(fileInfo.st_mode)) { char* command; char* awkline = "BEGIN {printf(\"{\\\"path\\\":\\\"%s\\\",\\n \\\"contents\\\":[\\n\",path)} END{print\"\\n ]\\n};\\n\"} NR > 2 { printf(\",\\n\") } NR >1 { printf(\" {\\\"filename\\\":\\\"%s\\\", \\\"attributes\\\":\\\"%s\\\", \\\"owner\\\":\\\"%s\\\", \\\"size\\\":%s}\", $9, $1, $3, $5) }"; //int commandLength = asprintf(&command,"ls -AlQ %s| awk -v path=%s '%s'",fileName,fileName,awkline); int commandLength = asprintf(&command,"./jsondir '%s'",fileName); logText(command); if (commandLength>0) { FILE* commandPipe = popen(command,"r"); if (commandPipe) { int commandfd=(fileno(commandPipe)); sendFileChunked(socketfd,"200 OK",commandfd,"application/json"); pclose(commandPipe); } else { sendSimpleHTMLPage(socketfd,"500 Internal Server Error","popen failure"); } free(command); } else { sendSimpleHTMLPage(socketfd,"200 OK","That's a directory"); } } } free(fileName); free(contentType); free(urlName); } } logText("done response, closing connection"); sleep(1); close(socketfd); exit(1); }
// is this a POST request encapsulating a file upload? bool HTTPHeader::isPostUpload(Socket &peersock) { if (header.front().toCharArray()[0] != 'P') { return false; } /*bool answer = false; int postlen = postdata.buffer_length; int i; if (postlen < 14) { // min length for there to be a match return false; } char *postdatablock = new char[postlen + 64]; // extra 64 for search try { postdata.copyToMemory(postdatablock); for (i = 0; i < postlen; i++) { // make lowercase char by char if (isupper(postdatablock[i])) { postdatablock[i] = tolower(postdatablock[i]); } } RegExp mysearch; std::string dis("content-type: "); // signifies file upload char *p = new char[32]; try { for (i = 0; i < (signed) dis.length(); i++) { p[i] = dis[i]; // copy it to the block of memory } char *pend = p + dis.length(); // pointer for search char *postdatablockend = postdatablock + postlen; // search the post data for the content type header char *res = mysearch.search(postdatablock, postdatablockend, p, pend); // if we searched all the way to the end without finding it, // there is no post upload going on; otherwise, there is if (res != postdatablockend) { answer = true; } } catch(exception & e) { }; delete[]p; } catch(exception & e) { }; delete[]postdatablock; return answer;*/ off_t cl = contentLength(); if (((cl > 0) && (cl < 14)) || (getContentType() == "application/x-www-form-urlencoded")) { #ifdef DGDEBUG std::cout << "Based on content length/type, is not POST upload!" << std::endl; #endif ispostupload = false; return false; } if (getContentType().length() > 0) { #ifdef DGDEBUG std::cout << "Based on content length/type, is POST upload!" << std::endl; #endif ispostupload = true; return true; } #ifdef DGDEBUG std::cout << "Reading a line of POST data to determine content type: "; #endif postdatalen = peersock.getLine(postdata, 14, 60, &postdatachopped); #ifdef DGDEBUG std::cout << postdata << std::endl; #endif if (postdatalen != 14) { #ifdef DGDEBUG std::cout << "Is not POST upload!" << std::endl; #endif ispostupload = false; return false; } String conttype(postdata); if (conttype.startsWithLower("content-type: ")) { #ifdef DGDEBUG std::cout << "Is POST upload!" << std::endl; #endif ispostupload = true; return true; } else { #ifdef DGDEBUG std::cout << "Is not POST upload!" << std::endl; #endif ispostupload = false; return false; } }
// does the given content type string match our headers? bool HTTPHeader::isContentType(const String& t) { return getContentType().startsWith(t); }