文件上传到HTTP服务器

文件上传到HTTP服务器
文件上传到HTTP服务器

文件上传到HTTP服务器

2011-03-14 17:15

最近两个星期主要搞这个东东,到今天总算比较圆满的搞定了. 用http协议上传主要有两种形式: 第一是用http的put协议,第二是用http的post协议.

先说说put协议, 所谓put,顾名思义,就是把文件"放"到server端. 这个过程不涉及文件的http和mime封装(post协议需要做), 因而比较简单.但是考虑到安全问题,一般服务器不会开发put权限,因此这种方法的用途并不广泛

废话不多说,来看看代码:

CInternetSession internetSession("my session"); //定义session

CHttpConnection* httpConnection = internetSession.GetHttpConnection(strServerIP,intServerPort); //获得链接CHttpFile* httpFile = httpConnection->OpenRequest(CHttpConnection::HTTP_VERB_PUT,strRemoteFile,NULL,0,NULL, NULL,INTERNET_FLAG_DONT_CACHE); //发送请求

...

httpFile->SendRequestEx(&BufferIn,NULL,HSR_INITIATE,0);

注意倒数第二句的CHttpConnection::HTTP_VERB_PUT, 表示程序将采用http的put协议上传文件.

再看post协议,这个东东如果只涉及文本还是比较简单的,可以直接post过去,不用构造表单. 但是一旦需要上传文件, 就需要用http和mime的两层封装了. 封装需要对http头和mime标识做一些了解,很恶心=,=. 最需要注意的一点, 在最后SendRequestEx的时候, 传递的参数是文件的字节数,这个字节数应该是所要上传的文件和http头以及mime头的字节总数! 否则即使CLIENT端不出错, server也得不到正确结果的!

也来看看代码吧:

CInternetSession internetSession("my session"); //定义session

CHttpConnection* httpConnection=internetSession.GetHttpConnection(strServerIP,intServerPort); //获得链接

CHttpFile* httpFile = httpConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST,strRemoteFile,NULL,0,NULL, NULL,INTERNET_FLAG_DONT_CACHE); //发送请求

...

httpFile->SendRequestEx(dwTotalRequestLength, HSR_SYNC | HSR_INITIATE);

随便说说,post协议俺用baidu搜了许久,找到了一个类似的程序,研究了许久搞不定.. 后来目有办法, google一个外文论坛, 拜读了某牛人的大作后,终于弄清楚了~ 看来以后还是要多啃鸟文啊..

附上源代码:

put协议:

UpLoadFile::UpLoadFile(void)

{

}

UpLoadFile::~UpLoadFile(void)

{

}

BOOL UpLoadFile::UseHttpSendReqEx(CHttpFile* httpFile, DWORD dwPostSize,CString strLocalFile)

{

try

{

DWORD dwRead,dwRet;

BYTE* buffer;

TRACE("Local file:%sn",strLocalFile);

FILE* fLocal;

if((fLocal=fopen(strLocalFile,"rb"))==NULL)

{

TRACE("Can't open the file:%s,maybe it doesn't exist!n",strLocalFile);

return false;

}

fseek(fLocal,0L,SEEK_END);

dwRead=ftell(fLocal);

rewind(fLocal);

buffer=(BYTE *)malloc(dwRead);

if(!buffer){

TRACE("not enough memory!n");

return false;

}

TRACE("length of file:%dn",dwRead);

dwRead=fread(buffer,1,dwRead,fLocal);

dwPostSize=dwRead;

INTERNET_BUFFERS BufferIn;

DWORD dwBytesWritten;

BOOL bRet;

BufferIn.dwStructSize = sizeof( INTERNET_BUFFERS ); // Must be set or error will occur

BufferIn.Next = NULL;

BufferIn.lpcszHeader = NULL;

BufferIn.dwHeadersLength = 0;

BufferIn.dwHeadersTotal = 0;

BufferIn.lpvBuffer = NULL;

BufferIn.dwBufferLength = 0;

BufferIn.dwBufferTotal = dwPostSize; // This is the only member used other than dwStructSize BufferIn.dwOffsetLow = 0;

BufferIn.dwOffsetHigh = 0;

httpFile->SendRequestEx(&BufferIn,NULL,HSR_INITIATE,0);

//httpFile->SendRequestEx(dwPostSize);

httpFile->Write( buffer, dwPostSize);

if(!httpFile->EndRequest(0,0,0))

{

TRACE( "Error on HttpEndRequest %lu n", GetLastError());

return FALSE;

}

fclose(fLocal);

free(buffer);

return TRUE;

}

catch (CInternetException* pEx)

{

//catch errors from WinInet

}

return FALSE;

}

