Initial import

This commit is contained in:
Justine Tunney 2020-06-15 07:18:57 -07:00
commit c91b3c5006
14915 changed files with 590219 additions and 0 deletions

View file

@ -0,0 +1,31 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/alg/alg.h"
#include "libc/bits/bits.h"
#include "libc/bits/pushpop.h"
#include "net/http/http.h"
void clearhttprequest(struct HttpRequest *req) {
req->uri.i = pushpop(0);
req->method.i = pushpop(0);
req->version.i = pushpop(0);
req->scratch.i = pushpop(0);
critbit0_clear(&req->headers);
}

662
net/http/csscolor.h Normal file
View file

@ -0,0 +1,662 @@
#ifndef COSMOPOLITAN_NET_HTTP_CSSCOLOR_H_
#define COSMOPOLITAN_NET_HTTP_CSSCOLOR_H_
#define ALICEBLUE 0xFFFFF8F0u
#define ANTIQUEWHITE 0xFFD7EBFAu
#define ANTIQUEWHITE1 0xFFDBEFFFu
#define ANTIQUEWHITE2 0xFFCCDFEEu
#define ANTIQUEWHITE3 0xFFB0C0CDu
#define ANTIQUEWHITE4 0xFF78838Bu
#define AQUAMARINE 0xFFD4FF7Fu
#define AQUAMARINE1 0xFFD4FF7Fu
#define AQUAMARINE2 0xFFC6EE76u
#define AQUAMARINE3 0xFFAACD66u
#define AQUAMARINE4 0xFF748B45u
#define AZURE 0xFFFFFFF0u
#define AZURE1 0xFFFFFFF0u
#define AZURE2 0xFFEEEEE0u
#define AZURE3 0xFFCDCDC1u
#define AZURE4 0xFF8B8B83u
#define BEIGE 0xFFDCF5F5u
#define BISQUE 0xFFC4E4FFu
#define BISQUE1 0xFFC4E4FFu
#define BISQUE2 0xFFB7D5EEu
#define BISQUE3 0xFF9EB7CDu
#define BISQUE4 0xFF6B7D8Bu
#define BLACK 0xFF000000u
#define BLANCHEDALMOND 0xFFCDEBFFu
#define BLUE 0xFFFF0000u
#define BLUE1 0xFFFF0000u
#define BLUE2 0xFFEE0000u
#define BLUE3 0xFFCD0000u
#define BLUE4 0xFF8B0000u
#define BLUEVIOLET 0xFFE22B8Au
#define BROWN 0xFF2A2AA5u
#define BROWN1 0xFF4040FFu
#define BROWN2 0xFF3B3BEEu
#define BROWN3 0xFF3333CDu
#define BROWN4 0xFF23238Bu
#define BURLYWOOD 0xFF87B8DEu
#define BURLYWOOD1 0xFF9BD3FFu
#define BURLYWOOD2 0xFF91C5EEu
#define BURLYWOOD3 0xFF7DAACDu
#define BURLYWOOD4 0xFF55738Bu
#define CADETBLUE 0xFFA09E5Fu
#define CADETBLUE1 0xFFFFF598u
#define CADETBLUE2 0xFFEEE58Eu
#define CADETBLUE3 0xFFCDC57Au
#define CADETBLUE4 0xFF8B8653u
#define CHARTREUSE 0xFF00FF7Fu
#define CHARTREUSE1 0xFF00FF7Fu
#define CHARTREUSE2 0xFF00EE76u
#define CHARTREUSE3 0xFF00CD66u
#define CHARTREUSE4 0xFF008B45u
#define CHOCOLATE 0xFF1E69D2u
#define CHOCOLATE1 0xFF247FFFu
#define CHOCOLATE2 0xFF2176EEu
#define CHOCOLATE3 0xFF1D66CDu
#define CHOCOLATE4 0xFF13458Bu
#define CORAL 0xFF507FFFu
#define CORAL1 0xFF5672FFu
#define CORAL2 0xFF506AEEu
#define CORAL3 0xFF455BCDu
#define CORAL4 0xFF2F3E8Bu
#define CORNFLOWERBLUE 0xFFED9564u
#define CORNSILK 0xFFDCF8FFu
#define CORNSILK1 0xFFDCF8FFu
#define CORNSILK2 0xFFCDE8EEu
#define CORNSILK3 0xFFB1C8CDu
#define CORNSILK4 0xFF78888Bu
#define CYAN 0xFFFFFF00u
#define CYAN1 0xFFFFFF00u
#define CYAN2 0xFFEEEE00u
#define CYAN3 0xFFCDCD00u
#define CYAN4 0xFF8B8B00u
#define DARKBLUE 0xFF8B0000u
#define DARKCYAN 0xFF8B8B00u
#define DARKGOLDENROD 0xFF0B86B8u
#define DARKGOLDENROD1 0xFF0FB9FFu
#define DARKGOLDENROD2 0xFF0EADEEu
#define DARKGOLDENROD3 0xFF0C95CDu
#define DARKGOLDENROD4 0xFF08658Bu
#define DARKGRAY 0xFFA9A9A9u
#define DARKGREEN 0xFF006400u
#define DARKGREY 0xFFA9A9A9u
#define DARKKHAKI 0xFF6BB7BDu
#define DARKMAGENTA 0xFF8B008Bu
#define DARKOLIVEGREEN 0xFF2F6B55u
#define DARKOLIVEGREEN1 0xFF70FFCAu
#define DARKOLIVEGREEN2 0xFF68EEBCu
#define DARKOLIVEGREEN3 0xFF5ACDA2u
#define DARKOLIVEGREEN4 0xFF3D8B6Eu
#define DARKORANGE 0xFF008CFFu
#define DARKORANGE1 0xFF007FFFu
#define DARKORANGE2 0xFF0076EEu
#define DARKORANGE3 0xFF0066CDu
#define DARKORANGE4 0xFF00458Bu
#define DARKORCHID 0xFFCC3299u
#define DARKORCHID1 0xFFFF3EBFu
#define DARKORCHID2 0xFFEE3AB2u
#define DARKORCHID3 0xFFCD329Au
#define DARKORCHID4 0xFF8B2268u
#define DARKRED 0xFF00008Bu
#define DARKSALMON 0xFF7A96E9u
#define DARKSEAGREEN 0xFF8FBC8Fu
#define DARKSEAGREEN1 0xFFC1FFC1u
#define DARKSEAGREEN2 0xFFB4EEB4u
#define DARKSEAGREEN3 0xFF9BCD9Bu
#define DARKSEAGREEN4 0xFF698B69u
#define DARKSLATEBLUE 0xFF8B3D48u
#define DARKSLATEGRAY 0xFF4F4F2Fu
#define DARKSLATEGRAY1 0xFFFFFF97u
#define DARKSLATEGRAY2 0xFFEEEE8Du
#define DARKSLATEGRAY3 0xFFCDCD79u
#define DARKSLATEGRAY4 0xFF8B8B52u
#define DARKSLATEGREY 0xFF4F4F2Fu
#define DARKTURQUOISE 0xFFD1CE00u
#define DARKVIOLET 0xFFD30094u
#define DEEPPINK 0xFF9314FFu
#define DEEPPINK1 0xFF9314FFu
#define DEEPPINK2 0xFF8912EEu
#define DEEPPINK3 0xFF7610CDu
#define DEEPPINK4 0xFF500A8Bu
#define DEEPSKYBLUE 0xFFFFBF00u
#define DEEPSKYBLUE1 0xFFFFBF00u
#define DEEPSKYBLUE2 0xFFEEB200u
#define DEEPSKYBLUE3 0xFFCD9A00u
#define DEEPSKYBLUE4 0xFF8B6800u
#define DIMGRAY 0xFF696969u
#define DIMGREY 0xFF696969u
#define DODGERBLUE 0xFFFF901Eu
#define DODGERBLUE1 0xFFFF901Eu
#define DODGERBLUE2 0xFFEE861Cu
#define DODGERBLUE3 0xFFCD7418u
#define DODGERBLUE4 0xFF8B4E10u
#define FIREBRICK 0xFF2222B2u
#define FIREBRICK1 0xFF3030FFu
#define FIREBRICK2 0xFF2C2CEEu
#define FIREBRICK3 0xFF2626CDu
#define FIREBRICK4 0xFF1A1A8Bu
#define FLORALWHITE 0xFFF0FAFFu
#define FORESTGREEN 0xFF228B22u
#define GAINSBORO 0xFFDCDCDCu
#define GHOSTWHITE 0xFFFFF8F8u
#define GOLD 0xFF00D7FFu
#define GOLD1 0xFF00D7FFu
#define GOLD2 0xFF00C9EEu
#define GOLD3 0xFF00ADCDu
#define GOLD4 0xFF00758Bu
#define GOLDENROD 0xFF20A5DAu
#define GOLDENROD1 0xFF25C1FFu
#define GOLDENROD2 0xFF22B4EEu
#define GOLDENROD3 0xFF1D9BCDu
#define GOLDENROD4 0xFF14698Bu
#define GRAY 0xFFBEBEBEu
#define GRAY0 0xFF000000u
#define GRAY1 0xFF030303u
#define GRAY10 0xFF1A1A1Au
#define GRAY100 0xFFFFFFFFu
#define GRAY11 0xFF1C1C1Cu
#define GRAY12 0xFF1F1F1Fu
#define GRAY13 0xFF212121u
#define GRAY14 0xFF242424u
#define GRAY15 0xFF262626u
#define GRAY16 0xFF292929u
#define GRAY17 0xFF2B2B2Bu
#define GRAY18 0xFF2E2E2Eu
#define GRAY19 0xFF303030u
#define GRAY2 0xFF050505u
#define GRAY20 0xFF333333u
#define GRAY21 0xFF363636u
#define GRAY22 0xFF383838u
#define GRAY23 0xFF3B3B3Bu
#define GRAY24 0xFF3D3D3Du
#define GRAY25 0xFF404040u
#define GRAY26 0xFF424242u
#define GRAY27 0xFF454545u
#define GRAY28 0xFF474747u
#define GRAY29 0xFF4A4A4Au
#define GRAY3 0xFF080808u
#define GRAY30 0xFF4D4D4Du
#define GRAY31 0xFF4F4F4Fu
#define GRAY32 0xFF525252u
#define GRAY33 0xFF545454u
#define GRAY34 0xFF575757u
#define GRAY35 0xFF595959u
#define GRAY36 0xFF5C5C5Cu
#define GRAY37 0xFF5E5E5Eu
#define GRAY38 0xFF616161u
#define GRAY39 0xFF636363u
#define GRAY4 0xFF0A0A0Au
#define GRAY40 0xFF666666u
#define GRAY41 0xFF696969u
#define GRAY42 0xFF6B6B6Bu
#define GRAY43 0xFF6E6E6Eu
#define GRAY44 0xFF707070u
#define GRAY45 0xFF737373u
#define GRAY46 0xFF757575u
#define GRAY47 0xFF787878u
#define GRAY48 0xFF7A7A7Au
#define GRAY49 0xFF7D7D7Du
#define GRAY5 0xFF0D0D0Du
#define GRAY50 0xFF7F7F7Fu
#define GRAY51 0xFF828282u
#define GRAY52 0xFF858585u
#define GRAY53 0xFF878787u
#define GRAY54 0xFF8A8A8Au
#define GRAY55 0xFF8C8C8Cu
#define GRAY56 0xFF8F8F8Fu
#define GRAY57 0xFF919191u
#define GRAY58 0xFF949494u
#define GRAY59 0xFF969696u
#define GRAY6 0xFF0F0F0Fu
#define GRAY60 0xFF999999u
#define GRAY61 0xFF9C9C9Cu
#define GRAY62 0xFF9E9E9Eu
#define GRAY63 0xFFA1A1A1u
#define GRAY64 0xFFA3A3A3u
#define GRAY65 0xFFA6A6A6u
#define GRAY66 0xFFA8A8A8u
#define GRAY67 0xFFABABABu
#define GRAY68 0xFFADADADu
#define GRAY69 0xFFB0B0B0u
#define GRAY7 0xFF121212u
#define GRAY70 0xFFB3B3B3u
#define GRAY71 0xFFB5B5B5u
#define GRAY72 0xFFB8B8B8u
#define GRAY73 0xFFBABABAu
#define GRAY74 0xFFBDBDBDu
#define GRAY75 0xFFBFBFBFu
#define GRAY76 0xFFC2C2C2u
#define GRAY77 0xFFC4C4C4u
#define GRAY78 0xFFC7C7C7u
#define GRAY79 0xFFC9C9C9u
#define GRAY8 0xFF141414u
#define GRAY80 0xFFCCCCCCu
#define GRAY81 0xFFCFCFCFu
#define GRAY82 0xFFD1D1D1u
#define GRAY83 0xFFD4D4D4u
#define GRAY84 0xFFD6D6D6u
#define GRAY85 0xFFD9D9D9u
#define GRAY86 0xFFDBDBDBu
#define GRAY87 0xFFDEDEDEu
#define GRAY88 0xFFE0E0E0u
#define GRAY89 0xFFE3E3E3u
#define GRAY9 0xFF171717u
#define GRAY90 0xFFE5E5E5u
#define GRAY91 0xFFE8E8E8u
#define GRAY92 0xFFEBEBEBu
#define GRAY93 0xFFEDEDEDu
#define GRAY94 0xFFF0F0F0u
#define GRAY95 0xFFF2F2F2u
#define GRAY96 0xFFF5F5F5u
#define GRAY97 0xFFF7F7F7u
#define GRAY98 0xFFFAFAFAu
#define GRAY99 0xFFFCFCFCu
#define GREEN 0xFF00FF00u
#define GREEN1 0xFF00FF00u
#define GREEN2 0xFF00EE00u
#define GREEN3 0xFF00CD00u
#define GREEN4 0xFF008B00u
#define GREENYELLOW 0xFF2FFFADu
#define GREY 0xFFBEBEBEu
#define GREY0 0xFF000000u
#define GREY1 0xFF030303u
#define GREY10 0xFF1A1A1Au
#define GREY100 0xFFFFFFFFu
#define GREY11 0xFF1C1C1Cu
#define GREY12 0xFF1F1F1Fu
#define GREY13 0xFF212121u
#define GREY14 0xFF242424u
#define GREY15 0xFF262626u
#define GREY16 0xFF292929u
#define GREY17 0xFF2B2B2Bu
#define GREY18 0xFF2E2E2Eu
#define GREY19 0xFF303030u
#define GREY2 0xFF050505u
#define GREY20 0xFF333333u
#define GREY21 0xFF363636u
#define GREY22 0xFF383838u
#define GREY23 0xFF3B3B3Bu
#define GREY24 0xFF3D3D3Du
#define GREY25 0xFF404040u
#define GREY26 0xFF424242u
#define GREY27 0xFF454545u
#define GREY28 0xFF474747u
#define GREY29 0xFF4A4A4Au
#define GREY3 0xFF080808u
#define GREY30 0xFF4D4D4Du
#define GREY31 0xFF4F4F4Fu
#define GREY32 0xFF525252u
#define GREY33 0xFF545454u
#define GREY34 0xFF575757u
#define GREY35 0xFF595959u
#define GREY36 0xFF5C5C5Cu
#define GREY37 0xFF5E5E5Eu
#define GREY38 0xFF616161u
#define GREY39 0xFF636363u
#define GREY4 0xFF0A0A0Au
#define GREY40 0xFF666666u
#define GREY41 0xFF696969u
#define GREY42 0xFF6B6B6Bu
#define GREY43 0xFF6E6E6Eu
#define GREY44 0xFF707070u
#define GREY45 0xFF737373u
#define GREY46 0xFF757575u
#define GREY47 0xFF787878u
#define GREY48 0xFF7A7A7Au
#define GREY49 0xFF7D7D7Du
#define GREY5 0xFF0D0D0Du
#define GREY50 0xFF7F7F7Fu
#define GREY51 0xFF828282u
#define GREY52 0xFF858585u
#define GREY53 0xFF878787u
#define GREY54 0xFF8A8A8Au
#define GREY55 0xFF8C8C8Cu
#define GREY56 0xFF8F8F8Fu
#define GREY57 0xFF919191u
#define GREY58 0xFF949494u
#define GREY59 0xFF969696u
#define GREY6 0xFF0F0F0Fu
#define GREY60 0xFF999999u
#define GREY61 0xFF9C9C9Cu
#define GREY62 0xFF9E9E9Eu
#define GREY63 0xFFA1A1A1u
#define GREY64 0xFFA3A3A3u
#define GREY65 0xFFA6A6A6u
#define GREY66 0xFFA8A8A8u
#define GREY67 0xFFABABABu
#define GREY68 0xFFADADADu
#define GREY69 0xFFB0B0B0u
#define GREY7 0xFF121212u
#define GREY70 0xFFB3B3B3u
#define GREY71 0xFFB5B5B5u
#define GREY72 0xFFB8B8B8u
#define GREY73 0xFFBABABAu
#define GREY74 0xFFBDBDBDu
#define GREY75 0xFFBFBFBFu
#define GREY76 0xFFC2C2C2u
#define GREY77 0xFFC4C4C4u
#define GREY78 0xFFC7C7C7u
#define GREY79 0xFFC9C9C9u
#define GREY8 0xFF141414u
#define GREY80 0xFFCCCCCCu
#define GREY81 0xFFCFCFCFu
#define GREY82 0xFFD1D1D1u
#define GREY83 0xFFD4D4D4u
#define GREY84 0xFFD6D6D6u
#define GREY85 0xFFD9D9D9u
#define GREY86 0xFFDBDBDBu
#define GREY87 0xFFDEDEDEu
#define GREY88 0xFFE0E0E0u
#define GREY89 0xFFE3E3E3u
#define GREY9 0xFF171717u
#define GREY90 0xFFE5E5E5u
#define GREY91 0xFFE8E8E8u
#define GREY92 0xFFEBEBEBu
#define GREY93 0xFFEDEDEDu
#define GREY94 0xFFF0F0F0u
#define GREY95 0xFFF2F2F2u
#define GREY96 0xFFF5F5F5u
#define GREY97 0xFFF7F7F7u
#define GREY98 0xFFFAFAFAu
#define GREY99 0xFFFCFCFCu
#define HONEYDEW 0xFFF0FFF0u
#define HONEYDEW1 0xFFF0FFF0u
#define HONEYDEW2 0xFFE0EEE0u
#define HONEYDEW3 0xFFC1CDC1u
#define HONEYDEW4 0xFF838B83u
#define HOTPINK 0xFFB469FFu
#define HOTPINK1 0xFFB46EFFu
#define HOTPINK2 0xFFA76AEEu
#define HOTPINK3 0xFF9060CDu
#define HOTPINK4 0xFF623A8Bu
#define INDIANRED 0xFF5C5CCDu
#define INDIANRED1 0xFF6A6AFFu
#define INDIANRED2 0xFF6363EEu
#define INDIANRED3 0xFF5555CDu
#define INDIANRED4 0xFF3A3A8Bu
#define IVORY 0xFFF0FFFFu
#define IVORY1 0xFFF0FFFFu
#define IVORY2 0xFFE0EEEEu
#define IVORY3 0xFFC1CDCDu
#define IVORY4 0xFF838B8Bu
#define KHAKI 0xFF8CE6F0u
#define KHAKI1 0xFF8FF6FFu
#define KHAKI2 0xFF85E6EEu
#define KHAKI3 0xFF73C6CDu
#define KHAKI4 0xFF4E868Bu
#define LAVENDER 0xFFFAE6E6u
#define LAVENDERBLUSH 0xFFF5F0FFu
#define LAVENDERBLUSH1 0xFFF5F0FFu
#define LAVENDERBLUSH2 0xFFE5E0EEu
#define LAVENDERBLUSH3 0xFFC5C1CDu
#define LAVENDERBLUSH4 0xFF86838Bu
#define LAWNGREEN 0xFF00FC7Cu
#define LEMONCHIFFON 0xFFCDFAFFu
#define LEMONCHIFFON1 0xFFCDFAFFu
#define LEMONCHIFFON2 0xFFBFE9EEu
#define LEMONCHIFFON3 0xFFA5C9CDu
#define LEMONCHIFFON4 0xFF70898Bu
#define LIGHTBLUE 0xFFE6D8ADu
#define LIGHTBLUE1 0xFFFFEFBFu
#define LIGHTBLUE2 0xFFEEDFB2u
#define LIGHTBLUE3 0xFFCDC09Au
#define LIGHTBLUE4 0xFF8B8368u
#define LIGHTCORAL 0xFF8080F0u
#define LIGHTCYAN 0xFFFFFFE0u
#define LIGHTCYAN1 0xFFFFFFE0u
#define LIGHTCYAN2 0xFFEEEED1u
#define LIGHTCYAN3 0xFFCDCDB4u
#define LIGHTCYAN4 0xFF8B8B7Au
#define LIGHTGOLDENROD 0xFF82DDEEu
#define LIGHTGOLDENROD1 0xFF8BECFFu
#define LIGHTGOLDENROD2 0xFF82DCEEu
#define LIGHTGOLDENROD3 0xFF70BECDu
#define LIGHTGOLDENROD4 0xFF4C818Bu
#define LIGHTGOLDENRODYELLOW 0xFFD2FAFAu
#define LIGHTGRAY 0xFFD3D3D3u
#define LIGHTGREEN 0xFF90EE90u
#define LIGHTGREY 0xFFD3D3D3u
#define LIGHTPINK 0xFFC1B6FFu
#define LIGHTPINK1 0xFFB9AEFFu
#define LIGHTPINK2 0xFFADA2EEu
#define LIGHTPINK3 0xFF958CCDu
#define LIGHTPINK4 0xFF655F8Bu
#define LIGHTSALMON 0xFF7AA0FFu
#define LIGHTSALMON1 0xFF7AA0FFu
#define LIGHTSALMON2 0xFF7295EEu
#define LIGHTSALMON3 0xFF6281CDu
#define LIGHTSALMON4 0xFF42578Bu
#define LIGHTSEAGREEN 0xFFAAB220u
#define LIGHTSKYBLUE 0xFFFACE87u
#define LIGHTSKYBLUE1 0xFFFFE2B0u
#define LIGHTSKYBLUE2 0xFFEED3A4u
#define LIGHTSKYBLUE3 0xFFCDB68Du
#define LIGHTSKYBLUE4 0xFF8B7B60u
#define LIGHTSLATEBLUE 0xFFFF7084u
#define LIGHTSLATEGRAY 0xFF998877u
#define LIGHTSLATEGREY 0xFF998877u
#define LIGHTSTEELBLUE 0xFFDEC4B0u
#define LIGHTSTEELBLUE1 0xFFFFE1CAu
#define LIGHTSTEELBLUE2 0xFFEED2BCu
#define LIGHTSTEELBLUE3 0xFFCDB5A2u
#define LIGHTSTEELBLUE4 0xFF8B7B6Eu
#define LIGHTYELLOW 0xFFE0FFFFu
#define LIGHTYELLOW1 0xFFE0FFFFu
#define LIGHTYELLOW2 0xFFD1EEEEu
#define LIGHTYELLOW3 0xFFB4CDCDu
#define LIGHTYELLOW4 0xFF7A8B8Bu
#define LIMEGREEN 0xFF32CD32u
#define LINEN 0xFFE6F0FAu
#define MAGENTA 0xFFFF00FFu
#define MAGENTA1 0xFFFF00FFu
#define MAGENTA2 0xFFEE00EEu
#define MAGENTA3 0xFFCD00CDu
#define MAGENTA4 0xFF8B008Bu
#define MAROON 0xFF6030B0u
#define MAROON1 0xFFB334FFu
#define MAROON2 0xFFA730EEu
#define MAROON3 0xFF9029CDu
#define MAROON4 0xFF621C8Bu
#define MEDIUMAQUAMARINE 0xFFAACD66u
#define MEDIUMBLUE 0xFFCD0000u
#define MEDIUMORCHID 0xFFD355BAu
#define MEDIUMORCHID1 0xFFFF66E0u
#define MEDIUMORCHID2 0xFFEE5FD1u
#define MEDIUMORCHID3 0xFFCD52B4u
#define MEDIUMORCHID4 0xFF8B377Au
#define MEDIUMPURPLE 0xFFDB7093u
#define MEDIUMPURPLE1 0xFFFF82ABu
#define MEDIUMPURPLE2 0xFFEE799Fu
#define MEDIUMPURPLE3 0xFFCD6889u
#define MEDIUMPURPLE4 0xFF8B475Du
#define MEDIUMSEAGREEN 0xFF71B33Cu
#define MEDIUMSLATEBLUE 0xFFEE687Bu
#define MEDIUMSPRINGGREEN 0xFF9AFA00u
#define MEDIUMTURQUOISE 0xFFCCD148u
#define MEDIUMVIOLETRED 0xFF8515C7u
#define MIDNIGHTBLUE 0xFF701919u
#define MINTCREAM 0xFFFAFFF5u
#define MISTYROSE 0xFFE1E4FFu
#define MISTYROSE1 0xFFE1E4FFu
#define MISTYROSE2 0xFFD2D5EEu
#define MISTYROSE3 0xFFB5B7CDu
#define MISTYROSE4 0xFF7B7D8Bu
#define MOCCASIN 0xFFB5E4FFu
#define NAVAJOWHITE 0xFFADDEFFu
#define NAVAJOWHITE1 0xFFADDEFFu
#define NAVAJOWHITE2 0xFFA1CFEEu
#define NAVAJOWHITE3 0xFF8BB3CDu
#define NAVAJOWHITE4 0xFF5E798Bu
#define NAVY 0xFF800000u
#define NAVYBLUE 0xFF800000u
#define OLDLACE 0xFFE6F5FDu
#define OLIVEDRAB 0xFF238E6Bu
#define OLIVEDRAB1 0xFF3EFFC0u
#define OLIVEDRAB2 0xFF3AEEB3u
#define OLIVEDRAB3 0xFF32CD9Au
#define OLIVEDRAB4 0xFF228B69u
#define ORANGE 0xFF00A5FFu
#define ORANGE1 0xFF00A5FFu
#define ORANGE2 0xFF009AEEu
#define ORANGE3 0xFF0085CDu
#define ORANGE4 0xFF005A8Bu
#define ORANGERED 0xFF0045FFu
#define ORANGERED1 0xFF0045FFu
#define ORANGERED2 0xFF0040EEu
#define ORANGERED3 0xFF0037CDu
#define ORANGERED4 0xFF00258Bu
#define ORCHID 0xFFD670DAu
#define ORCHID1 0xFFFA83FFu
#define ORCHID2 0xFFE97AEEu
#define ORCHID3 0xFFC969CDu
#define ORCHID4 0xFF89478Bu
#define PALEGOLDENROD 0xFFAAE8EEu
#define PALEGREEN 0xFF98FB98u
#define PALEGREEN1 0xFF9AFF9Au
#define PALEGREEN2 0xFF90EE90u
#define PALEGREEN3 0xFF7CCD7Cu
#define PALEGREEN4 0xFF548B54u
#define PALETURQUOISE 0xFFEEEEAFu
#define PALETURQUOISE1 0xFFFFFFBBu
#define PALETURQUOISE2 0xFFEEEEAEu
#define PALETURQUOISE3 0xFFCDCD96u
#define PALETURQUOISE4 0xFF8B8B66u
#define PALEVIOLETRED 0xFF9370DBu
#define PALEVIOLETRED1 0xFFAB82FFu
#define PALEVIOLETRED2 0xFF9F79EEu
#define PALEVIOLETRED3 0xFF8968CDu
#define PALEVIOLETRED4 0xFF5D478Bu
#define PAPAYAWHIP 0xFFD5EFFFu
#define PEACHPUFF 0xFFB9DAFFu
#define PEACHPUFF1 0xFFB9DAFFu
#define PEACHPUFF2 0xFFADCBEEu
#define PEACHPUFF3 0xFF95AFCDu
#define PEACHPUFF4 0xFF65778Bu
#define PERU 0xFF3F85CDu
#define PINK 0xFFCBC0FFu
#define PINK1 0xFFC5B5FFu
#define PINK2 0xFFB8A9EEu
#define PINK3 0xFF9E91CDu
#define PINK4 0xFF6C638Bu
#define PLUM 0xFFDDA0DDu
#define PLUM1 0xFFFFBBFFu
#define PLUM2 0xFFEEAEEEu
#define PLUM3 0xFFCD96CDu
#define PLUM4 0xFF8B668Bu
#define POWDERBLUE 0xFFE6E0B0u
#define PURPLE 0xFFF020A0u
#define PURPLE1 0xFFFF309Bu
#define PURPLE2 0xFFEE2C91u
#define PURPLE3 0xFFCD267Du
#define PURPLE4 0xFF8B1A55u
#define RED 0xFF0000FFu
#define RED1 0xFF0000FFu
#define RED2 0xFF0000EEu
#define RED3 0xFF0000CDu
#define RED4 0xFF00008Bu
#define ROSYBROWN 0xFF8F8FBCu
#define ROSYBROWN1 0xFFC1C1FFu
#define ROSYBROWN2 0xFFB4B4EEu
#define ROSYBROWN3 0xFF9B9BCDu
#define ROSYBROWN4 0xFF69698Bu
#define ROYALBLUE 0xFFE16941u
#define ROYALBLUE1 0xFFFF7648u
#define ROYALBLUE2 0xFFEE6E43u
#define ROYALBLUE3 0xFFCD5F3Au
#define ROYALBLUE4 0xFF8B4027u
#define SADDLEBROWN 0xFF13458Bu
#define SALMON 0xFF7280FAu
#define SALMON1 0xFF698CFFu
#define SALMON2 0xFF6282EEu
#define SALMON3 0xFF5470CDu
#define SALMON4 0xFF394C8Bu
#define SANDYBROWN 0xFF60A4F4u
#define SEAGREEN 0xFF578B2Eu
#define SEAGREEN1 0xFF9FFF54u
#define SEAGREEN2 0xFF94EE4Eu
#define SEAGREEN3 0xFF80CD43u
#define SEAGREEN4 0xFF578B2Eu
#define SEASHELL 0xFFEEF5FFu
#define SEASHELL1 0xFFEEF5FFu
#define SEASHELL2 0xFFDEE5EEu
#define SEASHELL3 0xFFBFC5CDu
#define SEASHELL4 0xFF82868Bu
#define SIENNA 0xFF2D52A0u
#define SIENNA1 0xFF4782FFu
#define SIENNA2 0xFF4279EEu
#define SIENNA3 0xFF3968CDu
#define SIENNA4 0xFF26478Bu
#define SKYBLUE 0xFFEBCE87u
#define SKYBLUE1 0xFFFFCE87u
#define SKYBLUE2 0xFFEEC07Eu
#define SKYBLUE3 0xFFCDA66Cu
#define SKYBLUE4 0xFF8B704Au
#define SLATEBLUE 0xFFCD5A6Au
#define SLATEBLUE1 0xFFFF6F83u
#define SLATEBLUE2 0xFFEE677Au
#define SLATEBLUE3 0xFFCD5969u
#define SLATEBLUE4 0xFF8B3C47u
#define SLATEGRAY 0xFF908070u
#define SLATEGRAY1 0xFFFFE2C6u
#define SLATEGRAY2 0xFFEED3B9u
#define SLATEGRAY3 0xFFCDB69Fu
#define SLATEGRAY4 0xFF8B7B6Cu
#define SLATEGREY 0xFF908070u
#define SNOW 0xFFFAFAFFu
#define SNOW1 0xFFFAFAFFu
#define SNOW2 0xFFE9E9EEu
#define SNOW3 0xFFC9C9CDu
#define SNOW4 0xFF89898Bu
#define SPRINGGREEN 0xFF7FFF00u
#define SPRINGGREEN1 0xFF7FFF00u
#define SPRINGGREEN2 0xFF76EE00u
#define SPRINGGREEN3 0xFF66CD00u
#define SPRINGGREEN4 0xFF458B00u
#define STEELBLUE 0xFFB48246u
#define STEELBLUE1 0xFFFFB863u
#define STEELBLUE2 0xFFEEAC5Cu
#define STEELBLUE3 0xFFCD944Fu
#define STEELBLUE4 0xFF8B6436u
#define TAN 0xFF8CB4D2u
#define TAN1 0xFF4FA5FFu
#define TAN2 0xFF499AEEu
#define TAN3 0xFF3F85CDu
#define TAN4 0xFF2B5A8Bu
#define THISTLE 0xFFD8BFD8u
#define THISTLE1 0xFFFFE1FFu
#define THISTLE2 0xFFEED2EEu
#define THISTLE3 0xFFCDB5CDu
#define THISTLE4 0xFF8B7B8Bu
#define TOMATO 0xFF4763FFu
#define TOMATO1 0xFF4763FFu
#define TOMATO2 0xFF425CEEu
#define TOMATO3 0xFF394FCDu
#define TOMATO4 0xFF26368Bu
#define TURQUOISE 0xFFD0E040u
#define TURQUOISE1 0xFFFFF500u
#define TURQUOISE2 0xFFEEE500u
#define TURQUOISE3 0xFFCDC500u
#define TURQUOISE4 0xFF8B8600u
#define VIOLET 0xFFEE82EEu
#define VIOLETRED 0xFF9020D0u
#define VIOLETRED1 0xFF963EFFu
#define VIOLETRED2 0xFF8C3AEEu
#define VIOLETRED3 0xFF7832CDu
#define VIOLETRED4 0xFF52228Bu
#define WHEAT 0xFFB3DEF5u
#define WHEAT1 0xFFBAE7FFu
#define WHEAT2 0xFFAED8EEu
#define WHEAT3 0xFF96BACDu
#define WHEAT4 0xFF667E8Bu
#define WHITE 0xFFFFFFFFu
#define WHITESMOKE 0xFFF5F5F5u
#define YELLOW 0xFF00FFFFu
#define YELLOW1 0xFF00FFFFu
#define YELLOW2 0xFF00EEEEu
#define YELLOW3 0xFF00CDCDu
#define YELLOW4 0xFF008B8Bu
#define YELLOWGREEN 0xFF32CD9Au
#endif /* COSMOPOLITAN_NET_HTTP_CSSCOLOR_H_ */

