linux+httpd+svn實現(xiàn)http訪問及修改口令

1.背景

本人團(tuán)隊原來使用VisualSVN工具搭建svn服務(wù)器,隨著時間的增長硅卢,windows的磁盤空間越來越大仁期,最后滿了,也不太好擴(kuò)容(當(dāng)然如果想擴(kuò)容懂盐,最終肯定是可以實現(xiàn)的)褥赊。為了以后更好的svn容量管理,就開始新搭建一臺linux服務(wù)器莉恼,將svn數(shù)據(jù)單獨(dú)放存儲上拌喉,這樣后期擴(kuò)容就很方便了速那。
簡單一句就是:從VisualSVN遷移數(shù)據(jù)至Linux版svn中。

2.原有功能

  • 協(xié)議為http://方式(web方式或客戶端方式均支持)
  • 可在線修改用戶自己口令
  • 庫名都是中文的

3.安裝過程

3.1.軟件版本

為支持原有功能尿背,本人先在網(wǎng)上搜索了很多端仰,然后參考linux下apache+SVN搭建完美版進(jìn)行搭建。
當(dāng)然本次遷移田藐,本人使用了最新的軟件版本荔烧,清單如下:

  • Apr: apr-1.5.2和apr-util-1.5.4
  • Apache: httpd-2.4.25
  • Subversion: subversion-1.9.5
  • Zlib: zlib-1.2.11
  • Sqlite: sqlite-autoconf-3170000
  • Pcre: pcre-8.40
    各個軟件包可以在官網(wǎng)下載,如何解壓見參考文汽久。

3.2.軟件編譯參數(shù)

上述各個軟件編譯時的參數(shù)清單如下(有軟件有安裝順序):

  • ./configure --prefix=/svn/bin/apr/
  • ./configure --prefix=/svn/bin/apr-util/ --with-apr=/svn/bin/apr/
  • ./configure --prefix=/svn/bin/sqlite/
  • ./configure --prefix=/svn/bin/zlib/
  • ./configure --prefix=/svn/bin/pcre/
  • ./configure --prefix=/svn/bin/httpd/ --enable-so --enable-dav --enable-dav-fs --enable-maintainer-mode --enable-deflate=shared --enable-expires=shared --enable-headers=shared --enable-rewrite=shared --enable-static-support --with-mpm=prefork --enable-cache --enable-file-cache --enable-rewrite --enable-ssl --enable-proxy --enable-proxy-http --with-apr=/svn/bin/apr/ --with-apr-util=/svn/bin/apr-util/ --with-sqlite=/svn/bin/sqlite/ --with-pcre=/svn/bin/pcre/
  • ./configure --prefix=/svn/bin/svn --with-apr=/svn/bin/apr --with-apr-util=/svn/bin/apr-util/ --with-sqlite=/svn/bin/sqlite/ --with-zlib=/svn/bin/zlib/ --with-apxs=/svn/bin/httpd/bin/apxs --with-apache-libexecdir=/svn/bin/httpd/modules --enable-mod-activation
    具體各個參數(shù)含義鹤竭,可通過./configure --help顯示,或者查找官方說明景醇。
    安裝及后續(xù)配置時建議均使用同一個用戶臀稚,如本文的svnapp用戶,就會少很多目錄權(quán)限的問題三痰。

3.3.安裝完結(jié)果

按照上述安裝完后烁涌,如果沒有異常發(fā)生,那么應(yīng)該存在以下重要信息:

  • /svn/bin/httpd/modules/目錄下應(yīng)有mod_dav_svn.so和mod_zuthz_svn.so兩個文件
  • /svn/bin/httpd/conf/httpd.conf文件中已經(jīng)自動LoadModule上面2個*.so文件

4.配置過程

4.1.svn建庫

mkdir -p /svndata/Repositories/測試;
/svn/bin/svn/bin/svnadmin create --pre-1.6-compatible /svndata/Repositories/測試

為了與原有客戶端兼容(原來VisualSVN為1.7版本)酒觅,需添加--pre-1.6-xx參數(shù)或者--pre-1.7-xx參數(shù)
此時,【/svndata/Repositories/測試】目錄下應(yīng)自動生成一些配置文件微峰。
驗證svn是否可用:
將/svndata/Repositories/測試/conf/svnserve.conf中anon-access參數(shù)修改為write
然后啟動svn【/svn/bin/svn/bin/svnserve -d -r /svndata/Repositories/】舷丹,使用svn客戶端,如TortoiseSVN訪問【svn://IP:9000/測試】應(yīng)該可以正常訪問蜓肆,且可以新增文件或文件夾颜凯,表示svn使用正常