BOOL UpLoadFile::Upload(CString strLocalFile,CString strServerIP,CString strServerPort,CString strRemoteFile)

{

try

{

DWORD dwPostSize=0;

INTERNET_PORT intServerPort=atoi(strServerPort);

CInternetSession internetSession("my session");

CHttpConnection* httpConnection = internetSession.GetHttpConnection(strServerIP,intServerPort);

if(httpConnection == NULL)

{

TRACE( "Failed to connectn" );

return FALSE;

}

CHttpFile* httpFile = httpConnection->OpenRequest(CHttpConnection::HTTP_VERB_PUT,strRemoteFile,NULL,0,NULL, NULL,INTERNET_FLAG_DONT_CACHE);

//CHttpFile* httpFile = httpConnection->OpenRequest(CHttpConnection::HTTP_VERB_PUT,strRemoteFile);

if(httpFile == NULL)

{

TRACE( "Failed to open request handlen" );

return FALSE;

}

if(UseHttpSendReqEx(httpFile, dwPostSize,strLocalFile))

{

TRACE( "nSend Finished.n" );

httpFile->Close();

httpConnection->Close();

internetSession.Close();

return TRUE;

}

httpFile->Close();

httpConnection->Close();

internetSession.Close();

}

catch (CInternetException* pEx)

{

//catch errors from WinInet

}

return FALSE;

}

post协议:

bool CVoiceXCtrl::UploadPCM()

{

TCHAR tempFilePath[MAX_PATH];

tempFilePath[0] = 0;

GetEnvironmentVariable(_T("ProgramFiles"), tempFilePath, MAX_PATH); if (tempFilePath[0] == 0)

{

strcpy(tempFilePath, "C:\Program Files");

}

strncat(tempFilePath, "\VoiceX\upload.pcm", MAX_PATH);

monWave.Save(tempFilePath);

int startp = m_StandardWavURL.ReverseFind('/');

int namelen = m_StandardWavURL.GetLength()-startp-1;

CString pcmname = m_StandardWavURL.Mid(startp+1,namelen);

CString defServerName ="https://www.360docs.net/doc/674478980.html,";

CString defObjectName ="/upload/upload.jsp";

// USES_CONVERSION;

CInternetSession Session;

CHttpConnection *pHttpConnection = NULL;

INTERNET_PORT nPort = 8090;

CFile fTrack;

CHttpFile* pHTTP;

CString strHTTPBoundary;

CString strPreFileData;

CString strPostFileData;

DWORD dwTotalRequestLength;

DWORD dwChunkLength;

DWORD dwReadLength;

DWORD dwResponseLength;

TCHAR szError[MAX_PATH];

void* pBuffer;

LPSTR szResponse;

CString strResponse;

BOOL bSuccess = TRUE;

CString strDebugMessage;

if (FALSE == fTrack.Open(tempFilePath, CFile::modeRead | CFile::shareDenyWrite))

{

AfxMessageBox(_T("Unable to open the file."));

return FALSE;

}

CString strFileName = "upload.pcm";

int iRecordID = 1;

strHTTPBoundary = _T("IllBeVerySurprisedIfThisTurnsUp");

strPreFileData = MakePreFileData(strHTTPBoundary, pcmname, iRecordID);

strPostFileData = MakePostFileData(strHTTPBoundary);

AfxMessageBox(strPreFileData);

AfxMessageBox(strPostFileData);

dwTotalRequestLength = strPreFileData.GetLength() + strPostFileData.GetLength() + fTrack.GetLength();

dwChunkLength = 64 * 1024;

pBuffer = malloc(dwChunkLength);

if (NULL == pBuffer)

{

return FALSE;

}

try

{

pHttpConnection = Session.GetHttpConnection(defServerName,nPort);

pHTTP = pHttpConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST, _T("/upload/upload.jsp"));

pHTTP->AddRequestHeaders(MakeRequestHeaders(strHTTPBoundary));

pHTTP->SendRequestEx(dwTotalRequestLength, HSR_SYNC | HSR_INITIATE);

#ifdef _UNICODE

pHTTP->Write(W2A(strPreFileData), strPreFileData.GetLength());

#else

pHTTP->Write((LPSTR)(LPCSTR)strPreFileData, strPreFileData.GetLength());

#endif

dwReadLength = -1;

while (0 != dwReadLength)

strDebugMessage.Format(_T("%u / %un"), fTrack.GetPosition(), fTrack.GetLength()); TRACE(strDebugMessage);

dwReadLength = fTrack.Read(pBuffer, dwChunkLength);

if (0 != dwReadLength)

{

pHTTP->Write(pBuffer, dwReadLength);

}

}

