0

I am writing a web proxy, and it is working great with web pages that can be translated to ASCII text. However, when I try to view pages with binary data (Youtube.com is the one I've been using), there is a memory leak someplace, and the same few characters will repeat over and over again at the end of the strings I'm sending to the client (and will show up in other places where they clearly shouldn't be).

Below is the relevant part of my code. SendHTTPResponse is a function that sends the response of the web page to the client using the proxy, and works correctly.

Does anyone have any insight?

int numBytes;  
char temp[3000];
memset(temp, '\0', 3000);  
numBytes = Read(internetSocket, temp, 2999);  
while (errno = 0, numBytes > 0 || errno == EINTR)
{
  SendHTTPResponse(socket, temp, numBytes);
  memset(temp, '\0', 3000);
  numBytes = Read(internetSocket, temp, 2999);     
}
user1174511
  • 309
  • 3
  • 5
  • 15
  • There's not enough information or code here to answer this question. You need to do some debugging and narrow it down. – Jonathon Reinhart Aug 05 '13 at 00:27
  • Don't you have to accept numBytes == 0 as a valid return-value, meaning nothing was in the buffer but the stream is still open & you should continue attempting to read? – Thomas W Aug 05 '13 at 00:38
  • 4
    errno = 0, numBytes > 0 ???? what is that? why are you using the comma operator like that? and WHY are you setting errno to 0? – Ahmed Masud Aug 05 '13 at 00:40
  • 2
    @ThomasW `numBytes == 0` means the peer has disconnected and you should *not* continue attempting to read. – user207421 Aug 05 '13 at 00:45
  • @EJP -- Reference for that? I remember running into this quirk in some programming language, and looked for a quick ref of Read() myself.. if you have one I'd be interested. – Thomas W Aug 05 '13 at 00:53
  • The problem is almost certainly in the `SendHTTPResponse()` function. – caf Aug 05 '13 at 01:18
  • 1
    @ThomasW *man recv()* would be a good start, don't you think? This is C not Java. – user207421 Aug 05 '13 at 01:25
  • Maybe it was Pascal or C that I saw this in.. but yes, I used to do low-level languages many many years ago. And no, this doesn't look like Java :) – Thomas W Aug 05 '13 at 01:53
  • @ThomasW It wasn't C. You must also be thinking of non-blocking mode in some language, or making it up. – user207421 Aug 05 '13 at 02:07
  • I beg pardon, @EJP? I've got 24 years commercial experience.. my memory is not perfect, but no I do not intentionally "make stuff up". To insinuate so is rude. To believe you know all the ins & outs, of every library of an unspecified language on every OS, is arrogant. You also seem to fail to read -- my statements have always been _qualified_ as my to actual experiences, whereas you seem to be asserting omniscience. Waiting for you to part some waves, or grow some manners. – Thomas W Aug 05 '13 at 05:58
  • Pity, since your answer below is good -- and I'd otherwise intend to +1 it. – Thomas W Aug 05 '13 at 05:59
  • @ThomasW Lighten up. I have 37 years, not that it's relevant. It's a surprising error, hence my comment. Frankly I find asking me for a reference for the BSD sockets API pretty strange as well. – user207421 Aug 05 '13 at 07:28
  • I'm a like amazed with all those comments... Does `Read` is any standard C socket function? If yes, which? If not, how can we check made any answer without understanding application context? – LS_ᴅᴇᴠ Aug 05 '13 at 08:02
  • @EJP Well, thanks for the reference you did suggest (no authoritative link, though). I don't see the macro mapping Read() to recv(), but I suppose an inference of socket API is reasonable -- in which case you would be correct. But never omniscient. – Thomas W Aug 05 '13 at 08:14
  • @ThomasW It seems to me that you're being pretty precious here. It's good enough for you to post some half-remembered unsupported misinformation, and to ask other people for citations when they demur, but it isn't good enough for those people to post correct answers that are supported by normative references? And don't try to tell me that the *man* page isn't authoritative. Finding it isn't beyond your capabilities surely? – user207421 Aug 05 '13 at 09:34
  • As I said, thanks for the reference. My comments were phrased as questions, never definitive or authoritative. 'man' was never the reference for any of MS C++ 7, Turbo Pascal, Delphi, or the assembler I used to use. You seem to make rather negative assumptions, and assume a lot more definitiveness than my actual comments _(read them)_. I was interested to find out more & don't have those manuals to hand, so I asked you -- since you seem to know -- for a reference. I tried to be polite & positive. Take being asked as a compliment, rather than as a continual snark. Thanks! Now p** off. – Thomas W Aug 05 '13 at 12:22

2 Answers2

1

To answer your question, there is no memory leak in this code.

There is also no reason to think a memory leak has anything to do with this problem.

However your code is wrong. It shouldn't set errno and it shouldn't test it either unless the method returned -1. It should read:

while ((numBytes = Read(socket, temp, sizeof temp)) > 0 || numBytes == -1 && errno == EINTR)
{
   SendHTTPResponse(socket, temp, numBytes);
}

You don't need the memset() calls and you don't need to leave any room for a trailing null, provided SendHTTPResponse() takes proper notice of the length you pass it. It should certainly not be looking for trailing nulls itself.

And 3000 is a very strange buffer size. I would use 8192 myself.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • If `numBytes` is -1, `SendHTTPResponse()` should not be called since there is no data to send, but `Read()` should be called again to keep reading when `errno` is `EINTR`. I would use a `do/while` loop instead, and then use a `break` when `Read()` actually fails. – Remy Lebeau Aug 05 '13 at 19:11
0

This is just an educated guess about your problem. As others have said, you have not posted enough information to find your error.

The greatest difference between binary data and text data is that the former (EDIT, thanks EJP) can contain null ('\0') bytes. If you are using string functions (e. g. strlen()), they will interpret these as end-of-string and so you will miss data.

DoxyLover
  • 3,366
  • 1
  • 15
  • 19