Example #1
0
 private byte[] OKResponse (OSHttpResponse httpResponse)
 {
     httpResponse.AddHeader ("X-Handlers-Provided", m_HandlersType);
     httpResponse.StatusCode = (int)HttpStatusCode.OK;
     httpResponse.StatusDescription = "OK";
     return new byte[0];
 }
Example #2
0
        /// <summary>
        ///     Invoked by OSHttpRequestPump.
        /// </summary>
        public override OSHttpHandlerResult Process(OSHttpRequest request)
        {
            // call handler method
            Hashtable responseData = _handler(request.Query);

            int    responseCode   = (int)responseData["int_response_code"];
            string responseString = (string)responseData["str_response_string"];
            string contentType    = (string)responseData["content_type"];

            //Even though only one other part of the entire code uses HTTPHandlers, we shouldn't expect this
            //and should check for NullReferenceExceptions
            if (string.IsNullOrEmpty(contentType))
            {
                contentType = "text/html";
            }

            OSHttpResponse response = new OSHttpResponse(request);

            // We're forgoing the usual error status codes here because the client
            // ignores anything but 200 and 301
            response.StatusCode = (int)OSHttpStatusCode.SuccessOk;

            if (responseCode == (int)OSHttpStatusCode.RedirectMovedPermanently)
            {
                response.RedirectLocation = (string)responseData["str_redirect_location"];
                response.StatusCode       = responseCode;
            }

            response.AddHeader("Content-type", contentType);

            byte[] buffer;

            if (!contentType.Contains("image"))
            {
                buffer = Encoding.UTF8.GetBytes(responseString);
            }
            else
            {
                buffer = Convert.FromBase64String(responseString);
            }

            response.SendChunked     = false;
            response.ContentLength64 = buffer.Length;
            response.ContentEncoding = Encoding.UTF8;

            try
            {
                response.Body.Write(buffer, 0, buffer.Length);
            }
            catch (Exception ex)
            {
                _log.ErrorFormat("[OSHttp Http Handler]: Error:  {0}", ex.Message);
            }
            finally
            {
                response.Send();
            }

            return(OSHttpHandlerResult.Done);
        }
Example #3
0
        byte[] OptionsHandler(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
        {
            httpResponse.AddHeader("DAV", "2");
            httpResponse.AddHeader("MS-Author-Via", "DAV");

            //This now gets all the events that have handler from the dav listener
            string allowString = server.GetAvailableMethods();

            //Add this information to both, Public and Allow. We currently have no way of separating these two
            httpResponse.AddHeader("Public", allowString);
            httpResponse.AddHeader("Allow", allowString);

            //Preserving the old headers as reference. These should be removed when method is mature enough
            //response.AddHeader("Public", "COPY, DELETE, GET, HEAD, MKCOL, MOVE, OPTIONS, PROPFIND, PROPPATCH, PUT");
            //response.AddHeader("Allow", "COPY, DELETE, GET, HEAD, MKCOL, MOVE, OPTIONS, PROPFIND, PROPPATCH, PUT");

            return OpenMetaverse.Utils.EmptyBytes;
        }
        private void WriteTextureData(OSHttpRequest request, OSHttpResponse response, AssetBase texture, string format)
        {
            string range = request.Headers.GetOne("Range");
            //m_log.DebugFormat("[GETTEXTURE]: Range {0}", range);
            if (!String.IsNullOrEmpty(range)) // JP2's only
            {
                // Range request
                int start, end;
                if (TryParseRange(range, out start, out end))
                {
                    // Before clamping start make sure we can satisfy it in order to avoid
                    // sending back the last byte instead of an error status
                    if (start >= texture.Data.Length)
                    {
                        response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
                        return;
                    }

                    end = Utils.Clamp(end, 0, texture.Data.Length - 1);
                    start = Utils.Clamp(start, 0, end);
                    int len = end - start + 1;

                    //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);

                    if (len < texture.Data.Length)
                        response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;

                    response.ContentLength = len;
                    response.ContentType = texture.Metadata.ContentType;
                    response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));

                    response.Body.Write(texture.Data, start, len);
                }
                else
                {
                    m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range);
                    response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
                }
            }
            else // JP2's or other formats
            {
                // Full content request
                response.StatusCode = (int)System.Net.HttpStatusCode.OK;
                response.ContentLength = texture.Data.Length;
                if (format == DefaultFormat)
                    response.ContentType = texture.Metadata.ContentType;
                else
                    response.ContentType = "image/" + format;
                response.Body.Write(texture.Data, 0, texture.Data.Length);
            }
        }
            public byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
            {
                byte[] assetData = null;
                UUID assetID;
                // Split the URL up into an AssetID and a method
                string[] rawUrl = httpRequest.Url.PathAndQuery.Split('/');

                if (rawUrl.Length >= 3 && UUID.TryParse(rawUrl[1], out assetID))
                {
                    UUID authToken = Utils.GetAuthToken(httpRequest);

                    if (m_server.AuthorizationProvider.IsDataAuthorized(authToken, assetID))
                    {
                        BackendResponse storageResponse = m_server.StorageProvider.TryFetchData(assetID, out assetData);

                        if (storageResponse == BackendResponse.Success)
                        {
                            httpResponse.StatusCode = (int) HttpStatusCode.OK;
                            httpResponse.ContentType = "application/octet-stream";
                            httpResponse.AddHeader("Content-Disposition", "attachment; filename=" + assetID.ToString());
                            httpResponse.ContentLength = assetData.Length;
                            httpResponse.Body.Write(assetData, 0, assetData.Length);
                        }
                        else if (storageResponse == BackendResponse.NotFound)
                        {
                            httpResponse.StatusCode = (int) HttpStatusCode.NotFound;
                        }
                        else
                        {
                            httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError;
                        }
                    }
                    else
                    {
                        httpResponse.StatusCode = (int) HttpStatusCode.Forbidden;
                    }

                    return assetData;
                }

                httpResponse.StatusCode = (int) HttpStatusCode.BadRequest;
                return assetData;
            }
Example #6
0
        internal void DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
        {
            //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
            int responsecode = (int)responsedata["int_response_code"];
            string responseString = (string)responsedata["str_response_string"];
            string contentType = (string)responsedata["content_type"];


            if (responsedata.ContainsKey("error_status_text"))
            {
                response.StatusDescription = (string)responsedata["error_status_text"];
            }
            if (responsedata.ContainsKey("http_protocol_version"))
            {
                response.ProtocolVersion = (string)responsedata["http_protocol_version"];
            }

            if (responsedata.ContainsKey("keepalive"))
            {
                bool keepalive = (bool)responsedata["keepalive"];
                response.KeepAlive = keepalive;

            }

            if (responsedata.ContainsKey("reusecontext"))
                response.ReuseContext = (bool) responsedata["reusecontext"];

            // Cross-Origin Resource Sharing with simple requests
            if (responsedata.ContainsKey("access_control_allow_origin"))
                response.AddHeader("Access-Control-Allow-Origin", (string)responsedata["access_control_allow_origin"]);

            //Even though only one other part of the entire code uses HTTPHandlers, we shouldn't expect this
            //and should check for NullReferenceExceptions

            if (string.IsNullOrEmpty(contentType))
            {
                contentType = "text/html";
            }

            // The client ignores anything but 200 here for web login, so ensure that this is 200 for that

            response.StatusCode = responsecode;

            if (responsecode == (int)OSHttpStatusCode.RedirectMovedPermanently)
            {
                response.RedirectLocation = (string)responsedata["str_redirect_location"];
                response.StatusCode = responsecode;
            }

            response.AddHeader("Content-Type", contentType);

            byte[] buffer;

            if (!(contentType.Contains("image")
                || contentType.Contains("x-shockwave-flash")
                || contentType.Contains("application/x-oar")
                || contentType.Contains("application/vnd.ll.mesh")))
            {
                // Text
                buffer = Encoding.UTF8.GetBytes(responseString);
            }
            else
            {
                // Binary!
                buffer = Convert.FromBase64String(responseString);
            }

            response.SendChunked = false;
            response.ContentLength64 = buffer.Length;
            response.ContentEncoding = Encoding.UTF8;

            try
            {
                response.OutputStream.Write(buffer, 0, buffer.Length);
            }
            catch (Exception ex)
            {
                m_log.Warn("[HTTPD]: Error - " + ex.Message);
            }
            finally
            {
                //response.OutputStream.Close();
                try
                {
                    response.OutputStream.Flush();
                    response.Send();

                    //if (!response.KeepAlive && response.ReuseContext)
                    //    response.FreeContext();
                }
                catch (SocketException e)
                {
                    // This has to be here to prevent a Linux/Mono crash
                    m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
                }
                catch (IOException e)
                {
                    m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
                }
            }
        }