4.2.svn角色權(quán)限配置

參考文linux下apache+SVN搭建完美版中已經(jīng)完美了。
本文中仗扬,用戶及權(quán)限文件存放于【/svndata/Repositories/svn_conf/】目錄下症概,文件名為authz及passwd(密碼為明文,因為svn只支持明文)
然后修改【/svndata/Repositories/測試/conf/svnserve.conf】中對應(yīng)的密碼及權(quán)限文件早芭,可以使用絕對路徑彼城,這樣權(quán)限角色及密碼就統(tǒng)一管理了。
如果只是使用一個庫退个,那么就省去單獨(dú)配置募壕,直接使用conf下的配置文件進(jìn)行配置即可。

4.3.apache配置

/svn/bin/httpd/conf/httpd.conf:
1语盈、Listen 80修改為9000端口(如果使用80端口舱馅,則需要root用戶啟動) 2、User daemon及Group daemon分別修改為svnapp和svngrp刀荒,即svn建庫用戶與apaache啟動用戶為同一個代嗤,就不用chmod命令了 3棘钞、ServerName 修改為自己的IP地址 4、文件最后添加一行Include conf/httpd-svn.conf干毅,把所有svn的配置都放在/svn/bin/httpd/conf/httpd-svn.conf文件中宜猜,方便管理
然后在conf目錄中touch httpd-svn.conf
此時可以使用命令啟動svn及httpd服務(wù):

  • /svn/bin/httpd/bin/apachectl -k start
    可以使用ps -fu svnapp查看這些進(jìn)程。
    至此溶锭,apache和svn是獨(dú)立啟動訪問的宝恶,保證都o(jì)k后,再往下走趴捅。

4.4.關(guān)聯(lián)apache和svn

/svn/bin/httpd/conf/httpd-svn.conf:

SVNUseUTF8 On
<Location /svn>
  DAV svn
  SVNParentPath /svndata/Repositories
  SVNListParentPath On
  SVNIndexXSLT "/svnindex.xsl"
  SVNPathAuthz short_circuit
  AuthType Basic
  AuthName "Subversion Repository"
  AuthUserFile /svndata/Repositories/svn_conf/htpasswd
  AuthzSVNAccessFile /svndata/Repositories/svn_conf/authz
  Require valid-user
</Location>
CustomLog logs/svn_logfile "%t %u %{SVN-ACTION}e" env=SVN-ACTION

大部分指令在參考網(wǎng)頁中已經(jīng)說明垫毙,現(xiàn)對特殊的簡要說明:

  • SVNUseUTF8指令是svn 1.8版本以后的新功能,告訴mod_dav_svn用utf8編碼解析URL及文件名拱绑。此處若不添加综芥,則可能會報【Can't convert string from 'UTF-8' to natvie encoding】的錯,詳情見why repository name should not be utf-8猎拨,此問題本人尋找了好幾天膀藐,終于在某個網(wǎng)頁上提及了這個指令,然后報著試一試的想法红省,果然能解決额各。
  • SVNIndexXSLT指令表示web端訪問時,要采用的樣式吧恃,這是一個xml的文檔定義表虾啦,即定義目錄名、文件名痕寓、上一層等顯示的css樣式傲醉,本文使用的代碼見后文。
  • CustomLog指令為svn正常訪問的日志重定向呻率,可用可不用

然后使用htpasswd命令創(chuàng)建1個用戶硬毕,然后設(shè)置好權(quán)限authz文件(這些均見參考網(wǎng)頁)。
至此礼仗,應(yīng)該可以使用“ http://IP:9000/svn/測試 ”在瀏覽器中訪問了(可先把SVNIndexXSLT指令注釋掉吐咳,再測試)

4.5.Web顯示樣式

這幾個顯示的樣式文件及js文件,均從VisualSVN中復(fù)制過來元践,然后稍做修改而得
/svn/bin/httpd/htdocs/svnindex.xsl(從VisualSVN來挪丢,未修改):