#ifdef _UNICODE

pHTTP->Write(W2A(strPostFileData), strPostFileData.GetLength());

#else

pHTTP->Write((LPSTR)(LPCSTR)strPostFileData, strPostFileData.GetLength());

#endif

pHTTP->EndRequest(HSR_SYNC);

dwResponseLength = pHTTP->GetLength();

while (0 != dwResponseLength)

{

szResponse = (LPSTR)malloc(dwResponseLength + 1);

szResponse[dwResponseLength] = '';

pHTTP->Read(szResponse, dwResponseLength);

strResponse += szResponse;

free(szResponse);

dwResponseLength = pHTTP->GetLength();

}

AfxMessageBox(strResponse);

}

catch (CException* e)

{

e->GetErrorMessage(szError, MAX_PATH);

e->Delete();

AfxMessageBox(szError);

bSuccess = FALSE;

}

pHTTP->Close();

delete pHTTP;

fTrack.Close();

if (NULL != pBuffer)

{

free(pBuffer);

}

return bSuccess;

}

CString CVoiceXCtrl::MakeRequestHeaders(CString& strBoundary)

{

CString strFormat;

CString strData;

strFormat = _T("Content-Type: multipart/form-data; boundary=%srn");

strData.Format(strFormat, strBoundary);

return strData;

}

CString CVoiceXCtrl::MakePreFileData(CString& strBoundary, CString& strFileName, int iRecordID)

{

CString strFormat;

CString strData;

strFormat += _T("--%s");

strFormat += _T("rn");

strFormat += _T("Content-Disposition: form-data; name="recordid"");

strFormat += _T("rnrn");

strFormat += _T("%i");

strFormat += _T("rn");

strFormat += _T("--%s");

strFormat += _T("rn");

strFormat += _T("Content-Disposition: form-data; name="trackdata"; filename="%s""); strFormat += _T("rn");

strFormat += _T("Content-Type: audio/wav");

strFormat += _T("rn");

strFormat += _T("Content-Transfer-Encoding: binary");

strFormat += _T("rnrn");

strData.Format(strFormat, strBoundary, iRecordID, strBoundary, strFileName);

return strData;

}

CString CVoiceXCtrl::MakePostFileData(CString& strBoundary)

{

CString strFormat;

CString strData;

strFormat = _T("rn");

strFormat += _T("--%s");

strFormat += _T("rn");

strFormat += _T("Content-Disposition: form-data; name="submitted""); strFormat += _T("rnrn");

strFormat += _T("hello");

strFormat += _T("rn");

strFormat += _T("--%s--");

strFormat += _T("rn");

strData.Format(strFormat, strBoundary, strBoundary);

return strData;

}

ABAP-本地文件上载到SAP 服务器

DATA: fname TYPE rlgrap-filename, ftype TYPE rlgrap-filetype, fsize TYPE i. DATA: fname_p TYPE string, fname_n TYPE string. DATA: sfname_p TYPE string . DATA: sfname LIKE rcgiedial-iefile. sfname_p = './'. DATA: r(1) TYPE c. DATA: data_tab LIKE rcgrepfile OCCURS 10 WITH HEADER LINE. DATA: lines TYPE i. CALL FUNCTION 'UPLOAD' EXPORTING filename = 'c:/' filetype = 'BIN' filetype_no_change = 'X' IMPORTING filesize = fsize act_filename = fname act_filetype = ftype TABLES data_tab = data_tab EXCEPTIONS conversion_error = 1 invalid_table_width = 2 invalid_type = 3. fname_n = fname. DO. SPLIT fname_n AT '/' INTO fname_p fname_n. SEARCH fname_n FOR '/'. IF sy-subrc = 4. EXIT.

ENDIF. ENDDO. fname_p = fname. SHIFT fname_p RIGHT DELETING TRAILING fname_n. SHIFT fname_p LEFT DELETING LEADING space. CONCATENATE sfname_p fname_n INTO sfname. DESCRIBE TABLE data_tab LINES lines. CALL FUNCTION 'C13Z_RAWDATA_WRITE' EXPORTING i_file = sfname i_file_size = fsize i_lines = lines TABLES i_rcgrepfile_tab = data_tab EXCEPTIONS no_permission = 1 open_failed = 2 OTHERS = 3. IF sy-subrc NE 0. MESSAGE i000(znyj13) WITH 'UPLOAD SUCC'. ENDIF. WRITE: 'SY-SUBRC:', sy-subrc, / '上载的本地文件名:', (60) fname, / '上载的远程文件名:',(60) sfname, / '文件类型:', ftype, / '文件大小:', fsize. SKIP.

