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; }
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; } }
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(); }