Displaying file: MessageBodyReader not found for media type=application/octet-stream - web-services

My requirement is that I should display a file using RESTFul services. Here how I proceeded:
Server:
#GET
#Path("/{name}")
#Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getFile {
...
return Response.ok(inputStream).header("Content-Disposition", "attachment; filename=" + fileName).build();
Client:
final WebTarget target = createRestClient("path/" + fileName, new HashMap<String, Object>());
return target.request(MediaType.APPLICATION_OCTET_STREAM).get().readEntity(Part.class);
When I run it, I've got this error:
MessageBodyReader not found for media type=application/octet-stream, type=interface javax.servlet.http.Part, genericType=interface javax.servlet.http.Part.
Do you have any idea where did this come from?
Thanks.

javax.servlet.http.Part should be used to obtain upload multipart data, and is created by the servlet container, which you obtain from a HttpServletRequest. It should not be used in this way. Beside the data is not even multipart.
Instead, you can simply get the InputStream from the from the Response and the Content-Dispostion get explicitly from the header. Something like
Response response = target.request()
.accept(MediaType.APPLICATION_OCTET_STREAM)
.get();
// get InputStream
InputStream is = response.readEntity(InputStream.class);
// get Content-Disposition header
String contentDisposition = (String)response
.getHeaderString(HttpHeaders.CONTENT_DISPOSITION);
// get filename
contentDisposition = contentDisposition
.substring(contentDisposition.indexOf("filename=") + "filename".length() + 1);
System.out.println(contentDisposition);

Related

Grapevine RestClient Json Body

I'm having difficulty putting together a request by sending a json content, can not find anything in the 4.x documentation it's completely different from version 3.x
RestClient client = new RestClient();
client.Host = "localhost";
client.Port = 8080;
RestRequest request = new Grapevine.Client.RestRequest("/route1");
request.HttpMethod = HttpMethod.POST;
RestResponse response = client.Execute(request) as RestResponse;
Somewhere in your code - prior to sending your request - you need to set the body (or payload) of your request.
request.Payload = "send this data";
The payload is just a string, so it's up to you to serialize your objects to a JSON string before making the assignment (and set the ContentType property appropriately). The Json.NET library is widely used to accomplish this. You can also do this by hand:
request.ContentType = ContentType.JSON;
request.Payload = "{\"key\":\"value\"}";

Why am I not recieving facebook graph entity_id value from http get request?

if I do a simple HTTP GET request with e.g. POSTMAN then in the response there's an element called 'entity_id'.
e.g. https://www.facebook.com/yourFacebookName
If however, I do the request from a simple C# app then the following code doesnt return the 'entity_id' element in the response and I cant figure out why?
Code from app:
string html = string.Empty;
string url = string.Format("https://www.facebook.com/{0}", "yourFBName");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.AutomaticDecompression = DecompressionMethods.GZip;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
html = reader.ReadToEnd();
}
if (html.Contains("entity_id"))
{
//do some stuff
}
Anyone know why its dropping the 'entity_id' element, but returning it when hitting that url from POSTMAN etc?

POCO : How to upload image to webser using poco in c++

