Fossil SCM
Add the "ui" command to automatically launch a web browser after starting the HTTP server. The web browser choice can be configured using the "setting" command.
Commit
dfb68976be2232e5d3f202e041240e165afb978b
Parent
24f336c9ae5e3ea…
4 files changed
+4
-1
+13
-7
+21
-2
+7
-1
+4
-1
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -1166,11 +1166,11 @@ | ||
| 1166 | 1166 | ** The parent never returns from this procedure. |
| 1167 | 1167 | ** |
| 1168 | 1168 | ** Return 0 to each child as it runs. If unable to establish a |
| 1169 | 1169 | ** listening socket, return non-zero. |
| 1170 | 1170 | */ |
| 1171 | -int cgi_http_server(int iPort){ | |
| 1171 | +int cgi_http_server(int iPort, char *zBrowser){ | |
| 1172 | 1172 | #ifdef __MINGW32__ |
| 1173 | 1173 | fprintf(stderr,"server not yet available in windows version of fossil\n"); |
| 1174 | 1174 | exit(1); |
| 1175 | 1175 | #else |
| 1176 | 1176 | int listener; /* The server socket */ |
| @@ -1198,10 +1198,13 @@ | ||
| 1198 | 1198 | if( bind(listener, (struct sockaddr*)&inaddr, sizeof(inaddr))<0 ){ |
| 1199 | 1199 | close(listener); |
| 1200 | 1200 | return 1; |
| 1201 | 1201 | } |
| 1202 | 1202 | listen(listener,10); |
| 1203 | + if( zBrowser ){ | |
| 1204 | + system(zBrowser); | |
| 1205 | + } | |
| 1203 | 1206 | while( 1 ){ |
| 1204 | 1207 | if( nchildren>MAX_PARALLEL ){ |
| 1205 | 1208 | /* Slow down if connections are arriving too fast */ |
| 1206 | 1209 | sleep( nchildren-MAX_PARALLEL ); |
| 1207 | 1210 | } |
| 1208 | 1211 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -1166,11 +1166,11 @@ | |
| 1166 | ** The parent never returns from this procedure. |
| 1167 | ** |
| 1168 | ** Return 0 to each child as it runs. If unable to establish a |
| 1169 | ** listening socket, return non-zero. |
| 1170 | */ |
| 1171 | int cgi_http_server(int iPort){ |
| 1172 | #ifdef __MINGW32__ |
| 1173 | fprintf(stderr,"server not yet available in windows version of fossil\n"); |
| 1174 | exit(1); |
| 1175 | #else |
| 1176 | int listener; /* The server socket */ |
| @@ -1198,10 +1198,13 @@ | |
| 1198 | if( bind(listener, (struct sockaddr*)&inaddr, sizeof(inaddr))<0 ){ |
| 1199 | close(listener); |
| 1200 | return 1; |
| 1201 | } |
| 1202 | listen(listener,10); |
| 1203 | while( 1 ){ |
| 1204 | if( nchildren>MAX_PARALLEL ){ |
| 1205 | /* Slow down if connections are arriving too fast */ |
| 1206 | sleep( nchildren-MAX_PARALLEL ); |
| 1207 | } |
| 1208 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -1166,11 +1166,11 @@ | |
| 1166 | ** The parent never returns from this procedure. |
| 1167 | ** |
| 1168 | ** Return 0 to each child as it runs. If unable to establish a |
| 1169 | ** listening socket, return non-zero. |
| 1170 | */ |
| 1171 | int cgi_http_server(int iPort, char *zBrowser){ |
| 1172 | #ifdef __MINGW32__ |
| 1173 | fprintf(stderr,"server not yet available in windows version of fossil\n"); |
| 1174 | exit(1); |
| 1175 | #else |
| 1176 | int listener; /* The server socket */ |
| @@ -1198,10 +1198,13 @@ | |
| 1198 | if( bind(listener, (struct sockaddr*)&inaddr, sizeof(inaddr))<0 ){ |
| 1199 | close(listener); |
| 1200 | return 1; |
| 1201 | } |
| 1202 | listen(listener,10); |
| 1203 | if( zBrowser ){ |
| 1204 | system(zBrowser); |
| 1205 | } |
| 1206 | while( 1 ){ |
| 1207 | if( nchildren>MAX_PARALLEL ){ |
| 1208 | /* Slow down if connections are arriving too fast */ |
| 1209 | sleep( nchildren-MAX_PARALLEL ); |
| 1210 | } |
| 1211 |
M
src/db.c
+13
-7
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -1095,33 +1095,38 @@ | ||
| 1095 | 1095 | ** |
| 1096 | 1096 | ** autosync If enabled, automatically pull prior to |
| 1097 | 1097 | ** commit or update and automatically push |
| 1098 | 1098 | ** after commit or tag or branch creation. |
| 1099 | 1099 | ** |
| 1100 | -** pgp-command Command used to clear-sign manifests at check-in. | |
| 1101 | -** The default is "gpg --clearsign -o ". | |
| 1100 | +** diff-command External command to run when performing a diff. | |
| 1101 | +** If undefined, the internal text diff will be used. | |
| 1102 | 1102 | ** |
| 1103 | 1103 | ** editor Text editor command used for check-in comments. |
| 1104 | +** | |
| 1105 | +** gdiff-command External command to run when performing a graphical | |
| 1106 | +** diff. If undefined, text diff will be used. | |
| 1104 | 1107 | ** |
| 1105 | 1108 | ** localauth If enabled, require that HTTP connections from |
| 1106 | 1109 | ** 127.0.0.1 be authenticated by password. If |
| 1107 | 1110 | ** false, all HTTP requests from localhost have |
| 1108 | 1111 | ** unrestricted access to the repository. |
| 1109 | 1112 | ** |
| 1110 | 1113 | ** omitsign When enabled, fossil will not attempt to sign any |
| 1111 | 1114 | ** commit with gpg. All commits will be unsigned. |
| 1115 | +** | |
| 1116 | +** pgp-command Command used to clear-sign manifests at check-in. | |
| 1117 | +** The default is "gpg --clearsign -o ". | |
| 1112 | 1118 | ** |
| 1113 | 1119 | ** proxy URL of the HTTP proxy. If undefined or "off" then |
| 1114 | 1120 | ** the "http_proxy" environment variable is consulted. |
| 1115 | 1121 | ** If the http_proxy environment variable is undefined |
| 1116 | 1122 | ** then a direct HTTP connection is used. |
| 1117 | 1123 | ** |
| 1118 | -** diff-command External command to run when performing a diff. | |
| 1119 | -** If undefined, the internal text diff will be used. | |
| 1120 | -** | |
| 1121 | -** gdiff-command External command to run when performing a graphical | |
| 1122 | -** diff. If undefined, text diff will be used. | |
| 1124 | +** web-browser A shell command used to launch your preferred | |
| 1125 | +** web browser when given a URL as an argument. | |
| 1126 | +** Defaults to "start" on windows, "open" on Mac, | |
| 1127 | +** and "firefox" on Unix. | |
| 1123 | 1128 | */ |
| 1124 | 1129 | void setting_cmd(void){ |
| 1125 | 1130 | static const char *azName[] = { |
| 1126 | 1131 | "autosync", |
| 1127 | 1132 | "diff-command", |
| @@ -1129,10 +1134,11 @@ | ||
| 1129 | 1134 | "gdiff-command", |
| 1130 | 1135 | "localauth", |
| 1131 | 1136 | "omitsign", |
| 1132 | 1137 | "pgp-command", |
| 1133 | 1138 | "proxy", |
| 1139 | + "web-browser", | |
| 1134 | 1140 | }; |
| 1135 | 1141 | int i; |
| 1136 | 1142 | int globalFlag = find_option("global","g",0)!=0; |
| 1137 | 1143 | int unsetFlag = g.argv[1][0]=='u'; |
| 1138 | 1144 | db_find_and_open_repository(0); |
| 1139 | 1145 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -1095,33 +1095,38 @@ | |
| 1095 | ** |
| 1096 | ** autosync If enabled, automatically pull prior to |
| 1097 | ** commit or update and automatically push |
| 1098 | ** after commit or tag or branch creation. |
| 1099 | ** |
| 1100 | ** pgp-command Command used to clear-sign manifests at check-in. |
| 1101 | ** The default is "gpg --clearsign -o ". |
| 1102 | ** |
| 1103 | ** editor Text editor command used for check-in comments. |
| 1104 | ** |
| 1105 | ** localauth If enabled, require that HTTP connections from |
| 1106 | ** 127.0.0.1 be authenticated by password. If |
| 1107 | ** false, all HTTP requests from localhost have |
| 1108 | ** unrestricted access to the repository. |
| 1109 | ** |
| 1110 | ** omitsign When enabled, fossil will not attempt to sign any |
| 1111 | ** commit with gpg. All commits will be unsigned. |
| 1112 | ** |
| 1113 | ** proxy URL of the HTTP proxy. If undefined or "off" then |
| 1114 | ** the "http_proxy" environment variable is consulted. |
| 1115 | ** If the http_proxy environment variable is undefined |
| 1116 | ** then a direct HTTP connection is used. |
| 1117 | ** |
| 1118 | ** diff-command External command to run when performing a diff. |
| 1119 | ** If undefined, the internal text diff will be used. |
| 1120 | ** |
| 1121 | ** gdiff-command External command to run when performing a graphical |
| 1122 | ** diff. If undefined, text diff will be used. |
| 1123 | */ |
| 1124 | void setting_cmd(void){ |
| 1125 | static const char *azName[] = { |
| 1126 | "autosync", |
| 1127 | "diff-command", |
| @@ -1129,10 +1134,11 @@ | |
| 1129 | "gdiff-command", |
| 1130 | "localauth", |
| 1131 | "omitsign", |
| 1132 | "pgp-command", |
| 1133 | "proxy", |
| 1134 | }; |
| 1135 | int i; |
| 1136 | int globalFlag = find_option("global","g",0)!=0; |
| 1137 | int unsetFlag = g.argv[1][0]=='u'; |
| 1138 | db_find_and_open_repository(0); |
| 1139 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -1095,33 +1095,38 @@ | |
| 1095 | ** |
| 1096 | ** autosync If enabled, automatically pull prior to |
| 1097 | ** commit or update and automatically push |
| 1098 | ** after commit or tag or branch creation. |
| 1099 | ** |
| 1100 | ** diff-command External command to run when performing a diff. |
| 1101 | ** If undefined, the internal text diff will be used. |
| 1102 | ** |
| 1103 | ** editor Text editor command used for check-in comments. |
| 1104 | ** |
| 1105 | ** gdiff-command External command to run when performing a graphical |
| 1106 | ** diff. If undefined, text diff will be used. |
| 1107 | ** |
| 1108 | ** localauth If enabled, require that HTTP connections from |
| 1109 | ** 127.0.0.1 be authenticated by password. If |
| 1110 | ** false, all HTTP requests from localhost have |
| 1111 | ** unrestricted access to the repository. |
| 1112 | ** |
| 1113 | ** omitsign When enabled, fossil will not attempt to sign any |
| 1114 | ** commit with gpg. All commits will be unsigned. |
| 1115 | ** |
| 1116 | ** pgp-command Command used to clear-sign manifests at check-in. |
| 1117 | ** The default is "gpg --clearsign -o ". |
| 1118 | ** |
| 1119 | ** proxy URL of the HTTP proxy. If undefined or "off" then |
| 1120 | ** the "http_proxy" environment variable is consulted. |
| 1121 | ** If the http_proxy environment variable is undefined |
| 1122 | ** then a direct HTTP connection is used. |
| 1123 | ** |
| 1124 | ** web-browser A shell command used to launch your preferred |
| 1125 | ** web browser when given a URL as an argument. |
| 1126 | ** Defaults to "start" on windows, "open" on Mac, |
| 1127 | ** and "firefox" on Unix. |
| 1128 | */ |
| 1129 | void setting_cmd(void){ |
| 1130 | static const char *azName[] = { |
| 1131 | "autosync", |
| 1132 | "diff-command", |
| @@ -1129,10 +1134,11 @@ | |
| 1134 | "gdiff-command", |
| 1135 | "localauth", |
| 1136 | "omitsign", |
| 1137 | "pgp-command", |
| 1138 | "proxy", |
| 1139 | "web-browser", |
| 1140 | }; |
| 1141 | int i; |
| 1142 | int globalFlag = find_option("global","g",0)!=0; |
| 1143 | int unsetFlag = g.argv[1][0]=='u'; |
| 1144 | db_find_and_open_repository(0); |
| 1145 |
+21
-2
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -650,22 +650,29 @@ | ||
| 650 | 650 | cmd_http(); |
| 651 | 651 | } |
| 652 | 652 | |
| 653 | 653 | /* |
| 654 | 654 | ** COMMAND: server |
| 655 | +** COMMAND: ui | |
| 655 | 656 | ** |
| 656 | 657 | ** Usage: %fossil server ?-P|--port TCPPORT? ?REPOSITORY? |
| 658 | +** Or: %fossil ui ?-P|--port TCPPORT? ?REPOSITORY? | |
| 657 | 659 | ** |
| 658 | 660 | ** Open a socket and begin listening and responding to HTTP requests on |
| 659 | 661 | ** TCP port 8080, or on any other TCP port defined by the -P or |
| 660 | 662 | ** --port option. The optional argument is the name of the repository. |
| 661 | 663 | ** The repository argument may be omitted if the working directory is |
| 662 | 664 | ** within an open checkout. |
| 665 | +** | |
| 666 | +** The "ui" command automatically starts a web browser after initializing | |
| 667 | +** the web server. | |
| 663 | 668 | */ |
| 664 | 669 | void cmd_webserver(void){ |
| 665 | 670 | int iPort; |
| 666 | 671 | const char *zPort; |
| 672 | + char *zBrowser; | |
| 673 | + char *zBrowserCmd = 0; | |
| 667 | 674 | |
| 668 | 675 | zPort = find_option("port", "P", 1); |
| 669 | 676 | if( zPort ){ |
| 670 | 677 | iPort = atoi(zPort); |
| 671 | 678 | }else{ |
| @@ -676,11 +683,19 @@ | ||
| 676 | 683 | db_must_be_within_tree(); |
| 677 | 684 | db_close(); |
| 678 | 685 | } |
| 679 | 686 | #ifndef __MINGW32__ |
| 680 | 687 | /* Unix implementation */ |
| 681 | - if( cgi_http_server(iPort) ){ | |
| 688 | + if( g.argv[1][0]=='u' ){ | |
| 689 | +#if !defined(__DARWIN__) && !defined(__APPLE__) | |
| 690 | + zBrowser = db_get("web-browser", "firefox"); | |
| 691 | +#else | |
| 692 | + zBrowser = db_get("web-browser", "open"); | |
| 693 | +#endif | |
| 694 | + zBrowserCmd = mprintf("%s http://localhost:%d/ &", zBrowser, iPort); | |
| 695 | + } | |
| 696 | + if( cgi_http_server(iPort, zBrowserCmd) ){ | |
| 682 | 697 | fossil_fatal("unable to listen on TCP socket %d", iPort); |
| 683 | 698 | } |
| 684 | 699 | g.httpIn = stdin; |
| 685 | 700 | g.httpOut = stdout; |
| 686 | 701 | if( g.fHttpTrace ){ |
| @@ -694,8 +709,12 @@ | ||
| 694 | 709 | } |
| 695 | 710 | cgi_handle_http_request(0); |
| 696 | 711 | process_one_web_page(); |
| 697 | 712 | #else |
| 698 | 713 | /* Win32 implementation */ |
| 699 | - win32_http_server(iPort); | |
| 714 | + if( g.argv[1][0]=='u' ){ | |
| 715 | + zBrowser = db_get("web-browser", "start"); | |
| 716 | + zBrowserCmd = mprintf("%s http://127.0.0.1:%d/", zBrowser, iPort); | |
| 717 | + } | |
| 718 | + win32_http_server(iPort, zBrowserCmd); | |
| 700 | 719 | #endif |
| 701 | 720 | } |
| 702 | 721 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -650,22 +650,29 @@ | |
| 650 | cmd_http(); |
| 651 | } |
| 652 | |
| 653 | /* |
| 654 | ** COMMAND: server |
| 655 | ** |
| 656 | ** Usage: %fossil server ?-P|--port TCPPORT? ?REPOSITORY? |
| 657 | ** |
| 658 | ** Open a socket and begin listening and responding to HTTP requests on |
| 659 | ** TCP port 8080, or on any other TCP port defined by the -P or |
| 660 | ** --port option. The optional argument is the name of the repository. |
| 661 | ** The repository argument may be omitted if the working directory is |
| 662 | ** within an open checkout. |
| 663 | */ |
| 664 | void cmd_webserver(void){ |
| 665 | int iPort; |
| 666 | const char *zPort; |
| 667 | |
| 668 | zPort = find_option("port", "P", 1); |
| 669 | if( zPort ){ |
| 670 | iPort = atoi(zPort); |
| 671 | }else{ |
| @@ -676,11 +683,19 @@ | |
| 676 | db_must_be_within_tree(); |
| 677 | db_close(); |
| 678 | } |
| 679 | #ifndef __MINGW32__ |
| 680 | /* Unix implementation */ |
| 681 | if( cgi_http_server(iPort) ){ |
| 682 | fossil_fatal("unable to listen on TCP socket %d", iPort); |
| 683 | } |
| 684 | g.httpIn = stdin; |
| 685 | g.httpOut = stdout; |
| 686 | if( g.fHttpTrace ){ |
| @@ -694,8 +709,12 @@ | |
| 694 | } |
| 695 | cgi_handle_http_request(0); |
| 696 | process_one_web_page(); |
| 697 | #else |
| 698 | /* Win32 implementation */ |
| 699 | win32_http_server(iPort); |
| 700 | #endif |
| 701 | } |
| 702 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -650,22 +650,29 @@ | |
| 650 | cmd_http(); |
| 651 | } |
| 652 | |
| 653 | /* |
| 654 | ** COMMAND: server |
| 655 | ** COMMAND: ui |
| 656 | ** |
| 657 | ** Usage: %fossil server ?-P|--port TCPPORT? ?REPOSITORY? |
| 658 | ** Or: %fossil ui ?-P|--port TCPPORT? ?REPOSITORY? |
| 659 | ** |
| 660 | ** Open a socket and begin listening and responding to HTTP requests on |
| 661 | ** TCP port 8080, or on any other TCP port defined by the -P or |
| 662 | ** --port option. The optional argument is the name of the repository. |
| 663 | ** The repository argument may be omitted if the working directory is |
| 664 | ** within an open checkout. |
| 665 | ** |
| 666 | ** The "ui" command automatically starts a web browser after initializing |
| 667 | ** the web server. |
| 668 | */ |
| 669 | void cmd_webserver(void){ |
| 670 | int iPort; |
| 671 | const char *zPort; |
| 672 | char *zBrowser; |
| 673 | char *zBrowserCmd = 0; |
| 674 | |
| 675 | zPort = find_option("port", "P", 1); |
| 676 | if( zPort ){ |
| 677 | iPort = atoi(zPort); |
| 678 | }else{ |
| @@ -676,11 +683,19 @@ | |
| 683 | db_must_be_within_tree(); |
| 684 | db_close(); |
| 685 | } |
| 686 | #ifndef __MINGW32__ |
| 687 | /* Unix implementation */ |
| 688 | if( g.argv[1][0]=='u' ){ |
| 689 | #if !defined(__DARWIN__) && !defined(__APPLE__) |
| 690 | zBrowser = db_get("web-browser", "firefox"); |
| 691 | #else |
| 692 | zBrowser = db_get("web-browser", "open"); |
| 693 | #endif |
| 694 | zBrowserCmd = mprintf("%s http://localhost:%d/ &", zBrowser, iPort); |
| 695 | } |
| 696 | if( cgi_http_server(iPort, zBrowserCmd) ){ |
| 697 | fossil_fatal("unable to listen on TCP socket %d", iPort); |
| 698 | } |
| 699 | g.httpIn = stdin; |
| 700 | g.httpOut = stdout; |
| 701 | if( g.fHttpTrace ){ |
| @@ -694,8 +709,12 @@ | |
| 709 | } |
| 710 | cgi_handle_http_request(0); |
| 711 | process_one_web_page(); |
| 712 | #else |
| 713 | /* Win32 implementation */ |
| 714 | if( g.argv[1][0]=='u' ){ |
| 715 | zBrowser = db_get("web-browser", "start"); |
| 716 | zBrowserCmd = mprintf("%s http://127.0.0.1:%d/", zBrowser, iPort); |
| 717 | } |
| 718 | win32_http_server(iPort, zBrowserCmd); |
| 719 | #endif |
| 720 | } |
| 721 |
+7
-1
| --- src/winhttp.c | ||
| +++ src/winhttp.c | ||
| @@ -134,11 +134,11 @@ | ||
| 134 | 134 | |
| 135 | 135 | /* |
| 136 | 136 | ** Start a listening socket and process incoming HTTP requests on |
| 137 | 137 | ** that socket. |
| 138 | 138 | */ |
| 139 | -void win32_http_server(int iPort){ | |
| 139 | +void win32_http_server(int iPort, char *zBrowser){ | |
| 140 | 140 | WSADATA wd; |
| 141 | 141 | SOCKET s; |
| 142 | 142 | SOCKADDR_IN addr; |
| 143 | 143 | int idCnt = 0; |
| 144 | 144 | |
| @@ -159,10 +159,16 @@ | ||
| 159 | 159 | } |
| 160 | 160 | if( listen(s, SOMAXCONN)==SOCKET_ERROR ){ |
| 161 | 161 | closesocket(s); |
| 162 | 162 | fossil_fatal("unable to listen"); |
| 163 | 163 | } |
| 164 | + printf("Listening for HTTP requests on TCP port %d\n", iPort); | |
| 165 | + if( zBrowser ){ | |
| 166 | + printf("Launch webbrowser: %s\n", zBrowser); | |
| 167 | + system(zBrowser); | |
| 168 | + } | |
| 169 | + printf("Type Ctrl-C to stop the HTTP server\n"); | |
| 164 | 170 | for(;;){ |
| 165 | 171 | SOCKET client; |
| 166 | 172 | SOCKADDR_IN client_addr; |
| 167 | 173 | HttpRequest *p; |
| 168 | 174 | int len = sizeof(client_addr); |
| 169 | 175 |
| --- src/winhttp.c | |
| +++ src/winhttp.c | |
| @@ -134,11 +134,11 @@ | |
| 134 | |
| 135 | /* |
| 136 | ** Start a listening socket and process incoming HTTP requests on |
| 137 | ** that socket. |
| 138 | */ |
| 139 | void win32_http_server(int iPort){ |
| 140 | WSADATA wd; |
| 141 | SOCKET s; |
| 142 | SOCKADDR_IN addr; |
| 143 | int idCnt = 0; |
| 144 | |
| @@ -159,10 +159,16 @@ | |
| 159 | } |
| 160 | if( listen(s, SOMAXCONN)==SOCKET_ERROR ){ |
| 161 | closesocket(s); |
| 162 | fossil_fatal("unable to listen"); |
| 163 | } |
| 164 | for(;;){ |
| 165 | SOCKET client; |
| 166 | SOCKADDR_IN client_addr; |
| 167 | HttpRequest *p; |
| 168 | int len = sizeof(client_addr); |
| 169 |
| --- src/winhttp.c | |
| +++ src/winhttp.c | |
| @@ -134,11 +134,11 @@ | |
| 134 | |
| 135 | /* |
| 136 | ** Start a listening socket and process incoming HTTP requests on |
| 137 | ** that socket. |
| 138 | */ |
| 139 | void win32_http_server(int iPort, char *zBrowser){ |
| 140 | WSADATA wd; |
| 141 | SOCKET s; |
| 142 | SOCKADDR_IN addr; |
| 143 | int idCnt = 0; |
| 144 | |
| @@ -159,10 +159,16 @@ | |
| 159 | } |
| 160 | if( listen(s, SOMAXCONN)==SOCKET_ERROR ){ |
| 161 | closesocket(s); |
| 162 | fossil_fatal("unable to listen"); |
| 163 | } |
| 164 | printf("Listening for HTTP requests on TCP port %d\n", iPort); |
| 165 | if( zBrowser ){ |
| 166 | printf("Launch webbrowser: %s\n", zBrowser); |
| 167 | system(zBrowser); |
| 168 | } |
| 169 | printf("Type Ctrl-C to stop the HTTP server\n"); |
| 170 | for(;;){ |
| 171 | SOCKET client; |
| 172 | SOCKADDR_IN client_addr; |
| 173 | HttpRequest *p; |
| 174 | int len = sizeof(client_addr); |
| 175 |