Ejemplo n.º 1
0
 public void HandlePost(System.Net.HttpListenerRequest request, System.Net.HttpListenerResponse response, Server.RequestData data)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 2
0
 public void HandlePost(HttpListenerRequest request, HttpListenerResponse response, Server.RequestData data)
 {
     response.StatusCode = 400;
     response.WriteResponse("Bad Request");
     //return new Httpd.HttpResponse(400, "Bad Request");
 }
Ejemplo n.º 3
0
        public void HandlePost(HttpListenerRequest request, HttpListenerResponse response, Server.RequestData data)
        {
            var presetName = data.PostParameters.GetFirstValue("preset");
            var value      = data.PostParameters.GetFirstValue("value");

            if (string.IsNullOrEmpty(presetName))
            {
                response.StatusCode = 400;
                response.WriteResponse("Missing preset name");
                return;
            }
            if (string.IsNullOrEmpty(value))
            {
                response.StatusCode = 400;
                response.WriteResponse("Missing preset value");
                return;
            }

            // TODO do we need to do filtering on this value?
            presets.Add(presetName, value);
            response.WriteResponse(200, "Preset added");
        }
Ejemplo n.º 4
0
 public void HandlePost(HttpListenerRequest request, HttpListenerResponse response, Server.RequestData data)
 {
     response.StatusCode = 404;
     response.WriteResponse("404 Page Not Found");
 }
Ejemplo n.º 5
0
 public void HandlePut(HttpListenerRequest request, HttpListenerResponse response, Server.RequestData data)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 6