Example #7
0
        internal byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
        {
            //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
            int responsecode = (int)responsedata["int_response_code"];
            string responseString = (string)responsedata["str_response_string"];
            string contentType = (string)responsedata["content_type"];

            if (responsedata.ContainsKey("error_status_text"))
            {
                response.StatusDescription = (string)responsedata["error_status_text"];
            }
            if (responsedata.ContainsKey("http_protocol_version"))
            {
                response.ProtocolVersion = (string)responsedata["http_protocol_version"];
            }

            if (responsedata.ContainsKey("keepalive"))
            {
                bool keepalive = (bool)responsedata["keepalive"];
                response.KeepAlive = keepalive;

            }

            if (responsedata.ContainsKey("reusecontext"))
                response.ReuseContext = (bool) responsedata["reusecontext"];

            // Cross-Origin Resource Sharing with simple requests
            if (responsedata.ContainsKey("access_control_allow_origin"))
                response.AddHeader("Access-Control-Allow-Origin", (string)responsedata["access_control_allow_origin"]);

            //Even though only one other part of the entire code uses HTTPHandlers, we shouldn't expect this
            //and should check for NullReferenceExceptions

            if (string.IsNullOrEmpty(contentType))
            {
                contentType = "text/html";
            }

            // The client ignores anything but 200 here for web login, so ensure that this is 200 for that

            response.StatusCode = responsecode;

            if (responsecode == (int)OSHttpStatusCode.RedirectMovedPermanently)
            {
                response.RedirectLocation = (string)responsedata["str_redirect_location"];
                response.StatusCode = responsecode;
            }

            response.AddHeader("Content-Type", contentType);

            byte[] buffer;

            if (!(contentType.Contains("image")
                || contentType.Contains("x-shockwave-flash")
                || contentType.Contains("application/x-oar")
                || contentType.Contains("application/vnd.ll.mesh")))
            {
                // Text
                buffer = Encoding.UTF8.GetBytes(responseString);
            }
            else
            {
                // Binary!
                buffer = Convert.FromBase64String(responseString);
            }

            response.SendChunked = false;
            response.ContentLength64 = buffer.Length;
            response.ContentEncoding = Encoding.UTF8;

            return buffer;
        }
Example #8
0
        public byte[] SendHTML500(OSHttpResponse response)
        {
            response.StatusCode = (int)OSHttpStatusCode.ServerErrorInternalError;
            response.AddHeader("Content-type", "text/html");

            string responseString = GetHTTP500();
            byte[] buffer = Encoding.UTF8.GetBytes(responseString);

            response.SendChunked = false;
            response.ContentLength64 = buffer.Length;
            response.ContentEncoding = Encoding.UTF8;

            return buffer;
        }
Example #9
0
        public byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpRequest request, OSHttpResponse response)
        {
            //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
            int responsecode = (int)responsedata["int_response_code"];
            string responseString = (string)responsedata["str_response_string"];
            string contentType = (string)responsedata["content_type"];
            byte[] responseBinary = responsedata.Contains("response_binary") ? (byte[])responsedata["response_binary"] : null;

            if (responsedata.ContainsKey("error_status_text"))
            {
                response.StatusDescription = (string)responsedata["error_status_text"];
            }
            if (responsedata.ContainsKey("http_protocol_version"))
            {
                response.ProtocolVersion = new System.Version((string)responsedata["http_protocol_version"]);
            }

            if (responsedata.ContainsKey("keepalive"))
            {
                bool keepalive = (bool)responsedata["keepalive"];
                response.KeepAlive = keepalive;
            }

            // Cross-Origin Resource Sharing with simple requests
            if (responsedata.ContainsKey("access_control_allow_origin"))
                response.AddHeader("Access-Control-Allow-Origin", (string)responsedata["access_control_allow_origin"]);

            // The client ignores anything but 200 here for web login, so ensure that this is 200 for that
            response.StatusCode = responsecode;
            if (responsecode == (int)OSHttpStatusCode.RedirectMovedPermanently)
            {
                response.RedirectLocation = (string)responsedata["str_redirect_location"];
                response.StatusCode = responsecode;
            }

            if (string.IsNullOrEmpty(contentType))
                contentType = "text/html";
            response.AddHeader("Content-Type", contentType);

            byte[] buffer;

            if (responseBinary != null)
            {
                buffer = responseBinary;
            }
            else
            {
                if (!(contentType.Contains("image")
                    || contentType.Contains("x-shockwave-flash")
                    || contentType.Contains("application/x-oar")
                    || contentType.Contains("application/vnd.ll.mesh")))
                {
                    // Text
                    buffer = Encoding.UTF8.GetBytes(responseString);
                }
                else
                {
                    // Binary!
                    buffer = Convert.FromBase64String(responseString);
                }
            }

            response.SendChunked = false;
            response.ContentLength64 = buffer.LongLength;
            response.ContentEncoding = System.Text.Encoding.UTF8;

            return buffer;
        }
Example #10
0
 public static void OpenAuthResponseToHttp(OSHttpResponse httpResponse, OutgoingWebResponse openAuthResponse)
 {
     httpResponse.StatusCode = (int)openAuthResponse.Status;
     foreach (string key in openAuthResponse.Headers.Keys)
         httpResponse.AddHeader(key, openAuthResponse.Headers[key]);
     if (!String.IsNullOrEmpty(openAuthResponse.Body))
         AddToBody(httpResponse, openAuthResponse.Body);
 }
Example #11
0
        /*public static void OpenAuthResponseToHttp(OSHttpResponse httpResponse, OutgoingWebResponse openAuthResponse)
        {
            httpResponse.StatusCode = (int)openAuthResponse.Status;
            foreach (string key in openAuthResponse.Headers.Keys)
                httpResponse.AddHeader(key, openAuthResponse.Headers[key]);
            if (!String.IsNullOrEmpty(openAuthResponse.Body))
                AddToBody(httpResponse, openAuthResponse.Body);
        }*/

        public static byte[] MakeOpenAuthResponse(OSHttpResponse httpResponse, OutgoingWebResponse openAuthResponse)
        {
            httpResponse.StatusCode = (int)openAuthResponse.Status;
            foreach (string key in openAuthResponse.Headers.Keys)
                httpResponse.AddHeader(key, openAuthResponse.Headers[key]);
            if (!String.IsNullOrEmpty(openAuthResponse.Body))
                return Encoding.UTF8.GetBytes(openAuthResponse.Body);
            else
                return Utils.EmptyBytes;
        }
