SophiaFramework UNIVERSE 5.3 |
The HTTP client can be implemented by taking the following procedures with the SFXHTTPConnection class.
Setting of the MIF file | |
---|---|
To use the SFXHTTPConnection class, the web access or network privilege option must be turned on in the MIF file's setting. |
Limitation on the HTTP communication in BREW 2.0 / 2.1 | |
---|---|
In case of the HTTP communication in BREW 2.0 / 2.1, data that is greater than or equals 1536 / 65536 bytes respectively cannot be sent. In this case, you have to divide data into several segments and send them or send data using the SFXTCPSocket / SFXSSLSocket class ( BREW API ISocket interface). |
The below is the code to read text data from the HTTP response body obtained using the GET method and display them on BREW Output Window.
Example 16.5. Reading text data using the GET method
// The _http variable is defined as class member variable since used in the callback function class MyClass { private: SFXHTTPConnection _http; SFXAnsiStringStreamReader _reader; SFXAnsiString _string; public: Void Start(Void); Void SaveToFile(SFXPathConstRef path, SFXAnsiStringConstRef string); XALLBACK_DECLARE_SFXHTTPCONNECTION(OnConnect) XALLBACK_DECLARE_SFXANSISTRINGSTREAMREADER(OnFetch) }; Void MyClass::Start(Void) { SFCError error(SFERR_NO_ERROR); // HTTP connection using GET method // * there is no need to specify "GET" in calling the SFXHTTPConnection::SetMethod function // open the HTTP connection if ((error = _http.Open()) == SFERR_NO_ERROR) { // start to connect #if 1 // in case of HTTP connection // connect to the Web server // * the connection result will be notified to the OnConnect function if ((error = _http.Connect("http://www.example.com/", XALLBACK_INTERNAL(OnConnect))) == SFERR_NO_ERROR) { #else // in case of HTTPS connection // set trust mode if necessary _http.SetTrustMode(SSL_TRUST_MODE_FAIL); // connect to the Web server // * the connection result will be notified to the OnConnect function if ((error = _http.Connect("https://www.example.com/", XALLBACK_INTERNAL(OnConnect))) == SFERR_NO_ERROR) { #endif TRACE(">> connecting..."); } } if (error != SFERR_NO_ERROR) { // if an error occurs // close the HTTP connection _http.Close(); } return; } // callback function notified of the connection result XALLBACK_IMPLEMENT_SFXHTTPCONNECTION(MyClass, OnConnect, error) { TRACE(">> connected... : %d", error); if (error == SFERR_NO_ERROR) { // check response code TRACE(">> result code : %d", _http.GetResultCode()); if (_http.GetResultCode() == 200) { // get input stream for reading data from HTTP response body if ((error = _http.GetStreamReader(1024, &_reader)) == SFERR_NO_ERROR) { // perform fetch: read next data from HTTP response body into input stream buffer // * the fetch result will be notified to the OnFetch function if ((error = _reader.Fetch(XALLBACK_INTERNAL(OnFetch))) == SFERR_NO_ERROR) { TRACE(">> fetching..."); } } } else { error = SFERR_INVALID_STATE; } } if (error != SFERR_NO_ERROR) { // if an error occurs // close the HTTP connection _http.Close(); } return; } // callback function notified of the fetch result XALLBACK_IMPLEMENT_SFXANSISTRINGSTREAMREADER(MyClass, OnFetch, error) { SFXAnsiString string; TRACE(">> fetched... : %d", error); if (error == SFERR_NO_ERROR) { // read data from input stream buffer to the string variable if ((error = _reader.ReadSFXAnsiString(&string)) == SFERR_NO_ERROR) { // add the string variable to the _string variable if ((error = _string.Add(string)) == SFERR_NO_ERROR) { // check whether or not data is still remaining if (_reader.Ends()) { // since all data have been read, display them on BREW Output Window TRACE("--------"); TRACE("%s", _string.GetCString()); // * TRACE("--------"); // release resource explicitly // release input stream for reading data from HTTP response body _reader.Release(); // close the HTTP connection _http.Close(); } else { // perform fetch: read next data from HTTP response body into input stream buffer // * the fetch result will be notified to the OnFetch function error = _reader.Fetch(XALLBACK_INTERNAL(OnFetch)); } } } } if (error != SFERR_NO_ERROR) { // if an error occurs // release input stream for reading data from HTTP response body _reader.Release(); // close the HTTP connection _http.Close(); } return; }
To save the data in the file, call the following function at the "*" position of above code.
Example 16.6. Save the read data in the file
// save string in file (path : file path) Void MyClass::SaveToFile(SFXPathConstRef path, SFXAnsiStringConstRef string) { SFCError error; SFXFile file; // file to save data SFXAnsiStringStreamWriter writer; // output stream for writing data into file // open the file in the read and write mode if ((error = file.OpenReadWrite(path)) == SFERR_NO_ERROR) { // get output stream for writing data into file if ((error = file.GetStreamWriter(string.GetLength(), &writer)) == SFERR_NO_ERROR) { // write data from the string variable into output stream buffer writer.WriteSFXAnsiString(string); // perform flush: write data from output stream buffer into file actually // * data will not be written into file unless Flush function is called explicitly error = writer.Flush(); // release output stream for writing data into file writer.Release(); } // close the file file.Close(); } if (error != SFERR_NO_ERROR) { // error handling } return; }
SFXHTTPConnection Instance | |
---|---|
If the SFXHTTPConnection instance is released before the callback function is called, program will not work correctly. |
The below is the code to read text data from the HTTP response body obtained using the POST method and display them on BREW Output Window.
Example 16.7. Reading text data using the POST method
// SFXHTTPConnection instance is defined as class member variable for the callback function class MyClass { private: SFXHTTPConnection _http; SFXAnsiStringStreamReader _reader; SFXAnsiString _string; public: Void Start(Void); XALLBACK_DECLARE_SFXHTTPCONNECTION(OnConnect) XALLBACK_DECLARE_SFXANSISTRINGSTREAMREADER(OnFetch) }; Void MyClass::Start(Void) { SFXAnsiStringStreamWriter writer; SFXAnsiString message; SFCError error(SFERR_NO_ERROR); unused(environment); // HTTP connection using POST method // * it is necessary to specify "POST" in calling the SFXHTTPConnection::SetMethod function // open the HTTP connection if ((error = _http.Open()) == SFERR_NO_ERROR) { // message: content of HTTP request body to set message = "abcdefghijklmnopqrstuvwxyz"; // get output stream for writing data into HTTP request body // * the stream buffer is variable since the size argument is not specified if ((error = _http.GetStreamWriter(&writer)) == SFERR_NO_ERROR) { // write data from the message variable into output stream buffer // *1. the stream buffer will be expanded automatically depending on the size of data to write // *2. the write operation will finish by calling the WriteSFXAnsiString function once if ((error = writer.WriteSFXAnsiString(message)) == SFERR_NO_ERROR) { // perform flush: write data from output stream buffer into http request body actually // * data will not be written into http request body if Flush function is not called explicitly if ((error = writer.Flush()) == SFERR_NO_ERROR) { // set request method to POST if ((error = _http.SetMethod("POST")) == SFERR_NO_ERROR) { // start to connect #if 1 // in case of HTTP connection // connect to the Web server // * the connection result will be notified to the OnConnect function if ((error = _http.Connect("http://www.example.com", XALLBACK_INTERNAL(OnConnect))) == SFERR_NO_ERROR) { #else // in case of HTTPS connection // set trust mode if necessary _http.SetTrustMode(SSL_TRUST_MODE_FAIL); // connect to the Web server // * the connection result will be notified to the OnConnect function if ((error = _http.Connect("https://www.example.com", XALLBACK_INTERNAL(OnConnect))) == SFERR_NO_ERROR) { #endif TRACE(">> connecting..."); } } } } } } if (error != SFERR_NO_ERROR) { // if an error occurs // close the HTTP connection _http.Close(); } return; } // callback function notified of the connection result XALLBACK_IMPLEMENT_SFXHTTPCONNECTION(MyClass, OnConnect, error) { TRACE(">> connected... : %d", error); if (error == SFERR_NO_ERROR) { // examine response code TRACE(">> result code : %d", _http.GetResultCode()); if (_http.GetResultCode() == 200) { // get input stream for reading data from HTTP response body if ((error = _http.GetStreamReader(1024, &_reader)) == SFERR_NO_ERROR) { // perform fetch: read data from HTTP request body into input stream buffer // * the fetch result will be notified to the OnFetch function if ((error = _reader.Fetch(XALLBACK_INTERNAL(OnFetch))) == SFERR_NO_ERROR) { TRACE(">> fetching..."); } } } else { error = SFERR_INVALID_STATE; } } if (error != SFERR_NO_ERROR) { // if an error occurs // close the HTTP connection _http.Close(); } return; } // callback function notified of the fetch result XALLBACK_IMPLEMENT_SFXANSISTRINGSTREAMREADER(MyClass, OnFetch, error) { SFXAnsiString string; TRACE("> fetched... : %d", error); if (error == SFERR_NO_ERROR) { // read data from input stream buffer into the string variable if ((error = _reader.ReadSFXAnsiString(&string)) == SFERR_NO_ERROR) { // add the string variable to the _string variable if ((error = _string.Add(string)) == SFERR_NO_ERROR) { // check whether or not data is still remaining if (_reader.Ends()) { // since all data have been read, display them on BREW Output Window TRACE("--------"); TRACE("%s", _string.GetCString()); TRACE("--------"); // release resources explicitly // release input stream for reading data from HTTP response body _reader.Release(); // close the HTTP connection _http.Close(); } else { // perform fetch: read data from HTTP response body into input stream buffer // * the fetch result will be notified to the OnFetch function error = _reader.Fetch(XALLBACK_INTERNAL(OnFetch)); } } } } if (error != SFERR_NO_ERROR) { // if an error occurs // release input stream for reading data from HTTP response body _reader.Release(); // close the HTTP connection _http.Close(); } return; }
The below is the code to read the binary data from the HTTP response body and save them into the file as it they are.
Example 16.8. Reading the binary data from the HTTP response body
// The _http variable is defined as class member variable since used in the callback function class MyClass { private: SFXHTTPConnection _http; SFXFile _file; SFXBinaryStreamReader _reader; // input stream for reading data from HTTP response body SFXBinaryStreamWriter _writer; // output stream for writing data into file SFXBuffer _buffer; // variable for storing read data SFXBuffer _tempbuffer; // variable for storing read data temporarily UInt32 _bufferSize; // buffer size of output stream for writing data in file public: Void Start(Void); XALLBACK_DECLARE_SFXHTTPCONNECTION(OnConnect) XALLBACK_DECLARE_SFXANSISTRINGSTREAMREADER(OnFetch) }; Void MyClass::Start(Void) { SFCError error(SFERR_NO_ERROR); // HTTP connection using GET method // * there is no need to specify "GET" in calling the SFXHTTPConnection::SetMethod function // open the HTTP connection if ((error = _http.Open()) == SFERR_NO_ERROR) { if 1 // in case of HTTP connection // connect to the Web server // * the connection result will be notified to the OnConnect function if ((error = _http.Connect("http://www.example.com", XALLBACK_INTERNAL(OnConnect))) == SFERR_NO_ERROR) { #else // in case of HTTPS connection // set trust mode if necessary _http.SetTrustMode(SSL_TRUST_MODE_FAIL); // connect to the Web server // * the connection result will be notified to the OnConnect function if ((error = _http.Connect("https://www.example.com", XALLBACK_INTERNAL(OnConnect))) == SFERR_NO_ERROR) { #endif TRACE(">> connecting..."); } if (error != SFERR_NO_ERROR) { // if an error occurs // close the HTTP connection _http.Close(); } } return; } // callback function notified of the connection result XALLBACK_IMPLEMENT_SFXHTTPCONNECTION(MyClass, OnConnect, error) { TRACE(">> connected... : %d", error); if (error == SFERR_NO_ERROR) { // check response code TRACE(">> result code : %d", _http.GetResultCode()); if (_http.GetResultCode() == 200) { // get input stream for reading data from HTTP response body if ((error = _http.GetStreamReader(_bufferSize, &_reader)) == SFERR_NO_ERROR) { // perform fetch: read data from HTTP response body into input stream buffer // * the fetch result will be notified to the OnFetch function if ((error = _reader.Fetch(XALLBACK_INTERNAL(OnFetch))) == SFERR_NO_ERROR) { TRACE(">> fetching..."); } } } else { error = SFERR_INVALID_STATE; } } // prepare to write data from HTTP response body to file if (error == SFERR_NO_ERROR) { // set buffer size _bufferSize = 1024; // set the size of _tempbuffer to 1024 if ((error = _tempbuffer.SetSize(_bufferSize)) == SFERR_NO_ERROR) { // open file in read/write mode if ((error = _file.OpenReadWrite(SFXPath("/example.dat"))) == SFERR_NO_ERROR) { // get output stream for writing data into file error = _file.GetStreamWriter(_bufferSize, &_writer); } } } if (error != SFERR_NO_ERROR) { // if an error occurs // release input stream for reading data from HTTP response body _reader.Release(); // close the HTTP connection _http.Close(); // release output stream for writing data into file _writer.Release(); // close the file _file.Close(); } return; } // callback function notified of the fetch result XALLBACK_IMPLEMENT_SFXANSISTRINGSTREAMREADER(MyClass, OnFetch, error) { TRACE(">> fetched... : %d", error); if (error == SFERR_NO_ERROR) { // set the size of _tempbuffer to readable size _tempbuffer.SetSize(_reader.GetReadableSize()); // read data from input stream buffer into the _tempbuffer variable if ((error = _reader.Read(&_tempbuffer)) == SFERR_NO_ERROR) { // write data from the _tempbuffer variable into output stream buffer if ((error = _writer.Write(_tempbuffer)) == SFERR_NO_ERROR) { // perform flush: write data from output stream buffer into file actually // * data will not be written into file if Flush function is not called explicitly if ((error = _writer.Flush()) == SFERR_NO_ERROR) { // add the _tempbuffer variable to the _buffer variable if ((error = _buffer.Add(_tempbuffer)) == SFERR_NO_ERROR) { // check whether or not data is still remaining if (_reader.Ends()) { // since all data have been read, display them on BREW Output Window TRACE("--------"); TRACE("%s", _buffer.GetBuffer()); TRACE("--------"); // release resources explicitly // release input stream for reading data from HTTP response body _reader.Release(); // close the HTTP connection _http.Close(); // release output stream for writing data into file _writer.Release(); // close the file _file.Close(); } else { // perform fetch: read next data from HTTP response body into input stream buffer // * the fetch result will be notified to the OnFetch function error = _reader.Fetch(XALLBACK_INTERNAL(OnFetch)); } } } } } } if (error != SFERR_NO_ERROR) { // if an error occurs // release input stream for reading data from HTTP response body _reader.Release(); // close the HTTP connection _http.Close(); // release output stream for writing data into file _writer.Release(); // close the file _file.Close(); } return; }
The below is the code to upload the file data to the Web server.
In the method to use the SetRequestContentToFileData function, data will be uploaded using the HTTP communication after all data is read into heap as the HTTP request body from the file. Therefore, the file size that can be uploaded is limited to the mobile phone's memory size.
In the method to use the SetRequestContentToFileStorage function, the file storage will be set as the HTTP request body using the SFXHTTPConnection::SetRequestContent function. In this method, since file data will be sent by streaming, the file size that can be uploaded does not depend on the mobile phone's memory size.
Note | |
---|---|
The SFXHTTPConnection::SetRequestContent function is effective in SophiaFramework UNIVERSE 5.1.11 or above. |
Caution | |
---|---|
In case of the HTTP communication in BREW 2.0 / 2.1, due to the BREW bug, the file whose size is greater than or equals 1536 / 65536 bytes respectively cannot be uploaded. In this case, you have to divide the file into several segments and upload them or upload the file using the SFXTCPSocket / SFXSSLSocket class ( BREW API ISocket interface). |
Example 16.9. Upload the file through the HTTP communication
#define SOURCE_FILE_PATH "/data.txt" // file to upload // The _http variable is defined as class member variable since used in the callback function class MyClass { private: SFXHTTPConnection _http; // HTTP connection SFXAnsiStringStreamReader _reader; // input stream for reading data from HTTP response body SFXAnsiString _string; // content of the read HTTP response body public: SFCError Start(Void); SFCError SetRequestContentToFileData(SFXFileRef file); SFCError SetRequestContentToFileStorage(SFXFileRef file); XALLBACK_DECLARE_SFXHTTPCONNECTION(OnConnect) XALLBACK_DECLARE_SFXANSISTRINGSTREAMREADER(OnFetch) }; SFCError MyClass::Start(Void) { SFXFile file; SFCError error(SFERR_NO_ERROR); // open the HTTP connection if ((error = _http.Open()) == SFERR_NO_ERROR) { // open the file if ((error = file.OpenReadOnly(SFXPath(SOURCE_FILE_PATH))) == SFERR_NO_ERROR) { #if 1 if ((error = SetRequestContentToFileData(file)) == SFERR_NO_ERROR) { #else if ((error = SetRequestContentToFileStorage(file)) == SFERR_NO_ERROR) { #endif // close the file file.Close(); if (error == SFERR_NO_ERROR) { // if succeeds to set the HTTP request body: // set request method to POST // * in case of the POST method, not only text but binary can be sent if ((error = _http.SetMethod("POST")) == SFERR_NO_ERROR) { // start to connect #if 1 // in case of HTTP connection // connect to the Web server // * the connection result will be notified to the OnConnect function if ((error = _http.Connect("http://www.example.com", XALLBACK_INTERNAL(OnConnect))) == SFERR_NO_ERROR) { #else // in case of HTTPS connection // set trust mode if necessary _http.SetTrustMode(SSL_TRUST_MODE_FAIL); // connect to the Web server // * the connection result will be notified to the OnConnect function if ((error = _http.Connect("https://www.example.com", XALLBACK_INTERNAL(OnConnect))) == SFERR_NO_ERROR) { #endif TRACE(">> connecting..."); } } } } } } if (error != SFERR_NO_ERROR) { // if an error occurs // close the file file.Close(); // close the HTTP connection _http.Close(); } return error; } // method to set the HTTP request body after the content of the HTTP request body is made on heap SFCError MyClass::SetRequestContentToFileData(SFXFileRef file) { SFXBinaryStreamReader reader; // input stream for reading data from file SFXBinaryStreamWriter writer; // out stream for writing data into HTTP request body SFXBuffer buffer; // buffer to store data read from file SFCError error(SFERR_NO_ERROR); // error value // get out stream for writing data into HTTP request body if ((error = _http.GetStreamWriter(1024, &writer)) == SFERR_NO_ERROR) { // get input stream for reading data from file if ((error = file.GetStreamReader(1024, &reader)) == SFERR_NO_ERROR) { // copy data from file to HTTP request body while ((error == SFERR_NO_ERROR) && !reader.Ends()) { // * repeat the following processing until the end of the file is reached // perform fetch: read data from file into input stream buffer if ((error = reader.Fetch()) == SFERR_NO_ERROR) { // set the size of buffer to readable size if ((error = buffer.SetSize(reader.GetReadableSize())) == SFERR_NO_ERROR) { // read data from input stream buffer into the buffer variable if ((error = reader.Read(&buffer)) == SFERR_NO_ERROR) { // write data from the buffer variable into output stream buffer if ((error = writer.Write(buffer)) == SFERR_NO_ERROR) { // perform flush: write data from output stream buffer into HTTP request body actually // * data will not be written into HTTP request body if Flush function is not called explicitly error = writer.Flush(); } } } } } } } // release input stream for reading data from file reader.Release(); // release out stream for writing data into HTTP request body writer.Release(); return error; } // method to set the HTTP request body to the file storage SFCError MyClass::SetRequestContentToFileStorage(SFXFileRef file) { UInt32 size; SFCError error(SFERR_NO_ERROR); // get the file size if ((error = SFXFile::GetSize(SFXPath(SOURCE_FILE_PATH), &size)) == SFERR_NO_ERROR) { // set the HTTP request body to the file storage and its size error = _http.SetRequestContent(file, size); } // you can describe as the below without the size argument instead of the above code // * in this case, the file size is automatically set as the size of the HTTP request body // error = _http.SetRequestContent(file); return error; } // callback function notified of the connection result XALLBACK_IMPLEMENT_SFXHTTPCONNECTION(MyClass, OnConnect, error) { TRACE(">> connected... : %d", error); if (error == SFERR_NO_ERROR) { // check response code TRACE(">> result code : %d", _http.GetResultCode()); if (_http.GetResultCode() == 200) { // get input stream for reading data from HTTP response body if ((error = _http.GetStreamReader(1024, &_reader)) == SFERR_NO_ERROR) { // perform fetch: read data from HTTP response body into input stream buffer // * the fetch result will be notified to the OnFetch function if ((error = _reader.Fetch(XALLBACK_INTERNAL(OnFetch))) == SFERR_NO_ERROR) { TRACE(">> fetching..."); } } } else { error = SFERR_INVALID_STATE; } } if (error != SFERR_NO_ERROR) { // If an error occurs // input stream for reading data from HTTP response body _reader.Release(); // close the HTTP connection _http.Close(); } return; } // callback function notified of the fetch result XALLBACK_IMPLEMENT_SFXANSISTRINGSTREAMREADER(MyClass, OnFetch, error) { SFXAnsiString string; TRACE(">> fetched... : %d", error); if (error == SFERR_NO_ERROR) { // read data from input stream buffer into the string variable if ((error = _reader.ReadSFXAnsiString(&string)) == SFERR_NO_ERROR) { // add the string variable to the _string variable if ((error = _string.Add(string)) == SFERR_NO_ERROR) { // check whether or not data is still remaining if (_reader.Ends()) { // since all data have been read, display them on BREW Output Window TRACE("--------"); TRACE("%s", _string.GetCString()); TRACE("--------"); // release resource explicitly _reader.Release(); _http.Close(); } else { // read next data from HTTP response body into input stream buffer // the fetch result will be notified to the OnFetch function error = _reader.Fetch(XALLBACK_INTERNAL(OnFetch)); } } } } if (error != SFERR_NO_ERROR) { // if an error occurs // release input stream for reading data from HTTP response body _reader.Release(); // close the HTTP connection _http.Close(); } return; }
The SetRequestContentToFileData function can be implemented using the memory storage(SFXMemory) and the SFXHTTPConnection::SetRequestContent function as follows:
Example 16.10. Another implementation of the SetRequestContentToFileData function
class MyClass { private: ... SFXMemory _memory; // memory storage ... public: .... }; SFCError MyClass::Start(Void) { ... if (error != SFERR_NO_ERROR) { // if an error occurs // close the memory _memory.Close(); // close the file file.Close(); // close the HTTP connection _http.Close(); } return error; } // method to set the HTTP request body using the memory storage SFCError MyClass::SetRequestContentToFileData(SFXFileRef file) { SFXBinaryStreamReader reader; // input stream for reading data from file SFXBinaryStreamWriter writer; // out stream for writing data into memory SFXBuffer buffer; // buffer to store data read from file SFCError error(SFERR_NO_ERROR); // error value // open the memory if ((error = _memory.Open()) == SFERR_NO_ERROR) { // get out stream for writing data into memory if ((error = _memory.GetStreamWriter(1024, &writer)) == SFERR_NO_ERROR) { // get input stream for reading data from file if ((error = file.GetStreamReader(1024, &reader)) == SFERR_NO_ERROR) { // copy data from file into memory while ((error == SFERR_NO_ERROR) && !reader.Ends()) { // * repeat the following processing until the end of the file is reached // perform fetch: read data from file into input stream buffer if ((error = reader.Fetch()) == SFERR_NO_ERROR) { // set the size of buffer to readable size if ((error = buffer.SetSize(reader.GetReadableSize())) == SFERR_NO_ERROR) { // read data from input stream buffer into the buffer variable if ((error = reader.Read(&buffer)) == SFERR_NO_ERROR) { // write data from the buffer variable into output stream buffer if ((error = writer.Write(buffer)) == SFERR_NO_ERROR) { // perform flush: write data from output stream buffer into memory // * data will not be written into HTTP request body if Flush function is not called explicitly error = writer.Flush(); } } } } } } } if (error == SFERR_NO_ERROR) { // set the HTTP request content to the memory and its size error = _http.SetRequestContent(_memory, _memory.GetSize()); // * the above can be described as "error = _http.SetRequestContent(_memory);" } // release input stream for reading data from file reader.Release(); // release out stream for writing data into memory writer.Release(); return error; } // callback function notified of the connection result XALLBACK_IMPLEMENT_SFXHTTPCONNECTION(MyClass, OnConnect, error) { TRACE(">> connected... : %d", error); // close the memory _memory.Close(); if (error == SFERR_NO_ERROR) { ... }
The below is the code to divide the file data into several segments and upload them to the Web server repeatedly.
Example 16.11. Upload the divided file segments through the HTTP communication
#define SOURCE_FILE_PATH "/data.txt" // file to upload #define SEGMENT_SIZE 1535 // segment size // The _http variable is defined as class member variable since used in the callback function class MyClass { private: SFXHTTPConnection _http; // HTTP connection SFXAnsiStringStreamReader _reader; // input stream for reading data from HTTP response body SFXAnsiString _string; // content of the read HTTP response body SFXFile _file; // file UInt32 _fileSize; // file size UInt32 _sentSize; // size of the sent data public: SFCError Start(Void); SFCError UploadFileSegment(Void); SFCError SetFileSegment(SFXFileRef file); XALLBACK_DECLARE_SFXHTTPCONNECTION(OnConnect) XALLBACK_DECLARE_SFXANSISTRINGSTREAMREADER(OnFetch) }; SFCError MyClass::Start(Void) { SFCError error(SFERR_NO_ERROR); // open the HTTP connection if ((error = _http.Open()) == SFERR_NO_ERROR) { // open the file if ((error = _file.OpenReadOnly(SFXPath(SOURCE_FILE_PATH))) == SFERR_NO_ERROR) { // get the file size if ((error = SFXFile::GetSize(SFXPath(SOURCE_FILE_PATH), &_fileSize)) == SFERR_NO_ERROR) { // set request method to POST // * in case of the POST method, not only text but binary can be sent if ((error = _http.SetMethod("POST")) == SFERR_NO_ERROR) { // upload the first segment error = UploadFileSegment(); } } } } if (error != SFERR_NO_ERROR) { // if an error occurs // close the file _file.Close(); // close the HTTP connection _http.Close(); } return error; } // upload the file segment SFCError MyClass::UploadFileSegment(Void) { SFCError error; // set the file segment if ((error = SetFileSegment(_file)) == SFERR_NO_ERROR) { // connect to the Web server // * the connection result will be notified to the OnConnect function if ((error = _http.Connect("http://www.example.com/cgi-bin/fileupload.cgi", XALLBACK_INTERNAL(OnConnect))) == SFERR_NO_ERROR) { TRACE(">> connecting..."); } } return error; } // set the file segment SFCError MyClass::SetFileSegment(SFXFileRef file) { UInt32 diff; // size of the remaining data: when it is less than or equals SFCError error(SFERR_NO_ERROR); // error value if (_sentSize + SEGMENT_SIZE < _fileSize) { _sentSize += SEGMENT_SIZE; // set the HTTP request body to the SEGMENT_SIZE of data from the current file pointer error = _http.SetRequestContent(file, SEGMENT_SIZE); } else { if (_fileSize > _sentSize) { diff = _fileSize - _sentSize; _sentSize = _fileSize; // set the HTTP request body to the diff size of data from the current file pointer error = _http.SetRequestContent(file, diff); } else { error = SFERR_FAILED; } } return error; } // callback function notified of the connection result XALLBACK_IMPLEMENT_SFXHTTPCONNECTION(MyClass, OnConnect, error) { TRACE(">> connected... : %d", error); if (error == SFERR_NO_ERROR) { // check response code TRACE(">> result code : %d", _http.GetResultCode()); if (_http.GetResultCode() == 200) { // get input stream for reading data from HTTP response body if ((error = _http.GetStreamReader(1024, &_reader)) == SFERR_NO_ERROR) { // perform fetch: read data from HTTP response body into input stream buffer // * the fetch result will be notified to the OnFetch function if ((error = _reader.Fetch(XALLBACK_INTERNAL(OnFetch))) == SFERR_NO_ERROR) { TRACE(">> fetching..."); } } } else { error = SFERR_INVALID_STATE; } } if (error != SFERR_NO_ERROR) { // if an error occurs // input stream for reading data from HTTP response body _reader.Release(); // close the file _file.Close(); // close the HTTP connection _http.Close(); } return; } // callback function notified of the fetch result XALLBACK_IMPLEMENT_SFXANSISTRINGSTREAMREADER(MyClass, OnFetch, error) { SFXAnsiString string; TRACE(">> fetched... : %d", error); if (error == SFERR_NO_ERROR) { // read data from input stream buffer into the string variable if ((error = _reader.ReadSFXAnsiString(&string)) == SFERR_NO_ERROR) { // add the string variable to the _string variable if ((error = _string.Add(string)) == SFERR_NO_ERROR) { // check whether or not data is still remaining if (_reader.Ends()) { // since all data have been read, display them on BREW Output Window TRACE("--------"); TRACE("%s", _string.GetCString()); TRACE("--------"); // release resource explicitly _reader.Release(); if (_sentSize == _fileSize) { // when all file segments have been uploaded: // close the file _file.Close(); // close the HTTP connection _http.Close(); } else { // when file segments to upload still exist: // upload the next file segment error = UploadFileSegment(); } _http.Close(); } else { // read next data from HTTP response body into input stream buffer // the fetch result will be notified to the OnFetch function error = _reader.Fetch(XALLBACK_INTERNAL(OnFetch)); } } } } if (error != SFERR_NO_ERROR) { // if an error occurs // input stream for reading data from HTTP response body _reader.Release(); // close the file _file.Close(); // close the HTTP connection _http.Close(); } return; }
Copyright(c) 2002 - 2024 Sophia Cradle Incorporated All Rights Reserved. |