Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:show references to commandline on webpages; add httptrace to windows http server
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | wolfgangHelpCmd
Files: files | file ages | folders
SHA1:d1d1cd122b279dbdf089540c4b24355df59cbf4b
User & Date: wolfgang 2010-10-09 20:13:31
Context
2010-10-10
08:59
added more cross reference check-in: c2ef3715 user: Ratte tags: wolfgangHelpCmd
2010-10-09
20:13
show references to commandline on webpages; add httptrace to windows http server check-in: d1d1cd12 user: wolfgang tags: wolfgangHelpCmd
15:39
merge from trunk check-in: e1d15514 user: wolfgang tags: wolfgangHelpCmd
Changes

Changes to src/browse.c.

245
246
247
248
249
250
251
252
253
    }else{
      @ <li><a href="%s(g.zBaseURL)/finfo?name=%T(zPrefix)%T(zFN)">%h(zFN)
      @     </a></li>
    }
  }
  db_finalize(&q);
  @ </ul></td></tr></table>
  style_footer();
}







|

245
246
247
248
249
250
251
252
253
    }else{
      @ <li><a href="%s(g.zBaseURL)/finfo?name=%T(zPrefix)%T(zFN)">%h(zFN)
      @     </a></li>
    }
  }
  db_finalize(&q);
  @ </ul></td></tr></table>
  style_footer_cmdref("ls");
}

Changes to src/configure.c.

405
406
407
408
409
410
411





412
413
414
415
416
417
418
**    %fossil configuration reset AREA
**
**        Restore the configuration to the default.  AREA as above.
**
** WARNING: Do not import or merge or pull configurations from an
** untrusted source.  The inbound configuration is not checked for
** safety and can introduce security vulnerabilities.





*/
void configuration_cmd(void){
  int n;
  const char *zMethod;
  if( g.argc<3 ){
    usage("export|import|merge|pull|reset ...");
  }







>
>
>
>
>







405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
**    %fossil configuration reset AREA
**
**        Restore the configuration to the default.  AREA as above.
**
** WARNING: Do not import or merge or pull configurations from an
** untrusted source.  The inbound configuration is not checked for
** safety and can introduce security vulnerabilities.
**
** The different parts of this configuration can also be controlled
** using the gui:
**  *  Go to page <a href="setup">Admin</a> and use the subcommands
**
*/
void configuration_cmd(void){
  int n;
  const char *zMethod;
  if( g.argc<3 ){
    usage("export|import|merge|pull|reset ...");
  }

Changes to src/diff.c.

813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
  annotate_file(&ann, fnid, mid, g.okHistory);
  @ <pre>
  for(i=0; i<ann.nOrig; i++){
    ((char*)ann.aOrig[i].z)[ann.aOrig[i].n] = 0;
    @ %s(ann.aOrig[i].zSrc): %h(ann.aOrig[i].z)
  }
  @ </pre>
  style_footer();
}

/*
** COMMAND: annotate
**
** %fossil annotate FILENAME
**







|







813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
  annotate_file(&ann, fnid, mid, g.okHistory);
  @ <pre>
  for(i=0; i<ann.nOrig; i++){
    ((char*)ann.aOrig[i].z)[ann.aOrig[i].n] = 0;
    @ %s(ann.aOrig[i].zSrc): %h(ann.aOrig[i].z)
  }
  @ </pre>
  style_footer_cmdref("annotate");
}

/*
** COMMAND: annotate
**
** %fossil annotate FILENAME
**

Changes to src/finfo.c.

210
211
212
213
214
215
216
217
218
    }else{
      @ <tr><td></td><td><div style="width:%d(pGraph->mxRail*20+30)px;"></div>
      @     </td></tr>
    }
  }
  @ </table>
  timeline_output_graph_javascript(pGraph);
  style_footer();
}







|

210
211
212
213
214
215
216
217
218
    }else{
      @ <tr><td></td><td><div style="width:%d(pGraph->mxRail*20+30)px;"></div>
      @     </td></tr>
    }
  }
  @ </table>
  timeline_output_graph_javascript(pGraph);
  style_footer_cmdref("finfo");
}

Changes to src/info.c.

465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
...
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
...
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
...
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
....
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
....
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
  while( db_step(&q)==SQLITE_ROW ){
    const char *zName = db_column_text(&q,0);
    const char *zOld = db_column_text(&q,1);
    const char *zNew = db_column_text(&q,2);
    append_file_change_line(zName, zOld, zNew, showDiff);
  }
  db_finalize(&q);
  style_footer();
}

/*
** WEBPAGE: winfo
** URL:  /winfo?name=RID
**
** Return information about a wiki page.
................................................................................
      blob_init(&wiki, m.zWiki, -1);
      @ <div class="section">Content</div>
      wiki_convert(&wiki, 0, 0);
      blob_reset(&wiki);
    }
    manifest_clear(&m);
  }
  style_footer();
}

/*
** Show a webpage error message
*/
void webpage_error(const char *zFormat, ...){
  va_list ap;
................................................................................
    @ <tr><td>to:</td><td><input type="text" size="40"
    @  name="to" value="%s(zTo?zTo:"")" /></td><td></td></tr>
    @ <tr><td>details:</td><td><input type="checkbox" name="detail"
    @  checked="checked" value="1" /></td></tr>
    @ <tr><td></td><td></td><td>
    @  <input type="submit" name="diff" value="diff" /></td></tr></table>
    @ </div></form>
    style_footer();
    return;
  }else if(    vdiff_parse_manifest("from", &ridFrom, &mFrom) 
            || vdiff_parse_manifest("to", &ridTo, &mTo)
  ){
    return;
  }
  style_header("Check-in Differences");
................................................................................
      iFrom++;
      iTo++;
    }
  }
  manifest_clear(&mFrom);
  manifest_clear(&mTo);

  style_footer();
}

