» »

c# mobitel m vrata

c# mobitel m vrata

Looooooka ::

A kdo slucajno uporablja kksno svojo kratko stevilko in preko nje pri mobitelu prejema MMS sporocila?
S prejemanjem v php-ju, asp-ju in asp.netu nimam nobenih problemov.
Ta teden, pa sem poskusal zadevo usposobiti z asp.net Web API-jem.
In ker nikakor ni uspelo branje nobenega requesta...sem spisal en client progrma, ki pac posta datoteke in podatke po rfc2388 specifikacijah.
Tam zadeva deluje perfektno.
Deluje tudi na http://www.posttestserver.com/.
No requeste, ki jih dobivam od mobitela pa moram (samo pri uporabi Web Apija) lastno rocno parsat. Dejansko se mi zdi, da po prvem content-typu, kjer bi morali slediti dve prazni vrstici posiljajo nek cuden znak, ki pa ocitno zgoraj omenjenih jezikov NE moti.
Tukaj pa pac crkne.

V glavnem...zadevo mam reseno in zdej pravilno parsam zadeve ampak je pac grdo, ker pac ne bi smelo biti potrebe po rocnem parsanju. Me zanima ce je imel slucajno se kdo drug isti problem pri katerem drugem jeziku(ki se tud striktno drzi specifikacije)?

Ker ce nisem edini bi sel tezit na mobitel ce lahko mal preverijo svoj del kode(ni razloga, da n-ljudi na svojem koncu dela neke hacke ce je problem na njihovi strani).

Bom pa drugace cez vikend se malo pogledat tist njihov post....mogoce je to celo kaksen bug v web api-ju.

Looooooka ::

