论坛 编程与开发 其他开发话题 (软件技术的领域实在太广。。。。。。)
|
本版斑竹:招募中... |
利用Http 1.1 的POST协议上传文件| <<上一页 1 下一页>> | |||
![]() 注册: 2008-05-06 积分: 3121 分 等级: ![]() ![]() ![]() 喜欢你,没道理! |
2008-05-18 09:05:33 #1
原文出处:http://www.cnitblog.com/apexchu/archive/2007/05/07/26710.html |
||
![]() 注册: 2008-04-24 积分: 12335 分 等级: ![]() ![]() ![]() 尘世如潮人如水 只叹江湖几人回 |
2008-06-05 00:09:59 #2
这里有一个非常棒的Library用于处理HTTP GET/POST请求: http://www.codeproject.com/KB/library/lyoulhttpclient.aspx IntroductionThis file contains classes which help to interact with a HTTP server. The codes contained in this file depends on the documentation of STLPort 4.6.1 (describing about exception safety). How to use RyeolHttpClientIn your project, include the following files.
In your stdafx.h file, add the following line. #include "RyeolHttpClient.h" How to send a request using HTTP GET
// Retrieves the resource specified by the szUrl using HTTP GET request. // szUrl [in] A HTTP URL. // bUseCache [in] Specifies whether to use cache. CHttpResponse * CHttpClient::RequestGet (PCSZ szUrl, BOOL bUseCache = FALSE) throw (Exception &) ; The following code demonstrates the basic usage of the using namespace Ryeol ;
CHttpClient objHttpReq ;
CHttpResponse * pobjHttpRes = NULL ;
try {
// Initialize the User Agent
objHttpReq.SetInternet (_T ("My User Agent v1.0")) ;
// Specifies whether to use UTF-8 encoding. (This uses ANSI encoding)
// Default is FALSE
objHttpReq.SetUseUtf8 (FALSE) ;
// Specifies a code page for ANSI strings. (This uses Korean)
// Default is CP_ACP
objHttpReq.SetAnsiCodePage (949) ;
// Add user's custom HTTP headers
objHttpReq.AddHeader (_T ("Ryeol-Magic"), _T ("My Magic Header")) ;
objHttpReq.AddHeader (_T ("User-Magic"), _T ("User's Magic Header")) ;
// Add user's parameters
objHttpReq.AddParam (_T ("where"), _T ("nexearch")) ;
objHttpReq.AddParam (_T ("frm"), _T ("t1")) ;
objHttpReq.AddParam (_T ("query"), _T ("%C3%D6%C1%F6%BF%EC"), CHttpClient::ParamEncodedValue) ;
// Send a request
pobjHttpRes = objHttpReq.RequestGet (_T ("http://search.naver.com/search.naver")) ;
... // Place codes to handle the returned CHttpResponse object.
} catch (httpclientexception & e) {
... // Place exception handling codes here.
}
How to send a request using HTTP POSTThe HTTP POST method is used in two ways. One is to post simple text, the other is to upload file. To post simple text, // Starts a new HTTP POST request // szUrl [in] A HTTP URL. // bUseCache [in] Specifies whether to use cache. void CHttpClient::BeginPost (PCSZ szUrl, BOOL bUseCache = FALSE) throw (Exception &) ; The following code demonstrates the basic usage of the using namespace Ryeol ;
CHttpClient objHttpReq ;
CHttpResponse * pobjHttpRes = NULL ;
try {
// Initialize the User Agent
objHttpReq.SetInternet (_T ("My User Agent v1.0")) ;
// Add user's custom HTTP headers
objHttpReq.AddHeader (_T ("Ryeol-Magic"), _T ("My Magic Header")) ;
objHttpReq.AddHeader (_T ("User-Magic"), _T ("User's Magic Header")) ;
// Add user's parameter
objHttpReq.AddParam (_T ("st"), _T ("kw")) ;
objHttpReq.AddParam (_T ("target"), _T ("WinInet")) ;
// Start a new request
objHttpReq.BeginPost (_T ("http://www.codeproject.com/info/search.asp")) ;
// Specifies the number of bytes to send when the Proceed method is called.
const DWORD cbProceed = 1024 ; // 1K
do {
... // Place codes to report progress information to user.
} while ( !(pobjHttpRes = objHttpReq.Proceed (cbProceed)) ) ;
... // Place codes to handle the returned CHttpResponse object.
} catch (httpclientexception & e) {
... // Place exception handling codes here.
}
To upload file, // Starts a new UPLOAD request // szUrl [in] A HTTP URL. // bUseCache [in] Specifies whether to use cache. void CHttpClient::BeginUpload (PCSZ szUrl, BOOL bUseCache = FALSE) throw (Exception &) ; The following code demonstrates the basic usage of the using namespace Ryeol ;
CHttpClient objHttpReq ;
CHttpResponse * pobjHttpRes = NULL ;
try {
// Initialize the User Agent
objHttpReq.SetInternet (_T ("My User Agent v1.0")) ;
// Add user's custom HTTP headers
objHttpReq.AddHeader (_T ("Ryeol-Magic"), _T ("My Magic Header")) ;
objHttpReq.AddHeader (_T ("User-Magic"), _T ("User's Magic Header")) ;
// Add user's parameters
objHttpReq.AddParam (_T ("nohtml"), _T ("1")) ;
objHttpReq.AddParam (_T ("title"), _T ("The K-NET photo")) ;
objHttpReq.AddParam (_T ("content"), _T ("A photo of the K-NET")) ;
// Specifies a file to upload
objHttpReq.AddParam (_T ("ufile01"), _T ("D:\\My Photo\\K-NET\\photo1.jpg"), CHttpClient::ParamFile) ;
// Start a new request
objHttpReq.BeginUpload (_T ("http://club.hooriza.com/cmd/box.html?clubid=1&boxid=53&action=store&link=")) ;
// Specifies the number of bytes to send when the Proceed method is called.
const DWORD cbProceed = 1024 ; // 1K
do {
... // Place codes to report progress information to user.
} while ( !(pobjHttpRes = objHttpReq.Proceed (cbProceed)) ) ;
... // Place codes to handle the returned CHttpResponse object.
} catch (httpclientexception && e) {
... // Place exception handling codes here.
}
How to handle the returned CHttpResponse objectWhen you send a request using // Returns the number of headers of which name is the szName DWORD CHttpResponse::GetHeaderCount (PCSZ szName) throw (Exception &) ; // Returns the header of which name is the szName PCSZ CHttpResponse::GetHeader (PCSZ szName, DWORD nIdx = 0) throw (Exception &) ; // Returns the HTTP status code returned by a HTTP server DWORD CHttpResponse::GetStatus (void) throw (Exception &) ; // Returns the HTTP status text returned by a HTTP server PCSZ CHttpResponse::GetStatusText (void) throw (Exception &) ; // Retrieves the length of the content returned by a HTTP server BOOL CHttpResponse::GetContentLength (DWORD & cbContLen) throw (Exception &) ; // Reads the content returned by a HTTP server DWORD CHttpResponse::ReadContent (BYTE * pbyBuff, DWORD cbBuff) throw (Exception &) ; The following code demonstrates the basic usage of the using namespace Ryeol ;
CHttpResponse * pobjHttpRes = NULL ;
try {
// Get the CHttpResponse object
pobjHttpRes = ... ;
// Reads the HTTP status code
_tprintf (_T ("%u"), pobjHttpRes->GetStatus ()) ;
// Reads the HTTP status text
_tprintf (_T (" %s\n"), pobjHttpRes->GetStatusText ()) ;
// Reads HTTP headers using an array of header names
static LPCTSTR szHeaders[] =
{ _T ("Server"), _T ("Date"), _T ("X-Powered-By"), _T ("Content-Length"), _T ("Set-Cookie")
, _T ("Expires"), _T ("Cache-control"), _T ("Connection"), _T ("Transfer-Encoding")
, _T ("Content-Type") } ;
LPCTSTR szHeader ;
for (size_t i = 0; i < sizeof (szHeaders) / sizeof (LPCTSTR); i++) {
if ( szHeader = pobjHttpRes->GetHeader (szHeaders[i]) )
_tprintf (_T ("%s: %s\n"), szHeaders[i], szHeader) ;
else
// If the header is not found..
_tprintf (_T ("'%s' header does not exist..\r\n"), szHeaders[i]) ;
}
_tprintf (_T ("\r\n")) ;
// Checks whether the returned stream is a text
BOOL bIsText = FALSE ;
if ( szHeader = pobjHttpRes->GetHeader (_T ("Content-Type")) )
bIsText = (0 == ::_tcsncicmp (szHeader, _T ("text/"), 5)) ;
// Reads the length of the stream
DWORD dwContSize ;
// If the length is not specified
if ( !pobjHttpRes->GetContentLength (dwContSize) )
dwContSize = 0 ;
const DWORD cbBuff = 1024 * 10 ;
BYTE byBuff[cbBuff] ;
DWORD dwRead ;
size_t cbTotal = 0 ;
// Reads the data stream returned by the HTTP server.
while ( dwRead = pobjHttpRes->ReadContent (byBuff, cbBuff - 1) ) {
cbTotal += dwRead ;
if ( bIsText ) {
byBuff[dwRead] = '\0' ;
printf ("%s", reinterpret_cast<LPCSTR> (byBuff)) ;
}
}
if ( !bIsText )
_tprintf (_T ("%u bytes skipped..\n"), cbTotal) ;
} catch (httpclientexception & e) {
... // Place exception handling codes here.
}
delete pobjHttpRes ;
pobjHttpRes = NULL ;
How to handle exceptionWhen an error occurred, class httpclientexception {
public:
// Returns the last error code. The error codes is defined in RyeolHttpClient.h
DWORD LastError (void) const throw () ;
// Returns the last error message.
LPCTSTR errmsg (void) const throw () ;
// Returns the last win32 error code retrieved by using ::GetLastError when an error occurred.
DWORD Win32LastError (void) const throw () ;
} ;
Before throwing an exception, most methods restore their internal states. (all or nothing like transaction) But if you call using namespace Ryeol ;
try {
... // Place codes which throw a httpclientexception exception
} catch (httpclientexception & e) {
_tprintf (_T ("An error has been occured\n")) ;
_tprintf (_T ("ErrCode: 0x%x\n"), e.LastError ()) ;
_tprintf (_T ("ErrMsg: %s\n"), e.errmsg ()) ;
if ( e.Win32LastError () != NO_ERROR ) {
TCHAR szErrMsg[512] ;
GetWinInetErrMsg (szErrMsg, 512, e.Win32LastError ()) ;
_tprintf (_T ("Win32ErrCode: 0x%x\n"), e.Win32LastError ()) ;
_tprintf (_T ("Win32ErrMsg: %s\n"), szErrMsg) ;
}
}
How to show progress information to userIf you call // Queries progress information of the current POST context // objPostStat [out] A CHttpPostStat object. void CHttpClient::Query (CHttpPostStat & objPostStat) throw () ;
using namespace Ryeol ;
CHttpClient objHttpReq ;
CHttpResponse * pobjHttpRes = NULL ;
size_t cbProceed = 1024 ; // 1k
try {
... ; // Intialize the CHttpClient object
// Starts a new POST request
objHttpReq.BeginPost (...) or objHttpReq.BeginUpload (...) ;
// Displays progress information
CHttpPostStat objPostStat ;
do {
// Retrieves progress information
objHttpReq.Query (objPostStat) ;
_tprintf (_T ("\nPost in progress... %2u/%2u\n")
, objPostStat.PostedCount () // The number of posted parameters
, objPostStat.TotalCount ()) ; // The total number of parameters
_tprintf (_T ("%s: %10u/%10u %10u/%10u %10u/%10u\n")
, objPostStat.CurrParam () // The name of the current parameter
, objPostStat.CurrParamPostedByte () // The number of posted bytes of the current parameter
, objPostStat.CurrParamTotalByte () // The total number of bytes of the current parameter
, objPostStat.PostedByte () // The number of posted bytes of the request
, objPostStat.TotalByte () // The total number of bytes of the request
, objPostStat.ActualPostedByte () // The actual number of posted bytes of the request
, objPostStat.ActualTotalByte ()) ; // The actual total number of bytes of the request
// If the current parameter is a file parameter, displays the file path
if ( objPostStat.CurrParamIsFile () )
_tprintf (_T ("-->%s\n")
, objPostStat.CurrFile ()) ;
// Sends the number of bytes specified by cbProceed to the server
} while ( !(pobjHttpRes = objHttpReq.Proceed (cbProceed)) ) ;
... ; // Handles the returned CHttpResponse object
} catch (httpclientexception & e) {
... // Place exception handling codes here.
}
|
||
![]() 注册: 2008-04-24 积分: 12335 分 等级: ![]() ![]() ![]() 尘世如潮人如水 只叹江湖几人回 |
2008-06-05 21:55:24 #3
FMF上传作品的时候就是用RyeolHttpClient来处理的,它支持UTF8,所以中文也能很好的搞定。用起来很方便,主要是因为作者写了很详细的instruction。 |
||
| <<上一页 1 下一页>> | |||