problem with showing the default page in web server - c

I have a simple webserver and When I run my webserver and try to access it through firefox it gives me bin file to download instead of showing the default page which is index.html
If I write it like localhost:8001/index.html it works fine and it shows the content of the index.html file
how can I fix it so that when i enter like localhost:8001 it just open the index.html file and show the content of it?
The main function of my code:
#define PORT 8001
int main()
{
int server_socket, new_socket;
long value;
struct sockaddr_in address;
int addrlen = sizeof(address);
char response_data[1024];
//open a file to serve
FILE *html_data = fopen("/home/seclab/www/index.html","r");
fgets(response_data, 1024, html_data);
char http_header[2048] = "HTTP/1.0 200 OK\r\n\n";
strcat(http_header, response_data);
//create a socket
if((server_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("can not create socket");
return 0;
}
//define the address
//memset(address.sin_zero, '\0' , sizeof address.sin_zero );
address.sin_family = AF_INET;
address.sin_port = htons(PORT);
address.sin_addr.s_addr = INADDR_ANY;
if(bind(server_socket, (struct sockaddr *) &address, sizeof(address)) < 0 )
{
perror("can't bind the address to the socket");
return 0;
}
if(listen(server_socket, 8) < 0)
{
perror("In listen");
exit(EXIT_FAILURE);
}
while(1)
{
//printf("\nwaiting for a connection\n\n");
if((new_socket = accept(server_socket,NULL , NULL)) < 0)
{
perror("In accept");
exit(EXIT_FAILURE);
}
send(new_socket, http_header, sizeof(http_header), 0);
printf("%s",http_header);
//char buffer[30000] = {0};
//value=read(new_socket, buffer , 30000);
//printf("%s\n",buffer);
//write(new_socket, response_data , strlen(response_data));
//printf("Greeting message sent\n");
close(new_socket);
}
return 0;
}
Screenshot:

You send a response that is sizeof(http_header) but that should be the actual size of the response, which is header + data read:
send(new_socket, http_header, strlen(http_header), 0);

Related

C Proxy crashing

Im writing a program which connects to a browser and sends the http request from the browser to a server, and then sends the response back to the browser, which loads the page with some of the content. My program sends things successfully and loads pages, but does not run continuously and will crash after a random amount of time- sometimes 10 seconds of running sometimes 1 minute. I want this proxy to be able to run forever. Below is how I have structured my code. I have included the recv and write section which I think is causing my errors in full. I am pretty new to socket programming and c In general and looking for some tips on my structure and anything I may have missed.
int main(int argc, char *argv[])
{
char ip[40]
char *host = argv[1];
char *port_s = argv[2];
int err;
int socket_browser, socket_newBrowser, c;
struct sockaddr_in server, client;
int n;
socket_browser= socket(AF_INET, SOCK_STREAM, 0);
if (socket_browser < 0)
{
printf("Could not create socket");
}
if (err = bind(socket_browser , (struct sockaddr *)&server, sizeof(server)) != 0)
{
resourceError(err, "bind");
return 1;
}
if (err = listen(socket_browser , 3) != 0)
{
resourceError(err, "listen");
}
while (1){
c = sizeof(struct sockaddr_in);
server_socket= accept(socket_browser, (struct sockaddr *)&client, (socklen_t *)&c);
char buf[256];
int n;
n = recv(socket_newBrowser, buf, 256, 0);
if (n < 0){
resourceError(n,"recv");
}
int server_socket;
struct sockaddr_in server2;
server_socket= socket(AF_INET, SOCK_STREAM, 0);
if (server_socket < 0)
{
resourceError(server_socket, "serverSocket");
}
server2.sin_addr.s_addr = inet_addr(ip);
server2.sin_family = AF_INET;
server2.sin_port = htons(80);
connect(server_socket, (struct sockaddr *)&server2, sizeof(server2))
send(server_socket, buf, strlen(buf), 0);
char reply[256];
int bytes_reply = 0;
do
{
bytes_reply = recv(server_socket, reply, sizeof(reply), 0);
// Need to check for double enter as this currently does not work in telnet
if (bytes_reply == -1)
{
perror("Recv error");
}
else
{
write(server_socket, reply, bytes_reply);
}
} while (bytes_reply > 0);
printf("connections closed");
}
return 0;
}
I think your problem (or at least a problem) is:
n = recv(socket_newBrowser, buf, 256, 0);
/*versus*/
send(server_socket, buf, strlen(buf), 0);
buf is not null-terminated, you should have used the n value returned from recv instead of strlen.

Forwarding data as TCP Client

I have a client requesting data (DA) from server A, and then I need to send DA to a second server B. I got it while the data is not larger than the buffer. However the following is not working for passing all data from A to B. I notice that when I create the socket_fwd and connect after closing the first sockfd, it works. But since I need to forward all data, I need to process all incomming as soon as it arrives
int sockfd, sockfd_fwd, n, n_fwd;
gint BUFFER=900;
char buf[BUFFER];
char* addr = "11.0.0.20"; //Server A listening on port 80
struct sockaddr_in server_addr = {0};
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(80);
char chunk[BUFFER];
gint nfw;
gint total_recv = 0;
gint total_fwd = 0;
struct sockaddr_in server_addr2 = {0};
server_addr2.sin_port = htons(5555);
server_addr2.sin_family = AF_INET;
char *addr2 = "127.0.0.1"; //Server B listening on port 555
//#################Request data from A:80 ###########################
if(inet_pton(AF_INET, addr, &server_addr.sin_addr) != 1){
perror("inet_pton");
return -1;
}
sockfd = socket(AF_INET, (SOCK_STREAM), 0); //socket with server A
if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0)
mylog(G_LOG_LEVEL_MESSAGE, __FUNCTION__,"Error on connect");
send(sockfd, buffer, strlen(buffer), 0); //Buffer contains something like get xx Kib to the server
bzero(buffer, BUFFER);
if(inet_pton(AF_INET, addr2, &server_addr2.sin_addr) != 1){
mylog(G_LOG_LEVEL_MESSAGE, __FUNCTION__,"Error inet pton");
return -1;
}
if(inet_pton(AF_INET, addr2, &server_addr2.sin_addr) != 1){
perror("inet_pton");
return -1;
}
sockfd_fwd = socket(AF_INET, (SOCK_STREAM), 0); //socket with server B
if (connect(sockfd_fwd, (struct sockaddr*)&server_addr2, sizeof(server_addr2)) < 0)
mylog(G_LOG_LEVEL_MESSAGE, __FUNCTION__,"Error on connect");
while ((n = recv(sockfd, chunk, BUFFER, 0)) > 0) {
total_recv += n;
mylog(G_LOG_LEVEL_MESSAGE, __FUNCTION__,"Recv chunk %s num-bytes:%i",chunk,total_recv);
nfw = send(sockfd_fwd, chunk ,n, 0);
memset(chunk,0,BUFFER);
}
close(sockfd);
close(sockfd_fwd);

