TEST_F (WebSockServerTester, FailedHandshakes_NoKey) {
    
    HTTP::Request request (HTTP::Method::GET, "/");
    request.SetHeader (HTTP::Header ("Connection", "Upgrade"));
    request.SetHeader (HTTP::Header ("Upgrade", "websocket"));
    VerifyBadRequest (request);
}
TEST_F (WebSockServerTester, FailedHandshakes_NoWebSocket) {
    
    HTTP::Request request (HTTP::Method::GET, "/");
    request.SetHeader (HTTP::Header ("Connection", "Upgrade"));
    request.SetHeader (HTTP::Header ("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ=="));
    VerifyBadRequest (request);
}
예제 #3
0
void handleFileExportRequest(const http::Request& request, 
                             http::Response* pResponse) 
{
   // see if this is a single or multiple file request
   std::string file = request.queryParamValue("file");
   if (!file.empty())
   {
      // resolve alias and ensure that it exists
      FilePath filePath = module_context::resolveAliasedPath(file);
      if (!filePath.exists())
      {
         pResponse->setError(http::status::NotFound, "file doesn't exist");
         return;
      }
      
      // get the name
      std::string name = request.queryParamValue("name");
      if (name.empty())
      {
         pResponse->setError(http::status::BadRequest, "name not specified");
         return;
      }
      
      // download as attachment
      setAttachmentResponse(request, name, filePath, pResponse);
   }
   else
   {
      handleMultipleFileExportRequest(request, pResponse);
   }
}
예제 #4
0
bool Server::Listen()
{
	m_valid = false;
	if (!m_server.Listen())
		return false;
	//Debug("Handshaking...");
	HTTP::Request handshake;
	if (!handshake.Receive(m_server))
	{
		Error("Failed to process HTTP request");
	}
	map<string, string> & headers = handshake.Headers();
	auto i = headers.find("Sec-WebSocket-Key");
	if (i == headers.end())
	{
		Error("No Sec-WebSocket-Key header!");
		for (i = headers.begin(); i != headers.end(); ++i)
		{
			Error("Key: %s = %s", i->first.c_str(), i->second.c_str());
		}
		return false;
	}
	//Debug("Finished handshake");
	string magic = Foxbox::WS::Magic(i->second);
	
	m_server.Send("HTTP/1.1 101 Switching Protocols\r\n");
	m_server.Send("Upgrade: WebSocket\r\n");
	m_server.Send("Connection: Upgrade\r\n");
	m_server.Send("Sec-WebSocket-Accept: %s\r\n", magic.c_str());
	m_server.Send("Sec-WebSocket-Protocol: %s\r\n\r\n", 
		headers["Sec-WebSocket-Protocol"].c_str());
	m_valid = true;
	return true;
}
예제 #5
0
void Authenticator::updateAuthInfo(http::Request& request)
{
    if (request.has("Authorization")) {
        const std::string& authorization = request.get("Authorization");

        if (isBasicCredentials(authorization)) {
            BasicAuthenticator(_username, _password).authenticate(request);
        }
        // else if (isDigestCredentials(authorization))
        //    ; // TODO
    }
}
예제 #6
0
void handleFileShow(const http::Request& request, http::Response* pResponse)
{
   // get the file path
   FilePath filePath(request.queryParamValue("path"));
   if (!filePath.exists())
   {
      pResponse->setNotFoundError(request.uri());
      return;
   }

   // send it back
   pResponse->setCacheWithRevalidationHeaders();
   pResponse->setCacheableFile(filePath, request);
}
예제 #7
0
void RFC6455::Client::HandleHandshake (const HTTP::Request& inRequest) {
    
    HTTP::Response response (HTTP::Code::BAD_REQUEST, inRequest.mVersion);
    
    bool isUpgraded (false);

    try {
        if (inRequest.GetHeaderValue ("Connection") == "Upgrade" && 
            inRequest.GetHeaderValue ("Upgrade") == "websocket" &&  
            inRequest.GetHeaderValue ("Sec-WebSocket-Key") != "" && 
            inRequest.mMethod == HTTP::Method::GET && 
            inRequest.mVersion == HTTP::Version::V11 
        ) {
            
            const auto key (inRequest.GetHeaderValue ("Sec-WebSocket-Key"));
            const auto keyWithMagicString (key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
            
            char base64[SHA1_BASE64_SIZE];
            sha1 (keyWithMagicString.c_str ()).finalize().print_base64 (base64);
            
            response.SetHeader (HTTP::Header ("Connection", "Upgrade"));
            response.SetHeader (HTTP::Header ("Upgrade", "websocket"));
            response.SetHeader (HTTP::Header ("Sec-WebSocket-Accept", std::string (base64)));
            
            response.mCode = HTTP::Code::SWITCHING_PROTOCOLS;
            isUpgraded = true;
        }
    } 
    catch (...) {}
    
    mResponseEncoder.Write (response);
    
    {
        using namespace HTTP;
        LOGINFO << "HTTP/" << VersionToString (response.mVersion) << " " << MethodToString (inRequest.mMethod) 
                << " " << inRequest.mPath << " - " << response.mCode << " " << CodeToString (response.mCode) << " - RFC6455";
    }
 
    if (!isUpgraded) {
        Quit ();
    }
    else {
        // Clear the stream, route the pipe through the frame decoder.
        GetReadStream ().Clear ().Pipe (mFrameDecoder).Pipe (this, &Client::HandleReceivedFrame);
        mResponseEncoder.Clear ();
        
        mPayloadStringEncoder.Pipe (mFrameEncoder).Pipe (GetWriteStream ());
        mPayloadBinaryEncoder.Pipe (mFrameEncoder);
    }
}
예제 #8
0
void handleFilesRequest(const http::Request& request, 
                        http::Response* pResponse)
{   
   Options& options = session::options();
   if (options.programMode() != kSessionProgramModeServer)
   {
      pResponse->setError(http::status::NotFound,
                          request.uri() + " not found");
      return;
   }
   
   // get prefix and uri
   std::string prefix = "/files/";
   std::string uri = request.uri();
   
   // validate the uri
   if (prefix.length() >= uri.length() ||    // prefix longer than uri
       uri.find(prefix) != 0 ||              // uri doesn't start with prefix
       uri.find("..") != std::string::npos)  // uri has inavlid char sequence
   {
      pResponse->setError(http::status::NotFound, 
                          request.uri() + " not found");
      return;
   }
   
   // compute path to file
   int prefixLen = prefix.length();
   std::string relativePath = http::util::urlDecode(uri.substr(prefixLen));
   if (relativePath.empty())
   {
      pResponse->setError(http::status::NotFound, request.uri() + " not found");
      return;
   }

   // complete path to file
   FilePath filePath = module_context::userHomePath().complete(relativePath);

   // no directory listing available
   if (filePath.isDirectory())
   {
      pResponse->setError(http::status::NotFound,
                          "No listing available for " + request.uri());
      return;
   }


   pResponse->setNoCacheHeaders();
   pResponse->setFile(filePath, request);
}
예제 #9
0
void setAttachmentResponse(const http::Request& request,
                           const std::string& filename,
                           const FilePath& attachmentPath,
                           http::Response* pResponse)
{
   if (request.headerValue("User-Agent").find("MSIE") == std::string::npos)
   {
      pResponse->setNoCacheHeaders();
   }
   else
   {
      // Can't set full no-cache headers because this breaks downloads in IE
      pResponse->setHeader("Expires", "Fri, 01 Jan 1990 00:00:00 GMT");
      pResponse->setHeader("Cache-Control", "private");
   }
   // Can't rely on "filename*" in Content-Disposition header because not all
   // browsers support non-ASCII characters here (e.g. Safari 5.0.5). If
   // possible, make the requesting URL contain the UTF-8 byte escaped filename
   // as the last path element.
   pResponse->setHeader("Content-Disposition",
                        "attachment; filename*=UTF-8''"
                        + http::util::urlEncode(filename, false));
   pResponse->setHeader("Content-Type", "application/octet-stream");
   pResponse->setBody(attachmentPath);
}
예제 #10
0
void Response::setMovedTemporarily(const http::Request& request,
                                   const std::string& location)
{
   std::string uri = URL::complete(request.absoluteUri(),
                                   safeLocation(location));
   setError(http::status::MovedTemporarily, uri);
   setHeader("Location", uri);
}
예제 #11
0
파일: fileserver.cpp 프로젝트: ivochkin/dfk
int Server::handle(http::Server* server, http::Request& request, http::Response& response)
{
  dfk_userdata_t user = (dfk_userdata_t) {nativeHandle()};
  return dfk_fileserver_handler(user,
      server->nativeHandle(),
      request.nativeHandle(),
      response.nativeHandle());
}
예제 #12
0
BasicAuthenticator::BasicAuthenticator(const http::Request& request)
{
    std::string scheme;
    std::string authInfo;
    request.getCredentials(scheme, authInfo);
    if (util::icompare(scheme, "Basic") == 0) {
        parseAuthInfo(authInfo);
    } else
        throw std::runtime_error("Basic authentication expected");
}
예제 #13
0
void WebSocketFramer::acceptRequest(http::Request& request, http::Response& response)
{
	if (util::icompare(request.get("Connection", ""), "upgrade") == 0 && 
		util::icompare(request.get("Upgrade", ""), "websocket") == 0) {
		std::string version = request.get("Sec-WebSocket-Version", "");
		if (version.empty()) throw std::runtime_error("WebSocket error: Missing Sec-WebSocket-Version in handshake request"); //, ws::ErrorHandshakeNoVersion
		if (version != ws::ProtocolVersion) throw std::runtime_error("WebSocket error: Unsupported WebSocket version requested: " + version); //, ws::ErrorHandshakeUnsupportedVersion
		std::string key = util::trim(request.get("Sec-WebSocket-Key", ""));
		if (key.empty()) throw std::runtime_error("WebSocket error: Missing Sec-WebSocket-Key in handshake request"); //, ws::ErrorHandshakeNoKey
		
		response.setStatus(http::StatusCode::SwitchingProtocols);
		response.set("Upgrade", "websocket");
		response.set("Connection", "Upgrade");
		response.set("Sec-WebSocket-Accept", computeAccept(key));

		// Set headerState 2 since the handshake was accepted.
		_headerState = 2;
	}
	else throw std::runtime_error("WebSocket error: No WebSocket handshake"); //, ws::ErrorNoHandshake
}
예제 #14
0
void WRestResource::handleRequest(const Http::Request &request,
                                  Http::Response &response)
{
  try {
    auto it = std::find(METHOD_STRINGS.cbegin(), METHOD_STRINGS.cend(), request.method());
    auto idx = static_cast<std::size_t>(std::distance(METHOD_STRINGS.cbegin(), it));
    if (it == METHOD_STRINGS.cend() || !handlers_[idx])
      response.setStatus(405);
  } catch (Exception e) {
    response.setStatus(e.status());
  }
}
예제 #15
0
void EtagStoreResource::handle_etag(const Http::Request& request,
                                    Http::Response& response) {
    // TODO http://redmine.webtoolkit.eu/issues/2471
    // const std::string* cookie_value = request.getCookieValue(cookie_name_);
    std::string cookies = request.headerValue("Cookie");
    if (cookies.empty()) {
        return;
    }
    std::string pattern = cookie_name_ + "=";
    int cookie_begin = cookies.find(pattern);
    if (cookie_begin == std::string::npos) {
        return;
    }
    cookie_begin += pattern.length();
    int cookie_end = cookies.find(';', cookie_begin);
    int cookie_length = (cookie_end == -1) ? -1 : (cookie_end - cookie_begin);
    std::string cookie_value = cookies.substr(cookie_begin, cookie_length);
    //
    std::string etag_value = request.headerValue(receive_header());
    boost::mutex::scoped_lock lock(cookie_to_etag_mutex_);
    Map::iterator it = cookie_to_etag_.find(cookie_value);
    if (it == cookie_to_etag_.end()) {
        return;
    }
    Etag& etag = it->second;
    if (etag_value.empty()) {
        etag_value = etag.def;
    }
    etag.from_client = etag_value;
    if (!etag.to_client.empty()) {
        response.addHeader(send_header(), etag.to_client);
        etag.to_client.clear();
    } else {
        etag.handler(etag.from_client);
    }
    if (!etag.from_client.empty()) {
        response.addHeader(send_header(), etag.from_client);
    }
}
예제 #16
0
int main(int argc, char *argv[])
{
	HTTP::HeaderSet hs;
	hs.add("Content-Type", "text/plain");
	assert(hs.has("Content-Type"));
	hs.add("Content-Length", "50823");
	hs.add("Rubbish", "123");
	hs.remove("Rubbish");
	assert(!hs.has("Rubbish"));

	std::string hso = hs.toString();
	assert_equal(hso, "Content-Length: 50823\r\nContent-Type: text/plain\r\n\r\n");

	HTTP::HeaderSet *hsp = HTTP::HeaderSet::fromString(hso);
	assert(hsp && "parsed header must be valid");
	std::string hspo = hsp->toString();
	assert_equal(hspo, hso);

	//Test the HTTP::Request object.
	HTTP::Request req;
	req.type = HTTP::Request::kPOST;
	req.path = "/meta.json";
	req.headers.add("Content-Type", "application/json");
	req.headers.add("Content-Length", "11");
	req.headers.add("User-Agent", "auris-db");
	req.content = "Hello World";

	std::string reqo = req.toString();
	assert_equal(reqo, "POST /meta.json HTTP/1.1\r\nContent-Length: 11\r\nContent-Type: application/json\r\nUser-Agent: auris-db\r\n\r\nHello World\r\n");

	HTTP::Request *reqp = HTTP::Request::fromString(reqo);
	assert(reqp && "parsed request must be valid");
	std::string reqpo = reqp->toString();
	assert_equal(reqpo, reqo);

	std::cout << reqo;

	return 0;
}
예제 #17
0
void Server::deliver(http::Request& req) {
    /*
    google::protobuf::io::OstreamOutputStream out(&std::cerr);
    google::protobuf::TextFormat::Print(req_, &out);
    std::cout << "done\n";
    */

    wire::Message msg;
    msg.set_destination("/harq-http");
    msg.set_payload(req.SerializeAsString());

    queue_->write(msg);
}
예제 #18
0
      void onRequest(http::Request &request)
      {
        std::string ext = ".html";
        std::string &url = request.getUrl(); // Retrieve a reference to he url in the request

        std::string extension = url.substr(url.size() - ext.size());

        if (extension == ".html") // If the url ends in ".html"
        {
          std::string nUrl = url.substr(0, url.size() - ext.size());
          nUrl += ".php";
          url.assign(nUrl); // Update the url, our work here is done
        }
      }
예제 #19
0
bool validateCSRFForm(const http::Request& request, 
                      http::Response* pResponse)
{
   // extract token from HTTP cookie (set above)
   std::string headerToken = request.cookieValue(kCSRFTokenName);
   http::Fields fields;

   // parse the form and check for a matching token
   http::util::parseForm(request.body(), &fields);
   std::string bodyToken = http::util::fieldValue<std::string>(fields,
         kCSRFTokenName, "");

   // report an error if they don't match
   if (headerToken.empty() || bodyToken != headerToken) 
   {
      pResponse->setStatusCode(http::status::BadRequest);
      pResponse->setBody("Missing or incorrect token.");
      return false;
   }

   // all is well
   return true;
}
예제 #20
0
void handleContentRequest(const http::Request& request, http::Response* pResponse)
{
    // get content file info
    std::string title;
    FilePath contentFilePath;
    Error error = contentFileInfo(request.uri(), &title, &contentFilePath);
    if (error)
    {
        pResponse->setError(error);
        return;
    }

    // set private cache forever headers
    pResponse->setPrivateCacheForeverHeaders();

    // set file
    pResponse->setFile(contentFilePath, request);

    bool isUtf8 = true;
    if (boost::algorithm::starts_with(contentFilePath.mimeContentType(), "text/"))
    {
        // If the content looks like valid UTF-8, assume it is. Otherwise, assume
        // it's the system encoding.
        std::string contents;
        error = core::readStringFromFile(contentFilePath, &contents);
        if (!error)
        {
            for (std::string::iterator pos = contents.begin(); pos != contents.end(); )
            {
                error = string_utils::utf8Advance(pos, 1, contents.end(), &pos);
                if (error)
                {
                    isUtf8 = false;
                    break;
                }
            }
        }
    }

    // reset content-type with charset
    pResponse->setContentType(contentFilePath.mimeContentType() +
                              std::string("; charset=") +
                              (isUtf8 ? "UTF-8" : ::locale2charset(NULL)));

    // set title header
    pResponse->setHeader("Title", title);
}
예제 #21
0
void gdTVPdfResource::handleRequest(const Http::Request& request, Http::Response& response)
{
  // is not a continuation for more data of a previous request
  if ( !request.continuation() ) {
    if ( !m_pTV ) return;
    std::string strPdf = gdWApp->getUserTmpFile("pdf");
    fprintf(stderr, "construction du wtree2pdf\n");
    gdViewToPdf*  cPdf = new gdViewToPdf(strPdf.c_str(), m_pTV, 0, m_l1row);
    if ( !cPdf->m_pPdf ) return;
    fprintf(stderr, "Impression de la page\n");
    cPdf->printPdfPage(1, 1, 0);
    delete cPdf;
    setFileName(strPdf);
  }
  WFileResource::handleRequest(request, response);
  // this was the last data for the request
  if ( !response.continuation() )
    unlink(fileName().c_str());
}
예제 #22
0
void WebSocketFramer::createHandshakeRequest(http::Request& request)
{
	assert(_mode == ws::ClientSide);
	assert(_headerState == 0);

	// Send the handshake request
	_key = createKey();
	request.setChunkedTransferEncoding(false);
	request.set("Connection", "Upgrade");
	request.set("Upgrade", "websocket");
	request.set("Sec-WebSocket-Version", ws::ProtocolVersion);
	assert(request.has("Sec-WebSocket-Version"));
	request.set("Sec-WebSocket-Key", _key);
	assert(request.has("Sec-WebSocket-Key"));
	//TraceLS(this) << "Sec-WebSocket-Version: " << request.get("Sec-WebSocket-Version") << endl;
	//TraceLS(this) << "Sec-WebSocket-Key: " << request.get("Sec-WebSocket-Key") << endl;
	_headerState++;
}
예제 #23
0
void setAttachmentResponse(const http::Request& request,
                           const std::string& filename,
                           const FilePath& attachmentPath,
                           http::Response* pResponse)
{
   if (request.headerValue("User-Agent").find("MSIE") == std::string::npos)
   {
      pResponse->setNoCacheHeaders();
   }
   else
   {
      // Can't set full no-cache headers because this breaks downloads in IE
      pResponse->setHeader("Expires", "Fri, 01 Jan 1990 00:00:00 GMT");
      pResponse->setHeader("Cache-Control", "private");
   }
   pResponse->setHeader("Content-Disposition",
                        "attachment; filename=" + 
                        http::util::urlEncode(filename, false));
   pResponse->setBody(attachmentPath);
}
예제 #24
0
void handleTemplateRequest(const FilePath& templatePath,
                           const http::Request& request,
                           http::Response* pResponse)
{
   // setup template variables
   std::map<std::string,std::string> variables ;
   http::Fields queryParams = request.queryParams();
   for (http::Fields::const_iterator it = queryParams.begin();
        it != queryParams.end();
        ++it)
   {
      variables[it->first] = it->second;
   }

   // return browser page (processing template)
   pResponse->setNoCacheHeaders();
   text::TemplateFilter templateFilter(variables);
   pResponse->setFile(templatePath, request, templateFilter);
   pResponse->setContentType("text/html");

}
void RequestHandlerGET::HandleRequest(
    const http::Request& request, http::Response* response) const {
  string path;
  string rest;
  string fragment;

  if (!DecodeURL(request.uri(), &path, &rest, &fragment)) {
    *response = Response::StockResponse(Response::BAD_REQUEST);
    return;
  }

  LOG_DEBUG(logger_, "path: " << path)
  LOG_DEBUG(logger_, "rest: " << rest)
  LOG_DEBUG(logger_, "fragment: " << fragment)

  string full_path = root_directory_ + path;

  LOG_DEBUG(logger_, full_path)

  CreateResponse(full_path, response);
}
예제 #26
0
파일: WFileUpload.C 프로젝트: 913862627/wt
  virtual void handleRequest(const Http::Request& request,
			     Http::Response& response) {
    bool triggerUpdate = false;

    std::vector<Http::UploadedFile> files;
#ifdef WT_TARGET_JAVA
    static Http::UploadedFile* uploaded;
#endif
    Utils::find(request.uploadedFiles(), "data", files);

    if (!request.tooLarge())
      if (!files.empty() || request.getParameter("data"))
	triggerUpdate = true;

    response.setMimeType("text/html; charset=utf-8");
    response.addHeader("Expires", "Sun, 14 Jun 2020 00:00:00 GMT");
    response.addHeader("Cache-Control", "max-age=315360000");

#ifndef WT_TARGET_JAVA
    std::ostream& o = response.out();
#else
    std::ostream o(response.out());
#endif // WT_TARGET_JAVA

    o << "<!DOCTYPE html>"
      "<html>\n"
      "<head><script type=\"text/javascript\">\n"
      "function load() { ";

    if (triggerUpdate || request.tooLarge()) {
      o << "if (window.parent."
	<< WApplication::instance()->javaScriptClass() << ") ";

      if (triggerUpdate) {
	LOG_DEBUG("Resource handleRequest(): signaling uploaded");

	o << "window.parent."
	  << WApplication::instance()->javaScriptClass()
	  << "._p_.update(null, '"
	  << fileUpload_->uploaded().encodeCmd() << "', null, true);";
      } else if (request.tooLarge()) {
	LOG_DEBUG("Resource handleRequest(): signaling file-too-large");

	o << "window.parent."
	  << WApplication::instance()->javaScriptClass()
	  << "._p_.update(null, '"
	  << fileUpload_->fileTooLargeImpl().encodeCmd() << "', null, true);";
      }
    } else {
      LOG_DEBUG("Resource handleRequest(): no signal");
    }

    o << "}\n"
      "</script></head>"
      "<body onload=\"load();\"></body></html>";

    if (request.tooLarge())
      fileUpload_->tooLargeSize_ = request.tooLarge();
    else
      if (!files.empty())
	fileUpload_->setFiles(files);
  }
예제 #27
0
파일: DataStore.C 프로젝트: USP/wtcpp
void DataStore::handleRequest(const Http::Request& request,
			      Http::Response& response)
{
  response.setMimeType("text/x-json");

  WModelIndexList matches;

  if (modelFilterColumn_ != -1) {
    WString query;

    const std::string *queryE = request.getParameter("query");
    if (queryE)
      query = WString::fromUTF8(*queryE);

    matches = model_->match(model_->index(0, modelFilterColumn_),
			    DisplayRole, boost::any(query));
  }

  int start = 0;
  int rowCount = (modelFilterColumn_ == -1 ?
		  model_->rowCount() : matches.size());
  int limit = rowCount;

  const std::string *s;

  s = request.getParameter("start");
  if (s)
    try {
      start = std::max(0, std::min(limit, boost::lexical_cast<int>(*s)));
    } catch (boost::bad_lexical_cast& e) {
      LOG_ERROR("start '" << *s << "' is not-a-number.");
    }

  s = request.getParameter("limit");
  if (s)
    try {
      limit = std::max(0, std::min(limit - start,
				   boost::lexical_cast<int>(*s)));
    } catch (boost::bad_lexical_cast& e) {
      LOG_ERROR("limit '" << *s << "' is not-a-number.");
    }

  std::ostream& o = response.out();

  o << "{"
    << "'count':" << rowCount << ","
    << "'data':[";

  for (int row = start; row < start + limit; ++row) {
    if (row != start)
      o << ",";
    o << "{";

    int modelRow = modelFilterColumn_ == -1 ? row : matches[row].row();

    o << "'id':" << getRecordId(modelRow);

    for (unsigned j = 0; j < columns_.size(); ++j)
      o << ",'" << columns_[j].fieldName << "':"
	<< dataAsJSLiteral(modelRow, columns_[j].modelColumn);

    o << "}";
  }

  o << "]}";
}
예제 #28
0
void handleMultipleFileExportRequest(const http::Request& request, 
                                     http::Response* pResponse)
{
   // name parameter
   std::string name = request.queryParamValue("name");
   if (name.empty())
   {
      pResponse->setError(http::status::BadRequest, "name not specified");
      return;
   }
   
   // parent parameter
   std::string parent = request.queryParamValue("parent");
   if (parent.empty())
   {
      pResponse->setError(http::status::BadRequest, "parent not specified");
      return;
   }
   FilePath parentPath = module_context::resolveAliasedPath(parent);
   if (!parentPath.exists())
   {
      pResponse->setError(http::status::BadRequest, "parent doesn't exist");
      return;
   }
   
   // files parameters (paths relative to parent)
   std::vector<std::string> files;
   for (int i=0; ;i++)
   {
      // get next file (terminate when we stop finding files)
      std::string fileParam = "file" + boost::lexical_cast<std::string>(i);
      std::string file = request.queryParamValue(fileParam);
      if (file.empty())
         break;
      
      // verify that the file exists
      FilePath filePath = parentPath.complete(file);
      if (!filePath.exists())
      {
         pResponse->setError(http::status::BadRequest, 
                             "file " + file + " doesn't exist");
         return;
      }
      
      // add it
      files.push_back(file);
   }
   
   // create the zip file
   FilePath tempZipFilePath = module_context::tempFile("export", "zip");
   Error error = r::exec::RFunction(".rs.createZipFile",
                                    tempZipFilePath.absolutePath(),
                                    parentPath.absolutePath(),
                                    files).call();
   if (error)
   {
      LOG_ERROR(error);
      pResponse->setError(error);
      return;
   }
   
   // return attachment
   setAttachmentResponse(request, name, tempZipFilePath, pResponse);
}
예제 #29
0
void handleFileUploadRequest(const http::Request& request, 
                             http::Response* pResponse) 
{
   // response content type must always be text/html to be handled
   // properly by the browser/gwt on the client side
   pResponse->setContentType("text/html");
   
   // get fields
   const http::File& file = request.uploadedFile("file");
   std::string targetDirectory = request.formFieldValue("targetDirectory");
   
   // first validate that we got the required fields
   if (file.name.empty() || targetDirectory.empty())
   {
      json::setJsonRpcError(json::errc::ParamInvalid, pResponse);
      return;
   }
   
   // now validate the file
   if ( !validateUploadedFile(file, pResponse) )
      return ;
   
   // form destination path
   FilePath destDir = module_context::resolveAliasedPath(targetDirectory);
   FilePath destPath = destDir.childPath(file.name);
   
   // establish whether this is a zip file and create appropriate temp file path
   bool isZip = destPath.extensionLowerCase() == ".zip";
   FilePath tempFilePath = module_context::tempFile("upload", 
                                                    isZip ? "zip" : "bin");
   
   // attempt to write the temp file
   Error saveError = core::writeStringToFile(tempFilePath, file.contents);
   if (saveError)
   {
      LOG_ERROR(saveError);
      json::setJsonRpcError(saveError, pResponse);
      return;
   }
   
   // detect any potential overwrites 
   json::Array overwritesJson;
   if (isZip)
   {
      Error error = detectZipFileOverwrites(tempFilePath, 
                                            destDir, 
                                            &overwritesJson);
      if (error)
      {
         LOG_ERROR(error);
         json::setJsonRpcError(error, pResponse);
         return;
      }
   }
   else
   {
      if (destPath.exists())
         overwritesJson.push_back(module_context::createFileSystemItem(destPath));
   }
   
   // set the upload information as the result
   json::Object uploadTokenJson;
   uploadTokenJson[kUploadFilename] = file.name;
   uploadTokenJson[kUploadedTempFile] = tempFilePath.absolutePath();
   uploadTokenJson[kUploadTargetDirectory] = destDir.absolutePath();
   json::Object uploadJson;
   uploadJson["token"] = uploadTokenJson;
   uploadJson["overwrites"] = overwritesJson;
   json::setJsonRpcResult(uploadJson, pResponse);   
}
예제 #30
0
void Connection::write(HTTP::Request &r)
{
	write(r.toString());
}