0
        public void HandlePost(HttpListenerRequest request, HttpListenerResponse response, Server.RequestData data)
        {
            try
            {
                string jobID              = data.PostParameters.GetFirstValue("jobid");
                string taskID             = data.PostParameters.GetFirstValue("taskid");
                string complete           = data.PostParameters.GetFirstValue("complete");
                string videoTag           = data.PostParameters.GetFirstValue("tag");
                string videoUrl           = data.PostParameters.GetFirstValue("video");
                string preset             = data.PostParameters.GetFirstValue("preset");
                string options            = data.PostParameters.GetFirstValue("encoding-options");
                string callbackUrl        = data.PostParameters.GetFirstValue("callback");
                string outputExtension    = data.PostParameters.GetFirstValue("extension");
                string multiPass          = data.PostParameters.GetFirstValue("multipass");
                string multiPassExtension = data.PostParameters.GetFirstValue("multipass-extension");
                string multiPassOptions   = data.PostParameters.GetFirstValue("multipass-options");
                string segment            = data.PostParameters.GetFirstValue("segment");

                if (string.IsNullOrEmpty(jobID))
                {
                    response.WriteResponse(400, "Missing parameter jobid");
                    return;
                }
                if (!Regex.Match(jobID, "^[a-zA-Z0-9_-]+$").Success)
                {
                    response.WriteResponse(400, "Job parameter container invalid characters [allowed characters a-Z, 0-9, _ -]");
                    return;
                }
                if (!string.IsNullOrEmpty(complete))
                {
                    if (jobs.ContainsKey(jobID))
                    {
                        jobs[jobID].Complete();
                        response.WriteResponse(200, jobs[jobID]);
                        return;
                    }
                    response.WriteResponse(400, "No such job");
                    return;
                }


                if (!string.IsNullOrEmpty(taskID))
                {
                    if (!Regex.Match(taskID, "^[a-zA-Z0-9_-]+$").Success)
                    {
                        response.WriteResponse(400, "TaskID parameter container invalid characters [allowed characters a-Z, 0-9, _ -]");
                        return;
                    }
                }
                else
                {
                    taskID = rGenerator.Next().ToString();
                }


                if (string.IsNullOrEmpty(outputExtension))
                {
                    response.WriteResponse(400, "Missing parameter extension");
                    return;
                }
                if (!Regex.Match(outputExtension, "^[a-zA-Z0-9]+$").Success)
                {
                    response.WriteResponse(400, "Extension contains invalid characters [allowed characters a-Z, 0-9]");
                    return;
                }
                bool multiPassVal = false;
                if (!string.IsNullOrEmpty(multiPass))
                {
                    if (string.IsNullOrEmpty(multiPassOptions))
                    {
                        response.WriteResponse(400, "MultiPass enabled but multipass-options not provided");
                        return;
                    }
                    if (string.IsNullOrEmpty(multiPassExtension))
                    {
                        response.WriteResponse(400, "MultiPass enabled but multipass-extension not provided");
                        return;
                    }
                    if (!Regex.Match(multiPassExtension, "^[a-zA-Z0-9]+$").Success)
                    {
                        response.WriteResponse(400, "Multipass extension contains invalid characters [allowed characters a-Z, 0-9]");
                        return;
                    }
                    multiPassVal     = true;
                    multiPassOptions = Uri.UnescapeDataString(multiPassOptions.Replace("+", " "));
                }
                else
                {
                    multiPassOptions   = null;
                    multiPassExtension = null;
                }
                if (!string.IsNullOrEmpty(segment))
                {
                    switch (segment.ToLower())
                    {
                    case "hls":
                        segment = "hls";
                        break;

                    default:
                        response.WriteResponse(400, "Invalid segment type valid types are [hls]");
                        return;
                    }
                }

                /*if (string.IsNullOrEmpty(callbackUrl))
                 * {
                 *  response.WriteResponse(400, "Missing parameter callbackUrl");
                 *  return;
                 * }*/
                if (string.IsNullOrEmpty(preset) && string.IsNullOrEmpty(options))
                {
                    response.WriteResponse(400, "Job must specify ffmpeg parameters or a preset");
                    return;
                }
                if (!string.IsNullOrEmpty(options))
                {
                    options = Uri.UnescapeDataString(options.Replace("+", " "));
                }
                if (data.Files.Count == 0)
                {
                    if (string.IsNullOrEmpty(videoUrl))
                    {
                        response.WriteResponse(400, "Missing parameter video");
                        return;
                    }
                    videoUrl = Uri.UnescapeDataString(videoUrl);
                }
                else
                {
                    if (!string.IsNullOrEmpty(videoUrl))
                    {
                        response.WriteResponse(400, "A video was uploaded but a video url parameter was also provided");
                        return;
                    }
                }
                if (Environment.OSVersion.Platform == PlatformID.Win32NT || Environment.OSVersion.Platform == PlatformID.Win32S || Environment.OSVersion.Platform == PlatformID.Win32Windows || Environment.OSVersion.Platform == PlatformID.WinCE)
                {
                    if (options != null)
                    {
                        options = Regex.Replace(options, " '([a-zA-Z0-9{}:=_-]+)'", " \"$1\"");
                    }
                    if (multiPassOptions != null)
                    {
                        multiPassOptions = Regex.Replace(multiPassOptions, " '([a-zA-Z0-9{}:=_-]+)'", " \"$1\"");
                    }
                }
                if (!string.IsNullOrEmpty(callbackUrl))
                {
                    callbackUrl = Uri.UnescapeDataString(callbackUrl);
                }
                TranscodeJob tj    = null;
                bool         added = jobs.TryAdd(jobID, tj);
                if (added)
                {
                    tj = new TranscodeJob(this.jobPool, jobID, callbackUrl);
                    if (!string.IsNullOrEmpty(videoTag))
                    {
                        tj.Tag = Uri.UnescapeDataString(videoTag);
                    }
                    jobs[jobID] = tj;
                    FFRest.stats.AddJob();
                    try
                    {
                        if (data.Files.Count > 0)
                        {
                            var download = new FileDownload(jobID, tj.WorkingDir, data.Files[0].Name);

                            tj.AddDownload(download);
                        }
                        else
                        {
                            var download = new FileDownload(jobID, videoUrl, tj.WorkingDir, jobID + ".vod");

                            tj.AddDownload(download);
                        }
                    }
                    catch (Exception ex)
                    {
                        tj.Fail("Unable to perform transcoding, are your sure your video file is a valid format?");
                    }
                    tj.GenerateThumbnails();
                }
                else
                {
                    tj = jobs[jobID];
                    if (!string.IsNullOrEmpty(videoTag))
                    {
                        tj.Tag = Uri.UnescapeDataString(videoTag);
                    }
                    // We should already have a file for this job on hand
                    if (tj.IsComplete && (tj.CanExpire || tj.IsFailed))
                    {
                        tj          = new TranscodeJob(this.jobPool, jobID, callbackUrl);
                        jobs[jobID] = tj;
                        FFRest.stats.AddJob();
                        try
                        {
                            if (data.Files.Count > 0)
                            {
                                var download = new FileDownload(jobID, tj.WorkingDir, data.Files[0].Name);
                                tj.AddDownload(download);
                            }
                            else
                            {
                                var download = new FileDownload(jobID, videoUrl, tj.WorkingDir, jobID + ".vod");
                                tj.AddDownload(download);
                            }
                        }
                        catch (Exception ex)
                        {
                            tj.Fail("Unable to perform transcoding, are your sure your video file is a valid format?");
                        }
                        tj.GenerateThumbnails();
                    }
                    else
                    {
                        if (data.Files.Count > 0)
                        {
                            foreach (var file in data.Files)
                            {
                                File.Delete(file.Path);
                            }
                        }
                    }
                }

                if (multiPassVal)
                {
                    var mpass = new Multipass(tj, jobID, tj.WorkingDir, multiPassExtension, multiPassOptions);
                    tj.AddFirstPass(mpass);
                }


                TranscoderResult tr = new TranscoderResult(tj.JobToken, taskID, tj.WorkingDir);
                TranscodeTask    tt = new TranscodeTask(tj, tr, taskID, segment, options, outputExtension, multiPassVal);
                tj.AddTask(tt, tr);
                response.WriteResponse(200, new TaskSubmittedResponse()
                {
                    Job = tj, Task = tt
                });
            }
            catch (Exception ex)
            {
                log.Debug("Failed to process request", ex);
                response.WriteResponse(500, "Server Error");
            }
        }