Example #12
0
        /// <summary>
        /// Returns information about a mumble server via a REST Request
        /// </summary>
        /// <param name="request"></param>
        /// <param name="path"></param>
        /// <param name="param">A string representing the sim's UUID</param>
        /// <param name="httpRequest">HTTP request header object</param>
        /// <param name="httpResponse">HTTP response header object</param>
        /// <returns>Information about the mumble server in http response headers</returns>
        public string RestGetMumbleServerInfo(Scene scene, string request, string path, string param,
                                       OSHttpRequest httpRequest, OSHttpResponse httpResponse)
        {
            if (m_murmurd_host == null)
            {
                httpResponse.StatusCode = 404;
                httpResponse.StatusDescription = "Not Found";

                string message = "[MurmurVoice]: Server info request from " + httpRequest.RemoteIPEndPoint.Address + ". Cannot send response, module is not configured properly.";
                m_log.Warn(message);
                return "Mumble server info is not available.";
            }
            if (httpRequest.Headers.GetValues("avatar_uuid") == null)
            {
                httpResponse.StatusCode = 400;
                httpResponse.StatusDescription = "Bad Request";

                string message = "[MurmurVoice]: Invalid server info request from " + httpRequest.RemoteIPEndPoint.Address + "";
                m_log.Warn(message);
                return "avatar_uuid header is missing";
            }
                
            string avatar_uuid = httpRequest.Headers.GetValues("avatar_uuid")[0];
            string responseBody = String.Empty;
            UUID avatarId;
            if (UUID.TryParse(avatar_uuid, out avatarId))
            {
                if (scene == null) throw new Exception("[MurmurVoice] Invalid scene.");

                ServerManager manager = GetServerManager(scene);
                Agent agent = manager.Agent.GetOrCreate(avatarId, scene);

                string channel_uri;

                ScenePresence avatar = scene.GetScenePresence(avatarId);
                
                // get channel_uri: check first whether estate
                // settings allow voice, then whether parcel allows
                // voice, if all do retrieve or obtain the parcel
                // voice channel
                LandData land = scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
                if (null == land) 
                    throw new Exception(String.Format("region \"{0}\": avatar \"{1}\": land data not yet available",
                                                      scene.RegionInfo.RegionName, avatar.Name));

                m_log.DebugFormat("[MurmurVoice] region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}",
                                  scene.RegionInfo.RegionName, land.Name, land.LocalID, avatar.Name, request, path, param);

                if (((land.Flags & (uint)ParcelFlags.AllowVoiceChat) > 0) && scene.RegionInfo.EstateSettings.AllowVoice)
                {
                    agent.channel = manager.Channel.GetOrCreate(ChannelName(scene, land));

                    // Host/port pair for voice server
                    channel_uri = String.Format("{0}:{1}", m_murmurd_host, m_murmurd_port);

                    if (agent.session > 0)
                    {
                        Murmur.User state = manager.Server.getState(agent.session);
                        GetServerCallback(scene).AddUserToChan(state, agent.channel);
                    }

                    m_log.InfoFormat("[MurmurVoice] {0}", channel_uri);
                }
                else
                {
                    m_log.DebugFormat("[MurmurVoice] Voice not enabled.");
                    channel_uri = "";
                }
                string m_context = "Mumble voice system";

                httpResponse.AddHeader("Mumble-Server", m_murmurd_host);
                httpResponse.AddHeader("Mumble-Version", m_server_version);
                httpResponse.AddHeader("Mumble-Channel", channel_uri);
                httpResponse.AddHeader("Mumble-User", avatar_uuid);
                httpResponse.AddHeader("Mumble-Password", agent.pass);
                httpResponse.AddHeader("Mumble-Avatar-Id", avatar_uuid);
                httpResponse.AddHeader("Mumble-Context-Id", m_context);

                responseBody += "Mumble-Server: " + m_murmurd_host + "\n";
                responseBody += "Mumble-Version: " + m_server_version + "\n";
                responseBody += "Mumble-Channel: " + channel_uri + "\n";
                responseBody += "Mumble-User: "******"\n";
                responseBody += "Mumble-Password: "******"\n";
                responseBody += "Mumble-Avatar-Id: " + avatar_uuid + "\n";
                responseBody += "Mumble-Context-Id: " + m_context + "\n";

                string log_message = "[MurmurVoice]: Server info request handled for " + httpRequest.RemoteIPEndPoint.Address + "";
                m_log.Info(log_message);
            }
            else
            {
                httpResponse.StatusCode = 400;
                httpResponse.StatusDescription = "Bad Request";

                m_log.Warn("[MurmurVoice]: Could not parse avatar uuid from request");
                return "could not parse avatar_uuid header";
            }

            return responseBody;
        }
