extern "C" SOAP_FMAC5 int SOAP_FMAC6 soap_serve(struct soap *soap)
{
#ifndef WITH_FASTCGI
	unsigned int k = soap->max_keep_alive;
#endif
	do
	{
#ifndef WITH_FASTCGI
		if (soap->max_keep_alive > 0 && !--k)
			soap->keep_alive = 0;
#endif
		if (soap_begin_serve(soap))
		{	if (soap->error >= SOAP_STOP)
				continue;
			return soap->error;
		}
		if (soap_serve_request(soap) || (soap->fserveloop && soap->fserveloop(soap)))
		{
#ifdef WITH_FASTCGI
			soap_send_fault(soap);
#else
			return soap_send_fault(soap);
#endif
		}

#ifdef WITH_FASTCGI
		soap_destroy(soap);
		soap_end(soap);
	} while (1);
#else
	} while (soap->keep_alive);
Example #2
0
SOAP_FMAC5 int SOAP_FMAC6 soap_serve(struct soap* soap)
{
#ifndef WITH_FASTCGI
    unsigned int k = soap->max_keep_alive;
#endif

    do
    {
#ifdef WITH_FASTCGI
        if (FCGI_Accept() < 0)
        {
            soap->error = SOAP_EOF;
            return soap_send_fault(soap);
        }
#endif

        soap_begin(soap);

#ifndef WITH_FASTCGI
        if (soap->max_keep_alive > 0 && !--k)
            soap->keep_alive = 0;
#endif

        if (soap_begin_recv(soap))
        {
            if (soap->error < SOAP_STOP)
            {
#ifdef WITH_FASTCGI
                soap_send_fault(soap);
#else
                return soap_send_fault(soap);
#endif
            }
            soap_closesock(soap);

            continue;
        }

        if (soap_envelope_begin_in(soap)
                || soap_recv_header(soap)
                || soap_body_begin_in(soap)
                || soap_serve_request(soap)
                || (soap->fserveloop && soap->fserveloop(soap)))
        {
#ifdef WITH_FASTCGI
            soap_send_fault(soap);
#else
            return soap_send_fault(soap);
#endif
        }

#ifdef WITH_FASTCGI
        soap_destroy(soap);
        soap_end(soap);
    }
    while (1);
#else
    } while (soap->keep_alive);
