Forum » Programiranje » 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.
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:
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 ()
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | Davčne blagajne (strani: 1 2 3 4 … 24 25 26 27 )Oddelek: Programiranje | 333582 (73585) | Macketina |
» | Pomoč pri kontakt formiOddelek: Izdelava spletišč | 18505 (18403) | Vzdevek |
» | ASP.NET + C# vprašanjeOddelek: Programiranje | 2796 (1810) | Morenov |
» | [baze] Povezava do slike ali BLOB?Oddelek: Programiranje | 1666 (1463) | BlueRunner |
» | Kako z VS.NET priti do izvorne kode neke html strani?Oddelek: Programiranje | 1350 (1145) | Microsoft |