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

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

Related

Use cpprest (Casablanca) to return PDF response

I am using cpprest in a server on Ubuntu Linux. So far I am able to process requests, and reply with JSON responses.
One of the requests that I accept needs to respond with a PDF file. I see that the http_request class has a reply() method that accepts an asynchronous stream. For the life of me, I can't figure out how to associate this stream with my PDF file on disk.
utility::string_t pdfFilename = getPdfFilename();
concurrency::streams::istream stream; // how do associate my pdfFilename?
request.reply(web::http::status_codes::OK, stream, "application/pdf");
I hope you already figured it out. Here's how I reply with local pdf files
void replyPdf(web::http::http_request message, string_t file_name)
{
concurrency::streams::fstream::open_istream(file_name, std::ios::in)
.then([=](concurrency::streams::istream is)
{
web::http::http_response response(web::http::status_codes::OK);
response.headers().add(L"Content-Disposition", U("inline; filename = \"") + file_name + U("\""));
response.set_body(std::move(is), U("application/pdf"));
message.reply(response).then([](pplx::task<void> t) {});
});
}

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

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);

JBoss EAP 5.1 Server not using Windows Network Setting

I'm trying to call a web service from my application. My system is protected with a Firewall and I'm using a Proxy to access any external URL/internet access. The application is running on JBoss EAP 5.1 server. The application fails to write to the service URL with IO Exception: 'Could not transmit message'.
However, when I'm trying to access the service URL with IE/Firefox, it's opening. Although the XML response I'm receiving from Browser states a generic error - 'invalid request parameters...', which is quite obvious. Because I'm not sending a proper request XML from Browser.
I'm really confused with this disparity. I used to believe that JBoss will pick up standard windows network settings, but in my case it is not.
My code is as follows:
String strUrl = "http://theurlgoeshere";
String requestXml = "<request></request>";
String wsResponse="";
SOAPConnection conn = null;
try {
MessageFactory msgFac = MessageFactory.newInstance();
MimeHeaders mh = new MimeHeaders();
mh.setHeader("Content-Type", "text/xml; charset=UTF-8");
log.info("Request Xml:" + requestXml );
InputStream is = new ByteArrayInputStream(requestXml.getBytes("UTF-8"));
SOAPMessage reqMsg = msgFac.createMessage(mh, is);
SOAPConnectionFactory conFac = SOAPConnectionFactory.newInstance();
conn = conFac.createConnection();
SOAPMessage repMsg = conn.call(reqMsg, strUrl);
ByteArrayOutputStream out = new ByteArrayOutputStream();
repMsg.writeTo(out);
wsResponse = new String(out.toByteArray());
}
catch (Exception e) {
e.printStackTrace();
}
Got it sorted few days back. Basically I am using HttpURLConnection now to add proxy setting in the java code itself while making the Webservice call. Just closing this question, since my query is solved.
Will update the new code, if anyone needs.

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