I have simple proxy app, that listens connections from browser on port 4711. Then app sends requests to server (own app) and compares server's version of requested data with local cache and then applies that difference and sends data back to browser.
I'm working till with very simply sites, that contents only home page. But there is working correctly only in IE 10. I tested FF, Chrome, Safari, but they are not working. They are hanging while requests to proxy.
The app is written on C, using SDL, and SDL_Net network functions. Used non-blocking TCP sockets. I'm debugging using VS 2010 and Windows 8.
Please suggest what should I check firstly. I understand i described the problem very briefly, but i can provide additional info (pieces of code etc.) if needed.
Ok. Put some code here.
typedef struct _UA_REQUEST
{
My_string full_url ;
uint32_t url_adler32 ;
TCPsocket sock_ua ;
uint32_t status_flag ; // ref Enum STATUS
} UA_REQUEST ;
UA_REQUEST GLB_ARRAY__UA_REQ[ NUM_UA_SOCK ] ;
TCPsocket GLB_SOCK_SS={0} , GLB_LSOCK_UA={0} ;
while( 1 )
{
nrdy = SDLNet_CheckSockets(GLB_SOCK_SET, -1 /*1000*/);
if(nrdy == -1 )
break ;
if( !nrdy )
continue ;
check_listener_socket() ;
check_user_agent_sockets() ;
check_single_stream_socket() ;
}
//==================================================================
// Check and handle connection request from UA ( user agent )
//==================================================================
void check_listener_socket()
{
uint32_t index ;
UA_REQUEST*ar = GLB_ARRAY__UA_REQ ;
if( !SDLNet_SocketReady( GLB_LSOCK_UA ) )
{
puts("check_listener_socket(): GLB_LSOCK_UA is not ready!");
return ;
}
TCPsocket sock_ua = SDLNet_TCP_Accept( GLB_LSOCK_UA ) ; // accept connection from browser
if( !sock_ua)
{
printf("ERR__TCP_Accept: %s\n", SDLNet_GetError());
goto quit ;
} else
printf("Accepted.\n");
for( index=0 ; (index < NUM_UA_SOCK) ; index++)
if( STATUS(ar,index) == ST_SOCK_CLOSED )
break ;
if( index >= NUM_UA_SOCK )
return;
SOCK_UA( ar , index ) = sock_ua;
STATUS( ar , index ) = ST_SOCK_AVLBL ;
SDLNet_TCP_AddSocket( GLB_SOCK_SET , SOCK_UA( ar, index ) ) ;
quit:
return;
}
//==================================================================
// Check and receive data from UA
//==================================================================
void check_user_agent_sockets()
{
UA_REQUEST *ar = GLB_ARRAY__UA_REQ ;
uint32_t index ;
for( index=0 ; index < NUM_UA_SOCK ; index++)
{
int ready = SDLNet_SocketReady( SOCK_UA(ar,index) );
if( /*STATUS( ar,index) != ST_SOCK_CLOSED &&*/
ready /*SDLNet_SocketReady( SOCK_UA(ar,index) ) */
)
{
printf("index = %i\n", index);
handle_ua_sock_ready( index ) ;
}
}
}
void handle_ua_sock_ready( uint32_t i )
{
My_string _req_mstr ;
MY_ALLOC( _req_mstr , MAXLEN )
byte*request = _req_mstr.c_str ;
byte*pcrlf = NULL ;
RESET_BUF(request)
UA_REQUEST*ar = GLB_ARRAY__UA_REQ ;
//uint32_t
int nrcv; // : Slava
nrcv = SDLNet_TCP_Recv( SOCK_UA(ar,i) , request , MAXLEN ) ;
if( nrcv<=0 )
{
puts("handle_ua_sock_ready() before handle_ua_sock_closed");
handle_ua_sock_closed( ar , i ) ;
puts("handle_ua_sock_ready() after handle_ua_sock_closed");
goto quit;
}
puts("1") ;
if(
( STATUS(ar,i) == ST_TUNNEL)
|| (MATCH( request , CONN , strlen(CONN)))
)
{
FULL_URL( ar , i ).c_str[0] = 0 ;
FULL_URL( ar , i ).len = 0 ;
STATUS( ar , i ) = ST_TUNNEL ;
request[nrcv] = 0 ;
send_to_server(TUNNEL_REQ ,request, nrcv, i);
goto quit;
}
puts("11") ;
if( get_hdrs_and_full_url(request, i ,(uint32_t*)&nrcv,pcrlf) == -1 )
{
puts("handle_ua_sock_ready() test 2");
goto quit ;
}
My_string *purl_mstr = &FULL_URL( ar , i ) ;
log_msg( purl_mstr->c_str , purl_mstr->len , __LINE__ ) ;
URL_ADLER32( ar, i) = my_adler_32( 1 , purl_mstr->c_str , purl_mstr->len ) ;
fwrite( FULL_URL(ar,i).c_str , sizeof(byte), FULL_URL(ar,i).len , GLB_REQ_LOG) ;
puts("111") ;
CHECK_AND_HANDLE_GET_HEAD_REQ( i , request , nrcv )
CHECK_AND_HANDLE_UNSUPPORTED(ar,i,request )
uint32_t uv = nrcv;
CHECK_AND_HANDLE_POST_OPT_REQ(ar,i,request ,/*nrcv*/ uv)
quit:
MY_FREE( _req_mstr )
return ;
}
//==================================================================
// Check and receive reply from "Server"
//==================================================================
void check_single_stream_socket()
{
puts("-- before return");
if( !SDLNet_SocketReady(GLB_SOCK_SS) )
{
return ;
}
puts("-- before receive_data_from_server()");
receive_data_from_server() ;
}
//==================================================================
//
// receive_data_from_server/0 :: First 4 bytes of "Payload" are eql to length of rest of Payload
//
//==================================================================
void receive_data_from_server()
{
My_string payload ;
MY_ALLOC( payload , MAXLEN )
int ncnt; // : Slava
uint32_t nreply , req_index , rep_index ;
uint32_t aallocated, ffreed ;
byte err[100] ;
bool bExitFlag = false;
puts("30001") ;
payload.len = 0 ;
if( get_payload(&payload) == -1 )
goto quit ;
UA_REQUEST*req_arr = GLB_ARRAY__UA_REQ ;
SS_REPLY*rep_arr = GLB_ARRAY__SS_REPLY ;
puts("30002") ;
// printf( "rep_type :: %u \nreq_id :: %u \n" , payload.c_str[0] , SDLNet_Read32( payload.c_str+1 ) ) ;
uint8_t rep_type = payload.c_str[0] ;
if( (rep_type == 1)
|| (rep_type == 3)
|| ( rep_type==4 )
) /*ie req_id == req_arr index*/
{
puts("30003") ;
req_index = SDLNet_Read32( payload.c_str+1 ) ;
nreply = payload.len-5 ;
ncnt = SDLNet_TCP_Send(
SOCK_UA( req_arr,req_index)
, payload.c_str+5 , nreply
) ;
if(ncnt < nreply)
{
sprintf((char*)err , "ERR__SOCK_WRITE :: bytes to be written: %u ;; actual num:: %u" , nreply , ncnt ) ;
log_msg(err , strlen((char*)err) , __LINE__ ) ;
handle_ua_sock_closed( req_arr , req_index ) ;
}
}
else if( payload.c_str[0] == 2 ) /* < req_id == "url_adler32" > */
{
puts("30004") ;
uint32_t url_adler32 = SDLNet_Read32( payload.c_str+1 ) ;
for( req_index = 0 ; req_index<NUM_UA_SOCK ; req_index++ )
{
if(URL_ADLER32( req_arr , req_index) == url_adler32 )
{
puts("30005") ;
My_string reply_mstr ;
MY_ALLOC( reply_mstr , MAXLEN )
update_cache__and__read_in_mystr( payload.c_str+5 ,payload.len-5
,&reply_mstr ,req_index
) ;
nreply = reply_mstr.len ;
puts("30006") ;
ncnt = SDLNet_TCP_Send(
SOCK_UA( req_arr , req_index)
, reply_mstr.c_str // reply_mstr
, nreply
) ;
if(ncnt < nreply)
{
sprintf((char*)err , "ERR__SOCK_WRITE :: bytes to be written: %u ;; actual num:: %u" , nreply , ncnt ) ;
log_msg(err , strlen((char*)err) , __LINE__ ) ;
handle_ua_sock_closed( req_arr , req_index ) ;
}
else
reset_req_arr_element( req_index) ;
MY_FREE( reply_mstr )
bExitFlag = true; // : Slava
break;
}
}
if (!bExitFlag)
{
for( rep_index = 0 ; rep_index<NUM_SS_REPLY ; rep_index++)
if(STATUS( rep_arr , rep_index )==ST_EMPTY)
break ;
My_string*pdel_mstr = &(REPLY( rep_arr , rep_index )) ;
if(pdel_mstr->len)
pdel_mstr->len = 0 ;
append( pdel_mstr , payload.c_str+5 , payload.len-5 ) ;
puts("30007") ;
STATUS( rep_arr , rep_index ) = ST_OCCUPIED ;
}
} /*</ id_type != "socket"> */
quit:
MY_FREE( payload )
}
I can also add that app does not send even need packets to browser. I used SoftPerfect sniffer for this goal.
Thanks for answers, specially to @n.m.. I used Fiddler and SoftPerfect sniffers to spot my bug. There is error in my code.
Thanks all, Vyacheslav