示例#1
0
void client_handler(client_t* client) {
	int ret;

	assert(client->fired_event != NULL);

	// Two stages
	// First, read HTTP request, interested in readable event
	if (client->stage == CS_READ_REQUEST) {
		if (client->fired_event->filter == EVFILT_READ) {
			ret = parse_http_request(client);
			if (ret) goto close;

			ret = generate_http_response(client);
			if (ret) goto close;

			client->stage = CS_WRITE_RESPONSE;
		}
	}
	// Then, write HTTP response, interested in writable event
	else if (client->stage == CS_WRITE_RESPONSE) {
		if (client->fired_event->filter == EVFILT_WRITE) {
			ret = write_http_response(client,
					client->fired_event->data);
			// When it went wrong or just finished correctly,
			// close the client
			if (ret) goto close;
		}
	}

	// Clear the event since it has been handled
	client->fired_event = NULL;
	return;
close:
	close_client(client);
}
示例#2
0
static int mod_mapcache_request_handler(request_rec *r)
{
  apr_table_t *params;
  mapcache_request *request = NULL;
  mapcache_context_apache_request *apache_ctx = NULL;
  mapcache_http_response *http_response = NULL;
  mapcache_context *global_ctx =  NULL;

  if (!r->handler || strcmp(r->handler, "mapcache")) {
    return DECLINED;
  }
  if (r->method_number != M_GET) {
    return HTTP_METHOD_NOT_ALLOWED;
  }


  apache_ctx = apache_request_context_create(r);
  global_ctx = (mapcache_context*)apache_ctx;

  params = mapcache_http_parse_param_string(global_ctx, r->args);

  mapcache_service_dispatch_request(global_ctx,&request,r->path_info,params,global_ctx->config);
  if(GC_HAS_ERROR(global_ctx) || !request) {
    return write_http_response(apache_ctx,
                               mapcache_core_respond_to_error(global_ctx));
  }

  if(request->type == MAPCACHE_REQUEST_GET_CAPABILITIES) {
    mapcache_request_get_capabilities *req_caps = (mapcache_request_get_capabilities*)request;
    request_rec *original;
    char *url;
    if(r->main)
      original = r->main;
    else
      original = r;
    url = ap_construct_url(r->pool,original->uri,original);

    /*
     * remove the path_info from the end of the url (we want the url of the base of the service)
     * TODO: is there an apache api to access this ?
     */
    if(*(original->path_info) && strcmp(original->path_info,"/")) {
      char *end = strstr(url,original->path_info);
      if(end) {
        /* make sure our url ends with a single '/' */
        if(*end == '/') {
          char *slash = end;
          while((*(--slash))=='/') end--;
          end++;
        }
        *end = '\0';
      }
    }
    http_response = mapcache_core_get_capabilities(global_ctx,request->service,req_caps,
                    url,original->path_info,global_ctx->config);
  } else if( request->type == MAPCACHE_REQUEST_GET_TILE) {
    mapcache_request_get_tile *req_tile = (mapcache_request_get_tile*)request;
    http_response = mapcache_core_get_tile(global_ctx,req_tile);
  } else if( request->type == MAPCACHE_REQUEST_PROXY ) {
    mapcache_request_proxy *req_proxy = (mapcache_request_proxy*)request;
    http_response = mapcache_core_proxy_request(global_ctx, req_proxy);
  } else if( request->type == MAPCACHE_REQUEST_GET_MAP) {
    mapcache_request_get_map *req_map = (mapcache_request_get_map*)request;
    http_response = mapcache_core_get_map(global_ctx,req_map);
  } else if( request->type == MAPCACHE_REQUEST_GET_FEATUREINFO) {
    mapcache_request_get_feature_info *req_fi = (mapcache_request_get_feature_info*)request;
    http_response = mapcache_core_get_featureinfo(global_ctx,req_fi);
  } else {
    global_ctx->set_error(global_ctx,500,"###BUG### unknown request type");
  }

  if(GC_HAS_ERROR(global_ctx)) {
    return write_http_response(apache_ctx,
                               mapcache_core_respond_to_error(global_ctx));
  }
  return write_http_response(apache_ctx,http_response);
}
示例#3
0
static int mod_mapcache_request_handler(request_rec *r)
{
  apr_table_t *params;
  mapcache_request *request = NULL;
  mapcache_context_apache_request *apache_ctx = NULL;
  mapcache_http_response *http_response = NULL;
  mapcache_context *global_ctx =  NULL;

  if (!r->handler || strcmp(r->handler, "mapcache")) {
    return DECLINED;
  }
  if (r->method_number != M_GET && r->method_number != M_POST) {
    return HTTP_METHOD_NOT_ALLOWED;
  }


  apache_ctx = apache_request_context_create(r);
  global_ctx = (mapcache_context*)apache_ctx;
  global_ctx->supports_redirects = 1;
  global_ctx->headers_in = r->headers_in;

  params = mapcache_http_parse_param_string(global_ctx, r->args);

  mapcache_service_dispatch_request(global_ctx,&request,r->path_info,params,global_ctx->config);
  if(GC_HAS_ERROR(global_ctx) || !request) {
    return write_http_response(apache_ctx,
                               mapcache_core_respond_to_error(global_ctx));
  }

  if(request->type == MAPCACHE_REQUEST_GET_CAPABILITIES) {
    mapcache_request_get_capabilities *req_caps = (mapcache_request_get_capabilities*)request;
    request_rec *original;
    char *url;
    if(r->main)
      original = r->main;
    else
      original = r;
    url = ap_construct_url(r->pool,original->uri,original);

    /*
     * remove the path_info from the end of the url (we want the url of the base of the service)
     * TODO: is there an apache api to access this ?
     */
    if(*(original->path_info) && strcmp(original->path_info,"/")) {
      char *end = strstr(url,original->path_info);
      if(end) {
        /* make sure our url ends with a single '/' */
        if(*end == '/') {
          char *slash = end;
          while((*(--slash))=='/') end--;
          end++;
        }
        *end = '\0';
      }
    }
    http_response = mapcache_core_get_capabilities(global_ctx,request->service,req_caps,
                    url,original->path_info,global_ctx->config);
  } else if( request->type == MAPCACHE_REQUEST_GET_TILE) {
    mapcache_request_get_tile *req_tile = (mapcache_request_get_tile*)request;
    http_response = mapcache_core_get_tile(global_ctx,req_tile);
  } else if( request->type == MAPCACHE_REQUEST_PROXY ) {
    const char *buf;
    mapcache_request_proxy *req_proxy = (mapcache_request_proxy*)request;
    if(r->method_number == M_POST) {
      read_post_body(apache_ctx, req_proxy);
      if(GC_HAS_ERROR(global_ctx)) {
        return write_http_response(apache_ctx, mapcache_core_respond_to_error(global_ctx));
      }
      if(!req_proxy->headers) {
        req_proxy->headers = apr_table_make(global_ctx->pool, 2);
      }
      apr_table_set(req_proxy->headers, "Content-Type", r->content_type);
      if((buf = apr_table_get(r->headers_in,"X-Forwarded-For"))) {
#if (AP_SERVER_MAJORVERSION_NUMBER == 2) && (AP_SERVER_MINORVERSION_NUMBER < 4)
        apr_table_set(req_proxy->headers, "X-Forwarded-For", apr_psprintf(global_ctx->pool,"%s, %s", buf, r->connection->remote_ip));
#else
        apr_table_set(req_proxy->headers, "X-Forwarded-For", apr_psprintf(global_ctx->pool,"%s, %s", buf, r->connection->client_ip));
#endif
      } else {
#if (AP_SERVER_MAJORVERSION_NUMBER == 2) && (AP_SERVER_MINORVERSION_NUMBER < 4)
        apr_table_set(req_proxy->headers, "X-Forwarded-For", r->connection->remote_ip);
#else
        apr_table_set(req_proxy->headers, "X-Forwarded-For", r->connection->client_ip);
#endif
      }
      if ((buf = apr_table_get(r->headers_in, "Host"))) {
        const char *buf2;
        if((buf2 = apr_table_get(r->headers_in,"X-Forwarded-Host"))) {
          apr_table_set(req_proxy->headers, "X-Forwarded-Host", apr_psprintf(global_ctx->pool,"%s, %s",buf2,buf));
        } else {
          apr_table_set(req_proxy->headers, "X-Forwarded-Host", buf);
        }
      }
      
      if ((buf = apr_table_get(r->headers_in, "X-Forwarded-Server"))) {
        apr_table_set(req_proxy->headers, "X-Forwarded-Server", apr_psprintf(global_ctx->pool, "%s, %s", buf, r->server->server_hostname));
      } else {
        apr_table_set(req_proxy->headers, "X-Forwarded-Server", r->server->server_hostname);
      }
    }
    http_response = mapcache_core_proxy_request(global_ctx, req_proxy);
  } else if( request->type == MAPCACHE_REQUEST_GET_MAP) {
    mapcache_request_get_map *req_map = (mapcache_request_get_map*)request;
    http_response = mapcache_core_get_map(global_ctx,req_map);
  } else if( request->type == MAPCACHE_REQUEST_GET_FEATUREINFO) {
    mapcache_request_get_feature_info *req_fi = (mapcache_request_get_feature_info*)request;
    http_response = mapcache_core_get_featureinfo(global_ctx,req_fi);
  } else {
    global_ctx->set_error(global_ctx,500,"###BUG### unknown request type");
  }

  if(GC_HAS_ERROR(global_ctx)) {
    return write_http_response(apache_ctx,
                               mapcache_core_respond_to_error(global_ctx));
  }
  return write_http_response(apache_ctx,http_response);
}
示例#4
0
  void http_session::read_http_header()
  {
    auto self = shared_from_this();
    // read until CRLFCRLF -> end of http header
    boost::asio::async_read_until(_socket, _buffer_request, HTTP_HEADER_END, [this, self](boost::system::error_code ec, std::size_t length)
    {
      if (!ec)
      {
        size_t content_length = 0;
        
        std::istream is(&_buffer_request);
        std::string line;
        std::getline(is, line);
        size_t sep1 = line.find(" ");
        size_t sep2 = line.find(" ", sep1 + 1);
        if (sep1 == std::string::npos || sep2 == std::string::npos)
        {
          LOG_ERROR << "invalid request " << line;
          _connection_close = true;
          write_http_response(HTTP_CODE_BAD_REQUEST);
          return;
        }
        _method = line.substr(0, sep1);
        _uri = line.substr(sep1 + 1, sep2 - sep1 - 1);
        _version = line.substr(sep2 + 1, line.size() - 1); // without \r at the end !
        LOG_DEBUG << "request " << _method << " " << _uri << " " << _version;
        
        if (_version == HTTP_VERSION_10)
        {
          _connection_close = true;
          LOG_DEBUG << HTTP_VERSION_10 " -> connection close";
        }

        while (std::getline(is, line) && line.size() > 1) // more than just \r in line
        {
          // iterate over all headers
          size_t pos_separator = line.find(": ");
          if (pos_separator == std::string::npos)
          {
            LOG_ERROR << "invalid header " << line;
            _connection_close = true;
            write_http_response(HTTP_CODE_BAD_REQUEST);
            return;
          }
          line[pos_separator] = 0; // put \0 in place of the : separator
          line[line.size() - 1] = 0; // put \0 in place of the \r at the end
          size_t pos_separator_params = line.find("; ");
          if (pos_separator_params != std::string::npos)
          {
            line[pos_separator_params] = 0; // put \0 in place of the ; separator
          }
          char* attr_name = &line[0];
          char* attr_value = &line[pos_separator + 2];
          if (strncmp(attr_name, HTTP_HEADER_CONTENT_LENGTH, sizeof(HTTP_HEADER_CONTENT_LENGTH)) == 0)
          {
            content_length = atol(attr_value);
            LOG_DEBUG << "content length " << content_length;
          }
          else if (strncmp(attr_name, HTTP_HEADER_CONNECTION, sizeof(HTTP_HEADER_CONNECTION)) == 0 &&
                   strncmp(attr_value, HTTP_HEADER_CONNECTION_CLOSE, sizeof(HTTP_HEADER_CONNECTION_CLOSE)) == 0)
          {
            _connection_close = true;
            LOG_DEBUG << "connection close header";
          }
          else if (strncmp(attr_name, HTTP_HEADER_CONTENT_TYPE, sizeof(HTTP_HEADER_CONTENT_TYPE)) == 0)
          {
            LOG_DEBUG << "content type raw " << attr_value;
            if (strncmp(attr_value, HTTP_HEADER_CONTENT_TYPE_JSON, sizeof(HTTP_HEADER_CONTENT_TYPE_JSON)) == 0)
            {
              _content_type = CONTENT_TYPE_JSON;
            }
            else if (strncmp(attr_value, HTTP_HEADER_CONTENT_TYPE_TEXT, sizeof(HTTP_HEADER_CONTENT_TYPE_TEXT)) == 0)
            {
              _content_type = CONTENT_TYPE_TEXT;
            }
            else if (strncmp(attr_value, HTTP_HEADER_CONTENT_TYPE_XML, sizeof(HTTP_HEADER_CONTENT_TYPE_XML)) == 0)
            {
              _content_type = CONTENT_TYPE_XML;
            }
            else
            {
              _content_type = CONTENT_TYPE_OTHER;
            }
            LOG_DEBUG << "body content type " << _content_type;
          }
        }
        
        read_http_body(content_length);
      }
      else
      {
        LOG_ERROR << "error while reading http header " << ec;
      }
    });
  }