2012-04-12 33 views
1

Ich versuche, eine Datei zu HTTP-Server über POST-Anforderung (C++ und winapi) zu senden, vor:das Hochladen von Dateien mit Httpsendrequest C++

// Read file into "buff" and file size into "buffSize" 
     .... 
    .... 
    .... 

    HINTERNET internetRoot; 
    HINTERNET httpSession; 
    HINTERNET httpRequest; 

    internetRoot = InternetOpen(agent_info, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, NULL); 

    //Connecting to the http server 
    httpSession = InternetConnect(internetRoot, IP,PORT_NUMBER, NULL, NULL, INTERNET_SERVICE_HTTP, NULL, NULL); 

    //Creating a new HTTP POST request to the default resource on the server 
    httpRequest = HttpOpenRequest(httpSession, TEXT("POST"), TEXT("/Post.aspx"), NULL, NULL, NULL, INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE, NULL); 

    //Send POST request 
    HttpSendRequest(httpRequest, NULL, NULL, buff, buffSize); 

    //Closing handles... 

In Server Ich bin recieving die Datei mit diesem Code (asp.net)

Stream httpStream; 
     try 
     { 
      httpStream = request.RequestContext.HttpContext.Request.InputStream; 
     } 
     catch (HttpException) 
     { 
      return; 
     } 

      byte[] tmp = new byte[httpStream.Length]; 
      int bytesRead = httpStream.Read(tmp, 0, 1024 * 1024); 
      int totalBytesRead = bytesRead; 
      while (bytesRead > 0) 
      { 
       bytesRead = httpStream.Read(tmp, totalBytesRead, 1024 * 1024); 
       totalBytesRead += bytesRead; 
      } 
      httpStream.Close(); 
      httpStream.Dispose(); 

      //Save "tmp" to file... 

ich große Dateien auf lokalen Server (Visual Studio aSP-Server) senden kann, aber ich kann Dateien über 1 MB Internet-Server nicht senden. (HttpOpenRequest ist fehlgeschlagen) gibt es eine bessere Möglichkeit zum Hochladen von Dateien?

Antwort

1

Vorbehalt: Mein Wininet ist in diesen Tagen sehr rostig.

Ich frage mich, ob Sie den Header "Content-Length" selbst setzen sollten. Ihr Code scheint davon auszugehen, dass entweder a) Sie eine HTTP/1.0-Anfrage stellen oder b) dass HttpSendRequest die Kopfzeile für Ihre hinzufügen wird (was ich nicht glaube).

In beiden Fällen, ohne dass dem Server mitgeteilt wird, wie groß die eingehende Anforderung ist, wird die Standardkonfiguration von IIS ablehnen, wenn sie die Anforderungsgröße selbst nicht schnell ermitteln kann.

Meine Schätzung ist, wenn Sie die lpszHeaders und dwHeadersLength Parameter der HttpSendRequest Funktion verwenden, um die entsprechende "Content-Length" Header enthalten das Problem wird gelöst werden.

+0

Dank für die Antwort, die ich versuche, dass, aber es ist seltsam, warum lokal hat es funktioniert (da kein IIS beteiligt) und wenn wir durch IIS gingen, änderten sich die Dinge ... – CnativeFreak

+0

@CnativeFreak: Nun, das klingt richtig für mich, es ist meine Vermutung, dass IIS die Anfrage ablehnt, um bösartige oder bösartige Anfragen zu verhindern schlechte Dinge wie DOS-Attacken auf einen Server zu tun. Der Cassini-Entwicklungsserver benötigt diesen Schutz nicht und daher funktioniert das lokale Debugging ohne IIS problemlos. – AnthonyWJones

+0

Ich habe die folgenden Char Header [255]; \t Memset (Header, 0,255); \t sprintf (Header, "Content-Length:% d", buffSize); \t wenn (!Httpsendrequest (httprequest, headers, strlen (Header), Buff, BUFFSIZE)) aber noch Httpsendrequest mit Fehler nicht verlässt sehr schnell – CnativeFreak

1

Welchen Fehler erhalten Sie? Ich meine was GetLastError() zurückgibt? Wenn Sie Datei 800KB senden, funktioniert es OK? Ich sehe nicht wirklich, wie HttpOpenRequest nicht über die Größe der Daten weiß.

Vielleicht Timeouts? Aber das würde bedeuten, dass HttpSendRequest tatsächlich fehlschlägt. Es kann alle Daten puffern, aber da die Größe sehr groß ist, benötigt es mehr Zeit, als Timeout erlaubt.

Verwendung folgende Code aktuelle Timeouts abzufragen (in ms):

InternetQueryOption(h, INTERNET_OPTION_RECEIVE_TIMEOUT, &dwReceiveTimeOut, sizeof(dwReceiveTimeOut)); 
InternetQueryOption(h, INTERNET_OPTION_SEND_TIMEOUT, &dwSendTimeOut, sizeof(dwSendTimeOut)); 

und folgenden neue zu setzen:

InternetSetOption(h, INTERNET_OPTION_RECEIVE_TIMEOUT, &dwNewReceiveTimeOut, sizeof(dwNewReceiveTimeOut)); 
InternetSetOption(h, INTERNET_OPTION_SEND_TIMEOUT, &dwNewSendTimeOut, sizeof(dwNewSendTimeOut)); 
+0

Ich versuchte dies, und es scheint, dass ich nur etwa 800 KB senden kann ich könnte nicht einmal 1 senden MB – CnativeFreak

+0

Ich las sie überprüfte sie im Debugger und sie waren 30000, dann setzen sie auf 600000 DWORD dwReceiveTimeOut; DWORD dwSendTimeOut; \t DWORD-Größe = sizeof (dwReceiveTimeOut); \t Internetquery (httprequest, INTERNET_OPTION_RECEIVE_TIMEOUT, & dwReceiveTimeOut, &size); \t Internetquery (httprequest, INTERNET_OPTION_SEND_TIMEOUT, & dwSendTimeOut, &size); \t dwReceiveTimeOut = 600000; \t dwSendTimeOut = 600000; \t InternetSetOption (httprequest, INTERNET_OPTION_RECEIVE_TIMEOUT, & dwReceiveTimeOut, size); \t InternetSetOption (httpRequest, INTERNET_OPTION_SEND_TIMEOUT, & dwSendTimeOut, Größe); – CnativeFreak