Example #13
0
        byte[] LockHandler(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
        {
            string username;
            if (server.AuthenticateRequest(httpRequest, httpResponse, out username))
            {
                WebDAVLockRequest lockRequest = ParseRequest(httpRequest);

                WebDAVLockResponse lockResponse = server.OnLockConnector(lockRequest);
                if (lockResponse == null)
                {
                    httpResponse.StatusCode = (int)HttpStatusCode.InternalServerError;
                    return OpenMetaverse.Utils.EmptyBytes;
                }

                if (lockResponse.HttpStatusCode == HttpStatusCode.OK || lockResponse.HttpStatusCode == HttpStatusCode.Created)
                {
                    using (MemoryStream responseStream = new MemoryStream())
                    {
                        using (XmlTextWriter xmlWriter = new XmlTextWriter(responseStream, Encoding.ASCII))
                        {
                            xmlWriter.Formatting = Formatting.Indented;
                            xmlWriter.IndentChar = '\t';
                            xmlWriter.Indentation = 1;
                            xmlWriter.WriteStartDocument();

                            xmlWriter.WriteStartElement("D", "prop", "DAV:");
                            xmlWriter.WriteStartElement("lockdiscovery", "DAV:");
                            xmlWriter.WriteStartElement("activelock", "DAV:");

                            xmlWriter.WriteStartElement("locktype", "DAV:");
                            xmlWriter.WriteElementString(Enum.GetName(typeof(LockType), lockResponse.LockType), "DAV:", String.Empty); //only legal value available. future extensions might support others
                            xmlWriter.WriteEndElement(); //locktype

                            xmlWriter.WriteStartElement("lockscope", "DAV:");
                            xmlWriter.WriteElementString(Enum.GetName(typeof(LockScope), lockResponse.LockScope), "DAV:", String.Empty); //possible values "exclusive" or "shared"
                            xmlWriter.WriteEndElement(); //lockscope

                            xmlWriter.WriteStartElement("depth", "DAV:");
                            xmlWriter.WriteValue(lockResponse.Depth);
                            xmlWriter.WriteEndElement(); //depth

                            //The server must save this identifier and return it in the lockdiscovery property so that other users and other client software can see some information about the lock creator.
                            xmlWriter.WriteStartElement("owner", "DAV:");
                            if (lockResponse.OwnerNamespaceUri != null && lockResponse.OwnerNamespaceUri != String.Empty)
                            {
                                xmlWriter.WriteAttributeString("xmlns:a", lockResponse.OwnerNamespaceUri);
                            }
                            if (lockResponse.OwnerValue != null && lockResponse.OwnerValue != String.Empty)
                            {
                                xmlWriter.WriteValue(lockResponse.OwnerValue);
                            }
                            else
                            {
                                foreach (KeyValuePair<string, string> kvp in lockResponse.OwnerValues)
                                {
                                    xmlWriter.WriteElementString(kvp.Key, "DAV:", kvp.Value);
                                }
                            }
                            //xmlWriter.WriteElementString("lock-user", "DAV:", username);
                            //xmlWriter.WriteElementString("created-by", "DAV:", "Some user");
                            xmlWriter.WriteEndElement(); //owner

                            xmlWriter.WriteElementString("timeout", "DAV:", lockResponse.Timeout);

                            xmlWriter.WriteStartElement("locktoken", "DAV:");
                            xmlWriter.WriteElementString("href", "DAV:", lockResponse.LockToken);
                            xmlWriter.WriteEndElement();
                            httpResponse.AddHeader("Lock-Token", lockResponse.LockToken); //add lock token also to header

                            xmlWriter.WriteEndElement(); //activelock
                            xmlWriter.WriteEndElement(); //lockdiscovery
                            xmlWriter.WriteEndElement(); //prop

                            xmlWriter.WriteEndDocument();
                            xmlWriter.Flush();

                            httpResponse.StatusCode = (int)lockResponse.HttpStatusCode;

                            byte[] bytes = responseStream.ToArray();
                            httpResponse.ContentLength = bytes.Length;
                            return bytes;
                        }
                    }
                }
                else
                {
                    httpResponse.StatusCode = (int)lockResponse.HttpStatusCode;
                    return OpenMetaverse.Utils.EmptyBytes;
                }
            }

            return OpenMetaverse.Utils.EmptyBytes;
        }
Example #14
0
        internal byte[] srvDoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
        {
            int    responsecode;
            string responseString = String.Empty;

            byte[] responseData = null;
            string contentType;

            if (responsedata == null)
            {
                responsecode   = 500;
                responseString = "No response could be obtained";
                contentType    = "text/plain";
                responsedata   = new Hashtable();
            }
            else
            {
                try
                {
                    //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
                    responsecode = (int)responsedata["int_response_code"];
                    if (responsedata["bin_response_data"] != null)
                    {
                        responseData = (byte[])responsedata["bin_response_data"];
                    }
                    else
                    {
                        responseString = (string)responsedata["str_response_string"];
                    }
                    contentType = (string)responsedata["content_type"];
                    if (responseString == null)
                    {
                        responseString = String.Empty;
                    }
                }
                catch
                {
                    responsecode   = 500;
                    responseString = "No response could be obtained";
                    contentType    = "text/plain";
                    responsedata   = new Hashtable();
                }
            }

            if (responsedata.ContainsKey("error_status_text"))
            {
                response.StatusDescription = (string)responsedata["error_status_text"];
            }
            if (responsedata.ContainsKey("http_protocol_version"))
            {
                response.ProtocolVersion = (string)responsedata["http_protocol_version"];
            }

            if (responsedata.ContainsKey("keepalive"))
            {
                bool keepalive = (bool)responsedata["keepalive"];
                response.KeepAlive = keepalive;
            }

            // Cross-Origin Resource Sharing with simple requests
            if (responsedata.ContainsKey("access_control_allow_origin"))
            {
                response.AddHeader("Access-Control-Allow-Origin", (string)responsedata["access_control_allow_origin"]);
            }

            //Even though only one other part of the entire code uses HTTPHandlers, we shouldn't expect this
            //and should check for NullReferenceExceptions

            if (string.IsNullOrEmpty(contentType))
            {
                contentType = "text/html";
            }

            // The client ignores anything but 200 here for web login, so ensure that this is 200 for that

            response.StatusCode = responsecode;

            if (responsecode == (int)OSHttpStatusCode.RedirectMovedPermanently)
            {
                response.RedirectLocation = (string)responsedata["str_redirect_location"];
                response.StatusCode       = responsecode;
            }

            response.AddHeader("Content-Type", contentType);
            if (responsedata.ContainsKey("headers"))
            {
                Hashtable headerdata = (Hashtable)responsedata["headers"];

                foreach (string header in headerdata.Keys)
                {
                    response.AddHeader(header, headerdata[header].ToString());
                }
            }

            byte[] buffer;

            if (responseData != null)
            {
                buffer = responseData;
            }
            else
            {
                if (!(contentType.Contains("image") ||
                      contentType.Contains("x-shockwave-flash") ||
                      contentType.Contains("application/x-oar") ||
                      contentType.Contains("application/vnd.ll.mesh")))
                {
                    // Text
                    buffer = Encoding.UTF8.GetBytes(responseString);
                }
                else
                {
                    // Binary!
                    buffer = Convert.FromBase64String(responseString);
                }

                response.SendChunked     = false;
                response.ContentLength64 = buffer.Length;
                response.ContentEncoding = Encoding.UTF8;
            }

            return(buffer);
        }
Example #15
0
        void OpenIDLoginGetHandler(OSHttpRequest httpRequest, OSHttpResponse httpResponse)
        {
            if (httpRequest.Url.AbsolutePath.EndsWith("openid_callback"))
            {
                #region OpenID Callback

                IAuthenticationResponse authResponse = CableBeachState.RelyingParty.GetResponse(OpenAuthHelper.GetRequestInfo(httpRequest));

                if (authResponse != null)
                {
                    if (authResponse.Status == AuthenticationStatus.Authenticated)
                    {
                        // OpenID authentication succeeded
                        Uri identity = new Uri(authResponse.ClaimedIdentifier.ToString());

                        // Check if this identity is authorized for access. This check is done here for the second time
                        // because the ClaimedIdentifier after authentication has finished is not necessarily the original
                        // OpenID URL entered into the login form
                        if (CableBeachState.IsIdentityAuthorized(identity))
                        {
                            string firstName = null, lastName = null, email = null;

                            // Get the Simple Registration attributes the IDP returned, if any
                            ClaimsResponse sreg = authResponse.GetExtension<ClaimsResponse>();
                            if (sreg != null)
                            {
                                if (!String.IsNullOrEmpty(sreg.FullName))
                                {
                                    string[] firstLast = sreg.FullName.Split(' ');
                                    if (firstLast.Length == 2)
                                    {
                                        firstName = firstLast[0];
                                        lastName = firstLast[1];
                                    }
                                }

                                email = sreg.Email;
                            }

                            CableBeachState.StartLogin(httpRequest, httpResponse, identity, firstName, lastName, email, CableBeachAuthMethods.OPENID);
                        }
                        else
                        {
                            CableBeachState.SendLoginTemplate(httpResponse, null, identity + " is not authorized to access this world");
                        }
                    }
                    else
                    {
                        // Parse an error message out of authResponse
                        string errorMsg = (authResponse.Exception != null) ?
                            authResponse.Exception.Message :
                            authResponse.Status.ToString();

                        CableBeachState.SendLoginTemplate(httpResponse, null, errorMsg);
                    }
                }
                else
                {
                    httpResponse.StatusCode = (int)HttpStatusCode.BadRequest;
                    OpenAuthHelper.AddToBody(httpResponse, "Invalid or missing OpenID callback data");
                }

                #endregion OpenID Callback
            }
            else if (httpRequest.Url.AbsolutePath.EndsWith("oauth_callback"))
            {
                #region OAuth Callback

                ServiceRequestsData stateData;
                string requestToken = OpenAuthHelper.GetQueryValue(httpRequest.Url.Query, "oauth_token");

                if (!String.IsNullOrEmpty(requestToken) && CableBeachState.CurrentServiceRequests.TryGetValue(requestToken, out stateData))
                {
                    ServiceIdentifier serviceIdentifier = CableBeachState.GetCurrentService(stateData.ServiceRequirements);
                    Service service;
                    CapabilityRequirements capRequirements;

                    if (serviceIdentifier != null)
                    {
                        if (stateData.Services.TryGetValue(serviceIdentifier, out service) &&
                            stateData.ServiceRequirements.TryGetValue(serviceIdentifier, out capRequirements))
                        {
                            try
                            {
                                OAuthConsumer consumer = new OAuthConsumer(OpenAuthHelper.CreateServiceProviderDescription(service), CableBeachState.OAuthTokenManager);
                                AuthorizedTokenResponse tokenResponse = consumer.ProcessUserAuthorization(OpenAuthHelper.GetRequestInfo(httpRequest));

                                // We actually don't need the access token at all since the capabilities should be in this response.
                                // Parse the capabilities out of ExtraData
                                CapabilityRequirements newCaps = new CapabilityRequirements();
                                foreach (KeyValuePair<string, string> capability in tokenResponse.ExtraData)
                                {
                                    Uri capIdentifier, capUri;
                                    if (Uri.TryCreate(capability.Key, UriKind.Absolute, out capIdentifier) &&
                                        Uri.TryCreate(capability.Value, UriKind.Absolute, out capUri))
                                    {
                                        newCaps[capIdentifier] = capUri;
                                    }
                                }

                                m_log.Info("[CABLE BEACH LOGIN]: Fetched " + newCaps.Count + " capabilities through OAuth from " + service.OAuthGetAccessToken);

                                // Update the capabilities for this service
                                stateData.ServiceRequirements[serviceIdentifier] = newCaps;
                            }
                            catch (Exception ex)
                            {
                                m_log.Error("[CABLE BEACH LOGIN]: Failed to exchange request token for capabilities at " + service.OAuthGetAccessToken + ": " + ex.Message);
                                CableBeachState.SendLoginTemplate(httpResponse, null, "OAuth request to " + service.OAuthGetAccessToken + " failed: " + ex.Message);
                                return;
                            }
                        }
                        else
                        {
                            m_log.Error("[CABLE BEACH LOGIN]: OAuth state data corrupted, could not find service or service requirements for " + serviceIdentifier);
                            CableBeachState.SendLoginTemplate(httpResponse, null, "OAuth state data corrupted, please try again");
                            return;
                        }
                    }
                    else
                    {
                        m_log.Warn("[CABLE BEACH LOGIN]: OAuth callback fired but there are no unfulfilled services. Could be a browser refresh");
                    }

                    // Check if we need to continue the cap requesting process
                    CableBeachState.GetCapabilitiesOrCompleteLogin(httpRequest, httpResponse, stateData, requestToken);
                }
                else
                {
                    // A number of different things could lead here (incomplete login sequence, browser refresh of a completed sequence).
                    // Safest thing to do would be to redirect back to the login screen
                    httpResponse.StatusCode = (int)HttpStatusCode.Found;
                    httpResponse.AddHeader("Location", new Uri(CableBeachState.UserServerUrl, "/login/").ToString());
                }

                #endregion OAuth Callback
            }
            else
            {
                // Make sure we are starting from the correct URL
                if (httpRequest.Url.Authority != CableBeachState.UserServerUrl.Authority)
                {
                    m_log.Debug("[CABLE BEACH LOGIN]: Redirecting from " + httpRequest.Url + " to " + CableBeachState.UserServerUrl);
                    httpResponse.StatusCode = (int)HttpStatusCode.Redirect;
                    httpResponse.RedirectLocation = new Uri(CableBeachState.UserServerUrl, "/login/").ToString();
                }
                else if (httpRequest.Query.ContainsKey("openid_identifier"))
                {
                    OpenIDLoginFormHandler(httpRequest, httpResponse, httpRequest.Query["openid_identifier"] as string);
                }
                else
                {
                    // TODO: Check for a client cookie with an authenticated session
                    CableBeachState.SendLoginTemplate(httpResponse, null, null);
                }
            }
        }
Example #16
0
        byte[] PropFindHandler(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
        {
            string username;
            if (server.AuthenticateRequest(httpRequest, httpResponse, out username))
            {
                //PropertyRequestType requestType = PropertyRequestType.AllProperties;
                List<string> davProperties = new List<string>();
                List<string> validProperties = new List<string>();
                List<string> invalidProperties = new List<string>();

                if (httpRequest.ContentLength != 0)
                {
                    XPathNavigator requestNavigator = new XPathDocument(httpRequest.InputStream).CreateNavigator();
                    XPathNodeIterator propNodeIterator = requestNavigator.SelectDescendants("prop", "DAV:", false);
                    if (propNodeIterator.MoveNext())
                    {
                        XPathNodeIterator nodeChildren = propNodeIterator.Current.SelectChildren(XPathNodeType.All);
                        while (nodeChildren.MoveNext())
                        {
                            XPathNavigator currentNode = nodeChildren.Current;

                            if (currentNode.NodeType == XPathNodeType.Element)
                                davProperties.Add(currentNode.LocalName.ToLower());
                        }
                    }
                }

                using (MemoryStream responseStream = new MemoryStream())
                {
                    using (XmlTextWriter xmlWriter = new XmlTextWriter(responseStream, Encoding.ASCII))
                    {
                        xmlWriter.Formatting = Formatting.Indented;
                        xmlWriter.IndentChar = '\t';
                        xmlWriter.Indentation = 1;
                        xmlWriter.WriteStartDocument();

                        xmlWriter.WriteStartElement("D", "multistatus", "DAV:");
                        // Microsoft cruft (joy)
                        xmlWriter.WriteAttributeString("xmlns:b", "urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882");
                        xmlWriter.WriteAttributeString("xmlns:c", "urn:schemas-microsoft-com:office:office");

                        DepthHeader depth = Depth.ParseDepth(httpRequest);

                        IList<IWebDAVResource> resources = server.OnPropFindConnector(username, httpRequest.Url.AbsolutePath, depth);
                        if (resources.Count > 0)
                        {
                            for (int i = 0; i < resources.Count; i++)
                                XmlResponse.WriteResponse(xmlWriter, davProperties, resources[i]);
                        }

                        xmlWriter.WriteEndElement(); // multistatus

                        xmlWriter.WriteEndDocument();
                        xmlWriter.Flush();

                        httpResponse.KeepAlive = httpRequest.KeepAlive;
                        httpResponse.ContentType = "text/xml";
                        httpResponse.ContentEncoding = Encoding.UTF8;
                        httpResponse.AddHeader("DAV", "1");
                        httpResponse.AddHeader("MS-Author-Via", "DAV");
                        httpResponse.AddHeader("Cache-Control", "no-cache");
                        if (resources.Count > 0)
                        {
                            httpResponse.StatusCode = 207; // Multistatus

                            byte[] bytes = responseStream.ToArray();
                            httpResponse.ContentLength = bytes.Length;
                            return bytes;
                        }
                        else
                        {
                            //eventually this should be the same that is defined in HttpListener.Set404Handler()
                            //that however needs some work in HttpServer
                            httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
                            httpResponse.StatusDescription = "Not Found";
                            string notFoundResponse = "<html><head><title>Page Not Found</title></head><body><h3>" + httpResponse.StatusDescription + "</h3></body></html>";
                            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(notFoundResponse);
                            httpResponse.ContentLength = buffer.Length;
                            return buffer;
                        }
                    }
                }
            }

            return OpenMetaverse.Utils.EmptyBytes;
        }
Example #17
0
        /// <summary>
        /// Handles all GET and POST requests for Facebook Connect logins
        /// </summary>
        public void Handle(string requestPath, Stream request, Stream response, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
        {
            if (!CanHandle(httpRequest.Url))
            {
                httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
                OpenAuthHelper.AddToBody(httpResponse, "File not found");
                return;
            }

            try
            {
                string path = GetPath(httpRequest.Url);
                string extension = GetFileExtension(path);
                if (extension == null)
                {
                    httpResponse.StatusCode = (int)HttpStatusCode.UnsupportedMediaType;
                    OpenAuthHelper.AddToBody(httpResponse, "Unsupported media type");
                    return;
                }

                if (m_mimeTypes.ContainsKey(extension))
                {
                    httpResponse.ContentType = m_mimeTypes[extension];
                }
                else
                {
                    httpResponse.StatusCode = (int)HttpStatusCode.UnsupportedMediaType;
                    OpenAuthHelper.AddToBody(httpResponse, "Unsupported media type");
                    return;
                }

                using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    if (!String.IsNullOrEmpty(httpRequest.Headers["if-modified-since"]))
                    {
                        DateTime lastRequest = DateTime.Parse(httpRequest.Headers["if-modified-since"]);
                        if (lastRequest.CompareTo(File.GetLastWriteTime(path)) <= 0)
                            httpResponse.StatusCode = (int)HttpStatusCode.NotModified;
                    }

                    httpResponse.AddHeader("Last-modified", File.GetLastWriteTime(path).ToString("r"));
                    httpResponse.ContentLength = stream.Length;

                    if (!httpRequest.HttpMethod.Equals("HEADERS", StringComparison.InvariantCultureIgnoreCase) &&
                        httpResponse.StatusCode != (int)HttpStatusCode.NotModified)
                    {
                        OpenAuthHelper.CopyTo(stream, httpResponse.OutputStream, (int)stream.Length);
                    }
                }
            }
            catch (FileNotFoundException)
            {
                httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
                OpenAuthHelper.AddToBody(httpResponse, "File not found");
            }
        }
Example #18
0
        private void WriteTextureData(OSHttpRequest request, OSHttpResponse response, AssetBase texture, string format)
        {
            m_service.Registry.RequestModuleInterface<ISimulationBase>().EventManager.FireGenericEventHandler(
                "AssetRequested", new object[] {m_service.Registry, texture, m_service.AgentID});

            string range = request.Headers.GetOne("Range");
            //MainConsole.Instance.DebugFormat("[GETTEXTURE]: Range {0}", range);
            if (!String.IsNullOrEmpty(range)) // JP2's only
            {
                // Range request
                int start, end;
                if (TryParseRange(range, out start, out end))
                {
                    // Before clamping start make sure we can satisfy it in order to avoid
                    // sending back the last byte instead of an error status
                    if (start >= texture.Data.Length)
                    {
                        response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
                    }
                    else
                    {
                        end = Utils.Clamp(end, 0, texture.Data.Length - 1);
                        start = Utils.Clamp(start, 0, end);
                        int len = end - start + 1;

                        //MainConsole.Instance.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);

                        if (len < texture.Data.Length)
                            response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
                        else
                            response.StatusCode = (int)System.Net.HttpStatusCode.OK;

                        response.ContentLength = len;
                        response.ContentType = texture.TypeString;
                        response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));

                        response.Body.Write(texture.Data, start, len);
                    }
                }
                else
                {
                    MainConsole.Instance.Warn("[GETTEXTURE]: Malformed Range header: " + range);
                    response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
                }
            }
            else // JP2's or other formats
            {
                // Full content request
                response.StatusCode = (int)System.Net.HttpStatusCode.OK;
                response.ContentLength = texture.Data.Length;
                response.ContentType = texture.TypeString;
                if (format == DefaultFormat)
                    response.ContentType = texture.TypeString;
                else
                    response.ContentType = "image/" + format;
                response.Body.Write(texture.Data, 0, texture.Data.Length);
            }
        }