Ejemplo n.º 7
0
        public object Handle()
        {
            try
            {
                if (handler == null)
                {
                    log.Error("HTTP Request Handler is null");
                }
                switch (context.Request.HttpMethod.ToLower())
                {
                case "get":

                    handler.HandleGet(context.Request, context.Response);
                    break;

                case "head":
                    if (handler is IHttpExtendedRequestHandler)
                    {
                        ((IHttpExtendedRequestHandler)handler).HandleHead(context.Request, context.Response);
                    }
                    else
                    {
                        context.Response.StatusCode = 404;
                        //context.Response.Close();
                    }
                    break;

                case "delete":
                    if (handler is IHttpExtendedRequestHandler)
                    {
                        ((IHttpExtendedRequestHandler)handler).HandleDelete(context.Request, context.Response);
                    }
                    else
                    {
                        context.Response.StatusCode = 404;
                        //context.Response.Close();
                    }
                    break;

                case "post":
                    Server.RequestData data = null;
                    // Handle multipart requests with file data
                    if (context.Request.ContentType != null && context.Request.ContentType.StartsWith("multipart/form-data;"))
                    {
                        var boundary = "--" + context.Request.ContentType.Substring(30);

                        byte[]       buffer  = new byte[4096];
                        int          read    = 0;
                        MemoryStream mstream = new MemoryStream();
                        while ((read = context.Request.InputStream.Read(buffer, 0, buffer.Length)) != 0)
                        {
                            mstream.Write(buffer, 0, read);
                        }
                        try
                        {
                            data = processMultipartData(mstream, boundary);
                        }
                        catch (Exception ex)
                        {
                            log.Error("Failed to process http post request", ex);
                            context.Response.WriteResponse(500, ex.Message);
                            return(null);
                        }
                    }
                    else
                    {
                        var post_string = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding).ReadToEnd();
                        var parts       = Server.ParseQueryString(post_string);
                        data = new Server.RequestData();
                        data.PostParameters = parts;
                    }

                    handler.HandlePost(context.Request, context.Response, data);
                    break;
                }
            }
            catch (Exception ex)
            {
                log.Error("HTTP Processing Exception", ex);
                if (context != null)
                {
                    if (context.Response != null)
                    {
                        if (context.Response.OutputStream.CanWrite)
                        {
                            try
                            {
                                context.Response.WriteResponse(500, ex.ToString());
                            }
                            catch (Exception innerException)
                            {
                                log.Error("Failed to write response", innerException);
                                //Console.WriteLine(innerException);
                            }
                        }
                    }
                }
            }

            try
            {
                if (context.Response.OutputStream.CanWrite)
                {
                    context.Response.Close();
                }
            }
            catch (Exception ex)
            {
                log.Error("Error closing stream", ex);
            }
            return(null);
        }
