- wxChar *tmp_buf;
- wxChar buf[200]; // 200 is arbitrary.
- wxString tmp_str = path;
-
- // If there is no User-Agent defined, define it.
- if (GetHeader(wxT("User-Agent")).IsNull())
- SetHeader(wxT("User-Agent"), wxT("wxWindows 2.x"));
-
- switch (req) {
- case wxHTTP_GET:
- tmp_buf = wxT("GET");
- break;
- default:
- return FALSE;
- }
-
- SaveState();
- SetFlags(NONE);
- Notify(FALSE);
-
- wxSprintf(buf, wxT("%s %s HTTP/1.0\n\r"), tmp_buf, tmp_str.GetData());
- const wxWX2MBbuf pathbuf = wxConvLibc.cWX2MB(buf);
- Write(pathbuf, strlen(wxMBSTRINGCAST pathbuf));
- SendHeaders();
- Write("\n\r", 2);
-
- 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();
-
- switch (tmp_str2[(unsigned int) 0]) {
- 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");
+ if ( GetHeader( wxT("Content-Length") ).empty() )
+ 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")).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
+ 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 = buf.mb_str();
+ Write(pathbuf, strlen(pathbuf));
+ SendHeaders();
+ Write("\r\n", 2);
+
+ if ( req == wxHTTP_POST ) {
+ // Post data can be arbitrary binary data when the "binary" content
+ // transfer encoding is used so don't assume it's ASCII only or
+ // NUL-terminated.
+ {
+ const wxScopedCharBuffer buf(m_post_buf.To8BitData());
+ Write(buf, buf.length());
+ } // delete the buffer before modifying the string it points to, it
+ // wouldn't really be a problem here even if we didn't do this
+ // because we won't use this buffer again but this will avoid any
+ // nasty surprises in the future if this code changes
+
+ m_post_buf = wxEmptyString;
+ }
+
+ 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();