Add even more of the source
This should be about everything needed to build so far?
This commit is contained in:
parent
af3619d4fa
commit
849723c9cf
547 changed files with 149239 additions and 0 deletions
123
APIModules/QTSSHomeDirectoryModule/DirectoryInfo.cpp
Normal file
123
APIModules/QTSSHomeDirectoryModule/DirectoryInfo.cpp
Normal file
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: DirectoryInfo.cpp
|
||||
|
||||
Contains: Implementation of class defined in .h file
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include "DirectoryInfo.h"
|
||||
|
||||
Bool16 SessionListElement::Equal(QTSS_ClientSessionObject* inSessionPtr)
|
||||
{
|
||||
UInt32 *theSessionID = 0;
|
||||
UInt32 *inSessionID = 0;
|
||||
UInt32 theLen = 0;
|
||||
|
||||
(void)QTSS_GetValuePtr(fSession, qtssCliSesCounterID, 0, (void **)&theSessionID, &theLen);
|
||||
Assert(theLen != 0);
|
||||
(void)QTSS_GetValuePtr(*inSessionPtr, qtssCliSesCounterID, 0, (void **)&inSessionID, &theLen);
|
||||
Assert(theLen != 0);
|
||||
|
||||
if (*theSessionID == *inSessionID)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
UInt32 SessionListElement::CurrentBitRate()
|
||||
{
|
||||
UInt32 *theBitRate = 0;
|
||||
UInt32 theLen = 0;
|
||||
|
||||
(void)QTSS_GetValuePtr(fSession, qtssCliSesCurrentBitRate, 0, (void **)&theBitRate, &theLen);
|
||||
Assert(theLen != 0);
|
||||
|
||||
return *theBitRate;
|
||||
}
|
||||
|
||||
static bool IsSession(PLDoubleLinkedListNode<SessionListElement>* node, void* userData)
|
||||
{
|
||||
/*
|
||||
used by ForEachUntil to find a SessionListElement with a given Session
|
||||
userData is a pointer to the QTSS_ClientSessionObject we want to find
|
||||
|
||||
*/
|
||||
return node->fElement->Equal((QTSS_ClientSessionObject *)userData);
|
||||
}
|
||||
|
||||
static void AddCurrentBitRate(PLDoubleLinkedListNode<SessionListElement>* node, void* userData)
|
||||
{
|
||||
*(UInt64 *)userData += node->fElement->CurrentBitRate();
|
||||
}
|
||||
|
||||
DirectoryInfo::~DirectoryInfo()
|
||||
{
|
||||
fMutex.Lock();
|
||||
fClientSessionList->ClearList();
|
||||
fNumSessions = 0;
|
||||
fHomeDir.Delete();
|
||||
fMutex.Unlock();
|
||||
}
|
||||
|
||||
void DirectoryInfo::AddSession(QTSS_ClientSessionObject *sessionPtr)
|
||||
{
|
||||
fMutex.Lock();
|
||||
|
||||
SessionListElement *theElement = NEW SessionListElement(sessionPtr);
|
||||
PLDoubleLinkedListNode<SessionListElement> *sessionNode = new PLDoubleLinkedListNode<SessionListElement> (theElement);
|
||||
fClientSessionList->AddNode(sessionNode);
|
||||
fNumSessions++;
|
||||
|
||||
fMutex.Unlock();
|
||||
}
|
||||
|
||||
void DirectoryInfo::RemoveSession(QTSS_ClientSessionObject *sessionPtr)
|
||||
{
|
||||
fMutex.Lock();
|
||||
|
||||
PLDoubleLinkedListNode<SessionListElement> *node = NULL;
|
||||
|
||||
node = fClientSessionList->ForEachUntil(IsSession, (void *)sessionPtr);
|
||||
if (node != NULL)
|
||||
{
|
||||
fClientSessionList->RemoveNode(node);
|
||||
fNumSessions--;
|
||||
}
|
||||
|
||||
fMutex.Unlock();
|
||||
}
|
||||
|
||||
UInt64 DirectoryInfo::CurrentTotalBandwidthInKbps()
|
||||
{
|
||||
fMutex.Lock();
|
||||
UInt64 totalBandwidth = 0;
|
||||
fClientSessionList->ForEach(AddCurrentBitRate, &totalBandwidth);
|
||||
fMutex.Unlock();
|
||||
|
||||
return (totalBandwidth/1024);
|
||||
}
|
79
APIModules/QTSSHomeDirectoryModule/DirectoryInfo.h
Normal file
79
APIModules/QTSSHomeDirectoryModule/DirectoryInfo.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: DirectoryInfo.h
|
||||
|
||||
Contains: Stores an array of client sessions, # of client sessions,
|
||||
and the home directory
|
||||
|
||||
|
||||
*/
|
||||
#ifndef _DIRECTORYINFO_H_
|
||||
#define _DIRECTORYINFO_H_
|
||||
#include "QTSS.h"
|
||||
#include "StrPtrLen.h"
|
||||
#include "OSRef.h"
|
||||
#include "OSMemory.h"
|
||||
#include "PLDoubleLinkedList.h"
|
||||
|
||||
class SessionListElement {
|
||||
public:
|
||||
SessionListElement(QTSS_ClientSessionObject *inSessionPtr) { fSession = *inSessionPtr; }
|
||||
|
||||
virtual ~SessionListElement() { fSession = NULL; }
|
||||
|
||||
Bool16 Equal(QTSS_ClientSessionObject* inSessionPtr);
|
||||
UInt32 CurrentBitRate();
|
||||
|
||||
private:
|
||||
QTSS_ClientSessionObject fSession;
|
||||
};
|
||||
|
||||
class DirectoryInfo
|
||||
{
|
||||
public:
|
||||
DirectoryInfo(StrPtrLen *inHomeDir):fNumSessions(0), fHomeDir(inHomeDir->GetAsCString())
|
||||
{
|
||||
fClientSessionList = NEW PLDoubleLinkedList<SessionListElement>;
|
||||
fRef.Set(fHomeDir, (void *)this);
|
||||
}
|
||||
|
||||
~DirectoryInfo();
|
||||
OSRef* GetRef() { return &fRef; }
|
||||
void AddSession(QTSS_ClientSessionObject *sessionPtr);
|
||||
void RemoveSession(QTSS_ClientSessionObject *sessionPtr);
|
||||
UInt64 CurrentTotalBandwidthInKbps();
|
||||
UInt32 NumSessions() { return fNumSessions; }
|
||||
|
||||
private:
|
||||
OSRef fRef;
|
||||
OSMutex fMutex;
|
||||
PLDoubleLinkedList<SessionListElement> *fClientSessionList;
|
||||
UInt32 fNumSessions;
|
||||
StrPtrLen fHomeDir;
|
||||
};
|
||||
|
||||
|
||||
#endif // _DIRECTORYINFO_H_
|
416
APIModules/QTSSHomeDirectoryModule/QTSSHomeDirectoryModule.cpp
Normal file
416
APIModules/QTSSHomeDirectoryModule/QTSSHomeDirectoryModule.cpp
Normal file
|
@ -0,0 +1,416 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: QTSSHomeDirectoryModule.cpp
|
||||
|
||||
Contains: Module that expands ~ in request URLs to home directories
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "SafeStdLib.h"
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include "OSMemory.h"
|
||||
#include "StringParser.h"
|
||||
#include "ResizeableStringFormatter.h"
|
||||
#include "QTSSModuleUtils.h"
|
||||
#include "OSArrayObjectDeleter.h"
|
||||
#include "DirectoryInfo.h"
|
||||
#include "QTSSMemoryDeleter.h"
|
||||
|
||||
#include "QTSSHomeDirectoryModule.h"
|
||||
|
||||
#define HOME_DIRECTORY_MODULE_DEBUGGING 0
|
||||
|
||||
// STATIC DATA
|
||||
static QTSS_ServerObject sServer = NULL;
|
||||
static QTSS_ModuleObject sModule = NULL;
|
||||
static QTSS_ModulePrefsObject sPrefs = NULL;
|
||||
|
||||
// Attributes
|
||||
static char* sIsFirstRequestName = "QTSSHomeDirectoryModuleIsFirstRequest";
|
||||
static QTSS_AttributeID sIsFirstRequestAttr = qtssIllegalAttrID;
|
||||
static char* sRequestHomeDirAttrName = "QTSSHomeDirectoryModuleHomeDir";
|
||||
static QTSS_AttributeID sRequestHomeDirAttr = qtssIllegalAttrID;
|
||||
static char* sSessionHomeDirAttrName = "QTSSHomeDirectoryModuleHomeDir";
|
||||
static QTSS_AttributeID sSessionHomeDirAttr = qtssIllegalAttrID;
|
||||
|
||||
// Module description and version
|
||||
static char* sDescription = "Provides support for streaming from users' home directories";
|
||||
static UInt32 sVersion = 0x00010000;
|
||||
|
||||
// Module preferences and their defaults
|
||||
static Bool16 sEnabled = false;
|
||||
static Bool16 kDefaultEnabled = false;
|
||||
static char* sMoviesDirectory = NULL; // Streaming dir in user's home dir
|
||||
static char* kDefaultMoviesDirectory = "/Sites/Streaming/";
|
||||
static UInt32 sMaxNumConnsPerHomeDir = 0; //Max conns. allowed per home directory
|
||||
static UInt32 kDefaultMaxNumConnsPerHomeDir = 0; // 0 => no limit enforced
|
||||
static UInt32 sMaxBWInKbpsPerHomeDir = 0; // Max BW allowed per home directory
|
||||
static UInt32 kDefaultMaxBWInKbpsPerHomeDir = 0; // 0 => no limit enforced
|
||||
|
||||
enum { kDefaultHomeDirSize = 64 };
|
||||
static Bool16 sTrue = true;
|
||||
|
||||
static OSRefTable* sDirectoryInfoMap = NULL;
|
||||
|
||||
// FUNCTIONS
|
||||
static QTSS_Error QTSSHomeDirectoryDispatch(QTSS_Role inRole, QTSS_RoleParamPtr inParams);
|
||||
static QTSS_Error Register(QTSS_Register_Params* inParams);
|
||||
static QTSS_Error Initialize(QTSS_Initialize_Params* inParams);
|
||||
static QTSS_Error RereadPrefs();
|
||||
static QTSS_Error RewriteRequestFilePathAndRootDir(QTSS_StandardRTSP_Params* inParams);
|
||||
static void RewriteRootDir(QTSS_StandardRTSP_Params* inParams, StrPtrLen* inHomeDir);
|
||||
static QTSS_Error AuthorizeRequest(QTSS_StandardRTSP_Params* inParams);
|
||||
static QTSS_Error RemoveClientSessionFromMap(QTSS_ClientSessionClosing_Params* inParams);
|
||||
|
||||
// Helper functions
|
||||
static Bool16 ExpandPath(const StrPtrLen *inPathPtr, StrPtrLen *outPathPtr);
|
||||
|
||||
// FUNCTION IMPLEMENTATIONS
|
||||
QTSS_Error QTSSHomeDirectoryModule_Main(void* inPrivateArgs)
|
||||
{
|
||||
return _stublibrary_main(inPrivateArgs, QTSSHomeDirectoryDispatch);
|
||||
}
|
||||
|
||||
|
||||
QTSS_Error QTSSHomeDirectoryDispatch(QTSS_Role inRole, QTSS_RoleParamPtr inParams)
|
||||
{
|
||||
switch (inRole)
|
||||
{
|
||||
case QTSS_Register_Role:
|
||||
return Register(&inParams->regParams);
|
||||
case QTSS_Initialize_Role:
|
||||
return Initialize(&inParams->initParams);
|
||||
case QTSS_RereadPrefs_Role:
|
||||
return RereadPrefs();
|
||||
case QTSS_RTSPRoute_Role:
|
||||
{
|
||||
if (!sEnabled)
|
||||
break;
|
||||
return RewriteRequestFilePathAndRootDir(&inParams->rtspRouteParams);
|
||||
}
|
||||
case QTSS_RTSPAuthorize_Role:
|
||||
{
|
||||
if (!sEnabled)
|
||||
break;
|
||||
return AuthorizeRequest(&inParams->rtspAuthParams);
|
||||
}
|
||||
case QTSS_ClientSessionClosing_Role:
|
||||
{
|
||||
if (!sEnabled)
|
||||
break;
|
||||
return RemoveClientSessionFromMap(&inParams->clientSessionClosingParams);
|
||||
}
|
||||
}
|
||||
return QTSS_NoErr;
|
||||
}
|
||||
|
||||
|
||||
QTSS_Error Register(QTSS_Register_Params* inParams)
|
||||
{
|
||||
// Do role & attribute setup
|
||||
(void)QTSS_AddRole(QTSS_Initialize_Role);
|
||||
(void)QTSS_AddRole(QTSS_RereadPrefs_Role);
|
||||
(void)QTSS_AddRole(QTSS_RTSPRoute_Role);
|
||||
(void)QTSS_AddRole(QTSS_RTSPAuthorize_Role);
|
||||
(void)QTSS_AddRole(QTSS_ClientSessionClosing_Role);
|
||||
|
||||
// Add an RTSP session attribute to track if the request is the first request of the session
|
||||
// so that the bandwidth/# of connections quota check can be done only if it is the first request
|
||||
(void)QTSS_AddStaticAttribute(qtssRTSPSessionObjectType, sIsFirstRequestName, NULL, qtssAttrDataTypeBool16);
|
||||
(void)QTSS_IDForAttr(qtssRTSPSessionObjectType, sIsFirstRequestName, &sIsFirstRequestAttr);
|
||||
|
||||
// Add an RTSP request object attribute for tracking the home directory it is being served from
|
||||
(void)QTSS_AddStaticAttribute(qtssRTSPRequestObjectType, sRequestHomeDirAttrName, NULL, qtssAttrDataTypeCharArray);
|
||||
(void)QTSS_IDForAttr(qtssRTSPRequestObjectType, sRequestHomeDirAttrName, &sRequestHomeDirAttr);
|
||||
|
||||
// Add an RTP session object attribute for tracking the home directory it is being served from
|
||||
(void)QTSS_AddStaticAttribute(qtssClientSessionObjectType, sSessionHomeDirAttrName, NULL, qtssAttrDataTypeCharArray);
|
||||
(void)QTSS_IDForAttr(qtssClientSessionObjectType, sSessionHomeDirAttrName, &sSessionHomeDirAttr);
|
||||
|
||||
|
||||
// Tell the server our name!
|
||||
static char* sModuleName = "QTSSHomeDirectoryModule";
|
||||
::strcpy(inParams->outModuleName, sModuleName);
|
||||
|
||||
return QTSS_NoErr;
|
||||
}
|
||||
|
||||
|
||||
QTSS_Error Initialize(QTSS_Initialize_Params* inParams)
|
||||
{
|
||||
// Setup module utils
|
||||
QTSSModuleUtils::Initialize(inParams->inMessages, inParams->inServer, inParams->inErrorLogStream);
|
||||
|
||||
// Get the server object
|
||||
sServer = inParams->inServer;
|
||||
|
||||
// Get our prefs object
|
||||
sModule = inParams->inModule;
|
||||
sPrefs = QTSSModuleUtils::GetModulePrefsObject(sModule);
|
||||
|
||||
// Set our version and description
|
||||
(void)QTSS_SetValue(sModule, qtssModDesc, 0, sDescription, ::strlen(sDescription));
|
||||
(void)QTSS_SetValue(sModule, qtssModVersion, 0, &sVersion, sizeof(sVersion));
|
||||
|
||||
RereadPrefs();
|
||||
|
||||
sDirectoryInfoMap = NEW OSRefTable();
|
||||
|
||||
return QTSS_NoErr;
|
||||
}
|
||||
|
||||
|
||||
QTSS_Error RereadPrefs()
|
||||
{
|
||||
QTSSModuleUtils::GetAttribute(sPrefs, "enabled", qtssAttrDataTypeBool16,
|
||||
&sEnabled, &kDefaultEnabled, sizeof(sEnabled));
|
||||
delete [] sMoviesDirectory;
|
||||
sMoviesDirectory = QTSSModuleUtils::GetStringAttribute(sPrefs, "movies_directory", kDefaultMoviesDirectory);
|
||||
QTSSModuleUtils::GetAttribute(sPrefs, "max_num_conns_per_home_directory", qtssAttrDataTypeUInt32,
|
||||
&sMaxNumConnsPerHomeDir, &kDefaultMaxNumConnsPerHomeDir, sizeof(sMaxNumConnsPerHomeDir));
|
||||
QTSSModuleUtils::GetAttribute(sPrefs, "max_bandwidth_kbps_per_home_directory", qtssAttrDataTypeUInt32,
|
||||
&sMaxBWInKbpsPerHomeDir, &kDefaultMaxBWInKbpsPerHomeDir, sizeof(sMaxBWInKbpsPerHomeDir));
|
||||
return QTSS_NoErr;
|
||||
}
|
||||
|
||||
|
||||
QTSS_Error RewriteRequestFilePathAndRootDir(QTSS_StandardRTSP_Params* inParams)
|
||||
{
|
||||
QTSS_RTSPRequestObject theRequest = inParams->inRTSPRequest;
|
||||
|
||||
char* requestPathStr;
|
||||
(void)QTSS_GetValueAsString(theRequest, qtssRTSPReqFilePath, 0, &requestPathStr);
|
||||
QTSSCharArrayDeleter requestPathStrDeleter(requestPathStr);
|
||||
StrPtrLen theRequestPath(requestPathStr);
|
||||
StringParser theRequestPathParser(&theRequestPath);
|
||||
|
||||
// request path begins with a '/' for ex. /mysample.mov or /~joe/mysample.mov
|
||||
theRequestPathParser.Expect('/');
|
||||
|
||||
if (theRequestPathParser.PeekFast() == '~')
|
||||
{
|
||||
theRequestPathParser.Expect('~');
|
||||
|
||||
StrPtrLen theFirstPath;
|
||||
theRequestPathParser.ConsumeUntil(&theFirstPath, '/');
|
||||
if (theFirstPath.Len != 0) // if the URI is /~/mysample.mov --> do nothing
|
||||
{
|
||||
StrPtrLen theHomeDir;
|
||||
// ExpandPath allocates memory, so delete it before exiting
|
||||
if (ExpandPath(&theFirstPath, &theHomeDir))
|
||||
{
|
||||
// Rewrite the qtssRTSPReqRootDir attribute
|
||||
RewriteRootDir(inParams, &theHomeDir);
|
||||
|
||||
StrPtrLen theStrippedRequestPath;
|
||||
theRequestPathParser.ConsumeLength(&theStrippedRequestPath, theRequestPathParser.GetDataRemaining());
|
||||
(void) QTSS_SetValue(theRequest, qtssRTSPReqFilePath, 0, theStrippedRequestPath.Ptr, theStrippedRequestPath.Len);
|
||||
}
|
||||
theHomeDir.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
return QTSS_NoErr;
|
||||
}
|
||||
|
||||
void RewriteRootDir(QTSS_StandardRTSP_Params* inParams, StrPtrLen* inHomeDir)
|
||||
{
|
||||
QTSS_RTSPRequestObject theRequest = inParams->inRTSPRequest;
|
||||
QTSS_ClientSessionObject theSession = inParams->inClientSession;
|
||||
QTSS_Error theErr = QTSS_NoErr;
|
||||
|
||||
Assert(inHomeDir->Len != 0);
|
||||
if (inHomeDir->Len == 0)
|
||||
return;
|
||||
|
||||
char homeDirFormatterBuf[kDefaultHomeDirSize] = "";
|
||||
ResizeableStringFormatter theHomeDirFormatter(homeDirFormatterBuf, kDefaultHomeDirSize);
|
||||
theHomeDirFormatter.Put(inHomeDir->Ptr, inHomeDir->Len);
|
||||
// Append a path separator if the movies directory doesn't begin with it
|
||||
if ((::strlen(sMoviesDirectory) != 0) && (sMoviesDirectory[0] != '/'))
|
||||
theHomeDirFormatter.PutChar('/');
|
||||
// Append the movies_directory
|
||||
theHomeDirFormatter.Put(sMoviesDirectory);
|
||||
|
||||
StrPtrLen theRootDir(theHomeDirFormatter.GetBufPtr(), theHomeDirFormatter.GetBytesWritten());
|
||||
|
||||
// Set qtssRTSPReqRootDir
|
||||
(void)QTSS_SetValue(theRequest, qtssRTSPReqRootDir, 0, theRootDir.Ptr, theRootDir.Len);
|
||||
|
||||
// Set the client session's home dir attribute
|
||||
(void)QTSS_SetValue(theSession, sSessionHomeDirAttr, 0, theRootDir.Ptr, theRootDir.Len);
|
||||
|
||||
// If the request is a PLAY, then add this to the session list for the home directory
|
||||
QTSS_RTSPMethod *theMethod = NULL;
|
||||
UInt32 theLen = 0;
|
||||
(void)QTSS_GetValuePtr(theRequest, qtssRTSPReqMethod, 0, (void **)&theMethod, &theLen);
|
||||
if (*theMethod == qtssPlayMethod)
|
||||
{
|
||||
OSRef* theDirectoryInfoRef = sDirectoryInfoMap->Resolve(&theRootDir);
|
||||
if (theDirectoryInfoRef == NULL)
|
||||
{
|
||||
DirectoryInfo* newDirInfo = NEW DirectoryInfo(&theRootDir);
|
||||
theErr = sDirectoryInfoMap->Register(newDirInfo->GetRef());
|
||||
Assert(theErr == QTSS_NoErr);
|
||||
theDirectoryInfoRef = sDirectoryInfoMap->Resolve(&theRootDir);
|
||||
Assert (theDirectoryInfoRef == newDirInfo->GetRef());
|
||||
}
|
||||
|
||||
DirectoryInfo* theDirInfo = (DirectoryInfo *)theDirectoryInfoRef->GetObject();
|
||||
theDirInfo->AddSession(&theSession);
|
||||
sDirectoryInfoMap->Release(theDirectoryInfoRef);
|
||||
}
|
||||
|
||||
#if HOME_DIRECTORY_MODULE_DEBUGGING
|
||||
char* newRequestPath = NULL;
|
||||
theErr = QTSS_GetValueAsString (theRequest, qtssRTSPReqFilePath, 0, &newRequestPath);
|
||||
qtss_printf("QTSSHomeDirectoryModule::RewriteRootDir qtssRTSPReqFilePath = %s\n", newRequestPath);
|
||||
QTSS_Delete(newRequestPath);
|
||||
|
||||
char* newRequestRootDir = NULL;
|
||||
theErr = QTSS_GetValueAsString (theRequest, qtssRTSPReqRootDir, 0, &newRequestRootDir);
|
||||
qtss_printf("QTSSHomeDirectoryModule::RewriteRootDir qtssRTSPReqRootDir = %s\n", newRequestRootDir);
|
||||
QTSS_Delete(newRequestRootDir);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
QTSS_Error AuthorizeRequest(QTSS_StandardRTSP_Params* inParams)
|
||||
{
|
||||
// Only do anything if this is the first request
|
||||
Bool16 *isFirstRequest = NULL;
|
||||
UInt32 theLen = sizeof(isFirstRequest);
|
||||
(void)QTSS_GetValuePtr(inParams->inRTSPSession, sIsFirstRequestAttr, 0, (void**)&isFirstRequest, &theLen);
|
||||
if (isFirstRequest != NULL)
|
||||
return QTSS_NoErr;
|
||||
|
||||
OSRef *theDirectoryInfoRef = NULL;
|
||||
DirectoryInfo *theDirInfo = NULL;
|
||||
StrPtrLen theHomeDir;
|
||||
|
||||
// if no limits are imposed, do nothing
|
||||
if ((sMaxNumConnsPerHomeDir == 0) && (sMaxBWInKbpsPerHomeDir == 0))
|
||||
goto end_authorize;
|
||||
|
||||
// Get this client session's home dir
|
||||
(void)QTSS_GetValuePtr(inParams->inClientSession, sSessionHomeDirAttr, 0, (void**)&theHomeDir.Ptr, &theHomeDir.Len);
|
||||
if ((theHomeDir.Ptr == NULL) || (theHomeDir.Len == 0)) // If it's NULL it's not served out of the home dir
|
||||
goto end_authorize;
|
||||
|
||||
// Get the sessions for this home dir
|
||||
theDirectoryInfoRef = sDirectoryInfoMap->Resolve(&theHomeDir);
|
||||
if (theDirectoryInfoRef == NULL) // No sessions exist yet for this homeDir
|
||||
goto end_authorize;
|
||||
|
||||
theDirInfo = (DirectoryInfo *)(theDirectoryInfoRef->GetObject());
|
||||
|
||||
if ((sMaxNumConnsPerHomeDir != 0) && ((theDirInfo->NumSessions()) >= sMaxNumConnsPerHomeDir))
|
||||
QTSSModuleUtils::SendErrorResponse(inParams->inRTSPRequest, qtssClientNotEnoughBandwidth, qtssMsgTooManyClients);
|
||||
else if((sMaxBWInKbpsPerHomeDir != 0) && ((theDirInfo->CurrentTotalBandwidthInKbps()) >= sMaxBWInKbpsPerHomeDir))
|
||||
QTSSModuleUtils::SendErrorResponse(inParams->inRTSPRequest, qtssClientNotEnoughBandwidth, qtssMsgTooMuchThruput);
|
||||
|
||||
sDirectoryInfoMap->Release(theDirectoryInfoRef);
|
||||
|
||||
end_authorize:
|
||||
// Mark the request so we'll know subsequent ones aren't the first.
|
||||
(void)QTSS_SetValue(inParams->inRTSPSession, sIsFirstRequestAttr, 0, &sTrue, sizeof(sTrue));
|
||||
|
||||
return QTSS_NoErr;
|
||||
}
|
||||
|
||||
QTSS_Error RemoveClientSessionFromMap(QTSS_ClientSessionClosing_Params* inParams)
|
||||
{
|
||||
QTSS_ClientSessionObject theSession = inParams->inClientSession;
|
||||
|
||||
StrPtrLen theHomeDir;
|
||||
(void)QTSS_GetValuePtr (theSession, sSessionHomeDirAttr, 0, (void**)&theHomeDir.Ptr, &theHomeDir.Len);
|
||||
if ((theHomeDir.Ptr != NULL) && (theHomeDir.Len != 0))
|
||||
{
|
||||
OSRef* theDirectoryInfoRef = sDirectoryInfoMap->Resolve(&theHomeDir);
|
||||
if (theDirectoryInfoRef != NULL)
|
||||
{
|
||||
DirectoryInfo *theDirInfo = (DirectoryInfo *)theDirectoryInfoRef->GetObject();
|
||||
theDirInfo->RemoveSession(&theSession);
|
||||
sDirectoryInfoMap->Release(theDirectoryInfoRef);
|
||||
(void)sDirectoryInfoMap->TryUnRegister(theDirectoryInfoRef);
|
||||
}
|
||||
}
|
||||
|
||||
return QTSS_NoErr;
|
||||
}
|
||||
|
||||
// Expand path expands the ~ or ~username to the home directory of the user
|
||||
// It allocates memory for the outPathPtr->Ptr, so the caller should delete it
|
||||
// inPathPtr has the tilde stripped off, so inPathPtr->Len == 0 is valid
|
||||
Bool16 ExpandPath(const StrPtrLen *inPathPtr, StrPtrLen *outPathPtr)
|
||||
{
|
||||
Assert(inPathPtr != NULL);
|
||||
Assert(outPathPtr != NULL);
|
||||
|
||||
char *newPath = NULL;
|
||||
|
||||
if (inPathPtr->Len != 0)
|
||||
{
|
||||
char* inPathStr = inPathPtr->GetAsCString();
|
||||
struct passwd *passwdStruct = getpwnam(inPathStr);
|
||||
delete [] inPathStr;
|
||||
if (passwdStruct != NULL)
|
||||
newPath = passwdStruct->pw_dir;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
if (inPathPtr->Len == 0)
|
||||
{
|
||||
newPath = getenv("HOME");
|
||||
|
||||
if (newPath == NULL)
|
||||
{
|
||||
struct passwd *passwdStruct = getpwuid(getuid());
|
||||
if (passwdStruct != NULL)
|
||||
newPath = passwdStruct->pw_dir;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (newPath == NULL)
|
||||
return false;
|
||||
|
||||
UInt32 newPathLen = ::strlen(newPath);
|
||||
char* newPathStr = NEW char[newPathLen + 1];
|
||||
::strcpy(newPathStr, newPath);
|
||||
|
||||
outPathPtr->Ptr = newPathStr;
|
||||
outPathPtr->Len = newPathLen;
|
||||
|
||||
return true;
|
||||
}
|
41
APIModules/QTSSHomeDirectoryModule/QTSSHomeDirectoryModule.h
Normal file
41
APIModules/QTSSHomeDirectoryModule/QTSSHomeDirectoryModule.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: QTSSHomeDirectoryModule.h
|
||||
|
||||
Contains: Module that expands ~ in request URLs to home directories
|
||||
*/
|
||||
|
||||
#ifndef __QTSS_HOMEDIRECTORY_MODULE_H__
|
||||
#define __QTSS_HOMEDIRECTORY_MODULE_H__
|
||||
|
||||
#include "QTSS.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
QTSS_Error QTSSHomeDirectoryModule_Main(void* inPrivateArgs);
|
||||
}
|
||||
|
||||
#endif // __QTSS_HOMEDIRECTORY_MODULE_H__
|
178
APIModules/QTSSHomeDirectoryModule/createuserstreamingdir
Executable file
178
APIModules/QTSSHomeDirectoryModule/createuserstreamingdir
Executable file
|
@ -0,0 +1,178 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
#
|
||||
OPTION=""
|
||||
PLAT=`uname`
|
||||
|
||||
if [ ${1} ]; then
|
||||
OPTION=${1}
|
||||
fi
|
||||
|
||||
if [ "$OPTION" = "-h" ]; then
|
||||
OPTION=""
|
||||
fi
|
||||
|
||||
if [ ${OPTION} ]; then
|
||||
OK=YES
|
||||
else
|
||||
echo ""
|
||||
echo "usage: createuserstreamingdir user"
|
||||
echo ""
|
||||
echo "This tool will create the directory ~user/Sites/Streaming/."
|
||||
echo "The created directory gives the QuickTimeStreamingServer access to user managed content."
|
||||
echo ""
|
||||
exit 0
|
||||
fi
|
||||
echo ""
|
||||
|
||||
CALLER=`whoami`
|
||||
|
||||
if [ "$1" = "$CALLER" ] ; then
|
||||
OK=YES
|
||||
else
|
||||
if [ `id -u` != 0 ]
|
||||
then
|
||||
echo "You must be root, ${1}, or use the sudo command to proceed. "
|
||||
echo "Cannot continue."
|
||||
echo ""
|
||||
echo "usage: createuserstreamingdir user"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
#
|
||||
# Home dir
|
||||
#
|
||||
NEWPATH=~"${1}"
|
||||
HOMEDIR=`eval "echo $NEWPATH"`
|
||||
|
||||
echo "examining the home directory for ${NEWPATH}"
|
||||
echo "home directory path = ${HOMEDIR}"
|
||||
if [ -e "${HOMEDIR}" ] ; then
|
||||
OK=YES
|
||||
else
|
||||
echo "The path \"${HOMEDIR}\" is not found."
|
||||
echo "Cannot continue."
|
||||
echo ""
|
||||
echo "usage: createuserstreamingdir user"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -d "${HOMEDIR}" ] ; then
|
||||
OK=YES
|
||||
else
|
||||
echo "${HOMEDIR} is not a directory."
|
||||
echo "Cannot continue."
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "Darwin" != "$PLAT" ]; then
|
||||
chmod 755 "${HOMEDIR}"
|
||||
echo "Set privileges for ${HOMEDIR} to 755 "
|
||||
fi
|
||||
|
||||
#
|
||||
# /Sites
|
||||
#
|
||||
|
||||
if [ -e "${HOMEDIR}/Sites" ]; then
|
||||
OK=YES
|
||||
else
|
||||
if [ -w "${HOMEDIR}/" ]; then
|
||||
mkdir "${HOMEDIR}/Sites"
|
||||
chmod 755 "${HOMEDIR}/Sites"
|
||||
chown ${1} "${HOMEDIR}/Sites"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -e "${HOMEDIR}/Sites" ]; then
|
||||
OK=YES
|
||||
else
|
||||
echo "You do not have privileges to create ${HOMEDIR}/Sites."
|
||||
echo "Cannot continue."
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -d "${HOMEDIR}/Sites" ]; then
|
||||
OK=YES
|
||||
else
|
||||
echo "${HOMEDIR}/Sites is not a directory."
|
||||
echo "Cannot continue."
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#
|
||||
# /Sites/Streaming
|
||||
#
|
||||
|
||||
if [ -e "${HOMEDIR}/Sites/Streaming" ]; then
|
||||
OK=YES
|
||||
else
|
||||
if [ -w "${HOMEDIR}/Sites" ]; then
|
||||
mkdir -m 755 "${HOMEDIR}/Sites/Streaming"
|
||||
chown ${1}:qtss "${HOMEDIR}/Sites/Streaming"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -e "${HOMEDIR}/Sites/Streaming" ]; then
|
||||
OK=YES
|
||||
else
|
||||
echo "You do not have privileges to create ${HOMEDIR}/Sites/Streaming."
|
||||
echo "Cannot continue."
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -d "${HOMEDIR}/Sites/Streaming" ]; then
|
||||
OK=YES
|
||||
else
|
||||
echo "${HOMEDIR}/Sites/Streaming is not a directory."
|
||||
echo "Cannot continue."
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#
|
||||
# Test access
|
||||
#
|
||||
|
||||
if [ -w "${HOMEDIR}/Sites/Streaming/" ]; then
|
||||
OK=YES
|
||||
else
|
||||
echo "You do not have privileges to modify ${HOMEDIR}/Sites/Streaming."
|
||||
echo "Cannot continue."
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
chown ${1}:qtss "${HOMEDIR}/Sites/Streaming" > /dev/null 2>&1
|
||||
if [ $? = 0 ]; then
|
||||
OK=YES
|
||||
else
|
||||
echo "You are not the owner."
|
||||
echo "You may need to run this tool again as root or use the sudo command."
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
chmod 755 "${HOMEDIR}/Sites/Streaming" > /dev/null 2>&1
|
||||
if [ $? = 0 ]; then
|
||||
OK=YES
|
||||
else
|
||||
echo "The permissions are not correct."
|
||||
echo "You may need to run this tool again as root or use the sudo command."
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
echo "${HOMEDIR}/Sites/Streaming is ready for streaming."
|
||||
echo ""
|
||||
|
||||
exit 0
|
Loading…
Add table
Add a link
Reference in a new issue