No...ker sm ze cajt zapravu na tem.
Izgleda da res en space narobe posiljajo.
parsanje ob vsaki funkciji se mi zdi debilno...ker ima Web Api ReadAsMultipartAsync() funkcijo, ki samo pricakuje stream v pravilni obliki.
med pisanjem sem se spomnil, da bi bilo mogoce fino popravljati tako crappy requeste spisane v nacinu, ki je napisan rfc1867(tega zgleda mobitel zajebe) kot requeste spisane v zgoraj omenjenemu rfc2388(ta omogoce, da namesto form-date in file data podatkov request vsebuje tudi svoj multipart/mixed podatke(oz po domace...forma v formi in vsaka forma ima lahko svoje form-data, file, in spet multipart/mixed podatke).

AAAAAAAAAAAAAAAAAAnyyyyyyyyyyyyywaaaaaaaaaay. Tale cheap fix je popravil mobitelove napake...in par "crappy" multipart postov, ki sem jih probal.

v web api-ju g auporabite tako, da v configu dodamo Filter ali pa MessageHandler (v datoteki sta oba)
config.Filters.Add(new MultiPartFormDataFixFilter())
ali pa
config.MessageHandlers.Add(new MultiPartFormDataFixHandler());

Koda:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using HttpUtils;
using System.IO;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using System.Web.Http.Filters;

namespace MultiPartFixer
{

    public class MultiPartInfo
    {
        public MultiPartInfo(String FileName, String Name, byte[] FileContents, IDictionary<String, String> Parameters)
        {
            this.Parameters = new Dictionary<string, String>();
            this.FileName = FileName;
            this.Name = Name;
            this.FileContents = FileContents;
            if (Parameters != null)
            {
                foreach (var item in Parameters)
                {
                    this.Parameters.Add(new KeyValuePair<String, String>(item.Key, item.Value));
                }
            }
        }
        public IDictionary<String, String> Parameters { get; private set; }

        public String Boundary
        {
            get
            {

                if (this.Parameters.ContainsKey("Boundary"))
                {
                    return this.Parameters["Boundary"].ToString();
                }
                else
                {
                    return String.Empty;
                }
            }
        }

        public String ContentTransferEncoding
        {
            get
            {

                if (this.Parameters.ContainsKey("ContentTransferEncoding"))
                {
                    return this.Parameters["ContentTransferEncoding"].ToString();
                }
                else
                {
                    return String.Empty;
                }
            }
        }

        public String ContentID
        {
            get
            {

                if (this.Parameters.ContainsKey("ContentID"))
                {
                    return this.Parameters["ContentID"].ToString();
                }
                else
                {
                    return String.Empty;
                }
            }
        }

        public String Name
        {
            get;
            private set;
        }

        public String ContentType
        {
            get
            {

                if (this.Parameters.ContainsKey("ContentType"))
                {
                    return this.Parameters["ContentType"].ToString();
                }
                else
                {
                    return String.Empty;
                }
            }
        }

        public String FileName { get; private set; }

        public Byte[] FileContents { get; private set; }
    }
    public class MultiPartFormDataFixHandler : DelegatingHandler
    {
        protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
        {
            MultiPartFix.FixRequest(request);
            return base.SendAsync(request, cancellationToken);
        }
    }
    public class MultiPartFormDataFixFilter : ActionFilterAttribute
    {
        public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            MultiPartFix.FixRequest(actionContext.Request);
        }
    }

    public static class MultiPartFix
    {
        private static String PreviousBoundary;

        private static string boundary = Environment.TickCount.ToString("X");
        public static String GetNewBoundary()
        {
            PreviousBoundary = boundary;
            while (PreviousBoundary == boundary)
            {
                boundary = Environment.TickCount.ToString("X");
            }
            PreviousBoundary = boundary;
            return boundary;
        }

        public static void FixRequest(HttpRequestMessage request)
        {
            //check if ContentType is null(which it most likely will if the request has an extra space character somewhere...
//feel free to ommit (request.Content.Headers.ContentType != null && request.Content.Headers.ContentType.MediaType == "multipart/form-data") if your users are always sending valid requests
            if (request.Content.Headers.ContentType == null || (request.Content.Headers.ContentType != null && request.Content.Headers.ContentType.MediaType == "multipart/form-data"))
            {
                Task<Stream> streamAsyncTask = request.Content.ReadAsStreamAsync();
                streamAsyncTask.Wait();
                if (streamAsyncTask.IsCanceled)
                {
                    throw streamAsyncTask.Exception.GetBaseException();
                }
                else if (streamAsyncTask.IsFaulted)
                {
                    throw streamAsyncTask.Exception.GetBaseException();
                }
                else
                {

                    List<MultiPartInfo> Parts = new List<MultiPartInfo>();
                    Dictionary<String, String> Parameters = new Dictionary<String, String>();
                    Stream stream = streamAsyncTask.Result;
                    //ReadFully is just an extension method to convert a stream to a byte array.
                    byte[] data = stream.ReadFully();
                    //we'll default to UTF8Encoding
                    Encoding encoding = new System.Text.UTF8Encoding();
                    //check if headers contain the encoding type parameter
                    String ContentEncoding = request.Content.Headers.ContentEncoding.FirstOrDefault();
                    if (request.Content.Headers != null && !String.IsNullOrEmpty(ContentEncoding))
                    {
                        encoding = Encoding.GetEncoding(ContentEncoding);
                    }

                    String content = encoding.GetString(data);

                    //Fix invalid boundaries(Mobitel seems to do this)
                    System.Text.RegularExpressions.Regex regreplace = new System.Text.RegularExpressions.Regex("(\n)(?<boundary>([-]{1,}[=].*(?=(--)))|([-]{1,}[=].*(?=(\r))))");

                    foreach (System.Text.RegularExpressions.Match item in regreplace.Matches(content))
                    {
                        content = content.Replace(item.Groups["boundary"].Value, String.Format("--{0}", MultiPartFix.GetNewBoundary()));
                    }

                    System.Text.RegularExpressions.Regex regmainboundary = new System.Text.RegularExpressions.Regex("(\n)(--)(?<boundary>(.*(?=(\r\n))))");
                    var result = regmainboundary.Match(content);
                    if (result.Success)
                    {
                        //find the start of the multipart/form-data ignoring ANY \r\n characters before the first --boundary sign
                        //this is also where i'm getting an extra space part from Mobitel
                        String boundary = String.Format("--{0}", result.Groups["boundary"].Value);
                        content = content.Substring(content.IndexOf(boundary));

                            string[] sections = content.Split(new string[] { boundary }, StringSplitOptions.RemoveEmptyEntries);

                        //remove the -- for future use
                            boundary = boundary.Substring(2);

                        //loop through parts and look for "Content-Disposition" part
                            foreach (string s in sections)
                            {

                                if (s.Contains("Content-Disposition"))
                                {
                                    String itemProperties = String.Empty;
                                    content = s;
                                    // If we find "Content-Disposition", this is a valid multi-part section
                                    //Find the Name
                                    Match nameMatch = new Regex(@"(?<=name\=\"")(.*?)(?=\"")").Match(s);
                                    String Name = nameMatch.Value.Trim().ToLower();

                                    //check if this section has it's own boundary(that would mean you probably have a multipart/mixed or other complex part inside the form
                                    Match boundaryMatch = new Regex(@"(?<=boundary\=)(?<boundary>.*?)(\r\n){2}").Match(s);


                                    //every part starts after 2 lines
                                    int fileStart = content.IndexOf("\r\n\r\n");
                                    itemProperties = content.Substring(0, fileStart + "\r\n\r\n".Length);
                                    content = content.Substring(fileStart);
                                    //by default itemProperties such as name,content-id and such are between the boundary and the first occurance of 2 lines

                                    //look for a filename part
                                    Match fileNameMatch = new Regex(@"(?<=filename\=\"")(.*?)(?=\"")").Match(s);
                                    Dictionary<String, String> tmpParameters = new Dictionary<String, String>();
                                    if (!boundaryMatch.Success && fileNameMatch.Success)
                                    {
                                        //we found a filename so we can look for aditional information(content-id etc)
                                        String FileName = fileNameMatch.Value.Trim();
                                        Regex re = new Regex(@"(\n)(?<name>.*)[:](\s)(?<value>.*)(\r)");
                                        MatchCollection itemPropMatches = re.Matches(itemProperties);
                                        foreach (Match item in itemPropMatches)
                                        {
                                            if (item.Groups["name"].Success && item.Groups["value"].Success)
                                            {
                                                tmpParameters.Add(item.Groups["name"].Value.ToString(), item.Groups["value"].Value.ToString());
                                            }
                                        }

                                        // Get the start & end indexes of the file contents
                                        int startIndex = content.IndexOf("\r\n\r\n") + "\r\n\r\n".Length;

                                        data = encoding.GetBytes(content);
                                        int endIndex = content.LastIndexOf("\r\n") - "\r\n".Length;

                                        int contentLength = endIndex - startIndex;

                                        // Extract the file contents from the byte array
                                        byte[] FileData = new byte[contentLength];

                                        Buffer.BlockCopy(data, startIndex, FileData, 0, contentLength);
                                        //copy file data info our multipartinfo holder
                                        Parts.Add(new MultiPartInfo(FileName, Name, FileData, tmpParameters));
                                    }
                                    else if (boundaryMatch.Success)
                                    {
                                        //if there was no filename and we have a boundary match...then this is probably another multipart/mixed part
                                        String subBoundary = subBoundary = boundaryMatch.Groups["boundary"].Value;
                                        String footer = String.Format("--{0}", subBoundary);
                                        //add --boundary to the start
                                         content = String.Format("--{0}{1}", boundary, s);
                                        //ignore everything beyond --boundary at the end(we will add the proper --\r\n ourselves 
                                         content = content.Substring(0, content.LastIndexOf(footer) + footer.Length);

                                        //add the proper ending
                                         content += "--\r\n";
                                        Regex re = new Regex(@"(\n)(?<name>.*)[:](\s)(?<value>.*)(\r)");
                                        MatchCollection itemPropMatches = re.Matches(itemProperties);
                                        //look for properties 
                                        foreach (Match item in itemPropMatches)
                                        {
                                            if (item.Groups["name"].Success && item.Groups["value"].Success)
                                            {
                                                tmpParameters.Add(item.Groups["name"].Value.ToString(), item.Groups["value"].Value.ToString());
                                            }
                                        };
                                        //copy data to a new bytearray
                                        data = encoding.GetBytes(content);

                                        byte[] FileData = new byte[data.Length];

                                        Buffer.BlockCopy(data, 0, FileData, 0, data.Length);

                                        Parts.Add(new MultiPartInfo(String.Empty, Name, FileData, tmpParameters));




                                    }
                                    else if (!String.IsNullOrEmpty(Name))
                                    {


                                        // Get the start & end indexes of the file contents
                                        int startIndex = nameMatch.Index + nameMatch.Length + "\r\n\r\n".Length;
                                        Parameters.Add(Name, s.Substring(startIndex).TrimEnd(new char[] { '\r', '\n' }).Trim());
                                    }
                                }
                           // }
                        }

                        if (Parts.Count > 0 || Parameters.Count > 0)
                        {
                            MemoryStream cms = new MemoryStream();

                            byte[] cdata = null;
                            string header = string.Format("--{0}", boundary);
                            string footer = string.Format("--{0}--", boundary);

                            StringBuilder contents = new StringBuilder();
                            if (Parameters.Count > 0)
                            {
                                int x = 0;
                                foreach (var item in Parameters)
                                {
                                    contents.Append(header);
                                    contents.Append("\r\n");
                                    contents.Append(String.Format("Content-Disposition: form-data; name=\"{0}\"", item.Key));
                                    contents.Append("\r\n");
                                    contents.Append("\r\n");
                                    contents.Append(item.Value);
                                    if (x < Parameters.Count - 1)
                                    {
                                        contents.Append("\r\n");
                                    }
                                    x += 1;
                                }
                                //Trace.WriteLine(sb.ToString());
                                cdata = encoding.GetBytes(contents.ToString());
                                cms.Write(cdata, 0, cdata.Length);
                            }
                            contents.Length = 0;
                            if (Parts.Count > 0)
                            {
                                if (Parameters.Count > 0)
                                {
                                    cdata = encoding.GetBytes("\r\n");
                                    cms.Write(cdata, 0, cdata.Length);
                                }
                                for (int x = 0; x < Parts.Count; x++)
                                {
                                    var item = Parts[x];
                                    contents = new StringBuilder();
                                    contents.Append(header);

                                    foreach (var param in item.Parameters)
                                    {
                                        contents.Append("\r\n");

                                        contents.Append(String.Format("{0}: {1}", param.Key, param.Value));
                                    }
                                    contents.Append("\r\n");

                                    contents.Append("\r\n");

                                    cdata = encoding.GetBytes(contents.ToString());
                                    cms.Write(cdata, 0, cdata.Length);

                                    cms.Write(item.FileContents, 0, item.FileContents.Length);
                                    contents.Length = 0;

                                    //if (x < Parts.Count - 1)
                                    //{
                                    contents.Append("\r\n");
                                    //}

                                    cdata = encoding.GetBytes(contents.ToString());
                                    cms.Write(cdata, 0, cdata.Length);
                                }
                            }
                            if (Parts.Count > 0)
                            {
                                cdata = encoding.GetBytes(String.Format("\r\n{0}\r\n", footer));
                            }
                            else
                            {
                                cdata = encoding.GetBytes(String.Format("\r\n{0}\r\n", footer));
                            }
                            cms.Write(cdata, 0, cdata.Length);
                            cms.Flush();
                            cms.Position = 0;
                            request.Content = new System.Net.Http.StreamContent(cms);
                            request.Content.Headers.ContentLength = cms.Length;
                            request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("multipart/form-data");
                            request.Content.Headers.ContentType.Parameters.Add(new System.Net.Http.Headers.NameValueHeaderValue("boundary", boundary));

                        }
                    }
                }
            }
        }

    }
}

Zgodovina sprememb…

  • spremenilo: Looooooka ()

darkolord ::

Ojej.


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Davčne blagajne (strani: 1 2 3 424 25 26 27 )

Oddelek: Programiranje
1344332293 (72296) Macketina
»

Pomoč pri kontakt formi

Oddelek: Izdelava spletišč
518495 (18393) Vzdevek
»

ASP.NET + C# vprašanje

Oddelek: Programiranje
342765 (1779) Morenov
»

[baze] Povezava do slike ali BLOB?

Oddelek: Programiranje
101658 (1455) BlueRunner
»

Kako z VS.NET priti do izvorne kode neke html strani?

Oddelek: Programiranje
91337 (1132) Microsoft

Več podobnih tem