0

I want to modify the headers of a request with TWebBrowser in Delphi XE5. As described in Modify requestHeaders in “custom” browser in delphi, you can do that using the OnBeforeNavigate2 event of the TWebBrowser. The procedure corresponding to the event would be:

procedure TForm1.WebBrowser1BeforeNavigate2(Sender: TObject;
  const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData,
  Headers: OleVariant; var Cancel: WordBool);

var
  NewHeaders: OleVariant;
begin
  // some code to stop the navigation, enhance the headers and avoid re-enterng the procedure

  // do not allow frames or iframes to raise this event
  if (pDisp as IUnknown) = (WebBrowser1.ControlInterface as IUnknown)     then
  begin
    // avoid stack overflow: check if our custom header is already set
    if Pos('MyHeader', Headers) <> 0 then Exit;

    // cancel the current navigation
    Cancel := True;
    (pDisp as IWebBrowser2).Stop;

    // modify headers with our custom header
    NewHeaders := Headers + 'MyHeader: Value'#13#10;
    // now proceed with navigation 
    (pDisp as IWebBrowser2).Navigate(URL, Flags, TargetFrameName, PostData, NewHeaders);
  end;
end;

The problem is that while the method proposed in the answer works for a GET request, for a POST request I run into the following problem: PostData only contains the beginning of the initially posted data (in my case a text file uploaded via a html form). Concretely, while a correct example of what a client sends back to the server would look like this:

--AaB03x
    content-disposition: form-data; name="field1"

    Joe Blow
    --AaB03x
    content-disposition: form-data; name="pics"; filename="file1.txt"
    Content-Type: text/plain

     ... contents of file1.txt ...
--AaB03x--

what I find while debugging as PostData is something like this PostString

'-----------------------------7e16'#$D#$A'Content-Disposition: form-data; name="myform"; filename="MyUploadedFile.csv"'#$D#$A'Content-Type: application/vnd.ms-excel'#$D#$A#$D#$A#0

Hence the entire content of the file is missing and the final boundary (i.e. -----------------------------7e16).

WireShark tells me that despite PostData is not NULL Navigate() is not making a POST request but a GET with a message body being exactly what I found during debugging and show above.

My guess is that the reason for the latter is that the Navigate() function performs a check on whether PostData is valid before it creates a POST request and it makes a GET otherwise.

Since someone claims that Navigate() works correctly with PostData what can I do to get the complete PostData for my OnBeforeNavigate2 event?

Community
  • 1
  • 1
acuser
  • 1
  • 3
  • Hard to tell what is going on. Can you make a complete example that exposes the problem? – whosrdaddy Aug 12 '15 at 13:18
  • @whosrdaddy I just posted code that adds a header "MyHeader" with the value "Value" to the headers before the navigation. As I said this works fine unless your request is a POST, e.g. the user filled out a html form in the Web Browser. – acuser Aug 12 '15 at 14:19
  • In the source code I see two `begin` but only one `end`. Where is the second end? – mjn Aug 12 '15 at 17:43
  • If `PostData` is incomplete than you are likely reading its data incorrectly. A browser would not post incomplete data, and certainly would not change a request from `POST` to `GET` based on the content of post data. The only thing that should ever change a request type from `POST` to `GET` is an HTTP redirect. If `PostData` is passed to `Navigate()` than it issues a `POST` request, not a `GET` request, period. This is documented behavior. – Remy Lebeau Aug 12 '15 at 19:24
  • @RemyLebeau The way I read PostData while debugging is: `PostString := TEncoding.ANSI.GetString(TBytes(PostData));`, but I am not responsible for the variable in the first place, since it is already set when the event is triggered. In addition, what I find while debugging is consistent with what WireShark is intercepting. I changed the question to reflect that in fact all I will probably need to achieve is to somehow get the complete PostData. – acuser Aug 13 '15 at 09:56

0 Answers0