📄 sbineturl.cpp
字号:
case VALUE_STRING:
return VXIStringCStr( (const VXIString *)value );
case VALUE_PTR:
{
void *valPtr = VXIPtrValue( (const VXIPtr *)value );
sprintf (tempBuf, "%p", valPtr);
}
break;
case VALUE_MAP:
case VALUE_VECTOR:
case VALUE_CONTENT:
default:
// These types are supposed to be handled before entering this function.
break;
}
return tempBuf;
}
bool SBinetURL::requiresMultipart(const VXIValue *value)
{
switch (VXIValueGetType(value))
{
case VALUE_CONTENT:
return true;
case VALUE_MAP:
return requiresMultipart((const VXIMap*) value);
case VALUE_VECTOR:
return requiresMultipart((const VXIVector*) value);
default:
return false;
}
}
bool SBinetURL::requiresMultipart(const VXIMap* vximap)
{
if (vximap == NULL) return false;
const VXIchar *key = NULL;
const VXIValue *value = NULL;
bool result = false;
VXIMapIterator *mapIterator = VXIMapGetFirstProperty( vximap, &key, &value );
do
{
if (key != NULL && value != NULL && requiresMultipart(value))
{
result = true;
break;
}
}
while (VXIMapGetNextProperty(mapIterator, &key, &value) == VXIvalue_RESULT_SUCCESS);
VXIMapIteratorDestroy(&mapIterator);
return result;
}
bool SBinetURL::requiresMultipart(const VXIVector* vxivector)
{
for (VXIunsigned i = VXIVectorLength(vxivector); i > 0; i--)
{
const VXIValue* value = VXIVectorGetElement(vxivector, i);
if (value != NULL && requiresMultipart(value))
{
return true;
}
}
return false;
}
void SBinetURL::appendQueryArgsToURL(const VXIMap* queryArgs)
{
SBinetNString queryArgsNStr = queryArgsToNString(queryArgs);
if (queryArgsNStr.length() > 0)
{
const wchar_t delim = wcschr(_strPath.c_str(), L'?') == NULL ? L'?' : L'&';
_strPath += delim;
_strPath += queryArgsNStr;
_absoluteURL += delim;
_absoluteURL += queryArgsNStr;
// maintain narrow and wide representations synchronized.
N_strPath += delim;
N_strPath += queryArgsNStr;
N_absoluteURL += delim;
N_absoluteURL += queryArgsNStr;
}
}
SBinetNString
SBinetURL::queryArgsToNString(const VXIMap* queryArgs) const
{
SBinetNString result;
if (queryArgs)
{
VXIString *strResult = VXIValueToString((const VXIValue *) queryArgs, L"",
VALUE_FORMAT_URL_QUERY_ARGS);
if (strResult)
{
// URL query args encoding ensures we only have ASCII here
result += VXIStringCStr(strResult);
VXIStringDestroy(&strResult);
}
}
return result;
}
/*
* Utilities
*/
void SBinetURL::appendKeyToMultipart(SBinetNString& result, const char *key )
{
// Print the boundary start
if (result.length() != 0)
result += CRLF;
result += "--" SB_BOUNDARY CRLF;
result += "Content-Disposition: form-data; name=\"";
result += key;
result += "\"" CRLF;
}
void SBinetURL::appendValueToMultipart(SBinetNString& result, const SBinetNString& value)
{
// char tempbuf[20];
// if (value.length() > 0)
// {
// result += "Content-Type: text/plain" CRLF;
// result += "Content-Length: ";
// sprintf(tempbuf, "%d", value.length());
// result += tempbuf;
// result += CRLF;
// // blank line.
// result += CRLF;
// result += value;
// }
result += CRLF;
result += value;
}
void SBinetURL::appendQueryArgsVectorToMultipart(SBinetNString& result,
const VXIVector *vxivector,
SBinetNString& fieldName)
{
const VXIValue *value = NULL;
VXIunsigned vectorLen = VXIVectorLength(vxivector);
int prevLen = fieldName.length();
for(VXIunsigned i = 0 ; i < vectorLen ; i++)
{
value = VXIVectorGetElement(vxivector, i);
if (value != NULL)
{
appendArrayIndexToName(fieldName, i);
appendQueryArgsToMultipart(result, value, fieldName);
fieldName.resize(prevLen);
}
}
}
void SBinetURL::appendQueryArgsMapToMultipart(SBinetNString& result,
const VXIMap *vximap,
SBinetNString& fieldName)
{
const VXIchar *key = NULL;
const VXIValue *value = NULL;
int prevLen = fieldName.length();
VXIMapIterator *mapIterator = VXIMapGetFirstProperty(vximap, &key, &value );
do
{
if (key != NULL && value != NULL)
{
fieldName += '.';
fieldName += key;
appendQueryArgsToMultipart(result, value, fieldName);
fieldName.resize(prevLen);
}
}
while (VXIMapGetNextProperty(mapIterator, &key, &value) ==
VXIvalue_RESULT_SUCCESS);
VXIMapIteratorDestroy(&mapIterator);
}
SBinetNString SBinetURL::queryArgsToMultipart(const VXIMap* queryArgs)
{
SBinetNString result;
if(!queryArgs) return(result);
const VXIchar *key = NULL;
const VXIValue *value = NULL;
VXIMapIterator* mapIterator = VXIMapGetFirstProperty( queryArgs, &key, &value );
do
{
if (key != NULL && value != NULL)
{
SBinetNString fieldName = key;
appendQueryArgsToMultipart(result, value, fieldName);
}
}
while ( VXIMapGetNextProperty( mapIterator, &key, &value ) == VXIvalue_RESULT_SUCCESS );
// Print the boundary terminator
result += CRLF "--" SB_BOUNDARY "--" CRLF;
VXIMapIteratorDestroy(&mapIterator);
return result;
}
void SBinetURL::appendQueryArgsToMultipart(SBinetNString& result, const VXIValue *value, SBinetNString& fieldName)
{
switch (VXIValueGetType(value))
{
case VALUE_CONTENT:
{
// audio
const VXIchar* type;
const VXIbyte* data;
VXIulong size;
char sizeInt[10];
appendKeyToMultipart(result, fieldName.c_str());
VXIContentValue((const VXIContent *) value, &type, &data, &size);
result += "Content-Type: ";
result += type;
result += CRLF;
sprintf(sizeInt,"%lu",size);
result += "Content-Length: ";
result += sizeInt;
result += CRLF;
// One blank line before actual data.
result += CRLF;
result.append((const char*) data, size);
}
break;
case VALUE_MAP:
appendQueryArgsMapToMultipart(result, (const VXIMap *) value, fieldName);
break;
case VALUE_VECTOR:
appendQueryArgsVectorToMultipart(result, (const VXIVector *)value, fieldName);
break;
default:
appendKeyToMultipart(result, fieldName.c_str());
appendValueToMultipart(result, valueToNString(value));
break;
}
}
//
// Infer a MIME content type from a URL (by the extension)
//
VXIString *SBinetURL::getContentTypeFromUrl() const
{
//
// Determine the extension. This has to work for local files and also HTTP
//
const VXIchar *url = _strPath.c_str();
if (url == NULL || !*url)
{
return NULL;
}
const VXIchar *urlEnd = url;
// Search for the end of the URL.
while (*urlEnd != L'?' && *urlEnd != L'#' && *urlEnd) urlEnd++;
// Now look for the last '.'
VXIchar ext[1024];
const VXIchar *urlDot = urlEnd - 1;
while (urlDot >= url && *urlDot != L'.') urlDot--;
if (urlDot >= url)
{
::wcsncpy(ext, urlDot, urlEnd - urlDot);
ext[urlEnd - urlDot] = L'\0';
if (*ext)
{
const VXIchar* typeFromMap = SBinetChannel::mapExtension(ext);
if (typeFromMap != NULL)
{
if (*typeFromMap)
return VXIStringCreate(typeFromMap);
else
return NULL;
}
// GN: Skip this step. The default type will be returned instead.
// This is what happens on other OSes. The problem is that if
// the file extension is .xml, FindMimeFromData() will return
// a MIME type of text/xml and this is not one of the supported
// types in SRGS. Allow the user of INET to determine the type
// instead by returning the default type.
#if 0
/*
* Could not find in map, use Win32 if available
*/
#ifdef _WIN32
// Try Windows, this supports a number of hardcoded MIME content
// types as well as extension mapping rules. To define a new
// extension mapping rule, create a new Win32 registry key called
// HKEY_CLASSES_ROOT\.<ext> where <ext> is the extension name. Then
// create a value under that called "Content Type" where the data is
// the content type string, such as "audio/aiff". Browse that
// location in the registry for numerous examples (not all have a
// content type mapping though).
//
// TBD sniff the actual data buffer too as this permits, pass the
// proposed MIME type too (as returned by the web server, if any).
VXIchar *mimeBuf;
if (FindMimeFromData (NULL, url, NULL, 0, NULL, 0, &mimeBuf, 0) !=
NOERROR)
mimeBuf = NULL;
/* FindMimeFromData( ) leaks, we add unknown extensions here to
make it so we only leak once per extension instead of
repeatedly */
if (mimeBuf && *mimeBuf) {
SBinetChannel::addExtensionRule(ext, mimeBuf);
return VXIStringCreate(mimeBuf);
} else {
SBinetChannel::addExtensionRule(ext, L"");
}
#endif
#endif
}
}
/*
* Couldn't figure out MIME type: return default type.
*/
return NULL;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -