void EmbeddedResourceHttpHandler::Handle(
    HttpOutput& output,
    HttpMethod method,
    const UriComponents& uri,
    const Arguments& headers,
    const Arguments& arguments,
    const std::string&)
  {
    if (method != HttpMethod_Get)
    {
      output.SendMethodNotAllowedError("GET");
      return;
    }

    std::string resourcePath = Toolbox::FlattenUri(uri, baseUri_.size());
    std::string contentType = Toolbox::AutodetectMimeType(resourcePath);

    try
    {
      const void* buffer = EmbeddedResources::GetDirectoryResourceBuffer(resourceId_, resourcePath.c_str());
      size_t size = EmbeddedResources::GetDirectoryResourceSize(resourceId_, resourcePath.c_str());
      output.AnswerBufferWithContentType(buffer, size, contentType);
    }
    catch (OrthancException&)
    {
      LOG(WARNING) << "Unable to find HTTP resource: " << resourcePath;
      output.SendHeader(HttpStatus_404_NotFound);
    }
  } 
  static void OutputDirectoryContent(HttpOutput& output,
                                     const IHttpHandler::Arguments& headers,
                                     const UriComponents& uri,
                                     const boost::filesystem::path& p)
  {
    namespace fs = boost::filesystem;

    std::string s;
    s += "<html>";
    s += "  <body>";
    s += "    <h1>Subdirectories</h1>";
    s += "    <ul>";

    if (uri.size() > 0)
    {
      std::string h = Toolbox::FlattenUri(uri) + "/..";
      s += "<li><a href=\"" + h + "\">..</a></li>";
    }

    fs::directory_iterator end;
    for (fs::directory_iterator it(p) ; it != end; ++it)
    {
#if BOOST_HAS_FILESYSTEM_V3 == 1
      std::string f = it->path().filename().string();
#else
      std::string f = it->path().filename();
#endif

      std::string h = Toolbox::FlattenUri(uri) + "/" + f;
      if (fs::is_directory(it->status()))
        s += "<li><a href=\"" + h + "\">" + f + "</a></li>";
    }      

    s += "    </ul>";      
    s += "    <h1>Files</h1>";
    s += "    <ul>";

    for (fs::directory_iterator it(p) ; it != end; ++it)
    {
#if BOOST_HAS_FILESYSTEM_V3 == 1
      std::string f = it->path().filename().string();
#else
      std::string f = it->path().filename();
#endif

      std::string h = Toolbox::FlattenUri(uri) + "/" + f;
      if (SystemToolbox::IsRegularFile(it->path().string()))
      {
        s += "<li><a href=\"" + h + "\">" + f + "</a></li>";
      }
    }      

    s += "    </ul>";
    s += "  </body>";
    s += "</html>";

    output.SetContentType("text/html");
    output.Answer(s);
  }
  bool FilesystemHttpHandler::Handle(
    HttpOutput& output,
    RequestOrigin /*origin*/,
    const char* /*remoteIp*/,
    const char* /*username*/,
    HttpMethod method,
    const UriComponents& uri,
    const Arguments& headers,
    const GetArguments& arguments,
    const char* /*bodyData*/,
    size_t /*bodySize*/)
  {
    if (!Toolbox::IsChildUri(pimpl_->baseUri_, uri))
    {
      // This URI is not served by this handler
      return false;
    }

    if (method != HttpMethod_Get)
    {
      output.SendMethodNotAllowed("GET");
      return true;
    }

    namespace fs = boost::filesystem;

    fs::path p = pimpl_->root_;
    for (size_t i = pimpl_->baseUri_.size(); i < uri.size(); i++)
    {
      p /= uri[i];
    }

    if (fs::exists(p) && fs::is_regular_file(p))
    {
      FilesystemHttpSender sender(p);
      output.Answer(sender);   // TODO COMPRESSION
    }
    else if (listDirectoryContent_ &&
             fs::exists(p) && 
             fs::is_directory(p))
    {
      OutputDirectoryContent(output, headers, uri, p);
    }
    else
    {
      output.SendStatus(HttpStatus_404_NotFound);
    }

    return true;
  } 
  bool FilesystemHttpSender::SendData(HttpOutput& output)
  {
    FILE* fp = fopen(path_.string().c_str(), "rb");
    if (!fp)
    {
      return false;
    }

    std::vector<uint8_t> buffer(1024 * 1024);  // Chunks of 1MB

    for (;;)
    {
      size_t nbytes = fread(&buffer[0], 1, buffer.size(), fp);
      if (nbytes == 0)
      {
        break;
      }
      else
      {
        output.Send(&buffer[0], nbytes);
      }
    }

    fclose(fp);

    return true;
  }
  bool FilesystemHttpHandler::Handle(
    HttpOutput& output,
    HttpMethod method,
    const UriComponents& uri,
    const Arguments& headers,
    const GetArguments& arguments,
    const std::string&)
  {
    if (!Toolbox::IsChildUri(pimpl_->baseUri_, uri))
    {
      // This URI is not served by this handler
      return false;
    }

    if (method != HttpMethod_Get)
    {
      output.SendMethodNotAllowed("GET");
      return true;
    }

    namespace fs = boost::filesystem;

    fs::path p = pimpl_->root_;
    for (size_t i = pimpl_->baseUri_.size(); i < uri.size(); i++)
    {
      p /= uri[i];
    }

    if (fs::exists(p) && fs::is_regular_file(p))
    {
      FilesystemHttpSender(p).Send(output);

      //output.AnswerFileAutodetectContentType(p.string());
    }
    else if (listDirectoryContent_ &&
             fs::exists(p) && 
             fs::is_directory(p))
    {
      OutputDirectoryContent(output, uri, p);
    }
    else
    {
      output.SendStatus(HttpStatus_404_NotFound);
    }

    return true;
  } 
