示例#1
0
/**
 * \brief Compare tribools for inequality
 *
 * \returns the result of comparing two tribool values for inequality,
 * according to the following table:
 *       <table border=1>
 *           <tr>
 *             <th><center><code>!=</code></center></th>
 *             <th><center>false</center></th>
 *             <th><center>true</center></th>
 *             <th><center>indeterminate</center></th>
 *           </tr>
 *           <tr>
 *             <th><center>false</center></th>
 *             <td><center>false</center></td>
 *             <td><center>true</center></td>
 *             <td><center>indeterminate</center></td>
 *           </tr>
 *           <tr>
 *             <th><center>true</center></th>
 *             <td><center>true</center></td>
 *             <td><center>false</center></td>
 *             <td><center>indeterminate</center></td>
 *           </tr>
 *           <tr>
 *             <th><center>indeterminate</center></th>
 *             <td><center>indeterminate</center></td>
 *             <td><center>indeterminate</center></td>
 *             <td><center>indeterminate</center></td>
 *           </tr>
 *       </table>
 * \throws nothrow
 */
inline tribool operator!=(tribool x, tribool y)
{
  if (indeterminate(x) || indeterminate(y))
    return indeterminate;
  else
    return !((x && y) || (!x && !y));
}
示例#2
0
文件: scs.c 项目: tkelman/scs
static void setSolution(Data * d, Work * w, Sol * sol, Info * info) {
	idxint l = d->n + d->m + 1;
	setx(d, w, sol);
	sety(d, w, sol);
	sets(d, w, sol);
	if (info->statusVal == 0 || info->statusVal == SOLVED) {
		pfloat tau = w->u[l - 1];
		pfloat kap = ABS(w->v[l - 1]);
		if (tau > INDETERMINATE_TOL && tau > kap) {
			info->statusVal = solved(d, sol, info, tau);
		} else {
			if (calcNorm(w->u, l) < INDETERMINATE_TOL * SQRTF((pfloat) l)) {
				info->statusVal = indeterminate(d, sol, info);
			} else {
				pfloat bTy = innerProd(d->b, sol->y, d->m);
				pfloat cTx = innerProd(d->c, sol->x, d->n);
				if (bTy < cTx) {
					info->statusVal = infeasible(d, sol, info);
				} else {
					info->statusVal = unbounded(d, sol, info);
				}
			}
		}
	} else if (info->statusVal == INFEASIBLE) {
		info->statusVal = infeasible(d, sol, info);
	} else {
		info->statusVal = unbounded(d, sol, info);
	}
}
示例#3
0
 TextWriter& operator()(const Enzymes& ezs)
 {
     (*this)("Enzymes: ");
     if (!indeterminate(ezs.independent))
         child()("independent: ", ezs.independent);
     if (!ezs.enzymes.empty())
         child()("enzymes: ", ezs.enzymes);
     return *this;
 }