Example #19
0
        public byte[] SendHTML404(OSHttpResponse response)
        {
            response.StatusCode = 404;
            response.AddHeader("Content-type", "text/html");

            string responseString = GetHTTP404();
            byte[] buffer = Encoding.UTF8.GetBytes(responseString);

            response.SendChunked = false;
            response.ContentLength64 = buffer.Length;
            response.ContentEncoding = Encoding.UTF8;

            return buffer;
        }
Example #20
0
        private void SendChunk(OSHttpRequest request, OSHttpResponse response, int X, int Y)
        {
            string range = request.Headers.GetOne("Range");
            //m_log.DebugFormat("[GETTEXTURE]: Range {0}", range);
            byte[] chunk = m_scene.Voxels.GetChunk(X, Y);
            if (!String.IsNullOrEmpty(range))
            {
                // Range request
                int start, end;
                if (TryParseRange(range, out start, out end))
                {
                    // Before clamping start make sure we can satisfy it in order to avoid
                    // sending back the last byte instead of an error status
                    if (start >= chunk.Length)
                    {
                        response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
                        return;
                    }

                    end = Utils.Clamp(end, 0, chunk.Length - 1);
                    start = Utils.Clamp(start, 0, end);
                    int len = end - start + 1;

                    //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);

                    if (len < chunk.Length)
                        response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;

                    response.ContentLength = len;
                    response.ContentType = "application/octet-stream";
                    response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, chunk.Length));

                    response.Body.Write(chunk, start, len);
                }
                else
                {
                    m_log.Warn("Malformed Range header: " + range);
                    response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
                }
            }
            else
            {
                // Full content request
                response.ContentLength = chunk.Length;
                response.ContentType = "application/octet-stream";
                response.Body.Write(chunk, 0, chunk.Length);
            }
        }
