void HttpdSocket::Send64(const std::string& str64, const std::string& type) { Base64 bb; if (!strcasecmp(m_start.c_str(), m_if_modified_since.c_str())) { SetStatus("304"); SetStatusText("Not Modified"); SendResponse(); } else { size_t len = bb.decode_length(str64); unsigned char *buf = new unsigned char[len]; SetStatus("200"); SetStatusText("OK"); AddResponseHeader("Content-length", Utility::l2string( (long)len) ); AddResponseHeader("Content-type", type ); AddResponseHeader("Last-modified", m_start); SendResponse(); bb.decode(str64, buf, len); SendBuf( (char *)buf, len); delete[] buf; } }
void HttpSocket::IHttpServer_Respond(const HttpResponse& res) { m_res = res; SetHttpVersion( m_res.HttpVersion() ); SetStatus( Utility::l2string(m_res.HttpStatusCode()) ); SetStatusText( m_res.HttpStatusMsg() ); if (!ResponseHeaderIsSet("content-length")) { AddResponseHeader( "content-length", Utility::l2string( m_res.GetFile().size() ) ); } for (Utility::ncmap<std::string>::const_iterator it = m_res.Headers().begin(); it != m_res.Headers().end(); ++it) { AddResponseHeader( it -> first, it -> second ); } std::list<std::string> vec = m_res.CookieNames(); for (std::list<std::string>::iterator it2 = vec.begin(); it2 != vec.end(); ++it2) { AppendResponseHeader( "set-cookie", m_res.Cookie(*it2) ); } SendResponse(); OnTransferLimit(); }
void HttpdSocket::OnData(const char *p,size_t l) { if (m_file) { m_file -> fwrite(p,1,l); } m_received += l; if (m_received >= m_content_length && m_content_length) { // all done if (m_file && !m_form) { m_form = new HttpdForm(m_file, m_content_type, m_content_length); AddResponseHeader("Date", datetime2httpdate(GetDate()) ); if (GetUri() == "/image") { Send64(Utility::Logo, "image/png"); } else { Exec(); } Reset(); // prepare for next request } } }
void CGeneralAgentHttpServer::CreateHeader() { SetStatus("200"); SetStatusText("OK"); fprintf(stderr, "Uri: '%s'\n", GetUri().c_str()); { size_t x = 0; for (size_t i = 0; i < GetUri().size(); i++) if (GetUri()[i] == '.') x = i; std::string ext = GetUri().substr(x + 1); if (ext == "gif" || ext == "jpg" || ext == "png") AddResponseHeader("Content-type", "image/" + ext); else AddResponseHeader("Content-type", "text/" + ext); } AddResponseHeader("Connection", "close"); SendResponse(); }
void EQWHTTPHandler::SendPage(const std::string &file) { std::string path = "templates/"; path += file; FILE *f = fopen(path.c_str(), "rb"); if(f == nullptr) { SendResponse("404", "Not Found"); SendString("Not found."); printf("%s not found.\n", file.c_str()); return; } std::string type = s_mime.GetMimeFromFilename(file); AddResponseHeader("Content-type", type); bool process = false; #ifdef EMBPERL if(type == "text/html") process = true; else { //not processing, send headers right away #endif SendResponse("200", "OK"); #ifdef EMBPERL } #endif char *buffer = new char[READ_BUFFER_LEN+1]; size_t len; std::string to_process; while((len = fread(buffer, 1, READ_BUFFER_LEN, f)) > 0) { buffer[len] = '\0'; if(process) to_process += buffer; else SendBuf(buffer, len); } delete[] buffer; fclose(f); #ifdef EMBPERL if(process) { //convert the base form into a useful perl exportable form HTTPRequest req(this, GetHttpForm()); GetParser()->SetHTTPRequest("testing", &req); //parse out the page and potentially pass some stuff on to perl. ProcessAndSend(to_process); //clear out the form, just in case (since it gets destroyed next) GetParser()->SetHTTPRequest("testing", nullptr); } #endif }
void HttpPutSocket::OnConnect() { SetMethod( "PUT" ); SetHttpVersion( "HTTP/1.1" ); AddResponseHeader( "Host", m_host ); AddResponseHeader( "Content-type", m_content_type ); AddResponseHeader( "Content-length", Utility::l2string(m_content_length) ); SendRequest(); FILE *fil = fopen(m_filename.c_str(), "rb"); if (fil) { size_t n; char buf[2000]; while ((n = fread(buf, 1, 2000, fil)) > 0) { SendBuf(buf, n); } fclose(fil); } }
void HttpdSocket::OnHeaderComplete() { m_cookies = new HttpdCookies(m_http_cookie); if (GetMethod() == "GET") { Utility::SetEnv("QUERY_STRING", GetQueryString()); } Utility::SetEnv("REQUEST_METHOD", GetMethod()); Utility::SetEnv("HTTP_COOKIE", m_http_cookie); Utility::SetEnv("CONTENT_TYPE", m_content_type); Utility::SetEnv("CONTENT_LENGTH", m_content_length_str); if (GetMethod() == "POST") { m_file = new MemFile; } else if (GetMethod() == "GET") { m_form = new HttpdForm(GetQueryString(), GetQueryString().size() ); AddResponseHeader("Date", datetime2httpdate(GetDate()) ); if (GetUri() == "/image") { Send64(Utility::Logo, "image/png"); } else { Exec(); } Reset(); // prepare for next request } else { AddResponseHeader("Date", GetHttpDate()); AddResponseHeader("Connection", "close"); SetStatus("405"); SetStatusText("Method not allowed"); SendResponse(); } }
void EQWHTTPHandler::Exec() { m_sentHeaders = false; m_responseCode = "200"; // printf("Request: %s, %s, %s, %s.\n", GetMethod().c_str(), GetUrl().c_str(), GetUri().c_str(), GetQueryString().c_str()); SetHttpVersion("HTTP/1.0"); AddResponseHeader("Connection", "close"); if(GetUri().find("..") != std::string::npos) { SendResponse("403", "Forbidden"); printf("%s is forbidden.\n", GetUri().c_str()); return; } if(!CheckAuth()) { AddResponseHeader("Content-type", "text/plain"); AddResponseHeader("WWW-Authenticate", "Basic realm=\"EQEmulator\""); SendResponse("401", "Authorization Required"); SendString("Gotta Authenticate."); } else { std::string::size_type start = GetUri().find_first_not_of('/'); std::string page; if(start != std::string::npos) page = GetUri().substr(start); else page = "index.html"; SendPage(page); } /* if (!Detach()) { printf("Unable to detach...\n"); } if(GetOutputLength() > 0) { //we cannot close yet m_closeOnFinish = true; } else { Close(); }*/ Free(); //the "app" side (us) is done with this connection too... Disconnect(); }
void HttpPutSocket::OnConnect() { SetMethod( "PUT" ); SetHttpVersion( "HTTP/1.1" ); AddResponseHeader( "Host", GetUrlHost() ); AddResponseHeader( "Content-type", m_content_type ); AddResponseHeader( "Content-length", Utility::l2string(m_content_length) ); AddResponseHeader( "User-agent", MyUseragent() ); SendRequest(); std::auto_ptr<IFile> fil = std::auto_ptr<IFile>(new File); if (fil -> fopen(m_filename, "rb")) { size_t n; char buf[32768]; while ((n = fil -> fread(buf, 1, 32768)) > 0) { SendBuf(buf, n); } fil -> fclose(); } }
XBOX::VError VHTTPResponse::SendData (void *inData, XBOX::VSize inDataSize, bool isChunked) { if ((NULL == inData) || (inDataSize <= 0)) return VE_HTTP_INVALID_ARGUMENT; XBOX::VError error = XBOX::VE_OK; if (!fNumOfChunkSent) { // Check if chunked data is possible (that's not the case before HTTP/1.1) if (isChunked && (GetRequestHTTPVersion() == VERSION_1_1)) { fIsChunked = AddResponseHeader (STRING_HEADER_TRANSFER_ENCODING, STRING_HEADER_VALUE_CHUNKED); /* For instance, for simplification, no compression allowed in chunked mode */ AllowCompression (false); } SetCacheBodyMessage (false); if (!IsResponseHeaderSet (STRING_HEADER_EXPIRES)) SetExpiresHeader (GMT_NOW); if (fIsChunked) { SetResponseStatusCode (HTTP_OK); error = _SendResponseHeader(); } } if ((XBOX::VE_OK == error) && (NULL != inData) && (inDataSize > 0)) { if (fIsChunked) { uLONG bufferSize = (uLONG)inDataSize; void * buffer = inData; error = _WriteChunkSize (inDataSize); if (XBOX::VE_OK == error) error = _WriteToSocket (buffer, &bufferSize); } else { /* Buffered response: Append data to body VPtrStream */ error = SetResponseBody (inData, inDataSize); AllowCompression (true); } } return error; }
void HTTPSocket::url_this(const std::string& url_in,std::string& protocol,std::string& host,port_t& port,std::string& url,std::string& file) { Parse pa(url_in,"/"); std::string user; std::string auth; protocol = pa.getword(); // http if (!strcasecmp(protocol.c_str(), "https:")) { #ifdef HAVE_OPENSSL EnableSSL(); #else Handler().LogError(this, "url_this", -1, "SSL not available", LOG_LEVEL_WARNING); #endif port = 443; } else { port = 80; } host = pa.getword(); size_t pos = host.find("@"); if (pos != std::string::npos) { user = host.substr(0, pos); host = host.substr(pos + 1); if (user.find(":") != std::string::npos) { AddResponseHeader("Authorization", "Basic " + Utility::base64(user)); } } if (strstr(host.c_str(),":")) { Parse pa(host,":"); pa.getword(host); port = static_cast<port_t>(pa.getvalue()); } url = "/" + pa.getrest(); { Parse pa(url,"/"); std::string tmp = pa.getword(); while (tmp.size()) { file = tmp; tmp = pa.getword(); } } } // url_this
void HttpGetSocket::OnConnect() { SetMethod( "GET" ); AddResponseHeader( "Accept", "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1"); AddResponseHeader( "Accept-Language", "en-us,en;q=0.5"); AddResponseHeader( "Accept-Encoding", "gzip,deflate"); AddResponseHeader( "Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7"); AddResponseHeader( "User-agent", MyUseragent() ); if (GetUrlPort() != 80 && GetUrlPort() != 443) AddResponseHeader( "Host", GetUrlHost() + ":" + Utility::l2string(GetUrlPort()) ); else AddResponseHeader( "Host", GetUrlHost() ); SendRequest(); }
void HttpdSocket::OnData(const char *p,size_t l) { if (m_file) { m_file -> fwrite(p,1,l); } m_received += l; if (m_received >= m_content_length && m_content_length) { // all done if (m_file && !m_form) { m_form = new HttpdForm(m_file); AddResponseHeader("Date", datetime2httpdate(GetDate()) ); Exec(); Reset(); // prepare for next request } } }
void HttpPostSocket::OnConnect() { if (m_bMultipart) { DoMultipartPost(); } else { std::string body; // only fields, no files, add urlencoding for (std::map<std::string,std::list<std::string> >::iterator it = m_fields.begin(); it != m_fields.end(); it++) { std::string name = (*it).first; std::list<std::string>& ref = (*it).second; if (body.size()) { body += '&'; } body += name + "="; bool first = true; for (std::list<std::string>::iterator it = ref.begin(); it != ref.end(); it++) { std::string value = *it; if (!first) { body += "%0d%0a"; // CRLF } body += Utility::rfc1738_encode(value); first = false; } } // build header, send body SetMethod("POST"); SetHttpVersion( "HTTP/1.1" ); AddResponseHeader( "Host", m_host ); // oops - this is actually a request header that we're adding.. AddResponseHeader( "User-agent", MyUseragent()); AddResponseHeader( "Accept", "text/html, text/plain, */*;q=0.01" ); AddResponseHeader( "Connection", "close" ); AddResponseHeader( "Content-type", "application/x-www-form-urlencoded" ); AddResponseHeader( "Content-length", Utility::l2string((long)body.size()) ); SendRequest(); // send body Send( body ); } }
MyHttpSocket(ISocketHandler& h,const std::string& url) : HttpGetSocket(h,url), m_url(url) { gettime(&m_create, NULL); AddResponseHeader("content-length", Utility::l2string(g_data_size)); }
XBOX::VError VHTTPResponse::SendResponse() { XBOX::VError error = XBOX::VE_OK; if (fIsChunked) { // First send buffered data that was not already sent... if (XBOX::VE_OK == (error = _SendResponseBody())) { // Then send special ending line for chunked encoding error = _WriteChunkSize (0); } } else { XBOX::VString contentType; XBOX::VString contentEncoding; GetHeaders().GetContentType (contentType); if (GetHeaders().GetHeaderValue (HEADER_CONTENT_ENCODING, contentEncoding) && !contentEncoding.IsEmpty()) { if (HTTPProtocol::NegotiateEncodingMethod (contentEncoding) != COMPRESSION_UNKNOWN) fCanCompressBody = false; } if (HTTP_UNDEFINED == fResponseStatusCode) fResponseStatusCode = HTTP_OK; VVirtualHost *virtualHost = dynamic_cast<VVirtualHost *>(GetVirtualHost()); if (NULL != virtualHost) { // Compress HTTP Message body when applicable #if HTTP_SERVER_GLOBAL_SETTINGS bool compressionEnabled = fHTTPServer->GetSettings()->GetEnableCompression(); #else bool compressionEnabled = virtualHost->GetSettings()->GetEnableCompression(); #endif if (fCanCompressBody && compressionEnabled) { sLONG size = (sLONG)GetBody().GetSize(); #if HTTP_SERVER_GLOBAL_SETTINGS sLONG minThreshold = (fMinCompressionThreshold == -1) ? fHTTPServer->GetSettings()->GetCompressionMinThreshold() : fMinCompressionThreshold; sLONG maxThreshold = (fMaxCompressionThreshold == -1) ? fHTTPServer->GetSettings()->GetCompressionMaxThreshold() : fMaxCompressionThreshold; #else sLONG minThreshold = (fMinCompressionThreshold == -1) ? virtualHost->GetSettings()->GetCompressionMinThreshold() : fMinCompressionThreshold; sLONG maxThreshold = (fMaxCompressionThreshold == -1) ? virtualHost->GetSettings()->GetCompressionMaxThreshold() : fMaxCompressionThreshold; #endif if ((size > minThreshold) && (size <= maxThreshold)) { if (!contentType.IsEmpty() && (VMimeTypeManager::IsMimeTypeCompressible (contentType))) { error = _CompressData(); } } } } // Put HTTP Message body in cache when applicable if ((NULL != virtualHost) && fCanCacheBody && (fResponseStatusCode == HTTP_OK)) { #if HTTP_SERVER_GLOBAL_CACHE VCacheManager * cacheManager = virtualHost->GetProject()->GetHTTPServer()->GetCacheManager(); #else VCacheManager * cacheManager = virtualHost->GetCacheManager(); #endif XBOX::VFilePath filePath; XBOX::VString locationPath; XBOX::VTime lastModified; XBOX::VString lastModifiedString; XBOX::VError fileError = XBOX::VE_OK; bool staticFile = false; if (XBOX::VE_OK == (fileError = virtualHost->GetFilePathFromURL (fRequest->GetURL(), locationPath))) { filePath.FromFullPath (locationPath); if (filePath.IsFile() && (XBOX::VE_OK == HTTPServerTools::GetFileInfos (filePath, &lastModified))) { staticFile = true; HTTPProtocol::MakeRFC822GMTDateString (lastModified, lastModifiedString); } } if ((XBOX::VE_OK == fileError) && (NULL != cacheManager) && cacheManager->GetEnableDataCache()) { uLONG bufferSize = (uLONG)GetBody().GetSize(); if (bufferSize <= cacheManager->GetCachedObjectMaxSize()) { void * buffer = GetBody().GetDataPtr(); XBOX::VTime lastChecked; VCachedObject * cachedObject = NULL; XBOX::VTime::Now (lastChecked); bool ok = cacheManager->AddPageToCache (fRequest->GetURL(), virtualHost->GetUUIDString(), contentType, buffer, bufferSize, filePath, lastChecked, lastModified, staticFile, fCompressionMode, &cachedObject); if (ok) { if (NULL != cachedObject) { XBOX::VTime expirationDate; sLONG maxAge = cachedObject->GetMaxAge(); if (maxAge > 0) { XBOX::VString string; string.FromCString ("max-age="); string.AppendLong (maxAge); AddResponseHeader (STRING_HEADER_CACHE_CONTROL, string); AddResponseHeader (STRING_HEADER_AGE, cachedObject->GetAge()); if (cachedObject->GetExpirationDate (expirationDate)) AddResponseHeader (STRING_HEADER_EXPIRES, expirationDate); } else if (cachedObject->GetExpirationDate (expirationDate) && IsVTimeValid (expirationDate)) { AddResponseHeader (STRING_HEADER_EXPIRES, expirationDate); } XBOX::QuickReleaseRefCountable (cachedObject); } } } } if (!lastModifiedString.IsEmpty()) AddResponseHeader (STRING_HEADER_LAST_MODIFIED, lastModifiedString); } if (HTTP_OK == fResponseStatusCode) { if (NULL != fFileToSend) { if (fFileToSend->Exists()) { sLONG8 fileSize = 0; fFileToSend->GetSize (&fileSize); this->SetContentLengthHeader (fileSize); // YT 18-Jul-2011 - ACI0072287 if (XBOX::VE_OK == (error = _SendResponseHeader())) { const sLONG CHUNK_BUFFER_SIZE = 0xFFFF; char * chunkBuffer = (char *)XBOX::vMalloc (CHUNK_BUFFER_SIZE, 0); if (testAssert (NULL != chunkBuffer)) { XBOX::VFileDesc *fileDesc = NULL; if ((XBOX::VE_OK == fFileToSend->Open (XBOX::FA_READ, &fileDesc, XBOX::FO_SequentialScan)) && (NULL != fileDesc)) { uLONG chunkSize = 0; XBOX::VSize readBytes = 0; XBOX::VError fileError = XBOX::VE_OK; sLONG8 unreadSize = 0; unreadSize = fileSize; fileDesc->SetPos (0, true); while ((XBOX::VE_OK == fileError) && (unreadSize > 0)) { chunkSize = (unreadSize > CHUNK_BUFFER_SIZE) ? CHUNK_BUFFER_SIZE : unreadSize; fileError = fileDesc->GetDataAtPos (chunkBuffer, chunkSize, 0, &readBytes); unreadSize -= (sLONG8)readBytes; if ((XBOX::VE_OK == fileError) || (XBOX::VE_STREAM_EOF == fileError)) { error = _WriteToSocket (chunkBuffer, &chunkSize); if (XBOX::VE_OK != error) break; } } delete fileDesc; fileDesc = NULL; } else { error = _SendResponseWithStatusCode (HTTP_INTERNAL_SERVER_ERROR); } XBOX::vFree (chunkBuffer); chunkBuffer = NULL; } else { error = _SendResponseWithStatusCode (HTTP_INTERNAL_SERVER_ERROR); } } } else { error = _SendResponseWithStatusCode (HTTP_NOT_FOUND); } XBOX::ReleaseRefCountable (&fFileToSend); } else if (GetBody().GetDataSize() >= 0) { if (XBOX::VE_OK == (error = _SendResponseHeader())) { if (NULL != GetBody().GetDataPtr()) error = _SendResponseBody(); } } else { error = _SendResponseWithStatusCode (HTTP_INTERNAL_SERVER_ERROR); } } else { error = _SendResponseWithStatusCode (fResponseStatusCode); } } return error; }
void HttpPostSocket::DoMultipartPost() { long length = 0; // calculate content_length of our post body std::string tmp; // fields { for (std::map<std::string,std::list<std::string> >::iterator it = m_fields.begin(); it != m_fields.end(); it++) { std::string name = (*it).first; std::list<std::string>& ref = (*it).second; tmp = "--" + m_boundary + "\r\n" "content-disposition: form-data; name=\"" + name + "\"\r\n" "\r\n"; for (std::list<std::string>::iterator it = ref.begin(); it != ref.end(); it++) { std::string value = *it; tmp += value + "\r\n"; } length += (long)tmp.size(); } } // files { for (std::map<std::string,std::string>::iterator it = m_files.begin(); it != m_files.end(); it++) { std::string name = (*it).first; std::string filename = (*it).second; long content_length = m_content_length[filename]; std::string content_type = m_content_type[filename]; tmp = "--" + m_boundary + "\r\n" "content-disposition: form-data; name=\"" + name + "\"; filename=\"" + filename + "\"\r\n" "content-type: " + content_type + "\r\n" "\r\n"; length += (long)tmp.size(); length += content_length; length += 2; // crlf after file } } // end tmp = "--" + m_boundary + "--\r\n"; length += (long)tmp.size(); // build header, send body SetMethod("POST"); SetHttpVersion( "HTTP/1.1" ); AddResponseHeader( "Host", m_host ); // oops - this is actually a request header that we're adding.. AddResponseHeader( "User-agent", MyUseragent()); AddResponseHeader( "Accept", "text/html, text/plain, */*;q=0.01" ); AddResponseHeader( "Connection", "close" ); AddResponseHeader( "Content-type", "multipart/form-data; boundary=" + m_boundary ); AddResponseHeader( "Content-length", Utility::l2string(length) ); SendRequest(); // send fields { for (std::map<std::string,std::list<std::string> >::iterator it = m_fields.begin(); it != m_fields.end(); it++) { std::string name = (*it).first; std::list<std::string>& ref = (*it).second; tmp = "--" + m_boundary + "\r\n" "content-disposition: form-data; name=\"" + name + "\"\r\n" "\r\n"; for (std::list<std::string>::iterator it = ref.begin(); it != ref.end(); it++) { std::string value = *it; tmp += value + "\r\n"; } Send( tmp ); } } // send files { for (std::map<std::string,std::string>::iterator it = m_files.begin(); it != m_files.end(); it++) { std::string name = (*it).first; std::string filename = (*it).second; std::string content_type = m_content_type[filename]; tmp = "--" + m_boundary + "\r\n" "content-disposition: form-data; name=\"" + name + "\"; filename=\"" + filename + "\"\r\n" "content-type: " + content_type + "\r\n" "\r\n"; Send( tmp ); { FILE *fil = fopen(filename.c_str(),"rb"); if (fil) { char slask[2000]; size_t n; while ((n = fread(slask, 1, 2000, fil)) > 0) { SendBuf(slask, n); } fclose(fil); } } Send("\r\n"); } } // end of send Send("--" + m_boundary + "--\r\n"); }
void HttpdSocket::OnHeaderComplete() { m_cookies = new HttpdCookies(m_http_cookie); #if (defined(SOLARIS8) || defined(SOLARIS)) { char slask[1000]; if (GetMethod() == "GET") { sprintf(slask,"QUERY_STRING=%s", GetQueryString().c_str()); putenv(slask); } sprintf(slask,"REQUEST_METHOD=%s", GetMethod().c_str()); putenv(slask); sprintf(slask,"HTTP_COOKIE=%s", m_http_cookie.c_str()); putenv(slask); sprintf(slask,"CONTENT_TYPE=%s", m_content_type.c_str()); putenv(slask); sprintf(slask,"CONTENT_LENGTH=%s", m_content_length_str.c_str()); putenv(slask); } #elif defined _WIN32 { char slask[1000]; if (GetMethod() == "GET") { sprintf(slask,"QUERY_STRING=%s", GetQueryString().c_str()); _putenv(slask); } sprintf(slask,"REQUEST_METHOD=%s", GetMethod().c_str()); _putenv(slask); sprintf(slask,"HTTP_COOKIE=%s", m_http_cookie.c_str()); _putenv(slask); sprintf(slask,"CONTENT_TYPE=%s", m_content_type.c_str()); _putenv(slask); sprintf(slask,"CONTENT_LENGTH=%s", m_content_length_str.c_str()); _putenv(slask); } #else if (GetMethod() == "GET") { setenv("QUERY_STRING", GetQueryString().c_str(), 1); } setenv("REQUEST_METHOD", GetMethod().c_str(), 1); setenv("HTTP_COOKIE", m_http_cookie.c_str(), 1); setenv("CONTENT_TYPE", m_content_type.c_str(), 1); setenv("CONTENT_LENGTH", m_content_length_str.c_str(), 1); #endif if (GetMethod() == "POST") { m_file = new MemFile; } else if (GetMethod() == "GET") { m_form = new HttpdForm(GetQueryString(), GetQueryString().size() ); AddResponseHeader("Date", datetime2httpdate(GetDate()) ); Exec(); Reset(); // prepare for next request } else { AddResponseHeader("Date", GetHttpDate()); AddResponseHeader("Connection", "close"); SetStatus("405"); SetStatusText("Method not allowed"); SendResponse(); } }