/*
** Write a description of an object to the www reply.
**
** If the object is a file then mention:
**
................................................................................
    }else{
      @ <pre>
      hexdump(&content);
      @ </pre>
    }
    @ </blockquote>
  }
  style_footer();
}  

/*
** WEBPAGE: tinfo
** URL: /tinfo?name=ARTIFACTID
**
** Show the details of a ticket change control artifact.
................................................................................
    @ </p>
  }
  @
  @ <ol>
  free(zDate);
  ticket_output_change_artifact(&m);
  manifest_clear(&m);
  style_footer();
}


/*
** WEBPAGE: info
** URL: info/ARTIFACTID
**







|







 







|







 







|







 







|







 







|







 







|







465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
...
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
...
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
...
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
....
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
....
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
  while( db_step(&q)==SQLITE_ROW ){
    const char *zName = db_column_text(&q,0);
    const char *zOld = db_column_text(&q,1);
    const char *zNew = db_column_text(&q,2);
    append_file_change_line(zName, zOld, zNew, showDiff);
  }
  db_finalize(&q);
  style_footer_cmdref("info");
}

/*
** WEBPAGE: winfo
** URL:  /winfo?name=RID
**
** Return information about a wiki page.
................................................................................
      blob_init(&wiki, m.zWiki, -1);
      @ <div class="section">Content</div>
      wiki_convert(&wiki, 0, 0);
      blob_reset(&wiki);
    }
    manifest_clear(&m);
  }
  style_footer_cmdref("info");
}

/*
** Show a webpage error message
*/
void webpage_error(const char *zFormat, ...){
  va_list ap;
................................................................................
    @ <tr><td>to:</td><td><input type="text" size="40"
    @  name="to" value="%s(zTo?zTo:"")" /></td><td></td></tr>
    @ <tr><td>details:</td><td><input type="checkbox" name="detail"
    @  checked="checked" value="1" /></td></tr>
    @ <tr><td></td><td></td><td>
    @  <input type="submit" name="diff" value="diff" /></td></tr></table>
    @ </div></form>
    style_footer_cmdref("diff");
    return;
  }else if(    vdiff_parse_manifest("from", &ridFrom, &mFrom) 
            || vdiff_parse_manifest("to", &ridTo, &mTo)
  ){
    return;
  }
  style_header("Check-in Differences");
................................................................................
      iFrom++;
      iTo++;
    }
  }
  manifest_clear(&mFrom);
  manifest_clear(&mTo);

  style_footer_cmdref("diff");
}

