when I use mongoose to process some http requests, it fails to get post data sometimes. Has anyone met the some problem? I am not sure whether the mongoose is stable enough. Can anyone give some ideas?
Thanks in advance.
I use the restClient to send the http request.
The mongoose library is downloaded from:http://code.google.com/p/mongoose/
The problem I encountered is
Uploading the file size exceeds 120MB, the will be a memory warning, and then the program crashes.After a preliminary test, to find the code of memory level 2 warnings:
MongooseServer.m
void *handleRequest(enum mg_event event,
struct mg_connection *conn,
const struct mg_request_info *request_info)
{
...
if ((cl = mg_get_header(conn, "Content-Length")) != NULL) {
len = atoi(cl);
if ((buf = malloc(len)) != NULL) {
mg_read(conn, buf, len);
body = [NSData dataWithBytes:buf length:len];
free(buf);
}
}
...
}
Specific problem is where I also did not identify, had determined after further debugging
Related
I am following Pixabay API documentation to retrieve/download images.
I don't have a lot of understanding of URI/REST/HTTP workings but I was able to follow some documentation and get boilerplate code:
int main()
{
auto fileStream = std::make_shared<ostream>();
//Open stream for output file
pplx::task<void> requestTask = fstream::open_ostream("results.html")
.then([=](ostream outFile) {
http_client client("https://pixabay.com/");
uri_builder builder("/api/");
builder.append_query("key", "xxxxxxx-xxxxxx-xxxxxxx");
builder.append_query("q", "yellow%20flowers");
builder.append_query("image_type", "photo");
std::cout << builder.to_string() << std::endl;
return client.request(methods::GET, builder.to_string()); })
// Handle the response headers arriving
.then([=](http_response response) {
printf("Received response status code: %u\n", response.status_code());
return response.body().read_to_end(fileStream->streambuf()); })
// Close the file stream.
.then([=](size_t) {
return fileStream->close(); });
// Wait for all the outstanding I/O to complete and handle any exceptions
try {
requestTask.wait();
}
catch (const std::exception &e) {
printf("Exception: %s\n", e.what());
}
return 0;
}
Problem : This code always gives me status code 301.
If I directly run https://pixabay.com/api/?key=xxxxxxx-xxxxxx-xxxxxxx&q=yellow+flowers&image_type=photo&pretty=true this link in the browser, I am getting the JSON data back. I am not sure if I am able to build this URI correctly through URI builder using the above code.
Some variation of the code that I tried involves commenting out query parameter q , removing/adding / from http_client/uri_builder but none of that worked.
Please help me understand what is the correct way of getting this done.
Thanks!
on adding an http_client_config the same code worked for me.
web::http::client::http_client_config httpConfig;
httpConfig.set_timeout(std::chrono::seconds(25));
httpConfig.set_validate_certificates(false);
and use this config while creating http_client
http_client client("https://pixabay.com/", httpConfig);
The C++ REST SDK has built-in support for automatically following 301 redirects when making HTTP requests. By default, the SDK will automatically follow up to 5 redirects.
I am looking for the best way to transfer files from the compact framework to a server via REST. I have a web service I created using .net Web API. I've looked at several SO questions and other sites that dealt with sending files, but none of them seem to work the for what I need.
I am trying to send media files from WM 6 and 6.5 devices to my REST service. While most of the files are less than 300k, an odd few may be 2-10 or so megabytes. Does anyone have some snippets I could use to make this work?
Thanks!
I think this is the minimum for sending a file:
using (var fileStream = File.Open(#"\file.txt", FileMode.Open, FileAccess.Read, FileShare.Read))
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://www.destination.com/path");
request.Method = "POST"; // or PUT, depending on what the server expects
request.ContentLength = fileStream.Length; // see the note below
using (var requestStream = request.GetRequestStream())
{
int bytes;
byte[] buffer = new byte[1024]; // any reasonable buffer size will do
while ((bytes = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
requestStream.Write(buffer, 0, bytes);
}
}
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
}
}
catch (WebException ex)
{
// failure
}
}
Note: HTTP needs a way to know when you're "done" sending data. There are three ways to achieve this:
Set request.ContentLength as used in the example, because we know the size of the file before sending anything
Set request.SendChunked, to send chunks of data including their individual size
You could also set request.AllowWriteStreamBuffering to write to an in-memory buffer, but I wouldn't recommend wasting that much memory on the compact framework.
I am implementing a server that sends xml to clients using boost. The problem I am facing is that the buffer doesn't get sent immediately and accumulates to a point then sends the whole thing. This cause a problem on my client side, when it parses the xml, it may have incomplete xml tag (incomplete message). Is there a way in boost to flush out the socket whenever it needs to send out a message? Below is server's write code.
void
ClientConnection::handle_write(const boost::system::error_code& error)
{
if (!error)
{
m_push_message_queue.pop_front ();
if (!m_push_message_queue.empty () && !m_disconnected)
{
boost::asio::async_write(m_socket,
boost::asio::buffer(m_push_message_queue.front().data(),
m_push_message_queue.front().length()),
boost::bind(&ClientConnection::handle_write, this,
boost::asio::placeholders::error));
}
}
else
{
std::err << "Error writting out message...\n";
m_disconnected = true;
m_server->DisconnectedClient (this);
}
}
Typically when creating applications using TCP byte streams the sender sends a fixed length header so the receiver knows how many bytes to expect. Then the receiver reads that many bytes and parses the resulting buffer into an XML object.
I assume you are using TCP connection. TCP is stream type, so you can't assume your packet will come in one big packet. You need to fix your communication design, by sending size length first like San Miller answer, or sending flag or delimiter after all xml data has been sent.
Assuming you are definitely going to have some data on the socket you want to clear, you could do something like this:
void fulsh_socket()
{
boost::asio::streambuf b;
boost::asio::streambuf::mutable_buffers_type bufs = b.prepare(BUFFER_SIZE);
std::size_t bytes = socket_.receive(bufs); // !!! This will block until some data becomes available
b.commit(bytes);
boost::asio::socket_base::bytes_readable command(true);
socket_.io_control(command);
while(command.get())
{
bufs = b.prepare(BUFFER_SIZE);
bytes = socket_.receive(bufs);
b.commit(bytes);
socket_.io_control(command); // reset for bytes pending
}
return;
}
where socket_ is a member variable.
HTH
I'm currently building an iPhone app based on Gsoap toolkit to connect to a webservice. Everything works fine except when I try to connect to my service after disconnecting and reconnecting 3g on the device, I get :
SOAP 1.1 fault: SOAP-ENV:Client [no subcode]
"Connection refused"
Detail: connect failed in tcp_connect()
Working through the debugger shows that the error comes from connect() method of socket.h.
I don't really understand, when I launch another app like safari, the device is connected to the Internet. And after loading a web page, my app's connection works fine.
Here is the code I'm using :
//GSoap initialization
struct soap soap;
soap_init(&soap);
soap.connect_timeout = 0;
soap.send_timeout = 0;
soap.recv_timeout = 0;
// objects request & response
// struct types can be foundin soapStub.h
struct _ns1__GetAuthentification requete;
struct _ns1__GetAuthentificationResponse reponse;
// init request
requete.ConnectPass = (char *) [connectPass UTF8String];
requete.Login = (char *) [login UTF8String];
requete.Password = (char *) [password UTF8String];
requete.soap = &soap;
// request callback. returns SOAP_OK if something has been returned
if(soap_call___ns1__GetAuthentification(&soap,NULL,NULL, &requete,&reponse) == SOAP_OK){
//then we build the result
NSLog(#"Yay!");
soap_end(&soap); // remove deserialized data and clean up
soap_done(&soap); // detach the gSOAP environment
return authResult;
}
else {
//NSLog(#"Soap Error : GetAuthentification");
// We try to see if there's any problem. #catch statements are here just to keep note of the concerned
// exceptions for each request. No utility for the code.
#try {
[self processFault:&soap];
}
#catch (MMWrongId * e) {
#throw e;
}
#catch (MMConnectionFailed * e) {
#throw e;
}
#catch (MMGetAuthentificationFault * e) {
#throw e;
}
return nil;
}
Am I missing any particular flag/option?
For those who encounter the same issue, I got a solution. Michael Lasmanis has been a huge help for this one. Here is his answer :
this is one of the reasons i no longer recommend gsoap for iphone new iphone developers. gsoap uses the lower bsd sockets and bypasses the higher level iphone apis. it is the higher level api that manage the state of the internet connectivity which is why if you start safari first, then everything works. the easiest workaround is to use nsurlconnection to open a http connect to a well know site before calling gsoap.
My program consists of 2 parts - A server socket (sits on port 3490) running on a different thread, and a client to test the server. Now the server has a pdf file, and I want the client to display it in a UIWebView. To achieve this I used the folllowing:
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://127.0.0.1:3490/"]];
[webView loadRequest:urlRequest];
The problem is that when a server posts its request I get in the console:
unable to open '': No such file or directory
In the server the most important part of the code is:
int fileDesc = open(viewController.filePath, O_RDONLY);
if (fileDesc == -1) {
fprintf(stderr, "unable to open '%s': %s\n", viewController.filePath, strerror(errno));
exit(1);
}
off_t offset = 0;
off_t len = 0;
struct sf_hdtr headers;
headers.headers = NULL;
headers.trailers = NULL;
if (sendfile (fileDesc, new_fd, offset, &len, &headers, 0) == -1){
perror("send");
}
Basically what I'm trying to do is to send the file via the socket to the client. Probably something is wrong here.
The rest of the server is pretty long so I'll just provide the link to it (It's modified - instead of send I use sendFile). http://beej.us/guide/bgnet/output/html/multipage/clientserver.html#simpleserver
Please help
Thanks
Alex
EDIT: Nevermind. I solved the issue. it seems that [viewController.filePath UTF8String] is needed in open(viewController.filePath, O_RDONLY);
Nevermind. I solved the issue. it seems that [viewController.filePath UTF8String] is needed in open(viewController.filePath, O_RDONLY);