Example #21
0
        public void SendResponse(OSHttpRequest request, OSHttpResponse response, IRequestHandler requestHandler, byte[] buffer)
        {
            try
            {
                request.InputStream.Close();

                // Do not include the time taken to actually send the response to the caller in the measurement
                // time.  This is to avoid logging when it's the client that is slow to process rather than the
                // server
                request.EndTime = Environment.TickCount;
                // Every month or so this will wrap and give bad numbers, not really a problem
                // since its just for reporting
                int tickdiff = request.EndTime - request.StartTime;

                // Dont log EQG messages.  They always run long due to the way the queue works
                if ((tickdiff > 3000) && (request.Url.AbsolutePath.StartsWith("/CAPS/EQG") == false))
                {
                    m_log.InfoFormat(
                        "[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} {4} from {5} took {6}ms",
                        request.SeqNo,
                        request.HttpMethod,
                        request.Url.AbsolutePath,
                        requestHandler != null ? requestHandler.Name : "",
                        requestHandler != null ? requestHandler.Description : "",
                        request.RemoteIPEndPoint,
                        tickdiff);
                }
                else if (DebugLevel >= 4)
                {
                    m_log.DebugFormat(
                        "[BASE HTTP SERVER]: HTTP IN {0} :{1} took {2}ms",
                        request.SeqNo,
                        Port,
                        tickdiff);
                }

                if (buffer != null)
                {          
                    //find the accept encoding key
                    string acceptEncodingKey = null;
                    foreach (string key in request.Headers.AllKeys)
                    {
                        if (key.ToLower() == "accept-encoding")
                        {
                            acceptEncodingKey = request.Headers[key];
                        }
                    }

                    // GZip compress the response if the client says they can handle that
                    if (acceptEncodingKey != null &&
                        request.Headers["accept-encoding"].Contains("gzip"))
                    {
                        using (MemoryStream ms = new MemoryStream())
                        {
                            using (GZipStream gs = new GZipStream(ms, CompressionMode.Compress))
                            {
                                gs.Write(buffer, 0, buffer.Length);
                            }

                            buffer = ms.ToArray();
                        }

                        response.AddHeader("Content-Encoding", "gzip");
                    }

                    if (!response.SendChunked)
                        response.ContentLength64 = buffer.LongLength;

                    response.OutputStream.BeginWrite(buffer, 0, buffer.Length, ResponseWriteFinished, Tuple.Create(request, response, requestHandler));
                }
            }
            catch (Exception e)
            {
                //fill out request end time to get an actual count in case the exception is thrown in response.Write
                request.EndTime = Environment.TickCount;
                int tickdiff = request.EndTime - request.StartTime;

                m_log.ErrorFormat(
                    "[BASE HTTP SERVER]: HandleRequest() threw {0} while processing {1} {2} {3} {4} {5} took {6}ms",
                    e,
                    request.SeqNo,
                    request.HttpMethod,
                    request.Url.AbsolutePath,
                    requestHandler != null ? requestHandler.Name : "",
                    requestHandler != null ? requestHandler.Description : "",
                    tickdiff);
                // note that request.RemoteIPEndPoint is often disposed when we reach here (e.g. remote end has crashed)
            }
        }
