Пример #1
0
int ec_responce_with_istag(ci_request_t * req, int ec)
{
     char buf[256];
     ci_service_xdata_t *srv_xdata;
     int len;
     srv_xdata = service_data(req->current_service_mod);
     ci_headers_reset(req->response_header);
     snprintf(buf, 256, "ICAP/1.0 %d %s",
              ci_error_code(ec), ci_error_code_string(ec));
     ci_headers_add(req->response_header, buf);
     ci_headers_add(req->response_header, "Server: C-ICAP/" VERSION);
     if (req->keepalive)
          ci_headers_add(req->response_header, "Connection: keep-alive");
     else
          ci_headers_add(req->response_header, "Connection: close");

     ci_service_data_read_lock(srv_xdata);
     ci_headers_add(req->response_header, srv_xdata->ISTag);
     ci_service_data_read_unlock(srv_xdata);
     if (!ci_headers_is_empty(req->xheaders)) {
	  ci_headers_addheaders(req->response_header, req->xheaders);
     }
     ci_headers_pack(req->response_header);

     len = ci_write(req->connection->fd, 
		    req->response_header->buf, req->response_header->bufused, 
		    TIMEOUT);
     if (len < 0)
	 return -1;

     req->bytes_out += len;
     return len;
}
Пример #2
0
int mk_responce_header(ci_request_t * req)
{
     ci_headers_list_t *head;
     ci_encaps_entity_t **e_list;
     ci_service_xdata_t *srv_xdata;
     char buf[512];
     srv_xdata = service_data(req->current_service_mod);
     ci_headers_reset(req->response_header);
     head = req->response_header;
     ci_headers_add(head, "ICAP/1.0 200 OK");
     ci_headers_add(head, "Server: C-ICAP/" VERSION);
     if (req->keepalive)
          ci_headers_add(head, "Connection: keep-alive");
     else
          ci_headers_add(head, "Connection: close");
     ci_service_data_read_lock(srv_xdata);
     ci_headers_add(head, srv_xdata->ISTag);
     ci_service_data_read_unlock(srv_xdata);
     if (!ci_headers_is_empty(req->xheaders)) {
          ci_headers_addheaders(head, req->xheaders);
     }

     e_list = req->entities;
     if (req->type == ICAP_RESPMOD) {
          if (e_list[0]->type == ICAP_REQ_HDR) {
               ci_request_release_entity(req, 0);
               e_list[0] = e_list[1];
               e_list[1] = e_list[2];
               e_list[2] = NULL;
          }
     }

     snprintf(buf, 512, "Via: ICAP/1.0 %s (C-ICAP/" VERSION " %s )",
              MY_HOSTNAME,
              (req->current_service_mod->mod_short_descr ? req->
               current_service_mod->mod_short_descr : req->current_service_mod->
               mod_name));
     buf[511] = '\0';
     /*Here we must append it to an existsing Via header not just add a new header */
     if (req->type == ICAP_RESPMOD) {
          ci_http_response_add_header(req, buf);
     }
     else if (req->type == ICAP_REQMOD) {
          ci_http_request_add_header(req, buf);
     }

     ci_response_pack(req);
     return 1;
}
Пример #3
0
void options_responce(ci_request_t * req)
{
     char buf[MAX_HEADER_SIZE + 1];
     char *str;
     ci_headers_list_t *head;
     ci_service_xdata_t *srv_xdata;
     unsigned int xopts;
     int preview, allow204, max_conns, xlen;
     head = req->response_header;
     srv_xdata = service_data(req->current_service_mod);
     ci_headers_reset(head);
     ci_headers_add(head, "ICAP/1.0 200 OK");
     strcpy(buf, "Methods: ");
     if (ci_method_support(req->current_service_mod->mod_type, ICAP_RESPMOD)) {
          strcat(buf, "RESPMOD");
          if (ci_method_support
              (req->current_service_mod->mod_type, ICAP_REQMOD)) {
               strcat(buf, ", REQMOD");
          }
     }
     else {                     /*At least one method must supported. A check for error must exists here..... */
          strcat(buf, "REQMOD");
     }

     ci_headers_add(head, buf);
     snprintf(buf, MAX_HEADER_SIZE, "Service: C-ICAP/" VERSION " server - %s",
              ((str =
                req->current_service_mod->mod_short_descr) ? str : req->
               current_service_mod->mod_name));
     buf[MAX_HEADER_SIZE] = '\0';
     ci_headers_add(head, buf);

     ci_service_data_read_lock(srv_xdata);
     ci_headers_add(head, srv_xdata->ISTag);
     if (srv_xdata->TransferPreview[0] != '\0')
          ci_headers_add(head, srv_xdata->TransferPreview);
     if (srv_xdata->TransferIgnore[0] != '\0')
          ci_headers_add(head, srv_xdata->TransferIgnore);
     if (srv_xdata->TransferComplete[0] != '\0')
          ci_headers_add(head, srv_xdata->TransferComplete);
     /*Get service options before close the lock.... */
     xopts = srv_xdata->xopts;
     preview = srv_xdata->preview_size;
     allow204 = srv_xdata->allow_204;
     max_conns = srv_xdata->max_connections;
     ci_service_data_read_unlock(srv_xdata);

     ci_debug_printf(5, "Options responce:\n"
		     " Preview :%d\n"
		     " Allow 204:%s\n"
		     " TransferPreview:\"%s\"\n"
		     " TransferIgnore:%s\n"
		     " TransferComplete:%s\n"
		     " Max-Connections:%d\n",
		     preview,(allow204?"yes":"no"),
		     srv_xdata->TransferPreview,
		     srv_xdata->TransferIgnore,
		     srv_xdata->TransferComplete,
		     max_conns
	             );

     /* ci_headers_add(head, "Max-Connections: 20"); */
     ci_headers_add(head, "Options-TTL: 3600");
     strcpy(buf, "Date: ");
     ci_strtime_rfc822(buf + strlen(buf));
     ci_headers_add(head, buf);
     if (preview >= 0) {
          sprintf(buf, "Preview: %d", srv_xdata->preview_size);
          ci_headers_add(head, buf);
     }
     if(max_conns > 0) {
	 sprintf(buf, "Max-Connections: %d", max_conns);
	 ci_headers_add(head, buf);
     }
     if (allow204) {
          ci_headers_add(head, "Allow: 204");
     }
     if (xopts) {
          strcpy(buf, "X-Include: ");
          xlen = 11;            /*sizeof("X-Include: ") */
          if ((xopts & CI_XCLIENTIP)) {
               strcat(buf, "X-Client-IP");
               xlen += sizeof("X-Client-IP");
          }
          if ((xopts & CI_XSERVERIP)) {
               if (xlen > 11) {
                    strcat(buf, ", ");
                    xlen += 2;
               }
               strcat(buf, "X-Server-IP");
               xlen += sizeof("X-Server-IP");
          }
          if ((xopts & CI_XSUBSCRIBERID)) {
               if (xlen > 11) {
                    strcat(buf, ", ");
                    xlen += 2;
               }
               strcat(buf, "X-Subscriber-ID");
               xlen += sizeof("X-Subscriber-ID");
          }
          if ((xopts & CI_XAUTHENTICATEDUSER)) {
               if (xlen > 11) {
                    strcat(buf, ", ");
                    xlen += 2;
               }
               strcat(buf, "X-Authenticated-User");
               xlen += sizeof("X-Authenticated-User");
          }
          if ((xopts & CI_XAUTHENTICATEDGROUPS)) {
               if (xlen > 11) {
                    strcat(buf, ", ");
                    xlen += 2;
               }
               strcat(buf, "X-Authenticated-Groups");
               xlen += sizeof("X-Authenticated-Groups");
          }
          if (xlen > 11)
               ci_headers_add(head, buf);
     }
     ci_response_pack(req);

     req->pstrblock_responce = head->buf;
     req->remain_send_block_bytes = head->bufused;

     do {
          if ((ci_wait_for_data(req->connection->fd, TIMEOUT, wait_for_write))
              <= 0) {
               ci_debug_printf(3, "Timeout sending data. Ending .......\n");
               return;
          }
          if (send_current_block_data(req) == CI_ERROR) {
               ci_debug_printf(3, "Error sending data. Ending .....\n");
               return;
          }
     } while (req->remain_send_block_bytes > 0);

//     if(responce_body)
//        send_body_responce(req,responce_body);

}
Пример #4
0
int process_request(ci_request_t * req)
{
    int res;
    ci_service_xdata_t *srv_xdata;
    res = do_request(req);
   
    if (!STATS)
        return res;

    if (res<0 && req->request_header->bufused == 0) /*Did not read anything*/
	return res;

    if (req->return_code == EC_404) {
        return res;
    }

    srv_xdata = service_data(req->current_service_mod);
    if (!srv_xdata) {
        ci_debug_printf(5, "Service not found, statistics not logged.");
        return res;
    }
	
    STATS_LOCK();
    if (STAT_REQUESTS >= 0) STATS_INT64_INC(STAT_REQUESTS,1);

    if (req->type == ICAP_REQMOD) {
      STATS_INT64_INC(STAT_REQMODS, 1);
      STATS_INT64_INC(srv_xdata->stat_reqmods, 1);
    }
    else if (req->type == ICAP_RESPMOD) {
      STATS_INT64_INC(STAT_RESPMODS, 1);
      STATS_INT64_INC(srv_xdata->stat_respmods, 1);
    }
    else if (req->type == ICAP_OPTIONS) {
      STATS_INT64_INC(STAT_OPTIONS, 1);
      STATS_INT64_INC(srv_xdata->stat_options, 1);
    }

    if (res <0 && STAT_FAILED_REQUESTS >= 0)
        STATS_INT64_INC(STAT_FAILED_REQUESTS,1);

    if (req->return_code == EC_204) {
      STATS_INT64_INC(STAT_ALLOW204, 1);
      STATS_INT64_INC(srv_xdata->stat_allow204, 1);
    }


    if (STAT_BYTES_IN >= 0) STATS_KBS_INC(STAT_BYTES_IN, req->bytes_in);
    if (STAT_BYTES_OUT >= 0) STATS_KBS_INC(STAT_BYTES_OUT, req->bytes_out);
    if (STAT_HTTP_BYTES_IN >= 0) STATS_KBS_INC(STAT_HTTP_BYTES_IN, req->http_bytes_in);
    if (STAT_HTTP_BYTES_OUT >= 0) STATS_KBS_INC(STAT_HTTP_BYTES_OUT, req->http_bytes_out);
    if (STAT_BODY_BYTES_IN >= 0) STATS_KBS_INC(STAT_BODY_BYTES_IN, req->body_bytes_in);
    if (STAT_BODY_BYTES_OUT >= 0) STATS_KBS_INC(STAT_BODY_BYTES_OUT, req->body_bytes_out);


    if (srv_xdata->stat_bytes_in >= 0) 
      STATS_KBS_INC(srv_xdata->stat_bytes_in, req->bytes_in);
    if (srv_xdata->stat_bytes_out >= 0) 
      STATS_KBS_INC(srv_xdata->stat_bytes_out, req->bytes_out);
    if (srv_xdata->stat_http_bytes_in >= 0) 
      STATS_KBS_INC(srv_xdata->stat_http_bytes_in, req->http_bytes_in);
    if (srv_xdata->stat_http_bytes_out >= 0) 
      STATS_KBS_INC(srv_xdata->stat_http_bytes_out, req->http_bytes_out);
    if (srv_xdata->stat_body_bytes_in >= 0) 
      STATS_KBS_INC(srv_xdata->stat_body_bytes_in, req->body_bytes_in);
    if (srv_xdata->stat_body_bytes_out >= 0) 
      STATS_KBS_INC(srv_xdata->stat_body_bytes_out, req->body_bytes_out);

    STATS_UNLOCK();

    return res;
}
Пример #5
0
/********************** Service aliases *****************************/
service_alias_t *add_service_alias(char *service_alias, char *service_name,
                                   char *args)
{
     ci_service_module_t *service = NULL;
     service_alias_t *salias = NULL;
     ci_service_xdata_t *xdata = NULL;

     int len = 0;
     int alias_indx = 0;
     if (service_aliases == NULL) {
          service_aliases = malloc(STEP * sizeof(service_alias_t));
          service_aliases_size = STEP;
     }
     else if (service_aliases_num == service_aliases_size) {
          service_aliases_size += STEP;
          service_aliases =
              realloc(service_aliases,
                      service_aliases_size * sizeof(service_alias_t));
     }

     if (service_aliases == NULL) {
          ci_debug_printf(1,
                          "add_service_alias: Error allocating memory. Exiting...\n");
          exit(-1);
     }

     service = find_service(service_name);
     if (!service) {
          salias = find_service_alias(service_name);
          if (!salias)
               return NULL;
          service = salias->service;
     }
     xdata = service_data(service);

     alias_indx = service_aliases_num;
     service_aliases_num++;
     service_aliases[alias_indx].service = service;
     strncpy(service_aliases[alias_indx].alias,
             service_alias, MAX_SERVICE_NAME);
     service_aliases[alias_indx].alias[MAX_SERVICE_NAME] = '\0';
     service_aliases[alias_indx].args[0] = '\0';
     if (salias) {
          len = strlen(salias->args);
          strcpy(service_aliases[alias_indx].args, salias->args);       /*we had check for len */
     }
     if (args && len) {
          service_aliases[alias_indx].args[len] = '&';
          len++;
     }
     if (args && MAX_SERVICE_ARGS - len > 0) {
          strcpy(service_aliases[alias_indx].args + len, args);
     }
     service_aliases[alias_indx].args[MAX_SERVICE_ARGS] = '\0';

     if (xdata->intl_srv_conf_table)
          register_conf_table(service_aliases[alias_indx].alias,
                              xdata->intl_srv_conf_table, ALIAS_TABLE);

     return &(service_aliases[alias_indx]);
}
Пример #6
0
void
configuration_t::parse_services_settings(const Json::Value& config_value) {
	const Json::Value services_list = config_value["services"];

	if (!services_list.isObject() || !services_list.size()) {
		std::string error_str = "\"services\" section is malformed, it must have at least one service defined, ";
		error_str += "see documentation for more info.";
		throw internal_error(error_str);
	}

	Json::Value::Members services_names(services_list.getMemberNames());
	for (Json::Value::Members::iterator it = services_names.begin(); it != services_names.end(); ++it) {
	    std::string service_name(*it);
	    Json::Value service_data(services_list[service_name]);

	    if (!service_data.isObject()) {
			std::string error_str = "\"service\" (with alias: " + service_name + ") is malformed, ";
			error_str += "see documentation for more info.";
			throw internal_error(error_str);
		}

	    service_info_t si;
		si.name = service_name;
		boost::trim(si.name);

	    if (si.name.empty()) {
	    	std::string error_str = "malformed \"service\" section found, alias must me non-empty string";
			throw internal_error(error_str);
	    }

	    si.description = service_data.get("description", "").asString();
	    boost::trim(si.description);

		si.app = service_data.get("app", "").asString();
		boost::trim(si.app);
		
		if (si.app.empty()) {
			std::string error_str = "malformed \"service\" " + si.name + " section found, field";
			error_str += "\"app\" must me non-empty string";
			throw internal_error(error_str);
		}

		// cocaine nodes autodiscovery
		const Json::Value autodiscovery = service_data["autodiscovery"];
		if (!autodiscovery.isObject()) {
			std::string error_str = "\"autodiscovery\" section for service " + service_name + " is malformed, ";
			error_str += "see documentation for more info.";
			throw internal_error(error_str);
		}

		si.hosts_source = autodiscovery.get("source", "").asString();
		boost::trim(si.hosts_source);

		if (si.hosts_source.empty()) {
			std::string error_str = "malformed \"service\" " + si.name + " section found, field";
			error_str += "\"source\" must me non-empty string";
			throw internal_error(error_str);
		}

		char* absolute_source_path = realpath(si.hosts_source.c_str(), NULL);
		if (NULL != absolute_source_path) {
    		si.hosts_source = absolute_source_path;
    	}

		std::string autodiscovery_type_str = autodiscovery.get("type", "").asString();

		if (autodiscovery_type_str == "FILE") {
			si.discovery_type = AT_FILE;
		}
		else if (autodiscovery_type_str == "HTTP") {
			si.discovery_type = AT_HTTP;
		}
		else if (autodiscovery_type_str == "MULTICAST") {
			si.discovery_type = AT_MULTICAST;
		}
		else {
			std::string error_str = "\"autodiscovery\" section for service " + service_name;
			error_str += " has malformed field \"type\", which can only take values FILE, HTTP, MULTICAST.";
			throw internal_error(error_str);
		}

		// default message policy
		const Json::Value mpolicy = service_data["policy"];
		if (mpolicy.isObject()) {
			si.policy.urgent = mpolicy.get("urgent", defaults_t::policy_urgent).asBool();
			si.policy.persistent = mpolicy.get("persistent", defaults_t::policy_persistent).asBool();
			si.policy.timeout = mpolicy.get("timeout", defaults_t::policy_chunk_timeout).asFloat();
			si.policy.ack_timeout = mpolicy.get("ack_timeout", defaults_t::policy_ack_timeout).asFloat();
			si.policy.deadline = mpolicy.get("deadline", defaults_t::policy_message_deadline).asFloat();
			si.policy.max_retries = mpolicy.get("max_retries", defaults_t::policy_max_retries).asInt();
		}

		// check for duplicate services
		std::map<std::string, service_info_t>::iterator lit = m_services_list.begin();
		for (;lit != m_services_list.end(); ++lit) {
			if (lit->second.name == si.name) {
				throw internal_error("duplicate service with name " + si.name + " was found in config!");
			}
		}

		m_services_list[si.name] = si;
	}
}