📄 http_helpers.cpp
字号:
// HTTP_Helpers.cpp,v 1.33 2005/04/23 04:45:09 ossama Exp// HTTP_Helpers.cpp -- Helper utilities for both server and client#include "HTTP_Helpers.h"#include "ace/Log_Msg.h"#include "ace/OS_NS_string.h"#include "ace/Guard_T.h"#include "ace/OS_NS_time.h"#include "ace/OS_NS_stdio.h"ACE_RCSID(server, HTTP_Helpers, "HTTP_Helpers.cpp,v 1.33 2005/04/23 04:45:09 ossama Exp")// = Static initialization.const char *constHTTP_Helper::months_[12]={ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};char const *HTTP_Helper::alphabet_ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";char * HTTP_Helper::date_string_ = 0;ACE_SYNCH_MUTEX HTTP_Helper::mutex_;ACE_SYNCH_MUTEX HTTP_Status_Code::lock_;int HTTP_Status_Code::instance_ = 0;const char *HTTP_Status_Code::Reason[HTTP_Status_Code::MAX_STATUS_CODE + 1];time_tHTTP_Helper::HTTP_mktime (const char *httpdate){ char *buf; ACE_NEW_RETURN (buf, char[ACE_OS::strlen (httpdate) + 1], (time_t) -1); // Make spaces in the date be semi-colons so we can parse robustly // with sscanf. const char *ptr1 = httpdate; char *ptr2 = buf; do { if (*ptr1 == ' ') *ptr2++ = ';'; else *ptr2++ = *ptr1; } while (*ptr1++ != '\0'); // In HTTP/1.0, there are three versions of an HTTP_date. // rfc1123-date = wkday "," SP dd month yyyy SP hh:mm:ss SP "GMT" // rfc850-date = weekday "," SP dd-month-yy SP hh:mm:ss SP "GMT" // asctime-date = wkday SP month dd SP hh:mm:ss SP yyyy static const char rfc1123_date[] = "%3s,;%2d;%3s;%4d;%2d:%2d:%2d;GMT"; static const char rfc850_date[] = "%s,;%2d-%3s-%2d;%2d:%2d:%2d;GMT"; static const char asctime_date[] = "%3s;%3s;%2d;%2d:%2d:%2d;%4d"; // Should also support other versions (such as from NNTP and SMTP) // for robustness, but it should be clear how to extend this. struct tm tms; char month[4]; char weekday[10]; if (::sscanf(buf, rfc1123_date, weekday, &tms.tm_mday, month, &tms.tm_year, &tms.tm_hour, &tms.tm_min, &tms.tm_sec) == 7) ; else if (::sscanf(buf, rfc850_date, weekday, &tms.tm_mday, month, &tms.tm_year, &tms.tm_hour, &tms.tm_min, &tms.tm_sec) == 7) { weekday[3] = '\0'; } else if (::sscanf(buf, asctime_date, weekday, month, &tms.tm_mday, &tms.tm_hour, &tms.tm_min, &tms.tm_sec, &tms.tm_year) == 7) { } delete [] buf; tms.tm_year = HTTP_Helper::fixyear (tms.tm_year); tms.tm_mon = HTTP_Helper::HTTP_month (month); if (tms.tm_mon == -1) return (time_t) -1; // mktime is a Standard C function. {#if !defined (ACE_HAS_REENTRANT_LIBC) ACE_MT (ACE_Guard<ACE_SYNCH_MUTEX> g (HTTP_Helper::mutex_));#endif /* NOT ACE_HAS_REENTRANT_LIBC */ return ACE_OS::mktime (&tms); }}const char *HTTP_Helper::HTTP_date (void){ if (HTTP_Helper::date_string_ == 0) { ACE_MT (ACE_Guard<ACE_SYNCH_MUTEX> m (HTTP_Helper::mutex_)); if (HTTP_Helper::date_string_ == 0) { // 40 bytes is all I need. ACE_NEW_RETURN (HTTP_Helper::date_string_, char[40], 0); if (!HTTP_Helper::HTTP_date (HTTP_Helper::date_string_)) { delete [] HTTP_Helper::date_string_; HTTP_Helper::date_string_ = 0; } } } return HTTP_Helper::date_string_;}const char *HTTP_Helper::HTTP_date (char *s){ // Return the date-string formatted per HTTP standards. Time must // be in UTC, so using the 'strftime' call (which obeys the locale) // isn't correct. static const char* months[] = {"Jan","Feb","Mar","Apr","May","Jun", "Jul","Aug","Sep","Oct","Nov","Dec"}; static const char* days[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; time_t tloc; struct tm tms; char * date_string = s; if (ACE_OS::time (&tloc) != (time_t) -1 && ACE_OS::gmtime_r (&tloc, &tms) != NULL) { ACE_OS::sprintf (date_string, "%s, %2.2d %s %4.4d %2.2d:%2.2d:%2.2d GMT", days[tms.tm_wday], tms.tm_mday, months[tms.tm_mon], tms.tm_year + 1900, tms.tm_hour, tms.tm_min, tms.tm_sec); } else date_string = 0; return date_string;}intHTTP_Helper::HTTP_month (const char *month){ for (size_t i = 0; i < 12; i++) if (ACE_OS::strcmp(month, HTTP_Helper::months_[i]) == 0) return i; return -1;}const char *HTTP_Helper::HTTP_month (int month){ if (month < 0 || month >= 12) return 0; return HTTP_Helper::months_[month];}// Fix the path if it needs fixing/is fixable.char *HTTP_Helper::HTTP_decode_string (char *path){ // replace the percentcodes with the actual character int i, j; char percentcode[3]; for (i = j = 0; path[i] != '\0'; i++, j++) { if (path[i] == '%') { percentcode[0] = path[++i]; percentcode[1] = path[++i]; percentcode[2] = '\0'; path[j] = (char) ACE_OS::strtol (percentcode, (char **) 0, 16); } else path[j] = path[i]; } path[j] = path[i]; return path;}char *HTTP_Helper::HTTP_decode_base64 (char *data){ char inalphabet[256], decoder[256]; ACE_OS::memset (inalphabet, 0, sizeof (inalphabet)); ACE_OS::memset (decoder, 0, sizeof (decoder)); for (int i = ACE_OS::strlen (HTTP_Helper::alphabet_) - 1; i >= 0; i--) { inalphabet[(unsigned int) HTTP_Helper::alphabet_[i]] = 1; decoder[(unsigned int) HTTP_Helper::alphabet_[i]] = i; } char *indata = data; char *outdata = data; int bits = 0; int c; int char_count = 0; int errors = 0; while ((c = *indata++) != '\0') { if (c == '=') break; if (c > 255 || ! inalphabet[c]) continue; bits += decoder[c]; char_count++; if (char_count == 4) { *outdata++ = (bits >> 16); *outdata++ = ((bits >> 8) & 0xff); *outdata++ = (bits & 0xff); bits = 0; char_count = 0; } else bits <<= 6; } if (c == '\0') { if (char_count) { ACE_DEBUG ((LM_DEBUG, "base64 encoding incomplete: at least %d bits truncated\n", ((4 - char_count) * 6))); errors++; } } else { // c == '=' switch (char_count) { case 1: ACE_DEBUG ((LM_DEBUG, "base64 encoding incomplete: at least 2 bits missing\n")); errors++; break; case 2: *outdata++ = (bits >> 10); break; case 3: *outdata++ = (bits >> 16); *outdata++ = ((bits >> 8) & 0xff); break; } } *outdata = '\0'; return errors ? 0 : data;}char *HTTP_Helper::HTTP_encode_base64 (char *data){ char buf[BUFSIZ]; int c; int error; int char_count = 0; int bits = 0; error = 0; char *indata = data; char *outdata = buf; const unsigned char ASCII_MAX = ~0; while ((c = *indata++) != '\0') { if (c > (int)ASCII_MAX) { ACE_DEBUG ((LM_DEBUG, "encountered char > 255 (decimal %d)\n", c)); error++; break; } bits += c; char_count++; if (char_count == 3) { *outdata++ = HTTP_Helper::alphabet_[bits >> 18]; *outdata++ = HTTP_Helper::alphabet_[(bits >> 12) & 0x3f]; *outdata++ = HTTP_Helper::alphabet_[(bits >> 6) & 0x3f]; *outdata++ = HTTP_Helper::alphabet_[bits & 0x3f]; bits = 0; char_count = 0; } else bits <<= 8; } if (!error) { if (char_count != 0) { bits <<= 16 - (8 * char_count); *outdata++ = HTTP_Helper::alphabet_[bits >> 18]; *outdata++ = HTTP_Helper::alphabet_[(bits >> 12) & 0x3f]; if (char_count == 1) { *outdata++ = '='; *outdata++ = '='; } else { *outdata++ = HTTP_Helper::alphabet_[(bits >> 6) & 0x3f]; *outdata++ = '='; } } *outdata = '\0'; ACE_OS::strcpy (data, buf); } return (error ? 0 : data);}intHTTP_Helper::fixyear (int year){ // Fix the year 2000 problem if (year > 1000) year -= 1900; else if (year < 100) { struct tm tms; time_t tloc; if (ACE_OS::time (&tloc) != (time_t) -1) { ACE_OS::gmtime_r (&tloc, &tms); if (tms.tm_year % 100 == year) year = tms.tm_year; // The last two cases check boundary conditions, in case the // year just changed at the moment we checked to see if we // need to fix it. if ((year+1) % 100 == tms.tm_year % 100) year = tms.tm_year - 1; if (year == (tms.tm_year + 1) % 100) year = tms.tm_year + 1; // What to do if none of the above? } } return year;}const char **HTTP_Status_Code::instance (void){ if (HTTP_Status_Code::instance_ == 0) { ACE_MT (ACE_Guard<ACE_SYNCH_MUTEX> g (lock_)); if (HTTP_Status_Code::instance_ == 0) { for (size_t i = 0; i < HTTP_Status_Code::MAX_STATUS_CODE + 1; i++) { switch (i) { case STATUS_OK: HTTP_Status_Code::Reason[i] = "OK"; break; case STATUS_CREATED: HTTP_Status_Code::Reason[i] = "Created"; break; case STATUS_ACCEPTED: HTTP_Status_Code::Reason[i] = "Accepted"; break; case STATUS_NO_CONTENT: HTTP_Status_Code::Reason[i] = "No Content"; break; case STATUS_MOVED_PERMANENTLY: HTTP_Status_Code::Reason[i] = "Moved Permanently"; break; case STATUS_MOVED_TEMPORARILY: HTTP_Status_Code::Reason[i] = "Moved Temporarily"; break; case STATUS_NOT_MODIFIED: HTTP_Status_Code::Reason[i] = "Not Modified"; break; case STATUS_BAD_REQUEST: HTTP_Status_Code::Reason[i] = "Bad Request"; break; case STATUS_UNAUTHORIZED: HTTP_Status_Code::Reason[i] = "Unauthorized"; break; case STATUS_FORBIDDEN: HTTP_Status_Code::Reason[i] = "Forbidden"; break; case STATUS_NOT_FOUND: HTTP_Status_Code::Reason[i] = "Not Found"; break; case STATUS_INTERNAL_SERVER_ERROR: HTTP_Status_Code::Reason[i] = "Internal Server Error"; break; case STATUS_NOT_IMPLEMENTED: HTTP_Status_Code::Reason[i] = "Not Implemented"; break; case STATUS_BAD_GATEWAY: HTTP_Status_Code::Reason[i] = "Bad Gateway"; break; case STATUS_SERVICE_UNAVAILABLE: HTTP_Status_Code::Reason[i] = "Service Unavailable"; break; default: HTTP_Status_Code::Reason[i] = "Unknown"; } } HTTP_Status_Code::instance_ = 1; } // GUARD released } return HTTP_Status_Code::Reason;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -