static int trySendFile(const std::string& realfile, HttpResponse& response) {
  std::ifstream ifs;
  ifs.open(realfile.c_str(), std::ifstream::in);

  // whether file not found
  if (!ifs.is_open()) {
    return 1;
  }

  VLOG(2) << "absolute file path: " << realfile;

  // get file length
  ifs.seekg(0, std::ios::end);
  int length = ifs.tellg();
  ifs.seekg(0, std::ios::beg);

  // read file content
  std::string buff;
  buff.resize(length);
  ifs.read(const_cast<char*>(buff.data()), length);
  ifs.close();

  response.setContent(buff);
  response.setStatus(HttpResponse::ok);
  std::string ext;
  std::string::size_type pos1 = realfile.rfind('.');
  if (pos1 != realfile.npos) {
    ext = realfile.substr(pos1 + 1, realfile.length() - pos1 - 1);
  }
  auto& mime = HttpMime::getMimeFromExt(ext);
  response.addHeader("Content-Type", mime);

  return 0;
}
void ShellHttpServlet::doPost(HttpRequest& request, HttpResponse& response) {
    char * tmpfile = tempnam("/tmp", "ecf_");
    std::string script_file = tmpfile;
    free(tmpfile);

    std::ofstream ofs(script_file.c_str());
    ofs << request.getBody();
    ofs << std::endl;
    ofs.close();

    LOG(INFO) << "file: " << script_file << ", script: " << request.getBody();

    std::string stdout;
    {
        std::lock_guard<std::mutex> guard(lock);
        exec_command("bash", script_file, &stdout, NULL);
    }

    response.setContent(stdout);
    response.setStatus(idgs::httpserver::HttpResponse::ok);

    response.addHeader(HTTP_HEADER_CONTENT_TYPE, CONTENT_TYPE_TEXT_PLAIN);

    remove(script_file.c_str());
    return;
}
Beispiel #3
0
bool RpcServer::processJsonRpcRequest(const HttpRequest& request, HttpResponse& response) {

  using namespace JsonRpc;

  response.addHeader("Content-Type", "application/json");

  JsonRpcRequest jsonRequest;
  JsonRpcResponse jsonResponse;

  try {
    logger(TRACE) << "JSON-RPC request: " << request.getBody();
    jsonRequest.parseRequest(request.getBody());
    jsonResponse.setId(jsonRequest.getId()); // copy id

    static std::unordered_map<std::string, JsonMemberMethod> jsonRpcHandlers = {
      { "getblockcount", makeMemberMethod(&RpcServer::on_getblockcount) },
      { "on_getblockhash", makeMemberMethod(&RpcServer::on_getblockhash) },
      { "getblocktemplate", makeMemberMethod(&RpcServer::on_getblocktemplate) },
      { "getcurrencyid", makeMemberMethod(&RpcServer::on_get_currency_id) },
      { "submitblock", makeMemberMethod(&RpcServer::on_submitblock) },
      { "getlastblockheader", makeMemberMethod(&RpcServer::on_get_last_block_header) },
      { "getblockheaderbyhash", makeMemberMethod(&RpcServer::on_get_block_header_by_hash) },
      { "getblockheaderbyheight", makeMemberMethod(&RpcServer::on_get_block_header_by_height) }
    };

    auto it = jsonRpcHandlers.find(jsonRequest.getMethod());
    if (it == jsonRpcHandlers.end()) {
      throw JsonRpcError(JsonRpc::errMethodNotFound);
    }

    if (jsonRequest.getMethod() != "getcurrencyid" && !checkCoreReady()) {
      throw JsonRpcError(CORE_RPC_ERROR_CODE_CORE_BUSY, "Core is busy");
    }

    it->second(this, jsonRequest, jsonResponse);

  } catch (const JsonRpcError& err) {
    jsonResponse.setError(err);
  } catch (const std::exception& e) {
    jsonResponse.setError(JsonRpcError(JsonRpc::errInternalError, e.what()));
  }

  response.setBody(jsonResponse.getBody());
  logger(TRACE) << "JSON-RPC response: " << jsonResponse.getBody();
  return true;
}
Beispiel #4
0
HttpResponse* listToResponse(HttpRequest* pRequest,
                             const Rcpp::List& response) {
  using namespace Rcpp;

  if (response.isNULL() || response.size() == 0)
    return NULL;

  CharacterVector names = response.names();

  int status = Rcpp::as<int>(response["status"]);
  std::string statusDesc = getStatusDescription(status);

  List responseHeaders = response["headers"];

  // Self-frees when response is written
  DataSource* pDataSource = NULL;

  // The response can either contain:
  // - bodyFile: String value that names the file that should be streamed
  // - body: Character vector (which is charToRaw-ed) or raw vector, or NULL
    if (std::find(names.begin(), names.end(), "bodyFile") != names.end()) {
    FileDataSource* pFDS = new FileDataSource();
    pFDS->initialize(Rcpp::as<std::string>(response["bodyFile"]),
        Rcpp::as<bool>(response["bodyFileOwned"]));
    pDataSource = pFDS;
  }
  else if (Rf_isString(response["body"])) {
    RawVector responseBytes = Function("charToRaw")(response["body"]);
    pDataSource = new RawVectorDataSource(responseBytes);
  }
  else {
    RawVector responseBytes = response["body"];
    pDataSource = new RawVectorDataSource(responseBytes);
  }

  HttpResponse* pResp = new HttpResponse(pRequest, status, statusDesc,
                                         pDataSource);
  CharacterVector headerNames = responseHeaders.names();
  for (R_len_t i = 0; i < responseHeaders.size(); i++) {
    pResp->addHeader(
      std::string((char*)headerNames[i], headerNames[i].size()),
      Rcpp::as<std::string>(responseHeaders[i]));
  }

  return pResp;
}
Beispiel #5
0
int HttpRequest::_on_headers_complete(http_parser* pParser) {
  trace("on_headers_complete");

  int result = 0;

  HttpResponse* pResp = _pWebApplication->onHeaders(this);
  if (pResp) {
    bool bodyExpected = _headers.find("Content-Length") != _headers.end() ||
      _headers.find("Transfer-Encoding") != _headers.end();

    if (bodyExpected) {
      // If we're expecting a request body and we're returning a response
      // prematurely, then add "Connection: close" header to the response and
      // set a flag to ignore all future reads on this connection.

      pResp->addHeader("Connection", "close");

      uv_read_stop((uv_stream_t*)handle());

      _ignoreNewData = true;
    }
    pResp->writeResponse();

    // result = 1 has special meaning to http_parser for this one callback; it
    // means F_SKIPBODY should be set on the parser. That's not what we want
    // here; we just want processing to terminate.
    result = 2;
  }
  else {
    // If the request is Expect: Continue, and the app didn't say otherwise,
    // then give it what it wants
    if (_headers.find("Expect") != _headers.end()
        && _headers["Expect"] == "100-continue") {
      pResp = new HttpResponse(this, 100, "Continue", NULL);
      pResp->writeResponse();
    }
  }

  // TODO: Allocate body
  return result;
}
Beispiel #6
0
int HttpRequest::_on_headers_complete(http_parser* pParser) {
  trace("on_headers_complete");

  int result = 0;

  HttpResponse* pResp = _pWebApplication->onHeaders(this);
  if (pResp) {
    bool bodyExpected = _headers.find("Content-Length") != _headers.end() ||
      _headers.find("Transfer-Encoding") != _headers.end();

    if (bodyExpected) {
      // If we're expecting a request body and we're returning a response
      // prematurely, then add "Connection: close" header to the response and
      // set a flag to ignore all future reads on this connection.

      pResp->addHeader("Connection", "close");

      // Do not call uv_read_stop, it mysteriously seems to prevent the response
      // from being written.
      // uv_read_stop((uv_stream_t*)handle());

      _ignoreNewData = true;
    }
    pResp->writeResponse();
    result = 1;
  }
  else {
    // If the request is Expect: Continue, and the app didn't say otherwise,
    // then give it what it wants
    if (_headers.find("Expect") != _headers.end()
        && _headers["Expect"] == "100-continue") {
      pResp = new HttpResponse(this, 100, "Continue", NULL);
      pResp->writeResponse();
    }
  }

  // TODO: Allocate body
  return result;
}
void ProcessingThread::processFileDescriptor(int fd)
{
	char buffer[1024*10]; // 10kb
	ssize_t count=1;

	while (count > 0)
	{
		count = read(fd, buffer, 1024*10);
		if (count < 1024*10)
			break;
	}

	HttpRequest req(buffer);
	HttpResponse resp;
	/*if (req.isKeepAlive())
	{
		resp.addHeader("Connection","Keep-Alive");
	}*/

	if (req.getRequestURI().compare("/sum") == 0)
	{
		int a=0,b=0;
		const vector<QueryParameter*>& params = req.getParams();
		for (unsigned i=0;i<params.size();i++)
		{
			if (params[i]->getParam().compare("a") == 0)
				a = atoi(params[i]->getValue().c_str());
			if (params[i]->getParam().compare("b") == 0)
				b = atoi(params[i]->getValue().c_str());
		}
		char buffer[128];
		sprintf(buffer,"<html><body>%d + %d = %d</body></html>",a,b,a+b);
		char len[10];
		sprintf(len,"%lu",strlen(buffer));
		HttpResponse resp("HTTP/1.1 200 OK");
		resp.addHeader("Content-Type","text/html; charset=utf-8");
		resp.addHeader("Content-Length",len);
		resp.setContent(((void*)buffer),strlen(buffer));
		resp.writeToFD(fd);
	}
	else if (!fileExists(req.getRequestURI().c_str()))
	{
		resp.setStatusLine("HTTP/1.1 404 Not found");
		resp.addHeader("Content-Type","text/html; charset=utf-8");
		resp.addHeader("Content-Length","50");
		resp.setContent(((void*)"<html><body><h1>404 - Not found</h1></body></html>"),50);
		resp.writeToFD(fd);
	}
	else
	{
		if (isDir(req.getRequestURI().c_str()))
		{
			resp.setStatusLine("HTTP/1.1 200 OK");
			resp.addHeader("Content-Type","text/html; charset=utf-8");
			unsigned length = 0;
			string body = "<html><body>";
			vector<string> files;
			dirLs(req.getRequestURI().c_str(),files);
			for (unsigned i=0;i<files.size();i++)
			{
				body += "<a href=\""+req.getRequestURI()+"/"+files[i]+"\">" + files[i] +"</a><br/>";
			}
			length = body.length();
			resp.setContent((void*)body.c_str(),length);
			char buff[10];
			sprintf(buff,"%d",length);
			resp.addHeader("Content-Length",buff);
			resp.writeToFD(fd);
		}
		else if (isFile(req.getRequestURI().c_str()))
		{
			string fileExt = getExtension(req.getRequestURI());
			if (fileExt != "lua")
			{
				ifstream file(req.getRequestURI().c_str());
				file.seekg(0,ios_base::end);
				streamsize fileSize = file.tellg();
				file.seekg(0,ios_base::beg);
				char* content = new char[fileSize];
				file.read(content,fileSize);
				file.close();
				char buff[10];
				sprintf(buff,"%ld",fileSize);
				resp.setStatusLine("HTTP/1.1 200 OK");
				resp.addHeader("Content-Length",buff);
				resp.setContent(content,fileSize);
				if (fileExt.compare("html") == 0)
				{
					resp.addHeader("Content-Type","text/html; charset=utf-8");
				}
				resp.writeToFD(fd);
				delete [] content;
			}
			else
			{
				int result = luaL_loadfile(luaState,req.getRequestURI().c_str());
				if (result != 0)
				{
					resp.setStatusLine("HTTP/1.1 500 Internal server error");
					resp.addHeader("Content-Type","text/html; charset=utf-8");
					char buffer[1024];
					sprintf(buffer,"<html><body><h1>500 Internal server error</h1><br/><p>%s</p></body></html>",lua_tostring(luaState,1));
					lua_pop(luaState,1); // pop the error message
					char lenBuff[10];
					sprintf(lenBuff,"%lu",strlen(buffer));
					resp.addHeader("Content-Length",lenBuff);
					resp.setContent(((void*)"<html><body><h1>404 - Not found</h1></body></html>"),strlen(buffer));
					resp.writeToFD(fd);
				}
				else
				{
					// environment table - replaced with globals, setting up an environment that includes all the built-in functions is a pain
					//lua_newtable(luaState);
					// print function
					stringstream ss;
					//lua_pushstring(luaState,"print");
					lua_pushlightuserdata(luaState,&ss);
					lua_pushcclosure(luaState,luaStdOutPrint,1);
					lua_setglobal(luaState,"print");
					//lua_settable(luaState,-3);
					// headers table
					//lua_pushstring(luaState,"HTTP_HEADERS");
					lua_newtable(luaState);
					const vector<HttpHeader*>& headers = req.getHeaders();
					for (unsigned i=0;i<headers.size();i++)
					{
						lua_pushstring(luaState,headers[i]->getField().c_str());
						lua_pushstring(luaState,headers[i]->getValue().c_str());
						lua_settable(luaState,-3);
					}
					lua_setglobal(luaState,"HTTP_HEADERS");
					//lua_settable(luaState,-3);
					// parameters table
					//lua_pushstring(luaState,"HTTP_QUERY_PARAMS");
					lua_newtable(luaState);
					const vector<QueryParameter*>& params = req.getParams();
					for (unsigned i=0;i<params.size();i++)
					{
						lua_pushstring(luaState,params[i]->getParam().c_str());
						lua_pushstring(luaState,params[i]->getValue().c_str());
						lua_settable(luaState,-3);
					}
					lua_setglobal(luaState,"HTTP_QUERY_PARAMS");
					//lua_settable(luaState,-3);
					// set the environment
					//lua_setupvalue(luaState, -2, 1);

					result = lua_pcall(luaState,0,LUA_MULTRET,0);
					if (result == 0)
					{
						resp.setStatusLine("HTTP/1.1 200 OK");
						resp.addHeader("Content-Type","text/html; charset=utf-8");
						const string& output = ss.str();
						char lenBuff[10];
						sprintf(lenBuff,"%lu",output.length());
						resp.addHeader("Content-Length",lenBuff);
						resp.setContent(((void*)output.c_str()),output.length());
						resp.writeToFD(fd);
					}
					else if (result == LUA_ERRRUN || result == LUA_ERRMEM || result == LUA_ERRERR)
					{
						resp.setStatusLine("HTTP/1.1 500 Internal server error");
						resp.addHeader("Content-Type","text/html; charset=utf-8");
						char buffer[1024];
						sprintf(buffer,"<html><body><h1>500 Internal server error</h1><br/><p>%s</p></body></html>",lua_tostring(luaState,1));
						lua_pop(luaState,1); // pop the error message
						char lenBuff[10];
						sprintf(lenBuff,"%lu",strlen(buffer));
						resp.addHeader("Content-Length",lenBuff);
						resp.setContent(((void*)buffer),strlen(buffer));
						resp.writeToFD(fd);
					}
				}
			}
		}
	}

	//if (!req.isKeepAlive())
		close(fd);
	/*else
		karThread->update(fd,15);*/
}
Beispiel #8
0
void HttpRequest::_on_request_read(uv_stream_t*, ssize_t nread, uv_buf_t buf) {
  if (nread > 0) {
    //std::cerr << nread << " bytes read\n";
    if (_ignoreNewData) {
      // Do nothing
    } else if (_protocol == HTTP) {
      int parsed = http_parser_execute(&_parser, &request_settings(), buf.base, nread);
      if (_parser.upgrade) {
        char* pData = buf.base + parsed;
        ssize_t pDataLen = nread - parsed;

        if (_headers.find("upgrade") != _headers.end() &&
            _headers["upgrade"] == std::string("websocket") &&
            _headers.find("sec-websocket-key") != _headers.end()) {

          // Freed in on_response_written
          HttpResponse* pResp = new HttpResponse(this, 101, "Switching Protocols",
            NULL);
          pResp->addHeader("Upgrade", "websocket");
          pResp->addHeader("Connection", "Upgrade");
          pResp->addHeader(
            "Sec-WebSocket-Accept",
            createHandshakeResponse(_headers["sec-websocket-key"]));
          // TODO: Consult app about supported WS protocol
          //pResp->addHeader("Sec-WebSocket-Protocol", "");

          pResp->writeResponse();

          _protocol = WebSockets;
          _pWebApplication->onWSOpen(this);

          read(pData, pDataLen);
        }

        if (_protocol != WebSockets) {
          // TODO: Write failure
          close();
        }
      } else if (parsed < nread) {
        if (!_ignoreNewData) {
          fatal_error("on_request_read", "parse error");
          uv_read_stop((uv_stream_t*)handle());
          close();
        }
      }
    } else if (_protocol == WebSockets) {
      read(buf.base, nread);
    }
  } else if (nread < 0) {
    uv_err_t err = uv_last_error(_pLoop);
    if (err.code == UV_EOF /*|| err.code == UV_ECONNRESET*/) {
    } else {
      fatal_error("on_request_read", uv_strerror(err));
    }
    close();
  } else {
    // It's normal for nread == 0, it's when uv requests a buffer then
    // decides it doesn't need it after all
  }

  free(buf.base);
}