/*
** Write a description of an object to the www reply.
**
** If the object is a file then mention:
**
................................................................................
    }else{
      @ <pre>
      hexdump(&content);
      @ </pre>
    }
    @ </blockquote>
  }
  style_footer_cmdref( "artifact" );
}  

/*
** WEBPAGE: tinfo
** URL: /tinfo?name=ARTIFACTID
**
** Show the details of a ticket change control artifact.
................................................................................
    @ </p>
  }
  @
  @ <ol>
  free(zDate);
  ticket_output_change_artifact(&m);
  manifest_clear(&m);
  style_footer_cmdref("info");
}


/*
** WEBPAGE: info
** URL: info/ARTIFACTID
**

Changes to src/setup.c.

215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
...
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
  @ privileges of <span class="usertype">developer</span>,
  @ <span class="usertype">anonymous</span>, and
  @ <span class="usertype">nobody</span>.
  @ </p></li>
  @
  @ </ol>
  @ </td></tr></table>
  style_footer();
}

/*
** Return true if zPw is a valid password string.  A valid
** password string is:
**
**  (1)  A zero-length string, or
................................................................................
  @ <span class="usertype">developer</span>
  @ user.  Similarly, the <span class="usertype">reader</span> user is a 
  @ template for users who are allowed more access than
  @ <span class="usertype">anonymous</span>,
  @ but less than a <span class="usertype">developer</span>.
  @ </p></li>
  @ </ul>
  style_footer();
}


/*
** Generate a checkbox for an attribute.
*/
static void onoff_attribute(







|







 







|







215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
...
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
  @ privileges of <span class="usertype">developer</span>,
  @ <span class="usertype">anonymous</span>, and
  @ <span class="usertype">nobody</span>.
  @ </p></li>
  @
  @ </ol>
  @ </td></tr></table>
  style_footer_cmdref("user");
}

/*
** Return true if zPw is a valid password string.  A valid
** password string is:
**
**  (1)  A zero-length string, or
................................................................................
  @ <span class="usertype">developer</span>
  @ user.  Similarly, the <span class="usertype">reader</span> user is a 
  @ template for users who are allowed more access than
  @ <span class="usertype">anonymous</span>,
  @ but less than a <span class="usertype">developer</span>.
  @ </p></li>
  @ </ul>
  style_footer_cmdref("user");
}


/*
** Generate a checkbox for an attribute.
*/
static void onoff_attribute(

Changes to src/style.c.

112
113
114
115
116
117
118











119
120
121
122
123
124
125
...
237
238
239
240
241
242
243

244
245
246
247
248
249
250
...
733
734
735
736
737
738
739








740
741
742
743
744
745
746
  if( g.thTrace ) Th_Trace("END_HEADER<br />\n", -1);
  Th_Unstore("title");   /* Avoid collisions with ticket field names */
  cgi_destination(CGI_BODY);
  g.cgiOutput = 1;
  headerHasBeenGenerated = 1;
  sideboxUsed = 0;
}












/*
** Draw the footer at the bottom of the page.
*/
void style_footer(void){
  const char *zFooter;

................................................................................
@   html "<a href='$baseurl/setup_ulist'>Users</a> "
@ }
@ if {[info exists login]} {
@   html "<a href='$baseurl/login'>Logout</a> "
@ } else {
@   html "<a href='$baseurl/login'>Login</a> "
@ }

@ </th1></div>
;

/*
** The default page footer
*/
const char zDefaultFooter[] = 
................................................................................
    @   color: blue;
  },
  { "a.hidden",
    "format for links, that should not be very visible",
    @   font-size: xx-small;
    @   color: #aaaaaa;
  },








  { 0,
    0,
    0
  }
};

/*







>
>
>
>
>
>
>
>
>
>
>







 







>







 







>
>
>
>
>
>
>
>







112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
...
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
...
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
  if( g.thTrace ) Th_Trace("END_HEADER<br />\n", -1);
  Th_Unstore("title");   /* Avoid collisions with ticket field names */
  cgi_destination(CGI_BODY);
  g.cgiOutput = 1;
  headerHasBeenGenerated = 1;
  sideboxUsed = 0;
}

/*
** append a reference to command line to a web page
** and generate the footer
*/
void style_footer_cmdref( const char * const zCmd ){
  @ <div class="cmdref">See also command line help:
  @  <a href="help?cmd=%s(zCmd)">%s(zCmd)</a>
  @ </div>
  style_footer();
}

