mirror of
https://github.com/lxsang/ant-http
synced 2024-11-17 17:08:20 +01:00
299 lines
6.4 KiB
C
299 lines
6.4 KiB
C
|
#include "utils.h"
|
||
|
char* __s(const char* fstring,...)
|
||
|
{
|
||
|
char* data;
|
||
|
va_list arguments;
|
||
|
int dlen;
|
||
|
va_start( arguments, fstring);
|
||
|
dlen = vsnprintf(0,0,fstring,arguments) + 1;
|
||
|
va_end(arguments);
|
||
|
va_end(arguments);
|
||
|
if ((data = (char*)malloc(dlen*sizeof(char))) != 0)
|
||
|
{
|
||
|
va_start(arguments, fstring);
|
||
|
vsnprintf(data, dlen, fstring, arguments);
|
||
|
va_end(arguments);
|
||
|
return data;
|
||
|
} else
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Trim a string by a character on both ends
|
||
|
* @param str The target string
|
||
|
* @param delim the delim
|
||
|
*/
|
||
|
void trim(char* str, const char delim)
|
||
|
{
|
||
|
char * p = str;
|
||
|
int l = strlen(p);
|
||
|
|
||
|
while(p[l - 1] == delim) p[--l] = 0;
|
||
|
while(* p && (* p) == delim ) ++p, --l;
|
||
|
memmove(str, p, l + 1);
|
||
|
}
|
||
|
|
||
|
void removeAll(const char* path,int mode)
|
||
|
{
|
||
|
DIR *d;
|
||
|
struct dirent *dir;
|
||
|
char* file;
|
||
|
struct stat st;
|
||
|
if( stat(path, &st) == 0)
|
||
|
{
|
||
|
if(S_ISDIR(st.st_mode))
|
||
|
{
|
||
|
d = opendir(path);
|
||
|
if(d)
|
||
|
{
|
||
|
while ((dir = readdir(d)) != NULL)
|
||
|
{
|
||
|
if(strcmp(dir->d_name,".") == 0 || strcmp(dir->d_name,"..")==0) continue;
|
||
|
file = __s("%s/%s",path,dir->d_name);
|
||
|
|
||
|
removeAll(file,1);
|
||
|
free(file);
|
||
|
}
|
||
|
closedir(d);
|
||
|
}
|
||
|
}
|
||
|
if(mode)
|
||
|
remove(path);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
char* __time(time_t time)
|
||
|
{
|
||
|
struct tm *t = localtime(&time);
|
||
|
char * buf = asctime(t);
|
||
|
char* pos = strchr(buf,'\n');
|
||
|
if(pos) *pos = '\0';
|
||
|
return buf;
|
||
|
}
|
||
|
char* server_time()
|
||
|
{
|
||
|
return __time(time(NULL));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get extension of a file name
|
||
|
* @param file The file name
|
||
|
* @return the extension
|
||
|
*/
|
||
|
char* ext(const char* file)
|
||
|
{
|
||
|
char* token,*ltoken = "";
|
||
|
if(file == NULL) return NULL;
|
||
|
char* str_cpy = strdup(file);
|
||
|
if(strstr(str_cpy,".")<= 0) return "";
|
||
|
if(*file == '.')
|
||
|
trim(str_cpy,'.');
|
||
|
|
||
|
while((token = strsep(&str_cpy,".")) && strlen(token)>0) {ltoken = token;}
|
||
|
free(str_cpy);
|
||
|
return ltoken;
|
||
|
|
||
|
}
|
||
|
/**
|
||
|
* Get correct HTTP mime type of a file
|
||
|
* This is a minimalistic mime type list supported
|
||
|
* by the server
|
||
|
* @param file File name
|
||
|
* @return The HTTP Mime Type
|
||
|
*/
|
||
|
char* mime(const char* file)
|
||
|
{
|
||
|
char * ex = ext(file);
|
||
|
if(IEQU(ex,"bmp"))
|
||
|
return "image/bmp";
|
||
|
else if(IEQU(ex,"jpg") || IEQU(ex,"jpeg"))
|
||
|
return "image/jpeg";
|
||
|
else if(IEQU(ex,"css"))
|
||
|
return "text/css";
|
||
|
else if(IEQU(ex,"csv"))
|
||
|
return "text/csv";
|
||
|
else if(IEQU(ex,"pdf"))
|
||
|
return "application/pdf";
|
||
|
else if(IEQU(ex,"gif"))
|
||
|
return "image/gif";
|
||
|
else if(IEQU(ex,"html")||(IEQU(ex,"htm")))
|
||
|
return "text/html";
|
||
|
else if(IEQU(ex,"json"))
|
||
|
return "application/json";
|
||
|
else if(IEQU(ex,"js"))
|
||
|
return "application/javascript";
|
||
|
else if(IEQU(ex,"png"))
|
||
|
return "image/png";
|
||
|
else if(IEQU(ex,"ppm"))
|
||
|
return "image/x-portable-pixmap";
|
||
|
else if(IEQU(ex,"rar"))
|
||
|
return "application/x-rar-compressed";
|
||
|
else if(IEQU(ex,"tiff"))
|
||
|
return "image/tiff";
|
||
|
else if(IEQU(ex,"tar"))
|
||
|
return "application/x-tar";
|
||
|
else if(IEQU(ex,"txt"))
|
||
|
return "text/plain";
|
||
|
else if(IEQU(ex,"ttf"))
|
||
|
return "application/x-font-ttf";
|
||
|
else if(IEQU(ex,"xhtml"))
|
||
|
return "application/xhtml+xml";
|
||
|
else if(IEQU(ex,"xml"))
|
||
|
return "application/xml";
|
||
|
else if(IEQU(ex,"zip"))
|
||
|
return "application/zip";
|
||
|
else if(IEQU(ex,"svg"))
|
||
|
return "image/svg+xml";
|
||
|
else if(IEQU(ex,"eot"))
|
||
|
return "application/vnd.ms-fontobject";
|
||
|
else if(IEQU(ex,"woff") || IEQU(ex,"woff2"))
|
||
|
return "application/x-font-woff";
|
||
|
else if(IEQU(ex,"otf"))
|
||
|
return "application/x-font-otf";
|
||
|
else
|
||
|
// The other type will be undestant as binary
|
||
|
return "application/octet-stream";
|
||
|
}
|
||
|
|
||
|
int is_bin(const char* file)
|
||
|
{
|
||
|
char * ex = ext(file);
|
||
|
if(IEQU(ex,"bmp"))
|
||
|
return true;
|
||
|
else if(IEQU(ex,"jpg") || IEQU(ex,"jpeg"))
|
||
|
return true;
|
||
|
else if(IEQU(ex,"css"))
|
||
|
return false;
|
||
|
else if(IEQU(ex,"csv"))
|
||
|
return false;
|
||
|
else if(IEQU(ex,"pdf"))
|
||
|
return true;
|
||
|
else if(IEQU(ex,"gif"))
|
||
|
return true;
|
||
|
else if(IEQU(ex,"html")||(IEQU(ex,"htm")))
|
||
|
return false;
|
||
|
else if(IEQU(ex,"json"))
|
||
|
return false;
|
||
|
else if(IEQU(ex,"js"))
|
||
|
return false;
|
||
|
else if(IEQU(ex,"png"))
|
||
|
return true;
|
||
|
else if(IEQU(ex,"ppm"))
|
||
|
return true;
|
||
|
else if(IEQU(ex,"rar"))
|
||
|
return true;
|
||
|
else if(IEQU(ex,"tiff"))
|
||
|
return true;
|
||
|
else if(IEQU(ex,"tar"))
|
||
|
return true;
|
||
|
else if(IEQU(ex,"txt"))
|
||
|
return false;
|
||
|
else if(IEQU(ex,"ttf"))
|
||
|
return true;
|
||
|
else if(IEQU(ex,"xhtml"))
|
||
|
return false;
|
||
|
else if(IEQU(ex,"xml"))
|
||
|
return false;
|
||
|
else if(IEQU(ex,"zip"))
|
||
|
return true;
|
||
|
else if(IEQU(ex,"svg"))
|
||
|
return false;
|
||
|
else if(IEQU(ex,"eot"))
|
||
|
return true;
|
||
|
else if(IEQU(ex,"woff") || IEQU(ex,"woff2"))
|
||
|
return true;
|
||
|
else if(IEQU(ex,"otf"))
|
||
|
return true;
|
||
|
else
|
||
|
// The other type will be undestant as binary
|
||
|
return "application/octet-stream";
|
||
|
}
|
||
|
|
||
|
int match_int(const char* search)
|
||
|
{
|
||
|
return regex_match("^[-+]?[0-9]+$",search);
|
||
|
}
|
||
|
int match_float(const char* search)
|
||
|
{
|
||
|
return regex_match("^[+-]?[0-9]*\\.[0-9]+$",search);
|
||
|
}
|
||
|
int regex_match(const char* expr,const char* search)
|
||
|
{
|
||
|
regex_t regex;
|
||
|
int reti;
|
||
|
char msgbuf[100];
|
||
|
int ret;
|
||
|
/* Compile regular expression */
|
||
|
reti = regcomp(®ex, expr, REG_ICASE | REG_EXTENDED);
|
||
|
if( reti ){
|
||
|
LOG("Could not compile regex: %s\n",expr);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/* Execute regular expression */
|
||
|
reti = regexec(®ex, search, 0, NULL, 0);
|
||
|
if( !reti ){
|
||
|
//LOG("Match");
|
||
|
ret = 1;
|
||
|
}
|
||
|
else if( reti == REG_NOMATCH ){
|
||
|
//LOG("No match");
|
||
|
ret = 0;
|
||
|
}
|
||
|
else{
|
||
|
regerror(reti, ®ex, msgbuf, sizeof(msgbuf));
|
||
|
LOG("Regex match failed: %s\n", msgbuf);
|
||
|
ret = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
regfree(®ex);
|
||
|
return ret;
|
||
|
}
|
||
|
char *url_decode(const char *str) {
|
||
|
char *pstr = str, *buf = malloc(strlen(str) + 1), *pbuf = buf;
|
||
|
|
||
|
while (*pstr) {
|
||
|
if (*pstr == '%') {
|
||
|
if (pstr[1] && pstr[2]) {
|
||
|
*pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]);
|
||
|
pstr += 2;
|
||
|
}
|
||
|
} else if (*pstr == '+') {
|
||
|
*pbuf++ = ' ';
|
||
|
} else {
|
||
|
*pbuf++ = *pstr;
|
||
|
}
|
||
|
pstr++;
|
||
|
}
|
||
|
*pbuf = '\0';
|
||
|
|
||
|
return buf;
|
||
|
}
|
||
|
|
||
|
char *url_encode(const char *str) {
|
||
|
char *pstr = str, *buf = malloc(strlen(str) * 3 + 1), *pbuf = buf;
|
||
|
while (*pstr) {
|
||
|
if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~')
|
||
|
*pbuf++ = *pstr;
|
||
|
else if (*pstr == ' ')
|
||
|
*pbuf++ = '+';
|
||
|
else
|
||
|
*pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
|
||
|
pstr++;
|
||
|
}
|
||
|
*pbuf = '\0';
|
||
|
return buf;
|
||
|
}
|
||
|
|
||
|
char from_hex(char ch) {
|
||
|
return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
|
||
|
}
|
||
|
|
||
|
char to_hex(char code) {
|
||
|
static char hex[] = "0123456789abcdef";
|
||
|
return hex[code & 15];
|
||
|
}
|