一个web服务器的实现(下)

/* ------------------------------------------------------ *
204  
205    process_rq( char *rq, int fd )
206  
207    分析客户端的请求,分析然后做出相应的应答
208  
209    rq is HTTP command:  GET /foo/bar.html HTTP/1.0
210  
211    ------------------------------------------------------ */
212  
213  
214  
215 process_rq( char *rq, int fd )
216  
217 {
218  
219     char    cmd[BUFSIZ], arg[BUFSIZ];
220  
221  
222  
223     /* create a new process and return if not the child */
224  
225     if ( fork() != 0 )
226  
227         return;
228  
229  
230  
231     strcpy(arg, "./");      /* precede args with ./ */
232  
233     if sscanf(rq, "%s%s", cmd, arg+2) != 2 )
234  
235         return;
236  
237  
238  
239     if strcmp(cmd,"GET") != 0 )
240  
241         cannot_do(fd);
242  
243     else if ( not_exist( arg ) )
244  
245         do_404(arg, fd );
246  
247     else if ( isadir( arg ) )
248  
249         do_ls( arg, fd );
250  
251     else if ( ends_in_cgi( arg ) )
252  
253         do_exec( arg, fd );
254  
255     else
256  
257         do_cat( arg, fd );
258  
259 }
260  
261  
262  
263 /* ------------------------------------------------------ *
264  
265    the reply header thing: all functions need one
266  
267    if content_type is NULL then don't send content type
268  
269    ------------------------------------------------------ */
270  
271  
272  
273 header( FILE *fp, char *content_type )
274  
275 {
276  
277     fprintf(fp, "HTTP/1.0 200 OK\r\n");
278  
279     if ( content_type )
280  
281         fprintf(fp, "Content-type: %s\r\n", content_type );
282  
283 }
284  
285  
286  
287 /* ------------------------------------------------------ *
288  
289    simple functions first:
290  
291         cannot_do(fd)       unimplemented HTTP command
292  
293     and do_404(item,fd)     no such object
294  
295    ------------------------------------------------------ */
296  
297  
298  
299 cannot_do(int fd)
300  
301 {
302  
303     FILE    *fp = fdopen(fd,"w");
304  
305  
306  
307     fprintf(fp, "HTTP/1.0 501 Not Implemented\r\n");
308  
309     fprintf(fp, "Content-type: text/plain\r\n");
310  
311     fprintf(fp, "\r\n");
312  
313  
314  
315     fprintf(fp, "That command is not yet implemented\r\n");
316  
317     fclose(fp);
318  
319 }
320  
321  
322  
323 do_404(char *item, int fd)
324  
325 {
326  
327     FILE    *fp = fdopen(fd,"w");
328  
329  
330  
331     fprintf(fp, "HTTP/1.0 404 Not Found\r\n");
332  
333     fprintf(fp, "Content-type: text/plain\r\n");
334  
335     fprintf(fp, "\r\n");
336  
337  
338  
339     fprintf(fp, "The item you requested: %s\r\nis not found\r\n",
340  
341             item);
342  
343     fclose(fp);
344  
345 }
346  
347  
348  
349 /* ------------------------------------------------------ *
350  
351    the directory listing section
352  
353    isadir() uses stat, not_exist() uses stat
354  
355    do_ls runs ls. It should not
356  
357    ------------------------------------------------------ */
358  
359  
360  
361 isadir(char *f)
362  
363 {
364  
365     struct stat info;
366  
367     return ( stat(f, &info) != -1 && S_ISDIR(info.st_mode) );
368  
369 }
370  
371  
372  
373 not_exist(char *f)
374  
375 {
376  
377     struct stat info;
378  
379     return( stat(f,&info) == -1 );
380  
381 }
382  
383  
384  
385 do_ls(char *dir, int fd)
386  
387 {
388  
389     FILE    *fp ;
390  
391  
392  
393     fp = fdopen(fd,"w");
394  
395     header(fp, "text/plain");
396  
397     fprintf(fp,"\r\n");
398  
399     fflush(fp);
400  
401  
402  
403     dup2(fd,1);
404  
405     dup2(fd,2);
406  
407     close(fd);
408  
409     execlp("ls","ls","-l",dir,NULL);
410  
411     perror(dir);
412  
413     exit(1);
414  
415 }
416  
417  
418  
419 /* ------------------------------------------------------ *
420  
421    the cgi stuff.  function to check extension and
422  
423    one to run the program.
424  
425    ------------------------------------------------------ */
426  
427  
428  
429 char * file_type(char *f)
430  
431 /* returns 'extension' of file */
432  
433 {
434  
435     char    *cp;
436  
437     if ( (cp = strrchr(f, '.' )) != NULL )
438  
439         return cp+1;
440  
441     return "";
442  
443 }
444  
445  
446  
447 ends_in_cgi(char *f)
448  
449 {
450  
451     return strcmp( file_type(f), "cgi" ) == 0 );
452  
453 }
454  
455  
456  
457 do_exec( char *prog, int fd )
458  
459 {
460  
461     FILE    *fp ;
462  
463  
464  
465     fp = fdopen(fd,"w");
466  
467     header(fp, NULL);
468  
469     fflush(fp);
470  
471     dup2(fd, 1);
472  
473     dup2(fd, 2);
474  
475     close(fd);
476  
477     execl(prog,prog,NULL);
478  
479     perror(prog);
480  
481 }
482  
483 /* ------------------------------------------------------ *
484  
485    do_cat(filename,fd)
486  
487    sends back contents after a header
488  
489    ------------------------------------------------------ */
490  
491  
492  
493 do_cat(char *f, int fd)
494  
495 {
496  
497     char    *extension = file_type(f);
498  
499     char    *content = "text/plain";
500  
501     FILE    *fpsock, *fpfile;
502  
503     int c;
504  
505  
506  
507     if strcmp(extension,"html") == 0 )
508  
509         content = "text/html";
510  
511     else if strcmp(extension, "gif") == 0 )
512  
513         content = "image/gif";
514  
515     else if strcmp(extension, "jpg") == 0 )
516  
517         content = "image/jpeg";
518  
519     else if strcmp(extension, "jpeg") == 0 )
520  
521         content = "image/jpeg";
522  
523  
524  
525     fpsock = fdopen(fd, "w");
526  
527     fpfile = fopen( f , "r");
528  
529     if ( fpsock != NULL && fpfile != NULL )
530  
531     {
532  
533         header( fpsock, content );
534  
535         fprintf(fpsock, "\r\n");
536  
537         while( (c = getc(fpfile) ) != EOF )
538  
539             putc(c, fpsock);
540  
541         fclose(fpfile);
542  
543         fclose(fpsock);
544  
545     }
546  
547     exit(0);
548  
549 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值