/*
** Draw the footer at the bottom of the page.
*/
void style_footer(void){
  const char *zFooter;

................................................................................
@   html "<a href='$baseurl/setup_ulist'>Users</a> "
@ }
@ if {[info exists login]} {
@   html "<a href='$baseurl/login'>Logout</a> "
@ } else {
@   html "<a href='$baseurl/login'>Login</a> "
@ }
@ html "<small><sup><a href='$baseurl/help'>?</a></sup></small>"
@ </th1></div>
;

/*
** The default page footer
*/
const char zDefaultFooter[] = 
................................................................................
    @   color: blue;
  },
  { "a.hidden",
    "format for links, that should not be very visible",
    @   font-size: xx-small;
    @   color: #aaaaaa;
  },
  { "div.cmdref",
    "format for references to command line help entries the actual gui page."
    "set \"display\" to \"none\" to suppress the display",
    @   font-size: small;
    @   text-align: right;
    @   font-family: monospace;
    @   color: #777777;
  },
  { 0,
    0,
    0
  }
};

/*

Changes to src/timeline.c.

950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
....
1093
1094
1095
1096
1097
1098
1099


1100
1101
1102
1103
1104
1105
1106
  }
  blob_zero(&sql);
  db_prepare(&q, "SELECT * FROM timeline ORDER BY timestamp DESC /*scan*/");
  @ <h2>%b(&desc)</h2>
  blob_reset(&desc);
  www_print_timeline(&q, tmFlags, 0);
  db_finalize(&q);
  style_footer();
}

/*
** The input query q selects various records.  Print a human-readable
** summary of those records.
**
** Limit the number of entries printed to nLine.
................................................................................
**     w  = wiki commits only
**     ci = file commits only
**     t  = tickets only
**     e  = events only
**
** The information can also be used in the gui:
**  * go to the <a href="timeline">timeline</a> page


*/
void timeline_cmd(void){
  Stmt q;
  int n, k;
  const char *zCount;
  const char *zType;
  char *zOrigin;







|







 







>
>







950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
....
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
  }
  blob_zero(&sql);
  db_prepare(&q, "SELECT * FROM timeline ORDER BY timestamp DESC /*scan*/");
  @ <h2>%b(&desc)</h2>
  blob_reset(&desc);
  www_print_timeline(&q, tmFlags, 0);
  db_finalize(&q);
  style_footer_cmdref("timeline");
}

/*
** The input query q selects various records.  Print a human-readable
** summary of those records.
**
** Limit the number of entries printed to nLine.
................................................................................
**     w  = wiki commits only
**     ci = file commits only
**     t  = tickets only
**     e  = events only
**
** The information can also be used in the gui:
**  * go to the <a href="timeline">timeline</a> page
**
** See also: <a>descendants</a>
*/
void timeline_cmd(void){
  Stmt q;
  int n, k;
  const char *zCount;
  const char *zType;
  char *zOrigin;

Changes to src/tkt.c.

364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
    }
    if( cnt ){
      @ </ul>
    }
    db_finalize(&q);
  }
 
  style_footer();
}

/*
** TH command:   append_field FIELD STRING
**
** FIELD is the name of a database column to which we might want
** to append text.  STRING is the text to be appended to that







|







364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
    }
    if( cnt ){
      @ </ul>
    }
    db_finalize(&q);
  }
 
  style_footer_cmdref("info");
}

/*
** TH command:   append_field FIELD STRING
**
** FIELD is the name of a database column to which we might want
** to append text.  STRING is the text to be appended to that

Changes to src/user.c.

169
170
171
172
173
174
175






176
177
178
179
180
181
182
**        Create a new user in the repository.  Users can never be
**        deleted.  They can be denied all access but they must continue
**        to exist in the database.
**
**    %fossil user password USERNAME ?PASSWORD?
**
**        Change the web access password for a user.






*/
void user_cmd(void){
  int n;
  db_find_and_open_repository(1);
  if( g.argc<3 ){
    usage("capabilities|default|list|new|password ...");
  }







>
>
>
>
>
>







169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
**        Create a new user in the repository.  Users can never be
**        deleted.  They can be denied all access but they must continue
**        to exist in the database.
**
**    %fossil user password USERNAME ?PASSWORD?
**
**        Change the web access password for a user.
**        Users can change their own password on the
**        <a href="login">Login/Logout</a> gui page.
**
** Administrators can also use the gui: 
**  *  Go to page <a href="setup">Admin</a>
**  ** and click <a href="setup_ulist">Users</a>
*/
void user_cmd(void){
  int n;
  db_find_and_open_repository(1);
  if( g.argc<3 ){
    usage("capabilities|default|list|new|password ...");
  }

Changes to src/wiki.c.

162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
...
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
...
897
898
899
900
901
902
903



904
905
906
907
908
909
910
    @ <li> <a href="%s(g.zBaseURL)/wcontent">List of All Wiki Pages</a>
    @      available on this server.</li>
    @ <li> <form method="get" action="%s(g.zBaseURL)/wfind"><div>
    @     Search wiki titles: <input type="text" name="title"/>
    @  &nbsp; <input type="submit" /></div></form>
    @ </li>
    @ </ul>
    style_footer();
    return;
  }
  if( check_name(zPageName) ) return;
  isSandbox = is_sandbox(zPageName);
  if( isSandbox ){
    zBody = db_get("sandbox",zBody);
  }else{
................................................................................
      @ <li><a href="%s(g.zTop)/wiki?name=%T(zName)">%h(zName)</a></li>
    }else if( showAll ){
      @ <li><a href="%s(g.zTop)/wiki?name=%T(zName)"><s>%h(zName)</s></a></li>
    }
  }
  db_finalize(&q);
  @ </ul>
  style_footer();
}

/*
** WEBPAGE: wfind
**
** URL: /wfind?title=TITLE
** List all wiki pages whose titles contain the search text
................................................................................
**        Lists the artifact ID and/or Date of last change along with
**        each entry name, delimited by the -s char.
**
**     %fossil wiki diff ?ARTIFACT? ?-f infile[=stdin]? EntryName
**
**        Diffs the local copy of a page with a given version (defaulting
**        to the head version).



*/
void wiki_cmd(void){
  int n;
  db_find_and_open_repository(1);
  if( g.argc<3 ){
    goto wiki_cmd_usage;
  }







|







 







|







 







>
>
>







162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
...
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
...
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
    @ <li> <a href="%s(g.zBaseURL)/wcontent">List of All Wiki Pages</a>
    @      available on this server.</li>
    @ <li> <form method="get" action="%s(g.zBaseURL)/wfind"><div>
    @     Search wiki titles: <input type="text" name="title"/>
    @  &nbsp; <input type="submit" /></div></form>
    @ </li>
    @ </ul>
    style_footer_cmdref("wiki");
    return;
  }
  if( check_name(zPageName) ) return;
  isSandbox = is_sandbox(zPageName);
  if( isSandbox ){
    zBody = db_get("sandbox",zBody);
  }else{
................................................................................
      @ <li><a href="%s(g.zTop)/wiki?name=%T(zName)">%h(zName)</a></li>
    }else if( showAll ){
      @ <li><a href="%s(g.zTop)/wiki?name=%T(zName)"><s>%h(zName)</s></a></li>
    }
  }
  db_finalize(&q);
  @ </ul>
  style_footer_cmdref("wiki");
}

