In another question here at Stack Overflow, I came across a very helpful code snippet to send code to the Google Closure Compiler, which can minify JavaScript files pretty good.
The problem I'm facing however is that it returns no compiled code in cases I don't expect it to do so.
Code:
This works, i.e. returns minified code:
Dim script = "function test(name) {alert(name);}test('New user');"
This one, on the other hand, does not return anything. The statistics are sent, but no compiled data...:
Dim script = "function test(name) {alert(name);}"
Rest of the code which actually does the work:
Dim Data = String.Format(ClosureWebServicePOSTData, HttpUtility.UrlEncode(script))
_Result = New StringBuilder
_HttpWebRequest = DirectCast(WebRequest.Create(ClosureWebServiceURL), HttpWebRequest)
_HttpWebRequest.Method = "POST"
_HttpWebRequest.ContentType = "application/x-www-form-urlencoded"
'//Set the content length to the length of the data. This might need to change if you're using characters that take more than 256 bytes
_HttpWebRequest.ContentLength = Data.Length
'//Write the request stream
Using SW As New StreamWriter(_HttpWebRequest.GetRequestStream())
SW.Write(Data)
End Using
Dim response As WebResponse = _HttpWebRequest.GetResponse()
Using responseStream As Stream = response.GetResponseStream
Dim encoding As Encoding = System.Text.Encoding.GetEncoding("utf-8")
Using readStream As New StreamReader(responseStream, encoding)
Dim read(256) As Char
Dim count As Integer = readStream.Read(read, 0, 256)
While count > 0
Dim str As New String(read, 0, count)
_Result.Append(str)
count = readStream.Read(read, 0, 256)
End While
End Using
End Using
What could be the casue at all? I'm curious to know.
Possibly using the ADVANCED_OPTIMIZATIONS setting? The function may have been stripped because it is defined, but never used.
check out this page: closure compiler tutorial
Related
Please see part of the code used to save response as a string to resultData variable:
Using response As WebResponse = request.GetResponse()
Dim responseStream As IO.Stream = response.GetResponseStream()
Dim sr As New IO.StreamReader(responseStream)
resultData = sr.ReadToEnd()
It works correctly.
I have one case where the output is a binary file. How can I modify this code to save the reponse as a binary ResultData variable?
Thank you in advance for your support.
There is many ways to do that. This one, is one of those. (This one help you also to show the progress)
However (as advice) to monitoring progress there exists better approaches like Async methods etc.
In the example below I’m going to show you how to save e WebRequest as binary data.
Note that, I’m based on your code and what you want, but, as I said before there exists different better approaches.
'here the file you want to save
Dim LocalFilePath As String = "C:\Users\MyUser\Documents\FolderXYZ\yourfileName.extension"
Using reader As IO.Stream = request.GetResponse.GetResponseStream
Using writer As IO.Stream = New IO.FileStream(LocalFilePath, IO.FileMode.OpenOrCreate, IO.FileAccess.ReadWrite)
Dim b(1024 * 2) As Byte
Dim buffer As Integer = b.Length
Do While buffer <> 0
buffer = reader.Read(b, 0, b.Length)
writer.Write(b, 0, buffer)
writer.Flush()
Loop
End Using
End Using
I have a JSON object created using Newtonsoft JObject but I get a bad request error when I try to submit it if any of the properties have spaces, slashes, etc.
updatestring = "date=2/14/2019"
Dim jobjattr As New Newtonsoft.Json.Linq.JObject(
New Newtonsoft.Json.Linq.JProperty("description", "test"),
New Newtonsoft.Json.Linq.JProperty("source", updatestring)
)
Dim jobjdat As New Newtonsoft.Json.Linq.JObject(
New Newtonsoft.Json.Linq.JProperty("type", "synch_log"),
New Newtonsoft.Json.Linq.JProperty("id", "6278042e-ed64-0418-a651-5c574dc4f12b"),
New Newtonsoft.Json.Linq.JProperty("attributes", jobjattr)
)
Dim jobj As New Newtonsoft.Json.Linq.JObject(New Newtonsoft.Json.Linq.JProperty("data", jobjdat))
Dim jsonserializersettings As New Newtonsoft.Json.JsonSerializerSettings
jsonserializersettings.StringEscapeHandling = Newtonsoft.Json.StringEscapeHandling.EscapeNonAscii
Dim stringReq = Newtonsoft.Json.JsonConvert.SerializeObject(jobj, jsonserializersettings)
Dim byteData As Byte() = System.Text.Encoding.UTF8.GetBytes(stringReq)
httprequest.ContentLength = byteData.Length
Dim postreqstream As System.IO.Stream = .GetRequestStream()
postreqstream.Write(byteData, 0, byteData.Length)
postreqstream.Close()
incoming jobj = {"data":{"type":"synch_log","id":"6278042e-ed64-0418-a651-5c574dc4f12b","attributes":{"description":"test","source":"date=2/14/2019"}}}
after serialzation byteData still = {"data":{"type":"synch_log","id":"6278042e-ed64-0418-a651-5c574dc4f12b","attributes":{"description":"test","source":"date=2/14/2019"}}}
I would expect the / to be escaped.
any text string works fine
I have also tried jsonserializer settings as Default and EscapeHtml but with the same result.
Other characters cause the same eror. "datetoday" posts correctly but "date=today" and "date today" result in a 400 bad request error
The closest answer I have found is that maybe the object is being double escaped but I can't see how that would be.
Thank you everyone. Brian, you led me in the right direction. I failed to mention that it is an API call to SuiteCRM but your question got me thinking to look on the server side and it turns out there is an unresolved bug with the V8 API. I just assumed it was my code.
github bug report
I'm trying to familiarize myself with network programming, and what better place to start than designing an FTP client code library?
So far I'm not doing very good. I'm trying to create a method which downloads a file from a remote server to a local file path. To do so, all the examples that I could find declare a byte array that serves as a data buffer. I completely understand the point of doing that, rather than reading and writing byte per byte, but I just can't get it to work. Whenever I set a buffer greater than 1 byte, the output is somehow corrupted (different checksums, media files won't play etc).
Can someone please point out what I'm doing wrong here:
Public Function DownloadFile(source As Uri, output As Uri) As FtpStatusCode
Dim request = FtpWebRequest.Create(source)
request.Method = WebRequestMethods.Ftp.DownloadFile
Using response As FtpWebResponse = CType(request.GetResponse, FtpWebResponse)
Using outputStream = New FileStream(output.AbsolutePath, FileMode.Create)
Do
Dim buffer(8192) As Byte
response.GetResponseStream.Read(buffer, 0, buffer.Length)
outputStream.Write(buffer, 0, buffer.Length)
Loop While outputStream.Position < response.ContentLength
End Using
Return response.StatusCode
End Using
End Function
Because this code does work when I set the buffer size to 1, I feel like there's something going wrong with the byte order. But all of this code is synchronous, so how is that even possible...
EDIT
I got it to work now, so here's the code solution for future reference (thanks again #tcarvin):
Public Function DownloadFile(source As Uri, output As Uri) As FtpStatusCode
Dim request = FtpWebRequest.Create(source)
request.Method = WebRequestMethods.Ftp.DownloadFile
Using response As FtpWebResponse = CType(request.GetResponse, FtpWebResponse)
Using inputStream = response.GetResponseStream
Using outputStream = New FileStream(output.AbsolutePath, FileMode.Create)
Do
Dim buffer(8192) As Byte
Dim buffered = inputStream.Read(buffer, 0, buffer.Length).Read(buffer, 0, buffer.Length)
outputStream.Write(buffer, 0, buffered)
Loop While outputStream.Position < response.ContentLength
End Using
End Using
Return response.StatusCode
End Using
End Function
When reading from a stream, you need to capture the return value of the method. Read returns how many bytes were just read. That is the number of bytes you need to then write to your output stream.
I'm trying to set the user agent for a request with XmlRead. I googled a lot about this and couldn't find the answer. Here is my chunk of code:
Dim RssData As DataSet
Dim Title As String
Dim Url As String
Dim Stream As String
Dim buffer As Integer
RssData = New DataSet()
RssData.ReadXml("http://localhost/user_agent.php")
buffer = 0
For Each RssRow As DataRow In RssData.Tables("entry").Rows
Title = Microsoft.VisualBasic.Left(RssRow.Item("title").ToString, 30)
Stream += Title & vbCrLf
Next
LinkLabel3.Text = Stream
For Each RssRow As DataRow In RssData.Tables("entry").Rows
Title = Microsoft.VisualBasic.Left(RssRow.Item("title").ToString, 30)
Url = RssRow.Item("url").ToString
LinkLabel3.Links.Add(buffer, Title.Length, Url)
buffer = buffer + Title.Length + 2
Next
The part of the code that actually performs the web request is buried pretty deep so you'd have to inherit a bunch of code to do what you asked for. Instead, let me suggest a different path, download the XML on your own with code that's easy to set that header, and then load that into the dataset. The WebClient class lets you set arbitrary headers and has a simple DownloadString method. Once you've got that you can wrap it in a MemoryStream and pass that into ReadXml(). (I couldn't find a way to read the XML as a string, that's why I was forced to read it as Stream.)
''//Will hold our downloaded XML
Dim MyXml As String
''//Create a webclient to download our XML
Using WC As New System.Net.WebClient()
''//Manually set the user agent header
WC.Headers.Add("user-agent", "your user agent here")
''//Download the XML
MyXml = WC.DownloadString("http://localhost/user_agent.php")
End Using
''//Create our dataset object
Dim RssData As New DataSet()
''//There is no direct method to load XML as a string (at least that I could find) so we will
''// convert it to a byte array and load it into a memory stream
Dim Bytes As Byte() = System.Text.Encoding.UTF8.GetBytes(MyXml)
Using MS As New System.IO.MemoryStream(Bytes)
''//Load the stream into the reader
RssData.ReadXml(MS)
End Using
''//Your code continues normally here
I am trying to Serialize an object to XML however my object is a generic list containing many records and causes the serializer to consume lots of memory. So I tried to serialize directly to a GZipStream with the following code:
Dim formatter As XmlSerializer = XmlSerializerFactory.GetSerializerForType(_type)
Using _ms As New MemoryStream()
Using gzStream As New GZipStream(_ms, CompressionMode.Compress, True)
_ms.Position = 0
formatter.Serialize(gzStream, obj)
_ms.Position = 0
gzStream.Flush()
gzStream.Close()
End Using
_ms.Position = 0
Dim decompressData() As Byte
Using gzStream As New GZipStream(_ms, CompressionMode.Decompress)
ReDim decompressData(9000 - 1) 'this number doesn't matter, the data in my test sample is small
Dim Len As Integer = gzStream.Read(decompressData, 0, decompressData.Length)
End Using
End Using
However I run into an InvalidDataException The magic number in GZip header is not correct. Make sure you are passing in a GZip stream. when trying to read the data into the decompressData array.
When I Serialize to a separate memory stream first and then compress that stream such as:
Dim formatter As XmlSerializer = XmlSerializerFactory.GetSerializerForType(_type)
Using _ms As New MemoryStream()
Dim uc_fileBytes() As Byte
Dim uc_len As Integer
Using _ms101 As New MemoryStream()
formatter.Serialize(_ms101, obj)
uc_fileBytes = _ms101.GetBuffer()
uc_len = _ms101.Length
End Using
Using gzStream As New GZipStream(_ms, CompressionMode.Compress, True)
_ms.Position = 0
gzStream.Write(uc_fileBytes, 0, uc_len)
gzStream.Flush()
gzStream.Close()
End Using
Dim decompressData() As Byte
Using gzStream As New GZipStream(_ms, CompressionMode.Decompress)
ReDim decompressData(9000 - 1)
Dim Len As Integer = gzStream.Read(decompressData, 0, decompressData.Length)
End Using
End Using
It works fine without error. But why does it fail when I serialize directly to the GZipStream?
The cause of the problem is because the GZipStream behaves differently (obviously) to the MemoryStream when writing to it. It doesn't handle paged writes very well.