<?xml version="1.0"?>
<!-- A sample XML transformation style sheet for displaying the Subversion
  directory listing that is generated by mod_dav_svn when the "SVNIndexXSLT"
  directive is used. -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="html"/>
  <xsl:template match="*"/>
  <xsl:template match="svn">
    <html>
      <head>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
        <title>
          <xsl:if test="index/@base">
            <xsl:text>代碼庫 </xsl:text>
            <xsl:value-of select="index/@base" /> 
            <xsl:text>:</xsl:text>
            <xsl:value-of select="index/@path"/>
          </xsl:if>
          <xsl:if test="string-length(index/@base) = 0">
            <xsl:text>倉庫列表</xsl:text>
          </xsl:if>
        </title>
        <link rel="stylesheet" type="text/css" href="/svnindex.css"/>
        <script language="javascript" type="text/javascript" src="/jquery.js" charset="utf-8"></script>
        <script language="javascript" type="text/javascript" src="/svnAuth.js" charset="utf-8"></script>
      </head>
      <body>
        <div class="header" id="header">
          <xsl:element name="a">
            <xsl:attribute name="id">
              <xsl:text>lnkModify</xsl:text>
            </xsl:attribute>
            <xsl:attribute name="style">
              <xsl:text>color:green;text-decoration:none;</xsl:text>
            </xsl:attribute>
            <xsl:attribute name="href">
              <xsl:text>javascript:doChange();void(0);</xsl:text>
            </xsl:attribute>
            <xsl:text>修改密碼</xsl:text>
          </xsl:element>
          <xsl:element name="span">
            <xsl:text> </xsl:text>
          </xsl:element>
          <xsl:element name="span">
            <xsl:text> </xsl:text>
          </xsl:element>
          <xsl:element name="a">
            <xsl:attribute name="style">
              <xsl:text>color:green;text-decoration:none;</xsl:text>
            </xsl:attribute>
            <xsl:attribute name="href">
              <xsl:text>http://www.visualsvn.com/doc/</xsl:text>
            </xsl:attribute>
            <xsl:text>幫助文檔</xsl:text>
          </xsl:element>
        </div>
        <div class="svn">
          <xsl:apply-templates/>
        </div>
        <div class="footer">
          <xsl:element name="a">
            <xsl:attribute name="href">
              <xsl:text>http://www.visualsvn.com/server/</xsl:text>
            </xsl:attribute>
            <xsl:text>VisualSVN Server</xsl:text>
          </xsl:element>

          <xsl:text>&#160;&#160;  powered by </xsl:text>
          <xsl:element name="a">
            <xsl:attribute name="href">
              <xsl:value-of select="@href"/>
            </xsl:attribute>
            <xsl:attribute name="title">
              <xsl:text>ver </xsl:text>
              <xsl:value-of select="@version"/>
            </xsl:attribute>
            <xsl:text>Subversion </xsl:text>
          </xsl:element>
        </div>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="index">
    <div class="rev">
      <xsl:value-of select="@name"/>
      <xsl:if test="@base">
        <xsl:text>代碼庫 </xsl:text>
        <xsl:value-of select="@base" />
        <xsl:text>:</xsl:text>
        <xsl:value-of select="@path"/>
        <xsl:text>&#160;&#160;</xsl:text>
        <xsl:if test="@rev">
          <xsl:text>當(dāng)前版本 Rev.</xsl:text>
          <xsl:value-of select="@rev"/>
        </xsl:if>
      </xsl:if>
      <xsl:if test="string-length(@base) = 0">
        <xsl:text>倉庫列表</xsl:text>
      </xsl:if>
    </div>
    <xsl:if test="@base">
      <div class="dir">
        <xsl:element name="a">
          <xsl:attribute name="href">/svn/</xsl:attribute>
          ![](/dir.png)
          <xsl:text>返回倉庫列表</xsl:text>
        </xsl:element>
      </div>
    </xsl:if>
    <xsl:apply-templates select="updir"/>
    <xsl:apply-templates select="dir"/>
    <xsl:apply-templates select="file"/>
  </xsl:template>

  <xsl:template match="updir">
    <div class="dir">
      <xsl:element name="a">
        <xsl:attribute name="href">..</xsl:attribute>

        ![](/dir.png)
        <xsl:text>&#160;</xsl:text>
        <xsl:text>..</xsl:text>

      </xsl:element>
    </div>
  </xsl:template>

  <xsl:template match="dir">
    <div class="dir">
      <xsl:element name="a">
        <xsl:attribute name="href">
          <xsl:value-of select="@href"/>
        </xsl:attribute>

        ![](/dir.png)
        <xsl:text>&#160;</xsl:text>
        <xsl:value-of select="@name"/>

        <xsl:text>/</xsl:text>
      </xsl:element>
    </div>
  </xsl:template>

  <xsl:template match="file">
    <div class="file">
      <xsl:element name="a">
        <xsl:attribute name="href">
          <xsl:value-of select="@href"/>
        </xsl:attribute>

        ![](/file.png)
        <xsl:text>&#160;</xsl:text>
        <xsl:value-of select="@name"/>

      </xsl:element>
    </div>
  </xsl:template>

