C + + Invoke HTTP implementation method
There are two ways of HTTP access, get and post, in terms of programming, get is relatively simple, it does not have to submit data to the server, the program uses the Post method,
Submits the data and obtains the return value from the server.
To achieve HTTP access, Microsoft offers two sets of api:wininet, WinHTTP. WinHTTP is more secure and robust than WinInet, so you can think of WinHTTP as an upgraded version of WinInet.
program, a macro is set to determine whether to use WinHTTP or WinInet.
#define USE_WINHTTP//comment This line to user WinInet.
The following is the process of implementing HTTP access (two sets of APIs are the same process):
1, first we open a session to get a hinternet session handle;
2, then we use this session handle to connect to the server to get a hinternet connect handle;
3, then we use this connect handle to open the HTTP request to get a handle to hinternet request;
4, we can use this request handle to send data and read the data returned from the server;
5, and then close the request,connect,session handle in turn.
/*********************** defines the method used to send HTTP ***********************************/
Hinternet opensession (Lpcwstr useragent = 0)
{
#ifdef use_winhttp
Return WinHttpOpen (useragent, NULL, NULL, NULL, NULL);;
#else
Return InternetOpen (useragent, internet_open_type_preconfig, NULL, NULL, 0);
#endif
}
Hinternet Connect (hinternet hsession, lpcwstr serveraddr, int portno)
{
#ifdef use_winhttp
Return Winhttpconnect (Hsession, Serveraddr, (internet_port) portno, 0);
#else
Return InternetConnect (Hsession, serveraddr, portno, NULL, NULL, internet_service_http, 0, 0);
#endif
}
Hinternet openrequest (hinternet hconnect, LPCWSTR verb, lpcwstr objectName, int scheme)
{
DWORD flags = 0;
#ifdef use_winhttp
if (scheme = = Internet_scheme_https) {
Flags |= winhttp_flag_secure;
}
Return winhttpopenrequest (hconnect, verb, objectName, NULL, NULL, NULL, flags);
#else
if (scheme = = Internet_scheme_https) {
Flags |= internet_flag_secure;
}
Return httpopenrequest (hconnect, verb, objectName, NULL, NULL, NULL, flags, 0);
#endif
}
BOOL addrequestheaders (hinternet hrequest, LPCWSTR header)
{
size_t len = lstrlenw (header);
#ifdef use_winhttp
Return Winhttpaddrequestheaders (hrequest, header, DWORD (len), winhttp_addreq_flag_add);
#else
Return Httpaddrequestheaders (hrequest, header, DWORD (len), http_addreq_flag_add);
#endif
}
BOOL SendRequest (hinternet hrequest, const void* body, DWORD size)
{
#ifdef use_winhttp
Return WinHttpSendRequest (hrequest, 0, 0, const_cast<void*> (body), size, size, 0);
#else
Return HttpSendRequest (hrequest, 0, 0, const_cast<void*> (body), size);
#endif
}
BOOL EndRequest (hinternet hrequest)
{
#ifdef use_winhttp
Return Winhttpreceiveresponse (hrequest, 0);
#else
If you use the HttpSendRequestEx to send request then use HttpEndRequest in here!
return TRUE;
#endif
}
BOOL QueryInfo (hinternet hrequest, int queryid, char* szbuf, dword* pdwsize)
{
#ifdef use_winhttp
Return WinHttpQueryHeaders (Hrequest, (DWORD) Queryid, 0, Szbuf, pdwsize, 0);
#else
Return HttpQueryInfo (hrequest, Queryid, Szbuf, pdwsize, 0);
#endif
}
BOOL ReadData (hinternet hrequest, void* buffer, DWORD length, dword* cbread)
{
#ifdef use_winhttp
Return WinHttpReadData (hrequest, buffer, length, cbread);
#else
Return InternetReadFile (hrequest, buffer, length, cbread);
#endif
}
void Closeinternethandle (hinternet hinternet)
{
if (hinternet)
{
#ifdef use_winhttp
Winhttpclosehandle (hinternet);
#else
InternetCloseHandle (hinternet);
#endif
}
}
/**********************************************************/
Send SMS by HTTP mode
String sendsms_http (const long ececcid,const string & password, const string & msisdn, const string &smsconten T
{
String rtnstr = "1";
Hinternet hsession = 0;
Hinternet hconnect = 0;
Hinternet hrequest = 0;
Wstring Strheader (L "content-type:application/x-www-form-urlencoded\r\n");
Test data
Crackedurl Crackedurl (L "http://pi.f3.cn/SendSMS.aspx");
String strpostdata = "ececcid=600000&password=" +password+ "&msisdn=" +msisdn+ "&smscontent=" +smsContent+ "&msgtype=5&longcode=";
Strpostdata = String_to_utf8 (Strpostdata);
Open session.
Hsession = Opensession (L "HttpPost by [email protected]");
if (hsession = = NULL) {
cout<< "Error:open session!\n";
Return "-1";
}
Connect.
Hconnect = Connect (Hsession, Crackedurl.gethostname (), Crackedurl.getport ());
if (hconnect = = NULL) {
cout<< "Error:connect failed!\n";
Return "-1";
}
Open request.
Hrequest = OpenRequest (hconnect, L "POST", Crackedurl.getpath (), Crackedurl.getscheme ());
if (hrequest = = NULL) {
cout<< "Error:openrequest failed!\n";
Return "-1";
}
ADD request header.
if (! Addrequestheaders (Hrequest, Strheader.c_str ())) {
cout<< "Error:addrequestheaders failed!\n";
Return "-1";
}
Send Post data.
if (! SendRequest (Hrequest, Strpostdata.c_str (), Strpostdata.length ())) {
cout<< "Error:sendrequest failed!\n";
Return "-1";
}
End Request
if (! EndRequest (hrequest)) {
cout<< "Error:endrequest failed!\n";
Return "-1";
}
Char Szbuf[buf_size];
DWORD dwsize = 0;
Szbuf[0] = 0;
Query Header info.
#ifdef use_winhttp
int contextlengthid = Winhttp_query_content_length;
int statuscodeid = Winhttp_query_status_code;
int statustextid = Winhttp_query_status_text;
#else
int contextlengthid = Http_query_content_length;
int statuscodeid = Http_query_status_code;
int statustextid = Http_query_status_text;
#endif
dwsize = buf_size;
if (QueryInfo (hrequest, Contextlengthid, Szbuf, &dwsize)) {
Szbuf[dwsize] = 0;
cout<< "Content Length:" <<szBuf<<endl;
}
dwsize = buf_size;
if (QueryInfo (hrequest, Statuscodeid, Szbuf, &dwsize)) {
Szbuf[dwsize] = 0;
cout<< "Status code:" << szbuf<<endl;
}
dwsize = buf_size;
if (QueryInfo (hrequest, Statustextid, Szbuf, &dwsize)) {
Szbuf[dwsize] = 0;
cout<< "Status text:" <<szBuf<<endl;
}
Read data.
for (;;) {
dwsize = buf_size;
if (ReadData (hrequest, Szbuf, dwsize, &dwsize) = = FALSE) {
Break
}
if (dwsize <= 0) {
Break
}
Szbuf[dwsize] = 0;
Rtnstr =::utf8_to_string (String (szbuf));
Cout<<rtnstr<<endl;//output return value
}
Closeinternethandle (hrequest);
Closeinternethandle (Hconnect);
Closeinternethandle (hsession);
return rtnstr;
}
The Crackurl method used in the above method is in the following CrackURL.h file:
#pragma once
#include <iostream>
using namespace Std;
#define USE_WINHTTP//comment This line to user WinInet.
#ifdef use_winhttp
#include <winhttp.h>
#pragma comment (lib, "Winhttp.lib")
#else
#include <wininet.h>
#pragma comment (lib, "Wininet.lib")
#endif
Crackedurl
Class Crackedurl {
int m_scheme;
Wstring M_host;
int m_port;
Wstring M_path;
Public
Crackedurl (lpcwstr URL)
{
Url_components UC = {0};
uc.dwstructsize = sizeof (UC);
Const DWORD Buf_len = 256;
WCHAR Host[buf_len];
Uc.lpszhostname = host;
Uc.dwhostnamelength = Buf_len;
WCHAR Path[buf_len];
Uc.lpszurlpath = path;
Uc.dwurlpathlength = Buf_len;
WCHAR Extra[buf_len];
Uc.lpszextrainfo = extra;
Uc.dwextrainfolength = Buf_len;
#ifdef use_winhttp
if (! WinHttpCrackUrl (URL, 0, Icu_escape, &uc)) {
cout<< "Error:winhttpcrackurl failed!\n";
}
#else
if (! Internetcrackurl (URL, 0, Icu_escape, &uc)) {
printf ("Error:internetcrackurl failed!\n");
}
#endif
M_scheme = Uc.nscheme;
M_host = host;
M_port = Uc.nport;
M_path = path;
}
int Getscheme () const
{
return m_scheme;
}
LPCWSTR GetHostName () const
{
return M_host.c_str ();
}
int Getport () const
{
return m_port;
}
LPCWSTR GetPath () const
{
return M_path.c_str ();
}
static string UrlEncode (const char* p)
{
if (p = = 0) {
return string ();
}
String buf;
for (;;) {
int ch = (BYTE) (* (p++));
if (ch = = ' + ') {
Break
}
if (isalnum (ch) | | ch = = ' _ ' | | ch = = '-' | | ch = = '. ') {
BUF + = (char) ch;
}
else if (ch = = ") {
BUF + = ' + ';
}
else {
Char c[16];
WSPRINTFA (c, "%%%02x", ch);
BUF + = C;
}
}
return buf;
}
};
C + + http