📄 httputils.cpp
字号:
/****************License************************************************ * * Copyright 2000-2003. ScanSoft, Inc. * * Use of this software is subject to notices and obligations set forth * in the SpeechWorks Public License - Software Version 1.2 which is * included with this software. * * ScanSoft is a registered trademark of ScanSoft, Inc., and OpenSpeech, * SpeechWorks and the SpeechWorks logo are registered trademarks or * trademarks of SpeechWorks International, Inc. in the United States * and other countries. * ***********************************************************************/ #include "SBinetString.hpp" #include "HttpUtils.hpp" #include <ctype.h> #include <stdlib.h> #include <string.h> #include "ap_ctype.h" #ifdef WIN32 #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <stdlib.h> #else #include <time.h> #include <sys/types.h> #include <sys/time.h> #include <sys/times.h> #include <unistd.h> #include <sys/select.h> #endif static void escapeDataIntern(const VXIbyte *data, VXIulong size, SBinetHttpUtils::HttpUriEncoding mask, SBinetNString &result) { /* * Bit 0 xalpha * Bit 1 xpalpha -- as xalpha but with plus. * Bit 2 ... path -- as xpalpha but with / */ static const VXIbyte isAcceptable[96] = /*0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xA 0xB 0xC 0xD 0xE 0xF */ { 0x0,0x0,0x0,0x0,0x0,0xE,0x0,0x0,0x0,0x0,0xF,0xE,0x0,0xF,0xF,0xC, /* 2x !"#$%&'()*+,-./ */ 0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0x8,0x0,0x0,0x0,0x0,0x0, /* 3x 0123456789:;<=>? */ 0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF, /* 4x @ABCDEFGHIJKLMNO */ 0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0x0,0x0,0x0,0x0,0xF, /* 5X PQRSTUVWXYZ[\]^_ */ 0x0,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF, /* 6x `abcdefghijklmno */ 0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0x0,0x0,0x0,0x0,0x0 /* 7X pqrstuvwxyz{\}~DEL */ }; static const char *hexChar = "0123456789ABCDEF"; // Now perform the actual conversion const VXIbyte *p; VXIulong i; for (i = 0, p = data; i < size; i++, p++) { VXIbyte a = *p; if (a < 32 || a >= 128 || !(isAcceptable[a-32] & mask)) { result += '%'; result += hexChar[a >> 4]; result += hexChar[a & 15]; } else result += static_cast<char>(*p); } } void SBinetHttpUtils::escapeString(const char *str, HttpUriEncoding mask, SBinetNString &result) { result.clear(); if (str == NULL) return; escapeDataIntern((const VXIbyte *) str, strlen(str), mask, result); } void SBinetHttpUtils::escapeData(const void *data, const int size, HttpUriEncoding mask, SBinetNString& result) { result.clear(); if (data == NULL) return; escapeDataIntern((const VXIbyte *) data, size, mask, result); } void SBinetHttpUtils::utf8encode(const VXIchar *str, SBinetNString& result) { result.clear(); if (str == NULL) return; // firstByteMark // A list of values to mask onto the first byte of an encoded sequence, // indexed by the number of bytes used to create the sequence. static const char firstByteMark[7] = { char(0x00), char(0x00), char(0xC0), char(0xE0), char(0xF0), char(0xF8), char(0xFC) }; for (const VXIchar *p = str; *p; p++) { VXIchar c = *p; if (c >= 0xD800 && c <= 0xDBFF) break; unsigned int encodedBytes; if (c < 0x80) encodedBytes = 1; else if (c < 0x800) encodedBytes = 2; else if (c < 0x10000) encodedBytes = 3; else if (c < 0x200000) encodedBytes = 4; else if (c < 0x4000000) encodedBytes = 5; else if (c <= 0x7FFFFFFF) encodedBytes = 6; else { result.clear(); break; } // And spit out the bytes. We spit them out in reverse order // here, so bump up the output pointer and work down as we go. char buffer[7] = { 0, 0, 0, 0, 0, 0, 0 }; char * outPtr = buffer + encodedBytes; switch (encodedBytes) { case 6 : *--outPtr = char((c | 0x80) & 0xBF); c >>= 6; case 5 : *--outPtr = char((c | 0x80) & 0xBF); c >>= 6; case 4 : *--outPtr = char((c | 0x80) & 0xBF); c >>= 6; case 3 : *--outPtr = char((c | 0x80) & 0xBF); c >>= 6; case 2 : *--outPtr = char((c | 0x80) & 0xBF); c >>= 6; case 1 : *--outPtr = char(c | firstByteMark[encodedBytes]); } for (int i = 0; buffer[i] != 0; i++) result += buffer[i]; } } const char *SBinetHttpUtils::getToken(const char *str, SBinetNString& token) { static const char *tspecials = "()<>@,;:\\\"/[]?={} \t"; const char *beg = str; while (*beg && ap_isspace(*beg)) beg++; if (!*beg) return NULL; const char *end = beg; while (*end && !strchr(tspecials, *end) && !ap_iscntrl(*end)) end++; if (end == beg) { return NULL; } token.clear(); token.append(beg, end - beg); return end; } const char *SBinetHttpUtils::getQuotedString(const char *str, SBinetNString& value) { // skip leading '"' ++str; value.clear(); while (*str && *str != '"') { switch (*str) { case '\\': str++; if (*str) value += *str; break; default: value += *str; break; } str++; } if (*str == '"') return ++str; return NULL; } const char *SBinetHttpUtils::getValue(const char *str, SBinetNString& value) { const char *beg = str; while (*beg && ap_isspace(*beg)) beg++; if (!*beg) return NULL; if (*beg == '"') { return getQuotedString(beg, value); } else { return getToken(beg, value); } } const char *SBinetHttpUtils::getCookieValue(const char *str, SBinetNString& value) { const char *beg = str; while (*beg && ap_isspace(*beg)) beg++; if (!*beg) return NULL; if (*beg == '"') { return getQuotedString(beg, value); } else { // The specification says that a value is either a token or a quoted // string. However, a lot of broken servers just don't quote string // containing blanks. We have to include everything up to the semicolon. #ifdef NO_BROKEN_SERVER return getToken(beg, value); #else while (*beg && ap_isspace(*beg)) beg++; if (!*beg) return NULL; const char *end = beg; while (*end && *end != ';') { // some really broken servers even put a comma in the value. In this // case, we scan the string to find the first occurence of a semi-colon // or an equal sign. If we find the semi-colon first, we assume that // the comma is part of the value and the value terminates at the // semi-colon location. Otherwise, the value terminates with the comma. if (*end == ',') { const char *orig_end = end; while (*end && *end != ';' && *end != '=') end++; if (*end == '=') end = orig_end; break; } end++; } // removing trailing blanks. const char *lastChar = end - 1; while (lastChar >= beg && ap_isspace(*lastChar)) lastChar--; lastChar++; value.clear(); value.append(beg, lastChar - beg); return end; #endif } } const char *SBinetHttpUtils::expectChar(const char *start, const char *delim) { while (*start && ap_isspace(*start)) start++; if (!*start || strchr(delim, *start)) return start; return NULL; } // Sleep with a duration in microseconds void SBinetHttpUtils::usleep(unsigned long microsecs) { #ifdef WIN32 Sleep (microsecs / 1000); #else fd_set fdset; struct timeval timeout; FD_ZERO(&fdset); timeout.tv_sec = microsecs / 1000000; timeout.tv_usec = microsecs % 1000000; select(0, &fdset, &fdset, &fdset, &timeout); #endif } // Case insensitive compare int SBinetHttpUtils::casecmp(const wchar_t *s1, const wchar_t *s2) { register unsigned int u1, u2; for (;;) { u1 = (unsigned int) *s1++; u2 = (unsigned int) *s2++; if (toUpper(u1) != toUpper(u2)) { return toUpper(u1) - toUpper(u2); } if (u1 == '\0') { break; } } return 0; } int SBinetHttpUtils::casecmp(const wchar_t *s1, const wchar_t *s2, register size_t n) { register unsigned int u1, u2; for (; n != 0; --n) { u1 = (unsigned int) *s1++; u2 = (unsigned int) *s2++; if (toUpper(u1) != toUpper(u2)) { return toUpper(u1) - toUpper(u2); } if (u1 == '\0') { break; } } return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -