mirror of
				https://github.com/jart/cosmopolitan.git
				synced 2025-10-28 03:44:33 +00:00 
			
		
		
		
	
							parent
							
								
									7abca1531f
								
							
						
					
					
						commit
						83abd68029
					
				
					 6 changed files with 59 additions and 26 deletions
				
			
		|  | @ -463,7 +463,7 @@ static void ProgramRedirect(int code, const char *src, const char *dst) { | |||
|   } else { | ||||
|     i = redirects.n; | ||||
|     redirects.p = xrealloc(redirects.p, (i + 1) * sizeof(*redirects.p)); | ||||
|     for (j = i; j > 0; --j) { | ||||
|     for (j = i; j; --j) { | ||||
|       if (CompareSlices(r.path, r.pathlen, redirects.p[j - 1].path, | ||||
|                         redirects.p[j - 1].pathlen) < 0) { | ||||
|         redirects.p[j] = redirects.p[j - 1]; | ||||
|  | @ -526,6 +526,10 @@ static const char *GetContentType2(const char *path, size_t n) { | |||
| } | ||||
| 
 | ||||
| static const char *GetContentType(struct Asset *a, const char *path, size_t n) { | ||||
|   const char *r; | ||||
|   if (a->file && (r = GetContentType2(a->file->path, strlen(a->file->path)))) { | ||||
|     return r; | ||||
|   } | ||||
|   return firstnonnull( | ||||
|       GetContentType2(path, n), | ||||
|       firstnonnull(GetContentType2(ZIP_LFILE_NAME(zmap + a->lf), | ||||
|  | @ -1114,6 +1118,19 @@ static void ParseRequestUri(void) { | |||
|   u.data = inbuf.p + msg.uri.a; | ||||
|   u.size = msg.uri.b - msg.uri.a; | ||||
|   memset(&request, 0, sizeof(request)); | ||||
|   if (u.size > 8 && !memcmp(u.data, "http", 4)) { | ||||
|     /*
 | ||||
|      * convert http://www.foo.com/index.html -> /www.foo.com/index.html
 | ||||
|      */ | ||||
|     if (u.data[4] == ':' && u.data[5] == '/' && u.data[6] == '/') { | ||||
|       u.data += 6; | ||||
|       u.size -= 6; | ||||
|     } else if (u.data[4] == 's' && u.data[5] == ':' && u.data[6] == '/' && | ||||
|                u.data[7] == '/') { | ||||
|       u.data += 7; | ||||
|       u.size -= 7; | ||||
|     } | ||||
|   } | ||||
|   u.q = u.p = FreeLater(xmalloc(u.size * 2)); | ||||
|   ParsePath(&u, &request.path); | ||||
|   if (u.c == '?') ParseParams(&u, &request.params); | ||||
|  | @ -1201,7 +1218,7 @@ static char *ServeError(int code, const char *reason) { | |||
|   contentlength = reasonlen + 2; | ||||
|   stpcpy(stpcpy(content, reason), "\r\n"); | ||||
|   WARNF("%s %s %`'.*s %d %s", clientaddrstr, kHttpMethod[msg.method], | ||||
|         request.path.n, request.path.p, code, reason); | ||||
|         msg.uri.b - msg.uri.a, inbuf.p + msg.uri.a, code, reason); | ||||
|   return p; | ||||
| } | ||||
| 
 | ||||
|  | @ -1233,9 +1250,10 @@ static char *AppendContentLength(char *p, size_t n) { | |||
| static char *AppendContentRange(char *p, long rangestart, long rangelength, | ||||
|                                 long contentlength) { | ||||
|   long endrange; | ||||
|   CHECK_GE(rangestart + rangelength, rangestart); | ||||
|   CHECK_GT(rangelength, 0); | ||||
|   CHECK_GT(rangestart + rangelength, rangestart); | ||||
|   CHECK_LE(rangestart + rangelength, contentlength); | ||||
|   if (__builtin_add_overflow(rangestart, rangelength, &endrange)) abort(); | ||||
|   endrange = rangestart + rangelength - 1; | ||||
|   p = AppendHeaderName(p, "Content-Range"); | ||||
|   p = stpcpy(p, "bytes "); | ||||
|   p += uint64toarray_radix10(rangestart, p); | ||||
|  | @ -1361,6 +1379,7 @@ static char *ServeAsset(struct Asset *a, const char *path, size_t pathlen) { | |||
|       if (ParseHttpRange(inbuf.p + msg.headers[kHttpRange].a, | ||||
|                          msg.headers[kHttpRange].b - msg.headers[kHttpRange].a, | ||||
|                          contentlength, &rangestart, &rangelength)) { | ||||
|         LOGF("rangestart = %ld rangelength = %ld", rangestart, rangelength); | ||||
|         p = SetStatus(206, "Partial Content"); | ||||
|         p = AppendContentRange(p, rangestart, rangelength, contentlength); | ||||
|         content = AddRange(content, rangestart, rangelength); | ||||
|  | @ -2139,7 +2158,7 @@ Content-Length: 0\r\n\ | |||
| 
 | ||||
| static void LogClose(const char *reason) { | ||||
|   if (amtread) { | ||||
|     WARNF("%s %s with %,ld bytes unprocessed", clientaddrstr, reason); | ||||
|     WARNF("%s %s with %,ld bytes unprocessed", clientaddrstr, reason, amtread); | ||||
|   } else { | ||||
|     DEBUGF("%s %s", clientaddrstr, reason); | ||||
|   } | ||||
|  | @ -2301,25 +2320,22 @@ static char *HandleMessage(void) { | |||
|   if (httpversion > 101) { | ||||
|     return ServeError(505, "HTTP Version Not Supported"); | ||||
|   } | ||||
|   if (msg.method > kHttpOptions || | ||||
|   if (HasHeader(kHttpExpect) && !HeaderEquals(kHttpExpect, "100-continue")) { | ||||
|     return ServeError(417, "Expectation Failed"); | ||||
|   } | ||||
|   if (msg.method == kHttpConnect || | ||||
|       (HasHeader(kHttpTransferEncoding) && | ||||
|        !HeaderEquals(kHttpTransferEncoding, "identity"))) { | ||||
|     return ServeError(501, "Not Implemented"); | ||||
|   } | ||||
|   if (HasHeader(kHttpExpect) && !HeaderEquals(kHttpExpect, "100-continue")) { | ||||
|     return ServeError(417, "Expectation Failed"); | ||||
|   if (!HasHeader(kHttpContentLength) && | ||||
|       (msg.method == kHttpPost || msg.method == kHttpPut)) { | ||||
|     return ServeError(411, "Length Required"); | ||||
|   } | ||||
|   if ((cl = ParseContentLength(inbuf.p + msg.headers[kHttpContentLength].a, | ||||
|                                msg.headers[kHttpContentLength].b - | ||||
|                                    msg.headers[kHttpContentLength].a)) == -1) { | ||||
|     if (HasHeader(kHttpContentLength)) { | ||||
|       return ServeError(400, "Bad Request"); | ||||
|     } else if (msg.method != kHttpGet && msg.method != kHttpHead && | ||||
|                msg.method != kHttpDelete && msg.method != kHttpOptions) { | ||||
|       return ServeError(411, "Length Required"); | ||||
|     } else { | ||||
|       cl = 0; | ||||
|     } | ||||
|     return ServeError(400, "Bad Request"); | ||||
|   } | ||||
|   need = hdrsize + cl; /* synchronization is possible */ | ||||
|   if (need > inbuf.n) { | ||||
|  | @ -2363,7 +2379,7 @@ static char *HandleMessage(void) { | |||
|     return ServeServerOptions(); | ||||
|   } | ||||
|   if (!IsAcceptableHttpRequestPath(request.path.p, request.path.n)) { | ||||
|     WARNF("%s could not parse request request %`'.*s", clientaddrstr, | ||||
|     WARNF("%s could not parse request %`'.*s", clientaddrstr, | ||||
|           msg.uri.b - msg.uri.a, inbuf.p + msg.uri.a); | ||||
|     connectionclose = true; | ||||
|     return ServeError(400, "Bad Request"); | ||||
|  | @ -2399,7 +2415,9 @@ static bool HandleRequest(void) { | |||
|     p = HandleMessage(); | ||||
|   } else { | ||||
|     httpversion = 101; | ||||
|     connectionclose = true; | ||||
|     p = ServeError(400, "Bad Request"); | ||||
|     DEBUGF("%s received garbage %`'.*s", clientaddrstr, amtread, inbuf.p); | ||||
|   } | ||||
|   if (!msgsize) { | ||||
|     amtread = 0; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue