Which ContentEncoding to be used for WOFF and TTF with HttpListener response? - truetype

Chrome and Firefox don't render Font-Awesome's WOFF/TTF, even if they download them from HttpListener, that said, Safari on iOS is rendering Font-Awesome correctly.
I am sending HTTP response using .NET's HttpListener class as follows:
private void Send(HttpListenerContext context, byte[] response, string contentType)
{
context.Response.StatusCode = (int)HttpStatusCode.OK;
context.Response.ContentEncoding = Encoding.UTF8;
context.Response.ContentType = contentType;
context.Response.ContentLength64 = response.Length;
context.Response.AddHeader("Server", SERVER);
if (response == null || response.Length == 0)
{
logger.Error("Send: Engine generated null or empty content");
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
return;
}
using (var s = context.Response.OutputStream)
{
s.Write(response, 0, response.Length);
}
}
Is there another encoding type (other than UTF8) for WOFF? or is there something that I have to take care of in Chrome or Firefox?
Any help or pointer appreciated, thanks.

In my own implementation, I leave out the ContentEncoding header all together when serving a font or binary.
This should work:
context.Response.ContentLength64 = response.Length;
context.Response.ContentType = "application/x-font-woff";
context.Response.OutputStream.Write(response, 0, response.Length);
context.Response.OutputStream.Close();

The problem was I had all the www content as Embedded Resource, and I created a method to convert those Embedded Resource Stream to a byte array by first converting that to a string using UTF-8 encoding.
So this stackoverflow question helped me to pinpoint the root cause. Once I converted the Embedded Resource Stream directly to a byte array, Chrome started showing Font-Awesome fonts correctly!

Related

Return binary string as plain text in browser window (and not as a downloadable file)

