hello guys I ask my question,
I have this code that download a web page
#include <iostream>
#include <urlmon.h>
#include <string>
#pragma comment(lib,"urlmon.lib")
using namespace std;
int main()
{
string indirizzo;
IStream * is;
char buffer[256];
cout<<"Insert adress of the web page: ";
cin>>indirizzo;
if(URLOpenBlockingStream(NULL,indirizzo.c_str(),&is,0,NULL)!=S_OK)
{
cerr<<"ERROR DOWNLOAD.";
}
else
{
cout<<"download OK"<<endl;
system("Pause");
ULONG readBytes;
while(is->Read(buffer,sizeof(buffer),&readBytes)==S_OK)
{
cout.write(buffer,readBytes);
}
is->Release();
}
system("cls");
system("Pause");
return 0;
}
You can do this by connecting the socket via a proxy before the http request? I would like to do everything through proxy
API that you use seems to be InternetExplorer derived. It seems that you cannot use proxy's (other than system-wide) using only this API. If that's fine with you, just set your ControlPanel proxy to desired settings and you are good to go. Browsers other than IE might even get configured so they use they own proxy settings, so you can limit the effects of system-wide settings if you need it only for your program.
If you need it stricly only for your app, or otherwise hidden/secured (users might be able to see/change IE settings) you might try to use WinINet to download your files, but that's not what you are asking. WinINet version will be lengthier and more troublesome I expect. See the MSDN WinINet documentation, specifically InternetSetOption.
EDIT:
I see that you will probably be able to use it to set IE settings both globally and on per-process basis. See How to programmatically query and set proxy settings under Internet Explorer, and documentation for INTERNET_OPTION_PER_CONNECTION_OPTION option.
To do it system-wide just use NULL as hInternet in InternetSetOption. To do it just for your own process, use InternetOpen before any other networking code, and use returned handle - it seems it should also affect dynamically loaded IE engine.
Related
I am trying to use the code given in this git repository. The code is not mine and I would like to thank honeyligo for his work!
I unfortunately can't manage to run it properly (I had to fix some compilation issues but nothing dramatic).
After setting the main.cpp to
#include <unistd.h>
#include "curlsmtp.h"
int main(){
CurlSmtp* mail = new CurlSmtp(
"MYADDRESS#gmail.com",
"MYPASSWORD",
{ "foo#yahoo.fr" },
{},
{},
{},
"it's a subject",
"hello world you aredfsf",
"smtp.gmail.com",
"465");
mail->send_mail();
sleep(3);
delete mail;
return 0;
}
it constantly returns
* Expire in 200 ms for 1 (transfer 0x558a3b95d7e0)
then fails after a timeout. The code is roughly 500 lines long and well commented but I can't figure out why it fails. I don't know much about curl but I'm looking for a way to automatically sent mails with a pdf attached to my high school students. I need to implement a c++ solution because this will be part of a larger project.
Thanks for your help!
After some testing with curl both from the CLI and in a C app using libcurl, I found the issue: gmail only accepts smtp requests if you explicitly use smtps (smtps://smtp.gmail.com).
As it's hardcoded in this curlsmtp lib to use smtp://, you either modify it (set_curl_option method) or use libcurl directly (an easy example here: https://curl.haxx.se/libcurl/c/smtp-mime.html)
Also, you either have to set up 2FA in your Google account and create an app password, or enable access for less secure apps if there is no 2FA (https://myaccount.google.com/lesssecureapps).
I'm wondering the most simple way to send a request to a API on my server then receive the API's response (json array) wihtout using any libraries. I've tried using libs like cURL & boost without any luck which is the reason i want to stay away from them. I've searched for many days for a answer and have not been able to find anything, which is why i've resorted to coming to the stack overflow community!
Even though the question is about not using a library I 'am taking this opportunity to show how easy it is to use a library than the user thinks.
Its better to use pre-built libraries and stop reinventing the wheel. You can use curlcpp library. Its a wrapper for libcurl. Using this library HTTP requests can be made easily. Learning curve is also less and it provides C++ style access which makes it more comfortable to work with.
The following code is taken from their gitHub page - https://github.com/JosephP91/curlcpp
It makes a simple GET request to Google and retrieves the HTML response. You can use this example to hit apis too.
#include "curl_easy.h"
#include "curl_exception.h"
using curl::curl_easy;
using curl::curl_easy_exception;
using curl::curlcpp_traceback;
int main(int argc, const char **argv) {
curl_easy easy;
// Add some option to the curl_easy object.
easy.add<CURLOPT_URL>("http://www.google.it");
easy.add<CURLOPT_FOLLOWLOCATION>(1L);
try {
// Execute the request.
easy.perform();
} catch (curl_easy_exception error) {
// If you want to get the entire error stack we can do:
curlcpp_traceback errors = error.get_traceback();
// Otherwise we could print the stack like this:
error.print_traceback();
// Note that the printing the stack will erase it
}
return 0;
}
I am trying to make this working code to check if URL exists (coded Visual C++):
void urlexists()
{
try
{
LPCWSTR pfile(NULL);
HRESULT hRez = URLDownloadToFile(NULL, _T("http://google.com"), (pfile), 0, NULL);
if (hRez != 0)
return;
}
catch (...)
{
return;
}
}
and make it portable for linux distros. What should I do? I didn't found nothing on Internet
As far as the process goes, if you make a GET request to the URL, you will get a 200/OK code back if the resource exists. You will receive a 404 if it does not. Your file will be in the body of the request if the request succeeds. You then copy the request body to the file on disk.
There isn't a good way to make this portable without writing a libcurl, winhttp, and possibly a core foundation implementation. You either need to abstract this and write an implementation for each platform, or use a library that does it for you. There are a few options. Boost has an http client you could use. Also, the AWS SDK for C++ has an http implementation that will do this for you.
Your other option is to read the HTTP spec, open the socket yourself and make the request manually. Fair warning however, this is non-trivial especially if TLS is involved.
If you want to write it yourself, I recommend libcurl for your linux implementation. You are more than welcome to use the examples here as a starting point. https://github.com/awslabs/aws-sdk-cpp/tree/master/aws-cpp-sdk-core/include/aws/core/http
I need to write a C++ interface that can read our data structure and provide the o/p based on query using http protocol.
Server Need
It should be able to serve 100 clients at the same time.
Why C++
All code is already written in C++. So we need to just write a http layer in C++. That's why I am choosing C++ instead of a more conventional web-programming language.
I am thinking to use nginx to serve static files and use its proxy pass to communicate with C++.
There are two approaches I have found:
Write a FastCGI c++ module.
Write a node.js c++ module.
Please just any other suggestion if you have
Can you please list the pros and cons for each method based on prior experience?
No one here seems to have addressed the actual question, though some nice work arounds have been offered. I've been able to build C++ modules for nginx with a couple of minor changes.
Change the module source file name to end with .cpp so gcc realizes it is dealing with C++.
Make sure all your Nginx includes (e.g. ngx_config.h, ngx_core.h, etc.) are wrapped with an extern "C" { } structure. Similarly make sure any functions called through Nginx function pointers are declared with a wrapper.
Add --with-ld-opt="-lstdc++" to your "configure" invocation when setting up Nginx.
With those three steps your module should compile, build, link, and actually work.
I think I will go forward with Nginx module devlopment http://www.evanmiller.org/nginx-modules-guide.html
Why ?
It don't require any other library dependency like fastcgi and
other.
I can use all feature of nginx inside my module.
What you are asking is basically how to turn the c++ process that holds your data strutures into a webserver. That might not be the best way to go about it. (Then again, maybe it is in your situation. It depends on the complexity of the c++ process's interfaces you are trying to expose i guess.)
Anyways, I would try to stick a small http frontend in between the c++ process and the clients that could do the http work and communicate with the c++ backend process using some simple messaging protocol like ZeroMQ/zmq.
zmq in c/c++ is fairly straight forward, and its very efficient and very fast. Using zmq you could very quickly setup a simple webserver frontend in python, or whatever language you prefer that has zmq bindings, and have that frontend communicate asyncronously or syncronously with the backend c++ process using zmq.
The c++ examples and the guide are nice starting points if you are looking into using zmq.
For Node.js there are also a few examples.
Try G-WAN, it allows you to use your c++ application directly.
You may try nginx c function
It is simple to use and built in nginx cache memory on apps layer, wiki for nginx c function
Example project with cpp
Sample code:
#include <stdio.h>
#include <ngx_http_c_func_module.h>
/*** build the program as .so library and copy to the preferred place for nginx to link this library ***/
/*** gcc -shared -o libcfuntest.so -fPIC cfuntest.c ***/
/*** cp libcfuntest.so /etc/nginx/ ***/
int is_service_on = 0;
void ngx_http_c_func_init(ngx_http_c_func_ctx_t* ctx) {
ngx_http_c_func_log(info, ctx, "%s", "Starting The Application");
is_service_on=1;
}
void my_app_simple_get_greeting(ngx_http_c_func_ctx_t *ctx) {
ngx_http_c_func_log_info(ctx, "Calling back and log from my_app_simple_get");
ngx_http_c_func_write_resp(
ctx,
200,
"200 OK",
"text/plain",
"greeting from ngx_http_c_func testing"
);
}
void my_app_simple_get_args(ngx_http_c_func_ctx_t *ctx) {
ngx_http_c_func_log_info(ctx, "Calling back and log from my_app_simple_get_args");
ngx_http_c_func_write_resp(
ctx,
200,
"200 OK",
"text/plain",
ctx->req_args
);
}
void my_app_simple_get_token_args(ngx_http_c_func_ctx_t *ctx) {
ngx_http_c_func_log_info(ctx, "Calling back and log from my_app_simple_get_token_args");
char * tokenArgs = ngx_http_c_func_get_query_param(ctx, "token");
if (! tokenArgs) {
ngx_http_c_func_write_resp(
ctx,
401,
"401 unauthorized",
"text/plain",
"Token Not Found"
);
} else {
ngx_http_c_func_write_resp(
ctx,
401,
"401 unauthorized",
"text/plain",
tokenArgs
);
}
}
void my_app_simple_post(ngx_http_c_func_ctx_t *ctx) {
ngx_http_c_func_log_info(ctx, "Calling back and log from my_app_simple_post");
ngx_http_c_func_write_resp(
ctx,
202,
"202 Accepted and Processing",
"text/plain",
ctx->req_body
);
}
void my_app_simple_get_no_resp(ngx_http_c_func_ctx_t *ctx) {
ngx_http_c_func_log_info(ctx, "Calling back and log from my_app_simple_get_no_resp");
}
void ngx_http_c_func_exit(ngx_http_c_func_ctx_t* ctx) {
ngx_http_c_func_log(info, ctx, "%s\n", "Shutting down The Application");
is_service_on = 0;
}
Just add an HTTP frontend to your C++ code, possibly using a library such as Beast, and then proxy_pass from nginx to your C++ server. You may or may not need nginx at all, depending on your use.
I am a beginner in writing web application, so please co-operate if its a silly question. Our web application is hosted using tomcat 6. I have some C++ code to be executed in server when user click on corresponding button. Client side is written in html/JS and hosted using tomcat.
So, My problem is I dont know how this C++ code will be executed when a button is clicked in html page. Can anyone please help me?
[updated]
I can change from tomcat to any other server but code has to be in c++. So if you have any other server(wamp or smthing) or links to do the same. Please let me know
Tomcat, a Java Servlet container is definitely not the most appropriate vehicle to execute C++ code in. You could try to use JNI to make a servlet run the C++ code, but it seems to me that there are much easier and reliable ways, like good old CGI's. Tomcat can do CGI, as explained here, with some limitations and restrictions.
Update: I think we can agree that the CGI route is the way to go. Most webservers allow you to run cgi's, and it will definitely be simpler than with Tomcat. I also suggest you delegate the work of connecting your code to the web server to a library, like gnu cgicc (nice tutorial here) or cgic. A plain old WAMP (you'll just use the WA part here) and that sample code should get you up to speed in no time. The rest will be pretty standard Web development.
https://stackoverflow.com/questions/175507/c-c-web-server-library answers may well help you out.
Given that Tomcat is no longer a requirement, using a different http front end may well make your life easier.
If you do decide to use Tomcat Which C++ Library for CGI Programming? may help you pick a library.
Barring that, if you use Apache, you can write a plugin module itself, instead of CGI, which will give you much better performance. (Other web servers generally have similar plug-in methodologies also...)
Good Luck
I'm not sure any of these answers addressed the question. Coding a CGI using C++ would mean reading environment variables that are set by the web server, regardless of whether or not you use a third party library or which web server is run, including tomcat. The following example is a quick-and-dirty way to grab the most interesting input, the query string. If you are starting out, it's I think better to start with basics so if you decide to use some sort of external library it will seem less mystical. This should give you enough to hit google and work out what's happening.
#include <stdlib.h>
#include <iostream>
using namespace std;
int
main(int argc, char** argv)
{
string method = getenv("REQUEST_METHOD");
string query;
if (method == "GET")
query = getenv("QUERY_STRING");
else if (method == "POST")
cin >> query;
else
query = "Not sure what to do with method " + method;
cout << "Content-Type: text/html" << endl << endl
<< "<html>" << endl
<< query << endl
<< "</html>" << endl;
}
Note Content-Type in the output. That's a HTTP header. You can add any number of headers before the double endl. For a light bulb moment try changing Content-Type to text/plain.
Compile the example code to shiney_cpp_cgi, copy it to your cgi dir (for tomcat that's generally tomcat_root/webapps/ROOT/WEB-INF/cgi), then hit it with your browser as such to use the GET method:
myserver.mydomain:myport/cgi-bin/shiney_cpp_cgi?foo=bar
To send in a post request, use CURL as such:
curl --data 'foo=bar' myserver.mydomain:myport/cgi-bin/shiney_cpp_cgi
To serve C++ from tomcat, you can edit tomcat_root/conf/web.xml and change executable to an empty string. By default, tomcat will try to run your C++ as a perl script, which perl will (hopefully!) not be able to parse.
<servlet>
<servlet-name>cgi</servlet-name>
<servlet-class>org.apache.catalina.servlets.CGIServlet</servlet-class>
...
<init-param>
<param-name>executable</param-name>
<param-value></param-value>
</init-param>
...
</servlet>