示例#4
0
bool
IGameEngine::SwitchBit(const NBit::EId& bit,blo::tribool enable) {

//     switchBit( mBitSet[bit]);
//    return mBitSet[bit];

    if(indeterminate(enable)){

        mBitSet.flip(bit);// = !mBitSet[bit];
    }
    else {
        mBitSet.set(bit,enable);
    }

    return mBitSet[bit];
}
示例#5
0
void CSSSelector::extractPseudoType() const
{
    if (m_match != PseudoClass && m_match != PseudoElement)
        return;

    AtomicString active("active");
    AtomicString after("after");
    AtomicString anyLink("-webkit-any-link");
    AtomicString autofill("-webkit-autofill");
    AtomicString before("before");
    AtomicString checked("checked");
    AtomicString fileUploadButton("-webkit-file-upload-button");
    AtomicString disabled("disabled");
    AtomicString drag("-webkit-drag");
    AtomicString dragAlias("-khtml-drag"); // was documented with this name in Apple documentation, so keep an alias
    AtomicString empty("empty");
    AtomicString enabled("enabled");
    AtomicString firstChild("first-child");
    AtomicString firstLetter("first-letter");
    AtomicString firstLine("first-line");
    AtomicString firstOfType("first-of-type");
    AtomicString nthChild("nth-child(");
    AtomicString nthOfType("nth-of-type(");
    AtomicString nthLastChild("nth-last-child(");
    AtomicString nthLastOfType("nth-last-of-type(");
    AtomicString focus("focus");
    AtomicString hover("hover");
    AtomicString indeterminate("indeterminate");
    AtomicString lastChild("last-child");
    AtomicString lastOfType("last-of-type");
    AtomicString link("link");
    AtomicString lang("lang(");
    AtomicString mediaControlsPanel("-webkit-media-controls-panel");
    AtomicString mediaControlsMuteButton("-webkit-media-controls-mute-button");
    AtomicString mediaControlsPlayButton("-webkit-media-controls-play-button");
    AtomicString mediaControlsTimeDisplay("-webkit-media-controls-time-display");
    AtomicString mediaControlsTimeline("-webkit-media-controls-timeline");
    AtomicString mediaControlsSeekBackButton("-webkit-media-controls-seek-back-button");
    AtomicString mediaControlsSeekForwardButton("-webkit-media-controls-seek-forward-button");
    AtomicString mediaControlsFullscreenButton("-webkit-media-controls-fullscreen-button");
    AtomicString notStr("not(");
    AtomicString onlyChild("only-child");
    AtomicString onlyOfType("only-of-type");
    AtomicString root("root");
    AtomicString searchCancelButton("-webkit-search-cancel-button");
    AtomicString searchDecoration("-webkit-search-decoration");
    AtomicString searchResultsDecoration("-webkit-search-results-decoration");
    AtomicString searchResultsButton("-webkit-search-results-button");
    AtomicString selection("selection");
    AtomicString sliderThumb("-webkit-slider-thumb");
    AtomicString target("target");
    AtomicString visited("visited");

    bool element = false; // pseudo-element
    bool compat = false; // single colon compatbility mode

    m_pseudoType = PseudoUnknown;
    if (m_value == active)
        m_pseudoType = PseudoActive;
    else if (m_value == after) {
        m_pseudoType = PseudoAfter;
        element = true;
        compat = true;
    } else if (m_value == anyLink)
        m_pseudoType = PseudoAnyLink;
    else if (m_value == autofill)
        m_pseudoType = PseudoAutofill;
    else if (m_value == before) {
        m_pseudoType = PseudoBefore;
        element = true;
        compat = true;
    } else if (m_value == checked)
        m_pseudoType = PseudoChecked;
    else if (m_value == fileUploadButton) {
        m_pseudoType = PseudoFileUploadButton;
        element = true;
    } else if (m_value == disabled)
        m_pseudoType = PseudoDisabled;
    else if (m_value == drag || m_value == dragAlias)
        m_pseudoType = PseudoDrag;
    else if (m_value == enabled)
        m_pseudoType = PseudoEnabled;
    else if (m_value == empty)
        m_pseudoType = PseudoEmpty;
    else if (m_value == firstChild)
        m_pseudoType = PseudoFirstChild;
    else if (m_value == lastChild)
        m_pseudoType = PseudoLastChild;
    else if (m_value == lastOfType)
        m_pseudoType = PseudoLastOfType;
    else if (m_value == onlyChild)
        m_pseudoType = PseudoOnlyChild;
    else if (m_value == onlyOfType)
        m_pseudoType = PseudoOnlyOfType;
    else if (m_value == firstLetter) {
        m_pseudoType = PseudoFirstLetter;
        element = true;
        compat = true;
    } else if (m_value == firstLine) {
        m_pseudoType = PseudoFirstLine;
        element = true;
        compat = true;
    } else if (m_value == firstOfType)
        m_pseudoType = PseudoFirstOfType;
    else if (m_value == focus)
        m_pseudoType = PseudoFocus;
    else if (m_value == hover)
        m_pseudoType = PseudoHover;
    else if (m_value == indeterminate)
        m_pseudoType = PseudoIndeterminate;
    else if (m_value == link)
        m_pseudoType = PseudoLink;
    else if (m_value == lang)
        m_pseudoType = PseudoLang;
    else if (m_value == mediaControlsPanel) {
        m_pseudoType = PseudoMediaControlsPanel;
        element = true;
    } else if (m_value == mediaControlsMuteButton) {
        m_pseudoType = PseudoMediaControlsMuteButton;
        element = true;
    } else if (m_value == mediaControlsPlayButton) {
        m_pseudoType = PseudoMediaControlsPlayButton;
        element = true;
    } else if (m_value == mediaControlsTimeDisplay) {
        m_pseudoType = PseudoMediaControlsTimeDisplay;
        element = true;
    } else if (m_value == mediaControlsTimeline) {
        m_pseudoType = PseudoMediaControlsTimeline;
        element = true;
    } else if (m_value == mediaControlsSeekBackButton) {
        m_pseudoType = PseudoMediaControlsSeekBackButton;
        element = true;
    } else if (m_value == mediaControlsSeekForwardButton) {
        m_pseudoType = PseudoMediaControlsSeekForwardButton;
        element = true;
    } else if (m_value == mediaControlsFullscreenButton) {
        m_pseudoType = PseudoMediaControlsFullscreenButton;
        element = true;
    } else if (m_value == notStr)
        m_pseudoType = PseudoNot;
    else if (m_value == nthChild)
        m_pseudoType = PseudoNthChild;
    else if (m_value == nthOfType)
        m_pseudoType = PseudoNthOfType;
    else if (m_value == nthLastChild)
        m_pseudoType = PseudoNthLastChild;
    else if (m_value == nthLastOfType)
        m_pseudoType = PseudoNthLastOfType;
    else if (m_value == root)
        m_pseudoType = PseudoRoot;
    else if (m_value == searchCancelButton) {
        m_pseudoType = PseudoSearchCancelButton;
        element = true;
    } else if (m_value == searchDecoration) {
        m_pseudoType = PseudoSearchDecoration;
        element = true;
    } else if (m_value == searchResultsDecoration) {
        m_pseudoType = PseudoSearchResultsDecoration;
        element = true;
    } else if (m_value == searchResultsButton) {
        m_pseudoType = PseudoSearchResultsButton;
        element = true;
    }  else if (m_value == selection) {
        m_pseudoType = PseudoSelection;
        element = true;
    } else if (m_value == sliderThumb) {
        m_pseudoType = PseudoSliderThumb;
        element = true;
    } else if (m_value == target)
        m_pseudoType = PseudoTarget;
    else if (m_value == visited)
        m_pseudoType = PseudoVisited;

    if (m_match == PseudoClass && element) {
        if (!compat)
            m_pseudoType = PseudoUnknown;
        else
            m_match = PseudoElement;
    } else if (m_match == PseudoElement && !element)
        m_pseudoType = PseudoUnknown;
}
示例#6
0
        std::tuple<
          boost::logic::tribool,
          boost::iterator_range<typename Range::const_iterator>>
          parse_until(state_t stop_state,
                      const Range& range_) {
          boost::logic::tribool parsed_ok(boost::logic::indeterminate);
          typename Range::const_iterator start = boost::begin(range_),
            current = start,
            end = boost::end(range_);
          boost::iterator_range<typename Range::const_iterator> local_range =
            boost::make_iterator_range(start, end);
          if (boost::empty(local_range))
            parsed_ok = false;
          while (!boost::empty(local_range) && indeterminate(parsed_ok)) {
            current = boost::begin(local_range);
            if (state_ == stop_state) {
              parsed_ok = true;
            } else {
              switch (state_) {
              case http_response_begin:
                if (*current == ' ' || *current == '\r' || *current == '\n') {
                  // skip valid leading whitespace
                  ++start;
                  ++current;
                } else if (*current == 'H') {
                  state_ = http_version_h;
                  start = current;
                  ++current;
                } else {
                  parsed_ok = false;
                }
                break;
              case http_version_h:
                if (*current == 'T') {
                  state_ = http_version_t1;
                  ++current;
                } else {
                  parsed_ok = false;
                }
                break;
              case http_version_t1:
                if (*current == 'T') {
                  state_ = http_version_t2;
                  ++current;
                } else {
                  parsed_ok = false;
                }
                break;
              case http_version_t2:
                if (*current == 'P') {
                  state_ = http_version_p;
                  ++current;
                } else {
                  parsed_ok = false;
                }
                break;
              case http_version_p:
                if (*current == '/') {
                  state_ = http_version_slash;
                  ++current;
                } else {
                  parsed_ok = false;
                }
                break;
              case http_version_slash:
                if (boost::algorithm::is_digit()(*current)) {
                  state_ = http_version_major;
                  ++current;
                } else {
                  parsed_ok = false;
                }
                break;
              case http_version_major:
                if (*current == '.') {
                  state_ = http_version_dot;
                  ++current;
                } else {
                  parsed_ok = false;
                }
                break;
              case http_version_dot:
                if (boost::algorithm::is_digit()(*current)) {
                  state_ = http_version_minor;
                  ++current;
                } else {
                  parsed_ok = false;
                }
                break;
              case http_version_minor:
                if (*current == ' ') {
                  state_ = http_version_done;
                  ++current;
                } else {
                  parsed_ok = false;
                }
                break;
              case http_version_done:
                if (boost::algorithm::is_digit()(*current)) {
                  state_ = http_status_digit;
                  ++current;
                } else {
                  parsed_ok = false;
                }
                break;
              case http_status_digit:
                if (boost::algorithm::is_digit()(*current)) {
                  ++current;
                } else if (*current == ' ') {
                  state_ = http_status_done;
                  ++current;
                } else {
                  parsed_ok = false;
                }
                break;
              case http_status_done:
                if (boost::algorithm::is_alnum()(*current)) {
                  state_ = http_status_message_char;
                  ++current;
                } else {
                  parsed_ok = false;
                }
                break;
              case http_status_message_char:
                if (boost::algorithm::is_alnum()(*current) ||
                    boost::algorithm::is_punct()(*current) || (*current == ' ')) {
                  ++current;
                } else if (*current == '\r') {
                  state_ = http_status_message_cr;
                  ++current;
                } else {
                  parsed_ok = false;
                }
                break;
              case http_status_message_cr:
                if (*current == '\n') {
                  state_ = http_status_message_done;
                  ++current;
                } else {
                  parsed_ok = false;
                }
                break;
              case http_status_message_done:
              case http_header_line_done:
                if (boost::algorithm::is_alnum()(*current)) {
                  state_ = http_header_name_char;
                  ++current;
                } else if (*current == '\r') {
                  state_ = http_headers_end_cr;
                  ++current;
                } else {
                  parsed_ok = false;
                }
                break;
              case http_header_name_char:
                if (*current == ':') {
                  state_ = http_header_colon;
                  ++current;
                } else if (boost::algorithm::is_alnum()(*current) ||
                           boost::algorithm::is_space()(*current) ||
                           boost::algorithm::is_punct()(*current)) {
                  ++current;
                } else {
                  parsed_ok = false;
                }
                break;
              case http_header_colon:
                if (boost::algorithm::is_space()(*current)) {
                  ++current;
                } else if (boost::algorithm::is_alnum()(*current) ||
                           boost::algorithm::is_punct()(*current)) {
                  state_ = http_header_value_char;
                  ++current;
                } else {
                  parsed_ok = false;
                }
                break;
              case http_header_value_char:
                if (*current == '\r') {
                  state_ = http_header_line_cr;
                  ++current;
                } else if (boost::algorithm::is_cntrl()(*current)) {
                  parsed_ok = false;
                } else {
                  ++current;
                }
                break;
              case http_header_line_cr:
                if (*current == '\n') {
                  state_ = http_header_line_done;
                  ++current;
                } else {
                  parsed_ok = false;
                }
                break;
              case http_headers_end_cr:
                if (*current == '\n') {
                  state_ = http_headers_done;
                  ++current;
                } else {
                  parsed_ok = false;
                }
                break;
              default:
                parsed_ok = false;
              }
            }

            local_range = boost::make_iterator_range(current, end);
          }
          if (state_ == stop_state)
            parsed_ok = true;
          return std::make_tuple(parsed_ok,
                                 boost::make_iterator_range(start, current));
        }