View file

@ -0,0 +1,33 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/alg/alg.h"
#include "libc/runtime/runtime.h"
#include "net/http/http.h"
void freehttprequest(struct HttpRequest **req) {
if (*req) {
critbit0_clear(&(*req)->headers);
free_s(&(*req)->method.p);
free_s(&(*req)->scratch.p);
free_s(&(*req)->uri.p);
free_s(&(*req)->version.p);
free_s(req);
}
}

33
net/http/gethttpheader.c Normal file
View file

@ -0,0 +1,33 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "net/http/gethttpheader.inc"
#include "net/http/http.h"
/**
* Returns small number for HTTP header, or 0 if not found.
*/
enum HttpHeader gethttpheader(const char *str, unsigned int len) {
const struct HttpHeaderSlot *slot;
if ((slot = in_word_set(str, len))) {
return slot->code;
} else {
return 0;
}
}

View file

@ -0,0 +1,62 @@
%{
#include "libc/str/str.h"
#include "net/http/http.h"
#define GPERF_DOWNCASE
%}
%compare-strncmp
%ignore-case
%language=ANSI-C
%pic
%readonly-tables
%struct-type
struct HttpHeaderSlot { unsigned char name; unsigned char code; };
%%
Accept, kHttpAccept
Accept-Charset, kHttpAcceptCharset
Accept-Encoding, kHttpAcceptEncoding
Accept-Language, kHttpAcceptLanguage
Age, kHttpAge
Allow, kHttpAllow
Authorization, kHttpAuthorization
Cache-Control, kHttpCacheControl
Chunked, kHttpChunked
Close, kHttpClose
Connection, kHttpConnection
Content-Base, kHttpContentBase
Content-Encoding, kHttpContentEncoding
Content-Language, kHttpContentLanguage
Content-Length, kHttpContentLength
Content-Location, kHttpContentLocation
Content-Md5, kHttpContentMd5
Content-Range, kHttpContentRange
Content-Type, kHttpContentType
Date, kHttpDate
Etag, kHttpEtag
Expires, kHttpExpires
From, kHttpFrom
Host, kHttpHost
If-Match, kHttpIfMatch
If-Modified-Since, kHttpIfModifiedSince
If-None-Match, kHttpIfNoneMatch
If-Range, kHttpIfRange
If-Unmodified-Since, kHttpIfUnmodifiedSince
Keep-Alive, kHttpKeepAlive
Max-Forwards, kHttpMaxForwards
Pragma, kHttpPragma
Proxy-Authenticate, kHttpProxyAuthenticate
Proxy-Authorization, kHttpProxyAuthorization
Proxy-Connection, kHttpProxyConnection
Range, kHttpRange
Referer, kHttpReferer
Transfer-Encoding, kHttpTransferEncoding
Upgrade, kHttpUpgrade
User-Agent, kHttpUserAgent
Via, kHttpVia
Location, kHttpLocation
Public, kHttpPublic
Retry-After, kHttpRetryAfter
Server, kHttpServer
Vary, kHttpVary
Warning, kHttpWarning
WWW-Authenticate, kHttpWwwAuthenticate
Last-Modified, kHttpLastModified

