> From: owner-openssl-us...@openssl.org On Behalf Of Raj
> Sent: Friday, 06 August, 2010 10:14

>        I was able to read the content data from the server 
> using SSL_read 
> and put back to the browser by using SSL_write. I don't know 
> whether is a 
> right approach or not. 

If you are doing an SSL connection to the server then 
SSL_write to and SSL_read from the server are correct.
(And you should since the client is requesting SSL.)
SSL_read from and SSL_write back to the client are 
correct if the client is SSL, and you said it is.

> For [an .ico] I got the response as follows and I was 
> able to see the 
> icon in my browser <snip>
> But for [a .png], which is  42,565 bytes long, I am 
> receiving the 
> following output. I understood that there is more to do 
> inorder to read the 
> content data, which I am not sure about <snip>
>     Can anybody tell me what else should I do inorder to read 
> the content 
> and show it the browser. The following are sending some code snippets
> 
> 
>             RequestSock = 
> WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);

For a socket used with openssl directly, I believe OVERLAPPED 
will be ignored and is of no use. I think you would have to do 
your own 'physical' level either as your own BIO type or as 
a BIO_pair looping back to your code (the more usual way). 
Frankly I don't think you're anywhere near ready for that.

>              pHost = gethostbyname(pcTargetURL);
>              memset(&ClientAddr,0,sizeof(ClientAddr));
>              ClientAddr.sin_family = AF_INET;
>              memcpy(&ClientAddr.sin_addr,pHost->h_addr, 
> pHost->h_length);
>              ClientAddr.sin_port = htons(atoi(pcPort));
>               if(0 != connect(RequestSock,(SOCKADDR *)&ClientAddr, 
> sizeof(SOCKADDR_IN)))
>              {
>                   closesocket(RequestSock); // Connection failed
>                   return false;
>               }
> 
>              SSL *Serverssl;
>              Serverssl = SSL_new(m_pSSLCtx);
>              SSL_set_fd(Serverssl, RequestSock);
>             iRes = SSL_connect(Serverssl);
>              if(iRes <= 0 )
>              {
>                       ERR_print_errors_fp(stderr);
>                       cout << " connect Failed " << endl;
>               }
>                iRes = SSL_write(Serverssl,pcData, strlen(pcData));

You should check for error (<=0) and report/handle it. Error on _write 
especially initial is not common, but if it ever happens, proceeding 
with other operations will likely cause much greater confusion.

>              SSL_accept(Serverssl);

This is useless. SSL_accept _creates_ a server-side endpoint;
it is not applicable to a client-side endpoint.

>              do
>              {
>                       dwReadDataLen = 
> SSL_read(Serverssl,pBuff,iBufferSize);
>                        SSL_write(SourceSsl,pBuff,dwReadDataLen);
>                        cout << "Read buffer \n" << pBuff << endl;

Again check for errors. Especially on the _read side, 
they are actually quite possible. 

Also, the data read by SSL_read (like POSIX read or C fread)
does not get a null terminator byte added, so outputting 
pBuff as a C-style string is likely to append garbage, 
especially on the second or more time through the loop.

>                } while(SSL_pending(Serverssl));
> 
That's your problem. SSL_pending only indicates data _already 
received and buffered_ by OpenSSL but not yet read by the app. 
For responses more than one SSL record (max 32kbytes if I recall 
correctly, and server may choose less) AND (probably) more than 
the TCP window (varies but typically 2 MTU = about 3kbytes to start) 
there will be some time delay between receiving the first chunk 
of the data and the next, and the next and so on.

For a waited/blocking socket, which is the default as you have here, 
you need to keep reading from the server (and in your case writing 
back to the client) until you've done all the data in the response.
If you require, or the server chooses, HTTP/1.0 style conn-per-txn 
(also known as connection: close or not-keepalive or not-pipelined, 
and also not-chunked) you can just loop until you receive "EOF" (0) 
from SSL_read, caused by the server closing the connection.

If you allow and the server uses HTTP/1.1 keep-alive (or pipelining) 
and/or chunked data, the situation can get quite a bit more 
complicated. See RFC 2616.

If you use a nonblocking socket (which is supported on Windows 
as far as I know but is apparently not the same as OVERLAPPED) 
you can also do your own timeout -- that is, read until EOF 
or optionally calculated end of the response body, *or* timeout. 
Since HTTP servers will normally send a complete response within 
a short time (like at most a few seconds), and if one doesn't 
a person at a browser usually doesn't want to wait anyway, 
this can be a good simple compromise.



______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to