/*
** WEBPAGE: wfind
**
** URL: /wfind?title=TITLE
** List all wiki pages whose titles contain the search text
................................................................................
**        Lists the artifact ID and/or Date of last change along with
**        each entry name, delimited by the -s char.
**
**     %fossil wiki diff ?ARTIFACT? ?-f infile[=stdin]? EntryName
**
**        Diffs the local copy of a page with a given version (defaulting
**        to the head version).
**
** The wiki format is explained on the <a href="wiki">Wiki</a> subpage
** <a href="wiki_rules">Formatting rules</a>.
*/
void wiki_cmd(void){
  int n;
  db_find_and_open_repository(1);
  if( g.argc<3 ){
    goto wiki_cmd_usage;
  }

Changes to src/winhttp.c.

87
88
89
90
91
92
93



94
95
96
97
98
99
100
...
107
108
109
110
111
112
113



114
115
116



117
118
119




120
121
122
123
124
125
126
...
213
214
215
216
217
218
219



220
221
222
223
224
225
226
    zHdr[amt] = 0;
    z = strstr(zHdr, "\r\n\r\n");
    if( z ){
      wanted = find_content_length(zHdr) + (&z[4]-zHdr) - amt;
      break;
    }
  }



  if( amt>=sizeof(zHdr) ) goto end_request;
  out = fopen(zRequestFName, "wb");
  if( out==0 ) goto end_request;
  fwrite(zHdr, 1, amt, out);
  while( wanted>0 ){
    got = recv(p->s, zHdr, sizeof(zHdr), 0);
    if( got==SOCKET_ERROR ) goto end_request;
................................................................................
  }
  fclose(out);
  out = 0;
  sprintf(zCmd, "\"%s\" http \"%s\" %s %s %s%s",
    g.argv[0], g.zRepositoryName, zRequestFName, zReplyFName, 
    inet_ntoa(p->addr.sin_addr), p->zNotFound
  );



  portable_system(zCmd);
  in = fopen(zReplyFName, "rb");
  if( in ){



    while( (got = fread(zHdr, 1, sizeof(zHdr), in))>0 ){
      send(p->s, zHdr, got, 0);
    }




  }

end_request:
  if( out ) fclose(out);
  if( in ) fclose(in);
  closesocket(p->s);
  unlink(zRequestFName);
................................................................................
    if( p==0 ){
      fossil_fatal("out of memory");
    }
    p->id = ++idCnt;
    p->s = client;
    p->addr = client_addr;
    p->zNotFound = zNotFoundOption;



    _beginthread(win32_process_one_http_request, 0, (void*)p);
  }
  closesocket(s);
  WSACleanup();
}

#endif /* _WIN32  -- This code is for win32 only */







>
>
>







 







>
>
>



>
>
>



>
>
>
>







 







>
>
>







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
...
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
...
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
    zHdr[amt] = 0;
    z = strstr(zHdr, "\r\n\r\n");
    if( z ){
      wanted = find_content_length(zHdr) + (&z[4]-zHdr) - amt;
      break;
    }
  }
  if( g.fHttpTrace ){
    fprintf(stderr,"HTTPTRACE(%p): got header '%s'\n",pAppData,zHdr);
  }
  if( amt>=sizeof(zHdr) ) goto end_request;
  out = fopen(zRequestFName, "wb");
  if( out==0 ) goto end_request;
  fwrite(zHdr, 1, amt, out);
  while( wanted>0 ){
    got = recv(p->s, zHdr, sizeof(zHdr), 0);
    if( got==SOCKET_ERROR ) goto end_request;
................................................................................
  }
  fclose(out);
  out = 0;
  sprintf(zCmd, "\"%s\" http \"%s\" %s %s %s%s",
    g.argv[0], g.zRepositoryName, zRequestFName, zReplyFName, 
    inet_ntoa(p->addr.sin_addr), p->zNotFound
  );
  if( g.fHttpTrace ){
    fprintf(stderr,"HTTPTRACE(%p): calling '%s'\n",pAppData,zCmd);
  }
  portable_system(zCmd);
  in = fopen(zReplyFName, "rb");
  if( in ){
    if( g.fHttpTrace ){
      fprintf(stderr,"HTTPTRACE(%p): read reply '%s'\n",pAppData,zReplyFName);
    }
    while( (got = fread(zHdr, 1, sizeof(zHdr), in))>0 ){
      send(p->s, zHdr, got, 0);
    }
  }else{
    if( g.fHttpTrace ){
      fprintf(stderr,"HTTPTRACE(%p): no reply '%s'\n",pAppData,zReplyFName);
    }
  }

end_request:
  if( out ) fclose(out);
  if( in ) fclose(in);
  closesocket(p->s);
  unlink(zRequestFName);
................................................................................
    if( p==0 ){
      fossil_fatal("out of memory");
    }
    p->id = ++idCnt;
    p->s = client;
    p->addr = client_addr;
    p->zNotFound = zNotFoundOption;
    if( g.fHttpTrace ){
      fprintf(stderr,"HTTPTRACE(%p): start new request thread\n",p);
    }
    _beginthread(win32_process_one_http_request, 0, (void*)p);
  }
  closesocket(s);
  WSACleanup();
}

#endif /* _WIN32  -- This code is for win32 only */