</xsl:stylesheet>

該文件引用的文件有/svn/bin/httpd/htdocs/jquery.js,直接從官網(wǎng)下載壓縮版的即可卢厂。
文件/svn/bin/httpd/htdocs/svnindex.css(從VisualSVN來乾蓬,未修改):

/* Style sheet for displaying the Subversion directory listing
   that is generated by mod_dav_svn and "svnindex.xsl". */

body{
  font-family:Verdana, Arial, Helvetica, sans-serif;
  font-size:9pt;
  background: #ffffff;
  margin: 0;
  padding: 0;
}

img { border: none; }

a {
  color: navy;
}

.header
{
  text-align: right;
  margin-right: 0.5em;
  clear: both;
  margin-left: 0.5em;
  background: url(header.png) top left no-repeat;
  height: 48px;
  padding: 6px;
}

.footer {
  text-align: right;
  margin-top: 1em;
  padding: 0.5em 1em 0.5em;
  font-size: 80%;
}

.svn {
  margin-left: 0.5em;
  margin-right: 0.5em;
}

.rev {
  margin-right: 3px;
  padding-left: 3px;
  text-align: left;
  font-size: 120%;
}

.dir a {
  text-decoration: none;
  color: black;
  display: block;
}

.dir img { vertical-align: middle }

.file a {
  text-decoration: none;
  color: black;
  display: block;
}

.file {
  margin: 3px;
  padding: 3px;
  background: rgb(95%,95%,95%);
}

.file img { vertical-align: middle }

.file:hover {
  margin: 3px;
  padding: 3px;
  background: rgb(90%,100%,90%);
}

.dir {
  margin: 3px;
  padding: 3px;
  background: rgb(90%,90%,90%);
}

.dir:hover {
  margin: 3px;
  padding: 3px;
  background: rgb(80%,100%,80%);
}

還有文件/svn/bin/httpd/htdocs/svnAuth.js(從VisualSVN來,增加txt = txt.replace(/[\n]/ig, '')語句慎恒,增加"&type=CHG"和"&type=NEW"兩條語句):

var svnpassURL="/cgi-bin/svnpass.py";
String.prototype.encodeURI=function() {var rS; rS=escape(this); return rS.replace(/\+/g,"%2B");};
function doChange() 
{ 
    if (document.getElementById("creatInfo")) $("#creatInfo").remove();
    if (!document.getElementById("pwInfo"))
    {
        $('<div id="pwInfo" style="background-color:#f3f3f3;padding:0px;"> '
        +'用戶名:<input type="text" id="username" size="10" /> '
        +'密 碼:<input type="password" id="oldpwd" size="8" /> '
        +'新密碼:<input type="password" id="newpwd" size="8" /> '
        +'新密碼確認(rèn):<input type="password" id="newpwdCfm" size="8" /> '
        +'<input type="button" id="btnSubmit" value="確認(rèn)修改" /> '
        +'<input type="button" id="btnCancel" value="取消修改" /> '
        +'</div>').insertBefore("#header");
        $("#btnSubmit").bind("click", execChange);
        $("#btnCancel").bind("click", function() { $("#pwInfo").remove(); } );
    }
}

function execChange()
{
    var u=function(txt) 
    { 
                txt = txt.replace(/[\n]/ig, '')
        if (txt=="0")
        {
            alert("操作成功任内!");
            $("#pwInfo").remove();
        }
        else
        {
            alert(txt);
            $("#btnSubmit").attr("value", "確認(rèn)修改").removeAttr("disabled");
        }
    };
    $("#btnSubmit").attr("value", "請稍等...").attr("disabled","disabled");
    jQuery.post(svnpassURL,
        "username="+$("#username").val().encodeURI()
        +"&oldpwd="+$("#oldpwd").val().encodeURI()
        +"&newpwd="+$("#newpwd").val().encodeURI()
        +"&newpwdcfm="+$("#newpwdCfm").val().encodeURI()
                +"&type=CHG",
    u)
}