Connection Refused even after adding a new Firewall rule

I am trying to connect to my local UNIX server i made from another remote device. the Server is up and listening to the port i specified. i also added a new firewall rule to open that port but still my client cannot connect. it shows ERROR CONNECTION REFUSED
here is my server code
int main() {
int fd, i,svclient,rval,msg;
int clients[10], num_clients;
fd_set read_set,write_set;
char buf[100];
struct sockaddr_in addr;
if ( (fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket error");
exit(-1);
}
bzero((char *) &addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(4001);
//strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)-1);
//strcpy(addr.sun_path, NAME);
if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
perror("bind error");
exit(-1);
}
printf("Bind complet...\n");
if (listen(fd, 20) == -1) {
perror("listen error");
exit(-1);
}
num_clients = 0;
int size = sizeof(fd);
while (1) {
int clientfd;
struct sockaddr_in client_addr;
int addrlen=sizeof(client_addr);
FD_ZERO(&read_set);
FD_SET(fd, &read_set);
for (i = 0; i < num_clients; i++) { //at first this part will not excute
FD_SET(clients[i], &read_set);
}
select(fd + num_clients + 1, &read_set, NULL, NULL, NULL);
if (FD_ISSET(fd, &read_set)) {
if ( (clients[num_clients++] = accept(fd,(struct sockaddr*)&client_addr,&addrlen)) == -1) {
perror("accept error");
continue;
}
/*printf("incoming message..................... !\n \n");*/
printf("%s:%d connected\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
}
for (i = 0; i < num_clients; i++) {
if (FD_ISSET(clients[i], &read_set)) {
msg = read(clients[i], buf, sizeof(buf));
if(msg > 0){
buf[msg] = 0;
int savedclnt = clients[i];
printf("%s \n \n", buf);
/*for(int p=0;p<num_clients;p++)
{
if( clients[p]!= savedclnt){
write(clients[p],buf,msg);
}
}*/
}
}
}
}
}
and my client
int main( )
{
struct uci_context *uci;
uci = uci_init();
int sockfd;
int ret;
struct sockaddr_in dest;
struct addrinfo hint, *res = NULL;
struct hostent *host;
char *hostip;
char *string;
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
{
puts("Unble to create socket");
exit(1);
}
hostip = ucix_get_option(uci, "pack_mon", "pack_monitoring", "address");
string = ucix_get_option(uci, "pack_mon", "pack_monitoring", "port");
bzero(&dest, sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_port = htons(atoi(string));
memset(&hint, '\0', sizeof hint);
hint.ai_family = PF_UNSPEC;
hint.ai_flags = AI_NUMERICHOST;
printf(" %s- %s\n", hostip, string );
if(isdigit(hostip[0])){
ret = getaddrinfo(hostip, NULL, &hint, &res);// this is more efficient than inet_addr
if (ret) {
exit(1);
}
}else if( (host = gethostbyname(hostip)) != 0){
memcpy((char*)&dest.sin_addr , (char*)host->h_addr , (sizeof dest.sin_addr)+1);
}else{
exit(1);
printf("cannot resolve ip address");
}
if ( connect(sockfd, (struct sockaddr *)&dest, sizeof(dest)) < 0 )
{
perror("ERROR Connecting" );
exit(1);
}else{
printf("Port number %s is open.....\n",string);
}
char *message;
message = "help";
write(sockfd,message,strlen(message));
close(sockfd);
freeaddrinfo(res);
return 0;
}
FIREWALL RULE
sudo iptables -I INPUT -p tcp --dport 4001 -j ACCEPT
Error is :
192.168.10.155- 4001
ERROR Connecting: Connection refused
and this logs are coming from this codes :
printf(" %s- %s\n", hostip, string );
perror("ERROR Connecting");
exit(1);
Your client has no code to specify the IP address it wants to connect to. All the code that could do that has been commented out.
Update: Now your bug is here:
strncpy((char*)&dest.sin_addr , (char*)host->h_addr , sizeof dest.sin_addr);
The strncpy function is only suitable for C-style strings. You need to use memcpy or something similar. This will only copy part of the IP address if any octet other than its last one (in network byte order) is zero.
Update: Now your bug is here:
printf("%d\n", connect(sockfd, (struct sockaddr *)&dest, sizeof(dest)) < 0);
perror("hmmmm" );
exit(1);
This calls connect, then calls printf and then calls perror. The problem is, the call to printf can modify errno even if it succeeds. Thus your call to perror can print a totally irrelevant error message.

What is the reason I am getting: Socket operation on non-socket

I am writing c sockets the send a file from client to server. client() is called in main client program while the server() is called in the server program. send_file() is a helper function for client(). I want the server to wait for another client connection after it finishes getting data from the current client.
The first iteration is fine but I am getting error from accept in the SECOND iteration in the server: server: accept: Socket operation on non-socket
What causes the problem?
int send_file(int socket, char *path) {
int len;
char buf[BUF_SIZE];
char size[BUF_SIZE];
struct stat stbuf;
int fd = open(path, O_RDONLY);
fstat(fd, &stbuf);
sprintf(size, "%d", (int)stbuf.st_size);
write(socket, size, BUF_SIZE);
while((len = read(fd, buf, BUF_SIZE)) > 0) {
write(socket, buf, len);
}
close(fd);
return 1;
}
int client(char *src_path, char *dest_path, char *host_ip, int port) {
int sock_fd;
// Create the sock fd
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if (sock_fd < 0) {
perror("client: socket");
exit(1);
}
// Set the IP and port of the server to connect to.
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(port);
if (inet_pton(AF_INET, host_ip, &server.sin_addr) < 1) {
perror("client: inet_pton");
close(sock_fd);
exit(1);
}
// Connect to the server
if (connect(sock_fd, (struct sockaddr *)&server, sizeof(server)) == -1) {
perror("client: connect");
close(sock_fd);
exit(1);
}
send_file(sock_fd, src_path);
return 0;
}
int server(int port) {
printf("PORT: %d\n", port);
char buf[BUF_SIZE];
int sock_fd, client_fd;
int len;
// Create the socket FD.
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if (sock_fd < 0) {
perror("server: socket");
exit(1);
}
// Set information about the port (and IP) we want to be connected to.
struct sockaddr_in server, client;
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.s_addr = INADDR_ANY;
memset(&server.sin_zero, 0, 8);
// Bind the selected port to the socket
if (bind(sock_fd, (struct sockaddr *)&server, sizeof(server)) < 0) {
perror("server: bind");
close(sock_fd);
exit(1);
}
// Announce willingness to accept connections on this socket
if (listen(sock_fd, MAX_BACKLOG) < 0) {
perror("server: listen");
close(sock_fd);
exit(1);
}
while(1) {
socklen_t client_size = sizeof(client);
if ((client_fd = accept(sock_fd, (struct sockaddr *)&client, &client_size)) < 0) {
perror("server: accept");
close(sock_fd);
exit(1);
}
read(client_fd, buf, BUF_SIZE);
int size = atoi(buf);
printf("Size: %d\n", size);
while ((size > 0) && ((len = read(client_fd, buf, BUF_SIZE)) > 0)) {
size -= len;
buf[len] = '\0';
printf("%s", buf);
}
close(client_fd);
}
close(sock_fd);
exit(1);
}
You have a buffer overflow in your read code on the server.
while ((size > 0) && ((len = read(client_fd, buf, BUF_SIZE)) > 0)) {
size -= len;
buf[len] = '\0';
// ^^^ Boom!!!
printf("%s", buf);
}
If you read BUF_SIZE bytes from the socket, len is BUF_SIZE and then you set the byte at buf[BUF_SIZE] to \0. This must be clobbering the socket file descriptor which is declared straight after the buffer.
I should add, the best way to fix it is probably to declare the buffer with size BUF_SIZE + 1 rather than read BUF_SIZE - 1 bytes because the IO will be a bit more efficient (you are writing in BUF_SIZE chunks).

Mp4 file is not playing when finished download with c socket

I am trying to download mp4 video using C socket. File downloaded successfully but when i am try to play it is not working. File is same as original file size. But their checksum is differents. But this code is working fine for pdf file.
I am grateful and appreciate for your afford.
int main() {
int socket_desc;
char *message;
char server_reply[100000];
char *file_path = "file.mp4";
ssize_t total_len = 0;
char *ip = NULL;
FILE *file = NULL;
struct sockaddr_in server;
//Create socket
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if (socket_desc == -1) {
printf("dCould not create socket");
}
server.sin_addr.s_addr = inet_addr("195.154.200.24");
server.sin_family = AF_INET;
server.sin_port = htons(80);
if (connect(socket_desc, (struct sockaddr *) &server, sizeof(server)) < 0) {
printf("connect error");
return 1;
}
message = "GET /upload_file/367/382/Indian%20Pop%20Hit%20Video%20Songs/Indian%20Pop%20Video%20Songs%202016%20-%20MP4/Jammin%20-%20Yaara%20-%20A%20R%20Rahman%20-%20Video%20MP4.mp4 HTTP/1.1\r\nHost: dl.pagal.link\r\n\r\n";
if (send(socket_desc, message, strlen(message), 0) < 0) {
printf("Send failed");
return 1;
}
remove( file_path );
file = fopen( file_path , "ab");
if (file == NULL) {
printf("File %s could not opened", file_path);
return 1;
}
while (1) {
ssize_t received_len = recv(socket_desc, server_reply, sizeof(server_reply), 0);
if (received_len < 0) {
printf("Received failed\n");
return -1;
}
if (received_len == 0) {
break;
}
fwrite(server_reply, (size_t) received_len, 1, file);
}
fclose(file);
return 0;
}

Resources