397
net/http/gethttpheader.inc Normal file
View file

@ -0,0 +1,397 @@
/* ANSI-C code produced by gperf version 3.0.4 */
/* Command-line: gperf net/http/gethttpheader.gperf */
/* Computed positions: -k'1,9,$' */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
&& ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
&& ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
&& ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
&& ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
&& ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
&& ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
&& ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
&& ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
&& ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
&& ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
&& ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
&& ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
&& ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
&& ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
&& ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
&& ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
&& ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
&& ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
/* The character set is not based on ISO-646. */
#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
#endif
#line 1 "net/http/gethttpheader.gperf"
#include "libc/str/str.h"
#include "net/http/http.h"
#define GPERF_DOWNCASE
#line 12 "net/http/gethttpheader.gperf"
struct HttpHeaderSlot { unsigned char name; unsigned char code; };
#define TOTAL_KEYWORDS 49
#define MIN_WORD_LENGTH 3
#define MAX_WORD_LENGTH 19
#define MIN_HASH_VALUE 5
#define MAX_HASH_VALUE 72
/* maximum key range = 68, duplicates = 0 */
#ifndef GPERF_DOWNCASE
#define GPERF_DOWNCASE 1
static unsigned char gperf_downcase[256] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
105, 106, 107, 108, 109, 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, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224,
225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
255
};
#endif
#ifndef GPERF_CASE_STRNCMP
#define GPERF_CASE_STRNCMP 1
static int
gperf_case_strncmp (register const char *s1, register const char *s2, register unsigned int n)
{
for (; n > 0;)
{
unsigned char c1 = gperf_downcase[(unsigned char)*s1++];
unsigned char c2 = gperf_downcase[(unsigned char)*s2++];
if (c1 != 0 && c1 == c2)
{
n--;
continue;
}
return (int)c1 - (int)c2;
}
return 0;
}
#endif
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static unsigned int
hash (register const char *str, register unsigned int len)
{
static const unsigned char asso_values[] =
{
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 0, 73, 73, 73, 73,
73, 73, 73, 0, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 5, 20, 0, 15, 0,
0, 45, 20, 5, 73, 10, 35, 5, 5, 5,
20, 73, 5, 30, 0, 0, 15, 20, 73, 15,
73, 73, 73, 73, 73, 73, 73, 5, 20, 0,
15, 0, 0, 45, 20, 5, 73, 10, 35, 5,
5, 5, 20, 73, 5, 30, 0, 0, 15, 20,
73, 15, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73
};
register int hval = len;
switch (hval)
{
default:
hval += asso_values[(unsigned char)str[8]];
/*FALLTHROUGH*/
case 8:
case 7:
case 6:
case 5:
case 4:
case 3:
case 2:
case 1:
hval += asso_values[(unsigned char)str[0]];
break;
}
return hval + asso_values[(unsigned char)str[len - 1]];
}
struct stringpool_t
{
char stringpool_str5[sizeof("Close")];
char stringpool_str7[sizeof("Upgrade")];
char stringpool_str8[sizeof("Age")];
char stringpool_str9[sizeof("From")];
char stringpool_str10[sizeof("Range")];
char stringpool_str11[sizeof("Accept")];
char stringpool_str12[sizeof("Content-Type")];
char stringpool_str13[sizeof("If-Range")];
char stringpool_str15[sizeof("User-Agent")];
char stringpool_str16[sizeof("Content-Md5")];
char stringpool_str17[sizeof("Referer")];
char stringpool_str18[sizeof("Content-Range")];
char stringpool_str19[sizeof("Date")];
char stringpool_str20[sizeof("Connection")];
char stringpool_str21[sizeof("Retry-After")];
char stringpool_str22[sizeof("Chunked")];
char stringpool_str23[sizeof("Via")];
char stringpool_str24[sizeof("Host")];
char stringpool_str25[sizeof("Accept-Language")];
char stringpool_str26[sizeof("Public")];
char stringpool_str27[sizeof("If-Modified-Since")];
char stringpool_str28[sizeof("Authorization")];
char stringpool_str29[sizeof("If-Unmodified-Since")];
char stringpool_str30[sizeof("Allow")];
char stringpool_str31[sizeof("Pragma")];
char stringpool_str32[sizeof("Content-Base")];
char stringpool_str33[sizeof("If-Match")];
char stringpool_str34[sizeof("Vary")];
char stringpool_str35[sizeof("Keep-Alive")];
char stringpool_str36[sizeof("WWW-Authenticate")];
char stringpool_str37[sizeof("Expires")];
char stringpool_str38[sizeof("Proxy-Authenticate")];
char stringpool_str39[sizeof("Accept-Charset")];
char stringpool_str41[sizeof("Server")];
char stringpool_str43[sizeof("If-None-Match")];
char stringpool_str44[sizeof("Proxy-Authorization")];
char stringpool_str46[sizeof("Proxy-Connection")];
char stringpool_str48[sizeof("Location")];
char stringpool_str49[sizeof("Etag")];
char stringpool_str51[sizeof("Content-Language")];
char stringpool_str52[sizeof("Max-Forwards")];
char stringpool_str53[sizeof("Cache-Control")];
char stringpool_str56[sizeof("Content-Location")];
char stringpool_str61[sizeof("Content-Encoding")];
char stringpool_str62[sizeof("Transfer-Encoding")];
char stringpool_str68[sizeof("Last-Modified")];
char stringpool_str69[sizeof("Content-Length")];
char stringpool_str70[sizeof("Accept-Encoding")];
char stringpool_str72[sizeof("Warning")];
};
static const struct stringpool_t stringpool_contents =
{
"Close",
"Upgrade",
"Age",
"From",
"Range",
"Accept",
"Content-Type",
"If-Range",
"User-Agent",
"Content-Md5",
"Referer",
"Content-Range",
"Date",
"Connection",
"Retry-After",
"Chunked",
"Via",
"Host",
"Accept-Language",
"Public",
"If-Modified-Since",
"Authorization",
"If-Unmodified-Since",
"Allow",
"Pragma",
"Content-Base",
"If-Match",
"Vary",
"Keep-Alive",
"WWW-Authenticate",
"Expires",
"Proxy-Authenticate",
"Accept-Charset",
"Server",
"If-None-Match",
"Proxy-Authorization",
"Proxy-Connection",
"Location",
"Etag",
"Content-Language",
"Max-Forwards",
"Cache-Control",
"Content-Location",
"Content-Encoding",
"Transfer-Encoding",
"Last-Modified",
"Content-Length",
"Accept-Encoding",
"Warning"
};
#define stringpool ((const char *) &stringpool_contents)
#ifdef __GNUC__
__inline
#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
__attribute__ ((__gnu_inline__))
#endif
#endif
const struct HttpHeaderSlot *
in_word_set (register const char *str, register unsigned int len)
{
static const struct HttpHeaderSlot wordlist[] =
{
{-1}, {-1}, {-1}, {-1}, {-1},
#line 23 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str5, kHttpClose },
{-1},
#line 52 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str7, kHttpUpgrade },
#line 18 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str8, kHttpAge },
#line 36 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str9, kHttpFrom },
#line 49 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str10, kHttpRange },
#line 14 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str11, kHttpAccept },
#line 32 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str12, kHttpContentType },
#line 41 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str13, kHttpIfRange },
{-1},
#line 53 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str15, kHttpUserAgent },
#line 30 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str16, kHttpContentMd5 },
#line 50 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str17, kHttpReferer },
#line 31 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str18, kHttpContentRange },
#line 33 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str19, kHttpDate },
#line 24 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str20, kHttpConnection },
#line 57 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str21, kHttpRetryAfter },
#line 22 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str22, kHttpChunked },
#line 54 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str23, kHttpVia },
#line 37 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str24, kHttpHost },
#line 17 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str25, kHttpAcceptLanguage },
#line 56 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str26, kHttpPublic },
#line 39 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str27, kHttpIfModifiedSince },
#line 20 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str28, kHttpAuthorization },
#line 42 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str29, kHttpIfUnmodifiedSince },
#line 19 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str30, kHttpAllow },
#line 45 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str31, kHttpPragma },
#line 25 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str32, kHttpContentBase },
#line 38 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str33, kHttpIfMatch },
#line 59 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str34, kHttpVary },
#line 43 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str35, kHttpKeepAlive },
#line 61 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str36, kHttpWwwAuthenticate },
#line 35 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str37, kHttpExpires },
#line 46 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str38, kHttpProxyAuthenticate },
#line 15 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str39, kHttpAcceptCharset },
{-1},
#line 58 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str41, kHttpServer },
{-1},
#line 40 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str43, kHttpIfNoneMatch },
#line 47 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str44, kHttpProxyAuthorization },
{-1},
#line 48 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str46, kHttpProxyConnection },
{-1},
#line 55 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str48, kHttpLocation },
#line 34 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str49, kHttpEtag },
{-1},
#line 27 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str51, kHttpContentLanguage },
#line 44 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str52, kHttpMaxForwards },
#line 21 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str53, kHttpCacheControl },
{-1}, {-1},
#line 29 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str56, kHttpContentLocation },
{-1}, {-1}, {-1}, {-1},
#line 26 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str61, kHttpContentEncoding },
#line 51 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str62, kHttpTransferEncoding },
{-1}, {-1}, {-1}, {-1}, {-1},
#line 62 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str68, kHttpLastModified },
#line 28 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str69, kHttpContentLength },
#line 16 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str70, kHttpAcceptEncoding },
{-1},
#line 60 "net/http/gethttpheader.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str72, kHttpWarning }
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
{
register int key = hash (str, len);
if (key <= MAX_HASH_VALUE && key >= 0)
{
register int o = wordlist[key].name;
if (o >= 0)
{
register const char *s = o + stringpool;
if ((((unsigned char)*str ^ (unsigned char)*s) & ~32) == 0 && !gperf_case_strncmp (str, s, len) && s[len] == '\0')
return &wordlist[key];
}
}
}
return 0;
}

View file

@ -0,0 +1,24 @@
%{
#include "libc/str/str.h"
#include "net/http/uri.h"
#define GPERF_DOWNCASE
%}
%compare-strncmp
%ignore-case
%language=ANSI-C
%pic
%readonly-tables
%struct-type
struct UriSchemeSlot { unsigned char name; unsigned char code; };
%%
http,kUriSchemeHttp
https,kUriSchemeHttps
file,kUriSchemeFile
data,kUriSchemeData
zip,kUriSchemeZip
sip,kUriSchemeSip
sips,kUriSchemeSips
tel,kUriSchemeTel
ssh,kUriSchemeSsh
gs,kUriSchemeGs
s3,kUriSchemeS3

219
net/http/geturischeme.inc Normal file
View file

@ -0,0 +1,219 @@
/* ANSI-C code produced by gperf version 3.0.4 */
/* Command-line: gperf net/http/geturischeme.gperf */
/* Computed positions: -k'1-2' */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
&& ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
&& ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
&& ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
&& ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
&& ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
&& ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
&& ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
&& ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
&& ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
&& ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
&& ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
&& ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
&& ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
&& ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
&& ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
&& ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
&& ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
&& ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
/* The character set is not based on ISO-646. */
#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
#endif
#line 1 "net/http/geturischeme.gperf"
#include "libc/str/str.h"
#include "net/http/uri.h"
#define GPERF_DOWNCASE
#line 12 "net/http/geturischeme.gperf"
struct UriSchemeSlot { unsigned char name; unsigned char code; };
#define TOTAL_KEYWORDS 11
#define MIN_WORD_LENGTH 2
#define MAX_WORD_LENGTH 5
#define MIN_HASH_VALUE 2
#define MAX_HASH_VALUE 19
/* maximum key range = 18, duplicates = 0 */
#ifndef GPERF_DOWNCASE
#define GPERF_DOWNCASE 1
static unsigned char gperf_downcase[256] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
105, 106, 107, 108, 109, 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, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224,
225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
255
};
#endif
#ifndef GPERF_CASE_STRNCMP
#define GPERF_CASE_STRNCMP 1
static int
gperf_case_strncmp (register const char *s1, register const char *s2, register unsigned int n)
{
for (; n > 0;)
{
unsigned char c1 = gperf_downcase[(unsigned char)*s1++];
unsigned char c2 = gperf_downcase[(unsigned char)*s2++];
if (c1 != 0 && c1 == c2)
{
n--;
continue;
}
return (int)c1 - (int)c2;
}
return 0;
}
#endif
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static unsigned int
hash (register const char *str, register unsigned int len)
{
static const unsigned char asso_values[] =
{
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 5, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 10, 20, 20, 5, 15,
5, 0, 0, 5, 20, 20, 20, 20, 20, 20,
20, 20, 20, 0, 0, 20, 20, 20, 20, 20,
5, 20, 20, 20, 20, 20, 20, 10, 20, 20,
5, 15, 5, 0, 0, 5, 20, 20, 20, 20,
20, 20, 20, 20, 20, 0, 0, 20, 20, 20,
20, 20, 5, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20
};
return len + asso_values[(unsigned char)str[1]] + asso_values[(unsigned char)str[0]];
}
struct stringpool_t
{
char stringpool_str2[sizeof("gs")];
char stringpool_str3[sizeof("ssh")];
char stringpool_str4[sizeof("http")];
char stringpool_str5[sizeof("https")];
char stringpool_str7[sizeof("s3")];
char stringpool_str8[sizeof("sip")];
char stringpool_str9[sizeof("sips")];
char stringpool_str13[sizeof("zip")];
char stringpool_str14[sizeof("file")];
char stringpool_str18[sizeof("tel")];
char stringpool_str19[sizeof("data")];
};
static const struct stringpool_t stringpool_contents =
{
"gs",
"ssh",
"http",
"https",
"s3",
"sip",
"sips",
"zip",
"file",
"tel",
"data"
};
#define stringpool ((const char *) &stringpool_contents)
#ifdef __GNUC__
__inline
#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
__attribute__ ((__gnu_inline__))
#endif
#endif
const struct UriSchemeSlot *
in_word_set (register const char *str, register unsigned int len)
{
static const struct UriSchemeSlot wordlist[] =
{
{-1}, {-1},
#line 23 "net/http/geturischeme.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str2,kUriSchemeGs},
#line 22 "net/http/geturischeme.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str3,kUriSchemeSsh},
#line 14 "net/http/geturischeme.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str4,kUriSchemeHttp},
#line 15 "net/http/geturischeme.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str5,kUriSchemeHttps},
{-1},
#line 24 "net/http/geturischeme.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str7,kUriSchemeS3},
#line 19 "net/http/geturischeme.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str8,kUriSchemeSip},
#line 20 "net/http/geturischeme.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str9,kUriSchemeSips},
{-1}, {-1}, {-1},
#line 18 "net/http/geturischeme.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str13,kUriSchemeZip},
#line 16 "net/http/geturischeme.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str14,kUriSchemeFile},
{-1}, {-1}, {-1},
#line 21 "net/http/geturischeme.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str18,kUriSchemeTel},
#line 17 "net/http/geturischeme.gperf"
{(int)(long)&((struct stringpool_t *)0)->stringpool_str19,kUriSchemeData}
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
{
register int key = hash (str, len);
if (key <= MAX_HASH_VALUE && key >= 0)
{
register int o = wordlist[key].name;
if (o >= 0)
{
register const char *s = o + stringpool;
if ((((unsigned char)*str ^ (unsigned char)*s) & ~32) == 0 && !gperf_case_strncmp (str, s, len) && s[len] == '\0')
return &wordlist[key];
}
}
}
return 0;
}

82
net/http/http.h Normal file
View file

@ -0,0 +1,82 @@
#ifndef COSMOPOLITAN_LIBC_HTTP_HTTP_H_
#define COSMOPOLITAN_LIBC_HTTP_HTTP_H_
#include "libc/alg/alg.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct FILE;
enum HttpHeader {
kHttpAccept = 1,
kHttpAcceptCharset,
kHttpAcceptEncoding,
kHttpAcceptLanguage,
kHttpAge,
kHttpAllow,
kHttpAuthorization,
kHttpCacheControl,
kHttpChunked,
kHttpClose,
kHttpConnection,
kHttpContentBase,
kHttpContentEncoding,
kHttpContentLanguage,
kHttpContentLength,
kHttpContentLocation,
kHttpContentMd5,
kHttpContentRange,
kHttpContentType,
kHttpDate,
kHttpEtag,
kHttpExpires,
kHttpFrom,
kHttpHost,
kHttpIfMatch,
kHttpIfModifiedSince,
kHttpIfNoneMatch,
kHttpIfRange,
kHttpIfUnmodifiedSince,
kHttpKeepAlive,
kHttpMaxForwards,
kHttpPragma,
kHttpProxyAuthenticate,
kHttpProxyAuthorization,
kHttpProxyConnection,
kHttpRange,
kHttpReferer,
kHttpTransferEncoding,
kHttpUpgrade,
kHttpUserAgent,
kHttpVia,
kHttpLocation,
kHttpPublic,
kHttpRetryAfter,
kHttpServer,
kHttpVary,
kHttpWarning,
kHttpWwwAuthenticate,
kHttpLastModified,
};
struct HttpStr {
char *p;
size_t i, n;
};
struct HttpRequest {
struct HttpStr uri; /* /foo/bar.html, etc. */
struct HttpStr method; /* "GET", "POST", etc. */
struct critbit0 headers; /* TreeMultiMap<"key:value"> (no space delims) */
struct HttpStr version; /* "HTTP/1.1", etc. */
struct HttpStr scratch; /* "HTTP/1.1", etc. */
};
int parsehttprequest(struct HttpRequest *, struct FILE *) paramsnonnull();
void clearhttprequest(struct HttpRequest *) paramsnonnull();
void freehttprequest(struct HttpRequest **) paramsnonnull();
int negotiatehttprequest(int, const char *, uint32_t *, char *, uint32_t *,
uint32_t *, bool, long double);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_HTTP_HTTP_H_ */

68
net/http/http.mk Normal file
View file

@ -0,0 +1,68 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += NET_HTTP
NET_HTTP_ARTIFACTS += NET_HTTP_A
NET_HTTP = $(NET_HTTP_A_DEPS) $(NET_HTTP_A)
NET_HTTP_A = o/$(MODE)/net/http/http.a
NET_HTTP_A_FILES := $(wildcard net/http/*)
NET_HTTP_A_HDRS = $(filter %.h,$(NET_HTTP_A_FILES))
NET_HTTP_A_SRCS_S = $(filter %.S,$(NET_HTTP_A_FILES))
NET_HTTP_A_SRCS_C = $(filter %.c,$(NET_HTTP_A_FILES))
NET_HTTP_A_SRCS_R = $(filter %.rl,$(NET_HTTP_A_FILES))
NET_HTTP_A_SRCS = \
$(NET_HTTP_A_SRCS_S) \
$(NET_HTTP_A_SRCS_C) \
$(NET_HTTP_A_SRCS_R)
NET_HTTP_A_OBJS = \
$(NET_HTTP_A_SRCS:%=o/$(MODE)/%.zip.o) \
$(NET_HTTP_A_SRCS_S:%.S=o/$(MODE)/%.o) \
$(NET_HTTP_A_SRCS_C:%.c=o/$(MODE)/%.o) \
$(NET_HTTP_A_SRCS_R:%.rl=o/$(MODE)/%.o)
NET_HTTP_A_CHECKS = \
$(NET_HTTP_A).pkg \
$(NET_HTTP_A_HDRS:%=o/$(MODE)/%.ok)
NET_HTTP_A_DIRECTDEPS = \
LIBC_ALG \
LIBC_CALLS \
LIBC_CONV \
LIBC_FMT \
LIBC_LOG \
LIBC_NEXGEN32E \
LIBC_RUNTIME \
LIBC_SOCK \
LIBC_STDIO \
LIBC_STUBS \
LIBC_SYSV \
LIBC_TIME \
LIBC_X
NET_HTTP_A_DEPS := \
$(call uniq,$(foreach x,$(NET_HTTP_A_DIRECTDEPS),$($(x))))
$(NET_HTTP_A): net/http/ \
$(NET_HTTP_A).pkg \
$(NET_HTTP_A_OBJS)
$(NET_HTTP_A).pkg: \
$(NET_HTTP_A_OBJS) \
$(foreach x,$(NET_HTTP_A_DIRECTDEPS),$($(x)_A).pkg)
NET_HTTP_LIBS = $(foreach x,$(NET_HTTP_ARTIFACTS),$($(x)))
NET_HTTP_SRCS = $(foreach x,$(NET_HTTP_ARTIFACTS),$($(x)_SRCS))
NET_HTTP_HDRS = $(foreach x,$(NET_HTTP_ARTIFACTS),$($(x)_HDRS))
NET_HTTP_CHECKS = $(foreach x,$(NET_HTTP_ARTIFACTS),$($(x)_CHECKS))
NET_HTTP_OBJS = $(foreach x,$(NET_HTTP_ARTIFACTS),$($(x)_OBJS))
$(NET_HTTP_OBJS): $(BUILD_FILES) net/http/http.mk
.PRECIOUS: $(NET_HTTP_A_SRCS_R:%.rl=build/bootstrap/%.c)
.PHONY: o/$(MODE)/net/http
o/$(MODE)/net/http: \
$(NET_HTTP_CHECKS) \
$(NET_HTTP_A_SRCS_R:%.rl=%.svgz)

24
net/http/method.gperf Normal file
View file

@ -0,0 +1,24 @@
DELETE
GET
HEAD
POST
PUT
CONNECT
OPTIONS
TRACE
COPY
CHECKOUT
LOCK
M-SEARCH
MERGE
MKACTIVITY
MKCOL
MOVE
NOTIFY
PATCH
PROPFIND
PROPPATCH
REPORT
SUBSCRIBE
UNLOCK
UNSUBSCRIBE

View file

@ -0,0 +1,107 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/alg/alg.h"
#include "libc/calls/calls.h"
#include "libc/macros.h"
#include "libc/math.h"
#include "libc/sock/sock.h"
#include "libc/sysv/consts/poll.h"
#include "libc/sysv/consts/shut.h"
#include "libc/sysv/errfuns.h"
#include "libc/time/time.h"
#include "net/http/http.h"
static pureconst long AsMilliseconds(long double ts) {
return ts * 1e3 + .5;
}
/**
* Negotiates HTTP request.
*
* This function blocks until a response header is consumed. We assume
* the response header is smaller than *inout_respsize. We're agnostic
* to the various different i/o paradigms. Goal is really good latency.
*
* @param singleshot should be true w/ connection: close
* @return 0 on success, or -1 w/ errno
*/
int negotiatehttprequest(int sock, const char *req, uint32_t *inout_reqsize,
char *resp, uint32_t *inout_respsize,
uint32_t *out_resphdrsize, bool singleshot,
long double timeout) {
ssize_t rc;
struct pollfd fd;
const char *body;
long double start, now, deadline;
uint32_t transmitted, received, exchanged, remaining;
fd.fd = sock;
received = 0;
transmitted = 0;
fd.events = POLLOUT | POLLIN;
deadline = (start = now = nowl()) + timeout;
do {
if ((rc = poll(&fd, 1, MAX(0, AsMilliseconds(deadline - now)))) == 1) {
if (fd.revents & POLLHUP) {
econnreset();
break;
}
if (fd.revents & (POLLIN | POLLERR)) {
remaining = *inout_respsize - received - 1;
if ((rc = recv(fd.fd, resp + received, remaining, 0)) != -1) {
exchanged = rc;
body = memmem(resp + (received >= 4 ? received - 4 : 0), exchanged,
"\r\n\r\n", 4);
received += exchanged;
if (body) {
resp[received] = '\0';
*inout_respsize = received;
*inout_reqsize = transmitted;
*out_resphdrsize = body - resp;
return 0;
}
if (exchanged == remaining) {
emsgsize();
break;
}
} else {
break;
}
}
if (fd.revents & POLLOUT) {
remaining = *inout_reqsize - transmitted;
if ((rc = send(fd.fd, req + transmitted, remaining, 0)) != -1) {
exchanged = rc;
transmitted += exchanged;
if (exchanged == remaining) {
if (singleshot) shutdown(fd.fd, SHUT_WR);
fd.events &= ~POLLOUT;
}
} else {
break;
}
}
} else {
if (!rc) etimedout();
break;
}
} while ((now = nowl()) < deadline);
close(fd.fd);
return -1;
}

133
net/http/parsehttprequest.c Normal file
View file

@ -0,0 +1,133 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/alg/alg.h"
#include "libc/alg/arraylist.h"
#include "libc/limits.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/errfuns.h"
#include "libc/x/x.h"
#include "net/http/http.h"
enum ParseHttpRequestState {
METHOD,
URI,
VERSION,
HKEY,
HSEP,
HVAL,
CR1,
LF1,
LF2
};
/**
* Parses req line and headers of HTTP req.
*
* This parser is very lax. All decoding is ISO-8859-1. A 1mB upper
* bound on memory is enforced.
*/
int parsehttprequest(struct HttpRequest *req, FILE *f) {
enum ParseHttpRequestState state = METHOD;
int toto = 0;
clearhttprequest(req);
while (true) {
char ch;
{
int c = fgetc(f);
if (c == -1) {
if (toto && !ferror(f)) {
return ebadmsg(); /* RFC7230 § 3.4 */
}
return -1;
}
ch = (unsigned char)c;
}
if (++toto == UINT16_MAX) {
return ebadmsg(); /* RFC7230 § 3.2.5 */
}
switch (state) {
case METHOD:
if (ch == '\r' || ch == '\n') break; /* RFC7230 § 3.5 */
if (ch == ' ') {
if (req->method.i == 0) return ebadmsg();
state = URI;
} else {
append(&req->method, &ch);
}
break;
case URI:
if (ch == ' ') {
if (req->uri.i == 0) return ebadmsg();
state = VERSION;
} else {
append(&req->uri, &ch);
}
break;
case VERSION:
if (ch == '\r' || ch == '\n') {
state = ch == '\r' ? CR1 : LF1;
} else {
append(&req->version, &ch);
}
break;
case CR1:
if (ch != '\n') return ebadmsg();
state = LF1;
break;
case LF1:
if (ch == '\r') {
state = LF2;
break;
} else if (ch == '\n') {
return 0;
} else if (ch == ' ' || ch == '\t') { /* line folding!!! */
return eprotonosupport(); /* RFC7230 § 3.2.4 */
}
state = HKEY;
/* εpsilon transition */
case HKEY:
if (ch == ':') state = HSEP;
ch = tolower(ch);
append(&req->scratch, &ch);
break;
case HSEP:
if (ch == ' ' || ch == '\t') break;
state = HVAL;
/* εpsilon transition */
case HVAL:
if (ch == '\r' || ch == '\n') {
state = ch == '\r' ? CR1 : LF1;
ch = '\0';
}
append(&req->scratch, &ch);
if (!ch) {
critbit0_insert(&req->headers, req->scratch.p);
req->scratch.i = 0;
}
break;
case LF2:
if (ch == '\n') return 0;
return ebadmsg();
default:
unreachable;
}
}
}

9075
net/http/rfc2068 Normal file

File diff suppressed because it is too large Load diff

2243
net/http/rfc2396 Normal file

File diff suppressed because it is too large Load diff

51
net/http/todo.S Normal file
View file

@ -0,0 +1,51 @@
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify │
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License. │
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of │
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software │
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
/ TODO(jart): FIX ME
.globl "o//net/http/uricspn.c"
.equ "o//net/http/uricspn.c",.
.globl "o//net/http/uriparse.c"
.equ "o//net/http/uriparse.c",.
.globl "o/rel/net/http/uricspn.c"
.equ "o/rel/net/http/uricspn.c",.
.globl "o/rel/net/http/uriparse.c"
.equ "o/rel/net/http/uriparse.c",.
.globl "o/tiny/net/http/uricspn.c"
.equ "o/tiny/net/http/uricspn.c",.
.globl "o/tiny/net/http/uriparse.c"
.equ "o/tiny/net/http/uriparse.c",.
.globl "o/dbg/net/http/uricspn.c"
.equ "o/dbg/net/http/uricspn.c",.
.globl "o/dbg/net/http/uriparse.c"
.equ "o/dbg/net/http/uriparse.c",.
.globl "o/opt/net/http/uricspn.c"
.equ "o/opt/net/http/uricspn.c",.
.globl "o/opt/net/http/uriparse.c"
.equ "o/opt/net/http/uriparse.c",.
.globl "o/ansi/net/http/uricspn.c"
.equ "o/ansi/net/http/uricspn.c",.
.globl "o/ansi/net/http/uriparse.c"
.equ "o/ansi/net/http/uriparse.c",.

106
net/http/uri.h Normal file
View file

@ -0,0 +1,106 @@
#ifndef COSMOPOLITAN_NET_HTTP_URI_H_
#define COSMOPOLITAN_NET_HTTP_URI_H_
#include "libc/dns/dns.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
enum UriScheme {
kUriSchemeHttp = 1,
kUriSchemeHttps,
kUriSchemeFile,
kUriSchemeData,
kUriSchemeZip,
kUriSchemeSip,
kUriSchemeSips,
kUriSchemeTel,
kUriSchemeSsh,
kUriSchemeGs,
kUriSchemeS3
};
struct Uri {
/*
* e.g. "", "http", "sip", "http", "dns+http", etc.
*/
struct UriSlice {
/*
* !i && !n means absent
* i && !n means empty
*/
unsigned i, n;
} scheme;
/*
* Holds remainder for exotic URI schemes, e.g. data.
*/
struct UriSlice opaque;
/*
* e.g. sip:user@host, //user:pass@host
*/
struct UriSlice userinfo;
/*
* e.g. "", "example.com", "1.2.3.4", "::1", etc.
*/
struct UriSlice host;
/*
* e.g. "", "5060", "80", etc.
*/
struct UriSlice port;
/*
* e.g. /dir/index.html means
* - memcmp("/dir/index.html",
* p + segs.p[0].i,
* (segs.p[segs.i - 1].n +
* (segs.p[segs.i - 1].i -
* segs.p[0].i))) == 0
* - memcmp("/dir", p + segs.p[0].i, segs.p[0].n) == 0
* - memcmp("/index.html", p + segs.p[1].i, segs.p[1].n) == 0
*/
struct UriSlices {
unsigned i, n;
struct UriSlice *p;
} segs;
/* e.g. ;lr;isup-oli=00;day=tuesday */
struct UriKeyvals {
unsigned i, n;
struct UriKeyval {
struct UriSlice k, v;
} * p;
} params;
/*
* e.g. /dir;super=rare/index.html
*
* let 𝑖 [0,params.i)
* paramsegs.p[𝑖].r [0,segs.i]
*/
struct UriRefs {
unsigned i, n;
struct UriRef {
unsigned r;
} * p;
} paramsegs;
/* e.g. ?boop&subject=project%20x&lol=cat */
struct UriKeyvals queries;
/* e.g. #anchor */
struct UriSlice fragment;
};
int uricspn(const char *data, size_t size);
int uriparse(struct Uri *, const char *, size_t) paramsnonnull((1));
enum UriScheme urischeme(struct UriSlice, const char *)
paramsnonnull() nosideeffect;
struct UriSlice uripath(const struct Uri *) paramsnonnull() nosideeffect;
char *urislice2cstr(char *, size_t, struct UriSlice, const char *, const char *)
paramsnonnull((1, 4));
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_NET_HTTP_URI_H_ */

62
net/http/uricspn-avx.S Normal file
View file

@ -0,0 +1,62 @@
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify │
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License. │
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of │
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software │
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/macros.h"
/ Verifies buffer contains only URI characters.
/
/ @param %rdi is data which should be 32-byte aligned
/ @param %rsi is byte length of data
/ @return number of kosher bytes
/ @cost 10x faster than fastest Ragel code
uricspn$avx:
.leafprologue
.profilable
vmovaps .Luric(%rip),%xmm0
mov $14,%eax
mov %rsi,%rdx
xor %esi,%esi
0: vmovdqu (%rdi,%rsi),%xmm1
vmovdqu 16(%rdi,%rsi),%xmm2
vpcmpestri $0b00010100,%xmm1,%xmm0
jc 1f
jo 1f
add $16,%rsi
sub $16,%rdx
vpcmpestri $0b00010100,%xmm2,%xmm0
jc 1f
jo 1f
add $16,%rsi
sub $16,%rdx
jmp 0b
1: lea (%rsi,%rcx),%rax
.leafepilogue
.endfn uricspn$avx,globl,hidden
.rodata.cst16
.Luric: .byte '!,'!
.byte '$,';
.byte '=,'=
.byte '?,'Z
.byte '_,'_
.byte 'a,'z
.byte '~,'~
.byte 0,0
.endobj .Luric
.previous

69
net/http/uricspn.rl Normal file
View file

@ -0,0 +1,69 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/assert.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/sysv/errfuns.h"
#include "net/http/uri.h"
#define static
/* clang-format off */
%% machine uricspn;
%% write data;
/* clang-format on */
int uricspn(const char *data, size_t size) {
int uricspn$avx(const char *, size_t) hidden;
const char *p, *pe;
int cs;
assert(data || !size);
assert(size <= 0x7ffff000);
assert(size <= 0x7ffff000);
if (X86_HAVE(AVX)) {
return uricspn$avx(data, size);
}
p = data;
pe = data + size;
/* clang-format off */
%%{
mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")";
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ",";
unreserved = alnum | mark;
uric = reserved | unreserved | "%";
machina := uric*;
}%%
%% write init;
cs = uricspn_en_machina;
%% write exec;
/* clang-format on */
if (cs >= uricspn_first_final) {
return p - data;
} else {
return einval();
}
}

BIN
net/http/uricspn.svgz Normal file

Binary file not shown.

246
net/http/uriparse.rl Normal file
View file

@ -0,0 +1,246 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/assert.h"
#include "libc/dce.h"
#include "libc/dns/dns.h"
#include "libc/log/log.h"
#include "libc/str/str.h"
#include "libc/sysv/errfuns.h"
#include "net/http/uri.h"
#define static
/* clang-format off */
%% machine uriparse;
%% write data;
/* clang-format on */
/**
* Parses URI.
*
* This is a general URL parser. It's typically used for HTTP. Support
* for the bonus syntax needed by SIP is provided. The whirlwhind tour
* of the URI rabbit hole is as follows:
*
* /foo.html
* //justine.local/foo.html
* http://justine.local/foo.html
* http://bettersearchengine.local/search.cgi?q=my%20query
* file:///etc/passwd
* gs://bucket/object.txt
* zip:///usr/share/zoneinfo/GMT
* sip:127.0.0.1:5060;lr
* sip:+12125650666@gateway.example
* sip:bob%20barker:priceisright@[dead:beef::666]:5060;isup-oli=00
* data:video/mpeg;base64,gigabytesofhex
*
* This parser operates on slices rather than C strings. It performs
* slicing and validation only. Operations like turning "%20"→" " or
* "80"→80 and perfect hashing can be done later, if needed.
*
* The Uri object is owned by the caller; it has a lifecycle like the
* following:
*
* struct Uri uri;
* memset(&uri, 0, sizeof(uri));
*
* uriparse(&uri, s1, strlen(s1));
* CHECK_EQ(kUriSchemeHttp, urischeme(uri->scheme, s1));
*
* uriparse(&uri, s2, strlen(s2));
* printf("host = %`.*s\n", uri->host.n, s2 + uri->host.i);
*
* Inner arrays may be granted memory by the caller. The uri->𝐴.i field
* is cleared at the mark of this function. No more than uri->𝐴.n items
* can be inserted. If we need more than that, then ENOMEM is returned
* rather than dynamically extending uri->𝐴.p. However, if uri->𝐴.n==0,
* we assume caller doesn't care about uri->𝐴 and its data is discarded.
*
* @param uri is owned by caller
* @param p is caller-owned uri string; won't copy/alias/mutate
* @return 0 on success, or -1 w/ errno
* @see RFC2396: Uniform Resource Identifiers (URI): Generic Syntax
* @see RFC3261: SIP: Session Initiation Protocol
*/
int uriparse(struct Uri *uri, const char *p, size_t size) {
unsigned zero, cs;
struct UriKeyval kv;
const char *pe, *eof, *buf, *mark;
assert(p || !size);
assert(size <= 0x7ffff000);
#define ABSENT ((struct UriSlice){zero, zero})
#define SLICE ((struct UriSlice){mark - buf, p - mark})
cs = zero = VEIL("r", 0u);
eof = pe = (mark = buf = p) + size;
uri->scheme = ABSENT;
uri->opaque = ABSENT;
uri->userinfo = ABSENT;
uri->host = ABSENT;
uri->port = ABSENT;
uri->fragment = ABSENT;
uri->segs.i = zero;
uri->paramsegs.i = zero;
uri->params.i = zero;
uri->queries.i = zero;
/* clang-format off */
%%{
action Mark { mark = p; }
action SetScheme { uri->scheme = SLICE; }
action SetFragment { uri->fragment = SLICE; }
action SetUserinfo { uri->userinfo = SLICE; }
action SetHost { uri->host = SLICE; }
action SetPort { uri->port = SLICE; }
action SetKey {
kv.k = SLICE;
kv.v = (struct UriSlice){zero, zero};
}
action SetVal {
kv.v = SLICE;
}
action RestartSegs {
uri->segs.i = zero;
uri->paramsegs.i = zero;
}
action AppendParam {
if (uri->params.n) {
if (uri->params.i < uri->params.n) {
uri->params.p[uri->params.i++] = kv;
} else {
return enomem();
}
}
}
action AppendQuery {
if (uri->queries.n) {
if (uri->queries.i < uri->queries.n) {
uri->queries.p[uri->queries.i++] = kv;
} else {
return enomem();
}
}
}
action AppendSegment {
if (p > mark && uri->segs.n) {
if (uri->segs.i < uri->segs.n) {
uri->segs.p[uri->segs.i++] = SLICE;
} else {
return enomem();
}
}
}
action HandleOpaquePart {
switch (urischeme(uri->scheme, buf)) {
case kUriSchemeSip:
case kUriSchemeSips:
--p;
fgoto sip;
default:
if (uricspn(p, pe - p) == pe - p) {
uri->opaque = (struct UriSlice){p - buf, pe - p};
return zero;
} else {
return einval();
}
}
}
mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")";
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ",";
unreserved = alnum | mark;
ipv4c = digit | ".";
ipv6c = xdigit | "." | ":";
hostc = alnum | "-" | ".";
telc = digit | "+" | "-";
schemec = alnum | "+" | "-" | ".";
userinfoc = unreserved | "&" | "=" | "+" | "$" | "," | "?" | ":";
paramc = unreserved | "[" | "]" | ":" | "&" | "+" | "$";
queryc = unreserved | "[" | "]" | "/" | "?" | ":" | "+" | "$";
pathc = unreserved | ":" | "@" | "&" | "=" | "+" | "$" | ",";
relc = unreserved | ";" | "@" | "&" | "=" | "+" | "$" | ",";
uric = reserved | unreserved;
escaped = "%" xdigit xdigit;
pathchar = escaped | pathc;
urichar = escaped | uric;
relchar = escaped | relc;
userinfochar = escaped | userinfoc;
paramchar = escaped | paramc;
querychar = escaped | queryc;
paramkey = paramchar+ >Mark %SetKey;
paramval = paramchar+ >Mark %SetVal;
param = ";" paramkey ( "=" paramval )? %AppendParam;
querykey = querychar+ >Mark %SetKey;
queryval = querychar+ >Mark %SetVal;
query = querykey ( "=" queryval )? %AppendQuery;
queries = "?" query ( "&" query )*;
scheme = ( alpha @Mark schemec* ) ":" @SetScheme;
userinfo = userinfochar+ >Mark "@" @SetUserinfo;
host6 = "[" ( ipv6c+ >Mark %SetHost ) "]";
host = host6 | ( ( ipv4c | hostc | telc )+ >Mark %SetHost );
port = digit+ >Mark %SetPort;
hostport = host ( ":" port )?;
authority = userinfo? hostport;
segment = pathchar+ %AppendSegment param*;
rel_segment = relchar+ >Mark %AppendSegment;
path_segments = segment ( "/" @Mark segment )*;
abs_path = "/" @Mark path_segments;
net_path = "//" authority abs_path? >RestartSegs;
hier_part = ( net_path | abs_path ) queries?;
rel_path = rel_segment abs_path?;
opaque_part = ( urichar -- "/" ) @HandleOpaquePart;
fragment = "#" urichar* >Mark %SetFragment;
relativeURI = ( net_path | abs_path | rel_path ) queries?;
absoluteURI = scheme ( hier_part | opaque_part );
sip := authority >Mark param*;
uri := ( relativeURI | absoluteURI )? fragment?;
}%%
%% write init;
cs = uriparse_en_uri;
%% write exec;
/* clang-format on */
if (cs >= uriparse_first_final) {
if (uri->host.n <= DNS_NAME_MAX && uri->port.n <= 6) {
return zero;
} else {
return eoverflow();
}
} else {
return einval();
}
}

BIN
net/http/uriparse.svgz Normal file

Binary file not shown.

31
net/http/uripath.c Normal file
View file

@ -0,0 +1,31 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "net/http/uri.h"
struct UriSlice uripath(const struct Uri *uri) {
if (uri->segs.i) {
return (struct UriSlice){
uri->segs.p[0].i,
(uri->segs.p[uri->segs.i - 1].n +
(uri->segs.p[uri->segs.i - 1].i - uri->segs.p[0].i))};
} else {
return (struct UriSlice){0, 0};
}
}

36
net/http/urischeme.c Normal file
View file

@ -0,0 +1,36 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "net/http/geturischeme.inc"
#include "net/http/uri.h"
/**
* Returns nonzero numeric code for resource paradigms we like.
*
* Lookups are case-insensitive and performed using a hash table that's
* literally perfect.
*/
enum UriScheme urischeme(struct UriSlice scheme, const char *str) {
const struct UriSchemeSlot *slot;
if ((slot = in_word_set(str + scheme.i, scheme.n))) {
return slot->code;
} else {
return 0;
}
}

35
net/http/urislice2cstr.c Normal file
View file

@ -0,0 +1,35 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
#include "net/http/uri.h"
char *urislice2cstr(char *buf, size_t size, struct UriSlice slice,
const char *uristr, const char *defaultval) {
/* TODO(jart): Unescape */
if (slice.n && slice.n + 1 < size) {
memcpy(buf, uristr + slice.i, slice.n);
} else if (defaultval) {
memcpy(buf, defaultval, (slice.n = strlen(defaultval)));
} else {
slice.n = 0;
}
buf[slice.n] = '\0';
return buf;
}