static byte[] HandleResponse(OSHttpRequest httpRequest, OSHttpResponse response, Stream stream, string urlToAppend, Dictionary <string, object> variables, HTTPReturned eventHandler) { Uri myUri = new Uri("http://localhost/index.php?" + HttpServerHandlerHelpers.ReadString(stream)); Dictionary <string, string> newVars = new Dictionary <string, string>(); foreach (string key in variables.Keys) { newVars[key] = HttpUtility.ParseQueryString(myUri.Query).Get(key); } string url = eventHandler(newVars); string html = "<html>" + (url == "" ? "" : ("<head>" + "<meta http-equiv=\"REFRESH\" content=\"0;url=" + url + "\"></HEAD>")) + "</HTML>"; response.ContentType = "text/html"; return(Encoding.UTF8.GetBytes(html)); }
/// <summary> /// Try all the registered xmlrpc handlers when an xmlrpc request is received. /// Sends back an XMLRPC unknown request response if no handler is registered for the requested method. /// </summary> /// <param name="request"></param> /// <param name="response"></param> private byte[] HandleXmlRpcRequests(OSHttpRequest request, OSHttpResponse response) { string requestBody = HttpServerHandlerHelpers.ReadString(request.InputStream); requestBody = requestBody.Replace("<base64></base64>", ""); string responseString = String.Empty; XmlRpcRequest xmlRprcRequest = null; try { xmlRprcRequest = (XmlRpcRequest)(new XmlRpcRequestDeserializer()).Deserialize(requestBody); } catch (XmlException e) { MainConsole.Instance.WarnFormat( "[BASE HTTP SERVER]: Got XMLRPC request with invalid XML from {0}. XML was '{1}'. Sending blank response. Exception: {2}", request.RemoteIPEndPoint, requestBody, e.ToString()); } if (xmlRprcRequest != null) { string methodName = xmlRprcRequest.MethodName; if (methodName != null) { xmlRprcRequest.Params.Add(request.RemoteIPEndPoint); // Param[1] XmlRpcResponse xmlRpcResponse; XmlRpcMethod method; bool methodWasFound; lock (m_rpcHandlers) methodWasFound = m_rpcHandlers.TryGetValue(methodName, out method); if (methodWasFound) { xmlRprcRequest.Params.Add(request.Url); // Param[2] string xff = "X-Forwarded-For"; string xfflower = xff.ToLower(); foreach (string s in request.Headers.AllKeys) { if (s != null && s.Equals(xfflower)) { xff = xfflower; break; } } xmlRprcRequest.Params.Add(request.Headers.Get(xff)); // Param[3] try { xmlRpcResponse = method(xmlRprcRequest, request.RemoteIPEndPoint); } catch (Exception e) { string errorMessage = String.Format( "Requested method [{0}] from {1} threw exception: {2} {3}", methodName, request.RemoteIPEndPoint.Address, e.Message, e.StackTrace); MainConsole.Instance.ErrorFormat("[BASE HTTP SERVER]: {0}", errorMessage); // if the registered XmlRpc method threw an exception, we pass a fault-code along xmlRpcResponse = new XmlRpcResponse(); // Code probably set in accordance with http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php xmlRpcResponse.SetFault(-32603, errorMessage); } } else { xmlRpcResponse = new XmlRpcResponse(); // Code set in accordance with http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php xmlRpcResponse.SetFault( XmlRpcErrorCodes.SERVER_ERROR_METHOD, String.Format("Requested method [{0}] not found", methodName)); } response.ContentType = "text/xml"; responseString = XmlRpcResponseSerializer.Singleton.Serialize(xmlRpcResponse); } else { response.ContentType = "text/plain"; response.StatusCode = 404; response.StatusDescription = "Not Found"; responseString = "Not found"; MainConsole.Instance.ErrorFormat( "[BASE HTTP SERVER]: Handler not found for http request {0} {1}", request.HttpMethod, request.Url.PathAndQuery); } } byte[] buffer = Encoding.UTF8.GetBytes(responseString); response.SendChunked = false; response.ContentEncoding = Encoding.UTF8; return(buffer); }
public void Run() { while (m_running) { PollServiceHttpRequest req = m_request.Dequeue(); try { byte[] buffer = null; if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id)) { StreamReader str; try { str = new StreamReader(req.Context.Request.InputStream); } catch (ArgumentException) { // Stream was not readable means a child agent // was closed due to logout, leaving the // Event Queue request orphaned. continue; } OSHttpResponse response = new OSHttpResponse(req.Context); buffer = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd(), response); } else { if ((Environment.TickCount - req.RequestTime) > m_timeout) { OSHttpResponse response = new OSHttpResponse(req.Context); buffer = req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id, response); } else { ReQueuePollServiceItem reQueueItem = ReQueue; if (reQueueItem != null) { reQueueItem(req); } } } if (buffer != null) { req.Context.Response.ContentEncoding = Encoding.UTF8; try { if (req.Context.Request.ProtocolVersion.Minor == 0) { //HTTP 1.0... no chunking req.Context.Response.ContentLength64 = buffer.Length; using (Stream stream = req.Context.Response.OutputStream) { HttpServerHandlerHelpers.WriteNonChunked(stream, buffer); } } else { req.Context.Response.SendChunked = true; using (Stream stream = req.Context.Response.OutputStream) { HttpServerHandlerHelpers.WriteChunked(stream, buffer); } } req.Context.Response.Close(); } catch (Exception ex) { if (!(ex is HttpListenerException) || !HttpListenerManager.IGNORE_ERROR_CODES.Contains(((HttpListenerException)ex).ErrorCode)) { MainConsole.Instance.WarnFormat("[Poll service worker thread]: Failed to write all data to the stream: {0}", ex.ToString()); } } } } catch (Exception e) { MainConsole.Instance.ErrorFormat("Exception in poll service thread: {0}", e.ToString()); } } }
/// <summary> /// This methods is the start of incoming HTTP request handling. /// </summary> /// <param name="context"></param> public virtual void HandleRequest(HttpListenerContext context) { HttpListenerRequest request = context.Request; using (HttpListenerResponse response = context.Response) { OSHttpRequest req = new OSHttpRequest(context); OSHttpResponse resp = new OSHttpResponse(context); if (request.HttpMethod == String.Empty) // Can't handle empty requests, not wasting a thread { byte[] buffer = GetHTML500(response); response.ContentLength64 = buffer.LongLength; response.Close(buffer, true); return; } response.KeepAlive = false; string requestMethod = request.HttpMethod; string uriString = request.RawUrl; int requestStartTick = Environment.TickCount; // Will be adjusted later on. int requestEndTick = requestStartTick; IStreamedRequestHandler requestHandler = null; try { System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US", true); string path = request.RawUrl; string handlerKey = GetHandlerKey(request.HttpMethod, path); byte[] buffer = null; if ((request.ContentType == "application/xml" || request.ContentType == "text/xml") && GetXmlRPCHandler(request.RawUrl) != null) { buffer = HandleXmlRpcRequests(req, resp); } else if (TryGetStreamHandler(handlerKey, out requestHandler)) { response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type. buffer = requestHandler.Handle(path, request.InputStream, req, resp); } request.InputStream.Close(); try { if (buffer != null) { if (request.ProtocolVersion.Minor == 0) { //HTTP 1.0... no chunking response.ContentLength64 = buffer.Length; using (Stream stream = response.OutputStream) { HttpServerHandlerHelpers.WriteNonChunked(stream, buffer); } } else { response.SendChunked = true; using (Stream stream = response.OutputStream) { HttpServerHandlerHelpers.WriteChunked(stream, buffer); } } response.Close(); } else { response.Close(new byte[0], true); } } catch (Exception ex) { if (!(ex is HttpListenerException) || !HttpListenerManager.IGNORE_ERROR_CODES.Contains(((HttpListenerException)ex).ErrorCode)) { MainConsole.Instance.WarnFormat( "[BASE HTTP SERVER]: HandleRequest failed to write all data to the stream: {0}", ex.ToString()); } response.Abort(); } requestEndTick = Environment.TickCount; } catch (Exception e) { MainConsole.Instance.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.ToString()); response.Abort(); } finally { // Every month or so this will wrap and give bad numbers, not really a problem // since its just for reporting int tickdiff = requestEndTick - requestStartTick; if (tickdiff > 3000 && requestHandler != null) { MainConsole.Instance.InfoFormat( "[BASE HTTP SERVER]: Slow handling of {0} {1} took {2}ms", requestMethod, uriString, tickdiff); } else if (MainConsole.Instance.IsTraceEnabled) { MainConsole.Instance.TraceFormat( "[BASE HTTP SERVER]: Handling {0} {1} took {2}ms", requestMethod, uriString, tickdiff); } } } }