I am trying to upload an image to remote web server. I have used HTMLForm and FilePartSource. I am able to successfully upload image to local sever (i.e. loclhost) but when i try to upload it in remote server, the response received from remote web server is "411 Length Required ".
I tried to set request.setContentLength(sizeofimagefile) but still same issue.
Can anyone guide me on what is the issue or .
Here is my code.
HTMLForm htmlform;
htmlform.set("aaaaaa", "bbbbbbb");
htmlform.set("cccccc", "ddddddd");
htmlform.setEncoding(HTMLForm::ENCODING_MULTIPART);
PartSource * pFileSrc = new FilePartSource("filename", "application/octet-stream");
std::istream& mystream = pFileSrc->stream();
mystream.seekg(0, std::ios::end);
int uiLength = mystream.tellg();
htmlform.addPart("file", pFileSrc);
URI uri("yyy");
HTTPClientSession session(uri.getHost(), uri.getPort());
HTTPRequest post_req(Poco::Net::HTTPRequest::HTTP_POST,"xxx",HTTPMessage::HTTP_1_1);
post_req.setKeepAlive(true);
htmlform.prepareSubmit(post_req);
std::ostream& oustr = session.sendRequest(post_req);
htmlform.write(oustr);
HTTPResponse res;
std::istream& rs = session.receiveResponse(res);
std::cerr << rs.rdbuf();
Thanks in advance
std::ostream& oustr = session.sendRequest(post_req);
htmlform.write(oustr);
Your code is not able to assign form data into the request object. So when you call session.sendRequest, an empty request is sent to the server. To do a proper conversion of HTMLForm to HTTPRequest, you must write like this -
htmlform.write(session.sendRequest(post_req));
The image upload code which is working for me is -
HTTPRequest request(HTTPRequest::HTTP_POST, "/fileupload/upload_file.php", HTTPMessage::HTTP_1_1);
HTMLForm form;
form.setEncoding(HTMLForm::ENCODING_MULTIPART);
form.set("entry1", "value1");
form.set("entry2", "value2");
form.addPart("file", new FilePartSource("/home/abc/Pictures/sample.png"));
form.prepareSubmit(request);
HTTPClientSession *httpSession = new HTTPClientSession("localhost");
httpSession->setTimeout(Poco::Timespan(20, 0));
form.write(httpSession->sendRequest(request));
Poco::Net::HTTPResponse res;
std::istream &is = httpSession->receiveResponse(res);
Poco::StreamCopier::copyStream(is, std::cout);
The corresponding upload server is using standard PHP code for uploading HTML form files.
If you can upload a file to your local server but can't with your remote server, first you should check if your remote Apache/PHP has an upload limit. Try a phpinfo() in your remote server.
http://www.cyberciti.biz/faq/linux-unix-apache-increase-php-upload-limit/
If not, you should revise your code...
From Poco documentation, at URL:
http://www.appinf.com/docs/poco/Poco.Net.HTMLForm.html
HTMLForm:
HTMLForm( const HTTPRequest & request, std::istream &
requestBody);
Creates a HTMLForm from the given HTTP request. Uploaded files are
silently discarded.
And with this constructor:
HTMLForm:
HTMLForm( const HTTPRequest & request, std::istream & requestBody, PartHandler & handler);
Creates a HTMLForm from the given HTTP request. Uploaded files are passed to the given PartHandler.
In your example, What constructor are you applying?
On the other hand,
addPart:
void addPart(
const std::string & name,
PartSource * pSource ); Adds an part/attachment (file upload) to the form. The form takes ownership of the PartSource and deletes it
when it is no longer needed. The part will only be sent if the
encoding set for the form is "multipart/form-data"
Try to use "multipart/form-data" with addPart and the second constructor for HTMLForm.
If it doesn't work, try to use a network sniffer like Wireshark to check what are you sendding.
Check if Content-Length header of your Request, have the sizeof(your image) + sizeof("aaaaaa" and "cccccc" params). Or try to send your form with GET method instead of POST.
Let me know if it works.
Regards

Unable to send post request via cpp-netlib

I am using cpp-netlib-0.9.4 with Visual Studio 2010. I have a function make_header which is like this:
http::client::request* Interface::make_request_header(const string& uri) {
string url = host_ + uri;
string json_type = "application/json";
http::client::request* req = new http::client::request(url);
req->add_header(make_pair("X-AUTH-TOKEN", token_));
req->add_header(make_pair("Content-Type", json_type));
req->add_header(make_pair("Accepts", json_type));
return req;
}
A get request works perfectly fine, which is something like:
http::client client;
http::client::request* req = make_request_header(my_uri);
http::client::response res = client.get(*req);
But a POST request throws an exception/core-dump. I have checked it multiple times otherwise and it seems to work every time on chrome dev http client extension. The URL I use for post request is:
http://myhost.com/commands?query=my query
In the above example, I try
http::client client;
http::client::request* req = make_request_header("http://myhost.com/commands?query=my query");
http::client::response res = client.post(*req); // FAILS AT THIS STEP.
Any ideas why?
A query parameter can not contain spaces, you have to URL-encode it.
Space is %20 to your query should look like
http://myhost.com/commands?query=my%20query

Can System.Net.WebClient be used in a console app to stream what my HttpHandler can do with Httpcontext.Response.OutputStream.Write?

I'm trying to do something in a console app for a test (based on some code in an HttpHandler in a web app).
Given something like this below which works for my HttpHandler which has HttpContext passed to it:
context.Response.AppendHeader("Content-Length", docContent.Length.ToString());
context.Response.AppendHeader("content-disposition", "attachment; filename=\"" + fileName + "\"");
context.Response.ContentType = MIMEType.MimeType(fileType);
context.Response.OutputStream.Write(docContent, 0, docContent.Length);
context.Response.OutputStream.Flush();
I have part of it, I think and then I get stuck:
WebClient client = new WebClient ();
client.Headers.Add("Content-Length", docContent.Length.ToString());
client.Headers.Add("content-disposition", "attachment; filename=\"" + fileName + "\"");
string ContentType = MIMEType.MimeType(fileType);
// ??
// how to build the response as an output stream from my byte array which has the data ?
MemoryStream(byte[]) can create a Stream from a byte[].
But a problem is WebClient is designed to issue HTTP requests only. If your goal is to test the server by downloading an attachment, then you'll need different headers.
If indeed you're trying to download a file, then try using WebClient.DownloadFile