Example #3
0
int Service::start(int port)
{
  if (!soap_valid_socket(bind(NULL, port, 100)))
  {
    soap_stream_fault(std::cerr);
    exit(1);
  }
  std::cerr << "Server Running" << std::endl;

  /* optional: set accept timeout to pulse acks every 500 ms, see below */
  soap->accept_timeout = -500000;

  for (;;)
  {
    if (soap_valid_socket(accept()))
    { 
      /* with iterative servers asynchronous messaging deadlock scenarios exist! */
      /* chain the WSRM service operations after the main service operations */
      if (soap_begin_serve(soap) == SOAP_OK)
        if (dispatch() == SOAP_NO_METHOD)
          soap_serve_request(soap);
      if (soap->error)
        soap_send_fault(soap);
      if (soap->error && soap->error != SOAP_STOP)
        soap_stream_fault(std::cerr);

      destroy();
      callback.destroy();

      soap_wsrm_dump(soap, stdout);
    }
    else
    {
      /* error or timeout? */
      if (soap->errnum)
      {
        soap_stream_fault(std::cerr);
        exit(1);
      }
      /* timeout occurs after 1 sec */
      /* send acks to peers (optional), 10 ms per message timeout */
      soap_wsrm_pulse(soap, -10000); /* 10 ms */
    }
  }
  return SOAP_OK;
}
Example #4
0
void *callback_thread(void *ctx)
{
  WSDualHttpBinding_USCOREICalculatorDuplexService *callback = (WSDualHttpBinding_USCOREICalculatorDuplexService*)ctx;
  THREAD_DETACH(THREAD_ID);

  /* chain the WSRM operations after callback operations */
  if (soap_begin_serve(callback->soap) == SOAP_OK)
    if (callback->dispatch() == SOAP_NO_METHOD)
      soap_serve_request(callback->soap);
  if (callback->soap->error)
    soap_send_fault(callback->soap);

  if (callback->soap->error != SOAP_STOP && callback->soap->error != SOAP_EOF)
    callback->soap_stream_fault(std::cerr);
  else if (callback->soap->error != SOAP_EOF || callback->soap->errnum)
    soap_wsrm_dump(callback->soap, stdout);

  callback->destroy();
  delete callback;

  return NULL;
}
Example #5
0
int Client::poll(int timeout)
{
#ifdef CB_THREAD

  // We leave the acceptance of messages to the callback server thread
  if (timeout < 0)
    timeout = 1;
  sleep(timeout); // but we want to wait some until these messages arrive

#else

  callback.soap->accept_timeout = timeout;

  printf("\n**** Callback Polling\n");

  while (soap_valid_socket(callback.accept()))
  {
    /* chain the WSRM operations after callback operations */
    if (soap_begin_serve(callback.soap) == SOAP_OK)
      if (callback.dispatch() == SOAP_NO_METHOD)
        soap_serve_request(callback.soap);
    if (callback.soap->error)
      soap_send_fault(callback.soap);

    soap->error = callback.soap->error;

    callback.destroy();

    if (soap->error && soap->error != SOAP_STOP)
    {
      soap_stream_fault(std::cerr);
      return soap->error;
    }
    soap_wsrm_dump(callback.soap, stdout);
  }
#endif

  return SOAP_OK;
}
Example #6
0
/*****************************************************************************
 函 数 名  : ws_internal_call
 功能描述  : 以内部方式调用一个web service方法
 输入参数  : ws_env     ---- web service执行环境
             ws_req_res ---- web service参数结构
             method     ---- web service方法名
             handle     ---- web service处理函数所在so文件据柄
             internal_env -- 内部执行环境
 输出参数  : 无
 返 回 值  : ERROR_SYSTEM  失败
             ERR_SUCESS           成功,无错误
             SOAP_FAULT           执行有错误,错误放soapFault中
 调用函数  : 
 被调函数  : 
 ============================================================================
 修改历史      :
  1.日    期   : 2008年8月8日
     
    修改内容   : 新生成函数

*****************************************************************************/
u_int32_t ws_internal_call(WS_ENV* ws_env, WS_REQ_RES* ws_req_res, char* method, void* handle,
            WS_INTERNAL_ENV *internal_env)
{
    char* pchar;
    char* error;
    /* 向web service发送数据的管道 */
    int file_to_ws[2];
    /* 从web service接收数据的管道 */
    int file_from_ws[2];

    SOAP_SERVE_REQUEST *soap_serve_request;
    u_int32_t ret;

    if((NULL == ws_env) || (NULL == ws_req_res) || (NULL == method))
    {
        return ERROR_SYSTEM;
    }
   
    do
    {
        /* 只执行一次 */
        error = NULL;
        dlerror();    /* Clear any existing error */
        /* 读入web service执行函数 */
        soap_serve_request = dlsym(handle, "soap_serve_request");
        if ((error = dlerror()) != NULL)  
        {
            break;
        }

        #ifndef WITH_NOIDREF
        /* 读入各模块支持函数,在web_frame.so中引用 */
        soap_putelement_ext = dlsym(handle, "soap_putelement");
        if ((error = dlerror()) != NULL)  
        {
            break;
        }
        #endif
        soap_ignore_element_ext = dlsym(handle, "soap_ignore_element");
        if ((error = dlerror()) != NULL)  
        {
            break;
        }
        soap_default_int_ext = dlsym(handle, "soap_default_int");
        if ((error = dlerror()) != NULL)  
        {
            break;
        }
        #ifndef WITH_NOIDREF
        soap_getindependent_ext = dlsym(handle, "soap_getindependent");
        if ((error = dlerror()) != NULL)  
        {
            break;
        }
        #endif
        soap_in_int_ext = dlsym(handle, "soap_in_int");
        if ((error = dlerror()) != NULL)  
        {
            break;
        }
         #ifndef WITH_NOIDREF
        soap_getelement_ext = dlsym(handle, "soap_getelement");
        if ((error = dlerror()) != NULL)  
        {
            break;
        }
       
        soap_putindependent_ext = dlsym(handle, "soap_putindependent");
        if ((error = dlerror()) != NULL)  
        {
            break;
        }
         #endif
        soap_out_int_ext = dlsym(handle, "soap_out_int");
        if ((error = dlerror()) != NULL)  
        {
            break;
        }
        #ifndef WITH_NOIDREF
        soap_markelement_ext = dlsym(handle, "soap_markelement");
        if ((error = dlerror()) != NULL)  
        {
            break;
        }
        #endif
        error = NULL;
        break;
    }while(error);
    if (NULL != error)
    {
        s8 err_info[200];
        
        /* 发生错误 */
        WEB_SEND_DEBUG_s(error);
        
        snprintf(err_info, sizeof(err_info), "Load web service method %s failed:%s", method, error);
        return (u32)ws_send_soap_error(ws_env, err_info);
    }

    /* 建立管道,准备向web service发送信息 */
    (void)pipe((int *)file_to_ws);
    /* 建立管道,准备向从web service接收信息 */
    (void)pipe((int *)file_from_ws);

    /* 通知web service要执行的方法,格式形如<ws:getSegmentById/> */
    pchar = "<ws:";
    ret = (u_int32_t)write(file_to_ws[1], pchar, strlen(pchar));
    pchar = method;
    write(file_to_ws[1], pchar, strlen(pchar));
//    pchar = "/>";
    // <nop/>用于表示参数,让gsoap可以正常处理
    pchar = "><nop/></ws:";
    write(file_to_ws[1], pchar, strlen(pchar));

    pchar = method;
    write(file_to_ws[1], pchar, strlen(pchar));
    pchar = ">";
    write(file_to_ws[1], pchar, strlen(pchar));
    
    close(file_to_ws[1]);

    /* 准备执行web service */
    ws_begin_exe(ws_env);

    /* 设置web service执行时的输入输出流 */
    ws_env->recvfd = file_to_ws[0];
    ws_env->sendfd = file_from_ws[1];

    /* 生成内部执行环境 */
    // memset(internal_env, 0, sizeof(WS_INTERNAL_ENV)); 不能清0,只能做自己的赋值
    internal_env->internal_run = BOOL_TRUE;
    internal_env->ws_req_res = ws_req_res;
    /* web service执行环境挂入内部执行环境 */
    ws_plug_intl_env(ws_env, internal_env);

    /* 执行 web service */
    ret = (u_int32_t)soap_serve_request(ws_env);
    if (WS_OK != ret)
    {
          soap_set_fault(ws_env);
          ret = WS_OK;
    }

    /* 关闭web service输入流 */
    close(file_from_ws[1]);
	close(file_from_ws[0]);
	close(file_to_ws[0]);

    ws_env->user = NULL;
    return ret;
}
Example #7
0
void process_requests(int server_s, struct soap *soap)/*by SeanHou*/
{
    /* :TODO:Monday, December 01, 2014 11:17:36 HKT:SeanHou:  */
    int OnvifEN = 0;
    int lookupindex = 0;
    char service_uri[100] = "";

    memset((void*)&soap->peer, 0, sizeof(soap->peer));
    soap->socket = SOAP_INVALID_SOCKET;
    soap->error  = SOAP_OK;
    soap->errmode = 0;
    soap->keep_alive = 0;

    fprintf(stderr, "Warning:" \
            "(==>%s).\n", __func__);

    /* :TODO:End---  */
    int retval = 0;
    request *current, *trailer;

    if (pending_requests) {
        get_request(server_s);
#ifdef ORIGINAL_BEHAVIOR
        pending_requests = 0;
#endif
    }

    current = request_ready;

    while (current) {
        /* :TODO:Monday, December 01, 2014 11:18:42 HKT:SeanHou: juge is onvif */
        OnvifEN = isonvif(current->client_stream, service_uri, &lookupindex);
        if(OnvifEN == 1)
        {
            fprintf(stderr, "[boa:onvif] Warning: is onvif line[%d]remote port[%d]h2ns[%d]remote ip[%s]\n", __LINE__, current->remote_port, htons(current->remote_port), current->remote_ip_addr);
            struct sockaddr_in onvif_client_addr;
            memset(&onvif_client_addr, 0, sizeof(onvif_client_addr));
            onvif_client_addr.sin_family = AF_INET;
            onvif_client_addr.sin_port = htons(current->remote_port);//随机端口
            onvif_client_addr.sin_addr.s_addr = inet_addr(current->remote_ip_addr);//

            soap->socket = current->fd;
            soap->peer = onvif_client_addr;
            if (soap_valid_socket(soap->socket))
            {
                soap->ip = ntohl(soap->peer.sin_addr.s_addr);
                soap->port = (int)ntohs(soap->peer.sin_port);
                soap->keep_alive = (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) != 0);
            }


            g_onvif_buffer = (char *)soap_malloc(soap, sizeof(current->client_stream));
            strcpy(g_onvif_buffer, current->client_stream);//mark

            soap_begin_recv(soap);
            if (soap_envelope_begin_in(soap))
            {
                soap_send_fault(soap);
            }
            if (soap_recv_header(soap))
            {
                soap_send_fault(soap);
            }
            if (soap_body_begin_in(soap))
            {
                soap_send_fault(soap);
            }

            int errorCode = 0;
            if (errorCode = soap_serve_request(soap))
            {
                fprintf(stderr, "[boa:onvif]soap_serve_request fail, errorCode %d \n", errorCode);
                soap_send_fault(soap);
            }

            memset(current->client_stream, 0, CLIENT_STREAM_SIZE );

            soap_dealloc(soap, NULL);
            soap_destroy(soap);      
            soap_end(soap);
            current->status = DONE;
            close(soap->socket);
            continue;
        }
        /* :TODO:End---  */
        time(&current_time);
        if (current->buffer_end && /* there is data in the buffer */
                current->status != DEAD && current->status != DONE) {
            retval = req_flush(current);
            /*
             * retval can be -2=error, -1=blocked, or bytes left
             */
            if (retval == -2) { /* error */
                current->status = DEAD;
                retval = 0;
            } else if (retval >= 0) {
                /* notice the >= which is different from below?
                   Here, we may just be flushing headers.
                   We don't want to return 0 because we are not DONE
                   or DEAD */

                retval = 1;
            }
        } else {
            switch (current->status) {
                case READ_HEADER:
                case ONE_CR:
                case ONE_LF:
                case TWO_CR:
                    retval = read_header(current);
                    break;
                case BODY_READ:
                    retval = read_body(current);
                    break;
                case BODY_WRITE:
                    retval = write_body(current);
                    break;
                case WRITE:
                    retval = process_get(current);
                    break;
                case PIPE_READ:
                    retval = read_from_pipe(current);
                    break;
                case PIPE_WRITE:
                    retval = write_from_pipe(current);
                    break;
                case DONE:
                    /* a non-status that will terminate the request */
                    retval = req_flush(current);
                    /*
                     * retval can be -2=error, -1=blocked, or bytes left
                     */
                    if (retval == -2) { /* error */
                        current->status = DEAD;
                        retval = 0;
                    } else if (retval > 0) {
                        retval = 1;
                    }
                    break;
                case DEAD:
                    retval = 0;
                    current->buffer_end = 0;
                    SQUASH_KA(current);
                    break;
                default:
                    retval = 0;
                    fprintf(stderr, "Unknown status (%d), "
                            "closing!\n", current->status);
                    current->status = DEAD;
                    break;
            }

        }

        if (sigterm_flag)
            SQUASH_KA(current);

        /* we put this here instead of after the switch so that
         * if we are on the last request, and get_request is successful,
         * current->next is valid!
         */
        if (pending_requests)
            get_request(server_s);

        switch (retval) {
            case -1:               /* request blocked */
                trailer = current;
                current = current->next;
                block_request(trailer);
                break;
            case 0:                /* request complete */
                current->time_last = current_time;
                trailer = current;
                current = current->next;
                free_request(&request_ready, trailer);
                break;
            case 1:                /* more to do */
                current->time_last = current_time;
                current = current->next;
                break;
            default:
                log_error_time();
                fprintf(stderr, "Unknown retval in process.c - "
                        "Status: %d, retval: %d\n", current->status, retval);
                current = current->next;
                break;
        }
    }
}