Ejemplo n.º 8
0
        private Server.RequestData processMultipartData(MemoryStream data, string boundary)
        {
            string endBoundary = boundary + "--";

            byte[] boundaryBytes    = Encoding.UTF8.GetBytes(boundary);
            byte[] endBoundaryBytes = Encoding.UTF8.GetBytes(endBoundary);
            var    requestData      = new Server.RequestData();

            using (data)
            {
                data.Position = 0;


                StreamReader sr = new StreamReader(data);

                while (true)
                {
                    string line = sr.ReadLine();

                    if (line == boundary)
                    {
                        break;
                    }
                    if (line == null)
                    {
                        log.Error("Parse error occurred when processing file data");
                    }
                }
                bool         endBoundaryFound = false;
                BinaryWriter currentWriter;
                while (!endBoundaryFound)
                {
                    var    parameters = new Dictionary <string, string>();
                    string line       = sr.ReadLine();

                    while (line != string.Empty)
                    {
                        if (line == null)
                        {
                            throw new Exception("Segment parse Error");
                        }
                        if (line == boundary || line == endBoundary)
                        {
                            throw new Exception("Unexpected segment end");
                        }
                        Dictionary <string, string> values = SplitBySemicolonIgnoringSemicolonsInQuotes(line)
                                                             .Select(x => x.Split(new[] { ':', '=' }, 2))
                                                             // Limit split to 2 splits so we don't accidently split characters in file paths.
                                                             .ToDictionary(
                            x => x[0].Trim().Replace("\"", string.Empty).ToLower(),
                            x => x[1].Trim().Replace("\"", string.Empty));
                        // parameters dictionary.
                        try
                        {
                            foreach (var pair in values)
                            {
                                parameters.Add(pair.Key, pair.Value);
                            }
                        }
                        catch (ArgumentException)
                        {
                            throw new Exception("Duplicate field in section");
                        }

                        line = sr.ReadLine();
                    }
                    if (parameters.ContainsKey("filename"))
                    {
                        string name     = parameters["name"];
                        string filename = Server.random.Next() + ".vod";//parameters["filename"];
                        File.Delete(filename);
                        string contentType        = parameters.ContainsKey("content-type") ? parameters["content-type"] : "text/plain";
                        string contentDisposition = parameters.ContainsKey("content-disposition")
                                                        ? parameters["content-disposition"]
                                                        : "form-data";

                        string filePath = FFRest.config["workingdir"];
                        currentWriter = new BinaryWriter(File.Open(filePath + Path.DirectorySeparatorChar + filename, FileMode.Append, FileAccess.Write, FileShare.Read));
                        bool writerOpen = true;
                        // We want to create a stream and fill it with the data from the
                        // file.
                        var curBuffer  = new byte[4096];
                        var prevBuffer = new byte[4096];
                        var fullBuffer = new byte[4096 * 2];
                        int curLength  = 0;
                        int prevLength = 0;
                        int fullLength = 0;
                        int fileSize   = 0;
                        data.Position = GetActualPosition(sr);
                        prevLength    = data.Read(prevBuffer, 0, prevBuffer.Length);
                        do
                        {
                            curLength = data.Read(curBuffer, 0, curBuffer.Length);


                            Buffer.BlockCopy(prevBuffer, 0, fullBuffer, 0, prevLength);
                            Buffer.BlockCopy(curBuffer, 0, fullBuffer, prevLength, curLength);
                            fullLength = prevLength + curLength;

                            // Now we want to check for a substring within the current buffer.
                            // We need to find the closest substring greedily. That is find the
                            // closest boundary and don't miss the end --'s if it's an end boundary.
                            int endBoundaryPos    = ByteSearch(fullBuffer, endBoundaryBytes, fullLength);
                            int endBoundaryLength = endBoundaryBytes.Length;
                            int boundaryPos       = ByteSearch(fullBuffer, boundaryBytes, fullLength);
                            int boundaryLength    = boundaryBytes.Length;

                            // We need to select the appropriate position and length
                            // based on the smallest non-negative position.
                            int endPos       = -1;
                            int endPosLength = 0;

                            if (endBoundaryPos >= 0 && boundaryPos >= 0)
                            {
                                if (boundaryPos < endBoundaryPos)
                                {
                                    // Select boundary
                                    endPos       = boundaryPos;
                                    endPosLength = boundaryLength;
                                }
                                else
                                {
                                    // Select end boundary
                                    endPos           = endBoundaryPos;
                                    endPosLength     = endBoundaryLength;
                                    endBoundaryFound = true;
                                }
                            }
                            else if (boundaryPos >= 0 && endBoundaryPos < 0)
                            {
                                // Select boundary
                                endPos       = boundaryPos;
                                endPosLength = boundaryLength;
                            }
                            else if (boundaryPos < 0 && endBoundaryPos >= 0)
                            {
                                // Select end boundary
                                endPos           = endBoundaryPos;
                                endPosLength     = endBoundaryLength;
                                endBoundaryFound = true;
                            }

                            if (endPos != -1)
                            {
                                // Now we need to check if the endPos is followed by \r\n or just \n. HTTP
                                // specifies \r\n but some clients might encode with \n. Or we might get 0 if
                                // we are at the end of the file.



                                // We also need to check if the last n characters of the buffer to write
                                // are a newline and if they are ignore them.
                                int    maxNewlineBytes     = Encoding.UTF8.GetMaxByteCount(2);
                                int    bufferNewlineOffset = -1;
                                byte[] dataRef             = fullBuffer;
                                int    tmpOffset           = Math.Max(0, endPos - maxNewlineBytes);
                                if (tmpOffset != 0)
                                {
                                    dataRef = fullBuffer.Skip(tmpOffset).ToArray();
                                }


                                int position = ByteSearch(dataRef, Encoding.UTF8.GetBytes("\r\n"), maxNewlineBytes);
                                if (position != -1)
                                {
                                    bufferNewlineOffset = position + tmpOffset;
                                }


                                int bufferNewlineLength = 0;
                                if (fullBuffer[bufferNewlineOffset] == '\r' && fullBuffer[bufferNewlineOffset + 1] == '\n')
                                {
                                    bufferNewlineLength = 2;
                                }

                                // We've found an end. We need to consume all the binary up to it
                                // and then write the remainder back to the original stream. Then we
                                // need to modify the original streams position to take into account
                                // the new data.
                                // We also want to chop off the newline that is inserted by the protocl.
                                // We can do this by reducing endPos by the length of newline in this environment
                                // and encoding
                                //FileHandler(name, filename, contentType, contentDisposition, fullBuffer,
                                //            endPos - bufferNewlineLength);
                                fileSize += endPos - bufferNewlineLength;
                                currentWriter.Write(fullBuffer, 0, endPos - bufferNewlineLength);
                                currentWriter.Flush();
                                currentWriter.Close();
                                writerOpen = false;
                                sr.DiscardBufferedData();

                                //int writeBackOffset = endPos + endPosLength + boundaryNewlineOffset;
                                //int writeBackAmount = (prevLength + curLength) - writeBackOffset;
                                //var writeBackBuffer = new byte[writeBackAmount];
                                //Buffer.BlockCopy(fullBuffer, writeBackOffset, writeBackBuffer, 0, writeBackAmount);
                                //reader.Buffer(writeBackBuffer);

                                break;
                            }


                            // No end, consume the entire previous buffer
                            fileSize += prevLength;
                            currentWriter.Write(prevBuffer, 0, prevLength);
                            sr.DiscardBufferedData();
                            //FileHandler(name, filename, contentType, contentDisposition, prevBuffer, prevLength);

                            // Now we want to swap the two buffers, we don't care
                            // what happens to the data from prevBuffer so we set
                            // curBuffer to it so it gets overwrited.

                            byte[] tempBuffer = curBuffer;
                            curBuffer  = prevBuffer;
                            prevBuffer = tempBuffer;

                            // We don't need to swap the lengths because
                            // curLength will be overwritten in the next
                            // iteration of the loop.
                            prevLength = curLength;
                        } while (prevLength != 0);
                        if (writerOpen)
                        {
                            currentWriter.Flush();
                            currentWriter.Close();
                        }
                        requestData.Files.Add(new Server.RequestData.UploadFile()
                        {
                            FileSize = fileSize,
                            Name     = filename,
                            Path     = filePath + Path.DirectorySeparatorChar + filename
                        });
                    }
                    else
                    {
                        var  paramData = new StringBuilder();
                        bool firstTime = true;
                        line = sr.ReadLine();
                        while (line != boundary && line != endBoundary)
                        {
                            if (line == null)
                            {
                                throw new Exception("Unexpected end of section");
                            }

                            if (firstTime)
                            {
                                paramData.Append(line);
                                firstTime = false;
                            }
                            else
                            {
                                paramData.Append(Environment.NewLine);
                                paramData.Append(line);
                            }
                            line = sr.ReadLine();
                        }

                        if (line == endBoundary)
                        {
                            endBoundaryFound = true;
                        }

                        // If we're here we've hit the boundary and have the data!
                        requestData.PostParameters.Add(parameters["name"], paramData.ToString());
                    }
                }
            }
            return(requestData);
        }