Example #1
0
int nth_request_treply(nth_request_t *req,
		       int status, char const *phrase,
		       tag_type_t tag, tag_value_t value, ...)
{
  msg_t *response, *next = NULL;
  http_t *http;
  int retval = -1;
  int req_close, close;
  ta_list ta;
  http_header_t const *as_info = NULL;

  if (req == NULL || status < 100 || status >= 600) {
    return -1;
  }

  response = req->req_response;
  http = http_object(response);

  if (status >= 200 && req->req_as)
    as_info = (http_header_t const *)req->req_as->as_info;

  ta_start(ta, tag, value);

  http_add_tl(response, http,
	      HTTPTAG_SERVER(req->req_server->srv_server),
	      HTTPTAG_HEADER(as_info),
	      ta_tags(ta));

  if (http->http_payload && !http->http_content_length) {
    http_content_length_t *l;
    http_payload_t *pl;
    size_t len = 0;

    for (pl = http->http_payload; pl; pl = pl->pl_next)
      len += pl->pl_len;

    if (len > UINT32_MAX)
      goto fail;

    l = http_content_length_create(msg_home(response), (uint32_t)len);

    msg_header_insert(response, (msg_pub_t *)http, (msg_header_t *)l);
  }

  if (req->req_method == http_method_head && http->http_payload) {
    http_payload_t *pl;

    for (pl = http->http_payload; pl; pl = pl->pl_next)
      msg_header_remove(response, (msg_pub_t *)http, (msg_header_t *)pl);
  }

  http_complete_response(response, status, phrase,
			 http_object(req->req_request));

  if (!http->http_date) {
    http_date_t date[1];
    http_date_init(date)->d_time = msg_now();
    msg_header_add_dup(response, (msg_pub_t *)http, (msg_header_t*)date);
  }

  if (status < 200) {
    close = 0;
    next = server_msg_create(req->req_server, 0, NULL, 0, NULL, NULL);
  }
  else {
    req_close = req->req_close;

    close = (http->http_connection &&
	     msg_params_find(http->http_connection->k_items, "close"));

    if (req_close && !close && status >= 200) {
      close = 1;
      http_add_tl(response, http, HTTPTAG_CONNECTION_STR("close"), TAG_END());
    }
  }

  msg_serialize(response, (msg_pub_t *)http);

  retval = tport_tqsend(req->req_tport, response, next,
			TAG_IF(close, TPTAG_CLOSE_AFTER(1)),
			ta_tags(ta));

 fail:
  ta_end(ta);

  if (retval == 0)
    req->req_status = status;

  return retval;
}
Example #2
0
/** Process incoming request message */
static
void server_request(server_t *srv,
		    tport_t *tport,
		    msg_t *request,
		    void *arg,
		    su_time_t now)
{
  nth_site_t *site = NULL, *subsite = NULL;
  msg_t *response;
  http_t *http = http_object(request);
  http_host_t *h;
  char const *host, *port, *path, *subpath = NULL;

  /* Disable streaming */
  if (msg_is_streaming(request)) {
    msg_set_streaming(request, (enum msg_streaming_status)0);
    return;
  }

  /* Create a response message */
  response = server_msg_create(srv, 0, NULL, 0, NULL, NULL);
  tport_tqueue(tport, response, TAG_END());

  if (http && http->http_flags & MSG_FLG_TIMEOUT) {
    server_reply(srv, tport, request, response, 400, "Request timeout");
    return;
  } else if (http && http->http_flags & MSG_FLG_TOOLARGE) {
    server_reply(srv, tport, request, response, HTTP_413_ENTITY_TOO_LARGE);
    return;
  } else if (!http || !http->http_request ||
	     (http->http_flags & MSG_FLG_ERROR)) {
    server_reply(srv, tport, request, response, HTTP_400_BAD_REQUEST);
    return;
  }

  if (http->http_request->rq_version != http_version_1_0 &&
      http->http_request->rq_version != http_version_1_1) {
    server_reply(srv, tport, request, response, HTTP_505_HTTP_VERSION);
    return;
  }

  h = http->http_host;

  if (h) {
    host = h->h_host, port = h->h_port;
  }
  else if (http->http_request->rq_url->url_host) {
    host = http->http_request->rq_url->url_host;
    port = http->http_request->rq_url->url_port;
  }
  else
    host = NULL, port = NULL;

  path = http->http_request->rq_url->url_path;

  if (host)
    site = *site_get_host(&srv->srv_sites, host, port);

  if (site == NULL && !srv->srv_sites->site_strict)
    site = srv->srv_sites;

  if (path == NULL)
    path = "";

  if (path[0])
    subsite = site_get_subdir(site, path, &subpath);

  if (subsite)
    subsite->site_access = now;
  else
    site->site_access = now;

  if (subsite && subsite->site_isdir && subpath == site_nodir_match) {
    /* Answer with 301 */
    http_location_t loc[1];
    http_location_init(loc);

    *loc->loc_url = *site->site_url;

    if (site->site_wildcard) {
      if (http->http_host) {
	loc->loc_url->url_host = http->http_host->h_host;
	loc->loc_url->url_port = http->http_host->h_port;
      }
      else {
	tp_name_t const *tpn = tport_name(tport); assert(tpn);
	loc->loc_url->url_host = tpn->tpn_canon;
	if (strcmp(url_port_default((enum url_type_e)loc->loc_url->url_type), tpn->tpn_port))
	  loc->loc_url->url_port = tpn->tpn_port;
      }
    }

    loc->loc_url->url_root = 1;
    loc->loc_url->url_path = subsite->site_url->url_path;

    msg_header_add_dup(response, NULL, (msg_header_t *)loc);

    server_reply(srv, tport, request, response, HTTP_301_MOVED_PERMANENTLY);
  }
  else if (subsite)
    nth_site_request(srv, subsite, tport, request, http, subpath, response);
  else if (site)
    nth_site_request(srv, site, tport, request, http, path, response);
  else
    /* Answer with 404 */
    server_reply(srv, tport, request, response, HTTP_404_NOT_FOUND);
}
Example #3
0
static
int
handle_msg(il_octet_string_t *event, long offset)
{
	struct server_msg *msg = NULL;
#if !defined(IL_NOTIFICATIONS)
	struct event_queue *eq_l;
#endif
	struct event_queue *eq_s;
	struct event_store *es;

	int ret;

	/* convert event to message for server */
	if((msg = server_msg_create(event, offset)) == NULL) {
		glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_WARN, 
				 "    handle_msg: error parsing event '%s': %s", 
				 event->data, error_get_msg());
		return(0);
	}

	/* sync event store with IPC (if neccessary)
	 * This MUST be called before inserting event into output queue! */
	if((es = event_store_find(msg->job_id_s, NULL)) == NULL)
		return(-1);
	msg->es = es;

