char *FinalizeDirListHTML(char *Buffer, HTTPSession *Session, const char *Path, const char *DirItemsHtml, const char *MimeIconsURL, int Flags) { char *HTML=NULL; HTML=FormatStr(Buffer,"<html>\r\n<head><title>/%s%s</title></head>\r\n<body>\r\n",Session->Host, Session->URL); if ((Flags & DIR_FANCY)) { if (Flags & DIR_INTERACTIVE) HTML=CatStr(HTML,"<form>\r\n"); HTML=CatStr(HTML,"<table align=center border=0><tr>\n"); if (Settings.Flags & FLAG_SSL) HTML=MCatStr(HTML,"<td><font color=green size=-1>SECURE<br/>",Session->Cipher,"</font></td>\n",NULL); else HTML=MCatStr(HTML,"<td><font color=red size=-1>Unencrypted<br/>Connection</font></td>\n",NULL); HTML=MCatStr(HTML,"<td><b>",Session->URL,"</b> at ",Session->Host, " <i>",GetDateStrFromSecs("%Y/%m/%d %H:%M:%S",Now,NULL),"</i><br/>",NULL); HTML=DisplayDirActions(HTML,Session,Flags); HTML=CatStr(HTML,"</td>\n"); HTML=MCatStr(HTML,"<td>User: "******"<br/>",NULL); if (Settings.Flags & FLAG_LOGOUT_AVAILABLE) HTML=MCatStr(HTML,"<a href=\"",GetLogoutPath(),"\">( Logout )</a>",NULL); HTML=CatStr(HTML,"</td></tr></table>\n"); } HTML=MCatStr(HTML,DirItemsHtml,"<br /> <br />",NULL); if (Flags & DIR_INTERACTIVE) HTML=CatStr(HTML,"</form>\r\n"); HTML=CatStr(HTML,"</body></html>\r\n"); return(HTML); }
int ProcessGetFileInfo(TFileStore *FS, char *Pattern, char *Arg, int CmdFlags, ListNode *Vars) { ListNode *Items=NULL, *Curr; char *Tempstr=NULL, *IncludePattern=NULL, *ExcludePattern=NULL, *ptr; TFileInfo *FI; int result=FALSE, Flags, i; char *DisplayVars[]={"Category","Author","Subtitle","Duration","Dimensions",NULL}; //"Summary","Description",NULL}; IncludePattern=CopyStr(IncludePattern,GetVar(Vars,"IncludePattern")); ExcludePattern=CopyStr(ExcludePattern,GetVar(Vars,"ExcludePattern")); Items=ListCreate(); Flags=LIST_REFRESH; //if (CmdFlags & FLAG_CMD_RECURSE) Flags |= LIST_INCLUDE_DIRS; FileStoreLoadDir(FS,Pattern,Items, Flags); Curr=ListGetNext(Items); while (Curr) { FI=(TFileInfo *) Curr->Item; if (FileIncluded(FI,IncludePattern,ExcludePattern,CmdFlags, Vars)) { if (FI->Type==FTYPE_DIR) { if (CmdFlags & FLAG_CMD_RECURSE) InternalRecurseInfoCommand(FS, FI->Name, Arg, CmdFlags, Vars, ProcessGetFileInfo); } else { printf("\nInfo For %s\n",FI->Path); printf("Size: %s (%d bytes)\n",GetHumanReadableDataQty(FI->Size,0),FI->Size); printf("ContentType: %s\n",FI->MediaType); printf("Timestamp: %s\n",GetDateStrFromSecs("%Y/%m/%d %H:%M:%S",FI->Mtime,NULL)); for (i=0; DisplayVars[i]; i++) { ptr=GetVar(FI->Vars,DisplayVars[i]); if (StrLen(ptr)) printf("%s: %s\n",DisplayVars[i],ptr); } } } Curr=ListGetNext(Curr); } ListDestroy(Items,FileInfoDestroy); DestroyString(IncludePattern); DestroyString(ExcludePattern); DestroyString(Tempstr); }
void HTTPServerSendCSV(STREAM *S, HTTPSession *Session, char *Path, int NoOfFiles, TPathItem **Files) { char *Tempstr=NULL, *SizeStr=NULL, *CSV=NULL; struct stat Stat; int i; CSV=CopyStr(CSV,"File Name,URL,Last Modified,Size\r\n"); for (i=0; i < NoOfFiles; i++) { stat(Files[i]->Path,&Stat); SizeStr=FormatStr(SizeStr,"%d",Stat.st_size); CSV=MCatStr(CSV,"\"",GetBasename(Files[i]->Path),"\", \"",Files[i]->URL,"\", \"",GetDateStrFromSecs("%Y/%m/%d %H:%M:%S",Stat.st_mtime,NULL),"\", \"",SizeStr,"\"\r\n",NULL); } Tempstr=MCopyStr(Tempstr,Path,".csv",NULL); SetVar(Session->Headers,"Content-disposition",Tempstr); HTTPServerSendResponse(S, Session, "200 OK","text/csv",CSV); DestroyString(Tempstr); DestroyString(SizeStr); DestroyString(CSV); }
void HTTPSendHeaders(STREAM *S, HTTPInfoStruct *Info) { char *SendStr=NULL, *Tempstr=NULL, *ptr; ListNode *Curr; int count; int i; static int AuthCounter=0; STREAMClearDataProcessors(S); SendStr=CopyStr(SendStr,Info->Method); SendStr=CatStr(SendStr," "); if (Info->Flags & HTTP_PROXY) Tempstr=HTTPInfoToURL(Tempstr, Info); else Tempstr=HTTPQuoteChars(Tempstr,Info->Doc," "); SendStr=CatStr(SendStr,Tempstr); if (Info->Flags & HTTP_VER1_0) SendStr=CatStr(SendStr," HTTP/1.0\r\n"); else SendStr=MCatStr(SendStr," HTTP/1.1\r\n","Host: ",Info->Host,"\r\n",NULL); if (StrLen(Info->PostContentType) >0) { Tempstr=FormatStr(Tempstr,"Content-type: %s\r\n",Info->PostContentType); SendStr=CatStr(SendStr,Tempstr); } if (Info->PostContentLength > 0) { Tempstr=FormatStr(Tempstr,"Content-Length: %d\r\n",Info->PostContentLength); SendStr=CatStr(SendStr,Tempstr); } if (StrLen(Info->Destination)) { Tempstr=FormatStr(Tempstr,"Destination: %s\r\n",Info->Destination); SendStr=CatStr(SendStr,Tempstr); } /* If we have authorisation details then send them */ if (Info->Authorization) SendStr=HTTPHeadersAppendAuth(SendStr, "Authorization", Info, Info->Authorization); if (Info->ProxyAuthorization) SendStr=HTTPHeadersAppendAuth(SendStr, "Proxy-Authorization", Info, Info->ProxyAuthorization); if (Info->Flags & HTTP_NOCACHE) SendStr=CatStr(SendStr,"Pragma: no-cache\r\nCache-control: no-cache\r\n"); if (Info->Depth > 0) { Tempstr=FormatStr(Tempstr,"Depth: %d\r\n",Info->Depth); SendStr=CatStr(SendStr,Tempstr); } /* if ((PathData->Options.Restart) && (PathData->offset >0)) { snprintf(Buffer,sizeof(Buffer),"Range: bytes=%d-\r\n",PathData->offset); SendStr=CatStr(SendStr,Buffer); } */ if (Info->IfModifiedSince > 0) { Tempstr=CopyStr(Tempstr,GetDateStrFromSecs("%a, %d %b %Y %H:%M:%S GMT",Info->IfModifiedSince,NULL)); SendStr=MCatStr(SendStr,"If-Modified-Since: ",Tempstr, "\r\n",NULL); } if ( (strcasecmp(Info->Method,"DELETE") !=0) && (strcasecmp(Info->Method,"HEAD") !=0) && (strcasecmp(Info->Method,"PUT") !=0) ) { Tempstr=CopyStr(Tempstr,""); if (! (Info->Flags & HTTP_NOCOMPRESS)) { if (DataProcessorAvailable("Compression","gzip")) Tempstr=CatStr(Tempstr,"gzip"); if (DataProcessorAvailable("Compression","zlib")) { if (StrLen(Tempstr)) Tempstr=CatStr(Tempstr,", deflate"); else Tempstr=CatStr(Tempstr,"deflate"); } } if (StrLen(Tempstr)) SendStr=MCatStr(SendStr,"Accept-Encoding: ",Tempstr,"\r\n",NULL); else SendStr=CatStr(SendStr,"Accept-Encoding:\r\n"); } if (Info->Flags & HTTP_KEEPALIVE) { //if (Info->Flags & HTTP_VER1_0) SendStr=CatStr(SendStr,"Connection: Keep-Alive\r\n"); //SendStr=CatStr(SendStr,"Content-Length: 0\r\n"); } else { SendStr=CatStr(SendStr,"Connection: Close\r\n"); } ptr=LibUsefulGetValue("HTTP:User-Agent"); if (StrLen(ptr)) SendStr=MCatStr(SendStr,"User-Agent: ",ptr, "\r\n",NULL); Curr=ListGetNext(Info->CustomSendHeaders); while (Curr) { SendStr=MCatStr(SendStr,Curr->Tag, ": ", (char *) Curr->Item, "\r\n",NULL); Curr=ListGetNext(Curr); } if (! (Info->Flags & HTTP_NOCOOKIES)) { SendStr=AppendCookies(SendStr,Cookies); } SendStr=CatStr(SendStr,"\r\n"); Info->State |= HTTP_HEADERS_SENT; if (Info->Flags & HTTP_DEBUG) fprintf(stderr,"HTTPSEND: ------\n%s------\n\n",SendStr); STREAMWriteLine(SendStr,S); STREAMFlush(S); DestroyString(Tempstr); DestroyString(SendStr); }
char *GetDateStr(const char *DateFormat, const char *TimeZone) { return(GetDateStrFromSecs(DateFormat, (time_t) GetTime(0), TimeZone)); }
char *FormatFancyDirItem(char *RetStr, int count, TPathItem *File, const char *MimeIconsURL, int Flags) { char *Tempstr=NULL, *FileType=NULL, *DateStr=NULL, *DisplayName=NULL, *Interact=NULL; char *Comment=NULL, *CheckBox=NULL, *ptr; char *bgcolor; ListNode *Vars; Vars=ListCreate(); LoadFileProperties(File->Path, Vars); /* ptr=GetVar(Vars,"comment"); if (StrLen(ptr)) { Comment=MCopyStr(Comment," title=\"",ptr,"\" ",NULL); } else Comment=CopyStr(Comment,""); */ Comment=FormatFancyDirComment(Comment, Vars); if ((count % 2)==0) bgcolor="#FFFFFF"; else bgcolor="#CCCCCC"; if ((Now - File->Mtime) < 60) { DateStr=FormatStr(DateStr,"<font color=red>%d seconds ago</font>",Now - File->Mtime); } else DateStr=CopyStr(DateStr,GetDateStrFromSecs("%Y/%m/%d %H:%M:%S",File->Mtime,NULL)); FileType=FormatFileType(FileType, File, Vars, MimeIconsURL); //Okay, start building the actual table row RetStr=MCatStr(RetStr, "<tr bgcolor=\"",bgcolor,"\">",NULL); Interact=CopyStr(Interact,""); CheckBox=CopyStr(CheckBox,""); if (strcmp(File->Name,"..")==0) { DisplayName=CopyStr(DisplayName,".. (Parent Directory)"); if (Settings.DirListFlags & DIR_INTERACTIVE) CheckBox=CopyStr(CheckBox,"<td align=\"center\"> </td>"); } else { if (Settings.DisplayNameLen && (StrLen(File->Name) > Settings.DisplayNameLen)) { DisplayName=CopyStrLen(DisplayName,File->Name,Settings.DisplayNameLen); DisplayName=CatStr(DisplayName,"..."); } else DisplayName=CopyStr(DisplayName,File->Name); if (Settings.DirListFlags & DIR_INTERACTIVE) { if (Flags & SELECT_ALL) CheckBox=MCatStr(CheckBox,"<td align=\"center\"><input type=\"checkbox\" name=\"selected\" value=\"",File->Name,"\" checked /></td>",NULL); else CheckBox=MCatStr(CheckBox,"<td align=\"center\"><input type=\"checkbox\" name=\"selected\" value=\"",File->Name,"\" /></td>",NULL); //Interaction string will be added to end of line Interact=MCatStr(Interact,"<input type='submit' name='edit:",File->URL,"' value='Edit' /> ",NULL); Interact=MCatStr(Interact,"<input type='submit' name='del:",File->URL,"' value='Del' /> ",NULL); //one day, but not yet //if (strncasecmp(File->ContentType,"audio/",6)==0) Interact=MCatStr(Interact,"<input type=\"button\" onclick=\"javascript: addaudio('",File->URL,"');\" value=\"Play\" /> ",NULL); } } Tempstr=FormatStr(Tempstr,"%s<td title=\"%s\">%s</td><td><a href=\"%s\" title=\"%s\">%s</a></td><td align=right> %s</td><td align=right> %s</td><td align=center>%s</td>",CheckBox,Comment,FileType,File->URL, File->Path, DisplayName, DateStr, GetHumanReadableDataQty((double) File->Size,0), Interact); //Append it all to our output RetStr=MCatStr(RetStr,Tempstr,"</tr>\r\n",NULL); DestroyString(DisplayName); DestroyString(FileType); DestroyString(Interact); DestroyString(Comment); DestroyString(Tempstr); DestroyString(DateStr); ListDestroy(Vars,DestroyString); return(RetStr); }
char *GetDateStr(const char *DateFormat, const char *TimeZone) { time(&CachedTime); return(GetDateStrFromSecs(DateFormat, CachedTime, TimeZone)); }
void HTTPServerSendHeaders(STREAM *S, HTTPSession *Session, int Flags) { char *Tempstr=NULL; ListNode *Curr; Tempstr=MCopyStr(Tempstr,Session->Protocol," ",Session->ResponseCode,"\r\n",NULL); STREAMWriteLine(Tempstr,S); if (Settings.Flags & FLAG_LOG_VERBOSE) LogToFile(Settings.LogPath,">> %s",Tempstr); HTTPServerSendHeader(S,"Date",GetDateStr("%a, %d %b %Y %H:%M:%S %Z",NULL)); if (Session->LastModified > 0) HTTPServerSendHeader(S,"Last-Modified",GetDateStrFromSecs("%a, %d %b %Y %H:%M:%S %Z",Session->LastModified,NULL)); if (Flags & HEADERS_AUTH) { if (Settings.AuthFlags & FLAG_AUTH_DIGEST) Tempstr=FormatStr(Tempstr,"Digest realm=\"%s\", qop=\"auth\", nonce=\"%x\"", Settings.AuthRealm, rand()); else Tempstr=MCopyStr(Tempstr,"Basic realm=\"",Settings.AuthRealm,"\"",NULL); if (IsProxyMethod(Session->MethodID) ) HTTPServerSendHeader(S,"Proxy-Authenticate",Tempstr); else { Tempstr=MCopyStr(Tempstr,"Basic realm=\"",Settings.AuthRealm,"\"",NULL); HTTPServerSendHeader(S,"WWW-Authenticate",Tempstr); if (Settings.AuthFlags & FLAG_AUTH_DIGEST) { Tempstr=FormatStr(Tempstr,"Digest realm=\"%s\", qop=\"auth\", nonce=\"%x\"", Settings.AuthRealm, rand()); HTTPServerSendHeader(S,"WWW-Authenticate",Tempstr); } } } //Special headers passed in for this transaction Curr=ListGetNext(Session->Headers); while (Curr) { HTTPServerSendHeader(S, Curr->Tag, (char *) Curr->Item); Curr=ListGetNext(Curr); } //Custom headers defined in the config file Curr=ListGetNext(Settings.CustomHeaders); while (Curr) { HTTPServerSendHeader(S, Curr->Tag, (char *) Curr->Item); Curr=ListGetNext(Curr); } if (Session->MethodID==METHOD_WEBSOCKET) { HTTPServerSendHeader(S, "Upgrade", "WebSocket"); HTTPServerSendHeader(S, "Connection", "Upgrade"); } else { if ((Flags & HEADERS_USECACHE) && (Settings.DocumentCacheTime > 0)) { Tempstr=FormatStr(Tempstr,"max-age=%d",Session->CacheTime); HTTPServerSendHeader(S, "Cache-Control", Tempstr); HTTPServerSendHeader(S,"Expires",GetDateStrFromSecs("%a, %d %b %Y %H:%M:%S %Z",time(NULL) + Session->CacheTime,NULL)); } else { HTTPServerSendHeader(S, "Cache-Control", "no-cache"); HTTPServerSendHeader(S, "Pragma", "no-cache"); } //Offer Upgrade to SSL if we have it if ((! Session->Flags & HTTP_SSL) && SSLAvailable()) { HTTPServerSendHeader(S, "Upgrade", "TLS/1.0"); } if ((Session->Flags & SESSION_KEEPALIVE) && (Flags & HEADERS_KEEPALIVE)) { HTTPServerSendHeader(S, "Connection", "Keep-Alive"); Session->Flags |= SESSION_REUSE; } else { HTTPServerSendHeader(S, "Connection", "close"); Session->Flags &= ~SESSION_REUSE; } if ((Settings.AuthFlags & FLAG_AUTH_COOKIE) && (Session->Flags & SESSION_AUTHENTICATED) && (! (Session->AuthFlags & FLAG_AUTH_HASCOOKIE))) { if (StrLen(Session->UserName)) { Tempstr=MakeAccessCookie(Tempstr, Session); HTTPServerSendHeader(S, "Set-Cookie", Tempstr); } } //If we are running a CGI script, then the script will handle all headers relating to content if (! (Flags & HEADERS_CGI)) { HTTPServerSendHeader(S, "DAV", "1"); if (StrLen(Session->ContentType)) HTTPServerSendHeader(S,"Content-Type",Session->ContentType); else HTTPServerSendHeader(S,"Content-Type","octet/stream"); if ((Session->Flags & SESSION_REUSE) || (Session->ContentSize > 0)) { Tempstr=FormatStr(Tempstr,"%d",Session->ContentSize); HTTPServerSendHeader(S,"Content-Length",Tempstr); } //some clients use 'x-gzip' rather than just 'gzip' if (Session->Flags & SESSION_ENCODE_XGZIP) HTTPServerSendHeader(S,"Content-Encoding","x-gzip"); else if (Session->Flags & SESSION_ENCODE_GZIP) HTTPServerSendHeader(S,"Content-Encoding", "gzip"); //Blank line to end headers STREAMWriteLine("\r\n",S); } } LogFileFlushAll(TRUE); DestroyString(Tempstr); }