Read until the server closes the connection - connection

I'm trying to read a JSON-encoded byte from a server, which will be indented, but of an unpredictable length, and no obvious termination byte. I would like to read the entire server response into a byte. The server will close the connection. Is it possible to do this using net?

As a supplement to #minikomi 's answer, I would like to add that, if you are sure that the bytes returned from the server are JSON encoded, there's a nice package encoding/json for this.
http://golang.org/pkg/encoding/json/
If you are using a decoder to decode directly from a connection, sometimes the error won't be returned. You might want to use fmt.Printf("%v\n", whateverDecodedFromTheConnection) to see what the decoder gets for your struct when the connection is closed.
For example, in my case, where the encoding/gob decoder is used to decode a message from a tcp connection into a struct defined as:
type MessageType struct {
Type uint8
}
When the connection is closed, decoder.Decode(&buffer) returns {0}. This might not be a common situation, but something needed to be watched out.

Please have a look at the docs at http://golang.org/pkg/net/http/
An http Get will return a Response struct, which will have a Body of type io.ReadCloser.
You can then use ioutil.ReadAll to read the entire response to a byte array.
resp, err := http.Get("http://example.com/")
if err != nil {
// handle error
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)

Related

Change Response Header Encode .Net Core

I need help changing the encoding of the response header on .Net Core 1.1.
We're developing an application and we created a custom header called "X-Application-Error" where any error that happens at the backend of the aplication returns a response code 500 and inside the header the message. This way I use the "app.UseExceptionHandler" to catch the errors, put it inside the header, and the front end, if it recieves and response code 500, displays the message sent at the header.
This is working as expected, the trouble that I'm having is that I need to send chacters like "é", "ã" and others, and the default encoding of the header is UTF-8, so it doesn't display those characters.
At the .net framework, we can use the "HttpResponse.HeaderEncoding" Property to change it (https://msdn.microsoft.com/en-us/library/system.web.httpresponse.headerencoding(v=vs.110).aspx)
but I can't find the equivalent for the .Net Core (1.1)
I found a similar question here (C# WebClient non-english request header value encoding) but no answer too.
Ok, I have found a work around (and yes, it seems obvious to me now).
From what I understood .Net Core won't allow characters like "á", "ã" inside a header if they are not encoded. So I just used "WebUtility.UrlEncode(string)" and sent the message encoded. At the FrontEnd, Angular decoded the message automatically. The code is like:
app.UseExceptionHandler(
builder =>
{
builder.Run(
async context =>
{
//Some validations I make
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
var error = context.Features.Get<IExceptionHandlerFeature>();
if (error != null)
{
try
{
context.Response.Headers.Add("Application-Error", WebUtility.UrlEncode(error.Error.Message));
}catch(Exception e)
{
context.Response.Headers.Add("Application-Error", e.Message);
}
//the rest of the code
}
});
});

Get original bytes from request

How I get original bytes from request? Calling request.body.asBytes() I get this message:
asBytes() expected list of bytes, instead got List<_InternalLinkedHashMap<String, dynamic>>
I saw that HTTPRequestBody has the property retainOriginalBytes to use in this case, but where I set it?
Thanks!
Whatever endpoint you're hitting with your request is returning a Map in its body, not a list of Bytes.
I'm not sure if you can control the contents of what that endpoint is returning but if you can that would be the place to change it.
Check out the BytesBuilder class. Also, read the Aqueduct docs for Request and Response Objects. Hopefully this gets you on the right path!
You're on the right track; this will work correctly once you've set retainOriginalBytes to true. This must be done before the body is decoded.
In an HTTPController, the request body is decoded before your method that handles the request is called. Just before the decoding, HTTPController calls its willDecodeRequestBody() method. This method does nothing by default, but you can override it to set retainOriginalBytes:
#override
void willDecodeRequestBody(HTTPRequestBody body) {
body.retainOriginalBytes = true;
}
Here is an example of an application that does this.

iOS url response bool

net web service that returns true or false but i don't know how to catch that response in my IOS App.
My service updates data in a database and i know it works the data gets updated it's catch the response that is the problem, i like to know so i can tell the user if something went wrong.
For those of you that know c# its a bool method, just simple try catch and return true or false.
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
//What to write here to catch my true or false
if(response) {
//true
} else {
//false
}
}
Thank you for your help
You should implementconnection:didReceiveData: to get and save NSData and – connectionDidFinishLoading: where you can interpret received data as BOOL.
basically didReceiveResponse: only get to you know about server response to your request not the entire answer.
You should check the response's HTTP status code, e.g.:
NSInteger statusCode = [(NSHTTPURLResponse*)response statusCode];
The status code for a successful request uses the range [200..299].
For example a successful GET request would be indicated with a 200 (OK).
A successful POST request will be indicated with a 201 (Created).
A successful DELET request will be indicated with a 204 (No Content)..
See also: wiki List of HTTP status codes.
Furthermore, you need to check the kind of data the server sent to you:
NSString* mimeType = [response MIMEType];
The mime type has been sent by the server in the Content-Type header of the response.
See also wiki MIME Internet Media Type
What you actually get fully depends on your request AND the server.
For example, the server may always answer with a JSON as content type. In this case, the header Content-Type of the response would be application/json. The actual JSON which represents the answer, will be related to the status code as well.
In order to provide a nice human readable message to the user, you need to consult the web service API and figure out how it is specified. Certain web service APIs may have a considerable large API. Unfortunately, some web services lack a comprehensive documentation.

Parse JSON string to detect error response

i'm working with a server which response using the JSON format.
when the request contain valid data they respond with a string like this
{"data":{"results":[{"Branch":"ACCT590006"}]}}
but if the parameters of the request are incorrect the response goes like this
{"error":{"errors":[{"domain":"global","reason":"invalid","message":"Invalid
Params"}],"code":98865,"message":"Invalid
param value"}}
So the questions are how i can determine when the response of the server contains a error string using the TJSONObject object and additionally parse the JSON string to show the messages and error codes like this.
Failed reason : invalid
Message : Invalid params
Code: 98865
message : invalid param value.
I've worked a little with JSON, an every time I've parsed from code(delphi 7). But i've searched a little bit, and here you may find the answer of your question:
http://edn.embarcadero.com/print/40882
and with a little adaption this should work.
Best regards,
Radu

Sending data in HTTP request's body fails

I am using the HttpConnection class of J2ME in my BlackBerry app to send data to a web server. I need to send the contents of an image in the body of the HTTP request.
This is what I do
Get the bytes of the file in an array
Open HTTP connection
Set content type header as image/jpeg
Get output stream of the connection
Write the bytes to the output stream
Close the output stream and connection
But the image is not uploaded to the server. What could be the problem?
Thanks.
EDIT - Adding code
HttpConnection conn = null;
OutputStream out = null;
try{
conn = new HttpConnection(Connector.open(myURL));
conn.setRequestProperty("Content-Type", "image/jpeg");
conn.setRequestMethod(HttpConnection.POST);
conn.setRequestProperty("Content-Disposition", "form-data");
conn.setRequestProperty("Connection", "Keep-Alive");
out = conn.openOutputStream;
out.write(buffer, 0, buffer.length);
conn.setRequestProperty("Content-Length", buffer.length);
out.flush();
}
catch(Exception e){
e.printStackTrace();
}
finally{
if(out != null)
out.close();
if(conn != null){
System.out.println("" + conn.getResponseCode());
conn.close();
}
}
EDIT
The same code, when I try it with a string, works fine and sends the string to the server. But it is still a problem with the image bytes.
A few things that may be missing from your list:
use HttpConnection.setRequestMethod(HttpConnection.POST) between 2 and 3.
set content length with HttpConnection.setRequestProperty("Content-Length",...) between 5 and 6.
knowing the HTTP request response code can help debug your issues: call HttpConnection.getResponseCode() after you've closed the OutputStream but before you close the HttpConnection.
conn = new HttpConnection(Connector.open(myURL));
This line is wrong. Connection is a factory class that creates new Connection objects by looking it's appropriate protocol implementation.
HttpConnection conn = (HttpConnection) Connector.open(myURL);
The rest of the code seems ok. When you're POSTing, at minimun you need to define the content-type and content-length.
You most definitely need to set all headers before sending the POST data, including the Content-Length header.
Also, make sure you are sending headers valid for requests, and not response-only headers.
You'll need to encode the bytes (preferably Base-64) and send that string. The raw bytes aren't likely to be http safe.
Then on the server, you'll need to decode them back into a byte array and do whatever you were going to do with it (save as file, stuff into database, etc.)

Resources