示例#7
0
void swd::connection::handle_read(const boost::system::error_code& e,
 std::size_t bytes_transferred) {
	/**
	 * If an error occurs then no new asynchronous operations are started. This
	 * means that all shared_ptr references to the connection object will disappear
	 * and the object will be destroyed automatically after this handler returns.
	 * The connection class's destructor closes the socket.
	 */
	if (e) {
		return;
	}

	/**
	 * Since there was no error we can start parsing the input now. The parser
	 * fills the object request_ with data.
	 */
	boost::tribool result;
	boost::tie(result, boost::tuples::ignore) =
		request_parser_.parse(
			request_,
			buffer_.data(),
			buffer_.data() + bytes_transferred
		);

	/**
	 * If result is true the complete request is parsed. If it is false there was
	 * an error. If it is indeterminate then the parsing is not complete yet and
	 * the program will read more input and append it to the old request_ object.
	 */
	if (indeterminate(result)) {
		/* Not finished yet with this request, start reading again. */
		this->start_read();

		/* And don't process the input yet. */
		return;
	}

	/* The handler used to process the reply. */
	swd::reply_handler reply_handler(reply_);

	try {
		if (!result) {
			swd::log::i()->send(swd::warning, "Bad request from "
			 + remote_address_.to_string());
			throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST);
		}

		/* Try to add a profile for the request. */
		try {
			swd::profile_ptr profile = swd::database::i()->get_profile(
				remote_address_.to_string(),
				request_->get_profile_id()
			);

			request_->set_profile(profile);
		} catch (swd::exceptions::database_exception& e) {
			swd::log::i()->send(swd::uncritical_error, e.what());
			throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST);
		}

		/* The handler used to process the incoming request. */
		swd::request_handler request_handler(request_);

		/* Only continue processing the reply if it is signed correctly. */
		if (!request_handler.valid_signature()) {
			swd::log::i()->send(swd::warning, "Bad signature from "
			 + remote_address_.to_string());
			throw swd::exceptions::connection_exception(STATUS_BAD_SIGNATURE);
		}

		/**
		 * Before the request can be processed the input has to be transfered
		 * from the encoded json string to a swd::parameters list.
		 */
		if (!request_handler.decode()) {
			swd::log::i()->send(swd::warning, "Bad json from "
			 + remote_address_.to_string());
			throw swd::exceptions::connection_exception(STATUS_BAD_JSON);
		}

		/* Process the request. */
		std::vector<std::string> threats;

		try {
			if (swd::database::i()->is_flooding(request_->get_client_ip(), request_->get_profile_id())) {
				throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST);
			}

			threats = request_handler.process();
		} catch (swd::exceptions::database_exception& e) {
			swd::log::i()->send(swd::uncritical_error, e.what());

			/**
			 * Problems with the database result in a bad request. If protection
			 * is enabled access to the site will not be granted.
			 */
			throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST);
		}

		if (!threats.empty()) {
			reply_->set_threats(threats);
			reply_->set_status(STATUS_ATTACK);
		} else {
			reply_->set_status(STATUS_OK);
		}
	} catch(swd::exceptions::connection_exception& e) {
		reply_->set_status(e.code());
	}

	/* Encode the reply. */
	reply_handler.encode();

	/* Send the answer to the client. */
	if (ssl_) {
		boost::asio::async_write(
			ssl_socket_,
			reply_->to_buffers(),
			strand_.wrap(
				boost::bind(
					&connection::handle_write,
					shared_from_this(),
					boost::asio::placeholders::error
				)
			)
		);
	} else {
		boost::asio::async_write(
			socket_,
			reply_->to_buffers(),
			strand_.wrap(
				boost::bind(
					&connection::handle_write,
					shared_from_this(),
					boost::asio::placeholders::error
				)
			)
		);
	}
}
示例#8
0
void swd::connection::handle_read(const boost::system::error_code& e,
 std::size_t bytes_transferred) {
    /**
     * If an error occurs then no new asynchronous operations are started. This
     * means that all shared_ptr references to the connection object will disappear
     * and the object will be destroyed automatically after this handler returns.
     * The connection class's destructor closes the socket.
     */
    if (e) {
        return;
    }

    /**
     * Since there was no error we can start parsing the input now. The parser
     * fills the object request_ with data.
     */
    boost::tribool result;
    boost::tie(result, boost::tuples::ignore) =
        request_parser_.parse(
            request_,
            buffer_.data(),
            buffer_.data() + bytes_transferred
        );

    /**
     * If result is true the complete request is parsed. If it is false there was
     * an error. If it is indeterminate then the parsing is not complete yet and
     * the program will read more input and append it to the old request_ object.
     */
    if (indeterminate(result)) {
        /* Not finished yet with this request, start reading again. */
        this->start_read();

        /* And don't process the input yet. */
        return;
    }

    /* The handler used to process the reply. */
    swd::reply_handler reply_handler(reply_);

    try {
        if (!result) {
            swd::log::i()->send(swd::warning, "Bad request from "
             + remote_address_.to_string());
            throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST);
        }

        /* Try to add a profile for the request. */
        try {
            swd::profile_ptr profile = database_->get_profile(
                remote_address_.to_string(),
                request_->get_profile_id()
            );

            request_->set_profile(profile);
        } catch (swd::exceptions::database_exception& e) {
            swd::log::i()->send(swd::uncritical_error, e.what());
            throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST);
        }

        /* The handler used to process the incoming request. */
        swd::request_handler request_handler(request_, cache_, storage_);

        /* Only continue processing the reply if it is signed correctly. */
        if (!request_handler.valid_signature()) {
            swd::log::i()->send(swd::warning, "Bad signature from "
             + remote_address_.to_string());
            throw swd::exceptions::connection_exception(STATUS_BAD_SIGNATURE);
        }

        /**
         * Before the request can be processed the input has to be transfered
         * from the encoded json string to a swd::parameters list.
         */
        if (!request_handler.decode()) {
            swd::log::i()->send(swd::warning, "Bad json from "
             + remote_address_.to_string());
            throw swd::exceptions::connection_exception(STATUS_BAD_JSON);
        }

        /* Check profile for outdated cache. */
        swd::profile_ptr profile = request_->get_profile();

        if (profile->is_cache_outdated()) {
            cache_->reset(profile->get_id());
        }

        /* Process the request. */
        std::vector<std::string> threats;

        try {
            swd::parameters parameters = request_->get_parameters();

            /**
             * Check security limitations first.
             */
            int max_params = swd::config::i()->get<int>("max-parameters");

            if ((max_params > -1) && (parameters.size() > max_params)) {
                swd::log::i()->send(swd::notice, "Too many parameters");
                throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST);
            }

            int max_length_path = swd::config::i()->get<int>("max-length-path");
            int max_length_value = swd::config::i()->get<int>("max-length-value");

            if ((max_length_path > -1) || (max_length_value > -1)) {
                for (swd::parameters::iterator it_parameter = parameters.begin();
                 it_parameter != parameters.end(); it_parameter++) {
                    swd::parameter_ptr parameter(*it_parameter);

                    if ((max_length_path > -1) && (parameter->get_path().length() > max_length_path)) {
                        swd::log::i()->send(swd::notice, "Too long parameter path");
                        throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST);
                    }

                    if ((max_length_value > -1) && (parameter->get_value().length() > max_length_value)) {
                        swd::log::i()->send(swd::notice, "Too long parameter value");
                        throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST);
                    }
                }
            }

            if (profile->is_flooding_enabled()) {
                if (database_->is_flooding(request_->get_client_ip(), profile->get_id())) {
                    swd::log::i()->send(swd::notice, "Too many requests");
                    throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST);
                }
            }

            /* Time to analyze the request. */
            request_handler.process();
        } catch (swd::exceptions::database_exception& e) {
            swd::log::i()->send(swd::uncritical_error, e.what());

            /**
             * Problems with the database result in a bad request. If protection
             * is enabled access to the site will not be granted.
             */
            throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST);
        }

        if (profile->get_mode() == MODE_ACTIVE) {
            if (request_->is_threat()) {
                reply_->set_status(STATUS_CRITICAL_ATTACK);
            } else if (request_->has_threats()) {
                reply_->set_threats(request_handler.get_threats());
                reply_->set_status(STATUS_ATTACK);
            } else {
                reply_->set_status(STATUS_OK);
            }
        } else {
            reply_->set_status(STATUS_OK);
        }
    } catch(swd::exceptions::connection_exception& e) {
        if (!request_->get_profile()) {
            reply_->set_status(STATUS_BAD_REQUEST);
        } else if (request_->get_profile()->get_mode() == MODE_ACTIVE) {
            reply_->set_status(e.code());
        } else {
            reply_->set_status(STATUS_OK);
        }
    }

    /* Encode the reply. */
    reply_handler.encode();

    /* Send the answer to the client. */
    if (ssl_) {
        boost::asio::async_write(
            ssl_socket_,
            reply_->to_buffers(),
            strand_.wrap(
                boost::bind(
                    &connection::handle_write,
                    shared_from_this(),
                    boost::asio::placeholders::error
                )
            )
        );
    } else {
        boost::asio::async_write(
            socket_,
            reply_->to_buffers(),
            strand_.wrap(
                boost::bind(
                    &connection::handle_write,
                    shared_from_this(),
                    boost::asio::placeholders::error
                )
            )
        );
    }
}
示例#9
0
 fusion::tuple<logic::tribool, iterator_range<typename Range::const_iterator> >
 parse_until(state_t stop_state, Range & range) {
     logic::tribool parsed_ok = logic::indeterminate;
     typedef typename range_iterator<Range>::type iterator;
     iterator start = boost::begin(range)
             , end  = boost::end(range)
             , current_iterator = start;
     iterator_range<iterator> local_range = 
         boost::make_iterator_range(start, end);
     while (
         !boost::empty(local_range)
         && stop_state != internal_state
         && indeterminate(parsed_ok)
     ) {
         current_iterator = boost::begin(local_range);
         switch(internal_state) {
             case method_start:
                 if (algorithm::is_upper()(*current_iterator)) internal_state = method_char;
                 else parsed_ok = false;
                 break;
             case method_char:
                 if (algorithm::is_upper()(*current_iterator)) break;
                 else if (algorithm::is_space()(*current_iterator)) internal_state = method_done;
                 else parsed_ok = false;
                 break;
             case method_done:
                 if (algorithm::is_cntrl()(*current_iterator)) parsed_ok = false;
                 else if (algorithm::is_space()(*current_iterator)) parsed_ok = false;
                 else internal_state = uri_char;
                 break;
             case uri_char:
                 if (algorithm::is_cntrl()(*current_iterator)) parsed_ok = false;
                 else if (algorithm::is_space()(*current_iterator)) internal_state = uri_done;
                 break;
             case uri_done:
                 if (*current_iterator == 'H') internal_state = version_h;
                 else parsed_ok = false;
                 break;
             case version_h:
                 if (*current_iterator == 'T') internal_state = version_t1;
                 else parsed_ok = false;
                 break;
             case version_t1:
                 if (*current_iterator == 'T') internal_state = version_t2;
                 else parsed_ok = false;
                 break;
             case version_t2:
                 if (*current_iterator == 'P') internal_state = version_p;
                 else parsed_ok = false;
                 break;
             case version_p:
                 if (*current_iterator == '/') internal_state = version_slash;
                 else parsed_ok = false;
                 break;
             case version_slash:
                 if (algorithm::is_digit()(*current_iterator)) internal_state = version_d1;
                 else parsed_ok = false;
                 break;
             case version_d1:
                 if (*current_iterator == '.') internal_state = version_dot;
                 else parsed_ok = false;
                 break;
             case version_dot:
                 if (algorithm::is_digit()(*current_iterator)) internal_state = version_d2;
                 else parsed_ok = false;
                 break;
             case version_d2:
                 if (*current_iterator == '\r') internal_state = version_cr;
                 else parsed_ok = false;
                 break;
             case version_cr:
                 if (*current_iterator == '\n') internal_state = version_done;
                 else parsed_ok = false;
                 break;
             case version_done:
                 if (algorithm::is_alnum()(*current_iterator)) internal_state = header_name;
                 else if (*current_iterator == '\r') internal_state = headers_cr;
                 else parsed_ok = false;
                 break;
             case header_name:
                 if (*current_iterator == ':') internal_state = header_colon;
                 else if (algorithm::is_alnum()(*current_iterator) || algorithm::is_punct()(*current_iterator)) break;
                 else parsed_ok = false;
                 break;
             case header_colon:
                 if (*current_iterator == ' ') internal_state = header_value;
                 else parsed_ok = false;
                 break;
             case header_value:
                 if (*current_iterator == '\r') internal_state = header_cr;
                 else if (algorithm::is_cntrl()(*current_iterator)) parsed_ok = false;
                 break;
             case header_cr:
                 if (*current_iterator == '\n') internal_state = header_line_done;
                 else parsed_ok = false;
                 break;
             case header_line_done:
                 if (*current_iterator == '\r') internal_state = headers_cr;
                 else if (algorithm::is_alnum()(*current_iterator)) internal_state = header_name;
                 else parsed_ok = false;
                 break;
             case headers_cr:
                 if (*current_iterator == '\n') internal_state = headers_done;
                 else parsed_ok = false;
                 break;
             case headers_done:
                 // anything that follows after headers_done is allowed.
                 break;
             default:
                 parsed_ok = false;
         };
         if (internal_state == stop_state) parsed_ok = true;
         local_range = boost::make_iterator_range(
             ++current_iterator, end);
     }
     return fusion::make_tuple(
         parsed_ok, 
         boost::make_iterator_range(
             start, current_iterator
         )
         );
 }