4

I'm trying to make an HTTP Post with HTTP Basic Authentication (cleartext username and password), using POCO. I found an example of a Get and have tried to modify it, but being a rookie I think I've mangled it beyond usefulness. Anyone know how to do this?

Yes, I've already seen the other SO question on this: POCO C++ - NET SSL - how to POST HTTPS request, but I can't make sense of how it is trying to implement the username and password part. I also don't understand the use of "x-www-form-urlencoded". Is this required for a Post? I don't have a form. Just want to POST to the server with username and password parameters.

bselu
  • 194
  • 2
  • 14
Alyoshak
  • 2,696
  • 10
  • 43
  • 70

3 Answers3

11

Finally. Here's how you do it:

HTTPClientSession session("yourdomain.com");
session.setKeepAlive(true);

Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_POST, "/myapi.php/api/validate", HTTPMessage::HTTP_1_1);
req.setContentType("application/x-www-form-urlencoded");
req.setKeepAlive(true); // notice setKeepAlive is also called on session (above)

std::string reqBody("username=user1@yourdomain.com&password=mypword");
req.setContentLength( reqBody.length() );

std::ostream& myOStream = session.sendRequest(req); // sends request, returns open stream
myOStream << reqBody;  // sends the body

req.write(std::cout);

Poco::Net::HTTPResponse res;
std::istream& iStr = session.receiveResponse(res);  // get the response from server
std::cerr << iStr.rdbuf();  // dump server response so you can view it
bselu
  • 194
  • 2
  • 14
Alyoshak
  • 2,696
  • 10
  • 43
  • 70
  • In the code, you have an explicit comment on using `setKeepAlive()` on both the session and the request. Could you possibly edit your answer to explain the purpose of both, and what the effect of leaving one or either out is? – omatai Feb 19 '16 at 01:35
  • And is there any reason you do not use `HTTPBasicCredentials`? – omatai Feb 19 '16 at 01:47
  • No, no deliberate reason I didn't use HTTPBasicCredentials. I wasn't aware of a lot of things back then. Was kind of thrown into iOS and had other projects going to. Will have to answer your 1st questions later. – Alyoshak Feb 19 '16 at 15:58
  • +1 as you helped me answer this question: https://stackoverflow.com/questions/44333630/how-to-exchange-code-for-token-in-spotify/44354280#44354280 If you are still around maybe you can help me get the authorization code using Poco Net. – CashCow Jun 04 '17 at 12:50
  • 1
    I see you ended up answering your own question too :) – CashCow Jun 04 '17 at 12:52
  • @CashCow -- Yes. I've done this more than once in fact. You seriously need a solution and then when you find it you feel obligated to share and not just go on your way. As you can see this answer has helped a few people. – Alyoshak Sep 14 '18 at 17:16
3

When you do an HTTP POST, typically the data that is being sent to the server is sent in one of two forms:

  • Name,Value pairs where the name and value are separated by "=", and distinct pairs are separated by "&". For example: var1=value1&var2=value2. Also, these name value pairs are sent so that certain special characters and non-alphanumeric characters are replaced by %HH, a percent sign and two hexadecimal digits representing the ASCII code of the character. For example, if value for the first parameter included an "#", it would be sent as var1=value1%23&var2=value2. When sending data in this format, the client is required to insert a Content-Type header with the value application/x-www-form-urlencoded so that the server may be able to decode the data correctly.

  • As a multipart MIME body where each part can be large in size as well as include "non-escaped" data (including binary data). Different MIME parts are separated by a string delimiter (boundary) that does not appear within any of the MIME "payloads". When sending data in this format, the client is required to insert a Content-Type header with the value multipart/form-data.

In the case of the previous StackOverflow question you referenced, the request body is being sent in the first manner as shown above. Hope that clarifies.

Regards, Siddharth

  • Siddhart, that does clarify a bit. Thanks. Have you used POCO? If you can offer code that will successfully Post with uname and pword using the POCO library I'll mark your answer as correct. – Alyoshak Oct 31 '12 at 19:42
2

From the POCO library credential test, here is the code:

HTTPRequest request;
assert (!request.hasCredentials());

HTTPBasicCredentials cred("user", "secret");
cred.authenticate(request);
assert (request.hasCredentials());
std::string scheme;
std::string info;
request.getCredentials(scheme, info);
assert (scheme == "Basic");
assert (info == "dXNlcjpzZWNyZXQ=");

HTTPBasicCredentials cred2(request);
assert (cred2.getUsername() == "user");
assert (cred2.getPassword() == "secret");

When sending the request, you would only use the first part of this code (stopping at cred.authenticate(request)).

Darth Vader
  • 203
  • 1
  • 5