- const wxChar *request;
-
- switch (req) {
- case wxHTTP_GET:
- request = wxT("GET");
- break;
- case wxHTTP_POST:
- request = wxT("POST");
- if ( GetHeader( wxT("Content-Length") ).IsNull() )
- SetHeader( wxT("Content-Length"), wxString::Format( wxT("%lu"), (unsigned long)m_post_buf.Len() ) );
- break;
- default:
- return false;
- }
-
- m_http_response = 0;
-
- // If there is no User-Agent defined, define it.
- if (GetHeader(wxT("User-Agent")).IsNull())
- SetHeader(wxT("User-Agent"), wxT("wxWidgets 2.x"));
-
- SaveState();
-
- // we may use non blocking sockets only if we can dispatch events from them
- SetFlags( wxIsMainThread() && wxApp::IsMainLoopRunning() ? wxSOCKET_NONE
- : wxSOCKET_BLOCK );
- Notify(false);
-
- wxString buf;
- buf.Printf(wxT("%s %s HTTP/1.0\r\n"), request, path.c_str());
- const wxWX2MBbuf pathbuf = wxConvLocal.cWX2MB(buf);
- Write(pathbuf, strlen(wxMBSTRINGCAST pathbuf));
- SendHeaders();
- Write("\r\n", 2);
-
- if ( req == wxHTTP_POST ) {
- Write(m_post_buf.mbc_str(), m_post_buf.Len());
- m_post_buf = wxEmptyString;
- }
-
- wxString tmp_str;
- m_perr = GetLine(this, tmp_str);
- if (m_perr != wxPROTO_NOERR) {
- RestoreState();
- return false;
- }
-
- if (!tmp_str.Contains(wxT("HTTP/"))) {
- // TODO: support HTTP v0.9 which can have no header.
- // FIXME: tmp_str is not put back in the in-queue of the socket.
- SetHeader(wxT("Content-Length"), wxT("-1"));
- SetHeader(wxT("Content-Type"), wxT("none/none"));
- RestoreState();
- return true;
- }
-
- wxStringTokenizer token(tmp_str,wxT(' '));
- wxString tmp_str2;
- bool ret_value;
-
- token.NextToken();
- tmp_str2 = token.NextToken();
-
- m_http_response = wxAtoi(tmp_str2);
-
- switch (tmp_str2[0u]) {
- case wxT('1'):
- /* INFORMATION / SUCCESS */
- break;
- case wxT('2'):
- /* SUCCESS */
- break;
- case wxT('3'):
- /* REDIRECTION */
- break;
- default:
- m_perr = wxPROTO_NOFILE;
+ const wxChar *request;
+
+ switch (req)
+ {
+ case wxHTTP_GET:
+ request = wxT("GET");
+ break;
+
+ case wxHTTP_POST:
+ request = wxT("POST");
+ // Content length must be correct, so always set, possibly
+ // overriding the value set explicitly by a previous call to
+ // SetHeader("Content-Length").
+ if ( !m_postBuffer.IsEmpty() )
+ {
+ wxString len;
+ len << m_postBuffer.GetDataLen();
+
+ SetHeader(wxS("Content-Length"), len);
+ }
+
+ // However if the user had explicitly set the content type, don't
+ // override it with the content type passed to SetPostText().
+ if ( !m_contentType.empty() && GetContentType().empty() )
+ SetHeader(wxS("Content-Type"), m_contentType);
+ break;
+
+ default:
+ return false;
+ }
+
+ m_http_response = 0;
+
+ // If there is no User-Agent defined, define it.
+ if ( GetHeader(wxT("User-Agent")).empty() )
+ SetHeader(wxT("User-Agent"), wxT("wxWidgets 2.x"));
+
+ // Send authentication information
+ if (!m_username.empty() || !m_password.empty()) {
+ SetHeader(wxT("Authorization"), GenerateAuthString(m_username, m_password));
+ }
+
+ SaveState();
+
+ // we may use non blocking sockets only if we can dispatch events from them
+ int flags = wxIsMainThread() && wxApp::IsMainLoopRunning() ? wxSOCKET_NONE
+ : wxSOCKET_BLOCK;
+ // and we must use wxSOCKET_WAITALL to ensure that all data is sent
+ flags |= wxSOCKET_WAITALL;
+ SetFlags(flags);
+ Notify(false);
+
+ wxString buf;
+ buf.Printf(wxT("%s %s HTTP/1.0\r\n"), request, path.c_str());
+ const wxWX2MBbuf pathbuf = buf.mb_str();
+ Write(pathbuf, strlen(pathbuf));
+ SendHeaders();
+ Write("\r\n", 2);
+
+ if ( req == wxHTTP_POST ) {
+ if ( !m_postBuffer.IsEmpty() )
+ Write(m_postBuffer.GetData(), m_postBuffer.GetDataLen());
+
+ m_postBuffer.Clear();
+ }
+
+ wxString tmp_str;
+ m_lastError = ReadLine(this, tmp_str);
+ if (m_lastError != wxPROTO_NOERR) {
+ RestoreState();
+ return false;
+ }
+
+ if (!tmp_str.Contains(wxT("HTTP/"))) {
+ // TODO: support HTTP v0.9 which can have no header.
+ // FIXME: tmp_str is not put back in the in-queue of the socket.
+ m_lastError = wxPROTO_NOERR;
+ SetHeader(wxT("Content-Length"), wxT("-1"));
+ SetHeader(wxT("Content-Type"), wxT("none/none"));
+ RestoreState();
+ return true;
+ }
+
+ wxStringTokenizer token(tmp_str,wxT(' '));
+ wxString tmp_str2;
+ bool ret_value;
+
+ token.NextToken();
+ tmp_str2 = token.NextToken();
+
+ m_http_response = wxAtoi(tmp_str2);
+
+ switch ( tmp_str2[0u].GetValue() )
+ {
+ case wxT('1'):
+ /* INFORMATION / SUCCESS */
+ break;
+
+ case wxT('2'):
+ /* SUCCESS */
+ break;
+
+ case wxT('3'):
+ /* REDIRECTION */
+ break;
+
+ default:
+ m_lastError = wxPROTO_NOFILE;
+ RestoreState();
+ return false;
+ }
+
+ m_lastError = wxPROTO_NOERR;
+ ret_value = ParseHeaders();