在WinForm中通过HTTP协议向服务器端上传文件

在WinForm中通过HTTP协议向服务器端上传文件相信用https://www.360docs.net/doc/674478980.html,写一个上传文件的网页大家都会写但是有没有人想过通过在WinForm中通过HTTP协议上传文件呢有些人说要向服务器端上传文件用FTP协议不是很简单吗效率又高为什么还要使用HTTP协议那么麻烦呢这里面有几个原因1FTP服务器的部署相对麻烦还要设置权限权限设置不对还会惹来一系列的安全问题。2如果双方都还有防火墙又不想开发FTP相关的一些端口时HTTP就会大派用场就像WEB Services能穿透防火墙一样。3其他的...还在想呢... 但是使用HTTP也有他的一些问题例如不能断点续传大文件上传很难速度很慢所以HTTP协议上传的文件大小不应该太大。说了这么多原归正传一般来说在Winform里通过HTTP 上传文件有几种可选的方法1前面提到的Web Services就是一种很好的方法通过编写一个WebMethod包含有byte 类型的参数然后调用Web Services的方法文件内容就会以Base64编码传到服务器上然后重新保存即可。WebMethod public void UploadFilebyte contentstring filename... Stream sw new StreamWriter... sw.Close 当然这种通过Base64编码的方法效率比较低那么可以采用WSE支持附件并以2进制形式传送效率会更高。2除了通过WebService另外一种更简单的方法就是通过WebClient或者HttpWebRequest来模拟HTTP的POST动作来实现。这时候首先需要编写一个https://www.360docs.net/doc/674478980.html,

用ACCESS向ftp服务器上传文件

用ACCESS向ftp服务器上传文件 用API调用: '声明: Private Declare Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" _ (ByVal sAgent As String, ByVal lAccessType As Long, ByVal sProxyName As String, _ ByVal sProxyBypass As String, ByVal lFlags As Long) As Long Private Declare Function InternetConnect Lib "wininet.dll" Alias "InternetConnectA" _ (ByVal hInternetSession As Long, ByVal sServerName As String, _ ByVal nServerPort As Integer, ByVal sUsername As String, _ ByVal sPassword As String, ByVal lService As Long, _ ByVal lFlags As Long, ByVal lContext As Long) As Long Private Declare Function FtpGetFile Lib "wininet.dll" Alias "FtpGetFileA" _ (ByVal hFtpSession As Long, ByVal lpszRemoteFile As String, _ ByVal lpszNewFile As String, ByVal fFailIfExists As Boolean, _ ByVal dwFlagsAndAttributes As Long, ByVal dwFlags As Long, _ ByVal dwContext As Long) As Boolean Private Declare Function FtpPutFile Lib "wininet.dll" Alias "FtpPutFileA" _ (ByVal hFtpSession As Long, ByVal lpszLocalFile As String, _ ByVal lpszRemoteFile As String, ByVal dwFlags As Long, _ ByVal dwContext As Long) As Boolean Private Declare Function InternetCloseHandle Lib "wininet.dll" (ByVal hInet As Long) As Integer '函数 Private Function UpLoadFile(ByVal LocateFile As String, ByVal RemoteFile As String) As

goAhead上实现文件上传到嵌入式Web服务器上

goAhead上实现文件上传到嵌入式Web服务器上 本文内容概要:详细描述了在goAhead 2.5上如何实现文件上传(上传文件)到服务器端的功能。 开发环境: 宿主机:Windows XP; 虚拟机:Ubuntu 9.10; 交叉编译器:arm-uclibc-gcc(arm-linux-gcc-4.3.2可以顺利编译通过)——————————————————————————————————— 1. 说明 最近调试web文件上传到服务器功能,但在调试时,处理函数总是获取不到文件路径,百思不得其解,查了网上许多文章,但大多提到的是前端文件上传的原理、实现方式等,而未提供服务器端处理的实现(利用C函数实现)。此外,由于对web不了解,花了些时间研究web程序。 2. goAhead实现文件上传的方法 总得来说,goAhead上实现文件上传功能是比较容易的。因为有现成的代码可用,稍微移植下即可。 2.1 实现原理 使用html form即表单提交文件上传请求,web服务器核心处理接收客户端Post过来的文件数据(注意post的是二进制数据),最后,web服务器把接收到文件数据以二进制格式写到服务器本端存储系统。 2.2 前端设计 前端设计比较简单,就是设计一个form,type属性为file,本人是在goAhead-2.5附带的wwwdemo的asptest.asp网页上增加了一个这样的form。 1. 2. 3. 4. 5.