I want to return the following protobuf serialised binary data to the browser (Chrome) and not as a downloadable file. I don't understand the mechanism that is prompting a download. It is not the mime type as I am using text/plain elsewhere.
Controller:
[HttpGet]
public async Task<ActionResult<string>> GenerateProtoFeed()
{
var feed = _gtfsrService.GenerateFeed();
using (var stream = new MemoryStream())
{
feed.WriteTo(stream);
stream.Position = 0;
using (var reader = new StreamReader(stream))
{
return Content(reader.ReadToEnd(), "text/plain");
}
}
}
What I really want is this (example) to be returned in the browser window:
2.0?????/?
-Mcycmmp9-o4C0qeoGdz*?
????/*0
rE6s0CN800STv61PAKtfHAL6wS0jjmZkSZwq1PAKtf8A08Z?
?
?#StationAlert Elevators at Commercial-Broadway and Brentwood Stations are temporarily out of service today. ^sdken
The browser handles responses from a server differently depending on how the user has configured it, and on the mime type of the response.
It looks like your browser's default behaviour for text/plain is to prompt a save action. If you set the mime type of your response to text/html, the browser should simply display it.
Note that this is of course technically incorrect in this case.

How is a PDF supposed to be encoded?

I'm trying to set up an API that generate PDF from web page (provided as URL). The API is gotenberg from thecodingmachine. I have it on Docker, it works just fine, I can't generate PDF through http request send with curl (for now I'm just trying to make it work, so I use the request provided as example in the documentation)
Now I am trying to make it work with my groovy/grails app. So I'm using the java tools to make the request.
Now here is my problem : the PDF file I get is blank (my app opend directly in my browser). It do has the right content, if I open it with the text editor, it's not empty, and it has almost the same content as the one I make using the curl request (which isn't blank).
I am 99% sure the problem come from the encoding. I tried changing the InputStreamReader encoding parameter, but it doesn't change anything. Here I put "X-MACROMAN" because that the encoding inside the pdf file that isn't blank, but it still doesn't change.
Here is my code :
static def execute(def apiURL)
{
def httpClient = HttpClients.createDefault()
// Request parameters and other properties.
def request = new HttpPost(apiURL)
MultipartEntityBuilder builder = MultipartEntityBuilder.create()
builder.addTextBody("remoteURL", 'https://google.com')
builder.addTextBody("marginTop", '0')
builder.addTextBody("marginBottom", '0')
builder.addTextBody("marginLeft", '0')
builder.addTextBody("marginRight", '0')
HttpEntity multipart = builder.build()
request.setEntity(multipart)
def response = httpClient.execute(request)
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent(), "X-MACROMAN"))
StringBuffer result = new StringBuffer()
String line = ""
Boolean a = Boolean.FALSE
while ((line = rd.readLine()) != null) {
if(!a){
a = Boolean.TRUE
}
else {
result.append("\n")
}
result.append(line)
}
return result
I am 99% sure the problem come from the encoding. I tried changing the InputStreamReader encoding parameter, but it doesn't change anything. Here I put "X-MACROMAN" because that the encoding inside the pdf file that isn't blank, but it still doesn't change.
Did I made myself clear ? And does those who understands has any ideas why my PDFs are blank ?

Prevent Caching .svg Images on Application Server

I have a JWS application that caches several different resource types. However, I do not want to cache .svg images. It seems that the framework does not honor the server side cache control HTTP headers that I have set.
I was wondering if there is some other way that I could load .svg images without caching. I am open to putting a solution in my loadSVGDocument() method, but my code is currently built around Apache Batik for loading .svg files. Is there a solution to pass an InputStream with a noCache flag within the Batik library similar to what DocumentBuilderFactory provides below?
URL url = new URL(fileLocation);
URLConnection connection = url.openConnection();
// Prevent JavaWebStart from returning cached copy.
connection.setUseCaches(false);
// Now fetch the content, e.g.
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(connection.getInputStream());
Here is my current loadSVGDocument() method that uses several Apache Batik fields:
public void loadSVGDocument(final String url)
{
System.out.println("THE SVG URL: " + url);
String oldURI = null;
if (svgDocument != null)
{
oldURI = svgDocument.getURL();
}
final ParsedURL newURI = new ParsedURL(oldURI, url);
String theUrl = newURI.toString();
fragmentIdentifier = newURI.getRef();
loader = new DocumentLoader(userAgent);
nextDocumentLoader = new SVGDocumentLoader(theUrl, loader);
nextDocumentLoader.setPriority(Thread.NORM_PRIORITY);
Iterator it = svgDocumentLoaderListeners.iterator();
while (it.hasNext())
{
nextDocumentLoader
.addSVGDocumentLoaderListener((SVGDocumentLoaderListener) it.next());
}
documentLoader = nextDocumentLoader;
nextDocumentLoader = null;
documentLoader.run();
}
For anyone interested, I found that I can call Batik's
DocumentLoader.loadDocument(URL url, InputStream is)
with the setUseCaches flag as false. Not only does this load the image, but it also removes it from the cache accordingly. Though not the best solution in the sense that it would be nice for JWS to honor my HTTP headers, this work-around is good enough.

REST Stream's OutgoingResponse.ContentType is ignored, always shows "application/xml" on receiving browser

I have a self-hosted WCF REST/webHttpBinding-endpoint-bound service. I have a few streams of different content types that it serves. The content itself is delivered correctly, but any OutgoingResponse.ContentType setting seems to be ignored and instead delivered as "application/xml" every time.
Browsers seems to get over it for javascript and html (depending on how it's to be consumed), but not for css files which are interpreted more strictly. CSS files are how I realized the problem but it's a problem for all Streams. Chromebug and IE developer tools both show "application/xml" regardless of what I put in the serving code for a content type. I've also tried setting the content type header as a Header in OutgoingResponse but that makes no difference and it probably just a long way of doing what OutgoingResponse.ContentType does already.
[OperationBehavior]
System.IO.Stream IContentChannel.Code_js()
{
WebOperationContext.Current.OutgoingResponse.ContentType = "text/javascript;charset=utf-8";
var ms = new System.IO.MemoryStream();
using (var sw = new System.IO.StreamWriter(ms, Encoding.UTF8, 512, true))
{
sw.Write(Resources.code_js);
sw.Flush();
}
ms.Position = 0;
return ms;
}
This behavior is added:
var whb = new WebHttpBehavior
{
DefaultBodyStyle = System.ServiceModel.Web.WebMessageBodyStyle.WrappedRequest,
DefaultOutgoingRequestFormat = System.ServiceModel.Web.WebMessageFormat.Json,
DefaultOutgoingResponseFormat = System.ServiceModel.Web.WebMessageFormat.Json,
HelpEnabled = false
};
I've tried setting AutomaticFormatSelectionEnabled = true and false just in case because it came up in google searches on this issue, but that has no effect on this.
I'm finding enough articles that show Stream and ContentType working together to confuse the heck out of me as to why this isn't working. I believe that the Stream is only intended to be the body of the response, not the entire envelope.
My .svclog doesn't show anything interesting/relevant that I recognize.
============
I can confirm in Fiddler2 that the headers are being delivered as shown in the browser.
...
Content-Type: application/xml; charset=utf-8
Server: Microsoft-HTTPAPI/2.0
...
Solved!
I had something like the following in a MessageInspector:
HttpResponseMessageProperty responseProperty = new HttpResponseMessageProperty();
responseProperty.Headers.Add("Access-Control-Allow-Origin", "*");
reply.Properties["httpResponse"] = responseProperty;
and this was overwriting the already-present HttpResponseMessageProperty in reply.Properties, including any contentType settings. Instead, I tryget the HttpResponseMessageProperty first and use the existing one if found.
I lucked out seeing that one.

WCF 4.0 REST Upload MS-Excel File

I am trying to upload MS-Excel file through WCF-REST Service.
I used the solution given in below post:-
RESTful WCF service image upload problem
My POST Method is declared as:
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/RFQ")]
[WebContentType("application/octet-stream")]
void UploadRFQDoc(Stream fileContents);
When I debug, stream content is fine till the call goes, and when I attach service to debug, Stream fileContents parameter becomes null , and service returns with [Bad Request]. I am not sending large file (it is just 50 KB). I am using HttpClient to call the Post.
Here are the client code(RestClient is HttpClient).
protected void Post(string uri, Stream stream, int length)
{
var content = HttpContent.Create(output => CopyToStream(stream, output, length), "application/octet-stream", length);
Uri relativeUri = new Uri(uri, UriKind.Relative);
var resp = RestClient.Post(relativeUri, content);
ProcessResponse(resp);
}
void CopyToStream(Stream input, Stream output, int length)
{
var buffer = new byte[length];
var read = input.Read(buffer, 0, Convert.ToInt32 (length));
output.Write(buffer, 0, read);
}
Any clue what else can go wrong.
Many Thanks.
[WebContentType("application/octet-stream")] attribute was unnecessary here. I commented it out, and all worked fine :).