Beispiel #6
0
void RestApi::Handle(HttpOutput& httpOutput, const std::string& uri, const std::string& method, const std::string& body)
{
    if (method == "GET")
    {
        bool foundHandler = false;
        for (GetHandlersType::iterator it = GetHandlers.begin(); it != GetHandlers.end(); ++it)
        {
            boost::regex ex(it->first);
            if (boost::regex_match(uri, ex))
            {
                RestApiOutput restApiOutput(httpOutput);
                RestApiGetCall restApiGetCall(restApiOutput, *this);

                const int subs[] = {1};  // we just want to see group 1
                boost::sregex_token_iterator i(uri.begin(), uri.end(), ex, subs);
                std::string id = *i;

                restApiGetCall.SetResourceID(id);

                it->second(restApiGetCall);
                foundHandler = true;
                break;
            }
        }
        if (!foundHandler)
        {
            httpOutput.SendBody("Handler not found\n");
            return;
        }
    }
    else if (method == "POST")
    {
        bool foundHandler = false;
        for (PostHandlersType::iterator it = PostHandlers.begin(); it != PostHandlers.end(); ++it)
        {
            boost::regex ex(it->first);
            if (boost::regex_match(uri, ex))
            {
                RestApiOutput restApiOutput(httpOutput);
                RestApiPostCall restApiPostCall(restApiOutput, *this, body);

                const int subs[] = {1};  // we just want to see group 1
                boost::regex ex2(it->first);
                boost::sregex_token_iterator i(uri.begin(), uri.end(), ex2, subs);
                std::string id = *i;

                restApiPostCall.SetResourceID(id);

                it->second(restApiPostCall);
                foundHandler = true;
                break;
            }
        }
        if (!foundHandler)
        {
            httpOutput.SendBody("Handler not found");
            return;
        }
    }
    else
    {
        httpOutput.SendBody("Not implemented");
        return;
    }
}
Beispiel #7
0
void FrontEnd::httpConnectorOnNewClient(HttpServerTask *task, Interface *intf, NPT_Socket *client)
{
	NPT_Result nr;
	NPT_InputStreamReference inputStream0;
	nr = client->GetInputStream(inputStream0);
	if (NPT_FAILED(nr)) {
		return;
	}

	NPT_OutputStreamReference outputStream;
	nr = client->GetOutputStream(outputStream);
	if (NPT_FAILED(nr)) {
		return;
	}

	NPT_BufferedInputStreamReference inputStream(new NPT_BufferedInputStream(inputStream0));

	NPT_HttpRequest *req;

	nr = NPT_HttpRequest::Parse(*inputStream.AsPointer(), NULL, req);
	if (NPT_FAILED(nr)) {
		return;
	}

	// TODO: validate "HOST" ???

	RequestContext reqCtx;
	reqCtx.clientHint = CH_Unknown;
	reqCtx.transferMode = TM_None;
	reqCtx.getcontentFeaturesReq = false;

	NPT_HttpHeader *hdrUserAgent = req->GetHeaders().GetHeader(NPT_HTTP_HEADER_USER_AGENT);
	if (hdrUserAgent) {
		if (hdrUserAgent->GetValue().Find("xbox", 0, true) >= 0) {
			NPT_LOG_INFO_1("XBox found [User-Agent: %s]", hdrUserAgent->GetValue().GetChars());
			reqCtx.clientHint = CH_XBox;
		}
	}

	NPT_HttpHeader *hdrTransferMode = req->GetHeaders().GetHeader("transferMode.dlna.org");
	if (hdrTransferMode) {
		const NPT_String& transferMode = hdrTransferMode->GetValue();
		if (transferMode.Compare("Streaming", true) == 0) {
			reqCtx.transferMode = TM_Streaming;
		} else if (transferMode.Compare("Interactive", true) == 0) {
			reqCtx.transferMode = TM_Interactive;
		} else if (transferMode.Compare("Background", true) == 0) {
			reqCtx.transferMode = TM_Background;
		} else {
			reqCtx.transferMode = TM_Unknown;
		}
	}

	NPT_HttpHeader *hdrGetContentFeatures = req->GetHeaders().GetHeader("getcontentFeatures.dlna.org");
	if (hdrGetContentFeatures) {
		NPT_String getContentFeatures = hdrGetContentFeatures->GetValue();
		if (getContentFeatures.Trim().Compare("1") == 0) {
			reqCtx.getcontentFeaturesReq = true;
		}
	}

	NPT_SocketInfo si;
	client->GetInfo(si);
	onHttpRequestHeader(si, req);

	PtrHolder<NPT_HttpRequest> req1(req);
	NPT_String reqPath(req->GetUrl().GetPath());

	NPT_TimeStamp ts;
	NPT_System::GetCurrentTimeStamp(ts);
	NPT_String dateStr = NPT_DateTime(ts).ToString(NPT_DateTime::FORMAT_RFC_1123);

	NPT_HttpResponse *resp = new NPT_HttpResponse(200, "OK", NPT_HTTP_PROTOCOL_1_1);
	PtrHolder<NPT_HttpResponse> resp1(resp);
	resp->GetHeaders().SetHeader(NPT_HTTP_HEADER_SERVER, m_serverHeader);
	resp->GetHeaders().SetHeader("Date", dateStr);
	resp->GetHeaders().SetHeader(NPT_HTTP_HEADER_CONTENT_LENGTH, "0");
	resp->GetHeaders().SetHeader(NPT_HTTP_HEADER_CONTENT_TYPE, "text/xml");

	HttpOutput *httpOutput = new HttpOutputImpl(this, si, outputStream);
	PtrHolder<HttpOutput> httpOutput1(httpOutput);

	{
		ReadLocker locker(m_cpLock);
		for (NPT_Ordinal i = 0; i < m_controlPointList.GetItemCount(); i++) {
			NPT_List<ControlPointInfo*>::Iterator it = m_controlPointList.GetItem(i);
			ControlPointInfo *info = *it;
			if (reqPath.StartsWith(info->m_context.m_httpRoot)) {
				NPT_InputStream *input = inputStream.AsPointer();
				inputStream.Detach();
				httpOutput1.detach();
				resp1.detach();
				req1.detach();
				task->detach();
				return info->m_controlPoint->processHttpRequest(&intf->m_context, reqPath.SubString(info->m_context.m_httpRoot.GetLength()), reqCtx, req, resp, input, httpOutput, client);
			}
		}
	}

	{
		ReadLocker locker(m_dsLock);
		for (NPT_Ordinal i = 0; i < m_deviceImplList.GetItemCount(); i++) {
			NPT_List<DeviceImplInfo*>::Iterator it = m_deviceImplList.GetItem(i);
			DeviceImplInfo *info = *it;
			if (reqPath.StartsWith(info->m_context.m_httpRoot)) {
				NPT_InputStream *input = inputStream.AsPointer();
				inputStream.Detach();
				httpOutput1.detach();
				resp1.detach();
				req1.detach();
				task->detach();
				return info->m_deviceImpl->processHttpRequest(&intf->m_context, reqPath.SubString(info->m_context.m_httpRoot.GetLength()), reqCtx, req, resp, input, httpOutput, client);
			}
		}
	}

	setStatusCode(*resp, 404);
	httpOutput->writeResponseHeader(*resp);
	httpOutput->flush();

}