1
0
mirror of https://github.com/lxsang/ant-http synced 2024-07-05 22:19:47 +02:00

support of rule, useful for sub domain remapping

This commit is contained in:
Xuan Sang LE 2018-02-04 19:46:47 +01:00
parent 01c32d964e
commit ff3c68ff64
5 changed files with 123 additions and 51 deletions

View File

@ -16,7 +16,7 @@ void accept_request(int client)
size_t i, j; size_t i, j;
struct stat st; struct stat st;
char *query_string = NULL; //char *query_string = NULL;
numchars = get_line(client, buf, sizeof(buf)); numchars = get_line(client, buf, sizeof(buf));
i = 0; j = 0; i = 0; j = 0;
@ -28,7 +28,7 @@ void accept_request(int client)
method[i] = '\0'; method[i] = '\0';
if (strcasecmp(method, "GET") && strcasecmp(method, "POST")) if (strcasecmp(method, "GET") && strcasecmp(method, "POST"))
{ {
printf("METHOD NOT FOUND %s\n", method); LOG("METHOD NOT FOUND %s\n", method);
// unimplemented // unimplemented
//while(get_line(client, buf, sizeof(buf)) > 0) printf("%s\n",buf ); //while(get_line(client, buf, sizeof(buf)) > 0) printf("%s\n",buf );
unimplemented(client); unimplemented(client);
@ -47,41 +47,20 @@ void accept_request(int client)
} }
url[i] = '\0'; url[i] = '\0';
if (strcasecmp(method, "GET") == 0)
{
query_string = url;
while ((*query_string != '?') && (*query_string != '\0'))
query_string++;
if (*query_string == '?')
{
*query_string = '\0';
query_string++;
}
}
// get the HOST header
line = read_line(client);
trim(line, '\n');
trim(line, '\r');
token = strsep(&line,":");
trim(token,' ');
trim(line,' ');
if(strcasecmp(token, "HOST"))
{
badrequest(client);
close(client);
return;
}
// perform rule check in domain
char* oldurl = strdup(url);
char* tmp = strchr(oldurl,'?');
if(tmp)
*tmp = '\0';
dictionary rq = decode_request(client, method, url);
sprintf(path, server_config.htdocs); sprintf(path, server_config.htdocs);
strcat(path, url); strcat(path, url);
//if (path[strlen(path) - 1] == '/') //if (path[strlen(path) - 1] == '/')
// strcat(path, "index.html"); // strcat(path, "index.html");
if (stat(path, &st) == -1) { if (stat(path, &st) == -1) {
if(execute_plugin(client,url,method,query_string) < 0) if(execute_plugin(client,oldurl,method,rq) < 0)
not_found(client); not_found(client);
} }
else else
@ -89,7 +68,7 @@ void accept_request(int client)
if (S_ISDIR(st.st_mode)) if (S_ISDIR(st.st_mode))
strcat(path, "/index.html"); strcat(path, "/index.html");
// check if the mime is supported // check if the mime is supported
// if the minme is not supported // if the mime is not supported
// find an handler plugin to process it // find an handler plugin to process it
// if the plugin is not found, forbidden access to the file should be sent // if the plugin is not found, forbidden access to the file should be sent
char* mime_type = mime(path); char* mime_type = mime(path);
@ -97,7 +76,7 @@ void accept_request(int client)
{ {
sprintf(buf,"/%s-api%s",ext(path),url); sprintf(buf,"/%s-api%s",ext(path),url);
LOG("WARNING::::Access octetstream via handler %s\n", buf); LOG("WARNING::::Access octetstream via handler %s\n", buf);
if(execute_plugin(client,buf,method,query_string) < 0) if(execute_plugin(client,buf,method,rq) < 0)
cannot_execute(client); cannot_execute(client);
} }
else else
@ -105,13 +84,68 @@ void accept_request(int client)
ctype(client,mime_type); ctype(client,mime_type);
// if the mime is supported, send the file // if the mime is supported, send the file
serve_file(client, path); serve_file(client, path);
//response(client,"this is the file");
} }
} }
free(oldurl);
free(rq);
close(client); close(client);
} }
void rule_check(association it, const char* host, const char* _url, const char* _query, char* buf)
{
// first perfom rule check on host, if not success, perform on url
regmatch_t key_matches[10];
regmatch_t val_matches[2];
char* query = strdup(_query);
char* url = strdup(_url);
int ret;
char* target;
char* tmp, rep[10];
int idx = 0;
memset(rep,0,10);
// 1 group
if( !(ret = regex_match(it->key,host, 10, key_matches)) )
{
target = url;
ret = regex_match(it->key,url, 10, key_matches);
}
else
target = host;
if(!ret) return;
tmp = (char*) it->value;
while((ret = regex_match( "{([a-zA-Z0-9]+)}",tmp, 2, val_matches)))
{
memcpy(buf + idx, tmp, val_matches[1].rm_so - 1);
idx += val_matches[1].rm_so - 1;
memcpy(rep, tmp + val_matches[1].rm_so, val_matches[1].rm_eo - val_matches[1].rm_so);
if(strcasecmp(rep,"url") == 0)
{
memcpy(buf+idx, url, strlen(url));
idx += strlen(url);
} else if(strcasecmp(rep,"query") == 0)
{
memcpy(buf+idx, query, strlen(query));
idx += strlen(query);
} else if(match_int(rep))
{
int i = atoi(rep);
memcpy(buf+idx, target + key_matches[i].rm_so, key_matches[i].rm_eo - key_matches[i].rm_so);
idx += key_matches[i].rm_eo - key_matches[i].rm_so;
} else { // just keep it
memcpy(buf+idx, tmp + val_matches[1].rm_so-1, val_matches[1].rm_eo + 2 - val_matches[1].rm_so);
idx+= val_matches[1].rm_eo + 2 - val_matches[1].rm_so;
}
tmp += val_matches[1].rm_eo + 1;
//break;
}
// now modify the match 2 group
if(idx > 0) buf[idx] = '\0';
free(url);
free(query);
}
/**********************************************************************/ /**********************************************************************/
/* Put the entire contents of a file out on a socket. This function /* Put the entire contents of a file out on a socket. This function
* is named after the UNIX "cat" command, because it might have been * is named after the UNIX "cat" command, because it might have been
@ -242,11 +276,11 @@ void serve_file(int client, const char *filename)
{ {
FILE *resource = NULL; FILE *resource = NULL;
int numchars = 1; int numchars = 1;
char buf[1024]; //char buf[1024];
buf[0] = 'A'; buf[1] = '\0'; //buf[0] = 'A'; buf[1] = '\0';
while ((numchars > 0) && strcmp("\n", buf)) /* read & discard headers */ //while ((numchars > 0) && strcmp("\n", buf)) /* read & discard headers */
numchars = get_line(client, buf, sizeof(buf)); // numchars = get_line(client, buf, sizeof(buf));
resource = fopen(filename, "rb"); resource = fopen(filename, "rb");
if (resource == NULL) if (resource == NULL)
@ -339,6 +373,34 @@ char* post_url_decode(int client,int len)
LOG("POST Query %s\n", query); LOG("POST Query %s\n", query);
return query; return query;
} }
char* apply_rules(const char* host, char*url)
{
association it;
// rule check
char* query_string = url;
while ((*query_string != '?') && (*query_string != '\0'))
query_string++;
if (*query_string == '?')
{
*query_string = '\0';
query_string++;
}
//char* oldurl = strdup(url);
for_each_assoc(it, server_config.rules)
{
// 1 group
rule_check(it,host, url, query_string, url);
query_string = url;
while ((*query_string != '?') && (*query_string != '\0'))
query_string++;
if (*query_string == '?')
{
*query_string = '\0';
query_string++;
}
}
return strdup(query_string);
}
/** /**
* Decode the HTTP request * Decode the HTTP request
* Get the cookie values * Get the cookie values
@ -352,13 +414,14 @@ char* post_url_decode(int client,int len)
* @param query query string in case of GET * @param query query string in case of GET
* @return a dictionary of key- value * @return a dictionary of key- value
*/ */
dictionary decode_request(int client,const char* method,const char* query) dictionary decode_request(int client,const char* method, char* url)
{ {
dictionary request = NULL; dictionary request = NULL;
dictionary cookie = NULL; dictionary cookie = NULL;
dictionary xheader = dict(); dictionary xheader = dict();
char* line; char* line;
char * token; char * token;
char* query = NULL;
if(strcmp(method,"GET") == 0) if(strcmp(method,"GET") == 0)
{ {
// this for check if web socket is enabled // this for check if web socket is enabled
@ -382,7 +445,11 @@ dictionary decode_request(int client,const char* method,const char* query)
trim(line, ' '); trim(line, ' ');
if(line != NULL && strcasecmp(line,"websocket") == 0) if(line != NULL && strcasecmp(line,"websocket") == 0)
ws = 1; ws = 1;
} else if(token != NULL && strcasecmp(token,"Sec-WebSocket-Key") == 0) }else if(token != NULL && strcasecmp(token,"Host") == 0)
{
query = apply_rules(line, url);
}
else if(token != NULL && strcasecmp(token,"Sec-WebSocket-Key") == 0)
{ {
// get the key from the client // get the key from the client
trim(line, ' '); trim(line, ' ');
@ -390,6 +457,7 @@ dictionary decode_request(int client,const char* method,const char* query)
} }
} }
request = decode_url_request(query); request = decode_url_request(query);
if(query) free(query);
if(ws && ws_key != NULL) if(ws && ws_key != NULL)
{ {
ws_confirm_request(client, ws_key); ws_confirm_request(client, ws_key);
@ -424,6 +492,9 @@ dictionary decode_request(int client,const char* method,const char* query)
token = strsep(&line,":"); token = strsep(&line,":");
trim(token,' '); trim(token,' ');
clen = atoi(token); clen = atoi(token);
}else if(token != NULL && strcasecmp(token,"Host") == 0)
{
apply_rules(line, url);
} }
else if(token != NULL &&strcasecmp(token,"Cookie") == 0) else if(token != NULL &&strcasecmp(token,"Cookie") == 0)
{ {
@ -735,7 +806,7 @@ char* json_data_decode(int client,int len)
* @return -1 if failure * @return -1 if failure
* 1 if sucess * 1 if sucess
*/ */
int execute_plugin(int client, const char *path, const char *method, const char *query_string) int execute_plugin(int client, const char *path, const char *method, dictionary dic)
{ {
char pname[255]; char pname[255];
char pfunc[255]; char pfunc[255];
@ -768,7 +839,7 @@ int execute_plugin(int client, const char *path, const char *method, const char
LOG("Method:%s\n", method); LOG("Method:%s\n", method);
LOG("Plugin name '%s'\n",pname); LOG("Plugin name '%s'\n",pname);
LOG("Query path. '%s'\n", pfunc); LOG("Query path. '%s'\n", pfunc);
LOG("query :%s\n", query_string); //LOG("query :%s\n", query_string);
//load the plugin //load the plugin
if((plugin = plugin_lookup(pname)) == NULL) if((plugin = plugin_lookup(pname)) == NULL)
@ -781,9 +852,9 @@ int execute_plugin(int client, const char *path, const char *method, const char
LOG("Problem when finding %s method from %s : %s \n", PLUGIN_HANDLER, pname,error); LOG("Problem when finding %s method from %s : %s \n", PLUGIN_HANDLER, pname,error);
return -1; return -1;
} }
dictionary dic = decode_request(client,method,query_string); //dictionary dic = decode_request(client,method,query_string);
(*fn)(client,method,pfunc,dic); (*fn)(client,method,pfunc,dic);
free(dic); //free(dic);
free(rpath); free(rpath);
return 1; return 1;
} }

View File

@ -31,15 +31,16 @@ void serve_file(int, const char *);
int startup(unsigned *); int startup(unsigned *);
void unimplemented(int); void unimplemented(int);
void badrequest(int); void badrequest(int);
void rule_check(association, const char* , const char* , const char* , char*);
void ws_confirm_request(int, const char*); void ws_confirm_request(int, const char*);
char* post_url_decode(int client,int len); char* post_url_decode(int client,int len);
dictionary decode_url_request(const char* query); dictionary decode_url_request(const char* query);
dictionary decode_request(int client,const char* method,const char* query); dictionary decode_request(int client,const char* method, char* url);
dictionary decode_multi_part_request(int,const char*); dictionary decode_multi_part_request(int,const char*);
dictionary decode_cookie(const char*); dictionary decode_cookie(const char*);
char* json_data_decode(int,int); char* json_data_decode(int,int);
int execute_plugin(int client, const char *path, int execute_plugin(int client, const char *path,
const char *method, const char *query_string); const char *method, dictionary rq);
#endif #endif

View File

@ -3,7 +3,7 @@
void set_status(int client,int code,const char* msg) void set_status(int client,int code,const char* msg)
{ {
response(client, __s("HTTP/1.0 %d %s", code, msg)); response(client, __s("HTTP/1.1 %d %s", code, msg));
response(client, __s("Server: %s ", SERVER_NAME)); response(client, __s("Server: %s ", SERVER_NAME));
} }
void redirect(int client,const char*path) void redirect(int client,const char*path)

View File

@ -193,11 +193,11 @@ int is_bin(const char* file)
int match_int(const char* search) int match_int(const char* search)
{ {
return regex_match("^[-+]?[0-9]+$",search); 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); return regex_match("^[+-]?[0-9]*\\.[0-9]+$",search,0,NULL);
} }
/* /*
regmatch_t matches[MAX_MATCHES]; regmatch_t matches[MAX_MATCHES];
@ -206,7 +206,7 @@ if (regexec(&exp, sz, MAX_MATCHES, matches, 0) == 0) {
printf("group1: %s\n", buff); printf("group1: %s\n", buff);
} }
*/ */
int regex_match(const char* expr,const char* search) int regex_match(const char* expr,const char* search, int msize, regmatch_t* matches)
{ {
regex_t regex; regex_t regex;
int reti; int reti;
@ -220,7 +220,7 @@ int regex_match(const char* expr,const char* search)
} }
/* Execute regular expression */ /* Execute regular expression */
reti = regexec(&regex, search, 0, NULL, 0); reti = regexec(&regex, search, msize, matches, 0);
if( !reti ){ if( !reti ){
//LOG("Match"); //LOG("Match");
ret = 1; ret = 1;

View File

@ -84,7 +84,7 @@ char* mime(const char*);
int is_bin(const char*); int is_bin(const char*);
int match_int(const char*); int match_int(const char*);
int match_float(const char*); int match_float(const char*);
int regex_match(const char*,const char*); int regex_match(const char*,const char*, int, regmatch_t*);
char *url_decode(const char *str); char *url_decode(const char *str);
char *url_encode(const char *str); char *url_encode(const char *str);
char from_hex(char ch); char from_hex(char ch);