Example #22
0
        public void SendHTML404(OSHttpResponse response, string host)
        {
            // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s
            //MSIE doesn't allow for 400 pages to show... so we send 200 for now
            response.StatusCode = 200;
            //response.StatusCode = 400;
            response.AddHeader("Content-type", "text/html");

            string responseString = GetHTTP404(host);
            byte[] buffer = Encoding.UTF8.GetBytes(responseString);

            response.SendChunked = false;
            response.ContentLength64 = buffer.Length;
            response.ContentEncoding = Encoding.UTF8;

            try
            {
                response.OutputStream.Write(buffer, 0, buffer.Length);
            }
            catch (Exception ex)
            {
                m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.ToString());
            }
            finally
            {
                //response.OutputStream.Close();
                try
                {
                    response.Send();
                    //response.FreeContext();
                }
                catch (SocketException e)
                {
                    // This has to be here to prevent a Linux/Mono crash
                    m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
                }
            }
        }
Example #23
0
        public byte[] SendHTML500(OSHttpResponse response)
        {
            // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s
            response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
            response.AddHeader("Content-type", "text/html");

            string responseString = GetHTTP500();
            byte[] buffer = Encoding.UTF8.GetBytes(responseString);

            response.SendChunked = false;
            response.ContentLength64 = buffer.Length;
            response.ContentEncoding = Encoding.UTF8;
            
                
            return buffer;
        }
        public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
        {
            Uri xrdUrl = new Uri(CableBeachServerState.ServiceUrl, "/xrd");
            httpResponse.AddHeader("link", String.Format("<{0}>; rel=\"describedby\"; type=\"application/xrd+xml\"", xrdUrl));

            httpResponse.ContentType = "text/html";
            return CableBeachServerState.BuildServiceRootPageTemplate(xrdUrl.ToString());
        }
Example #25
0
        internal void DoHTTPGruntWork(Hashtable responsedata)
        {
            if (Request.Body.CanRead)
            {
                Request.Body.Dispose();
            }

            if (responsedata.Contains("h"))
            {
                OSHttpResponse r = (OSHttpResponse)responsedata["h"];
                try
                {
                    r.Send();
                }
                catch { }
                PollServiceArgs.RequestsHandled++;
                return;
            }

            OSHttpResponse response = new OSHttpResponse(new HttpResponse(Request));

            if (responsedata == null)
            {
                SendNoContentError(response);
                return;
            }

            int    responsecode   = 200;
            string responseString = String.Empty;
            string contentType;

            byte[] buffer     = null;
            int    rangeStart = 0;
            int    rangeLen   = -1;

            try
            {
                //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
                if (responsedata["int_response_code"] != null)
                {
                    responsecode = (int)responsedata["int_response_code"];
                }

                if (responsedata["bin_response_data"] != null)
                {
                    buffer = (byte[])responsedata["bin_response_data"];
                    responsedata["bin_response_data"] = null;

                    if (responsedata["bin_start"] != null)
                    {
                        rangeStart = (int)responsedata["bin_start"];
                    }

                    if (responsedata["int_bytes"] != null)
                    {
                        rangeLen = (int)responsedata["int_bytes"];
                    }
                }
                else
                {
                    responseString = (string)responsedata["str_response_string"];
                }

                contentType = (string)responsedata["content_type"];
                if (responseString == null)
                {
                    responseString = String.Empty;
                }
            }
            catch
            {
                SendNoContentError(response);
                return;
            }

            response.StatusCode = responsecode;
            if (responsecode == (int)HttpStatusCode.Moved)
            {
                response.AddHeader("Location", (string)responsedata["str_redirect_location"]);
                response.KeepAlive = false;
                PollServiceArgs.RequestsHandled++;
                response.Send();
                return;
            }

            if (responsedata.ContainsKey("http_protocol_version"))
            {
                response.ProtocolVersion = (string)responsedata["http_protocol_version"];
            }

            if (responsedata.ContainsKey("keepalive"))
            {
                response.KeepAlive = (bool)responsedata["keepalive"];
            }

            if (responsedata.ContainsKey("keepaliveTimeout"))
            {
                response.KeepAliveTimeout = (int)responsedata["keepaliveTimeout"];
            }


            if (responsedata.ContainsKey("prio"))
            {
                response.Priority = (int)responsedata["prio"];
            }

            if (responsedata.ContainsKey("error_status_text"))
            {
                response.StatusDescription = (string)responsedata["error_status_text"];
            }

            // Cross-Origin Resource Sharing with simple requests
            if (responsedata.ContainsKey("access_control_allow_origin"))
            {
                response.AddHeader("Access-Control-Allow-Origin", (string)responsedata["access_control_allow_origin"]);
            }

            if (string.IsNullOrEmpty(contentType))
            {
                response.AddHeader("Content-Type", "text/html");
            }
            else
            {
                response.AddHeader("Content-Type", contentType);
            }

            if (responsedata.ContainsKey("headers"))
            {
                Hashtable headerdata = (Hashtable)responsedata["headers"];

                foreach (string header in headerdata.Keys)
                {
                    response.AddHeader(header, headerdata[header].ToString());
                }
            }

            if (buffer == null)
            {
                if (contentType != null && (!(contentType.Contains("image") ||
                                              contentType.Contains("x-shockwave-flash") ||
                                              contentType.Contains("application/x-oar") ||
                                              contentType.Contains("application/vnd.ll.mesh"))))
                {
                    // Text
                    buffer = Encoding.UTF8.GetBytes(responseString);
                }
                else
                {
                    // Binary!
                    buffer = Convert.FromBase64String(responseString);
                }
                response.ContentEncoding = Encoding.UTF8;
            }

            if (rangeStart < 0 || rangeStart > buffer.Length)
            {
                rangeStart = 0;
            }

            if (rangeLen < 0)
            {
                rangeLen = buffer.Length;
            }
            else if (rangeLen + rangeStart > buffer.Length)
            {
                rangeLen = buffer.Length - rangeStart;
            }

            response.ContentLength64 = rangeLen;

            try
            {
                if (rangeLen > 0)
                {
                    response.RawBufferStart = rangeStart;
                    response.RawBufferLen   = rangeLen;
                    response.RawBuffer      = buffer;
                    //response.OutputStream.Write(buffer, rangeStart, rangeLen);
                }

                buffer = null;

                response.Send();
            }
            catch (Exception ex)
            {
                if (ex is System.Net.Sockets.SocketException)
                {
                    // only mute connection reset by peer so we are not totally blind for now
                    if (((System.Net.Sockets.SocketException)ex).SocketErrorCode != System.Net.Sockets.SocketError.ConnectionReset)
                    {
                        m_log.Warn("[POLL SERVICE WORKER THREAD]: Error ", ex);
                    }
                }
                else
                {
                    m_log.Warn("[POLL SERVICE WORKER THREAD]: Error ", ex);
                }
            }

            PollServiceArgs.RequestsHandled++;
        }
