Exemplo n.º 1
0
/**
int  recv_https_closed(int sofd, SSL* ssl, Buffer* buf, int tm, FILE* fp)

HTTPメッセージで recv_https_header() で受信したヘッダに引き続いて,Chunkモードのコンテンツデータを受信する.

fp がNULLでなければ,受信データ(コンテンツ)はファイルにも保存される.

@param          sofd   接続相手へのソケット
@param          ssl    接続相手への SSLソケット.SSL通信でない場合は NULL を指定.
@param[in,out]  buf    全コンテンツを保存する変数.最初に,recv_https_header()で受信したコンテンツ部分を入れて置く.
@param          tm     タイムアウト秒数.
@param          fp     受信したコンテンツを保存するファイルディスクリプタ.NULLなら保存しない.

@retval 0以上          全コンテンツのサイズ(Byte).recv_https_header()で受信したコンテンツ部分を含む.
@retval 0未満          エラー
*/
int  recv_https_closed(int sofd, SSL* ssl, Buffer* buf, int tm, FILE* fp)
{
	int	cc, sz, tout;
	Buffer rcv;


	sz = buf->vldsz;

	rcv = make_Buffer(RECVBUFSZ);
	while ((tout=recv_wait(sofd, tm))) {
		cc = ssl_tcp_recv_Buffer(sofd, ssl, &rcv);
		if (cc>0) {
			if (fp!=NULL) fwrite(rcv.buf, cc, 1, fp);
			cat_Buffer(&rcv, buf);
			sz += cc;
		}
		else {
			break;
		}
		memset(rcv.buf, 0, cc);
	}
	free_Buffer(&rcv);

	if (!tout) return RECV_TIMEOUTED;

	return sz;
}
Exemplo n.º 2
0
/**
 * Server loop. 
 *
 * Wait for incoming data from remote peer and if echo mode is on, echo it
 * back.
 * 
 * @param ctx Pointer to main context.
 * @param fd The socket to the remote peer (in SOCK_STREAM mode) or the "server
 * socket" in SOCK_SEQPKT mode.
 * @return SERVER_USER_CLOSE if user requested stop (ctrl+c was pressed),
 * SERVER_ERROR if there was error when receiving data, SERVER_OK if the remote
 * end closed connetion.
 */
int do_server( struct server_ctx *ctx, int fd ) 
{
        struct sockaddr_storage peer_ss;
        socklen_t peerlen;
        struct sctp_sndrcvinfo info;
        int ret,flags;

        while( ! close_req ) {
                memset( &peer_ss, 0, sizeof( peer_ss ));
                memset( &info, 0, sizeof( peer_ss ));
                peerlen = sizeof( struct sockaddr_in6);
                flags = 0;

                ret = recv_wait( fd, ACCEPT_TIMEOUT_MS,
                                ctx->recvbuf, ctx->recvbuf_size, 
                                (struct sockaddr *)&peer_ss, &peerlen,
                                &info, &flags );
                if ( ret == -1 ) {
                        if ( errno == EINTR )
                                continue;

                        print_error("Unable to read data", errno);
                        return SERVER_ERROR;
                } else if ( ret == -2 )  {
                        printf("Connection closed by remote host\n" );
                        return SERVER_REMOTE_CLOSED;
                } else if ( ret > 0 ) {
                        DBG("Received %d bytes \n", ret );
                        partial_store_collect(&ctx->partial, ctx->recvbuf, ret);

                        if ( flags & MSG_NOTIFICATION ) {
                                TRACE("Received SCTP event\n");
                                if ( flags & MSG_EOR ) {
                                        handle_event(partial_store_dataptr(&ctx->partial));
                                        partial_store_flush(&ctx->partial);
                                } 
                                continue;
                        }

                        if (is_flag(ctx->options, VERBOSE_FLAG)) 
                                print_input( &peer_ss, ret, flags, &info);
                        else
                                print_input( &peer_ss, ret, flags, NULL);

                        if (is_flag(ctx->options, XDUMP_FLAG))
                                        xdump_data( stdout, ctx->recvbuf, ret, "Received data" );

                        if ( is_flag( ctx->options, ECHO_FLAG ) && (flags & MSG_EOR) ) {
                                if ( sendit( fd, info.sinfo_ppid, info.sinfo_stream,
                                             (struct sockaddr *)&peer_ss, peerlen,
                                              partial_store_dataptr( &ctx->partial),
                                              partial_store_len( &ctx->partial) ) < 0) {
                                        WARN("Error while echoing data!\n");
                                } else {
                                        if (is_flag(ctx->options, VERBOSE_FLAG)) 
                                                print_output_verbose(&peer_ss,
                                                     partial_store_len(&ctx->partial),
                                                     info.sinfo_ppid, info.sinfo_stream);
                                        else
                                                print_output( &peer_ss,
                                                     partial_store_len(&ctx->partial));
                                }
                        }
                        if ( flags & MSG_EOR ) 
                                partial_store_flush( &ctx->partial );
                }
        }
        return SERVER_USER_CLOSE;
}