Exemple #1
0
int32 PoorManServer::_Listener(void* data)
{
	PRINT(("The listener thread is working.\n"));
	int retval;
	thread_id tid;
	httpd_conn* hc;
	PoorManServer* s = static_cast<PoorManServer*>(data);
	
	while (s->fIsRunning) {
		hc = new httpd_conn;
		hc->initialized = 0;
		PRINT(("calling httpd_get_conn()\n"));
		retval = //accept(), blocked here
			httpd_get_conn(s->fHttpdServer, s->fHttpdServer->listen4_fd, hc);
		switch (retval) {
			case GC_OK:
				break;
			case GC_FAIL:
				httpd_destroy_conn(hc);
				delete hc;
				s->fIsRunning = false;
				return -1;
			case GC_NO_MORE:
				//should not happen, since we have a blocking socket
				httpd_destroy_conn(hc);
				continue;
				break;
			default: 
				//shouldn't happen
				continue;
				break;
		}
		
		if (s->fCurConns > s->fMaxConns) {
			httpd_send_err(hc, 503,
				httpd_err503title, (char *)"", httpd_err503form, (char *)"");
			httpd_write_response(hc);
			continue;
		}
		
		tid = spawn_thread(
			PoorManServer::_Worker,
			"www connection",
			B_NORMAL_PRIORITY,
			static_cast<void*>(s)
		);
		if (tid < B_OK) {
			continue;
		}
		/*We don't check the return code here.
		 *As we can't kill a thread that doesn't receive the
		 *httpd_conn, we simply let it die itself.
		 */
		send_data(tid, 512, &hc, sizeof(httpd_conn*));
		atomic_add(&s->fCurConns, 1);
		resume_thread(tid);
	}//while
	return 0;
}
static void shut_down(void)
{
  int cnum;

  for (cnum = 0; cnum < AVAILABLE_FDS; ++cnum)
    {
      if (connects[cnum].conn_state != CNST_FREE)
        {
          httpd_close_conn(connects[cnum].hc);
        }

      if (connects[cnum].hc != NULL)
        {
          httpd_destroy_conn(connects[cnum].hc);
          httpd_free((void *)connects[cnum].hc);
          connects[cnum].hc = NULL;
        }
    }

  if (hs)
    {
      httpd_server *ths = hs;
      hs = NULL;
      if (ths->listen_fd != -1)
        {
          fdwatch_del_fd(fw, ths->listen_fd);
        }
      httpd_terminate(ths);
    }

  tmr_destroy();
  httpd_free((void *)connects);
}
Exemple #3
0
static void
shut_down( void )
    {
    int cnum;
    struct timeval tv;

    (void) gettimeofday( &tv, (struct timezone*) 0 );
    for ( cnum = 0; cnum < max_connects; ++cnum )
	{
	if ( connects[cnum].conn_state != CNST_FREE )
	    httpd_close_conn( connects[cnum].hc, &tv );
	if ( connects[cnum].hc != (httpd_conn*) 0 )
	    {
	    httpd_destroy_conn( connects[cnum].hc );
	    free( (void*) connects[cnum].hc );
	    --httpd_conn_count;
	    connects[cnum].hc = (httpd_conn*) 0;
	    }
	}
    if ( hs != (httpd_server*) 0 )
	{
	httpd_server* ths = hs;
	hs = (httpd_server*) 0;
	if ( ths->listen4_fd != -1 )
	    fdwatch_del_fd( ths->listen4_fd );
	if ( ths->listen6_fd != -1 )
	    fdwatch_del_fd( ths->listen6_fd );
	httpd_terminate( ths );
	}
    tmr_destroy();
    free( (void*) connects );
    }
Exemple #4
0
static void
shut_down( void )
    {
    int cnum;
    struct timeval tv;

    (void) gettimeofday( &tv, (struct timezone*) 0 );
    logstats( &tv );
    for ( cnum = 0; cnum < maxconnects; ++cnum )
	{
	if ( connects[cnum].conn_state != CNST_FREE )
	    httpd_close_conn( connects[cnum].hc, &tv );
	if ( connects[cnum].hc != (httpd_conn*) 0 )
	    {
	    httpd_destroy_conn( connects[cnum].hc );
	    free( (void*) connects[cnum].hc );
	    --httpd_conn_count;
	    connects[cnum].hc = (httpd_conn*) 0;
	    }
	}
    if ( hs != (httpd_server*) 0 )
	{
	httpd_server* ths = hs;
	hs = (httpd_server*) 0;
	httpd_terminate( ths );
	}
    mmc_destroy();
    tmr_destroy();
    free( (void*) connects );
    if ( throttles != (throttletab*) 0 )
	free( (void*) throttles );
    }
Exemple #5
0
int32 PoorManServer::_Worker(void* data)
{
	static const struct timeval kTimeVal = {60, 0};
	PoorManServer* s = static_cast<PoorManServer*>(data);
	httpd_conn* hc;
	int retval;
	
	if (has_data(find_thread(NULL))) {
		thread_id sender;
		if (receive_data(&sender, &hc, sizeof(httpd_conn*)) != 512)
			goto cleanup;
	} else {
		// No need to go throught the whole cleanup, as we haven't open
		// nor allocated ht yet.
		atomic_add(&s->fCurConns, -1);
		return 0;
	}
	
	PRINT(("A worker thread starts to work.\n"));

	setsockopt(hc->conn_fd, SOL_SOCKET, SO_RCVTIMEO, &kTimeVal,
		sizeof(struct timeval));
	retval = recv(
		hc->conn_fd,
		&(hc->read_buf[hc->read_idx]),
		hc->read_size - hc->read_idx,
		0
	);
	if (retval < 0)
		goto cleanup;

	hc->read_idx += retval;
	switch(httpd_got_request(hc)) {
		case GR_GOT_REQUEST:
			break;
		case GR_BAD_REQUEST:
			httpd_send_err(hc, 400,
				httpd_err400title, (char *)"", httpd_err400form, (char *)"");
			httpd_write_response(hc);//fall through
		case GR_NO_REQUEST: //fall through
		default: //won't happen
			goto cleanup;
			break;
	}
	
	if (httpd_parse_request(hc) < 0) {
		httpd_write_response(hc);
		goto cleanup;
	}
	
	retval = httpd_start_request(hc, (struct timeval*)0);
	if (retval < 0) {
		httpd_write_response(hc);
		goto cleanup;
	}
	
	/*true means the connection is already handled
	 *by the directory index generator in httpd_start_request().
	 */
	if (hc->file_address == (char*) 0) {
		static_cast<PoorManApplication*>(be_app)->GetPoorManWindow()->SetHits(
			static_cast<PoorManApplication*>(be_app)->GetPoorManWindow()->GetHits() + 1
		);
		hc->conn_fd = -1;
		goto cleanup;
	}
	
	switch (hc->method) {
		case METHOD_GET:
			s->_HandleGet(hc);
			break;
		case METHOD_HEAD:
			s->_HandleHead(hc);
			break;
		case METHOD_POST:
			s->_HandlePost(hc);
			break;
	}
	
cleanup: ;
	httpd_close_conn(hc, (struct timeval*)0);
	httpd_destroy_conn(hc);
	
	delete hc;
	atomic_add(&s->fCurConns, -1);
	return 0;
}