mirror of
https://github.com/lxsang/ant-http
synced 2025-07-13 13:04:23 +02:00
refactor: refactoring base code
This commit is contained in:
264
lib/dbhelper.c
264
lib/dbhelper.c
@ -1,264 +0,0 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "dbhelper.h"
|
||||
#include "utils.h"
|
||||
|
||||
sqlite3 * database(const char* file)
|
||||
{
|
||||
sqlite3* db;
|
||||
int rc = sqlite3_open(file,&db);
|
||||
if (rc != SQLITE_OK) {
|
||||
ERROR( "Cannot open database: %s %s",file, sqlite3_errmsg(db));
|
||||
sqlite3_close(db);
|
||||
return NULL;
|
||||
}
|
||||
return db;
|
||||
}
|
||||
void dbclose(sqlite3* db)
|
||||
{
|
||||
sqlite3_close(db);
|
||||
}
|
||||
int dbquery(sqlite3* db,const char* sql, int (*call_back)())
|
||||
{
|
||||
char *err_msg = 0;
|
||||
sqlite3_mutex_enter(sqlite3_db_mutex(db));
|
||||
int rc = sqlite3_exec(db,sql,call_back,0,&err_msg);
|
||||
sqlite3_mutex_leave(sqlite3_db_mutex(db));
|
||||
if(rc != SQLITE_OK)
|
||||
{
|
||||
ERROR("Cannot query : '%s' [%s]", sql,err_msg);
|
||||
sqlite3_free(err_msg);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
dbfield __field()
|
||||
{
|
||||
dbfield ret = malloc(sizeof *ret);
|
||||
ret->name = NULL;
|
||||
ret->value = NULL;
|
||||
ret->next = NULL;
|
||||
return ret;
|
||||
}
|
||||
dbrecord __record()
|
||||
{
|
||||
dbrecord ret = malloc(sizeof *ret);
|
||||
ret->fields = NULL;
|
||||
ret->idx = 0;
|
||||
ret->next = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* __name_list(const dbfield f)
|
||||
{
|
||||
char* sql = f->name;
|
||||
for(dbfield p=f->next;p!=NULL;p=p->next)
|
||||
{
|
||||
sql = __s("%s,%s",sql,p->name);
|
||||
}
|
||||
return sql;
|
||||
}
|
||||
char* __value_list(const dbfield f)
|
||||
{
|
||||
char* sql = __s("'%s'",f->value);
|
||||
for(dbfield p=f->next;p!=NULL;p=p->next)
|
||||
{
|
||||
sql = __s("%s,'%s'",sql,p->value);
|
||||
}
|
||||
return sql;
|
||||
}
|
||||
char* __name_value_list(const dbfield f)
|
||||
{
|
||||
char* sql = __s("%s='%s'", f->name,f->value);
|
||||
for(dbfield p=f->next;p!=NULL;p=p->next)
|
||||
{
|
||||
sql = __s("%s,%s='%s'",sql, p->name,f->value);
|
||||
}
|
||||
return sql;
|
||||
}
|
||||
|
||||
void add_record(dbrecord* r,dbfield f)
|
||||
{
|
||||
dbrecord new_r = malloc(sizeof *new_r);
|
||||
new_r->fields = f;
|
||||
new_r->idx = 1;
|
||||
new_r->next = NULL;
|
||||
if((*r)->idx == 0)
|
||||
{
|
||||
freerecord(&(*r));
|
||||
*r = new_r;
|
||||
}
|
||||
else
|
||||
{
|
||||
dbrecord* temp;
|
||||
for(temp = r;(*temp)->next!=NULL;temp=&((*temp)->next))
|
||||
{
|
||||
(*temp)->idx++;
|
||||
}
|
||||
(*temp)->next = new_r;
|
||||
}
|
||||
//new_r->next = *r;
|
||||
//*r = new_r;
|
||||
}
|
||||
|
||||
void add_field(dbfield* field,const char* name, const char* value)
|
||||
{
|
||||
dbfield new_field = malloc(sizeof *new_field);
|
||||
new_field->name = strdup(name);
|
||||
new_field->value = strdup(value);
|
||||
new_field->next = *field;
|
||||
*field = new_field;
|
||||
}
|
||||
char* value_of(const dbfield f,const char* key)
|
||||
{
|
||||
for(dbfield t = f; t != NULL; t=t->next)
|
||||
if(strcmp(t->name,key)==0)
|
||||
return t->value;
|
||||
return NULL;
|
||||
}
|
||||
int dbinsert(sqlite3* db,const char* table, const dbfield fields)
|
||||
{
|
||||
char* sqlprefix = "INSERT INTO %s (%s) VALUES (%s)";
|
||||
char* name_list = __name_list(fields);
|
||||
char* value_list = __value_list(fields);
|
||||
char* sql = __s(sqlprefix,table,name_list,value_list);
|
||||
int ret = dbquery(db,sql,NULL);
|
||||
free(name_list);
|
||||
free(value_list);
|
||||
free(sql);
|
||||
|
||||
if(ret == 0)
|
||||
return -1;
|
||||
return sqlite3_last_insert_rowid(db);
|
||||
}
|
||||
dbrecord dball(sqlite3* db,const char* table)
|
||||
{
|
||||
return dbselect(db,table,"1=%s","1");
|
||||
}
|
||||
dbrecord dbselect(sqlite3* db, const char* table, const char* fname,const char* fstring,...)
|
||||
{
|
||||
char* sql;
|
||||
char* prefix = "SELECT %s FROM %s WHERE %s";
|
||||
char* cond;
|
||||
va_list arguments;
|
||||
int dlen;
|
||||
sqlite3_stmt *statement;
|
||||
dbrecord records = __record();
|
||||
|
||||
va_start( arguments, fstring);
|
||||
dlen = vsnprintf(0,0,fstring,arguments) + 1;
|
||||
va_end(arguments);
|
||||
cond = (char*) malloc(dlen*sizeof(char));
|
||||
va_start(arguments, fstring);
|
||||
vsnprintf(cond, dlen, fstring, arguments);
|
||||
va_end(arguments);
|
||||
sql = __s(prefix, fname,table,cond);
|
||||
|
||||
if(sqlite3_prepare_v2(db, sql, -1, &statement, 0) == SQLITE_OK)
|
||||
{
|
||||
int cols = sqlite3_column_count(statement);
|
||||
int result = 0;
|
||||
while((result = sqlite3_step(statement)) == SQLITE_ROW)
|
||||
{
|
||||
dbfield fields = __field();
|
||||
for(int col = 0; col < cols; col++)
|
||||
{
|
||||
const char *value = (const char*)sqlite3_column_text(statement, col);
|
||||
const char *name = sqlite3_column_name(statement, col);
|
||||
add_field(&fields,name,(value!=0)?value:"");
|
||||
}
|
||||
add_record(&records,fields);
|
||||
}
|
||||
sqlite3_finalize(statement);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("Can not select:%s [%s]\n",sql,sqlite3_errmsg(db));
|
||||
}
|
||||
|
||||
free(cond);
|
||||
free(sql);
|
||||
return records;
|
||||
}
|
||||
int hastable(sqlite3* db,const char* table)
|
||||
{
|
||||
//char * prefix = __s("type='table' and name='%s'",table);
|
||||
dbrecord rc = dbselect(db,"sqlite_master","*","type='table' and name='%s'", table);
|
||||
//free(prefix);
|
||||
if(!rc) return 0;
|
||||
if(!rc->fields)
|
||||
{
|
||||
freerecord(&rc);
|
||||
return 0;
|
||||
}
|
||||
freerecord(&rc);
|
||||
return 1;
|
||||
}
|
||||
int dbupdate(sqlite3* db,const char* table,const dbfield field,const char* fstring,...)
|
||||
{
|
||||
char* sql;
|
||||
char* prefix = "UPDATE %s SET %s WHERE (%s)";
|
||||
char* cond;
|
||||
char* list;
|
||||
va_list arguments;
|
||||
int dlen;
|
||||
va_start( arguments, fstring);
|
||||
dlen = vsnprintf(0,0,fstring,arguments) + 1;
|
||||
va_end(arguments);
|
||||
cond = (char*) malloc(dlen*sizeof(char));
|
||||
va_start(arguments, fstring);
|
||||
vsnprintf(cond, dlen, fstring, arguments);
|
||||
va_end(arguments);
|
||||
|
||||
list = __name_value_list(field);
|
||||
sql = __s(prefix,table,list,cond);
|
||||
int ret = dbquery(db,sql,NULL);
|
||||
free(cond);
|
||||
free(list);
|
||||
free(sql);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dbdelete(sqlite3* db,const char* table,const char* fstring,...)
|
||||
{
|
||||
char* sql;
|
||||
char* prefix = "DELETE FROM %s WHERE (%s)";
|
||||
char* cond;
|
||||
va_list arguments;
|
||||
int dlen;
|
||||
va_start( arguments, fstring);
|
||||
dlen = vsnprintf(0,0,fstring,arguments) + 1;
|
||||
va_end(arguments);
|
||||
cond = (char*) malloc(dlen*sizeof(char));
|
||||
va_start(arguments, fstring);
|
||||
vsnprintf(cond, dlen, fstring, arguments);
|
||||
va_end(arguments);
|
||||
sql = __s(prefix,table,cond);
|
||||
int ret = dbquery(db,sql,NULL);
|
||||
free(cond);
|
||||
free(sql);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void freerecord(dbrecord * r)
|
||||
{
|
||||
dbrecord curr;
|
||||
while ((curr = (*r)) != NULL) {
|
||||
(*r) = (*r)->next;
|
||||
if(curr->fields)
|
||||
freefield(&(curr->fields));
|
||||
free (curr);
|
||||
}
|
||||
}
|
||||
void freefield(dbfield *f)
|
||||
{
|
||||
dbfield curr;
|
||||
while( (curr = (*f)) != NULL )
|
||||
{
|
||||
(*f) = (*f)->next;
|
||||
if(curr->name) free(curr->name);
|
||||
if(curr->value) free(curr->value);
|
||||
free(curr);
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
#ifndef DB_HELPER
|
||||
#define DB_HELPER
|
||||
#include <sqlite3.h>
|
||||
|
||||
sqlite3 * database(const char*);
|
||||
typedef struct _dbfield
|
||||
{
|
||||
char* name;
|
||||
char* value;
|
||||
struct _dbfield* next;
|
||||
} *dbfield ;
|
||||
|
||||
typedef struct _dbrecord
|
||||
{
|
||||
dbfield fields;
|
||||
int idx;
|
||||
struct _dbrecord* next;
|
||||
} * dbrecord;
|
||||
|
||||
int dbquery(sqlite3*,const char*, int (*)());
|
||||
int dbinsert(sqlite3*,const char*,const dbfield);
|
||||
int hastable(sqlite3*,const char*);
|
||||
int dbupdate(sqlite3*,const char*,const dbfield,const char*,...);
|
||||
dbrecord dbselect(sqlite3*, const char*, const char*,const char*,...);
|
||||
dbrecord dball(sqlite3*,const char*);
|
||||
int dbdelete(sqlite3*,const char*,const char*,...);
|
||||
dbfield __field();
|
||||
dbrecord __record();
|
||||
char* __name_list(const dbfield);
|
||||
char* __value_list(const dbfield);
|
||||
char* __name_value_list(const dbfield);
|
||||
char* value_of(const dbfield,const char*);
|
||||
void add_field(dbfield*,const char*, const char*);
|
||||
void add_record(dbrecord*,dbfield);
|
||||
void dbclose(sqlite3*);
|
||||
void freerecord(dbrecord *);
|
||||
void freefield(dbfield *);
|
||||
#endif
|
47
lib/handle.h
47
lib/handle.h
@ -40,25 +40,13 @@ typedef enum
|
||||
ANTD_CNONE
|
||||
} antd_compress_t;
|
||||
|
||||
|
||||
typedef enum {
|
||||
ANTD_PROTO_IP_4,
|
||||
ANTD_PROTO_IP_6,
|
||||
ANTD_PROTO_ALL
|
||||
} antd_proto_t;
|
||||
|
||||
//extern config_t server_config;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int port;
|
||||
int usessl;
|
||||
char *htdocs;
|
||||
char* plugins;
|
||||
int sock;
|
||||
antd_proto_t type;
|
||||
dictionary_t rules;
|
||||
} port_config_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int sock;
|
||||
@ -85,36 +73,6 @@ typedef struct
|
||||
|
||||
} antd_response_header_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
//int port;
|
||||
char *plugins_dir;
|
||||
char *plugins_ext;
|
||||
char *db_path;
|
||||
//char* htdocs;
|
||||
char *tmpdir;
|
||||
char *stat_fifo_path;
|
||||
dictionary_t handlers;
|
||||
int backlog;
|
||||
int maxcon;
|
||||
int connection;
|
||||
int n_workers;
|
||||
int scheduler_timeout;
|
||||
int max_upload_size;
|
||||
// ssl
|
||||
int enable_ssl;
|
||||
char *sslcert;
|
||||
char *sslkey;
|
||||
char *ssl_cipher;
|
||||
int gzip_enable;
|
||||
int debug_enable;
|
||||
list_t gzip_types;
|
||||
dictionary_t mimes;
|
||||
dictionary_t ports;
|
||||
dictionary_t plugins;
|
||||
// #endif
|
||||
} config_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[MAX_PATH_LEN];
|
||||
@ -124,10 +82,9 @@ typedef struct
|
||||
dictionary_t config;
|
||||
int raw_body;
|
||||
int status;
|
||||
void *instance_data;
|
||||
} plugin_header_t;
|
||||
|
||||
|
||||
|
||||
void set_nonblock(int socket);
|
||||
//void set_block(int socket);
|
||||
|
||||
|
29
lib/plugin.h
29
lib/plugin.h
@ -6,19 +6,8 @@
|
||||
|
||||
#include "utils.h"
|
||||
#include "handle.h"
|
||||
#include "dbhelper.h"
|
||||
|
||||
|
||||
//typedef void(*call)();
|
||||
#ifdef USE_DB
|
||||
typedef sqlite3* sqldb;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_DB
|
||||
sqldb getdb();
|
||||
sqldb __getdb(char *name);
|
||||
#endif
|
||||
|
||||
char* config_dir();
|
||||
/*Default function for plugin*/
|
||||
@ -49,24 +38,6 @@ void use_raw_body()
|
||||
{
|
||||
__plugin__.raw_body = 1;
|
||||
}
|
||||
#ifdef USE_DB
|
||||
sqldb __getdb(char *name)
|
||||
{
|
||||
int plen = strlen(name)+strlen(__plugin__.dbpath)+4;
|
||||
char* path = (char*) malloc(plen*sizeof(char));
|
||||
strcpy(path,__plugin__.dbpath);
|
||||
strcat(path,name);
|
||||
strcat(path,".db");
|
||||
//LOG("database: %s\n", path);
|
||||
sqldb ret = (sqldb)database(path);
|
||||
free(path);
|
||||
return ret;
|
||||
}
|
||||
sqldb getdb()
|
||||
{
|
||||
return __getdb(__plugin__.name);
|
||||
}
|
||||
#endif
|
||||
|
||||
plugin_header_t* meta()
|
||||
{
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <poll.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include "scheduler.h"
|
||||
#include "utils.h"
|
||||
#include "bst.h"
|
||||
|
@ -77,6 +77,8 @@ A million repetitions of "a"
|
||||
*/
|
||||
|
||||
/* #define SHA1HANDSOFF */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "sha1.h"
|
||||
|
||||
void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]);
|
||||
|
@ -3,8 +3,6 @@
|
||||
|
||||
#ifndef __SHA1_H
|
||||
#define __SHA1_H
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
689
lib/utils.c
689
lib/utils.c
@ -43,64 +43,64 @@ THE SOFTWARE.
|
||||
#include "sha1.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include "dictionary.h"
|
||||
// #include <time.h>
|
||||
|
||||
|
||||
/**
|
||||
* 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)
|
||||
void trim(char *str, const char delim)
|
||||
{
|
||||
if(!str || strlen(str) == 0) return;
|
||||
char * p = str;
|
||||
if (!str || strlen(str) == 0)
|
||||
return;
|
||||
char *p = str;
|
||||
int l = strlen(p);
|
||||
while(l > 0 && p[l - 1] == delim)
|
||||
while (l > 0 && p[l - 1] == delim)
|
||||
p[--l] = 0;
|
||||
while(* p && (* p) == delim ) ++p, --l;
|
||||
while (*p && (*p) == delim)
|
||||
++p, --l;
|
||||
memmove(str, p, l + 1);
|
||||
}
|
||||
|
||||
void removeAll(const char* path,int mode)
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
removeAll(file, 1);
|
||||
free(file);
|
||||
}
|
||||
closedir(d);
|
||||
}
|
||||
}
|
||||
if (mode)
|
||||
remove(path);
|
||||
}
|
||||
}
|
||||
|
||||
// WARNING:
|
||||
// TODO: remove it, this function is not thread-safe
|
||||
|
||||
void timestr(time_t time, char* buf,int len,char* format, int gmt)
|
||||
void timestr(time_t time, char *buf, int len, char *format, int gmt)
|
||||
{
|
||||
struct tm t;
|
||||
if(gmt)
|
||||
struct tm t;
|
||||
if (gmt)
|
||||
{
|
||||
gmtime_r(&time, &t);
|
||||
}
|
||||
@ -108,52 +108,55 @@ void timestr(time_t time, char* buf,int len,char* format, int gmt)
|
||||
{
|
||||
localtime_r(&time, &t);
|
||||
}
|
||||
strftime(buf, len, format, &t);
|
||||
strftime(buf, len, format, &t);
|
||||
}
|
||||
void server_time(char* buf, int len)
|
||||
void server_time(char *buf, int len)
|
||||
{
|
||||
timestr(time(NULL), buf, len ,"%a, %d %b %Y %H:%M:%S", 0);
|
||||
timestr(time(NULL), buf, len, "%a, %d %b %Y %H:%M:%S", 0);
|
||||
}
|
||||
/**
|
||||
* Get extension of a file name
|
||||
* @param file The file name
|
||||
* @return the extension
|
||||
*/
|
||||
char* ext(const char* file)
|
||||
char *ext(const char *file)
|
||||
{
|
||||
char* token,*ltoken = "";
|
||||
if(file == NULL) return NULL;
|
||||
char* str_cpy = strdup(file);
|
||||
char* str_org = str_cpy;
|
||||
if(!strstr(str_cpy,"."))
|
||||
char *token, *ltoken = "";
|
||||
if (file == NULL)
|
||||
return NULL;
|
||||
char *str_cpy = strdup(file);
|
||||
char *str_org = str_cpy;
|
||||
if (!strstr(str_cpy, "."))
|
||||
{
|
||||
free(str_org);
|
||||
return NULL;
|
||||
}
|
||||
if(*file == '.')
|
||||
trim(str_cpy,'.');
|
||||
}
|
||||
if (*file == '.')
|
||||
trim(str_cpy, '.');
|
||||
|
||||
while((token = strsep(&str_cpy,".")) && strlen(token)>0) {ltoken = token;}
|
||||
char* ext = strdup(ltoken);
|
||||
while ((token = strsep(&str_cpy, ".")) && strlen(token) > 0)
|
||||
{
|
||||
ltoken = token;
|
||||
}
|
||||
char *ext = strdup(ltoken);
|
||||
free(str_org);
|
||||
return ext;
|
||||
|
||||
return ext;
|
||||
}
|
||||
/*get mime file info from extension*/
|
||||
mime_t mime_from_ext(const char* ex)
|
||||
mime_t mime_from_ext(const char *ex)
|
||||
{
|
||||
dictionary_t mime_list = mimes_list();
|
||||
mime_t ret = (mime_t){"application/octet-stream",NULL};
|
||||
if(!mime_list)
|
||||
mime_t ret = (mime_t){"application/octet-stream", NULL};
|
||||
if (!mime_list)
|
||||
return ret;
|
||||
chain_t it;
|
||||
char * pattern = __s("(^\\s*%s\\s*,)|(\\s*,\\s*%s\\s*,\\s*)|(^\\s*%s\\s*$)|(,\\s*%s\\s*$)", ex, ex, ex, ex);
|
||||
if(pattern)
|
||||
char *pattern = __s("(^\\s*%s\\s*,)|(\\s*,\\s*%s\\s*,\\s*)|(^\\s*%s\\s*$)|(,\\s*%s\\s*$)", ex, ex, ex, ex);
|
||||
if (pattern)
|
||||
{
|
||||
for_each_assoc(it,mime_list)
|
||||
for_each_assoc(it, mime_list)
|
||||
{
|
||||
|
||||
if(regex_match(pattern,it->value,0, NULL))
|
||||
|
||||
if (regex_match(pattern, it->value, 0, NULL))
|
||||
{
|
||||
ret.type = it->key;
|
||||
ret.ext = it->value;
|
||||
@ -166,18 +169,17 @@ mime_t mime_from_ext(const char* ex)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void verify_header(char* k)
|
||||
void verify_header(char *k)
|
||||
{
|
||||
k[0] = toupper(k[0]);
|
||||
int len = strlen(k);
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
if(k[i] == '-' && i < len-1)
|
||||
if (k[i] == '-' && i < len - 1)
|
||||
{
|
||||
k[i+1] = toupper(k[i+1]);
|
||||
k[i + 1] = toupper(k[i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dictionary_t mimes_list()
|
||||
@ -185,19 +187,19 @@ dictionary_t mimes_list()
|
||||
return NULL;
|
||||
}
|
||||
/*get mime file info from type*/
|
||||
mime_t mime_from_type(const char* type)
|
||||
mime_t mime_from_type(const char *type)
|
||||
{
|
||||
dictionary_t mime_list = mimes_list();
|
||||
mime_t ret = (mime_t){NULL,NULL};
|
||||
if(!mime_list)
|
||||
mime_t ret = (mime_t){NULL, NULL};
|
||||
if (!mime_list)
|
||||
return ret;
|
||||
chain_t it = dlookup(mime_list, type);
|
||||
if(it)
|
||||
if (it)
|
||||
{
|
||||
ret.type = it->key;
|
||||
ret.ext = it->value;
|
||||
}
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* Get correct HTTP mime type of a file
|
||||
@ -206,157 +208,176 @@ mime_t mime_from_type(const char* type)
|
||||
* @param file File name
|
||||
* @return The HTTP Mime Type
|
||||
*/
|
||||
char* mime(const char* file)
|
||||
char *mime(const char *file)
|
||||
{
|
||||
char * ex = ext(file);
|
||||
if(!ex) return "application/octet-stream";
|
||||
mime_t m = mime_from_ext(ex);
|
||||
if(ex)
|
||||
char *ex = ext(file);
|
||||
if (!ex)
|
||||
return "application/octet-stream";
|
||||
mime_t m = mime_from_ext(ex);
|
||||
if (ex)
|
||||
{
|
||||
free(ex);
|
||||
}
|
||||
return (char*)m.type;
|
||||
return (char *)m.type;
|
||||
}
|
||||
|
||||
int match_int(const char* search)
|
||||
int match_int(const char *search)
|
||||
{
|
||||
return regex_match("^[-+]?[0-9]+$",search,0, NULL);
|
||||
return regex_match("^[-+]?[0-9]+$", search, 0, NULL);
|
||||
}
|
||||
int match_float(const char* search)
|
||||
int match_float(const char *search)
|
||||
{
|
||||
return regex_match("^[+-]?[0-9]*\\.[0-9]+$",search,0,NULL);
|
||||
return regex_match("^[+-]?[0-9]*\\.[0-9]+$", search, 0, NULL);
|
||||
}
|
||||
/*
|
||||
regmatch_t matches[MAX_MATCHES];
|
||||
if (regexec(&exp, sz, MAX_MATCHES, matches, 0) == 0) {
|
||||
memcpy(buff, sz + matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so);
|
||||
printf("group1: %s\n", buff);
|
||||
regmatch_t matches[MAX_MATCHES];
|
||||
if (regexec(&exp, sz, MAX_MATCHES, matches, 0) == 0) {
|
||||
memcpy(buff, sz + matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so);
|
||||
printf("group1: %s\n", buff);
|
||||
}
|
||||
*/
|
||||
int regex_match(const char* expr,const char* search, int msize, regmatch_t* matches)
|
||||
int regex_match(const char *expr, const char *search, int msize, regmatch_t *matches)
|
||||
{
|
||||
regex_t regex;
|
||||
regex_t regex;
|
||||
int reti;
|
||||
char msgbuf[100];
|
||||
int ret;
|
||||
/* Compile regular expression */
|
||||
/* Compile regular expression */
|
||||
reti = regcomp(®ex, expr, REG_ICASE | REG_EXTENDED);
|
||||
if( reti ){
|
||||
//ERROR("Could not compile regex: %s",expr);
|
||||
if (reti)
|
||||
{
|
||||
// ERROR("Could not compile regex: %s",expr);
|
||||
regerror(reti, ®ex, msgbuf, sizeof(msgbuf));
|
||||
ERROR("Regex match failed: %s", msgbuf);
|
||||
//return 0;
|
||||
// return 0;
|
||||
}
|
||||
|
||||
/* Execute regular expression */
|
||||
/* Execute regular expression */
|
||||
reti = regexec(®ex, search, msize, matches, 0);
|
||||
if( !reti ){
|
||||
//LOG("Match");
|
||||
ret = 1;
|
||||
if (!reti)
|
||||
{
|
||||
// LOG("Match");
|
||||
ret = 1;
|
||||
}
|
||||
else if( reti == REG_NOMATCH ){
|
||||
//LOG("No match");
|
||||
ret = 0;
|
||||
else if (reti == REG_NOMATCH)
|
||||
{
|
||||
// LOG("No match");
|
||||
ret = 0;
|
||||
}
|
||||
else{
|
||||
else
|
||||
{
|
||||
regerror(reti, ®ex, msgbuf, sizeof(msgbuf));
|
||||
//ERROR("Regex match failed: %s\n", msgbuf);
|
||||
// ERROR("Regex match failed: %s\n", msgbuf);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
|
||||
regfree(®ex);
|
||||
return ret;
|
||||
regfree(®ex);
|
||||
return ret;
|
||||
}
|
||||
char *url_decode(const char *str) {
|
||||
if(!str)
|
||||
char *url_decode(const char *str)
|
||||
{
|
||||
if (!str)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
char *pstr = (char*)str, *buf = malloc(strlen(str) + 1), *pbuf = buf;
|
||||
char *pstr = (char *)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';
|
||||
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;
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *url_encode(const char *str) {
|
||||
char *pstr = (char*)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];
|
||||
}
|
||||
unsigned hash(const char* key, int hash_size)
|
||||
char *url_encode(const char *str)
|
||||
{
|
||||
unsigned hashval = simple_hash(key);
|
||||
return hashval % hash_size;
|
||||
char *pstr = (char *)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;
|
||||
}
|
||||
unsigned simple_hash(const char* key)
|
||||
|
||||
char from_hex(char ch)
|
||||
{
|
||||
unsigned hashval;
|
||||
return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
|
||||
}
|
||||
|
||||
char to_hex(char code)
|
||||
{
|
||||
static char hex[] = "0123456789abcdef";
|
||||
return hex[code & 15];
|
||||
}
|
||||
unsigned hash(const char *key, int hash_size)
|
||||
{
|
||||
unsigned hashval = simple_hash(key);
|
||||
return hashval % hash_size;
|
||||
}
|
||||
unsigned simple_hash(const char *key)
|
||||
{
|
||||
unsigned hashval;
|
||||
for (hashval = 0; *key != '\0'; key++)
|
||||
hashval = *key + 31 * hashval;
|
||||
return hashval;
|
||||
hashval = *key + 31 * hashval;
|
||||
return hashval;
|
||||
}
|
||||
int _exist(const char* f)
|
||||
int _exist(const char *f)
|
||||
{
|
||||
struct stat st;
|
||||
return !(stat(f, &st) == -1);
|
||||
struct stat st;
|
||||
return !(stat(f, &st) == -1);
|
||||
}
|
||||
int is_file(const char* f)
|
||||
int is_file(const char *f)
|
||||
{
|
||||
int st = is_dir(f);
|
||||
if(st == -1) return -1;
|
||||
else return st==0;
|
||||
int st = is_dir(f);
|
||||
if (st == -1)
|
||||
return -1;
|
||||
else
|
||||
return st == 0;
|
||||
}
|
||||
int is_dir(const char* f)
|
||||
int is_dir(const char *f)
|
||||
{
|
||||
struct stat st;
|
||||
if(stat(f, &st) == -1)
|
||||
return -1; // unknow
|
||||
else if(st.st_mode & S_IFDIR)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
struct stat st;
|
||||
if (stat(f, &st) == -1)
|
||||
return -1; // unknow
|
||||
else if (st.st_mode & S_IFDIR)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
// These vars will contain the hash
|
||||
|
||||
void md5(uint8_t *initial_msg, size_t initial_len, char* buff) {
|
||||
uint32_t h0, h1, h2, h3;
|
||||
char tmp[80];
|
||||
|
||||
void md5(uint8_t *initial_msg, size_t initial_len, char *buff)
|
||||
{
|
||||
uint32_t h0, h1, h2, h3;
|
||||
char tmp[80];
|
||||
uint8_t *msg = NULL;
|
||||
uint32_t r[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
|
||||
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
|
||||
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
|
||||
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
|
||||
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
|
||||
// Use binary integer part of the sines of integers (in radians) as constants// Initialize variables:
|
||||
@ -377,104 +398,111 @@ void md5(uint8_t *initial_msg, size_t initial_len, char* buff) {
|
||||
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
|
||||
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
|
||||
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391};
|
||||
|
||||
|
||||
h0 = 0x67452301;
|
||||
h1 = 0xefcdab89;
|
||||
h2 = 0x98badcfe;
|
||||
h3 = 0x10325476;
|
||||
|
||||
|
||||
// Pre-processing: adding a single 1 bit
|
||||
//append "1" bit to message
|
||||
// append "1" bit to message
|
||||
/* Notice: the input bytes are considered as bits strings,
|
||||
where the first bit is the most significant bit of the byte.[37] */
|
||||
|
||||
|
||||
// Pre-processing: padding with zeros
|
||||
//append "0" bit until message length in bit ≡ 448 (mod 512)
|
||||
//append length mod (2 pow 64) to message
|
||||
|
||||
// append "0" bit until message length in bit ≡ 448 (mod 512)
|
||||
// append length mod (2 pow 64) to message
|
||||
|
||||
int new_len;
|
||||
for(new_len = initial_len*8 + 1; new_len%512!=448; new_len++);
|
||||
for (new_len = initial_len * 8 + 1; new_len % 512 != 448; new_len++)
|
||||
;
|
||||
new_len /= 8;
|
||||
|
||||
msg = calloc(new_len + 64, 1); // also appends "0" bits
|
||||
|
||||
msg = calloc(new_len + 64, 1); // also appends "0" bits
|
||||
// (we alloc also 64 extra bytes...)
|
||||
memcpy(msg, initial_msg, initial_len);
|
||||
msg[initial_len] = 128; // write the "1" bit
|
||||
|
||||
uint32_t bits_len = 8*initial_len; // note, we append the len
|
||||
memcpy(msg + new_len, &bits_len, 4); // in bits at the end of the buffer
|
||||
|
||||
|
||||
uint32_t bits_len = 8 * initial_len; // note, we append the len
|
||||
memcpy(msg + new_len, &bits_len, 4); // in bits at the end of the buffer
|
||||
|
||||
// Process the message in successive 512-bit chunks:
|
||||
//for each 512-bit chunk of message:
|
||||
// for each 512-bit chunk of message:
|
||||
int offset;
|
||||
for(offset=0; offset<new_len; offset += (512/8)) {
|
||||
|
||||
for (offset = 0; offset < new_len; offset += (512 / 8))
|
||||
{
|
||||
|
||||
// break chunk into sixteen 32-bit words w[j], 0 ≤ j ≤ 15
|
||||
uint32_t *w = (uint32_t *) (msg + offset);
|
||||
|
||||
uint32_t *w = (uint32_t *)(msg + offset);
|
||||
|
||||
// Initialize hash value for this chunk:
|
||||
uint32_t a = h0;
|
||||
uint32_t b = h1;
|
||||
uint32_t c = h2;
|
||||
uint32_t d = h3;
|
||||
|
||||
|
||||
// Main loop:
|
||||
uint32_t i;
|
||||
for(i = 0; i<64; i++) {
|
||||
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
|
||||
uint32_t f, g;
|
||||
|
||||
if (i < 16) {
|
||||
|
||||
if (i < 16)
|
||||
{
|
||||
f = (b & c) | ((~b) & d);
|
||||
g = i;
|
||||
} else if (i < 32) {
|
||||
}
|
||||
else if (i < 32)
|
||||
{
|
||||
f = (d & b) | ((~d) & c);
|
||||
g = (5*i + 1) % 16;
|
||||
} else if (i < 48) {
|
||||
g = (5 * i + 1) % 16;
|
||||
}
|
||||
else if (i < 48)
|
||||
{
|
||||
f = b ^ c ^ d;
|
||||
g = (3*i + 5) % 16;
|
||||
} else {
|
||||
g = (3 * i + 5) % 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
f = c ^ (b | (~d));
|
||||
g = (7*i) % 16;
|
||||
g = (7 * i) % 16;
|
||||
}
|
||||
|
||||
uint32_t temp = d;
|
||||
d = c;
|
||||
c = b;
|
||||
//printf("rotateLeft(%x + %x + %x + %x, %d)\n", a, f, k[i], w[g], r[i]);
|
||||
// printf("rotateLeft(%x + %x + %x + %x, %d)\n", a, f, k[i], w[g], r[i]);
|
||||
b = b + LEFTROTATE((a + f + k[i] + w[g]), r[i]);
|
||||
a = temp;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Add this chunk's hash to result so far:
|
||||
|
||||
|
||||
h0 += a;
|
||||
h1 += b;
|
||||
h2 += c;
|
||||
h3 += d;
|
||||
|
||||
}
|
||||
uint8_t *p;
|
||||
p=(uint8_t *)&h0;
|
||||
sprintf(tmp,"%02x%02x%02x%02x", p[0], p[1], p[2], p[3]);//, h0
|
||||
strcpy(buff, tmp);
|
||||
p=(uint8_t *)&h1;
|
||||
sprintf(tmp,"%02x%02x%02x%02x", p[0], p[1], p[2], p[3]); //, h1)
|
||||
strcat(buff,tmp);
|
||||
p=(uint8_t *)&h2;
|
||||
sprintf(tmp,"%02x%02x%02x%02x", p[0], p[1], p[2], p[3]); // , h2
|
||||
strcat(buff,tmp);
|
||||
p=(uint8_t *)&h3;
|
||||
sprintf(tmp,"%02x%02x%02x%02x", p[0], p[1], p[2], p[3]); // , h3
|
||||
strcat(buff,tmp);
|
||||
uint8_t *p;
|
||||
p = (uint8_t *)&h0;
|
||||
sprintf(tmp, "%02x%02x%02x%02x", p[0], p[1], p[2], p[3]); //, h0
|
||||
strcpy(buff, tmp);
|
||||
p = (uint8_t *)&h1;
|
||||
sprintf(tmp, "%02x%02x%02x%02x", p[0], p[1], p[2], p[3]); //, h1)
|
||||
strcat(buff, tmp);
|
||||
p = (uint8_t *)&h2;
|
||||
sprintf(tmp, "%02x%02x%02x%02x", p[0], p[1], p[2], p[3]); // , h2
|
||||
strcat(buff, tmp);
|
||||
p = (uint8_t *)&h3;
|
||||
sprintf(tmp, "%02x%02x%02x%02x", p[0], p[1], p[2], p[3]); // , h3
|
||||
strcat(buff, tmp);
|
||||
// cleanup
|
||||
free(msg);
|
||||
|
||||
}
|
||||
void sha1(const char* text, char* out)
|
||||
{
|
||||
uint8_t d [20];
|
||||
void sha1(const char *text, char *out)
|
||||
{
|
||||
uint8_t d[20];
|
||||
#ifdef USE_OPENSSL
|
||||
SHA_CTX context;
|
||||
#else
|
||||
@ -483,32 +511,32 @@ void sha1(const char* text, char* out)
|
||||
SHA1_Init(&context);
|
||||
SHA1_Update(&context, text, strlen(text));
|
||||
SHA1_Final(d, &context);
|
||||
digest_to_hex(d,out);
|
||||
digest_to_hex(d, out);
|
||||
}
|
||||
|
||||
|
||||
char* __s(const char* fstring,...)
|
||||
char *__s(const char *fstring, ...)
|
||||
{
|
||||
char* data;
|
||||
va_list arguments;
|
||||
int dlen;
|
||||
va_start( arguments, fstring);
|
||||
dlen = vsnprintf(0,0,fstring,arguments) + 1;
|
||||
char *data;
|
||||
va_list arguments;
|
||||
int dlen;
|
||||
va_start(arguments, fstring);
|
||||
dlen = vsnprintf(0, 0, fstring, arguments) + 1;
|
||||
va_end(arguments);
|
||||
if ((data = (char*)malloc(dlen*sizeof(char))) != 0)
|
||||
if ((data = (char *)malloc(dlen * sizeof(char))) != 0)
|
||||
{
|
||||
va_start(arguments, fstring);
|
||||
vsnprintf(data, dlen, fstring, arguments);
|
||||
va_end(arguments);
|
||||
return data;
|
||||
} else
|
||||
return "";
|
||||
}
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
int mkdirp(const char* path, mode_t mode)
|
||||
int mkdirp(const char *path, mode_t mode)
|
||||
{
|
||||
char tmp[BUFFLEN];
|
||||
if(strlen(path) > BUFFLEN)
|
||||
if (strlen(path) > BUFFLEN)
|
||||
{
|
||||
ERROR("mkdirp: Path is too long %s", path);
|
||||
return -1;
|
||||
@ -516,16 +544,17 @@ int mkdirp(const char* path, mode_t mode)
|
||||
char *p = NULL;
|
||||
size_t len;
|
||||
int stat;
|
||||
snprintf(tmp, sizeof(tmp),"%s",path);
|
||||
snprintf(tmp, sizeof(tmp), "%s", path);
|
||||
len = strlen(tmp);
|
||||
if(tmp[len - 1] == '/')
|
||||
tmp[len - 1] = 0;
|
||||
for(p = tmp + 1; *p; p++)
|
||||
if (tmp[len - 1] == '/')
|
||||
tmp[len - 1] = 0;
|
||||
for (p = tmp + 1; *p; p++)
|
||||
{
|
||||
if(*p == '/') {
|
||||
if (*p == '/')
|
||||
{
|
||||
*p = 0;
|
||||
stat = mkdir(tmp, mode);
|
||||
if(stat == -1 && errno != EEXIST)
|
||||
if (stat == -1 && errno != EEXIST)
|
||||
return stat;
|
||||
*p = '/';
|
||||
}
|
||||
@ -533,22 +562,21 @@ int mkdirp(const char* path, mode_t mode)
|
||||
return mkdir(path, mode);
|
||||
}
|
||||
|
||||
|
||||
int guard_read(int fd, void* buffer, size_t size)
|
||||
int guard_read(int fd, void *buffer, size_t size)
|
||||
{
|
||||
int n = 0;
|
||||
int read_len;
|
||||
int st;
|
||||
while(n != (int)size)
|
||||
while (n != (int)size)
|
||||
{
|
||||
read_len = (int)size - n;
|
||||
st = read(fd,buffer + n,read_len);
|
||||
if(st == -1)
|
||||
st = read(fd, buffer + n, read_len);
|
||||
if (st == -1)
|
||||
{
|
||||
ERROR( "Unable to read from #%d: %s", fd, strerror(errno));
|
||||
ERROR("Unable to read from #%d: %s", fd, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if(st == 0)
|
||||
if (st == 0)
|
||||
{
|
||||
ERROR("Endpoint %d is closed", fd);
|
||||
return -1;
|
||||
@ -558,21 +586,21 @@ int guard_read(int fd, void* buffer, size_t size)
|
||||
return n;
|
||||
}
|
||||
|
||||
int guard_write(int fd, void* buffer, size_t size)
|
||||
int guard_write(int fd, void *buffer, size_t size)
|
||||
{
|
||||
int n = 0;
|
||||
int write_len;
|
||||
int st;
|
||||
while(n != (int)size)
|
||||
while (n != (int)size)
|
||||
{
|
||||
write_len = (int)size - n;
|
||||
st = write(fd,buffer + n,write_len);
|
||||
if(st == -1)
|
||||
st = write(fd, buffer + n, write_len);
|
||||
if (st == -1)
|
||||
{
|
||||
ERROR("Unable to write to #%d: %s", fd, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if(st == 0)
|
||||
if (st == 0)
|
||||
{
|
||||
ERROR("Endpoint %d is closed", fd);
|
||||
return -1;
|
||||
@ -585,63 +613,130 @@ int guard_write(int fd, void* buffer, size_t size)
|
||||
/*
|
||||
send a request
|
||||
*/
|
||||
int request_socket(const char *ip, int port)
|
||||
int antd_request_socket(const char *ip, int port)
|
||||
{
|
||||
int sockfd;
|
||||
struct sockaddr_in dest;
|
||||
if(!ip)
|
||||
int sockfd;
|
||||
struct sockaddr_in dest;
|
||||
if (!ip)
|
||||
{
|
||||
ERROR("Invalid IP address");
|
||||
return -1;
|
||||
}
|
||||
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||
{
|
||||
ERROR("Socket: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
/*struct linger lingerStruct;
|
||||
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||
{
|
||||
ERROR("Socket: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
/*struct linger lingerStruct;
|
||||
lingerStruct.l_onoff = 0; // turn lingering off for sockets
|
||||
setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &lingerStruct, sizeof(lingerStruct));*/
|
||||
|
||||
bzero(&dest, sizeof(dest));
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = htons(port);
|
||||
if (inet_aton(ip, &dest.sin_addr) == 0)
|
||||
{
|
||||
perror(ip);
|
||||
close(sockfd);
|
||||
return -1;
|
||||
}
|
||||
if (connect(sockfd, (struct sockaddr *)&dest, sizeof(dest)) != 0)
|
||||
{
|
||||
close(sockfd);
|
||||
ERROR("Connect:%s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return sockfd;
|
||||
bzero(&dest, sizeof(dest));
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = htons(port);
|
||||
if (inet_aton(ip, &dest.sin_addr) == 0)
|
||||
{
|
||||
ERROR("[%s] inet_aton: %s", ip, strerror(errno));
|
||||
close(sockfd);
|
||||
return -1;
|
||||
}
|
||||
if (connect(sockfd, (struct sockaddr *)&dest, sizeof(dest)) != 0)
|
||||
{
|
||||
close(sockfd);
|
||||
ERROR("Connect:%s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
char* ip_from_hostname(const char *hostname)
|
||||
char *ip_from_hostname(const char *hostname)
|
||||
{
|
||||
struct hostent *he;
|
||||
struct in_addr **addr_list;
|
||||
int i;
|
||||
if(!hostname)
|
||||
struct hostent *he;
|
||||
struct in_addr **addr_list;
|
||||
int i;
|
||||
if (!hostname)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if ((he = gethostbyname(hostname)) == NULL)
|
||||
{
|
||||
// get the host info
|
||||
ERROR("gethostbyname:%s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
addr_list = (struct in_addr **)he->h_addr_list;
|
||||
if ((he = gethostbyname(hostname)) == NULL)
|
||||
{
|
||||
// get the host info
|
||||
ERROR("gethostbyname:%s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
addr_list = (struct in_addr **)he->h_addr_list;
|
||||
|
||||
for (i = 0; addr_list[i] != NULL; i++)
|
||||
{
|
||||
//Return the first one;
|
||||
return inet_ntoa(*addr_list[i]);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; addr_list[i] != NULL; i++)
|
||||
{
|
||||
// Return the first one;
|
||||
return inet_ntoa(*addr_list[i]);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int antd_listen(unsigned *port, int ipv6, int backlog)
|
||||
{
|
||||
int httpd = 0;
|
||||
antd_sockaddr_t name;
|
||||
memset(&name, 0, sizeof(name));
|
||||
struct sockaddr *ptr;
|
||||
// TODO: allow to set listen address
|
||||
if (ipv6)
|
||||
{
|
||||
name.addr6.sin6_port = htons(*port);
|
||||
name.addr6.sin6_family = AF_INET6;
|
||||
name.addr6.sin6_addr = in6addr_any;
|
||||
httpd = socket(AF_INET6, SOCK_STREAM, 0);
|
||||
ptr = (struct sockaddr *)&name.addr6;
|
||||
}
|
||||
else
|
||||
{
|
||||
name.addr4.sin_port = htons(*port);
|
||||
name.addr4.sin_family = AF_INET;
|
||||
name.addr4.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
httpd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
ptr = (struct sockaddr *)&name.addr4;
|
||||
}
|
||||
|
||||
if (httpd == -1)
|
||||
{
|
||||
ERROR("Port %d - socket: %s", *port, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(httpd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)) == -1)
|
||||
{
|
||||
ERROR("Unable to set reuse address on port %d - setsockopt: %s", *port, strerror(errno));
|
||||
}
|
||||
|
||||
if (bind(httpd, ptr, sizeof(name)) < 0)
|
||||
{
|
||||
ERROR("Port %d -bind: %s", *port, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (*port == 0) /* if dynamically allocating a port */
|
||||
{
|
||||
socklen_t namelen = sizeof(name);
|
||||
if (getsockname(httpd, (struct sockaddr *)&name, &namelen) == -1)
|
||||
{
|
||||
ERROR("Port %d - getsockname: %s", *port, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (ipv6)
|
||||
{
|
||||
*port = ntohs(name.addr6.sin6_port);
|
||||
}
|
||||
else
|
||||
{
|
||||
*port = ntohs(name.addr4.sin_port);
|
||||
}
|
||||
}
|
||||
|
||||
if (listen(httpd, backlog) < 0)
|
||||
{
|
||||
ERROR("Port %d - listen: %s", *port, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
LOG("%s Listen on port %d", ipv6 ? "IPv6" : "IPv4", *port);
|
||||
return (httpd);
|
||||
}
|
||||
|
11
lib/utils.h
11
lib/utils.h
@ -30,6 +30,7 @@ THE SOFTWARE.
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "dictionary.h"
|
||||
|
||||
@ -58,6 +59,12 @@ typedef struct{
|
||||
const char* ext;
|
||||
} mime_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct sockaddr_in6 addr6;
|
||||
struct sockaddr_in addr4;
|
||||
} antd_sockaddr_t;
|
||||
|
||||
dictionary_t __attribute__((weak)) mimes_list();
|
||||
char* __s(const char*,...);
|
||||
void trim(char*,const char);
|
||||
@ -87,6 +94,8 @@ void digest_to_hex(const uint8_t *, char *);
|
||||
void verify_header(char* k);
|
||||
int guard_read(int fd, void* buffer, size_t size);
|
||||
int guard_write(int fd, void* buffer, size_t size);
|
||||
int request_socket(const char *ip, int port);
|
||||
char* ip_from_hostname(const char *hostname);
|
||||
|
||||
int antd_request_socket(const char *ip, int port);
|
||||
int antd_listen(unsigned *port, int ipv6, int backlog);
|
||||
#endif
|
||||
|
133
lib/ws.c
133
lib/ws.c
@ -15,6 +15,13 @@
|
||||
#include "handle.h"
|
||||
|
||||
#include "ws.h"
|
||||
#define CONN_TIME_OUT_S 3
|
||||
#define BITV(v, i) ((v & (1 << i)) >> i)
|
||||
#define MAX_BUFF 1024
|
||||
#define PREFERRED_WS_CIPHERS "HIGH:!aNULL:!kRSA:!SRP:!PSK:!CAMELLIA:!RC4:!MD5:!DSS"
|
||||
#define CLIENT_RQ "GET /%s HTTP/1.1\r\nHost: %s\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nSec-WebSocket-Version: 13\r\n\r\n"
|
||||
#define SERVER_WS_KEY "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="
|
||||
|
||||
static void ws_gen_mask_key(ws_msg_header_t *header)
|
||||
{
|
||||
int r = rand();
|
||||
@ -24,10 +31,10 @@ static void ws_gen_mask_key(ws_msg_header_t *header)
|
||||
header->mask_key[3] = r & 0xFF;
|
||||
}
|
||||
/**
|
||||
* Read a frame header
|
||||
* based on this header, we'll decide
|
||||
* the appropriate handle for frame data
|
||||
*/
|
||||
* Read a frame header
|
||||
* based on this header, we'll decide
|
||||
* the appropriate handle for frame data
|
||||
*/
|
||||
ws_msg_header_t *ws_read_header(void *client)
|
||||
{
|
||||
|
||||
@ -41,8 +48,8 @@ ws_msg_header_t *ws_read_header(void *client)
|
||||
if (BITV(byte, 6) || BITV(byte, 5) || BITV(byte, 4))
|
||||
goto fail; // all RSV bit must be 0
|
||||
|
||||
//printf("FIN: %d, RSV1: %d, RSV2: %d, RSV3:%d, opcode:%d\n", BITV(byte,7), BITV(byte,6), BITV(byte,5), BITV(byte,4),(byte & 0x0F) );
|
||||
// find and opcode
|
||||
// printf("FIN: %d, RSV1: %d, RSV2: %d, RSV3:%d, opcode:%d\n", BITV(byte,7), BITV(byte,6), BITV(byte,5), BITV(byte,4),(byte & 0x0F) );
|
||||
// find and opcode
|
||||
header->fin = BITV(byte, 7);
|
||||
header->opcode = (byte & 0x0F);
|
||||
|
||||
@ -50,8 +57,8 @@ ws_msg_header_t *ws_read_header(void *client)
|
||||
if (antd_recv(client, &byte, sizeof(byte)) <= 0)
|
||||
goto fail;
|
||||
|
||||
//printf("MASK: %d paylen:%d\n", BITV(byte,7), (byte & 0x7F));
|
||||
// check mask bit, should be 1
|
||||
// printf("MASK: %d paylen:%d\n", BITV(byte,7), (byte & 0x7F));
|
||||
// check mask bit, should be 1
|
||||
header->mask = BITV(byte, 7);
|
||||
/*if(!BITV(byte,7))
|
||||
{
|
||||
@ -73,28 +80,28 @@ ws_msg_header_t *ws_read_header(void *client)
|
||||
}
|
||||
else
|
||||
{
|
||||
//read only last 4 byte
|
||||
// read only last 4 byte
|
||||
if (antd_recv(client, bytes, 8 * sizeof(uint8_t)) <= 0)
|
||||
goto fail;
|
||||
header->plen = (bytes[4] << 24) + (bytes[5] << 16) + (bytes[6] << 8) + bytes[7];
|
||||
}
|
||||
//printf("len: %d\n", header->plen);
|
||||
// last step is to get the maskey
|
||||
// printf("len: %d\n", header->plen);
|
||||
// last step is to get the maskey
|
||||
if (header->mask)
|
||||
if (antd_recv(client, header->mask_key, 4 * sizeof(uint8_t)) <= 0)
|
||||
goto fail;
|
||||
//printf("key 0: %d key 1: %d key2:%d, key3: %d\n",header->mask_key[0],header->mask_key[1],header->mask_key[2], header->mask_key[3] );
|
||||
// printf("key 0: %d key 1: %d key2:%d, key3: %d\n",header->mask_key[0],header->mask_key[1],header->mask_key[2], header->mask_key[3] );
|
||||
|
||||
// check wheather it is a ping or a close message
|
||||
// process it and return NULL
|
||||
//otherwise return the header
|
||||
//return the header
|
||||
// otherwise return the header
|
||||
// return the header
|
||||
switch (header->opcode)
|
||||
{
|
||||
case WS_CLOSE: // client requests to close the connection
|
||||
// send back a close message
|
||||
UNUSED(ws_send_close(client, 1000, header->mask ? 0 : 1));
|
||||
//goto fail;
|
||||
// goto fail;
|
||||
break;
|
||||
|
||||
case WS_PING: // client send a ping
|
||||
@ -112,9 +119,9 @@ fail:
|
||||
return NULL;
|
||||
}
|
||||
/**
|
||||
* Read data from client
|
||||
* and unmask data using the key
|
||||
*/
|
||||
* Read data from client
|
||||
* and unmask data using the key
|
||||
*/
|
||||
int ws_read_data(void *client, ws_msg_header_t *header, int len, uint8_t *data)
|
||||
{
|
||||
// if len == -1 ==> read all remaining data to 'data';
|
||||
@ -137,14 +144,14 @@ int _send_header(void *client, ws_msg_header_t header)
|
||||
uint8_t bytes[8];
|
||||
for (int i = 0; i < 8; i++)
|
||||
bytes[i] = 0;
|
||||
//first byte |FIN|000|opcode|
|
||||
// first byte |FIN|000|opcode|
|
||||
byte = (header.fin << 7) + header.opcode;
|
||||
//printf("BYTE: %d\n", byte);
|
||||
// printf("BYTE: %d\n", byte);
|
||||
if (antd_send(client, &byte, 1) != 1)
|
||||
return -1;
|
||||
// second byte, payload length
|
||||
// mask may be 0 or 1
|
||||
//if(header.mask == 1)
|
||||
// if(header.mask == 1)
|
||||
// printf("Data is masked\n");
|
||||
if (header.plen <= 125)
|
||||
{
|
||||
@ -183,8 +190,8 @@ int _send_header(void *client, ws_msg_header_t header)
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* Send a frame to client
|
||||
*/
|
||||
* Send a frame to client
|
||||
*/
|
||||
int ws_send_frame(void *client, uint8_t *data, ws_msg_header_t header)
|
||||
{
|
||||
uint8_t *masked;
|
||||
@ -212,8 +219,8 @@ int ws_send_frame(void *client, uint8_t *data, ws_msg_header_t header)
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* send a text data frame to client
|
||||
*/
|
||||
* send a text data frame to client
|
||||
*/
|
||||
int ws_send_text(void *client, const char *data, int mask)
|
||||
{
|
||||
ws_msg_header_t header;
|
||||
@ -222,13 +229,13 @@ int ws_send_text(void *client, const char *data, int mask)
|
||||
header.mask = mask;
|
||||
header.plen = strlen(data);
|
||||
//_send_header(client,header);
|
||||
//send(client, data, header.plen,0);
|
||||
// send(client, data, header.plen,0);
|
||||
return ws_send_frame(client, (uint8_t *)data, header);
|
||||
}
|
||||
/**
|
||||
* send a single binary data fram to client
|
||||
* not tested yet, but should work
|
||||
*/
|
||||
* send a single binary data fram to client
|
||||
* not tested yet, but should work
|
||||
*/
|
||||
int ws_send_binary(void *client, uint8_t *data, int l, int mask)
|
||||
{
|
||||
ws_msg_header_t header;
|
||||
@ -238,11 +245,11 @@ int ws_send_binary(void *client, uint8_t *data, int l, int mask)
|
||||
header.mask = mask;
|
||||
return ws_send_frame(client, data, header);
|
||||
//_send_header(client,header);
|
||||
//send(client, data, header.plen,0);
|
||||
// send(client, data, header.plen,0);
|
||||
}
|
||||
/*
|
||||
* send a file as binary data
|
||||
*/
|
||||
* send a file as binary data
|
||||
*/
|
||||
int ws_send_file(void *client, const char *file, int mask)
|
||||
{
|
||||
uint8_t buff[1024];
|
||||
@ -257,7 +264,7 @@ int ws_send_file(void *client, const char *file, int mask)
|
||||
size_t size;
|
||||
int first_frame = 1;
|
||||
int ret = 0;
|
||||
//ws_send_frame(client,buff,header);
|
||||
// ws_send_frame(client,buff,header);
|
||||
header.mask = mask;
|
||||
while (!feof(ptr))
|
||||
{
|
||||
@ -275,7 +282,7 @@ int ws_send_file(void *client, const char *file, int mask)
|
||||
else
|
||||
header.opcode = 0;
|
||||
header.plen = size;
|
||||
//printf("FIN: %d OC:%d\n", header.fin, header.opcode);
|
||||
// printf("FIN: %d OC:%d\n", header.fin, header.opcode);
|
||||
ret += ws_send_frame(client, buff, header);
|
||||
}
|
||||
fclose(ptr);
|
||||
@ -286,9 +293,9 @@ int ws_send_file(void *client, const char *file, int mask)
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* Not tested yet
|
||||
* but should work
|
||||
*/
|
||||
* Not tested yet
|
||||
* but should work
|
||||
*/
|
||||
int ws_pong(void *client, ws_msg_header_t *oheader, int mask)
|
||||
{
|
||||
ws_msg_header_t pheader;
|
||||
@ -310,7 +317,7 @@ int ws_pong(void *client, ws_msg_header_t *oheader, int mask)
|
||||
ret = ws_send_frame(client, data, pheader);
|
||||
free(data);
|
||||
//_send_header(client, pheader);
|
||||
//send(client, data, len, 0);
|
||||
// send(client, data, len, 0);
|
||||
return ret;
|
||||
}
|
||||
int ws_ping(void *client, const char *echo, int mask)
|
||||
@ -323,11 +330,11 @@ int ws_ping(void *client, const char *echo, int mask)
|
||||
return ws_send_frame(client, (uint8_t *)echo, pheader);
|
||||
}
|
||||
/*
|
||||
* Not tested yet, but should work
|
||||
*/
|
||||
* Not tested yet, but should work
|
||||
*/
|
||||
int ws_send_close(void *client, unsigned int status, int mask)
|
||||
{
|
||||
//printf("CLOSED\n");
|
||||
// printf("CLOSED\n");
|
||||
ws_msg_header_t header;
|
||||
header.fin = 1;
|
||||
header.opcode = WS_CLOSE;
|
||||
@ -345,7 +352,7 @@ int ws_send_close(void *client, unsigned int status, int mask)
|
||||
}*/
|
||||
return ws_send_frame(client, bytes, header);
|
||||
//_send_header(client, header);
|
||||
//send(client,bytes,2,0);
|
||||
// send(client,bytes,2,0);
|
||||
}
|
||||
|
||||
void ws_client_close(ws_client_t *wsclient)
|
||||
@ -368,13 +375,13 @@ void ws_client_close(ws_client_t *wsclient)
|
||||
#endif
|
||||
}
|
||||
|
||||
//this is for the client side, not use for now
|
||||
int ws_client_connect(ws_client_t *wsclient, port_config_t pcnf)
|
||||
// this is for the client side, not use for now
|
||||
int ws_client_connect(ws_client_t *wsclient, ws_port_config_t pcnf)
|
||||
{
|
||||
char* ip = ip_from_hostname(wsclient->host);
|
||||
char *ip = ip_from_hostname(wsclient->host);
|
||||
if (ip == NULL)
|
||||
return -1;
|
||||
int sock = request_socket(ip, pcnf.port);
|
||||
int sock = antd_request_socket(ip, pcnf.port);
|
||||
if (sock <= 0)
|
||||
{
|
||||
ERROR("Cannot request socket");
|
||||
@ -383,13 +390,13 @@ int ws_client_connect(ws_client_t *wsclient, port_config_t pcnf)
|
||||
// time out setting
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = CONN_TIME_OUT_S;
|
||||
timeout.tv_usec = 0; //3 s
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0)
|
||||
timeout.tv_usec = 0; // 3 s
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0)
|
||||
ERROR("setsockopt failed:%s", strerror(errno));
|
||||
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0)
|
||||
ERROR("setsockopt failed:%s", strerror(errno));
|
||||
|
||||
|
||||
// will be free
|
||||
wsclient->antdsock->sock = sock;
|
||||
wsclient->antdsock->z_status = 0;
|
||||
@ -427,7 +434,7 @@ int ws_client_connect(ws_client_t *wsclient, port_config_t pcnf)
|
||||
SSL_CTX_set_options(wsclient->ssl_ctx, SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_SSLv2 | SSL_OP_NO_TICKET);
|
||||
// set the cipher suit
|
||||
const char *suit = wsclient->ciphersuit ? wsclient->ciphersuit : PREFERRED_WS_CIPHERS;
|
||||
//const char* suit = "AES128-SHA";
|
||||
// const char* suit = "AES128-SHA";
|
||||
if (SSL_CTX_set_cipher_list(wsclient->ssl_ctx, suit) != 1)
|
||||
{
|
||||
ssl_err = ERR_get_error();
|
||||
@ -514,7 +521,7 @@ int ws_open_handshake(ws_client_t *client)
|
||||
char buf[MAX_BUFF];
|
||||
// now send ws request handshake
|
||||
sprintf(buf, CLIENT_RQ, client->resource, client->host);
|
||||
//printf("Send %s\n", buf);
|
||||
// printf("Send %s\n", buf);
|
||||
int size = antd_send(client->antdsock, buf, strlen(buf));
|
||||
if (size != (int)strlen(buf))
|
||||
{
|
||||
@ -538,7 +545,7 @@ int ws_open_handshake(ws_client_t *client)
|
||||
trim(token, '\r');
|
||||
if (strcasecmp(token, SERVER_WS_KEY) == 0)
|
||||
{
|
||||
//LOG("Handshake sucessfull\n");
|
||||
// LOG("Handshake sucessfull\n");
|
||||
done = 1;
|
||||
}
|
||||
else
|
||||
@ -547,30 +554,10 @@ int ws_open_handshake(ws_client_t *client)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
//if(line) free(line);
|
||||
// if(line) free(line);
|
||||
size = read_buf(client->antdsock, buf, MAX_BUFF);
|
||||
}
|
||||
if (done)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
char *get_ip_address()
|
||||
{
|
||||
struct ifaddrs *addrs;
|
||||
getifaddrs(&addrs);
|
||||
struct ifaddrs *tmp = addrs;
|
||||
char *ip;
|
||||
while (tmp)
|
||||
{
|
||||
if (tmp->ifa_addr && tmp->ifa_addr->sa_family == AF_INET)
|
||||
{
|
||||
struct sockaddr_in *pAddr = (struct sockaddr_in *)tmp->ifa_addr;
|
||||
ip = inet_ntoa(pAddr->sin_addr);
|
||||
if (strcmp(ip, "127.0.0.1") != 0)
|
||||
return ip;
|
||||
}
|
||||
tmp = tmp->ifa_next;
|
||||
}
|
||||
freeifaddrs(addrs);
|
||||
return "127.0.0.1";
|
||||
}
|
19
lib/ws.h
19
lib/ws.h
@ -3,10 +3,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "handle.h"
|
||||
|
||||
#define CONN_TIME_OUT_S 3
|
||||
#define BITV(v, i) ((v & (1 << i)) >> i)
|
||||
#define WS_TEXT 0x1
|
||||
#define WS_BIN 0x2
|
||||
#define WS_CLOSE 0x8
|
||||
@ -16,11 +12,14 @@
|
||||
#define ws_b(c, d, z) (ws_send_binary(c, d, z, 0))
|
||||
#define ws_f(c, f) (ws_send_file(c, f, 0))
|
||||
#define ws_close(c, r) (ws_send_close(c, r, 0))
|
||||
#define MAX_BUFF 1024
|
||||
|
||||
#define PREFERRED_WS_CIPHERS "HIGH:!aNULL:!kRSA:!SRP:!PSK:!CAMELLIA:!RC4:!MD5:!DSS"
|
||||
#define CLIENT_RQ "GET /%s HTTP/1.1\r\nHost: %s\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nSec-WebSocket-Version: 13\r\n\r\n"
|
||||
#define SERVER_WS_KEY "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="
|
||||
typedef struct
|
||||
{
|
||||
unsigned int port;
|
||||
int usessl;
|
||||
int sock;
|
||||
antd_proto_t type;
|
||||
} ws_port_config_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -57,12 +56,10 @@ int ws_send_file(void *client, const char *file, int mask);
|
||||
int ws_send_binary(void *client, uint8_t *data, int l, int mask);
|
||||
|
||||
int ws_read_data(void *, ws_msg_header_t *, int, uint8_t *);
|
||||
//int ws_open_hand_shake(const char* host, int port, const char* resource);
|
||||
char *get_ip_address();
|
||||
|
||||
// client
|
||||
|
||||
void ws_client_close(ws_client_t *wsclient);
|
||||
int ws_client_connect(ws_client_t *wsclient, port_config_t pcnf);
|
||||
int ws_client_connect(ws_client_t *wsclient, ws_port_config_t pcnf);
|
||||
int ws_open_handshake(ws_client_t *client);
|
||||
#endif
|
Reference in New Issue
Block a user