#ifdef LB_PERF
	if(nosync)
		ret = 1;
	else
#endif
		ret = event_store_sync(es, offset);
	/* no longer informative:
	il_log(LOG_DEBUG, "  syncing event store at %d with event at %d, result %d\n", es->offset, offset, ret);
	*/
	if(ret < 0) {
		glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_ERROR, 
				 "    handle_msg: error syncing event store: %s", 
				 error_get_msg());
		/* XXX should error during event store recovery cause us to drop the message? */
		/* Probably no, because the attempt to recover means we have missed some events,
		   and delivery of this one will not move offset ahead. So try our best and deliver it
		   even if it may cause duplicates on server. */
		/* COMMENTED OUT: uncommented again */
		server_msg_free(msg);
		event_store_release(es);
		return(0);
		/* */
	} else if(ret == 0) {
		/* we have seen this event already */
		server_msg_free(msg);
		event_store_release(es);
		return(1);
	}

	/* find apropriate queue for this event */
#if defined(IL_NOTIFICATIONS)
	eq_s = queue_list_get(msg->dest);
#else
	eq_s = queue_list_get(msg->job_id_s);
#endif
	if(eq_s == NULL) {
		glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_ERROR, 
				 "    handle_msg: apropriate queue not found: %s", 
				 error_get_msg());
		clear_error();
	} else {
		if(enqueue_msg(eq_s, msg) < 0)
			goto err;
	}

#if !defined(IL_NOTIFICATIONS)
	eq_l = queue_list_get(NULL);
	if(!bs_only && eq_l != eq_s) {
		/* send to default queue (logging server) as well */
		if(enqueue_msg(eq_l, msg) < 0)
			goto err;
	}
#endif

	/* if there was no error, set the next expected event offset */
	event_store_next(es, offset, msg->ev_len);

	/* allow cleanup thread to check on this event_store */
	event_store_release(es);

	/* free the message */
	server_msg_free(msg);
	return(1);

err:
	event_store_release(es);
	server_msg_free(msg);
	return(-1);
}