Example #1
0
MORDOR_MAIN(int argc, const char * const argv[])
{
    try {
        Config::loadFromEnvironment();
        StdoutStream stdoutStream;
        WorkerPool pool(2);
        if (argc == 1) {
            argc = 2;
            const char * const hyphen[] = { "", "-" };
            argv = hyphen;
        }
        for (int i = 1; i < argc; ++i) {
            Stream::ptr inStream;
            std::string arg(argv[i]);
            if (arg == "-") {
                inStream.reset(new StdinStream());
            } else {
                inStream.reset(new FileStream(arg, FileStream::READ));
            }
            transferStream(inStream, stdoutStream);
        }
    } catch (const std::exception& ex) {
        std::cerr << ex.what() << std::endl;
    }
    return 0;
}
Example #2
0
Stream::ptr
Connection::getStream(const GeneralHeaders &general,
    const EntityHeaders &entity, const std::string &method, Status status,
    boost::function<void()> notifyOnEof,
    boost::function<void()> notifyOnException, bool forRead)
{
    MORDOR_ASSERT(hasMessageBody(general, entity, method, status));
    Stream::ptr stream;
    if (forRead) {
        stream.reset(new SingleplexStream(m_stream, SingleplexStream::READ, false));
    } else {
        stream.reset(new SingleplexStream(m_stream, SingleplexStream::WRITE, false));
    }
    Stream::ptr baseStream(stream);
    for (ParameterizedList::const_reverse_iterator it(general.transferEncoding.rbegin());
        it != general.transferEncoding.rend();
        ++it) {
        if (stricmp(it->value.c_str(), "chunked") == 0) {
            stream.reset(new ChunkedStream(stream));
        } else if (stricmp(it->value.c_str(), "deflate") == 0) {
            stream.reset(new ZlibStream(stream));
        } else if (stricmp(it->value.c_str(), "gzip") == 0 ||
            stricmp(it->value.c_str(), "x-gzip") == 0) {
            stream.reset(new GzipStream(stream));
        } else if (stricmp(it->value.c_str(), "compress") == 0 ||
            stricmp(it->value.c_str(), "x-compress") == 0) {
            MORDOR_ASSERT(false);
        } else if (stricmp(it->value.c_str(), "identity") == 0) {
            MORDOR_ASSERT(false);
        } else {
            MORDOR_ASSERT(false);
        }
    }
    if (stream != baseStream) {
    } else if (entity.contentLength != ~0ull) {
        LimitedStream::ptr limited(new LimitedStream(stream, entity.contentLength));
        limited->strict(true);
        stream = limited;
    } else if (entity.contentType.type == "multipart") {
        // Getting stream to pass to multipart; self-delimiting
    } else {
        // Delimited by closing the connection
    }
    NotifyStream::ptr notify(new NotifyStream(stream));
    stream = notify;
    notify->notifyOnClose = notifyOnEof;
    notify->notifyOnEof = notifyOnEof;
    notify->notifyOnException = notifyOnException;
    return stream;
}
Example #3
0
void Config::request(ServerRequest::ptr request, Access access)
{
    const std::string &method = request->request().requestLine.method;
    if (method == POST) {
        if (access != READWRITE) {
            respondError(request, FORBIDDEN);
            return;
        }
        if (request->request().entity.contentType.type != "application" ||
            request->request().entity.contentType.subtype != "x-www-form-urlencoded") {
            respondError(request, UNSUPPORTED_MEDIA_TYPE);
            return;
        }
        Stream::ptr requestStream = request->requestStream();
        requestStream.reset(new LimitedStream(requestStream, 65536));
        MemoryStream requestBody;
        transferStream(requestStream, requestBody);
        std::string queryString;
        queryString.resize(requestBody.buffer().readAvailable());
        requestBody.buffer().copyOut(&queryString[0], requestBody.buffer().readAvailable());

        bool failed = false;
        URI::QueryString qs(queryString);
        for (URI::QueryString::const_iterator it = qs.begin();
            it != qs.end();
            ++it) {
            ConfigVarBase::ptr var = Mordor::Config::lookup(it->first);
            if (var && !var->fromString(it->second))
                failed = true;
        }
        if (failed) {
            respondError(request, HTTP::FORBIDDEN,
                "One or more new values were not accepted");
            return;
        }
        // Fall through
    }
    if (method == GET || method == HEAD || method == POST) {
        Format format = HTML;
        URI::QueryString qs;
        if (request->request().requestLine.uri.queryDefined())
            qs = request->request().requestLine.uri.queryString();
        URI::QueryString::const_iterator it = qs.find("alt");
        if (it != qs.end() && it->second == "json")
            format = JSON;
        // TODO: use Accept to indicate JSON
        switch (format) {
            case HTML:
            {
                request->response().status.status = OK;
                request->response().entity.contentType = MediaType("text", "html");
                if (method == HEAD) {
                    if (request->request().requestLine.ver == Version(1, 1) &&
                        isAcceptable(request->request().request.te, "chunked", true)) {
                        request->response().general.transferEncoding.push_back("chunked");
                    }
                    return;
                }
                Stream::ptr response = request->responseStream();
                response.reset(new BufferedStream(response));
                response->write("<html><body><table>\n", 20);
                Mordor::Config::visit(boost::bind(access == READWRITE ?
                    &eachConfigVarHTMLWrite : &eachConfigVarHTML, _1,
                    response));
                response->write("</table></body></html>", 22);
                response->close();
                break;
            }
            case JSON:
            {
                JSON::Object root;
                Mordor::Config::visit(boost::bind(&eachConfigVarJSON, _1, boost::ref(root)));
                std::ostringstream os;
                os << root;
                std::string str = os.str();
                request->response().status.status = OK;
                request->response().entity.contentType = MediaType("application", "json");
                request->response().entity.contentLength = str.size();
                if (method != HEAD) {
                    request->responseStream()->write(str.c_str(), str.size());
                    request->responseStream()->close();
                }
                break;
            }
            default:
                MORDOR_NOTREACHED();
        }
    } else {
        respondError(request, METHOD_NOT_ALLOWED);
    }
}