function doCreate() 
{ 
    if (document.getElementById("pwInfo")) $("#pwInfo").remove();
    if (!document.getElementById("creatInfo"))
    {
        $('<div id="creatInfo" style="background-color:#D1EDD1;padding:0px;"> '
        +'用戶名:<input type="text" id="usernameApply" size="10" /> '
        +'登錄密碼:<input type="password" id="pwd" size="8" /> '
        +'密碼確認(rèn):<input type="password" id="pwdCfm" size="8" /> '
        +'<input type="button" id="btnApply" value="確認(rèn)申請" /> '
        +'<input type="button" id="btnApplyCancel" value="取消申請" /> '
        +'</div>').insertBefore("#header");
        $("#btnApply").bind("click", execCreat);
        $("#btnApplyCancel").bind("click", function() { $("#creatInfo").remove(); } );
    }
}

function execCreat()
{
    var u=function(txt) 
    { 
                txt = txt.replace(/[\n]/ig, '')
        if (txt=="0")
        {
            alert("操作成功撵渡!");
            $("#creatInfo").remove();
        }
        else
        {
            alert(txt);
            $("#btnApply").attr("value", "確認(rèn)申請").removeAttr("disabled");
        }
    };
    $("#btnApply").attr("value", "請稍等...").attr("disabled","disabled");
    jQuery.post(svnpassURL,
        "username="+$("#usernameApply").val().encodeURI()
        +"&pwd="+$("#pwd").val().encodeURI()
        +"&pwdcfm="+$("#pwdCfm").val().encodeURI(),
                +"&type=NEW",
    u)
}


$(document).bind('ready',function(){
    if (document.location.href.toLowerCase().indexOf("/svnauth/")!=-1)
    {
        $("#lnkModify").before('<a href="javascript:doCreate();void(0);" style="color:green;text-decoration:none;">創(chuàng)建新用戶</a>&nbsp;&nbsp;'); 
    }
});

當(dāng)然,除了這3個文件外死嗦,還有圖片趋距,請讀者自行添加即可。

至此越除,web瀏覽器訪問出來的效果就很好看了节腐。但還無法進(jìn)行web端修改密碼。

5.實現(xiàn)客戶端修改口令

本人在網(wǎng)上找了很多摘盆,大部分是PHP的腳本旺入,還需要安裝PHP梨树,感覺并不太方便芙粱,也沒有解釋原理熟史,本人實現(xiàn)效果如下:


133965876475086475.jpg

現(xiàn)整理下實現(xiàn)原理如下:

  • WEB端彈出的密碼框由上面的svnAuth.js動態(tài)控制
  • 真正實現(xiàn)修改口令的是cgi腳本,本文直接使用python提供

因此类垦,本人就偷懶了下狈邑,直接把VisualSVN的前端頁面(如上述的css和js文件)拿過來了,這樣就不用重復(fù)造輪子了蚤认。
但由于VisualSVN執(zhí)行的cgi程序svnpass為二進(jìn)制文件米苹,無法直接放到linux上執(zhí)行,所以就放棄了砰琢。
這里得說下驱入,網(wǎng)上大多使用的是apache2xPasswd和apache2xPasswd.ini文件作為cgi的后臺支持。但本人找了下氯析,好像還沒有apache24Passwd的文件,而且這還是二進(jìn)制的文件莺褒,太方便修改了掩缓。所以本人還是自己動手吧,最終發(fā)現(xiàn)其實并不復(fù)雜遵岩。
現(xiàn)直接亮出python腳本:/svn/bin/httpd/cgi-bin/svnpass.py:

#!/usr/bin/python
#-*- coding: UTF-8

import os
import cgi
import subprocess

pwdfile = "/svndata/Repositories/svn_conf/htpasswd"
cmdfile = "/svn/bin/httpd/bin/htpasswd"

errmsg = ""

def run_script(c):
    try :
        res = subprocess.check_output(c, shell=True)
        return True
    except Exception as exp:
        errmsg = exp.output
        return False

def check(n, p):
    cmd = "%s -bv %s %s %s" % (cmdfile, pwdfile, n, p)
    #print "check: ", cmd
    return run_script(cmd)

def setPwd(n, p):
    cmd = "%s -D %s %s;%s -b %s %s %s" % (cmdfile, pwdfile, n, cmdfile, pwdfile, n, p)
    return run_script(cmd)

