You can subscribe to this list here.
2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(52) |
Jun
(30) |
Jul
(17) |
Aug
(9) |
Sep
(4) |
Oct
(7) |
Nov
(11) |
Dec
(19) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2008 |
Jan
|
Feb
(1) |
Mar
(37) |
Apr
(28) |
May
(15) |
Jun
(28) |
Jul
(7) |
Aug
(125) |
Sep
(116) |
Oct
(85) |
Nov
(14) |
Dec
(6) |
2009 |
Jan
(11) |
Feb
(4) |
Mar
(5) |
Apr
|
May
(9) |
Jun
(5) |
Jul
(4) |
Aug
(40) |
Sep
(1) |
Oct
(19) |
Nov
(43) |
Dec
(45) |
2010 |
Jan
(76) |
Feb
(95) |
Mar
(3) |
Apr
(23) |
May
(39) |
Jun
(54) |
Jul
(6) |
Aug
(13) |
Sep
(12) |
Oct
(59) |
Nov
(53) |
Dec
(43) |
2011 |
Jan
(43) |
Feb
(44) |
Mar
(25) |
Apr
(23) |
May
|
Jun
|
Jul
|
Aug
|
Sep
(5) |
Oct
(1) |
Nov
(2) |
Dec
|
2013 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(6) |
Oct
|
Nov
|
Dec
|
From: Kim G. <kim...@gm...> - 2011-02-01 20:10:07
|
Erik, Dean On Tue, Feb 1, 2011 at 20:24, Nelson, Erik - 2 <eri...@ba...> wrote: > >> For data that's already in memory I get the utility of being able to >> refer to the bytes directly. Unfortunately making the library >> deallocate memory that the user allocated is, quite bluntly, bad form >> and error prone. >> >> Makes sense? > > I'd say that passing ownership of an object to a library is neither bad form nor error prone. Sutter has a good writeup of > using auto_ptr effectively in 'Exceptional C++' that seems applicable. Transferring object ownership with auto_ptr is > safe, efficient, and idiomatic. I agree with this. Using auto_ptr to transfer ownership seems like a no-brainer. However, it doesn't really solve the transfer-data-without-copy problem, at least not entirely. What if I have a char buffer I got out of some C API, and I'd like to transfer that; char buffer[1024]; unsigned long bufsize = sizeof(buffer) / sizeof(*buffer); GetUserNameA(buffer, &bufsize); // Now what? I think in the cases where your data comes from somewhere out of your control and it's not packed in an auto_ptr, you'll be just as screwed as with the current std::string -- in order to get it transferable you would have to reallocate it into an auto_ptr, and that might even involve packing it into an auto_ptr< vector<T> >, which feels pretty raw. I don't have a good idea for how to solve the lifetime issues of the payload, but an auto_ptr probably won't help (much) here. Cheers, - Kim |
From: Nelson, E. - 2 <eri...@ba...> - 2011-02-01 19:25:07
|
> Dean Michael Berris wrote on Tuesday, February 01, 2011 1:20 PM > > Well, the problem with sending binary data as 7-bit clear over the > network has been documented extensively over the Internet. The spec > clearly states that you have to be transferring data safe to transfer > over 7-bit transfers encoding -- meaning that's technically ASCII > text. It is an accident that images are being sent in the clear as > binary data, and if you notice in history this is largely why people > (browser developers and server developers) had to agree that they > would just take whatever was sent over the wire in the body and just > have the MIME identifiers there. > Either way you're sending binary in these examples... the only issue was whether that binary should be copied into a std::string > The design of the library has actually nothing to do with whether I > think text should be the only way transmitted over HTTP. If you also > notice the type of the string is parametric to the tag type used. It > makes it *easy* to just use std::string. I could very well be > implementing a chained-block-data-structure for the underlying message > storage and manipulate those directly and expose ranges for the > accessor/wrappers (like how ACE does it) but that's too much work to > do at the moment -- patches to implement this would be most welcome. > ;) > > At any rate, the reason why it's technically better to send things via > HTTP using Base64 encoding is really just so that you're OK as far as > the spec goes. This avoids all the endianness issues you might > encounter on the other end (although Boost.Asio should be dealing with > that issue for us). It's also largely a matter of convenience -- it's > perfectly *fine* to put binary data in an std::string or an > std::vector. > > > Having an overload that makes std::string usage natural (like it is > now) is good thing. Forcing someone to copy memory regions into a > std::string is a bad thing. > > > > The reason the copy is forced is for simplicity of the implementation. > Again if you wanted to use a no-copy or single-copy interface, use the > asynchronous server implementation *today*. ;) > > >> > >> Yet another way is to put the burden of managing the memory of the > >> data to be written out by the server, by providing an optional > >> callback function when providing the content. So it would then be a > >> variant between a string and a tuple<void*, size_t, > >> function<void(void*)> >. All of these options makes the synchronous > >> handler's implementation needlessly complex. > > > > My original point was only about the inelegance of using std::string. > The point you're raising here is a different one, and all you're > saying is that the lifetime of the payload needs to be roughly the same > as the lifetime of the result object. That's not a terribly > complicated- problem, and there are lots of solutions to it. It seems > that one that's easy for the user is to just hand off ownership to the > response, something like > > > > See, the fact that I'm even using std::string is already something I > detest (read the thread about [string]proposal on the Boost ML ;) ) -- I've been reading the (extensive) [string] proposal on boost. :) > but at the moment it is the most sane and simple thing to do lacking a > proper efficient segmented data storage mechanism around (no > std::deque has its own issues, and ptr_list<array<T,N> > is too > "esoteric"). Forcing people to deal with std::vector<char> is just > unnecessary when std::string is much more familiar however ugly. I'm not proposing vector<char>- the foundation of my point is the library *should not* make the container choice for the user. There is no choice that works well for everyone. > > Of course nothing's stopping you or anyone to create a different tag > type that defines string<Tag>::type as std::vector<char> or anything > for that matter. ;) > > The idea is really, to make the hard thing simple to do -- imagine > having to implement your own HTTP server, and you might think whether > you're making a copy of the data one extra time is *not* that big of a > deal. Of course I'd like to improve the library, it's just that, well, > if only more people submitted pull requests and actually addressed it, > we might have a better library to use sooner than later. :P > > Erik wrote: >> >> auto_ptr<MyObject> obj(new MyObject); >> response << body(obj); >> > Uh oh, this is dangerous because the user can use the obj right after > the data is passed to the response. Nope- the auto_ptr will be cleared when the ownership transfers to the response, right? > Erik wrote: >> should be sufficient for POD types, and for non-POD types, maybe >> you'd need something like >> >> auto_ptr<vector<char> > obj(new vector<char>()); >> response << body(&(*obj)[0], obj->size(), obj); >> > > And this is just ugly. ;) A little... think of it from a user standpoint- how would you send an arbitrary object in the response body? Can you write anything cleaner or more intuitive than response << body(void*, length) ? The way you're describing makes you write response.content.resize(length); memcpy((void*)response.content.data(), &object, length); That looks less ugly? More intuitive? > Erik wrote: >>> The response can delete it whenever it's done with doing whatever it >> does. >> > > That's bad design. :D > That's what it happens in the current implementation... the only difference is that it is deleting a copy (that's in the body) instead of the original. The issue here is that the lifetime of the response object is longer than the lifetime of the handler function. The solution is going to be to have the response destroy the body memory, either in std::string form (like now) or in original-object form. Either way the response is taking ownership of the memory that it is sending down the wire. > > Unfortunately, that's not much better than saying: > > std::ifstream f(...); > response.content.reserve(file_size); > f.read(response.content.data(), file_size); > > Am I missing something? I think this example illustrates my point about the trickiness of the interface. There are two reasons this won't work. 1. response.content.data() returns const char*, right? You can't write into that. 2. After this is run, response.content.size() will always be zero, right? And nothing will be sent? You probably wrote these bugs because you're up too late. :) Still, they show the brittleness of using a string like this. > > For data that's already in memory I get the utility of being able to > refer to the bytes directly. Unfortunately making the library > deallocate memory that the user allocated is, quite bluntly, bad form > and error prone. > > Makes sense? > I'd say that passing ownership of an object to a library is neither bad form nor error prone. Sutter has a good writeup of using auto_ptr effectively in 'Exceptional C++' that seems applicable. Transferring object ownership with auto_ptr is safe, efficient, and idiomatic. Anyway, you're putting the sweat equity into cpp-netlib, and are closer to the project. My only original observation was 'The same question will come up again and again because it's a surprising interface'. It clearly can work as it is, but it is surprising. That's why he didn't figure it out by himself. Erik ---------------------------------------------------------------------- This message w/attachments (message) is intended solely for the use of the intended recipient(s) and may contain information that is privileged, confidential or proprietary. If you are not an intended recipient, please notify the sender, and then please delete and destroy all copies and attachments, and be advised that any review or dissemination of, or the taking of any action in reliance on, the information contained in or attached to this message is prohibited. Unless specifically indicated, this message is not an offer to sell or a solicitation of any investment products or other financial product or service, an official confirmation of any transaction, or an official statement of Sender. Subject to applicable law, Sender may intercept, monitor, review and retain e-communications (EC) traveling through its networks/systems and may produce any such EC to regulators, law enforcement, in litigation and as required by law. The laws of the country of each sender/recipient may impact the handling of EC, and EC may be archived, supervised and produced in countries other than the country in which you are located. This message cannot be guaranteed to be secure or free of errors or viruses. References to "Sender" are references to any subsidiary of Bank of America Corporation. Securities and Insurance Products: * Are Not FDIC Insured * Are Not Bank Guaranteed * May Lose Value * Are Not a Bank Deposit * Are Not a Condition to Any Banking Service or Activity * Are Not Insured by Any Federal Government Agency. Attachments that are part of this EC may have additional important disclosures and disclaimers, which you should read. This message is subject to terms available at the following link: http://www.bankofamerica.com/emaildisclaimer. By messaging with Sender you consent to the foregoing. |
From: Dean M. B. <mik...@gm...> - 2011-02-01 18:20:22
|
On Wed, Feb 2, 2011 at 1:04 AM, Nelson, Erik - 2 <eri...@ba...> wrote: >> From: Dean Michael Berris wrote on Tuesday, February 01, 2011 9:00 AM >>> This question will continue to come up. It's true that std::string >>> *can* hold binary data. It's just not *natural*. The std::string >>> interface is strongly influenced by null-terminated strings. Things >>> that the interface implies (like string.c_str() or string(char*) >>> constructor actually do what you'd think) are broken if you use >>> std::string with binary data. >> >> I know. ;) >> >> Except a lot of times though, the HTTP protocol largely deals with >> *text transfer*. Also it's not as simple as it sounds. See below. >> > > The fact that it's a common use case (I'd suggest that actually much more binary image data is transmitted than text) means that the library should easily accommodate text transfer. I think this goes back to an underlying assumption that you expressed some time ago- iirc, you believed that HTTP could *only* transmit text, and that binary data needed to be base64'd into text before transmission. That assumption may still be informing your design choices here, but the very suggestion of copying binary data into a string should (in my opinion) is a red flag that there's something wrong with the interface. > Well, the problem with sending binary data as 7-bit clear over the network has been documented extensively over the Internet. The spec clearly states that you have to be transferring data safe to transfer over 7-bit transfers encoding -- meaning that's technically ASCII text. It is an accident that images are being sent in the clear as binary data, and if you notice in history this is largely why people (browser developers and server developers) had to agree that they would just take whatever was sent over the wire in the body and just have the MIME identifiers there. The design of the library has actually nothing to do with whether I think text should be the only way transmitted over HTTP. If you also notice the type of the string is parametric to the tag type used. It makes it *easy* to just use std::string. I could very well be implementing a chained-block-data-structure for the underlying message storage and manipulate those directly and expose ranges for the accessor/wrappers (like how ACE does it) but that's too much work to do at the moment -- patches to implement this would be most welcome. ;) At any rate, the reason why it's technically better to send things via HTTP using Base64 encoding is really just so that you're OK as far as the spec goes. This avoids all the endianness issues you might encounter on the other end (although Boost.Asio should be dealing with that issue for us). It's also largely a matter of convenience -- it's perfectly *fine* to put binary data in an std::string or an std::vector. > Having an overload that makes std::string usage natural (like it is now) is good thing. Forcing someone to copy memory regions into a std::string is a bad thing. > The reason the copy is forced is for simplicity of the implementation. Again if you wanted to use a no-copy or single-copy interface, use the asynchronous server implementation *today*. ;) >> >> Yet another way is to put the burden of managing the memory of the >> data to be written out by the server, by providing an optional >> callback function when providing the content. So it would then be a >> variant between a string and a tuple<void*, size_t, >> function<void(void*)> >. All of these options makes the synchronous >> handler's implementation needlessly complex. > > My original point was only about the inelegance of using std::string. The point you're raising here is a different one, and all you're saying is that the lifetime of the payload needs to be roughly the same as the lifetime of the result object. That's not a terribly complicated- problem, and there are lots of solutions to it. It seems that one that's easy for the user is to just hand off ownership to the response, something like > See, the fact that I'm even using std::string is already something I detest (read the thread about [string]proposal on the Boost ML ;) ) -- but at the moment it is the most sane and simple thing to do lacking a proper efficient segmented data storage mechanism around (no std::deque has its own issues, and ptr_list<array<T,N> > is too "esoteric"). Forcing people to deal with std::vector<char> is just unnecessary when std::string is much more familiar however ugly. Of course nothing's stopping you or anyone to create a different tag type that defines string<Tag>::type as std::vector<char> or anything for that matter. ;) The idea is really, to make the hard thing simple to do -- imagine having to implement your own HTTP server, and you might think whether you're making a copy of the data one extra time is *not* that big of a deal. Of course I'd like to improve the library, it's just that, well, if only more people submitted pull requests and actually addressed it, we might have a better library to use sooner than later. :P > > auto_ptr<MyObject> obj(new MyObject); > response << body(obj); > Uh oh, this is dangerous because the user can use the obj right after the data is passed to the response. > should be sufficient for POD types, and for non-POD types, maybe you'd need something like > > auto_ptr<vector<char> > obj(new vector<char>()); > response << body(&(*obj)[0], obj->size(), obj); > And this is just ugly. ;) > The response can delete it whenever it's done with doing whatever it does. > That's bad design. :D > That seems to me to be pretty easy and intuitive for the user. > Unfortunately, that's not much better than saying: std::ifstream f(...); response.content.reserve(file_size); f.read(response.content.data(), file_size); Am I missing something? For data that's already in memory I get the utility of being able to refer to the bytes directly. Unfortunately making the library deallocate memory that the user allocated is, quite bluntly, bad form and error prone. Makes sense? BTW I should really be asleep right now, but I just couldn't wait until I'm awake post my side of the story as to why things are as they are for the synchronous server. For the asynchronous server, this is largely a non-issue. ;) -- Dean Michael Berris about.me/deanberris |
From: Nelson, E. - 2 <eri...@ba...> - 2011-02-01 17:04:24
|
> From: Dean Michael Berris wrote on Tuesday, February 01, 2011 9:00 AM >> On Tue, Feb 1, 2011 at 3:09 AM, Nelson, Erik - 2 wrote: >>> Dean Michael Berris wrote on Saturday, January 29, 2011 8:33 AM >>> The way I would do it is to somehow mmap the file, get the mmap'ed >>> pointer, and copy the data into response.content directly. Binary >>> data is held fine by std::string instances, you just have >>> to reserve the appropriate amount of memory when you're doing that. >> This question will continue to come up. It's true that std::string >> *can* hold binary data. It's just not *natural*. The std::string >> interface is strongly influenced by null-terminated strings. Things >> that the interface implies (like string.c_str() or string(char*) >> constructor actually do what you'd think) are broken if you use >> std::string with binary data. > > I know. ;) > > Except a lot of times though, the HTTP protocol largely deals with > *text transfer*. Also it's not as simple as it sounds. See below. > The fact that it's a common use case (I'd suggest that actually much more binary image data is transmitted than text) means that the library should easily accommodate text transfer. I think this goes back to an underlying assumption that you expressed some time ago- iirc, you believed that HTTP could *only* transmit text, and that binary data needed to be base64'd into text before transmission. That assumption may still be informing your design choices here, but the very suggestion of copying binary data into a string should (in my opinion) is a red flag that there's something wrong with the interface. Having an overload that makes std::string usage natural (like it is now) is good thing. Forcing someone to copy memory regions into a std::string is a bad thing. >> The more natural interface (used by asio as well) is a buffer object >> which is just a tuple of the form {void*, size_t}, which is easily >> constructed from a string, vector<char>, array, or just about any >> container that the user has for the data. The user should *not* be >> forced to make a copy of their data in a std::string just to satisfy >> the network library. > > And this interface is already available in 0.8.1, in the asynchronous > server type. Basically now (thanks to Oleg Malashenko) you can do > `write(boost::asio::const_buffers_1(ptr, size))` and it won't make a > copy. > > The problem we have here in the synchronous server example is that the > response object has to be created before we even pass it into the > handler's operator()(...) overload. It also means that the data will > have to be "accessible" until the internal write completion handler is > invoked by Boost.Asio *after the handler's operator() overload is > finished*. This means the data that you have to put in the response > object that is passed into the synchronous server implementation, > should out-live the scope of the handler's operator() overload. > > I see two possibilities moving forward here: > > 1. ) Break the interface of the server response type and require that > data to be placed into the response object's body should be a variant > of either a string or a boost::tuple<shared_ptr<void>, size_t> -- > which I'm not even positive will work as I expect because what's in > the shared_ptr<void> should be an object and not just an arbitrary > pointer. This is going to make the server template's connection > implementation a lot more tricky than it has to be. > > 2. ) Deprecate the synchronous server template in favor of the > asynchronous server template. This will remove the simplicity of the > approach provided for in the implementation. > > Yet another way is to put the burden of managing the memory of the > data to be written out by the server, by providing an optional > callback function when providing the content. So it would then be a > variant between a string and a tuple<void*, size_t, > function<void(void*)> >. All of these options makes the synchronous > handler's implementation needlessly complex. My original point was only about the inelegance of using std::string. The point you're raising here is a different one, and all you're saying is that the lifetime of the payload needs to be roughly the same as the lifetime of the result object. That's not a terribly complicated- problem, and there are lots of solutions to it. It seems that one that's easy for the user is to just hand off ownership to the response, something like auto_ptr<MyObject> obj(new MyObject); response << body(obj); should be sufficient for POD types, and for non-POD types, maybe you'd need something like auto_ptr<vector<char> > obj(new vector<char>()); response << body(&(*obj)[0], obj->size(), obj); The response can delete it whenever it's done with doing whatever it does. That seems to me to be pretty easy and intuitive for the user. Erik ---------------------------------------------------------------------- This message w/attachments (message) is intended solely for the use of the intended recipient(s) and may contain information that is privileged, confidential or proprietary. If you are not an intended recipient, please notify the sender, and then please delete and destroy all copies and attachments, and be advised that any review or dissemination of, or the taking of any action in reliance on, the information contained in or attached to this message is prohibited. Unless specifically indicated, this message is not an offer to sell or a solicitation of any investment products or other financial product or service, an official confirmation of any transaction, or an official statement of Sender. Subject to applicable law, Sender may intercept, monitor, review and retain e-communications (EC) traveling through its networks/systems and may produce any such EC to regulators, law enforcement, in litigation and as required by law. The laws of the country of each sender/recipient may impact the handling of EC, and EC may be archived, supervised and produced in countries other than the country in which you are located. This message cannot be guaranteed to be secure or free of errors or viruses. References to "Sender" are references to any subsidiary of Bank of America Corporation. Securities and Insurance Products: * Are Not FDIC Insured * Are Not Bank Guaranteed * May Lose Value * Are Not a Bank Deposit * Are Not a Condition to Any Banking Service or Activity * Are Not Insured by Any Federal Government Agency. Attachments that are part of this EC may have additional important disclosures and disclaimers, which you should read. This message is subject to terms available at the following link: http://www.bankofamerica.com/emaildisclaimer. By messaging with Sender you consent to the foregoing. |
From: Dean M. B. <mik...@gm...> - 2011-02-01 14:11:40
|
On Tue, Feb 1, 2011 at 3:49 AM, David Hite <dav...@gm...> wrote: > > On Mon, Jan 31, 2011 at 12:09 PM, Nelson, Erik - 2 > <eri...@ba...> wrote: > > Hey Erik, > Good point! I agree. vector<char> seems to be a good standard. Actually what would be better would a vector<uint8_t> so you don't miss the 8-bit goodness of the data but that's beside the point. ;) > In fact, it > looks like vector<char> is (or will be) the mandated underlying storage > container for std::string. > Yeah, unfortunately. But that's another discussion. :P > For info, here's what I have working. It seems the easy pitfall is using > assignment operator "=" with a char* buffer for a string assumes NULL > terminated string. The alternative is to use the string constructor with a > char* and size. > > Here's the code to load binary files (i.e. images) and serve with > synchronous server. > Thanks David! :) Would you mind contributing this as an example to the project? :D Have a good one and I hope to hear from you again soon! :) -- Dean Michael Berris about.me/deanberris |
From: Dean M. B. <mik...@gm...> - 2011-02-01 14:00:35
|
On Tue, Feb 1, 2011 at 3:09 AM, Nelson, Erik - 2 <eri...@ba...> wrote: >> Dean Michael Berris wrote on Saturday, January 29, 2011 8:33 AM >> On Sat, Jan 29, 2011 at 7:08 AM, David Hite <dav...@gm...> wrote: >>> However, now I have the problem that response.content is a string. >>> How do I >>> send binary data, such as an image file? >>> >> >> The way I would do it is to somehow mmap the file, get the mmap'ed >> pointer, and copy the data into response.content directly. Binary data >> is held fine by std::string instances, you just have to reserve the >> appropriate amount of memory when you're doing that. >> > > This question will continue to come up. It's true that std::string *can* hold binary data. It's just not *natural*. The std::string interface is strongly influenced by null-terminated strings. Things that the interface implies (like string.c_str() or string(char*) constructor actually do what you'd think) are broken if you use std::string with binary data. > I know. ;) Except a lot of times though, the HTTP protocol largely deals with *text transfer*. Also it's not as simple as it sounds. See below. > The more natural interface (used by asio as well) is a buffer object which is just a tuple of the form {void*, size_t}, which is easily constructed from a string, vector<char>, array, or just about any container that the user has for the data. The user should *not* be forced to make a copy of their data in a std::string just to satisfy the network library. > And this interface is already available in 0.8.1, in the asynchronous server type. Basically now (thanks to Oleg Malashenko) you can do `write(boost::asio::const_buffers_1(ptr, size))` and it won't make a copy. The problem we have here in the synchronous server example is that the response object has to be created before we even pass it into the handler's operator()(...) overload. It also means that the data will have to be "accessible" until the internal write completion handler is invoked by Boost.Asio *after the handler's operator() overload is finished*. This means the data that you have to put in the response object that is passed into the synchronous server implementation, should out-live the scope of the handler's operator() overload. I see two possibilities moving forward here: 1. ) Break the interface of the server response type and require that data to be placed into the response object's body should be a variant of either a string or a boost::tuple<shared_ptr<void>, size_t> -- which I'm not even positive will work as I expect because what's in the shared_ptr<void> should be an object and not just an arbitrary pointer. This is going to make the server template's connection implementation a lot more tricky than it has to be. 2. ) Deprecate the synchronous server template in favor of the asynchronous server template. This will remove the simplicity of the approach provided for in the implementation. Yet another way is to put the burden of managing the memory of the data to be written out by the server, by providing an optional callback function when providing the content. So it would then be a variant between a string and a tuple<void*, size_t, function<void(void*)> >. All of these options makes the synchronous handler's implementation needlessly complex. Of course, any ideas and/or patches would be most welcome especially if makes things simple. :) -- Dean Michael Berris about.me/deanberris |
From: David H. <dav...@gm...> - 2011-01-31 19:49:38
|
On Mon, Jan 31, 2011 at 12:09 PM, Nelson, Erik - 2 < eri...@ba...> wrote: > > Dean Michael Berris wrote on Saturday, January 29, 2011 8:33 AM > > On Sat, Jan 29, 2011 at 7:08 AM, David Hite <dav...@gm...> wrote: > >> However, now I have the problem that response.content is a string. > >> How do I > >> send binary data, such as an image file? > >> > > > > The way I would do it is to somehow mmap the file, get the mmap'ed > > pointer, and copy the data into response.content directly. Binary data > > is held fine by std::string instances, you just have to reserve the > > appropriate amount of memory when you're doing that. > > > > This question will continue to come up. It's true that std::string *can* > hold binary data. It's just not *natural*. The std::string interface is > strongly influenced by null-terminated strings. Things that the interface > implies (like string.c_str() or string(char*) constructor actually do what > you'd think) are broken if you use std::string with binary data. > > The more natural interface (used by asio as well) is a buffer object which > is just a tuple of the form {void*, size_t}, which is easily constructed > from a string, vector<char>, array, or just about any container that the > user has for the data. The user should *not* be forced to make a copy of > their data in a std::string just to satisfy the network library. > > Erik > > > _______________________________________________ > Cpp-netlib-devel mailing list > Cpp...@li... > https://lists.sourceforge.net/lists/listinfo/cpp-netlib-devel > Hey Erik, Good point! I agree. vector<char> seems to be a good standard. In fact, it looks like vector<char> is (or will be) the mandated underlying storage container for std::string. For info, here's what I have working. It seems the easy pitfall is using assignment operator "=" with a char* buffer for a string assumes NULL terminated string. The alternative is to use the string constructor with a char* and size. Here's the code to load binary files (i.e. images) and serve with synchronous server. namespace http = boost::network::http; namespace utils = boost::network::utils; namespace fs = boost::filesystem; void serveFile(const Server::request &request, Server::response &response){ // get destination request for image file Server::string_type dest = destination(request); // internal document root string doc_root_path = "/path/to/doc_root" // set boost::filesystem::path (using filesystem "/" operator for directory/path concatenation fs::path file(doc_root_path / dest); // optional... perform error detection on existence of file... ifstream infile(file.c_str()); int size = fs::file_size(file); char *buf = new char[size]; infile.read(buf, size); // copy binary file into string string bin_str(buf, read_count); // set response contents response.content = bin_str; // set status response.status = Server::response::ok; // optional... check for file extension and assign mime type accordingly... // string file_ext = file.extension().c_str(); // Generic mime type for image (binary) file types http::request_header<http::tags::http_server> content_type = {"Content-Type", "x-application/octet-stream"}; response.headers.push_back( content_type ); } -Dave- |
From: Nelson, E. - 2 <eri...@ba...> - 2011-01-31 19:09:31
|
> Dean Michael Berris wrote on Saturday, January 29, 2011 8:33 AM > On Sat, Jan 29, 2011 at 7:08 AM, David Hite <dav...@gm...> wrote: >> However, now I have the problem that response.content is a string. >> How do I >> send binary data, such as an image file? >> > > The way I would do it is to somehow mmap the file, get the mmap'ed > pointer, and copy the data into response.content directly. Binary data > is held fine by std::string instances, you just have to reserve the > appropriate amount of memory when you're doing that. > This question will continue to come up. It's true that std::string *can* hold binary data. It's just not *natural*. The std::string interface is strongly influenced by null-terminated strings. Things that the interface implies (like string.c_str() or string(char*) constructor actually do what you'd think) are broken if you use std::string with binary data. The more natural interface (used by asio as well) is a buffer object which is just a tuple of the form {void*, size_t}, which is easily constructed from a string, vector<char>, array, or just about any container that the user has for the data. The user should *not* be forced to make a copy of their data in a std::string just to satisfy the network library. Erik ---------------------------------------------------------------------- This message w/attachments (message) is intended solely for the use of the intended recipient(s) and may contain information that is privileged, confidential or proprietary. If you are not an intended recipient, please notify the sender, and then please delete and destroy all copies and attachments, and be advised that any review or dissemination of, or the taking of any action in reliance on, the information contained in or attached to this message is prohibited. Unless specifically indicated, this message is not an offer to sell or a solicitation of any investment products or other financial product or service, an official confirmation of any transaction, or an official statement of Sender. Subject to applicable law, Sender may intercept, monitor, review and retain e-communications (EC) traveling through its networks/systems and may produce any such EC to regulators, law enforcement, in litigation and as required by law. The laws of the country of each sender/recipient may impact the handling of EC, and EC may be archived, supervised and produced in countries other than the country in which you are located. This message cannot be guaranteed to be secure or free of errors or viruses. References to "Sender" are references to any subsidiary of Bank of America Corporation. Securities and Insurance Products: * Are Not FDIC Insured * Are Not Bank Guaranteed * May Lose Value * Are Not a Bank Deposit * Are Not a Condition to Any Banking Service or Activity * Are Not Insured by Any Federal Government Agency. Attachments that are part of this EC may have additional important disclosures and disclaimers, which you should read. This message is subject to terms available at the following link: http://www.bankofamerica.com/emaildisclaimer. By messaging with Sender you consent to the foregoing. |
From: Dean M. B. <mik...@gm...> - 2011-01-29 20:52:06
|
Hi Everyone, Just a quick note, there's an update to the 0.8 line which addresses issues that have been identified with the previous 0.8 release. It's recommended that people using the 0.8 release upgrade to 0.8.1. This release is still a header-only release, with some features back-ported from the 0.9-devel branch. You can get the 0.8.1 release at https://github.com/cpp-netlib/cpp-netlib/downloads Have a good day everyone and I hope this helps. PS. The 0.9 release should come out soon, final documentation updates are just getting done; the 0.9 line will be the version that shall be submitted for review, looking for interested review managers at this time. -- Dean Michael Berris about.me/deanberris |
From: Dean M. B. <mik...@gm...> - 2011-01-29 13:33:54
|
On Sat, Jan 29, 2011 at 7:08 AM, David Hite <dav...@gm...> wrote: > >> >> response << Server::response::body(buffer); >> This should just be: namespace http = boost::network::http; response << http::body(buffer); > > However, now I have the problem that response.content is a string. How do I > send binary data, such as an image file? > The way I would do it is to somehow mmap the file, get the mmap'ed pointer, and copy the data into response.content directly. Binary data is held fine by std::string instances, you just have to reserve the appropriate amount of memory when you're doing that. HTH -- Dean Michael Berris about.me/deanberris |
From: David H. <dav...@gm...> - 2011-01-28 23:08:37
|
On Fri, Jan 28, 2011 at 3:22 PM, David Hite <dav...@gm...> wrote: > > On Thu, Jan 27, 2011 at 9:45 PM, Dean Michael Berris < > mik...@gm...> wrote: > >> On Fri, Jan 28, 2011 at 9:35 AM, David Hite <dav...@gm...> wrote: >> > My question is that I have been using stock_reply for the response and >> am >> > wondering if there are other methods for sending messages. >> > >> > The line I have been using is: >> > "response = Server::response::stock_reply(ok, msg);" >> > In all the examples I see and also looking through the code all I can >> find >> > is the "stock_reply" method. >> >> If you look at the code in the libs/network/test/hello_world.cpp -- or >> there abouts I don't have the directory handy at the moment -- you >> should see something like this: >> >> response << header("Content-Type", "application/octet-stream") >> << header("Connection", "close"); >> >> What that actually means is you're pushing in HTTP headers into the >> response. It's the same if you intend to push in the body of the >> response as well: >> >> response << body("The quick brown fox jumps over the lazy dog."); >> >> You can find information about this in the documentation for the HTTP >> Response in the library: >> http://cpp-netlib.github.com/reference_http_response.html >> >> HTH >> >> >> -- >> Dean Michael Berris >> about.me/deanberris >> >> >> ------------------------------------------------------------------------------ >> Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)! >> Finally, a world-class log management solution at an even better >> price-free! >> Download using promo code Free_Logger_4_Dev2Dev. Offer expires >> February 28th, so secure your free ArcSight Logger TODAY! >> http://p.sf.net/sfu/arcsight-sfd2d >> _______________________________________________ >> Cpp-netlib-devel mailing list >> Cpp...@li... >> https://lists.sourceforge.net/lists/listinfo/cpp-netlib-devel >> > > Hi Dean, Thanks for the quick response. > > Sorry for the trouble but I'm getting a compile error. > > Error: 'body' is not a member of > 'boost::network::http::basic_response<boost::network::http::tags::http_server>' > > Here's the code: > > response << Server::response::body(buffer); > > using Server defined as > > typedef http::server<CgiResourceManager> Server; > > I'm using cpp-netlib v0.8 > > Any ideas? > Thanks, > -Dave- > Hello, Ok, so I figured out how to directly set the response message. For example: response.content = "Hello world!" response.status = Server::response::ok; http::request_header<http::tags::http_server> content_type = {"Content-Type", "text/html"}; response.headers.push_back( content_type ); However, now I have the problem that response.content is a string. How do I send binary data, such as an image file? Thanks! -Dave- |
From: David H. <dav...@gm...> - 2011-01-28 22:22:36
|
On Thu, Jan 27, 2011 at 9:45 PM, Dean Michael Berris <mik...@gm... > wrote: > On Fri, Jan 28, 2011 at 9:35 AM, David Hite <dav...@gm...> wrote: > > My question is that I have been using stock_reply for the response and am > > wondering if there are other methods for sending messages. > > > > The line I have been using is: > > "response = Server::response::stock_reply(ok, msg);" > > In all the examples I see and also looking through the code all I can > find > > is the "stock_reply" method. > > If you look at the code in the libs/network/test/hello_world.cpp -- or > there abouts I don't have the directory handy at the moment -- you > should see something like this: > > response << header("Content-Type", "application/octet-stream") > << header("Connection", "close"); > > What that actually means is you're pushing in HTTP headers into the > response. It's the same if you intend to push in the body of the > response as well: > > response << body("The quick brown fox jumps over the lazy dog."); > > You can find information about this in the documentation for the HTTP > Response in the library: > http://cpp-netlib.github.com/reference_http_response.html > > HTH > > > -- > Dean Michael Berris > about.me/deanberris > > > ------------------------------------------------------------------------------ > Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)! > Finally, a world-class log management solution at an even better > price-free! > Download using promo code Free_Logger_4_Dev2Dev. Offer expires > February 28th, so secure your free ArcSight Logger TODAY! > http://p.sf.net/sfu/arcsight-sfd2d > _______________________________________________ > Cpp-netlib-devel mailing list > Cpp...@li... > https://lists.sourceforge.net/lists/listinfo/cpp-netlib-devel > Hi Dean, Thanks for the quick response. Sorry for the trouble but I'm getting a compile error. Error: 'body' is not a member of 'boost::network::http::basic_response<boost::network::http::tags::http_server>' Here's the code: response << Server::response::body(buffer); using Server defined as typedef http::server<CgiResourceManager> Server; I'm using cpp-netlib v0.8 Any ideas? Thanks, -Dave- |
From: Dean M. B. <mik...@gm...> - 2011-01-28 04:46:26
|
On Fri, Jan 28, 2011 at 9:35 AM, David Hite <dav...@gm...> wrote: > My question is that I have been using stock_reply for the response and am > wondering if there are other methods for sending messages. > > The line I have been using is: > "response = Server::response::stock_reply(ok, msg);" > In all the examples I see and also looking through the code all I can find > is the "stock_reply" method. If you look at the code in the libs/network/test/hello_world.cpp -- or there abouts I don't have the directory handy at the moment -- you should see something like this: response << header("Content-Type", "application/octet-stream") << header("Connection", "close"); What that actually means is you're pushing in HTTP headers into the response. It's the same if you intend to push in the body of the response as well: response << body("The quick brown fox jumps over the lazy dog."); You can find information about this in the documentation for the HTTP Response in the library: http://cpp-netlib.github.com/reference_http_response.html HTH -- Dean Michael Berris about.me/deanberris |
From: David H. <dav...@gm...> - 2011-01-28 01:35:22
|
Hi everybody, I'm working with a HTTP Synchronous server and am experimenting with a file server and different mime types. My question is that I have been using stock_reply for the response and am wondering if there are other methods for sending messages. The line I have been using is: "response = Server::response::stock_reply(ok, msg);" In all the examples I see and also looking through the code all I can find is the "stock_reply" method. Any ideas? Thanks, -Dave- |
From: Dean M. B. <mik...@gm...> - 2011-01-21 16:42:09
|
On Fri, Jan 21, 2011 at 11:59 PM, Max Malmgren <ma...@kt...> wrote: > > I'm trying to use the cpp-netlib to forward live http streams, such as when broadcasting from a webcam or similar, so I am trying to use both the server and client components asynchronously. As far as I can see, this is working fine for the server. > > However, when it comes to the asynchronous client, I would like to do this: > [snip] > > Is it possible with the current API to simulate this behaviour? I saw an issue about implementing client streams, but I thought, it can't hurt to ask? > Unfortunately, it's not possible to do that at the moment. Supporting streaming from the client is something I fully intend to implement, when I do get the time to do it. At the moment I've been preoccupied with paid work to be able to devote enough time to this. > Thanks for your time. > I'm sorry it's not possible to do this yet, but I assure you it's up there in the list of things for me to fix. (Or maybe if others had the time to do it, maybe that might happen sooner :) ). -- Dean Michael Berris about.me/deanberris |
From: Max M. <ma...@kt...> - 2011-01-21 15:59:43
|
Hi everybody, Perhaps I've missed some vital information or link, but it seems to difficult to find any extensive documentation at all about the specific capabilities of the cpp-netlib, so I guess I'll go ahead and ask here and either you can help me directly, post a link to extensive documentation, or ignore. I've already viewed http://cpp-netlib.github.com/reference_http_response.html#response-concept and http://cpp-netlib.github.com/reference_http_client.html. I'm trying to use the cpp-netlib to forward live http streams, such as when broadcasting from a webcam or similar, so I am trying to use both the server and client components asynchronously. As far as I can see, this is working fine for the server. However, when it comes to the asynchronous client, I would like to do this: client::request clientRequest(reqUrl); client::response clientResponse; clientResponse = clnt.get(clientRequest); strtype result; while(!(result = clientResponse.body()).empty()) { std::cout << result << std::endl; connection->write(boost::make_iterator_range(result)); } Idiomatically this is pretty easy to understand, assuming that clientResponse.body() returns the bytes already read from the response, and that empty returns true when no more bytes can be read. This does not work (but I thought it was worth a try when I had no idea about the implementation ;) ) Is it possible with the current API to simulate this behaviour? I saw an issue about implementing client streams, but I thought, it can't hurt to ask? Thanks for your time. Best regards, Max Malmgren |
From: Oleg M. <ole...@gm...> - 2011-01-21 08:42:29
|
On 21.01.2011 18:17, Dean Michael Berris wrote: >> Seems that type_ != ipv4, though I have no idea why. It seems to be >> some win-specific implementation above in the stack-trace, which >> would explain why it works on Ubuntu. > > It looks like you're using IPv6 -- which IMO is a good thing, but > not so good for cpp-netlib. :D As a workaround try "0.0.0.0" or "127.0.0.1" instead of "localhost" in prox.startProxy(): it should force resolver to use ipv4 endpoints. -- Best regards, Oleg Malashenko. |
From: Dean M. B. <mik...@gm...> - 2011-01-21 08:17:31
|
On Fri, Jan 21, 2011 at 4:08 PM, Max Malmgren <ma...@kt...> wrote: > Hi! See below for my call stack information at the moment of error. I will try to investigate a little on my own, even though I am not very experienced at c++ or boost. > For convieniency, here is the method that seems to fail: > > boost::asio::ip::address_v4 address::to_v4() const > { > if (type_ != ipv4) > { > std::bad_cast ex; > boost::throw_exception(ex); > } > return ipv4_address_; > } > > Seems that type_ != ipv4, though I have no idea why. It seems to be some win-specific implementation above in the stack-trace, which would explain why it works on Ubuntu. > Sorry if I am wasting your time! > It looks like you're using IPv6 -- which IMO is a good thing, but not so good for cpp-netlib. :D This is a bug because I assumed that all servers will be using ipv4 addresses. Please file that as an issue in the issue tracker at http://github.com/cpp-netlib/cpp-netlib/issues -- have a good one and thanks for reporting the issue. :) (Also, next time, please don't top-post. :) ) -- Dean Michael Berris about.me/deanberris |
From: Max M. <ma...@kt...> - 2011-01-21 08:08:53
|
Hi! See below for my call stack information at the moment of error. I will try to investigate a little on my own, even though I am not very experienced at c++ or boost. For convieniency, here is the method that seems to fail: boost::asio::ip::address_v4 address::to_v4() const { if (type_ != ipv4) { std::bad_cast ex; boost::throw_exception(ex); } return ipv4_address_; } Seems that type_ != ipv4, though I have no idea why. It seems to be some win-specific implementation above in the stack-trace, which would explain why it works on Ubuntu. Sorry if I am wasting your time! Best regards, Max Malmgren KernelBase.dll!76bcb727() [Frames below may be incorrect and/or missing, no symbols loaded for KernelBase.dll] KernelBase.dll!76bcb727() msvcr100.dll!std::bad_cast::bad_cast(const std::bad_cast & that) Line 75 + 0x10 bytes C++ 81fd17b7() msvcr100.dll!_CxxThrowException(void * pExceptionObject, const _s__ThrowInfo * pThrowInfo) Line 157 C++ NativeCodeTest.exe!boost::throw_exception<std::bad_cast>(const std::bad_cast & e) Line 61 + 0x2e bytes C++ > NativeCodeTest.exe!boost::asio::ip::address::to_v4() Line 91 C++ NativeCodeTest.exe!boost::network::http::async_connection<boost::network::http::tags::http_async_server,proxy::ASyncProxy>::start() Line 313 + 0x5a bytes C++ NativeCodeTest.exe!boost::network::http::async_server_base<boost::network::http::tags::http_async_server,proxy::ASyncProxy>::handle_accept(const boost::system::error_code & ec) Line 71 C++ NativeCodeTest.exe!boost::asio::asio_handler_invoke<boost::asio::detail::binder1<boost::_bi::bind_t<void,boost::_mfi::mf1<void,boost::network::http::sync_server_base<boost::network::http::tags::http_server,proxy::SyncProxy>,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<boost::network::http::sync_server_base<boost::network::http::tags::http_server,proxy::SyncProxy> *>,boost::arg<1> > >,boost::system::error_code> >(boost::asio::detail::binder1<boost::_bi::bind_t<void,boost::_mfi::mf1<void,boost::network::http::sync_server_base<boost::network::http::tags::http_server,proxy::SyncProxy>,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<boost::network::http::sync_server_base<boost::network::http::tags::http_server,proxy::SyncProxy> *>,boost::arg<1> > >,boost::system::error_code> function, ...) Line 65 C++ NativeCodeTest.exe!boost::asio::detail::win_iocp_socket_accept_op<boost::asio::basic_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ip::tcp,boost::_bi::bind_t<void,boost::_mfi::mf1<void,boost::network::http::async_server_base<boost::network::http::tags::http_async_server,proxy::ASyncProxy>,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<boost::network::http::async_server_base<boost::network::http::tags::http_async_server,proxy::ASyncProxy> *>,boost::arg<1> > > >::do_complete(boost::asio::detail::win_iocp_io_service * owner, boost::asio::detail::win_iocp_operation * base, boost::system::error_code ec, unsigned int __formal) Line 136 + 0x2a bytes C++ NativeCodeTest.exe!boost::asio::detail::win_iocp_io_service::do_one(bool block, boost::system::error_code & ec) Line 386 + 0x10 bytes C++ NativeCodeTest.exe!boost::asio::detail::win_iocp_io_service::run(boost::system::error_code & ec) Line 160 + 0xb bytes C++ NativeCodeTest.exe!boost::asio::io_service::run() Line 58 C++ NativeCodeTest.exe!proxy::ASyncProxy::startProxy(std::basic_string<char,std::char_traits<char>,std::allocator<char> > url, std::basic_string<char,std::char_traits<char>,std::allocator<char> > port) Line 14 C++ NativeCodeTest.exe!StartASyncProxy(char * port, char * url) Line 64 C++ NativeCodeTest.exe!main() Line 76 + 0xf bytes C++ NativeCodeTest.exe!__tmainCRTStartup() Line 555 + 0x17 bytes C kernel32.dll!76363677() ntdll.dll!776b9d42() ntdll.dll!776b9d15() ________________________________________ From: Oleg Malashenko [ole...@gm...] Sent: Friday, January 21, 2011 2:39 AM To: C++ Networking Library Developers Mailing List Subject: Re: [cpp-netlib-devel] cpp-netlib async server request - bad cast exception thrown Hello, Max, On 21.01.2011 00:41, Max Malmgren wrote: > Originally I got a compile error, but once I included boost/or.hpp in > the boost/network/version.hpp file it compiled. However, it still > does not work on my windows distribution, while it does on my ubuntu > distribution. I still get a bad_cast exception thrown. Can you please run it under MSVS debugger and post a backtrace from the point where exception is thrown? It shouldn't be a problem. -- Best regards, Oleg Malashenko. |
From: Oleg M. <ole...@gm...> - 2011-01-21 01:40:16
|
Hello, Max, On 21.01.2011 00:41, Max Malmgren wrote: > Originally I got a compile error, but once I included boost/or.hpp in > the boost/network/version.hpp file it compiled. However, it still > does not work on my windows distribution, while it does on my ubuntu > distribution. I still get a bad_cast exception thrown. Can you please run it under MSVS debugger and post a backtrace from the point where exception is thrown? It shouldn't be a problem. -- Best regards, Oleg Malashenko. |
From: Oleg M. <ole...@gm...> - 2011-01-21 01:24:19
|
On 21.01.2011 06:41, Jeff Graham wrote: > Hello, > > I downloaded both version 0.8 and git source from today. > > The hello world server compiles and runs fine. The hello world client > does not compile due to the following error: > > hello_world_client.cpp:38: error: no match for ‘operator<<’ in > ‘std::cout << boost::network::body(const T&) [with T = > boost::network::http::basic_response<boost::network::http::tags::http_default_8bit_udp_resolve>]()’ > This line is: > > std::cout << boost::network::body(response) << std::endl; > It seems that body(response) resolves to body_directive instead of boost::network::impl::body_wrapper. And even if it resolved correctly we need to add explicit operator<<(ostream&, impl::body_wrapper const&) to make that code work. To be honest it seems quite overcomplicated to me. The working line: std::cout << boost::network::impl::body_wrapper_const<http::client::tag_type(response).operator std::string() << std::endl; -- Best regards, Oleg Malashenko. |
From: Jeff G. <Jef...@br...> - 2011-01-20 20:41:46
|
Hello, I downloaded both version 0.8 and git source from today. The hello world server compiles and runs fine. The hello world client does not compile due to the following error: hello_world_client.cpp:38: error: no match for 'operator<<' in 'std::cout << boost::network::body(const T&) [with T = boost::network::http::basic_response<boost::network::http::tags::http_de fault_8bit_udp_resolve>]()' This line is: std::cout << boost::network::body(response) << std::endl; Not such as big deal perhaps, but my first impression is not so good. I have no troubles with other boost or boost asio programs. Here is my environment: gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3 Linux ubuntu 2.6.32-24-generic #41-Ubuntu SMP Thu Aug 19 01:12:52 UTC 2010 i686 GNU/Linux Thanks! |
From: Max M. <ma...@kt...> - 2011-01-20 14:41:24
|
Hi! I have now done a few tests regarding the ASyncProxy class I mailed about. The original problem arised when compiling with MSVS 2010, using boost 1.44 installed with the boost pro installer package. This yielded a bad_cast exception thrown whenever a request was made. Then I decided to test it on my Ubuntu machine. I installed boost 1.45 using bjam. Everything worked fine. I got no exception and the connection.write("hello") indeed sent that very response to my browser. I concluded that I should probably build boost 1.45 on my windows machine, which is what I did today. Following your advice I also checked out cpp-netlib from the master branch of the git repository, and used that instead of the download. Originally I got a compile error, but once I included boost/or.hpp in the boost/network/version.hpp file it compiled. However, it still does not work on my windows distribution, while it does on my ubuntu distribution. I still get a bad_cast exception thrown. Do you have any idea what might be the problem? Any known compiler weirdness regarding MSVC 2010 vs g++? I am using firefox both on windows and on my ubuntu machine, they both issued GET requests, difference was the user-agent header. Thanks for any and all replies. Best regards, Max Malmgren ________________________________________ From: Oleg Malashenko [ole...@gm...] Sent: Wednesday, January 19, 2011 4:15 AM To: C++ Networking Library Developers Mailing List Subject: Re: [cpp-netlib-devel] cpp-netlib async server request - bad cast exception thrown Hello Max, On 18.01.2011 02:11, Max Malmgren wrote: > I have a problem using the asynchronous server version of the > cpp-netlib. As soon as I make a request a bad_cast exception is cast on > the thread that ran .run(). Dean has already spotted the problem in ASyncProxy::operator(). Apart of that please consider using master or 0.8-devel branch of git://github.com/mikhailberis/cpp-netlib.git until 0.8.1 is released: there are important fixes to async_connection. -- Best regards, Oleg Malashenko. |
From: Oleg M. <ole...@gm...> - 2011-01-19 03:15:53
|
Hello Max, On 18.01.2011 02:11, Max Malmgren wrote: > I have a problem using the asynchronous server version of the > cpp-netlib. As soon as I make a request a bad_cast exception is cast on > the thread that ran .run(). Dean has already spotted the problem in ASyncProxy::operator(). Apart of that please consider using master or 0.8-devel branch of git://github.com/mikhailberis/cpp-netlib.git until 0.8.1 is released: there are important fixes to async_connection. -- Best regards, Oleg Malashenko. |
From: Dean M. B. <mik...@gm...> - 2011-01-18 05:07:42
|
Hi Max, Sorry for the late response this time, I've been asleep for a bit and taking a break earlier today. Please see thoughts below. On Tue, Jan 18, 2011 at 12:11 AM, Max Malmgren <ma...@kt...> wrote: > Hey everybody. > > I have a problem using the asynchronous server version of the cpp-netlib. As > soon as I make a request a bad_cast exception is cast on the thread that ran > .run(). > > I am making a request to > "http://localhost:11200/proxy/?url=http://www.google.se", but all other > requests seem to fail aswell. > > This is working fine for the synchronous version of the server. I am making > this request from firefox. Also, I am using v0.8 of the library. > Can you please send the exact request that the browser sends over the line? Can you please use something like FireBug to catch the raw request (with method, headers, and body) that it sends to the server? > Any ideas? Checking the documentation for using the async-server, it seems > to be pretty identical to what I am doing. > > //asyncproxy.cpp > #include <string> > #include "asyncproxy.h" > > namespace proxy { > void ASyncProxy::startProxy(std::string url, std::string port) > { > boost::network::utils::thread_pool thread_pool(2); > http_server server(url, port, *this, thread_pool); > server.run(); > } > ASyncProxy::ASyncProxy(void (*callback)(std::string)) > { > this->callback = callback; > } > void ASyncProxy::operator()(http_server::request const & req, > http_server::connection_ptr connection) > { > connection->set_status(http_server::connection::ok); This is it? Unfortunately you'd need to write out headers and data to the connection too for anything to actually be sent through the connection. Please check the test in libs/network/test/http_async_server.cpp to see what an asynchronous handler should look like. HTH -- Dean Michael Berris about.me/deanberris |