Newer
Older
case AUTHENTICATION_TLS_PSK:
add_env(session,"AUTH_TYPE","TLS-PSK");
break;
case AUTHENTICATION_BASIC:
add_env(session,"AUTH_TYPE","Basic");
break;
case AUTHENTICATION_DIGEST:
add_env(session,"AUTH_TYPE","Digest");
break;
/* Should use real name if set to do so somewhere ToDo */
add_env(session,"REMOTE_USER",session->user.alias);
if(thisuser.pass[0])
loginSuccess(startup->login_attempt_list, &session->addr);
return(TRUE);
/* Should go to the hack log? */
lprintf(LOG_WARNING,"%04d !AUTHORIZATION FAILURE for user %s, ARS: %s"
,session->socket,session->req.auth.username,session->req.ars);
if(startup->hack_sound[0] && !(startup->options&BBS_OPT_MUTE))
PlaySound(startup->hack_sound, NULL, SND_ASYNC|SND_FILENAME);
#endif
return(FALSE);
}
static named_string_t** read_ini_list(char* path, char* section, char* desc
,named_string_t** list)
size_t i;
list=iniFreeNamedStringList(list);
if((fp=iniOpenFile(path, /* create? */FALSE))!=NULL) {
list=iniReadNamedStringList(fp,section);
iniCloseFile(fp);
COUNT_LIST_ITEMS(list,i);
if(i)
lprintf(LOG_DEBUG,"Read %lu %s from %s section of %s"
,(ulong)i,desc,section==NULL ? "root":section,path);
} else
lprintf(LOG_WARNING, "Error %d opening %s", errno, path);
return(list);
static int sess_recv(http_session_t *session, char *buf, size_t length, int flags)
{
int len=0;
if (session->is_tls) {
if (flags == MSG_PEEK) {
if (session->peeked_valid) {
buf[0] = session->peeked;
return 1;
}
if (HANDLE_CRYPT_CALL_EXCEPT2(cryptPopData(session->tls_sess, &session->peeked, 1, &len), session, "popping data", CRYPT_ERROR_TIMEOUT, CRYPT_ERROR_COMPLETE)) {
if (len == 1) {
session->peeked_valid = TRUE;
buf[0] = session->peeked;
return 1;
}
return 0;
}
return -1;
}
else {
if (session->peeked_valid) {
buf[0] = session->peeked;
session->peeked_valid = FALSE;
return 1;
}
if (HANDLE_CRYPT_CALL_EXCEPT2(cryptPopData(session->tls_sess, buf, length, &len), session, "popping data", CRYPT_ERROR_TIMEOUT, CRYPT_ERROR_COMPLETE)) {
len = -1;
}
return len;
}
return -1;
}
}
else {
return recv(session->socket, buf, length, flags);
}
}
static int sockreadline(http_session_t * session, char *buf, size_t length)
fd_set rd_set;
struct timeval tv;
if(session->socket==INVALID_SOCKET)
return(-1);
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
if ((!session->is_tls) || (!session->tls_pending)) {
FD_ZERO(&rd_set);
FD_SET(session->socket,&rd_set);
/* Convert timeout from ms to sec/usec */
tv.tv_sec=startup->max_inactivity;
tv.tv_usec=0;
sel=select(session->socket+1,&rd_set,NULL,NULL,&tv);
switch(sel) {
case 1:
if (session->is_tls)
session->tls_pending=TRUE;
break;
case -1:
close_session_socket(session);
lprintf(LOG_DEBUG,"%04d !ERROR %d selecting socket for read",session->socket,ERROR_VALUE);
return(-1);
default:
/* Timeout */
lprintf(LOG_NOTICE,"%04d Session timeout due to inactivity (%d seconds)",session->socket,startup->max_inactivity);
return(-1);
}
case -1:
if(startup->options&WEB_OPT_DEBUG_RX)
lprintf(LOG_DEBUG,"%04d !ERROR %d receiving on socket",session->socket,ERROR_VALUE);
return(-1);
}
break;
case 0:
return(-1);
}
if(ch=='\n')
break;
if(i<length)
buf[i++]=ch;
else
chucked++;
/* Terminate at length if longer */
if(i>length)
i=length;
while(i>0 && buf[i-1]=='\r')
i--;
buf[i]=0;
if(startup->options&WEB_OPT_DEBUG_RX) {
lprintf(LOG_DEBUG,"%04d RX: %s",session->socket,buf);
lprintf(LOG_DEBUG,"%04d Long header, chucked %d bytes",session->socket,chucked);
}
#if defined(_WIN32)
static int pipereadline(HANDLE pipe, char *buf, size_t length, char *fullbuf, size_t fullbuf_len)
#else
static int pipereadline(int pipe, char *buf, size_t length, char *fullbuf, size_t fullbuf_len)
#endif
{
char ch;
DWORD i;
#ifndef _WIN32
struct timeval tv={0,0};
fd_set read_set;
#endif
/* Terminate buffers */
if(buf != NULL)
buf[0]=0;
if(fullbuf != NULL)
fullbuf[0]=0;
for(i=0;TRUE;) {
#if defined(_WIN32)
ret=0;
ReadFile(pipe, &ch, 1, (DWORD*)&ret, NULL);
#else
tv.tv_sec=startup->max_cgi_inactivity;
tv.tv_usec=0;
FD_ZERO(&read_set);
FD_SET(pipe, &read_set);
if(select(pipe+1, &read_set, NULL, NULL, &tv)<1)
return(-1);
#endif
if(fullbuf != NULL && i < (fullbuf_len-1)) {
fullbuf[i]=ch;
fullbuf[i+1]=0;
}
if(ch=='\n')
break;
}
}
/* Terminate at length if longer */
if(i>length)
i=length;
static int recvbufsocket(http_session_t *session, char *buf, long count)
{
int rd=0;
if(count<1) {
errno=ERANGE;
return(0);
}
while(rd<count && session_check(session,NULL,NULL,startup->max_inactivity*1000)) {
i=sess_recv(session,buf+rd,count-rd,0);
switch(i) {
case -1:
if (ERROR_VALUE == EAGAIN && !session->is_tls)
break;
// Fall-through...
case 0:
*buf=0;
return(0);
}
if(rd==count) {
return(rd);
}
*buf=0;
}
static void unescape(char *p)
{
char * dst;
char code[3];
dst=p;
for(;*p;p++) {
if(*p=='%' && isxdigit((uchar)*(p+1)) && isxdigit((uchar)*(p+2))) {
sprintf(code,"%.2s",p+1);
*(dst++)=(char)strtol(code,NULL,16);
p+=2;
}
else {
if(*p=='+') {
*(dst++)=' ';
}
else {
*(dst++)=*p;
}
}
}
*(dst)=0;
}
static void js_add_queryval(http_session_t * session, char *key, char *value)
JSObject* keyarray;
jsval val;
int alen;
/* Return existing object if it's already been created */
if(JS_GetProperty(session->js_cx,session->js_query,key,&val) && val!=JSVAL_VOID) {
keyarray = JSVAL_TO_OBJECT(val);
alen=-1;
}
else {
keyarray = JS_NewArrayObject(session->js_cx, 0, NULL);
if(!JS_DefineProperty(session->js_cx, session->js_query, key, OBJECT_TO_JSVAL(keyarray)
, NULL, NULL, JSPROP_ENUMERATE))
return;
alen=0;
}
if(alen==-1) {
if(JS_GetArrayLength(session->js_cx, keyarray, &len)==JS_FALSE)
return;
}
lprintf(LOG_DEBUG,"%04d Adding query value %s=%s at pos %d",session->socket,key,value,alen);
val=STRING_TO_JSVAL(JS_NewStringCopyZ(session->js_cx,value));
JS_SetElement(session->js_cx, keyarray, alen, &val);
}
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
static void js_add_cookieval(http_session_t * session, char *key, char *value)
{
JSObject* keyarray;
jsval val;
jsuint len;
int alen;
/* Return existing object if it's already been created */
if(JS_GetProperty(session->js_cx,session->js_cookie,key,&val) && val!=JSVAL_VOID) {
keyarray = JSVAL_TO_OBJECT(val);
alen=-1;
}
else {
keyarray = JS_NewArrayObject(session->js_cx, 0, NULL);
if(!JS_DefineProperty(session->js_cx, session->js_cookie, key, OBJECT_TO_JSVAL(keyarray)
, NULL, NULL, JSPROP_ENUMERATE))
return;
alen=0;
}
if(alen==-1) {
if(JS_GetArrayLength(session->js_cx, keyarray, &len)==JS_FALSE)
return;
alen=len;
}
lprintf(LOG_DEBUG,"%04d Adding cookie value %s=%s at pos %d",session->socket,key,value,alen);
val=STRING_TO_JSVAL(JS_NewStringCopyZ(session->js_cx,value));
JS_SetElement(session->js_cx, keyarray, alen, &val);
}
static void js_add_request_property(http_session_t * session, char *key, char *value, size_t len, bool writeable)
{
JSString* js_str;
if(session->js_cx==NULL || session->js_request==NULL)
return;
if(key==NULL || value==NULL)
return;
if(len)
js_str=JS_NewStringCopyN(session->js_cx, value, len);
else
js_str=JS_NewStringCopyZ(session->js_cx, value);
if(js_str == NULL)
uintN attrs = JSPROP_ENUMERATE;
if(!writeable)
attrs |= JSPROP_READONLY;
JS_DefineProperty(session->js_cx, session->js_request, key, STRING_TO_JSVAL(js_str)
,NULL,NULL,attrs);
static void js_add_request_prop_writeable(http_session_t * session, char *key, char *value)
js_add_request_property(session, key, value, 0, /* writeable: */true);
}
static void js_add_request_prop(http_session_t * session, char *key, char *value)
{
js_add_request_property(session, key, value, 0, /* writeable: */false);
static void js_add_header(http_session_t * session, char *key, char *value)
{
JSString* js_str;
char *lckey;
return;
strlwr(lckey);
if((js_str=JS_NewStringCopyZ(session->js_cx, value))==NULL) {
return;
}
JS_DefineProperty(session->js_cx, session->js_header, lckey, STRING_TO_JSVAL(js_str)
,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
}
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
#if 0
static void js_parse_multipart(http_session_t * session, char *p) {
size_t key_len;
size_t value_len;
char *lp;
char *key;
char *value;
if(p == NULL)
return;
lp=p;
while((key_len=strcspn(lp,"="))!=0) {
key=lp;
lp+=key_len;
if(*lp) {
*lp=0;
lp++;
}
value_len=strcspn(lp,"&");
value=lp;
lp+=value_len;
if(*lp) {
*lp=0;
lp++;
}
unescape(value);
unescape(key);
js_add_queryval(session, key, value);
}
}
#endif
static void js_parse_query(http_session_t * session, char *p) {
size_t key_len;
size_t value_len;
char *lp;
char *key;
char *value;
if(p == NULL)
return;
lp=p;
key=lp;
lp+=key_len;
value_len=strcspn(lp,"&");
value=lp;
unescape(value);
unescape(key);
js_add_queryval(session, key, value);
}
}
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
static char *get_token_value(char **p)
{
char *pos=*p;
char *start;
char *out;
BOOL escaped=FALSE;
start=pos;
out=start;
if(*pos=='"') {
for(pos++; *pos; pos++) {
if(escaped && *pos)
*(out++)=*pos;
else if(*pos=='"') {
pos++;
break;
}
else if(*pos=='\\')
escaped=TRUE;
else
*(out++)=*pos;
}
}
else {
for(; *pos; pos++) {
if(iscntrl(*pos))
break;
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
switch(*pos) {
case 0:
case '(':
case ')':
case '<':
case '>':
case '@':
case ',':
case ';':
case ':':
case '\\':
case '"':
case '/':
case '[':
case ']':
case '?':
case '=':
case '{':
case '}':
case ' ':
case '\t':
goto end_of_text;
}
*(out++)=*pos;
}
}
end_of_text:
while(*pos==',' || isspace(*pos))
pos++;
*out=0;
*p=pos;
return(start);
}
static int hexval(unsigned char ch)
{
ch-='0';
if(ch<10)
return(ch);
ch-=7;
if(ch<16 && ch>9)
return(ch);
if(ch>41) {
ch-=32;
if(ch<16 && ch>9)
return(ch);
}
return(0);
}
static BOOL parse_headers(http_session_t * session)
{
char *p;
int i;
size_t idx;
size_t content_len=0;
for(idx=0;session->req.headers[idx]!=NULL;idx++) {
/* TODO: strdup() is possibly too slow here... */
head_line=strdup(session->req.headers[idx]);
if((strtok_r(head_line,":",&last))!=NULL && (value=strtok_r(NULL,"",&last))!=NULL) {
i=get_header_type(head_line);
while(*value && *value<=' ') value++;
switch(i) {
case HEAD_AUTH:
/* If you're authenticated via TLS-PSK, you can't use basic or digest */
if (session->req.auth.type != AUTHENTICATION_TLS_PSK) {
if((p=strtok_r(value," ",&last))!=NULL) {
if(stricmp(p, "Basic")==0) {
p=strtok_r(NULL," ",&last);
if(p==NULL)
while(*p && *p<' ') p++;
b64_decode(p,strlen(p),p,strlen(p));
p=strtok_r(p,":",&last);
SAFECOPY(session->req.auth.username, p);
p=strtok_r(NULL,":",&last);
if(p) {
if(strlen(p) >= sizeof(session->req.auth.password))
break;
SAFECOPY(session->req.auth.password, p);
session->req.auth.type=AUTHENTICATION_BASIC;
}
else if(stricmp(p, "Digest")==0) {
p=strtok_r(NULL, "", &last);
/* Defaults */
session->req.auth.algorithm=ALGORITHM_MD5;
session->req.auth.type=AUTHENTICATION_DIGEST;
/* Parse out values one at a time and store */
while(p != NULL && *p) {
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
while(isspace(*p))
p++;
if(strnicmp(p,"username=",9)==0) {
p+=9;
tvalue=get_token_value(&p);
if(strlen(tvalue) >= sizeof(session->req.auth.username))
break;
SAFECOPY(session->req.auth.username, tvalue);
}
else if(strnicmp(p,"realm=",6)==0) {
p+=6;
session->req.auth.realm=strdup(get_token_value(&p));
}
else if(strnicmp(p,"nonce=",6)==0) {
p+=6;
session->req.auth.nonce=strdup(get_token_value(&p));
}
else if(strnicmp(p,"uri=",4)==0) {
p+=4;
session->req.auth.digest_uri=strdup(get_token_value(&p));
}
else if(strnicmp(p,"response=",9)==0) {
p+=9;
tvalue=get_token_value(&p);
if(strlen(tvalue)==32) {
for(i=0; i<16; i++) {
session->req.auth.digest[i]=hexval(tvalue[i*2])<<4 | hexval(tvalue[i*2+1]);
}
else if(strnicmp(p,"algorithm=",10)==0) {
p+=10;
tvalue=get_token_value(&p);
if(stricmp(tvalue,"MD5")==0) {
session->req.auth.algorithm=ALGORITHM_MD5;
}
else {
session->req.auth.algorithm=ALGORITHM_UNKNOWN;
}
else if(strnicmp(p,"cnonce=",7)==0) {
p+=7;
session->req.auth.cnonce=strdup(get_token_value(&p));
else if(strnicmp(p,"qop=",4)==0) {
p+=4;
tvalue=get_token_value(&p);
if(stricmp(tvalue,"auth")==0) {
session->req.auth.qop_value=QOP_AUTH;
}
else if (stricmp(tvalue,"auth-int")==0) {
session->req.auth.qop_value=QOP_AUTH_INT;
}
else {
session->req.auth.qop_value=QOP_UNKNOWN;
}
else if(strnicmp(p,"nc=",3)==0) {
p+=3;
session->req.auth.nonce_count=strdup(get_token_value(&p));
while(*p && *p != '=')
p++;
if(*p == '=')
get_token_value(&p);
if(session->req.auth.digest_uri==NULL)
session->req.auth.digest_uri=strdup(session->req.request_line);
/* Validate that we have the required values... */
switch(session->req.auth.qop_value) {
case QOP_NONE:
if(session->req.auth.realm==NULL
|| session->req.auth.nonce==NULL
|| session->req.auth.digest_uri==NULL)
send_error(session,__LINE__,"400 Bad Request");
break;
case QOP_AUTH:
case QOP_AUTH_INT:
if(session->req.auth.realm==NULL
|| session->req.auth.nonce==NULL
|| session->req.auth.nonce_count==NULL
|| session->req.auth.cnonce==NULL
|| session->req.auth.digest_uri==NULL)
send_error(session,__LINE__,"400 Bad Request");
send_error(session,__LINE__,"400 Bad Request");
break;
case HEAD_LENGTH:
add_env(session,"CONTENT_LENGTH",value);
break;
case HEAD_IFMODIFIED:
session->req.if_modified_since=decode_date(value);
break;
case HEAD_CONNECTION:
if(!stricmp(value,"Keep-Alive")) {
session->req.keep_alive=TRUE;
}
if(!stricmp(value,"Close")) {
session->req.keep_alive=FALSE;
}
case HEAD_REFERER:
if(session->req.ld!=NULL) {
FREE_AND_NULL(session->req.ld->referrer);
/* FREE()d in http_logging_thread() */
session->req.ld->referrer=strdup(value);
break;
case HEAD_AGENT:
if(session->req.ld!=NULL) {
FREE_AND_NULL(session->req.ld->agent);
/* FREE()d in http_logging_thread() */
session->req.ld->agent=strdup(value);
break;
case HEAD_TRANSFER_ENCODING:
if(!stricmp(value,"chunked"))
session->req.read_chunked=TRUE;
else
send_error(session,__LINE__,"501 Not Implemented");
break;
if(!stricmp(value,"bytes=")) {
send_error(session,__LINE__,error_416);
break;
}
value+=6;
if(strchr(value,',')!=NULL) { /* We don't do multiple ranges yet - TODO */
send_error(session,__LINE__,error_416);
break;
}
/* Check for offset from end. */
if(*value=='-') {
session->req.range_start=strtol(value,NULL,10);
session->req.range_end=-1;
break;
}
if((p=strtok_r(value,"-",&last))!=NULL) {
session->req.range_start=strtol(p,NULL,10);
if((p=strtok_r(NULL,"-",&last))!=NULL)
session->req.range_end=strtol(p,NULL,10);
else
session->req.range_end=-1;
send_error(session,__LINE__,error_416);
break;
case HEAD_IFRANGE:
session->req.if_range=decode_date(value);
break;
case HEAD_TYPE:
add_env(session,"CONTENT_TYPE",value);
break;
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
case HEAD_UPGRADEINSECURE:
if (startup->options & WEB_OPT_HSTS_SAFE) {
if (strcmp(value, "1") == 0) {
if (!session->is_tls) {
portstr[0] = 0;
if (startup->tls_port != 443)
sprintf(portstr, ":%hu", startup->tls_port);
p = realloc(session->req.vary_list, (session->req.vary_list ? strlen(session->req.vary_list) + 2 : 0) + strlen(get_header(HEAD_UPGRADEINSECURE)) + 1);
if (p == NULL)
send_error(session, __LINE__, error_500);
else {
if (session->req.vary_list)
strcat(p, ", ");
strcat(p, get_header(HEAD_UPGRADEINSECURE));
session->req.vary_list = p;
session->req.send_location = MOVED_TEMPREDIR;
session->req.upgrading = TRUE;
session->req.keep_alive = FALSE;
FREE_AND_NULL(session->req.location_to_send);
if (asprintf(&session->req.location_to_send, "https://%s%s%s", session->req.vhost, portstr, session->req.virtual_path) < 0)
send_error(session, __LINE__, error_500);
}
}
}
}
break;
default:
break;
}
SAFEPRINTF(env_name,"HTTP_%s",head_line);
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
add_env(session,env_name,value);
}
free(head_line);
}
if(content_len)
session->req.post_len = content_len;
add_env(session,"SERVER_NAME",session->req.host[0] ? session->req.host : startup->host_name );
return TRUE;
}
static BOOL parse_js_headers(http_session_t * session)
{
char *head_line;
char *value;
char *last;
char *p;
int i;
size_t idx;
for(idx=0;session->req.headers[idx]!=NULL;idx++) {
head_line=session->req.headers[idx];
if((strtok_r(head_line,":",&last))!=NULL && (value=strtok_r(NULL,"",&last))!=NULL) {
i=get_header_type(head_line);
while(*value && *value<=' ') value++;
js_add_header(session,head_line,value);
switch(i) {
case HEAD_TYPE:
if(session->req.dynamic==IS_SSJS) {
/*
* We need to parse out the files based on RFC1867
*
* And example reponse looks like this:
* Content-type: multipart/form-data, boundary=AaB03x
* --AaB03x
* content-disposition: form-data; name="field1"
* Joe Blow
* --AaB03x
* content-disposition: form-data; name="pics"
* Content-type: multipart/mixed, boundary=BbC04y
* --BbC04y
* Content-disposition: attachment; filename="file1.txt"
* ... contents of file1.txt ...
* --BbC04y
* Content-disposition: attachment; filename="file2.gif"
* Content-type: image/gif
* Content-Transfer-Encoding: binary
* ...contents of file2.gif...
* --BbC04y--
* --AaB03x--
case HEAD_COOKIE:
if(session->req.dynamic==IS_SSJS) {
char *key;
char *val;
p=value;
while((key=strtok_r(p,"=",&last))!=NULL) {
while(isspace(*key))
key++;
p=NULL;
if((val=strtok_r(p,";\t\n\v\f\r ",&last))!=NULL) { /* Whitespace */
js_add_cookieval(session,key,val);
}
}
}
break;
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
default:
break;
}
}
}
return TRUE;
}
static int get_version(char *p)
{
int i;
if(p==NULL)
return(0);
while(*p && *p<' ') p++;
if(*p==0)
return(0);
for(i=1;http_vers[i]!=NULL;i++) {
if(!stricmp(p,http_vers[i])) {
return(i);
}
}
return(i-1);
}
static int is_dynamic_req(http_session_t* session)
{
char drive[4];
char cgidrive[4];
char dir[MAX_PATH+1];
char cgidir[MAX_PATH+1];
char fname[MAX_PATH+1];
char ext[MAX_PATH+1];
check_extra_path(session);
_splitpath(session->req.physical_path, drive, dir, fname, ext);
if(!(startup->options&WEB_OPT_NO_CGI)) {
if (session->req.fastcgi_socket) {
init_enviro(session);
return IS_FASTCGI;
}
}
if(stricmp(ext,startup->ssjs_ext)==0)
i=IS_SSJS;
else if(get_xjs_handler(ext,session))
i=IS_SSJS;
if(!(startup->options&BBS_OPT_NO_JAVASCRIPT) && i) {
lprintf(LOG_DEBUG,"%04d Setting up JavaScript support", session->socket);
if(!js_setup(session)) {
lprintf(LOG_ERR,"%04d !ERROR setting up JavaScript support", session->socket);
send_error(session,__LINE__,error_500);
return(IS_STATIC);
}
if(!(startup->options&WEB_OPT_NO_CGI)) {
for(i=0; startup->cgi_ext!=NULL && startup->cgi_ext[i]!=NULL; i++) {
if(stricmp(ext,startup->cgi_ext[i])==0) {
return(IS_CGI);
}
}
_splitpath(session->req.cgi_dir?session->req.cgi_dir:cgi_dir, cgidrive, cgidir, fname, ext);
if(stricmp(dir,cgidir)==0 && stricmp(drive,cgidrive)==0) {
}
}
return(IS_STATIC);
}
char *ret = NULL;
if (isdigit(*p)) {
/*
* If the first and last : are not the same, and it doesn't
* start with '[', there's no port part.
*/
if (host[0] != '[') {
if (strchr(host, ':') != strrchr(host, ':'))
return NULL;
}
for(; p >= host; p--) {
if (*p == ':') {
*p = 0;
ret = p+1;
break;
}
if (!isdigit(*p))
break;
// Now, remove []s...
if (host[0] == '[') {
memmove(host, host+1, strlen(host));
p=strchr(host, ']');
if (p)
*p = 0;
}
return ret;
}
static void remove_port_part(char *host)
{
split_port_part(host);
static char *get_request(http_session_t * session, char *req_line)
char* p;
char* retval;
const char* scheme = NULL;
size_t scheme_len;
SKIP_WHITESPACE(req_line);
SAFECOPY(session->req.virtual_path,req_line);
if(strtok_r(session->req.virtual_path," \t",&last))
retval=strtok_r(NULL," \t",&last);
else
retval=NULL;
SAFECOPY(session->req.request_line,session->req.virtual_path);
if (!session->req.orig_request_line[0])