def main():
    print "Content-type: text/html; charset=utf-8\n"

    form = cgi.FieldStorage()

    name    = form.getvalue("username" , "").strip()
    optype  = form.getvalue("type"     , "").strip()
    ## create
    pwd     = form.getvalue("pwd"      , "").strip()
    pwdcfm  = form.getvalue("pwdcfm"   , "").strip()
    ## change
    oldpwd  = form.getvalue("oldpwd"   , "").strip()
    newpwd1 = form.getvalue("newpwd"   , "").strip()
    newpwd2 = form.getvalue("newpwdcfm", "").strip()

    if name == "" or optype == "" :
        print "缺少參數(shù)用戶名或者類型"
        return

    ## create
    if optype == "NEW" :
        if pwd == "" or pwdcfm == "" or pwd != pwdcfm :
            print "密碼不能為空或兩次密碼輸入不一致你辣!"
        else :
            print ("0" if setPwd(name, pwd) else "設(shè)置密碼失敗:" + errmsg)
    elif optype == "CHG" :
        if oldpwd == "" or newpwd1 == "" or newpwd2 == "" or newpwd1 != newpwd2 :
            print "密碼不能為空或兩次密碼輸入不一致尘执!"
        else :
            if not check(name, oldpwd) :
                print "原始密碼驗證失敗"
            else :
                print ("0" if setPwd(name, newpwd1) else "修改密碼失斏岷濉:" + errmsg)
    else :
        print "類型不正確!"

    ## for key in os.environ.keys():
    ##     print "%s = %s<br/>" % (key, os.environ[key])

main()

此腳本就是當(dāng)前端svnAuth.js執(zhí)行jquery.post()方法時誊锭,異步的返回是否修改口令成功表悬,如果返回"0",表示成功丧靡,返回其它字符表示出錯了蟆沫。當(dāng)然這種前后臺接口是最low的籽暇,但對于svn這種工具,也沒有必要花心思去設(shè)計那么完美的接口饭庞,比如什么json戒悠、restfull之類的東東。
總結(jié)起來核心點(diǎn)是:

  • 使用/svn/bin/httpd/bin/htpasswd命令行工具進(jìn)行驗證舟山、修改用戶口令

那么也就是說大家熟悉哪門語言或者說linux服務(wù)器上支持哪門語言绸狐,就可以直接寫這樣類似的腳本。本人當(dāng)前機(jī)器剛好已經(jīng)自帶了python2.7累盗,所以就直接用python去寫了寒矿。
然后設(shè)置一下svnpass.py的執(zhí)行權(quán)限為+x。

至此幅骄,所有的配置就已經(jīng)完成了劫窒。

經(jīng)過這快2周的調(diào)試,總算弄明白這svn通過http方式訪問的原理拆座,而且用戶能自己修改口令主巍。其實我真希望svn官網(wǎng)能直接提供這種支持,讓用戶使用起來更加方便挪凑。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末孕索,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子躏碳,更是在濱河造成了極大的恐慌搞旭,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件菇绵,死亡現(xiàn)場離奇詭異肄渗,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)咬最,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進(jìn)店門翎嫡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人永乌,你說我怎么就攤上這事惑申。” “怎么了翅雏?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵圈驼,是天一觀的道長。 經(jīng)常有香客問我望几,道長绩脆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮衙伶,結(jié)果婚禮上祈坠,老公的妹妹穿的比我還像新娘。我一直安慰自己矢劲,他們只是感情好赦拘,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著芬沉,像睡著了一般躺同。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上丸逸,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天蹋艺,我揣著相機(jī)與錄音,去河邊找鬼黄刚。 笑死捎谨,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的憔维。 我是一名探鬼主播涛救,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼业扒!你這毒婦竟也來了检吆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤程储,失蹤者是張志新(化名)和其女友劉穎蹭沛,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體章鲤,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡摊灭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了败徊。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片帚呼。...
    茶點(diǎn)故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖集嵌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情御毅,我是刑警寧澤根欧,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站端蛆,受9級特大地震影響凤粗,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一嫌拣、第九天 我趴在偏房一處隱蔽的房頂上張望柔袁。 院中可真熱鬧,春花似錦异逐、人聲如沸捶索。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽腥例。三九已至,卻和暖如春酝润,著一層夾襖步出監(jiān)牢的瞬間燎竖,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工要销, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留构回,地道東北人。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓疏咐,卻偏偏與公主長得像纤掸,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子凳鬓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評論 2 359

推薦閱讀更多精彩內(nèi)容