Example #26
0
        /// <summary>
        /// Invoked by OSHttpRequestPump.
        /// </summary>
        public override OSHttpHandlerResult Process(OSHttpRequest request)
        {
            // call handler method
            Hashtable responseData = _handler(request.Query);

            int responseCode = (int)responseData["int_response_code"];
            string responseString = (string)responseData["str_response_string"];
            string contentType = (string)responseData["content_type"];

            //Even though only one other part of the entire code uses HTTPHandlers, we shouldn't expect this
            //and should check for NullReferenceExceptions

            if (string.IsNullOrEmpty(contentType))
            {
                contentType = "text/html";
            }

            OSHttpResponse response = new OSHttpResponse(request);

            // We're forgoing the usual error status codes here because the client
            // ignores anything but 200 and 301

            response.StatusCode = (int)OSHttpStatusCode.SuccessOk;

            if (responseCode == (int)OSHttpStatusCode.RedirectMovedPermanently)
            {
                response.RedirectLocation = (string)responseData["str_redirect_location"];
                response.StatusCode = responseCode;
            }

            response.AddHeader("Content-type", contentType);

            byte[] buffer;

            if (!contentType.Contains("image"))
            {
                buffer = Encoding.UTF8.GetBytes(responseString);
            }
            else
            {
                buffer = Convert.FromBase64String(responseString);
            }

            response.SendChunked = false;
            response.ContentLength64 = buffer.Length;
            response.ContentEncoding = Encoding.UTF8;

            try
            {
                response.Body.Write(buffer, 0, buffer.Length);
            }
            catch (Exception ex)
            {
                _log.ErrorFormat("[OSHttpHttpHandler]: Error:  {0}", ex.Message);
            }
            finally
            {
                response.Send();
            }

            return OSHttpHandlerResult.Done;
        }
Example #27
0
        public void SendHTML500(OSHttpResponse response)
        {
            // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s
            response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
            response.AddHeader("Content-type", "text/html");

            string responseString = GetHTTP500();
            byte[] buffer = Encoding.UTF8.GetBytes(responseString);

            response.SendChunked = false;
            response.ContentLength64 = buffer.Length;
            response.ContentEncoding = Encoding.UTF8;
            try
            {
                response.OutputStream.Write(buffer, 0, buffer.Length);
            }
            catch (Exception ex)
            {
                m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message);
            }
            finally
            {
                //response.OutputStream.Close();
                try
                {
                    response.Send();
                    //response.FreeContext();
                }
                catch (SocketException e)
                {
                    // This has to be here to prevent a Linux/Mono crash
                    m_log.WarnFormat("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
                }
            }
        }
Example #28
0
        internal bool AuthenticateRequest(OSHttpRequest request, OSHttpResponse response, out string username)
        {
            username = String.Empty;
            bool authSuccess = true;

            if (Authentication != AuthenticationType.None)
            {
                authSuccess = false;

                string[] authHeaderValues = request.Headers.GetValues("Authorization");
                string authHeader = (authHeaderValues != null && authHeaderValues.Length > 0) ?
                    authHeader = authHeaderValues[0] :
                    authHeader = String.Empty;

                switch (Authentication)
                {
                    case AuthenticationType.Basic:
                        if (authHeader.StartsWith("Basic"))
                        {
                            string basicStr = Encoding.ASCII.GetString(Convert.FromBase64String(authHeader.Substring(6)));
                            int colonPos = basicStr.LastIndexOf(':');
                            if (colonPos > -1)
                            {
                                username = basicStr.Substring(0, colonPos);
                                string password = basicStr.Substring(colonPos + 1);

                                if (OnBasicAuthenticate != null)
                                    authSuccess = OnBasicAuthenticate(username, password);
                            }
                        }
                        break;
                    case AuthenticationType.Digest:
                        authHeader = authHeader.Trim();
                        if (authHeader.StartsWith("Digest"))
                        {
                            Dictionary<string, string> digestives = new Dictionary<string, string>();
                            digestives = GetHeaderParts(authHeader);

                            if (digestives["uri"] != HttpUtility.UrlPathEncode(request.Url.PathAndQuery))
                            {
                                response.StatusCode = (int)HttpStatusCode.BadRequest;
                                return false;
                            }

                            string passwd = null;
                            PasswordFormat format;
                            if (OnDigestAuthenticate != null)
                            {
                                if (!OnDigestAuthenticate(digestives["username"], out format, out passwd))
                                {
                                    authSuccess = false; //failed to find password
                                    break;
                                }
                            }
                            else
                            {
                                //no password request handler
                                response.StatusCode = (int)HttpStatusCode.InternalServerError;
                                return false;
                            }

                            string ha1 = null;
                            username = digestives["username"];
                            //For some unknown horrible reason, windows vista client gives username in format DOMAIN\USER, but
                            //calculates the MD5 hash with format DOMAIN\USER. To prevent it from failing well need to convert
                            //the username to proper format. For more info
                            //see: http://www.webdavsystem.com/server/documentation/authentication/digest_vista_xp_2003
                            if (request.Headers["User-Agent"] != null && request.Headers["User-Agent"].StartsWith("Microsoft-WebDAV-MiniRedir/6") && username.Contains("\\\\"))
                            {
                                string[] usernameParts = username.Split('\\');
                                username = usernameParts[0] + "\\" + usernameParts[2];
                            }

                            if (format == PasswordFormat.Plain)
                                ha1 = MD5HashString(username + ":" + digestives["realm"] + ":" + passwd);
                            else
                                ha1 = passwd;

                            string ha2 = null;
                            if (digestives["qop"] != null && digestives["qop"] == "auth-int")
                            {
                                string entityHash = MD5HashString(request.InputStream.ToString());
                                ha2 = MD5HashString(request.HttpMethod + ":" + digestives["uri"] + ":" + entityHash);
                            }
                            else
                                ha2 = MD5HashString(request.HttpMethod + ":" + digestives["uri"]);

                            string myResponse = null;
                            if (digestives["qop"] != null && (digestives["qop"] == "auth-int" || digestives["qop"] == "auth"))
                                myResponse = MD5HashString(
                                    ha1 + ":" +
                                    digestives["nonce"] + ":" +
                                    digestives["nc"] + ":" +
                                    digestives["cnonce"] + ":" +
                                    digestives["qop"] + ":" +
                                    ha2);
                            else
                                myResponse = MD5HashString(ha1 + ":" + digestives["nonce"] + ":" + ha2);

                            if (myResponse == digestives["response"] && 
                                IsValidNonce(digestives["nonce"]))
                                authSuccess = true;
                            else
                                authSuccess = false;
                            break;

                        }
                        authSuccess = false;
                        break;
                }
            }

            if (authSuccess)
            {
                return true;
            }
            else
            {
                byte[] responseData = Encoding.UTF8.GetBytes("401 Access Denied");
                response.StatusCode = (int)HttpStatusCode.Unauthorized;
                response.StatusDescription = "Access Denied";
                response.ContentLength = responseData.Length;
                response.Body.Write(responseData, 0, responseData.Length);

                if (Authentication == AuthenticationType.Digest)
                {
                    string realm = request.Url.Host;
                    string nonce = GenerateNonce();

                    //qop indicates that the server is merely looking for the client to authenticate
                    //may ask for message integrity as well (qop=auth-int)
                    string qop = "auth";

                    //advices if the client on whether it's appropriate to prompt the user for the password again or use a cached value
                    bool stale = false; //send stale=true when it needs the client to rechallenge the user.

                    //construct the digest header value
                    string digest = "Digest realm=\"" + realm + "\",";
                    digest += " stale=" + stale.ToString() + ",";
                    digest += " nonce=\"" + nonce + "\",";
                    digest += " qop=\"" + qop + "\", algorithm=\"MD5\"";
                    response.AddHeader("WWW-Authenticate", digest);
                }
                else
                {
                    response.AddHeader("WWW-Authenticate", "Basic Realm=\"\"");
                }

                return false;
            }
        }