⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 a_httpreq.cpp

📁 一个不错
💻 CPP
字号:
/* Copyright is licensed under GNU LGPL.                 by I.J.Wang 2006  Send HTTP request to server, specified by the command line and rURI  Build: make a_httpreq*/#include "../src/wystr.h"#include "../src/wysockfile.h"#include "../src/wysockaddrinet4.h"#include "../src/wysockaddrinet6.h"#include "../src/wy_uty.h"#include "../src/wy_atdestroy.h"#include <netdb.h>#include <new>// Class inheriting WY_RepInfo for macro EAI_... from  ::getaddrinfo.(very basic)// Error text is borrowed from <netdb.h> (LGPL checked)//class EAI_ErrInfo : public Wy_RepInfo {  public:    EAI_ErrInfo(int ec, const char* cstr) throw() : Wy_RepInfo(ec,cstr) {};     size_t get_reply(char* buf, size_t blen) const WY__NOTHROW__         { return Wy_RepInfo::get_reply(buf,blen); };     void set_reply(const char* str, size_t slen) WY__NOTHROW__         {};  // no effect};static EAI_ErrInfo ei_EAI_BADFLAGS(EAI_BADFLAGS,"Invalid value for `ai_flags' field");static EAI_ErrInfo ei_EAI_NONAME(EAI_NONAME,"NAME or SERVICE is unknown");static EAI_ErrInfo ei_EAI_AGAIN(EAI_AGAIN,"Temporary failure in name resolution");static EAI_ErrInfo ei_EAI_FAIL(EAI_FAIL,"Non-recoverable failure in name res");static EAI_ErrInfo ei_EAI_NODATA(EAI_NODATA,"No address associated with NAME");static EAI_ErrInfo ei_EAI_FAMILY(EAI_FAMILY,"`ai_family' not supported");static EAI_ErrInfo ei_EAI_SOCKTYPE(EAI_SOCKTYPE,"`ai_socktype' not supported");static EAI_ErrInfo ei_EAI_SERVICE(EAI_SERVICE,"SERVICE not supported for `ai_socktype'");static EAI_ErrInfo ei_EAI_ADDRFAMILY(EAI_ADDRFAMILY,"Address family for NAME not supported");static EAI_ErrInfo ei_EAI_MEMORY(EAI_MEMORY,"Memory allocation failure");static EAI_ErrInfo ei_EAI_SYSTEM(EAI_SYSTEM,"System error returned in `errno'");static EAI_ErrInfo ei_EAI_OVERFLOW(EAI_OVERFLOW,"Argument buffer overflow");const WyReply Wym_EAI_BADFLAGS(ei_EAI_BADFLAGS);const WyReply Wym_EAI_NONAME(ei_EAI_NONAME);const WyReply Wym_EAI_AGAIN(ei_EAI_AGAIN);const WyReply Wym_EAI_FAIL(ei_EAI_FAIL);const WyReply Wym_EAI_NODATA(ei_EAI_NODATA);const WyReply Wym_EAI_FAMILY(ei_EAI_FAMILY);const WyReply Wym_EAI_SOCKTYPE(ei_EAI_SOCKTYPE);const WyReply Wym_EAI_SERVICE(ei_EAI_SERVICE);const WyReply Wym_EAI_ADDRFAMILY(ei_EAI_ADDRFAMILY);const WyReply Wym_EAI_MEMORY(ei_EAI_MEMORY);const WyReply Wym_EAI_SYSTEM(ei_EAI_SYSTEM);const WyReply Wym_EAI_OVERFLOW(ei_EAI_OVERFLOW);// The '::getaddrinfo' function this file uses, mainly for return status// conversion//static WyRet wy_getaddrinfo(const char* node, const char* service,                     const struct addrinfo* hints, struct addrinfo** res){ const int v=::getaddrinfo(node,service,hints,res); if(v==0) {   return( Ok ); } WyRet r; switch(v) {   case EAI_FAMILY:   r= Wym_EAI_FAMILY ; break;   case EAI_SOCKTYPE: r= Wym_EAI_SOCKTYPE ; break;   case EAI_BADFLAGS: r= Wym_EAI_BADFLAGS ; break;   case EAI_NONAME:   r= Wym_EAI_NONAME ; break;   case EAI_SERVICE:  r= Wym_EAI_SERVICE ; break;   case EAI_ADDRFAMILY: r= Wym_EAI_ADDRFAMILY ; break;   case EAI_NODATA:   r= Wym_EAI_NODATA ; break;   case EAI_MEMORY:   r= Wym_EAI_MEMORY ; break;   case EAI_FAIL:     r= Wym_EAI_FAIL ; break;   case EAI_AGAIN:    r= Wym_EAI_AGAIN ; break;   case EAI_SYSTEM:   r= Wym_EAI_SYSTEM ; break;   case EAI_OVERFLOW: r= Wym_EAI_OVERFLOW ; break;   default:           WY_THROW( WyRet() ); }; WY_RETURN(r);};// [Syn] Write addr notation to Wy::cout//WyRet print_sockaddr(const Wy_SockAddr& addr)try { WyStr str; WyRet r( addr.notation(str) ); if(r!=Ok) {   WY_RETURN(r); } size_t n_wr; if((r=Wy::full_write(Wy::cout,str,n_wr))!=Ok) {   WY_RETURN(r); } if(n_wr!=str.size()) {   WY_RETURN( Wym_EIO ); } return(Ok);}catch(const WyStr::Reply& e) { WY_RETURN(e);}catch(const WyRet& e) { WY_THROW( WyRet(e) );};// [Syn] Get socket address object converted from addr.ai_addr//// [Ret] Pointer to socket address object allocated from addr.ai_addr//       , or NULL if failed//       //       Note: App. is responsible to delete the return object//static Wy_SockAddr* get_sockaddr(const struct ::addrinfo& addr){ switch(addr.ai_addr->sa_family) {   case AF_INET:        return new(std::nothrow) WySockAddrINet4( *(struct sockaddr_in*)addr.ai_addr );   case AF_INET6:        return new(std::nothrow) WySockAddrINet6( *(struct sockaddr_in6*)addr.ai_addr );   default:        return NULL; };};static WyRet http_client(const WyStr& domain_name, const WyStr& ruri)try { const char* Service="http"; struct addrinfo hints,*addr; WyRet r; ::memset(&hints,0,sizeof(hints)); hints.ai_socktype= SOCK_STREAM; // call getaddrinfo, result is allocated and pointed by addr for(;;) {   const WyRet v( wy_getaddrinfo(domain_name.c_str(),Service,&hints,&addr) );   if(v==Ok) {     break;   }   if(v==Wym_EAI_AGAIN) {     continue;   }   WY_RETURN(v); } Wy_AtDestroy<void,struct addrinfo*> rrid(::freeaddrinfo,addr); // loop each addrinfo and request domain_name+ruri for(struct addrinfo *pa=addr; pa!=NULL; pa=pa->ai_next) {   Wy_SockAddr *sa_ptr= get_sockaddr(*pa);   if(sa_ptr==NULL) {     WY_RETURN(Wym_ESRCH);       // no address found (or ENOMEM)   }   Wy_AtDestroy<void,Wy_SockAddr*> rrid(Wy::_delete_one,sa_ptr);   if((r=print_sockaddr(*sa_ptr))!=Ok) {     WY_RETURN(r);   }   // connect to *sa_ptr pointed Http server, request for /   const WyCSeg ReqHdr("GET ");   const WyCSeg ReqTrail(" HTTP/1.0\r\n\r\n");   WyStr hmsg(ReqHdr+"http://"+domain_name+ruri+ReqTrail);   Wy::cout << "Send Request>" << hmsg << '\n';   WySockFile sock;   if((r=sock.reset(sa_ptr->family(),SOCK_STREAM,0))!=Ok) {     Wy::cerr << Wy::wrd(r) << '\n';     continue;   }   if((r=sock.connect(*sa_ptr))!=Ok) {     Wy::cerr << Wy::wrd(r) << '\n';     continue;   }   // send header/request message   sock << hmsg;   // get response untill eof   {     WyStr rbuf;     for(;;) {       sock >> rbuf;       if(rbuf.size()==0) {         break;    // EOF       }       Wy::cout << rbuf;     }   }   break;  }; return(Ok);}catch(const WySockFile::Reply& e) { WY_RETURN(e);}catch(const WyStr::Reply& e) { WY_RETURN(e);}catch(const WySysFile::Reply& e) { WY_RETURN(e);}catch(const WyRet& e) { WY_TERMINATE("unexpected Reply");};static const char* syntax= "Syntax>./a_httpreq dn ru\n" "  dn= Domain name. E.g. www.linux.org\n" "  ru= Absolute URI. E.g. /\n";int main(int argc, char* argv[])try { if(argc!=3) {   Wy::cerr << syntax;   return(-1); } const WyRet r( http_client( WyCSeg(argv[1]), WyCSeg(argv[2])) ); if(r!=Ok) {   Wy::cerr << Wy::wrd(r) << '\n'; } Wy::cout << "Ok\n"; return(0);}catch(...) { Wy::cerr << "Unidentified throw type\n"; return(-1);};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -